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);
83 static int mpt_msi_enable_spi;
84 module_param(mpt_msi_enable_spi, int, 0);
85 MODULE_PARM_DESC(mpt_msi_enable_spi, " Enable MSI Support for SPI \
86 controllers (default=0)");
88 static int mpt_msi_enable_fc;
89 module_param(mpt_msi_enable_fc, int, 0);
90 MODULE_PARM_DESC(mpt_msi_enable_fc, " Enable MSI Support for FC \
91 controllers (default=0)");
93 static int mpt_msi_enable_sas;
94 module_param(mpt_msi_enable_sas, int, 1);
95 MODULE_PARM_DESC(mpt_msi_enable_sas, " Enable MSI Support for SAS \
96 controllers (default=1)");
99 static int mpt_channel_mapping;
100 module_param(mpt_channel_mapping, int, 0);
101 MODULE_PARM_DESC(mpt_channel_mapping, " Mapping id's to channels (default=0)");
103 static int mpt_debug_level;
104 static int mpt_set_debug_level(const char *val, struct kernel_param *kp);
105 module_param_call(mpt_debug_level, mpt_set_debug_level, param_get_int,
106 &mpt_debug_level, 0600);
107 MODULE_PARM_DESC(mpt_debug_level, " debug level - refer to mptdebug.h \
112 static int mfcounter = 0;
113 #define PRINT_MF_COUNT 20000
116 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
121 static struct proc_dir_entry *mpt_proc_root_dir;
123 #define WHOINIT_UNKNOWN 0xAA
125 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
129 /* Adapter link list */
131 /* Callback lookup table */
132 static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
133 /* Protocol driver class lookup table */
134 static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
135 /* Event handler lookup table */
136 static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
137 /* Reset handler lookup table */
138 static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
139 static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
141 static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq);
144 * Driver Callback Index's
146 static u8 mpt_base_index = MPT_MAX_PROTOCOL_DRIVERS;
147 static u8 last_drv_idx;
149 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
153 static irqreturn_t mpt_interrupt(int irq, void *bus_id);
154 static int mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
155 static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
156 u32 *req, int replyBytes, u16 *u16reply, int maxwait,
158 static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
159 static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
160 static void mpt_adapter_disable(MPT_ADAPTER *ioc);
161 static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
163 static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
164 static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
165 static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
166 static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
167 static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
168 static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
169 static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
170 static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
171 static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
172 static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
173 static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
174 static int PrimeIocFifos(MPT_ADAPTER *ioc);
175 static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
176 static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
177 static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
178 static int GetLanConfigPages(MPT_ADAPTER *ioc);
179 static int GetIoUnitPage2(MPT_ADAPTER *ioc);
180 int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
181 static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
182 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
183 static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
184 static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
185 static void mpt_timer_expired(unsigned long data);
186 static void mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc);
187 static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
188 static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
189 static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
190 static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
192 #ifdef CONFIG_PROC_FS
193 static int procmpt_summary_read(char *buf, char **start, off_t offset,
194 int request, int *eof, void *data);
195 static int procmpt_version_read(char *buf, char **start, off_t offset,
196 int request, int *eof, void *data);
197 static int procmpt_iocinfo_read(char *buf, char **start, off_t offset,
198 int request, int *eof, void *data);
200 static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
202 //int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
203 static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers);
204 static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
205 static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
206 static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
207 static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
208 static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
209 static void mpt_inactive_raid_list_free(MPT_ADAPTER *ioc);
211 /* module entry point */
212 static int __init fusion_init (void);
213 static void __exit fusion_exit (void);
215 #define CHIPREG_READ32(addr) readl_relaxed(addr)
216 #define CHIPREG_READ32_dmasync(addr) readl(addr)
217 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
218 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
219 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
222 pci_disable_io_access(struct pci_dev *pdev)
226 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
228 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
232 pci_enable_io_access(struct pci_dev *pdev)
236 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
238 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
241 static int mpt_set_debug_level(const char *val, struct kernel_param *kp)
243 int ret = param_set_int(val, kp);
249 list_for_each_entry(ioc, &ioc_list, list)
250 ioc->debug_level = mpt_debug_level;
255 * mpt_get_cb_idx - obtain cb_idx for registered driver
256 * @dclass: class driver enum
258 * Returns cb_idx, or zero means it wasn't found
261 mpt_get_cb_idx(MPT_DRIVER_CLASS dclass)
265 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--)
266 if (MptDriverClass[cb_idx] == dclass)
272 * mpt_fault_reset_work - work performed on workq after ioc fault
273 * @work: input argument, used to derive ioc
277 mpt_fault_reset_work(struct work_struct *work)
280 container_of(work, MPT_ADAPTER, fault_reset_work.work);
285 if (ioc->diagPending || !ioc->active)
288 ioc_raw_state = mpt_GetIocState(ioc, 0);
289 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
290 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state (%04xh)!!!\n",
291 ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
292 printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n",
293 ioc->name, __func__);
294 rc = mpt_HardResetHandler(ioc, CAN_SLEEP);
295 printk(MYIOC_s_WARN_FMT "%s: HardReset: %s\n", ioc->name,
296 __func__, (rc == 0) ? "success" : "failed");
297 ioc_raw_state = mpt_GetIocState(ioc, 0);
298 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT)
299 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state after "
300 "reset (%04xh)\n", ioc->name, ioc_raw_state &
301 MPI_DOORBELL_DATA_MASK);
306 * Take turns polling alternate controller
311 /* rearm the timer */
312 spin_lock_irqsave(&ioc->fault_reset_work_lock, flags);
313 if (ioc->reset_work_q)
314 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
315 msecs_to_jiffies(MPT_POLLING_INTERVAL));
316 spin_unlock_irqrestore(&ioc->fault_reset_work_lock, flags);
321 * Process turbo (context) reply...
324 mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
326 MPT_FRAME_HDR *mf = NULL;
327 MPT_FRAME_HDR *mr = NULL;
331 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got TURBO reply req_idx=%08x\n",
334 switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
335 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
336 req_idx = pa & 0x0000FFFF;
337 cb_idx = (pa & 0x00FF0000) >> 16;
338 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
340 case MPI_CONTEXT_REPLY_TYPE_LAN:
341 cb_idx = mpt_get_cb_idx(MPTLAN_DRIVER);
343 * Blind set of mf to NULL here was fatal
344 * after lan_reply says "freeme"
345 * Fix sort of combined with an optimization here;
346 * added explicit check for case where lan_reply
347 * was just returning 1 and doing nothing else.
348 * For this case skip the callback, but set up
349 * proper mf value first here:-)
351 if ((pa & 0x58000000) == 0x58000000) {
352 req_idx = pa & 0x0000FFFF;
353 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
354 mpt_free_msg_frame(ioc, mf);
359 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
361 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
362 cb_idx = mpt_get_cb_idx(MPTSTM_DRIVER);
363 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
370 /* Check for (valid) IO callback! */
371 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
372 MptCallbacks[cb_idx] == NULL) {
373 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
374 __func__, ioc->name, cb_idx);
378 if (MptCallbacks[cb_idx](ioc, mf, mr))
379 mpt_free_msg_frame(ioc, mf);
385 mpt_reply(MPT_ADAPTER *ioc, u32 pa)
396 /* non-TURBO reply! Hmmm, something may be up...
397 * Newest turbo reply mechanism; get address
398 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
401 /* Map DMA address of reply header to cpu address.
402 * pa is 32 bits - but the dma address may be 32 or 64 bits
403 * get offset based only only the low addresses
406 reply_dma_low = (pa <<= 1);
407 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
408 (reply_dma_low - ioc->reply_frames_low_dma));
410 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
411 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
412 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
414 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
415 ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
416 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mr);
418 /* Check/log IOC log info
420 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
421 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
422 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
423 if (ioc->bus_type == FC)
424 mpt_fc_log_info(ioc, log_info);
425 else if (ioc->bus_type == SPI)
426 mpt_spi_log_info(ioc, log_info);
427 else if (ioc->bus_type == SAS)
428 mpt_sas_log_info(ioc, log_info);
431 if (ioc_stat & MPI_IOCSTATUS_MASK)
432 mpt_iocstatus_info(ioc, (u32)ioc_stat, mf);
434 /* Check for (valid) IO callback! */
435 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
436 MptCallbacks[cb_idx] == NULL) {
437 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
438 __func__, ioc->name, cb_idx);
443 freeme = MptCallbacks[cb_idx](ioc, mf, mr);
446 /* Flush (non-TURBO) reply with a WRITE! */
447 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
450 mpt_free_msg_frame(ioc, mf);
454 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
456 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
457 * @irq: irq number (not used)
458 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
460 * This routine is registered via the request_irq() kernel API call,
461 * and handles all interrupts generated from a specific MPT adapter
462 * (also referred to as a IO Controller or IOC).
463 * This routine must clear the interrupt from the adapter and does
464 * so by reading the reply FIFO. Multiple replies may be processed
465 * per single call to this routine.
467 * This routine handles register-level access of the adapter but
468 * dispatches (calls) a protocol-specific callback routine to handle
469 * the protocol-specific details of the MPT request completion.
472 mpt_interrupt(int irq, void *bus_id)
474 MPT_ADAPTER *ioc = bus_id;
475 u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
477 if (pa == 0xFFFFFFFF)
481 * Drain the reply FIFO!
484 if (pa & MPI_ADDRESS_REPLY_A_BIT)
487 mpt_turbo_reply(ioc, pa);
488 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
489 } while (pa != 0xFFFFFFFF);
494 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
496 * mpt_base_reply - MPT base driver's callback routine
497 * @ioc: Pointer to MPT_ADAPTER structure
498 * @mf: Pointer to original MPT request frame
499 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
501 * MPT base driver's callback routine; all base driver
502 * "internal" request/reply processing is routed here.
503 * Currently used for EventNotification and EventAck handling.
505 * Returns 1 indicating original alloc'd request frame ptr
506 * should be freed, or 0 if it shouldn't.
509 mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
514 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply() called\n", ioc->name));
515 #ifdef CONFIG_FUSION_LOGGING
516 if ((ioc->debug_level & MPT_DEBUG_MSG_FRAME) &&
517 !(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) {
518 dmfprintk(ioc, printk(MYIOC_s_INFO_FMT ": Original request frame (@%p) header\n",
520 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)mf);
524 func = reply->u.hdr.Function;
525 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply, Function=%02Xh\n",
528 if (func == MPI_FUNCTION_EVENT_NOTIFICATION) {
529 EventNotificationReply_t *pEvReply = (EventNotificationReply_t *) reply;
533 results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
534 if (results != evHandlers) {
535 /* CHECKME! Any special handling needed here? */
536 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
537 ioc->name, evHandlers, results));
541 * Hmmm... It seems that EventNotificationReply is an exception
542 * to the rule of one reply per request.
544 if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) {
547 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
548 ioc->name, pEvReply));
551 #ifdef CONFIG_PROC_FS
552 // LogEvent(ioc, pEvReply);
555 } else if (func == MPI_FUNCTION_EVENT_ACK) {
556 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply, EventAck reply received\n",
558 } else if (func == MPI_FUNCTION_CONFIG) {
562 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "config_complete (mf=%p,mr=%p)\n",
563 ioc->name, mf, reply));
565 pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *)));
568 /* disable timer and remove from linked list */
569 del_timer(&pCfg->timer);
571 spin_lock_irqsave(&ioc->FreeQlock, flags);
572 list_del(&pCfg->linkage);
573 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
576 * If IOC Status is SUCCESS, save the header
577 * and set the status code to GOOD.
579 pCfg->status = MPT_CONFIG_ERROR;
581 ConfigReply_t *pReply = (ConfigReply_t *)reply;
584 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
585 dcprintk(ioc, printk(MYIOC_s_NOTE_FMT " IOCStatus=%04xh, IOCLogInfo=%08xh\n",
586 ioc->name, status, le32_to_cpu(pReply->IOCLogInfo)));
588 pCfg->status = status;
589 if (status == MPI_IOCSTATUS_SUCCESS) {
590 if ((pReply->Header.PageType &
591 MPI_CONFIG_PAGETYPE_MASK) ==
592 MPI_CONFIG_PAGETYPE_EXTENDED) {
593 pCfg->cfghdr.ehdr->ExtPageLength =
594 le16_to_cpu(pReply->ExtPageLength);
595 pCfg->cfghdr.ehdr->ExtPageType =
598 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
600 /* If this is a regular header, save PageLength. */
601 /* LMP Do this better so not using a reserved field! */
602 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
603 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
604 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
609 * Wake up the original calling thread
614 } else if (func == MPI_FUNCTION_SAS_IO_UNIT_CONTROL) {
615 /* we should be always getting a reply frame */
616 memcpy(ioc->persist_reply_frame, reply,
617 min(MPT_DEFAULT_FRAME_SIZE,
618 4*reply->u.reply.MsgLength));
619 del_timer(&ioc->persist_timer);
620 ioc->persist_wait_done = 1;
623 printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
628 * Conditionally tell caller to free the original
629 * EventNotification/EventAck/unexpected request frame!
634 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
636 * mpt_register - Register protocol-specific main callback handler.
637 * @cbfunc: callback function pointer
638 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
640 * This routine is called by a protocol-specific driver (SCSI host,
641 * LAN, SCSI target) to register its reply callback routine. Each
642 * protocol-specific driver must do this before it will be able to
643 * use any IOC resources, such as obtaining request frames.
645 * NOTES: The SCSI protocol driver currently calls this routine thrice
646 * in order to register separate callbacks; one for "normal" SCSI IO;
647 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
649 * Returns u8 valued "handle" in the range (and S.O.D. order)
650 * {N,...,7,6,5,...,1} if successful.
651 * A return value of MPT_MAX_PROTOCOL_DRIVERS (including zero!) should be
652 * considered an error by the caller.
655 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
658 last_drv_idx = MPT_MAX_PROTOCOL_DRIVERS;
661 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
662 * (slot/handle 0 is reserved!)
664 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
665 if (MptCallbacks[cb_idx] == NULL) {
666 MptCallbacks[cb_idx] = cbfunc;
667 MptDriverClass[cb_idx] = dclass;
668 MptEvHandlers[cb_idx] = NULL;
669 last_drv_idx = cb_idx;
677 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
679 * mpt_deregister - Deregister a protocol drivers resources.
680 * @cb_idx: previously registered callback handle
682 * Each protocol-specific driver should call this routine when its
683 * module is unloaded.
686 mpt_deregister(u8 cb_idx)
688 if (cb_idx && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
689 MptCallbacks[cb_idx] = NULL;
690 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
691 MptEvHandlers[cb_idx] = NULL;
697 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
699 * mpt_event_register - Register protocol-specific event callback handler.
700 * @cb_idx: previously registered (via mpt_register) callback handle
701 * @ev_cbfunc: callback function
703 * This routine can be called by one or more protocol-specific drivers
704 * if/when they choose to be notified of MPT events.
706 * Returns 0 for success.
709 mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc)
711 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
714 MptEvHandlers[cb_idx] = ev_cbfunc;
718 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
720 * mpt_event_deregister - Deregister protocol-specific event callback handler
721 * @cb_idx: previously registered callback handle
723 * Each protocol-specific driver should call this routine
724 * when it does not (or can no longer) handle events,
725 * or when its module is unloaded.
728 mpt_event_deregister(u8 cb_idx)
730 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
733 MptEvHandlers[cb_idx] = NULL;
736 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
738 * mpt_reset_register - Register protocol-specific IOC reset handler.
739 * @cb_idx: previously registered (via mpt_register) callback handle
740 * @reset_func: reset function
742 * This routine can be called by one or more protocol-specific drivers
743 * if/when they choose to be notified of IOC resets.
745 * Returns 0 for success.
748 mpt_reset_register(u8 cb_idx, MPT_RESETHANDLER reset_func)
750 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
753 MptResetHandlers[cb_idx] = reset_func;
757 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
759 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
760 * @cb_idx: previously registered callback handle
762 * Each protocol-specific driver should call this routine
763 * when it does not (or can no longer) handle IOC reset handling,
764 * or when its module is unloaded.
767 mpt_reset_deregister(u8 cb_idx)
769 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
772 MptResetHandlers[cb_idx] = NULL;
775 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
777 * mpt_device_driver_register - Register device driver hooks
778 * @dd_cbfunc: driver callbacks struct
779 * @cb_idx: MPT protocol driver index
782 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, u8 cb_idx)
785 const struct pci_device_id *id;
787 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
790 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
792 /* call per pci device probe entry point */
793 list_for_each_entry(ioc, &ioc_list, list) {
794 id = ioc->pcidev->driver ?
795 ioc->pcidev->driver->id_table : NULL;
796 if (dd_cbfunc->probe)
797 dd_cbfunc->probe(ioc->pcidev, id);
803 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
805 * mpt_device_driver_deregister - DeRegister device driver hooks
806 * @cb_idx: MPT protocol driver index
809 mpt_device_driver_deregister(u8 cb_idx)
811 struct mpt_pci_driver *dd_cbfunc;
814 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
817 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
819 list_for_each_entry(ioc, &ioc_list, list) {
820 if (dd_cbfunc->remove)
821 dd_cbfunc->remove(ioc->pcidev);
824 MptDeviceDriverHandlers[cb_idx] = NULL;
828 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
830 * mpt_get_msg_frame - Obtain an MPT request frame from the pool
831 * @cb_idx: Handle of registered MPT protocol driver
832 * @ioc: Pointer to MPT adapter structure
834 * Obtain an MPT request frame from the pool (of 1024) that are
835 * allocated per MPT adapter.
837 * Returns pointer to a MPT request frame or %NULL if none are available
838 * or IOC is not active.
841 mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc)
845 u16 req_idx; /* Request index */
847 /* validate handle and ioc identifier */
851 printk(MYIOC_s_WARN_FMT "IOC Not Active! mpt_get_msg_frame "
852 "returning NULL!\n", ioc->name);
855 /* If interrupts are not attached, do not return a request frame */
859 spin_lock_irqsave(&ioc->FreeQlock, flags);
860 if (!list_empty(&ioc->FreeQ)) {
863 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
864 u.frame.linkage.list);
865 list_del(&mf->u.frame.linkage.list);
866 mf->u.frame.linkage.arg1 = 0;
867 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
868 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
870 req_idx = req_offset / ioc->req_sz;
871 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
872 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
873 /* Default, will be changed if necessary in SG generation */
874 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame;
881 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
885 printk(MYIOC_s_WARN_FMT "IOC Active. No free Msg Frames! "
886 "Count 0x%x Max 0x%x\n", ioc->name, ioc->mfcnt,
889 if (mfcounter == PRINT_MF_COUNT)
890 printk(MYIOC_s_INFO_FMT "MF Count 0x%x Max 0x%x \n", ioc->name,
891 ioc->mfcnt, ioc->req_depth);
894 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_get_msg_frame(%d,%d), got mf=%p\n",
895 ioc->name, cb_idx, ioc->id, mf));
899 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
901 * mpt_put_msg_frame - Send a protocol-specific MPT request frame to an IOC
902 * @cb_idx: Handle of registered MPT protocol driver
903 * @ioc: Pointer to MPT adapter structure
904 * @mf: Pointer to MPT request frame
906 * This routine posts an MPT request frame to the request post FIFO of a
907 * specific MPT adapter.
910 mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
914 u16 req_idx; /* Request index */
916 /* ensure values are reset properly! */
917 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
918 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
920 req_idx = req_offset / ioc->req_sz;
921 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
922 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
924 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
926 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
927 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d "
928 "RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx,
929 ioc->RequestNB[req_idx]));
930 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
934 * mpt_put_msg_frame_hi_pri - Send a hi-pri protocol-specific MPT request frame
935 * @cb_idx: Handle of registered MPT protocol driver
936 * @ioc: Pointer to MPT adapter structure
937 * @mf: Pointer to MPT request frame
939 * Send a protocol-specific MPT request frame to an IOC using
940 * hi-priority request queue.
942 * This routine posts an MPT request frame to the request post FIFO of a
943 * specific MPT adapter.
946 mpt_put_msg_frame_hi_pri(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
950 u16 req_idx; /* Request index */
952 /* ensure values are reset properly! */
953 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
954 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
955 req_idx = req_offset / ioc->req_sz;
956 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
957 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
959 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
961 mf_dma_addr = (ioc->req_frames_low_dma + req_offset);
962 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d\n",
963 ioc->name, mf_dma_addr, req_idx));
964 CHIPREG_WRITE32(&ioc->chip->RequestHiPriFifo, mf_dma_addr);
967 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
969 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
970 * @ioc: Pointer to MPT adapter structure
971 * @mf: Pointer to MPT request frame
973 * This routine places a MPT request frame back on the MPT adapter's
977 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
981 /* Put Request back on FreeQ! */
982 spin_lock_irqsave(&ioc->FreeQlock, flags);
983 mf->u.frame.linkage.arg1 = 0xdeadbeaf; /* signature to know if this mf is freed */
984 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
988 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
991 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
993 * mpt_add_sge - Place a simple SGE at address pAddr.
994 * @pAddr: virtual address for SGE
995 * @flagslength: SGE flags and data transfer length
996 * @dma_addr: Physical address
998 * This routine places a MPT request frame back on the MPT adapter's
1002 mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
1004 if (sizeof(dma_addr_t) == sizeof(u64)) {
1005 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1006 u32 tmp = dma_addr & 0xFFFFFFFF;
1008 pSge->FlagsLength = cpu_to_le32(flagslength);
1009 pSge->Address.Low = cpu_to_le32(tmp);
1010 tmp = (u32) ((u64)dma_addr >> 32);
1011 pSge->Address.High = cpu_to_le32(tmp);
1014 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
1015 pSge->FlagsLength = cpu_to_le32(flagslength);
1016 pSge->Address = cpu_to_le32(dma_addr);
1020 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1022 * mpt_send_handshake_request - Send MPT request via doorbell handshake method.
1023 * @cb_idx: Handle of registered MPT protocol driver
1024 * @ioc: Pointer to MPT adapter structure
1025 * @reqBytes: Size of the request in bytes
1026 * @req: Pointer to MPT request frame
1027 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1029 * This routine is used exclusively to send MptScsiTaskMgmt
1030 * requests since they are required to be sent via doorbell handshake.
1032 * NOTE: It is the callers responsibility to byte-swap fields in the
1033 * request which are greater than 1 byte in size.
1035 * Returns 0 for success, non-zero for failure.
1038 mpt_send_handshake_request(u8 cb_idx, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
1044 /* State is known to be good upon entering
1045 * this function so issue the bus reset
1050 * Emulate what mpt_put_msg_frame() does /wrt to sanity
1051 * setting cb_idx/req_idx. But ONLY if this request
1052 * is in proper (pre-alloc'd) request buffer range...
1054 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
1055 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
1056 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
1057 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
1058 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
1061 /* Make sure there are no doorbells */
1062 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1064 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1065 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
1066 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
1068 /* Wait for IOC doorbell int */
1069 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
1073 /* Read doorbell and check for active bit */
1074 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
1077 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_send_handshake_request start, WaitCnt=%d\n",
1080 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1082 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1086 /* Send request via doorbell handshake */
1087 req_as_bytes = (u8 *) req;
1088 for (ii = 0; ii < reqBytes/4; ii++) {
1091 word = ((req_as_bytes[(ii*4) + 0] << 0) |
1092 (req_as_bytes[(ii*4) + 1] << 8) |
1093 (req_as_bytes[(ii*4) + 2] << 16) |
1094 (req_as_bytes[(ii*4) + 3] << 24));
1095 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
1096 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1102 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
1107 /* Make sure there are no doorbells */
1108 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1113 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1115 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
1116 * @ioc: Pointer to MPT adapter structure
1117 * @access_control_value: define bits below
1118 * @sleepFlag: Specifies whether the process can sleep
1120 * Provides mechanism for the host driver to control the IOC's
1121 * Host Page Buffer access.
1123 * Access Control Value - bits[15:12]
1125 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1126 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1127 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1129 * Returns 0 for success, non-zero for failure.
1133 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1137 /* return if in use */
1138 if (CHIPREG_READ32(&ioc->chip->Doorbell)
1139 & MPI_DOORBELL_ACTIVE)
1142 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1144 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1145 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1146 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1147 (access_control_value<<12)));
1149 /* Wait for IOC to clear Doorbell Status bit */
1150 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1156 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1158 * mpt_host_page_alloc - allocate system memory for the fw
1159 * @ioc: Pointer to pointer to IOC adapter
1160 * @ioc_init: Pointer to ioc init config page
1162 * If we already allocated memory in past, then resend the same pointer.
1163 * Returns 0 for success, non-zero for failure.
1166 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1170 u32 host_page_buffer_sz=0;
1172 if(!ioc->HostPageBuffer) {
1174 host_page_buffer_sz =
1175 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1177 if(!host_page_buffer_sz)
1178 return 0; /* fw doesn't need any host buffers */
1180 /* spin till we get enough memory */
1181 while(host_page_buffer_sz > 0) {
1183 if((ioc->HostPageBuffer = pci_alloc_consistent(
1185 host_page_buffer_sz,
1186 &ioc->HostPageBuffer_dma)) != NULL) {
1188 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1189 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1190 ioc->name, ioc->HostPageBuffer,
1191 (u32)ioc->HostPageBuffer_dma,
1192 host_page_buffer_sz));
1193 ioc->alloc_total += host_page_buffer_sz;
1194 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1198 host_page_buffer_sz -= (4*1024);
1202 if(!ioc->HostPageBuffer) {
1203 printk(MYIOC_s_ERR_FMT
1204 "Failed to alloc memory for host_page_buffer!\n",
1209 psge = (char *)&ioc_init->HostPageBufferSGE;
1210 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1211 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1212 MPI_SGE_FLAGS_32_BIT_ADDRESSING |
1213 MPI_SGE_FLAGS_HOST_TO_IOC |
1214 MPI_SGE_FLAGS_END_OF_BUFFER;
1215 if (sizeof(dma_addr_t) == sizeof(u64)) {
1216 flags_length |= MPI_SGE_FLAGS_64_BIT_ADDRESSING;
1218 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1219 flags_length |= ioc->HostPageBuffer_sz;
1220 mpt_add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1221 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1226 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1228 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1229 * @iocid: IOC unique identifier (integer)
1230 * @iocpp: Pointer to pointer to IOC adapter
1232 * Given a unique IOC identifier, set pointer to the associated MPT
1233 * adapter structure.
1235 * Returns iocid and sets iocpp if iocid is found.
1236 * Returns -1 if iocid is not found.
1239 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1243 list_for_each_entry(ioc,&ioc_list,list) {
1244 if (ioc->id == iocid) {
1255 * mpt_get_product_name - returns product string
1256 * @vendor: pci vendor id
1257 * @device: pci device id
1258 * @revision: pci revision id
1259 * @prod_name: string returned
1261 * Returns product string displayed when driver loads,
1262 * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1266 mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name)
1268 char *product_str = NULL;
1270 if (vendor == PCI_VENDOR_ID_BROCADE) {
1273 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1277 product_str = "BRE040 A0";
1280 product_str = "BRE040 A1";
1283 product_str = "BRE040";
1293 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1294 product_str = "LSIFC909 B1";
1296 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1297 product_str = "LSIFC919 B0";
1299 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1300 product_str = "LSIFC929 B0";
1302 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1303 if (revision < 0x80)
1304 product_str = "LSIFC919X A0";
1306 product_str = "LSIFC919XL A1";
1308 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1309 if (revision < 0x80)
1310 product_str = "LSIFC929X A0";
1312 product_str = "LSIFC929XL A1";
1314 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1315 product_str = "LSIFC939X A1";
1317 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1318 product_str = "LSIFC949X A1";
1320 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1324 product_str = "LSIFC949E A0";
1327 product_str = "LSIFC949E A1";
1330 product_str = "LSIFC949E";
1334 case MPI_MANUFACTPAGE_DEVID_53C1030:
1338 product_str = "LSI53C1030 A0";
1341 product_str = "LSI53C1030 B0";
1344 product_str = "LSI53C1030 B1";
1347 product_str = "LSI53C1030 B2";
1350 product_str = "LSI53C1030 C0";
1353 product_str = "LSI53C1030T A0";
1356 product_str = "LSI53C1030T A2";
1359 product_str = "LSI53C1030T A3";
1362 product_str = "LSI53C1020A A1";
1365 product_str = "LSI53C1030";
1369 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1373 product_str = "LSI53C1035 A2";
1376 product_str = "LSI53C1035 B0";
1379 product_str = "LSI53C1035";
1383 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1387 product_str = "LSISAS1064 A1";
1390 product_str = "LSISAS1064 A2";
1393 product_str = "LSISAS1064 A3";
1396 product_str = "LSISAS1064 A4";
1399 product_str = "LSISAS1064";
1403 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1407 product_str = "LSISAS1064E A0";
1410 product_str = "LSISAS1064E B0";
1413 product_str = "LSISAS1064E B1";
1416 product_str = "LSISAS1064E B2";
1419 product_str = "LSISAS1064E B3";
1422 product_str = "LSISAS1064E";
1426 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1430 product_str = "LSISAS1068 A0";
1433 product_str = "LSISAS1068 B0";
1436 product_str = "LSISAS1068 B1";
1439 product_str = "LSISAS1068";
1443 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1447 product_str = "LSISAS1068E A0";
1450 product_str = "LSISAS1068E B0";
1453 product_str = "LSISAS1068E B1";
1456 product_str = "LSISAS1068E B2";
1459 product_str = "LSISAS1068E B3";
1462 product_str = "LSISAS1068E";
1466 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1470 product_str = "LSISAS1078 A0";
1473 product_str = "LSISAS1078 B0";
1476 product_str = "LSISAS1078 C0";
1479 product_str = "LSISAS1078 C1";
1482 product_str = "LSISAS1078 C2";
1485 product_str = "LSISAS1078";
1493 sprintf(prod_name, "%s", product_str);
1497 * mpt_mapresources - map in memory mapped io
1498 * @ioc: Pointer to pointer to IOC adapter
1502 mpt_mapresources(MPT_ADAPTER *ioc)
1506 unsigned long mem_phys;
1512 struct pci_dev *pdev;
1515 ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
1516 if (pci_enable_device_mem(pdev)) {
1517 printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() "
1518 "failed\n", ioc->name);
1521 if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) {
1522 printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with "
1523 "MEM failed\n", ioc->name);
1527 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1529 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)
1530 && !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
1531 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1532 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1534 } else if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)
1535 && !pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
1536 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1537 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1540 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1541 ioc->name, pci_name(pdev));
1542 pci_release_selected_regions(pdev, ioc->bars);
1546 mem_phys = msize = 0;
1548 for (ii = 0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1549 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1552 /* Get I/O space! */
1553 port = pci_resource_start(pdev, ii);
1554 psize = pci_resource_len(pdev, ii);
1559 mem_phys = pci_resource_start(pdev, ii);
1560 msize = pci_resource_len(pdev, ii);
1563 ioc->mem_size = msize;
1566 /* Get logical ptr for PciMem0 space */
1567 /*mem = ioremap(mem_phys, msize);*/
1568 mem = ioremap(mem_phys, msize);
1570 printk(MYIOC_s_ERR_FMT ": ERROR - Unable to map adapter"
1571 " memory!\n", ioc->name);
1575 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %lx\n",
1576 ioc->name, mem, mem_phys));
1578 ioc->mem_phys = mem_phys;
1579 ioc->chip = (SYSIF_REGS __iomem *)mem;
1581 /* Save Port IO values in case we need to do downloadboot */
1582 ioc->pio_mem_phys = port;
1583 ioc->pio_chip = (SYSIF_REGS __iomem *)port;
1588 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1590 * mpt_attach - Install a PCI intelligent MPT adapter.
1591 * @pdev: Pointer to pci_dev structure
1592 * @id: PCI device ID information
1594 * This routine performs all the steps necessary to bring the IOC of
1595 * a MPT adapter to a OPERATIONAL state. This includes registering
1596 * memory regions, registering the interrupt, and allocating request
1597 * and reply memory pools.
1599 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1602 * Returns 0 for success, non-zero for failure.
1604 * TODO: Add support for polled controllers
1607 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1614 static int mpt_ids = 0;
1615 #ifdef CONFIG_PROC_FS
1616 struct proc_dir_entry *dent, *ent;
1619 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1621 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1625 ioc->id = mpt_ids++;
1626 sprintf(ioc->name, "ioc%d", ioc->id);
1629 * set initial debug level
1630 * (refer to mptdebug.h)
1633 ioc->debug_level = mpt_debug_level;
1634 if (mpt_debug_level)
1635 printk(KERN_INFO "mpt_debug_level=%xh\n", mpt_debug_level);
1637 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name));
1640 if (mpt_mapresources(ioc)) {
1645 ioc->alloc_total = sizeof(MPT_ADAPTER);
1646 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1647 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1650 ioc->diagPending = 0;
1651 spin_lock_init(&ioc->diagLock);
1652 spin_lock_init(&ioc->initializing_hba_lock);
1654 /* Initialize the event logging.
1656 ioc->eventTypes = 0; /* None */
1657 ioc->eventContext = 0;
1658 ioc->eventLogSize = 0;
1665 ioc->cached_fw = NULL;
1667 /* Initilize SCSI Config Data structure
1669 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1671 /* Initialize the running configQ head.
1673 INIT_LIST_HEAD(&ioc->configQ);
1675 /* Initialize the fc rport list head.
1677 INIT_LIST_HEAD(&ioc->fc_rports);
1679 /* Find lookup slot. */
1680 INIT_LIST_HEAD(&ioc->list);
1683 /* Initialize workqueue */
1684 INIT_DELAYED_WORK(&ioc->fault_reset_work, mpt_fault_reset_work);
1685 spin_lock_init(&ioc->fault_reset_work_lock);
1687 snprintf(ioc->reset_work_q_name, sizeof(ioc->reset_work_q_name),
1688 "mpt_poll_%d", ioc->id);
1690 create_singlethread_workqueue(ioc->reset_work_q_name);
1691 if (!ioc->reset_work_q) {
1692 printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n",
1694 pci_release_selected_regions(pdev, ioc->bars);
1699 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",
1700 ioc->name, &ioc->facts, &ioc->pfacts[0]));
1702 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1703 mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name);
1705 switch (pdev->device)
1707 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1708 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1709 ioc->errata_flag_1064 = 1;
1710 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1711 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1712 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1713 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1717 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1718 if (revision < XL_929) {
1719 /* 929X Chip Fix. Set Split transactions level
1720 * for PCIX. Set MOST bits to zero.
1722 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1724 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1726 /* 929XL Chip Fix. Set MMRBC to 0x08.
1728 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1730 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1735 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1736 /* 919X Chip Fix. Set Split transactions level
1737 * for PCIX. Set MOST bits to zero.
1739 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1741 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1745 case MPI_MANUFACTPAGE_DEVID_53C1030:
1746 /* 1030 Chip Fix. Disable Split transactions
1747 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1749 if (revision < C0_1030) {
1750 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1752 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1755 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1756 ioc->bus_type = SPI;
1759 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1760 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1761 ioc->errata_flag_1064 = 1;
1763 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1764 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1765 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1766 ioc->bus_type = SAS;
1770 switch (ioc->bus_type) {
1773 ioc->msi_enable = mpt_msi_enable_sas;
1777 ioc->msi_enable = mpt_msi_enable_spi;
1781 ioc->msi_enable = mpt_msi_enable_fc;
1785 ioc->msi_enable = 0;
1788 if (ioc->errata_flag_1064)
1789 pci_disable_io_access(pdev);
1791 spin_lock_init(&ioc->FreeQlock);
1794 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1796 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1798 /* Set IOC ptr in the pcidev's driver data. */
1799 pci_set_drvdata(ioc->pcidev, ioc);
1801 /* Set lookup ptr. */
1802 list_add_tail(&ioc->list, &ioc_list);
1804 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1806 mpt_detect_bound_ports(ioc, pdev);
1808 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1810 printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",
1813 list_del(&ioc->list);
1815 ioc->alt_ioc->alt_ioc = NULL;
1816 iounmap(ioc->memmap);
1818 pci_release_selected_regions(pdev, ioc->bars);
1820 destroy_workqueue(ioc->reset_work_q);
1821 ioc->reset_work_q = NULL;
1824 pci_set_drvdata(pdev, NULL);
1828 /* call per device driver probe entry point */
1829 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
1830 if(MptDeviceDriverHandlers[cb_idx] &&
1831 MptDeviceDriverHandlers[cb_idx]->probe) {
1832 MptDeviceDriverHandlers[cb_idx]->probe(pdev,id);
1836 #ifdef CONFIG_PROC_FS
1838 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1840 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1842 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1844 ent->read_proc = procmpt_iocinfo_read;
1847 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1849 ent->read_proc = procmpt_summary_read;
1856 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
1857 msecs_to_jiffies(MPT_POLLING_INTERVAL));
1862 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1864 * mpt_detach - Remove a PCI intelligent MPT adapter.
1865 * @pdev: Pointer to pci_dev structure
1869 mpt_detach(struct pci_dev *pdev)
1871 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1874 unsigned long flags;
1875 struct workqueue_struct *wq;
1878 * Stop polling ioc for fault condition
1880 spin_lock_irqsave(&ioc->fault_reset_work_lock, flags);
1881 wq = ioc->reset_work_q;
1882 ioc->reset_work_q = NULL;
1883 spin_unlock_irqrestore(&ioc->fault_reset_work_lock, flags);
1884 cancel_delayed_work(&ioc->fault_reset_work);
1885 destroy_workqueue(wq);
1888 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
1889 remove_proc_entry(pname, NULL);
1890 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
1891 remove_proc_entry(pname, NULL);
1892 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
1893 remove_proc_entry(pname, NULL);
1895 /* call per device driver remove entry point */
1896 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
1897 if(MptDeviceDriverHandlers[cb_idx] &&
1898 MptDeviceDriverHandlers[cb_idx]->remove) {
1899 MptDeviceDriverHandlers[cb_idx]->remove(pdev);
1903 /* Disable interrupts! */
1904 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1907 synchronize_irq(pdev->irq);
1909 /* Clear any lingering interrupt */
1910 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1912 CHIPREG_READ32(&ioc->chip->IntStatus);
1914 mpt_adapter_dispose(ioc);
1916 pci_set_drvdata(pdev, NULL);
1919 /**************************************************************************
1923 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1925 * mpt_suspend - Fusion MPT base driver suspend routine.
1926 * @pdev: Pointer to pci_dev structure
1927 * @state: new state to enter
1930 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
1933 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1935 device_state = pci_choose_state(pdev, state);
1936 printk(MYIOC_s_INFO_FMT "pci-suspend: pdev=0x%p, slot=%s, Entering "
1937 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
1940 /* put ioc into READY_STATE */
1941 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
1942 printk(MYIOC_s_ERR_FMT
1943 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
1946 /* disable interrupts */
1947 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1950 /* Clear any lingering interrupt */
1951 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1953 free_irq(ioc->pci_irq, ioc);
1954 if (ioc->msi_enable)
1955 pci_disable_msi(ioc->pcidev);
1957 pci_save_state(pdev);
1958 pci_disable_device(pdev);
1959 pci_release_selected_regions(pdev, ioc->bars);
1960 pci_set_power_state(pdev, device_state);
1964 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1966 * mpt_resume - Fusion MPT base driver resume routine.
1967 * @pdev: Pointer to pci_dev structure
1970 mpt_resume(struct pci_dev *pdev)
1972 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1973 u32 device_state = pdev->current_state;
1977 printk(MYIOC_s_INFO_FMT "pci-resume: pdev=0x%p, slot=%s, Previous "
1978 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
1981 pci_set_power_state(pdev, PCI_D0);
1982 pci_enable_wake(pdev, PCI_D0, 0);
1983 pci_restore_state(pdev);
1985 err = mpt_mapresources(ioc);
1989 printk(MYIOC_s_INFO_FMT "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1990 ioc->name, (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1991 CHIPREG_READ32(&ioc->chip->Doorbell));
1994 * Errata workaround for SAS pci express:
1995 * Upon returning to the D0 state, the contents of the doorbell will be
1996 * stale data, and this will incorrectly signal to the host driver that
1997 * the firmware is ready to process mpt commands. The workaround is
1998 * to issue a diagnostic reset.
2000 if (ioc->bus_type == SAS && (pdev->device ==
2001 MPI_MANUFACTPAGE_DEVID_SAS1068E || pdev->device ==
2002 MPI_MANUFACTPAGE_DEVID_SAS1064E)) {
2003 if (KickStart(ioc, 1, CAN_SLEEP) < 0) {
2004 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover\n",
2010 /* bring ioc to operational state */
2011 printk(MYIOC_s_INFO_FMT "Sending mpt_do_ioc_recovery\n", ioc->name);
2012 recovery_state = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
2014 if (recovery_state != 0)
2015 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover, "
2016 "error:[%x]\n", ioc->name, recovery_state);
2018 printk(MYIOC_s_INFO_FMT
2019 "pci-resume: success\n", ioc->name);
2027 mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase)
2029 if ((MptDriverClass[index] == MPTSPI_DRIVER &&
2030 ioc->bus_type != SPI) ||
2031 (MptDriverClass[index] == MPTFC_DRIVER &&
2032 ioc->bus_type != FC) ||
2033 (MptDriverClass[index] == MPTSAS_DRIVER &&
2034 ioc->bus_type != SAS))
2035 /* make sure we only call the relevant reset handler
2038 return (MptResetHandlers[index])(ioc, reset_phase);
2041 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2043 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
2044 * @ioc: Pointer to MPT adapter structure
2045 * @reason: Event word / reason
2046 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
2048 * This routine performs all the steps necessary to bring the IOC
2049 * to a OPERATIONAL state.
2051 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
2056 * -1 if failed to get board READY
2057 * -2 if READY but IOCFacts Failed
2058 * -3 if READY but PrimeIOCFifos Failed
2059 * -4 if READY but IOCInit Failed
2060 * -5 if failed to enable_device and/or request_selected_regions
2061 * -6 if failed to upload firmware
2064 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2066 int hard_reset_done = 0;
2067 int alt_ioc_ready = 0;
2074 int reset_alt_ioc_active = 0;
2075 int irq_allocated = 0;
2078 printk(MYIOC_s_INFO_FMT "Initiating %s\n", ioc->name,
2079 reason == MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
2081 /* Disable reply interrupts (also blocks FreeQ) */
2082 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2086 if (ioc->alt_ioc->active)
2087 reset_alt_ioc_active = 1;
2089 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
2090 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
2091 ioc->alt_ioc->active = 0;
2095 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
2098 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
2099 if (hard_reset_done == -4) {
2100 printk(MYIOC_s_WARN_FMT "Owned by PEER..skipping!\n",
2103 if (reset_alt_ioc_active && ioc->alt_ioc) {
2104 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
2105 dprintk(ioc, printk(MYIOC_s_INFO_FMT
2106 "alt_ioc reply irq re-enabled\n", ioc->alt_ioc->name));
2107 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2108 ioc->alt_ioc->active = 1;
2112 printk(MYIOC_s_WARN_FMT "NOT READY!\n", ioc->name);
2117 /* hard_reset_done = 0 if a soft reset was performed
2118 * and 1 if a hard reset was performed.
2120 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
2121 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
2124 printk(MYIOC_s_WARN_FMT "alt_ioc not ready!\n", ioc->alt_ioc->name);
2127 for (ii=0; ii<5; ii++) {
2128 /* Get IOC facts! Allow 5 retries */
2129 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
2135 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2136 "Retry IocFacts failed rc=%x\n", ioc->name, rc));
2138 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2139 MptDisplayIocCapabilities(ioc);
2142 if (alt_ioc_ready) {
2143 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
2144 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2145 "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
2146 /* Retry - alt IOC was initialized once
2148 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
2151 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2152 "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
2154 reset_alt_ioc_active = 0;
2155 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2156 MptDisplayIocCapabilities(ioc->alt_ioc);
2160 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP) &&
2161 (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)) {
2162 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2163 ioc->bars = pci_select_bars(ioc->pcidev, IORESOURCE_MEM |
2165 if (pci_enable_device(ioc->pcidev))
2167 if (pci_request_selected_regions(ioc->pcidev, ioc->bars,
2173 * Device is reset now. It must have de-asserted the interrupt line
2174 * (if it was asserted) and it should be safe to register for the
2177 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2179 if (ioc->pcidev->irq) {
2180 if (ioc->msi_enable && !pci_enable_msi(ioc->pcidev))
2181 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
2184 ioc->msi_enable = 0;
2185 rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
2186 IRQF_SHARED, ioc->name, ioc);
2188 printk(MYIOC_s_ERR_FMT "Unable to allocate "
2189 "interrupt %d!\n", ioc->name, ioc->pcidev->irq);
2190 if (ioc->msi_enable)
2191 pci_disable_msi(ioc->pcidev);
2195 ioc->pci_irq = ioc->pcidev->irq;
2196 pci_set_master(ioc->pcidev); /* ?? */
2197 dprintk(ioc, printk(MYIOC_s_INFO_FMT "installed at interrupt "
2198 "%d\n", ioc->name, ioc->pcidev->irq));
2202 /* Prime reply & request queues!
2203 * (mucho alloc's) Must be done prior to
2204 * init as upper addresses are needed for init.
2205 * If fails, continue with alt-ioc processing
2207 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
2210 /* May need to check/upload firmware & data here!
2211 * If fails, continue with alt-ioc processing
2213 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
2216 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
2217 printk(MYIOC_s_WARN_FMT ": alt_ioc (%d) FIFO mgmt alloc!\n",
2218 ioc->alt_ioc->name, rc);
2220 reset_alt_ioc_active = 0;
2223 if (alt_ioc_ready) {
2224 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
2226 reset_alt_ioc_active = 0;
2227 printk(MYIOC_s_WARN_FMT "alt_ioc (%d) init failure!\n",
2228 ioc->alt_ioc->name, rc);
2232 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
2233 if (ioc->upload_fw) {
2234 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2235 "firmware upload required!\n", ioc->name));
2237 /* Controller is not operational, cannot do upload
2240 rc = mpt_do_upload(ioc, sleepFlag);
2242 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2244 * Maintain only one pointer to FW memory
2245 * so there will not be two attempt to
2246 * downloadboot onboard dual function
2247 * chips (mpt_adapter_disable,
2250 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2251 "mpt_upload: alt_%s has cached_fw=%p \n",
2252 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
2253 ioc->cached_fw = NULL;
2256 printk(MYIOC_s_WARN_FMT
2257 "firmware upload failure!\n", ioc->name);
2265 /* Enable! (reply interrupt) */
2266 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
2270 if (reset_alt_ioc_active && ioc->alt_ioc) {
2271 /* (re)Enable alt-IOC! (reply interrupt) */
2272 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "alt_ioc reply irq re-enabled\n",
2273 ioc->alt_ioc->name));
2274 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2275 ioc->alt_ioc->active = 1;
2278 /* Enable MPT base driver management of EventNotification
2279 * and EventAck handling.
2281 if ((ret == 0) && (!ioc->facts.EventState))
2282 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
2284 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2285 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
2287 /* Add additional "reason" check before call to GetLanConfigPages
2288 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2289 * recursive scenario; GetLanConfigPages times out, timer expired
2290 * routine calls HardResetHandler, which calls into here again,
2291 * and we try GetLanConfigPages again...
2293 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2296 * Initalize link list for inactive raid volumes.
2298 mutex_init(&ioc->raid_data.inactive_list_mutex);
2299 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2301 if (ioc->bus_type == SAS) {
2303 /* clear persistency table */
2304 if(ioc->facts.IOCExceptions &
2305 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
2306 ret = mptbase_sas_persist_operation(ioc,
2307 MPI_SAS_OP_CLEAR_NOT_PRESENT);
2314 mpt_findImVolumes(ioc);
2316 } else if (ioc->bus_type == FC) {
2317 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
2318 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2320 * Pre-fetch the ports LAN MAC address!
2321 * (LANPage1_t stuff)
2323 (void) GetLanConfigPages(ioc);
2324 a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2325 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2326 "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
2327 ioc->name, a[5], a[4], a[3], a[2], a[1], a[0]));
2331 /* Get NVRAM and adapter maximums from SPP 0 and 2
2333 mpt_GetScsiPortSettings(ioc, 0);
2335 /* Get version and length of SDP 1
2337 mpt_readScsiDevicePageHeaders(ioc, 0);
2341 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
2342 mpt_findImVolumes(ioc);
2344 /* Check, and possibly reset, the coalescing value
2346 mpt_read_ioc_pg_1(ioc);
2348 mpt_read_ioc_pg_4(ioc);
2351 GetIoUnitPage2(ioc);
2352 mpt_get_manufacturing_pg_0(ioc);
2356 * Call each currently registered protocol IOC reset handler
2357 * with post-reset indication.
2358 * NOTE: If we're doing _IOC_BRINGUP, there can be no
2359 * MptResetHandlers[] registered yet.
2361 if (hard_reset_done) {
2363 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
2364 if ((ret == 0) && MptResetHandlers[cb_idx]) {
2365 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2366 "Calling IOC post_reset handler #%d\n",
2367 ioc->name, cb_idx));
2368 rc += mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET);
2372 if (alt_ioc_ready && MptResetHandlers[cb_idx]) {
2373 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2374 "Calling IOC post_reset handler #%d\n",
2375 ioc->alt_ioc->name, cb_idx));
2376 rc += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_POST_RESET);
2380 /* FIXME? Examine results here? */
2384 if ((ret != 0) && irq_allocated) {
2385 free_irq(ioc->pci_irq, ioc);
2386 if (ioc->msi_enable)
2387 pci_disable_msi(ioc->pcidev);
2392 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2394 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2395 * @ioc: Pointer to MPT adapter structure
2396 * @pdev: Pointer to (struct pci_dev) structure
2398 * Search for PCI bus/dev_function which matches
2399 * PCI bus/dev_function (+/-1) for newly discovered 929,
2400 * 929X, 1030 or 1035.
2402 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2403 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2406 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
2408 struct pci_dev *peer=NULL;
2409 unsigned int slot = PCI_SLOT(pdev->devfn);
2410 unsigned int func = PCI_FUNC(pdev->devfn);
2411 MPT_ADAPTER *ioc_srch;
2413 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PCI device %s devfn=%x/%x,"
2414 " searching for devfn match on %x or %x\n",
2415 ioc->name, pci_name(pdev), pdev->bus->number,
2416 pdev->devfn, func-1, func+1));
2418 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
2420 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
2425 list_for_each_entry(ioc_srch, &ioc_list, list) {
2426 struct pci_dev *_pcidev = ioc_srch->pcidev;
2427 if (_pcidev == peer) {
2428 /* Paranoia checks */
2429 if (ioc->alt_ioc != NULL) {
2430 printk(MYIOC_s_WARN_FMT "Oops, already bound to %s!\n",
2431 ioc->name, ioc->alt_ioc->name);
2433 } else if (ioc_srch->alt_ioc != NULL) {
2434 printk(MYIOC_s_WARN_FMT "Oops, already bound to %s!\n",
2435 ioc_srch->name, ioc_srch->alt_ioc->name);
2438 dprintk(ioc, printk(MYIOC_s_INFO_FMT "FOUND! binding to %s\n",
2439 ioc->name, ioc_srch->name));
2440 ioc_srch->alt_ioc = ioc;
2441 ioc->alt_ioc = ioc_srch;
2447 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2449 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2450 * @ioc: Pointer to MPT adapter structure
2453 mpt_adapter_disable(MPT_ADAPTER *ioc)
2458 if (ioc->cached_fw != NULL) {
2459 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: Pushing FW onto "
2460 "adapter\n", __func__, ioc->name));
2461 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)
2462 ioc->cached_fw, CAN_SLEEP)) < 0) {
2463 printk(MYIOC_s_WARN_FMT
2464 ": firmware downloadboot failure (%d)!\n",
2469 /* Disable adapter interrupts! */
2470 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2472 /* Clear any lingering interrupt */
2473 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2475 if (ioc->alloc != NULL) {
2477 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "free @ %p, sz=%d bytes\n",
2478 ioc->name, ioc->alloc, ioc->alloc_sz));
2479 pci_free_consistent(ioc->pcidev, sz,
2480 ioc->alloc, ioc->alloc_dma);
2481 ioc->reply_frames = NULL;
2482 ioc->req_frames = NULL;
2484 ioc->alloc_total -= sz;
2487 if (ioc->sense_buf_pool != NULL) {
2488 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2489 pci_free_consistent(ioc->pcidev, sz,
2490 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2491 ioc->sense_buf_pool = NULL;
2492 ioc->alloc_total -= sz;
2495 if (ioc->events != NULL){
2496 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2499 ioc->alloc_total -= sz;
2502 mpt_free_fw_memory(ioc);
2504 kfree(ioc->spi_data.nvram);
2505 mpt_inactive_raid_list_free(ioc);
2506 kfree(ioc->raid_data.pIocPg2);
2507 kfree(ioc->raid_data.pIocPg3);
2508 ioc->spi_data.nvram = NULL;
2509 ioc->raid_data.pIocPg3 = NULL;
2511 if (ioc->spi_data.pIocPg4 != NULL) {
2512 sz = ioc->spi_data.IocPg4Sz;
2513 pci_free_consistent(ioc->pcidev, sz,
2514 ioc->spi_data.pIocPg4,
2515 ioc->spi_data.IocPg4_dma);
2516 ioc->spi_data.pIocPg4 = NULL;
2517 ioc->alloc_total -= sz;
2520 if (ioc->ReqToChain != NULL) {
2521 kfree(ioc->ReqToChain);
2522 kfree(ioc->RequestNB);
2523 ioc->ReqToChain = NULL;
2526 kfree(ioc->ChainToChain);
2527 ioc->ChainToChain = NULL;
2529 if (ioc->HostPageBuffer != NULL) {
2530 if((ret = mpt_host_page_access_control(ioc,
2531 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2532 printk(MYIOC_s_ERR_FMT
2533 "host page buffers free failed (%d)!\n",
2536 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "HostPageBuffer free @ %p, sz=%d bytes\n",
2537 ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
2538 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2539 ioc->HostPageBuffer, ioc->HostPageBuffer_dma);
2540 ioc->HostPageBuffer = NULL;
2541 ioc->HostPageBuffer_sz = 0;
2542 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2546 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2548 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2549 * @ioc: Pointer to MPT adapter structure
2551 * This routine unregisters h/w resources and frees all alloc'd memory
2552 * associated with a MPT adapter structure.
2555 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2557 int sz_first, sz_last;
2562 sz_first = ioc->alloc_total;
2564 mpt_adapter_disable(ioc);
2566 if (ioc->pci_irq != -1) {
2567 free_irq(ioc->pci_irq, ioc);
2568 if (ioc->msi_enable)
2569 pci_disable_msi(ioc->pcidev);
2573 if (ioc->memmap != NULL) {
2574 iounmap(ioc->memmap);
2578 pci_disable_device(ioc->pcidev);
2579 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2581 #if defined(CONFIG_MTRR) && 0
2582 if (ioc->mtrr_reg > 0) {
2583 mtrr_del(ioc->mtrr_reg, 0, 0);
2584 dprintk(ioc, printk(MYIOC_s_INFO_FMT "MTRR region de-registered\n", ioc->name));
2588 /* Zap the adapter lookup ptr! */
2589 list_del(&ioc->list);
2591 sz_last = ioc->alloc_total;
2592 dprintk(ioc, printk(MYIOC_s_INFO_FMT "free'd %d of %d bytes\n",
2593 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2596 ioc->alt_ioc->alt_ioc = NULL;
2601 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2603 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2604 * @ioc: Pointer to MPT adapter structure
2607 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2611 printk(KERN_INFO "%s: ", ioc->name);
2613 printk("%s: ", ioc->prod_name);
2614 printk("Capabilities={");
2616 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2617 printk("Initiator");
2621 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2622 printk("%sTarget", i ? "," : "");
2626 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2627 printk("%sLAN", i ? "," : "");
2633 * This would probably evoke more questions than it's worth
2635 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2636 printk("%sLogBusAddr", i ? "," : "");
2644 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2646 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2647 * @ioc: Pointer to MPT_ADAPTER structure
2648 * @force: Force hard KickStart of IOC
2649 * @sleepFlag: Specifies whether the process can sleep
2652 * 1 - DIAG reset and READY
2653 * 0 - READY initially OR soft reset and READY
2654 * -1 - Any failure on KickStart
2655 * -2 - Msg Unit Reset Failed
2656 * -3 - IO Unit Reset Failed
2657 * -4 - IOC owned by a PEER
2660 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2665 int hard_reset_done = 0;
2670 /* Get current [raw] IOC state */
2671 ioc_state = mpt_GetIocState(ioc, 0);
2672 dhsprintk(ioc, printk(MYIOC_s_INFO_FMT "MakeIocReady [raw] state=%08x\n", ioc->name, ioc_state));
2675 * Check to see if IOC got left/stuck in doorbell handshake
2676 * grip of death. If so, hard reset the IOC.
2678 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2680 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2684 /* Is it already READY? */
2685 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
2689 * Check to see if IOC is in FAULT state.
2691 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2693 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2695 printk(MYIOC_s_WARN_FMT " FAULT code = %04xh\n",
2696 ioc->name, ioc_state & MPI_DOORBELL_DATA_MASK);
2700 * Hmmm... Did it get left operational?
2702 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2703 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC operational unexpected\n",
2707 * If PCI Peer, exit.
2708 * Else, if no fault conditions are present, issue a MessageUnitReset
2709 * Else, fall through to KickStart case
2711 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2712 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2713 "whoinit 0x%x statefault %d force %d\n",
2714 ioc->name, whoinit, statefault, force));
2715 if (whoinit == MPI_WHOINIT_PCI_PEER)
2718 if ((statefault == 0 ) && (force == 0)) {
2719 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2726 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2727 if (hard_reset_done < 0)
2731 * Loop here waiting for IOC to come READY.
2734 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2736 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2737 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2739 * BIOS or previous driver load left IOC in OP state.
2740 * Reset messaging FIFOs.
2742 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2743 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2746 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2748 * Something is wrong. Try to get IOC back
2751 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2752 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2759 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2760 ioc->name, (int)((ii+5)/HZ));
2764 if (sleepFlag == CAN_SLEEP) {
2767 mdelay (1); /* 1 msec delay */
2772 if (statefault < 3) {
2773 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2775 statefault==1 ? "stuck handshake" : "IOC FAULT");
2778 return hard_reset_done;
2781 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2783 * mpt_GetIocState - Get the current state of a MPT adapter.
2784 * @ioc: Pointer to MPT_ADAPTER structure
2785 * @cooked: Request raw or cooked IOC state
2787 * Returns all IOC Doorbell register bits if cooked==0, else just the
2788 * Doorbell bits in MPI_IOC_STATE_MASK.
2791 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2796 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2797 sc = s & MPI_IOC_STATE_MASK;
2800 ioc->last_state = sc;
2802 return cooked ? sc : s;
2805 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2807 * GetIocFacts - Send IOCFacts request to MPT adapter.
2808 * @ioc: Pointer to MPT_ADAPTER structure
2809 * @sleepFlag: Specifies whether the process can sleep
2810 * @reason: If recovery, only update facts.
2812 * Returns 0 for success, non-zero for failure.
2815 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2817 IOCFacts_t get_facts;
2818 IOCFactsReply_t *facts;
2826 /* IOC *must* NOT be in RESET state! */
2827 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2828 printk(MYIOC_s_ERR_FMT "Can't get IOCFacts NOT READY! (%08x)\n",
2829 ioc->name, ioc->last_state );
2833 facts = &ioc->facts;
2835 /* Destination (reply area)... */
2836 reply_sz = sizeof(*facts);
2837 memset(facts, 0, reply_sz);
2839 /* Request area (get_facts on the stack right now!) */
2840 req_sz = sizeof(get_facts);
2841 memset(&get_facts, 0, req_sz);
2843 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2844 /* Assert: All other get_facts fields are zero! */
2846 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2847 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2848 ioc->name, req_sz, reply_sz));
2850 /* No non-zero fields in the get_facts request are greater than
2851 * 1 byte in size, so we can just fire it off as is.
2853 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2854 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2859 * Now byte swap (GRRR) the necessary fields before any further
2860 * inspection of reply contents.
2862 * But need to do some sanity checks on MsgLength (byte) field
2863 * to make sure we don't zero IOC's req_sz!
2865 /* Did we get a valid reply? */
2866 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2867 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2869 * If not been here, done that, save off first WhoInit value
2871 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2872 ioc->FirstWhoInit = facts->WhoInit;
2875 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2876 facts->MsgContext = le32_to_cpu(facts->MsgContext);
2877 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2878 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2879 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2880 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
2881 /* CHECKME! IOCStatus, IOCLogInfo */
2883 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2884 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2887 * FC f/w version changed between 1.1 and 1.2
2888 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2889 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2891 if (facts->MsgVersion < 0x0102) {
2893 * Handle old FC f/w style, convert to new...
2895 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2896 facts->FWVersion.Word =
2897 ((oldv<<12) & 0xFF000000) |
2898 ((oldv<<8) & 0x000FFF00);
2900 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2902 facts->ProductID = le16_to_cpu(facts->ProductID);
2903 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
2904 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
2905 ioc->ir_firmware = 1;
2906 facts->CurrentHostMfaHighAddr =
2907 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2908 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2909 facts->CurrentSenseBufferHighAddr =
2910 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2911 facts->CurReplyFrameSize =
2912 le16_to_cpu(facts->CurReplyFrameSize);
2913 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
2916 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2917 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2918 * to 14 in MPI-1.01.0x.
2920 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2921 facts->MsgVersion > 0x0100) {
2922 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2925 sz = facts->FWImageSize;
2930 facts->FWImageSize = sz;
2932 if (!facts->RequestFrameSize) {
2933 /* Something is wrong! */
2934 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2939 r = sz = facts->BlockSize;
2940 vv = ((63 / (sz * 4)) + 1) & 0x03;
2941 ioc->NB_for_64_byte_frame = vv;
2947 ioc->NBShiftFactor = shiftFactor;
2948 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2949 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2950 ioc->name, vv, shiftFactor, r));
2952 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2954 * Set values for this IOC's request & reply frame sizes,
2955 * and request & reply queue depths...
2957 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2958 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2959 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2960 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2962 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "reply_sz=%3d, reply_depth=%4d\n",
2963 ioc->name, ioc->reply_sz, ioc->reply_depth));
2964 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "req_sz =%3d, req_depth =%4d\n",
2965 ioc->name, ioc->req_sz, ioc->req_depth));
2967 /* Get port facts! */
2968 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2972 printk(MYIOC_s_ERR_FMT
2973 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2974 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2975 RequestFrameSize)/sizeof(u32)));
2982 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2984 * GetPortFacts - Send PortFacts request to MPT adapter.
2985 * @ioc: Pointer to MPT_ADAPTER structure
2986 * @portnum: Port number
2987 * @sleepFlag: Specifies whether the process can sleep
2989 * Returns 0 for success, non-zero for failure.
2992 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2994 PortFacts_t get_pfacts;
2995 PortFactsReply_t *pfacts;
3001 /* IOC *must* NOT be in RESET state! */
3002 if (ioc->last_state == MPI_IOC_STATE_RESET) {
3003 printk(MYIOC_s_ERR_FMT "Can't get PortFacts NOT READY! (%08x)\n",
3004 ioc->name, ioc->last_state );
3008 pfacts = &ioc->pfacts[portnum];
3010 /* Destination (reply area)... */
3011 reply_sz = sizeof(*pfacts);
3012 memset(pfacts, 0, reply_sz);
3014 /* Request area (get_pfacts on the stack right now!) */
3015 req_sz = sizeof(get_pfacts);
3016 memset(&get_pfacts, 0, req_sz);
3018 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
3019 get_pfacts.PortNumber = portnum;
3020 /* Assert: All other get_pfacts fields are zero! */
3022 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending get PortFacts(%d) request\n",
3023 ioc->name, portnum));
3025 /* No non-zero fields in the get_pfacts request are greater than
3026 * 1 byte in size, so we can just fire it off as is.
3028 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
3029 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
3033 /* Did we get a valid reply? */
3035 /* Now byte swap the necessary fields in the response. */
3036 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
3037 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
3038 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
3039 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
3040 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
3041 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
3042 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
3043 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
3044 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
3046 max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
3048 ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
3049 ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
3052 * Place all the devices on channels
3056 if (mpt_channel_mapping) {
3057 ioc->devices_per_bus = 1;
3058 ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
3064 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3066 * SendIocInit - Send IOCInit request to MPT adapter.
3067 * @ioc: Pointer to MPT_ADAPTER structure
3068 * @sleepFlag: Specifies whether the process can sleep
3070 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
3072 * Returns 0 for success, non-zero for failure.
3075 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
3078 MPIDefaultReply_t init_reply;
3084 memset(&ioc_init, 0, sizeof(ioc_init));
3085 memset(&init_reply, 0, sizeof(init_reply));
3087 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
3088 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
3090 /* If we are in a recovery mode and we uploaded the FW image,
3091 * then this pointer is not NULL. Skip the upload a second time.
3092 * Set this flag if cached_fw set for either IOC.
3094 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
3098 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "upload_fw %d facts.Flags=%x\n",
3099 ioc->name, ioc->upload_fw, ioc->facts.Flags));
3101 ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
3102 ioc_init.MaxBuses = (U8)ioc->number_of_buses;
3103 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n",
3104 ioc->name, ioc->facts.MsgVersion));
3105 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
3106 // set MsgVersion and HeaderVersion host driver was built with
3107 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
3108 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
3110 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
3111 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
3112 } else if(mpt_host_page_alloc(ioc, &ioc_init))
3115 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
3117 if (sizeof(dma_addr_t) == sizeof(u64)) {
3118 /* Save the upper 32-bits of the request
3119 * (reply) and sense buffers.
3121 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
3122 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
3124 /* Force 32-bit addressing */
3125 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
3126 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
3129 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
3130 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
3131 ioc->facts.MaxDevices = ioc_init.MaxDevices;
3132 ioc->facts.MaxBuses = ioc_init.MaxBuses;
3134 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOCInit (req @ %p)\n",
3135 ioc->name, &ioc_init));
3137 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
3138 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
3140 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
3144 /* No need to byte swap the multibyte fields in the reply
3145 * since we don't even look at its contents.
3148 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending PortEnable (req @ %p)\n",
3149 ioc->name, &ioc_init));
3151 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
3152 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
3156 /* YIKES! SUPER IMPORTANT!!!
3157 * Poll IocState until _OPERATIONAL while IOC is doing
3158 * LoopInit and TargetDiscovery!
3161 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
3162 state = mpt_GetIocState(ioc, 1);
3163 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
3164 if (sleepFlag == CAN_SLEEP) {
3171 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
3172 ioc->name, (int)((count+5)/HZ));
3176 state = mpt_GetIocState(ioc, 1);
3179 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wait IOC_OPERATIONAL state (cnt=%d)\n",
3182 ioc->aen_event_read_flag=0;
3186 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3188 * SendPortEnable - Send PortEnable request to MPT adapter port.
3189 * @ioc: Pointer to MPT_ADAPTER structure
3190 * @portnum: Port number to enable
3191 * @sleepFlag: Specifies whether the process can sleep
3193 * Send PortEnable to bring IOC to OPERATIONAL state.
3195 * Returns 0 for success, non-zero for failure.
3198 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3200 PortEnable_t port_enable;
3201 MPIDefaultReply_t reply_buf;
3206 /* Destination... */
3207 reply_sz = sizeof(MPIDefaultReply_t);
3208 memset(&reply_buf, 0, reply_sz);
3210 req_sz = sizeof(PortEnable_t);
3211 memset(&port_enable, 0, req_sz);
3213 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
3214 port_enable.PortNumber = portnum;
3215 /* port_enable.ChainOffset = 0; */
3216 /* port_enable.MsgFlags = 0; */
3217 /* port_enable.MsgContext = 0; */
3219 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Port(%d)Enable (req @ %p)\n",
3220 ioc->name, portnum, &port_enable));
3222 /* RAID FW may take a long time to enable
3224 if (ioc->ir_firmware || ioc->bus_type == SAS) {
3225 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3226 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3227 300 /*seconds*/, sleepFlag);
3229 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3230 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3231 30 /*seconds*/, sleepFlag);
3237 * mpt_alloc_fw_memory - allocate firmware memory
3238 * @ioc: Pointer to MPT_ADAPTER structure
3239 * @size: total FW bytes
3241 * If memory has already been allocated, the same (cached) value
3244 * Return 0 if successfull, or non-zero for failure
3247 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
3251 if (ioc->cached_fw) {
3252 rc = 0; /* use already allocated memory */
3255 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
3256 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
3257 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
3261 ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma);
3262 if (!ioc->cached_fw) {
3263 printk(MYIOC_s_ERR_FMT "Unable to allocate memory for the cached firmware image!\n",
3267 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Image @ %p[%p], sz=%d[%x] bytes\n",
3268 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, size, size));
3269 ioc->alloc_total += size;
3277 * mpt_free_fw_memory - free firmware memory
3278 * @ioc: Pointer to MPT_ADAPTER structure
3280 * If alt_img is NULL, delete from ioc structure.
3281 * Else, delete a secondary image in same format.
3284 mpt_free_fw_memory(MPT_ADAPTER *ioc)
3288 if (!ioc->cached_fw)
3291 sz = ioc->facts.FWImageSize;
3292 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3293 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3294 pci_free_consistent(ioc->pcidev, sz, ioc->cached_fw, ioc->cached_fw_dma);
3295 ioc->alloc_total -= sz;
3296 ioc->cached_fw = NULL;
3299 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3301 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3302 * @ioc: Pointer to MPT_ADAPTER structure
3303 * @sleepFlag: Specifies whether the process can sleep
3305 * Returns 0 for success, >0 for handshake failure
3306 * <0 for fw upload failure.
3308 * Remark: If bound IOC and a successful FWUpload was performed
3309 * on the bound IOC, the second image is discarded
3310 * and memory is free'd. Both channels must upload to prevent
3311 * IOC from running in degraded mode.
3314 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3316 u8 reply[sizeof(FWUploadReply_t)];
3317 FWUpload_t *prequest;
3318 FWUploadReply_t *preply;
3319 FWUploadTCSGE_t *ptcsge;
3322 int ii, sz, reply_sz;
3325 /* If the image size is 0, we are done.
3327 if ((sz = ioc->facts.FWImageSize) == 0)
3330 if (mpt_alloc_fw_memory(ioc, ioc->facts.FWImageSize) != 0)
3333 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3334 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3336 prequest = (sleepFlag == NO_SLEEP) ? kzalloc(ioc->req_sz, GFP_ATOMIC) :
3337 kzalloc(ioc->req_sz, GFP_KERNEL);
3339 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed "
3340 "while allocating memory \n", ioc->name));
3341 mpt_free_fw_memory(ioc);
3345 preply = (FWUploadReply_t *)&reply;
3347 reply_sz = sizeof(reply);
3348 memset(preply, 0, reply_sz);
3350 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
3351 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
3353 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
3354 ptcsge->DetailsLength = 12;
3355 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
3356 ptcsge->ImageSize = cpu_to_le32(sz);
3359 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
3361 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3362 mpt_add_sge((char *)ptcsge, flagsLength, ioc->cached_fw_dma);
3364 sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
3365 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": Sending FW Upload (req @ %p) sgeoffset=%d \n",
3366 ioc->name, prequest, sgeoffset));
3367 DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest);
3369 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
3370 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
3372 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Upload completed rc=%x \n", ioc->name, ii));
3374 cmdStatus = -EFAULT;
3376 /* Handshake transfer was complete and successful.
3377 * Check the Reply Frame.
3379 int status, transfer_sz;
3380 status = le16_to_cpu(preply->IOCStatus);
3381 if (status == MPI_IOCSTATUS_SUCCESS) {
3382 transfer_sz = le32_to_cpu(preply->ActualImageSize);
3383 if (transfer_sz == sz)
3387 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n",
3388 ioc->name, cmdStatus));
3393 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": fw upload failed, freeing image \n",
3395 mpt_free_fw_memory(ioc);
3402 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3404 * mpt_downloadboot - DownloadBoot code
3405 * @ioc: Pointer to MPT_ADAPTER structure
3406 * @pFwHeader: Pointer to firmware header info
3407 * @sleepFlag: Specifies whether the process can sleep
3409 * FwDownloadBoot requires Programmed IO access.
3411 * Returns 0 for success
3412 * -1 FW Image size is 0
3413 * -2 No valid cached_fw Pointer
3414 * <0 for fw upload failure.
3417 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3419 MpiExtImageHeader_t *pExtImage;
3429 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3430 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
3432 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3433 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3434 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3435 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3436 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3437 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3439 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
3442 if (sleepFlag == CAN_SLEEP) {
3448 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3449 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3451 for (count = 0; count < 30; count ++) {
3452 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3453 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3454 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESET_ADAPTER cleared, count=%d\n",
3459 if (sleepFlag == CAN_SLEEP) {
3466 if ( count == 30 ) {
3467 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot failed! "
3468 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3469 ioc->name, diag0val));
3473 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3474 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3475 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3476 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3477 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3478 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3480 /* Set the DiagRwEn and Disable ARM bits */
3481 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3483 fwSize = (pFwHeader->ImageSize + 3)/4;
3484 ptrFw = (u32 *) pFwHeader;
3486 /* Write the LoadStartAddress to the DiagRw Address Register
3487 * using Programmed IO
3489 if (ioc->errata_flag_1064)
3490 pci_enable_io_access(ioc->pcidev);
3492 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3493 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "LoadStart addr written 0x%x \n",
3494 ioc->name, pFwHeader->LoadStartAddress));
3496 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write FW Image: 0x%x bytes @ %p\n",
3497 ioc->name, fwSize*4, ptrFw));
3499 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3502 nextImage = pFwHeader->NextImageHeaderOffset;
3504 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3506 load_addr = pExtImage->LoadStartAddress;
3508 fwSize = (pExtImage->ImageSize + 3) >> 2;
3509 ptrFw = (u32 *)pExtImage;
3511 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3512 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3513 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3516 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3518 nextImage = pExtImage->NextImageHeaderOffset;
3521 /* Write the IopResetVectorRegAddr */
3522 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
3523 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3525 /* Write the IopResetVectorValue */
3526 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3527 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3529 /* Clear the internal flash bad bit - autoincrementing register,
3530 * so must do two writes.
3532 if (ioc->bus_type == SPI) {
3534 * 1030 and 1035 H/W errata, workaround to access
3535 * the ClearFlashBadSignatureBit
3537 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3538 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3539 diagRwData |= 0x40000000;
3540 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3541 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3543 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3544 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3545 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3546 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3549 if (sleepFlag == CAN_SLEEP) {
3556 if (ioc->errata_flag_1064)
3557 pci_disable_io_access(ioc->pcidev);
3559 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3560 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot diag0val=%x, "
3561 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3562 ioc->name, diag0val));
3563 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3564 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot now diag0val=%x\n",
3565 ioc->name, diag0val));
3566 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3568 /* Write 0xFF to reset the sequencer */
3569 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3571 if (ioc->bus_type == SAS) {
3572 ioc_state = mpt_GetIocState(ioc, 0);
3573 if ( (GetIocFacts(ioc, sleepFlag,
3574 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3575 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "GetIocFacts failed: IocState=%x\n",
3576 ioc->name, ioc_state));
3581 for (count=0; count<HZ*20; count++) {
3582 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3583 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3584 "downloadboot successful! (count=%d) IocState=%x\n",
3585 ioc->name, count, ioc_state));
3586 if (ioc->bus_type == SAS) {
3589 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3590 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3591 "downloadboot: SendIocInit failed\n",
3595 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3596 "downloadboot: SendIocInit successful\n",
3600 if (sleepFlag == CAN_SLEEP) {
3606 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3607 "downloadboot failed! IocState=%x\n",ioc->name, ioc_state));
3611 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3613 * KickStart - Perform hard reset of MPT adapter.
3614 * @ioc: Pointer to MPT_ADAPTER structure
3615 * @force: Force hard reset
3616 * @sleepFlag: Specifies whether the process can sleep
3618 * This routine places MPT adapter in diagnostic mode via the
3619 * WriteSequence register, and then performs a hard reset of adapter
3620 * via the Diagnostic register.
3622 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3623 * or NO_SLEEP (interrupt thread, use mdelay)
3624 * force - 1 if doorbell active, board fault state
3625 * board operational, IOC_RECOVERY or
3626 * IOC_BRINGUP and there is an alt_ioc.
3630 * 1 - hard reset, READY
3631 * 0 - no reset due to History bit, READY
3632 * -1 - no reset due to History bit but not READY
3633 * OR reset but failed to come READY
3634 * -2 - no reset, could not enter DIAG mode
3635 * -3 - reset but bad FW bit
3638 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3640 int hard_reset_done = 0;
3644 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStarting!\n", ioc->name));
3645 if (ioc->bus_type == SPI) {
3646 /* Always issue a Msg Unit Reset first. This will clear some
3647 * SCSI bus hang conditions.
3649 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3651 if (sleepFlag == CAN_SLEEP) {
3658 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3659 if (hard_reset_done < 0)
3660 return hard_reset_done;
3662 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n",
3665 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3666 for (cnt=0; cnt<cntdn; cnt++) {
3667 ioc_state = mpt_GetIocState(ioc, 1);
3668 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3669 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStart successful! (cnt=%d)\n",
3671 return hard_reset_done;
3673 if (sleepFlag == CAN_SLEEP) {
3680 dinitprintk(ioc, printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3681 ioc->name, mpt_GetIocState(ioc, 0)));
3685 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3687 * mpt_diag_reset - Perform hard reset of the adapter.
3688 * @ioc: Pointer to MPT_ADAPTER structure
3689 * @ignore: Set if to honor and clear to ignore
3690 * the reset history bit
3691 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3692 * else set to NO_SLEEP (use mdelay instead)
3694 * This routine places the adapter in diagnostic mode via the
3695 * WriteSequence register and then performs a hard reset of adapter
3696 * via the Diagnostic register. Adapter should be in ready state
3697 * upon successful completion.
3699 * Returns: 1 hard reset successful
3700 * 0 no reset performed because reset history bit set
3701 * -2 enabling diagnostic mode failed
3702 * -3 diagnostic reset failed
3705 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3709 int hard_reset_done = 0;
3712 MpiFwHeader_t *cached_fw; /* Pointer to FW */
3714 /* Clear any existing interrupts */
3715 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3717 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3718 drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3719 "address=%p\n", ioc->name, __func__,
3720 &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3721 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3722 if (sleepFlag == CAN_SLEEP)
3727 for (count = 0; count < 60; count ++) {
3728 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3729 doorbell &= MPI_IOC_STATE_MASK;
3731 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3732 "looking for READY STATE: doorbell=%x"
3734 ioc->name, doorbell, count));
3735 if (doorbell == MPI_IOC_STATE_READY) {
3740 if (sleepFlag == CAN_SLEEP)
3748 /* Use "Diagnostic reset" method! (only thing available!) */
3749 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3751 if (ioc->debug_level & MPT_DEBUG) {
3753 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3754 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3755 ioc->name, diag0val, diag1val));
3758 /* Do the reset if we are told to ignore the reset history
3759 * or if the reset history is 0
3761 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3762 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3763 /* Write magic sequence to WriteSequence register
3764 * Loop until in diagnostic mode
3766 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3767 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3768 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3769 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3770 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3771 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3774 if (sleepFlag == CAN_SLEEP) {
3782 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3783 ioc->name, diag0val);
3788 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3790 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3791 ioc->name, diag0val));
3794 if (ioc->debug_level & MPT_DEBUG) {
3796 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3797 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3798 ioc->name, diag0val, diag1val));
3801 * Disable the ARM (Bug fix)
3804 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3808 * Now hit the reset bit in the Diagnostic register
3809 * (THE BIG HAMMER!) (Clears DRWE bit).
3811 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3812 hard_reset_done = 1;
3813 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset performed\n",
3817 * Call each currently registered protocol IOC reset handler
3818 * with pre-reset indication.
3819 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3820 * MptResetHandlers[] registered yet.
3826 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
3827 if (MptResetHandlers[cb_idx]) {
3828 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3829 "Calling IOC pre_reset handler #%d\n",
3830 ioc->name, cb_idx));
3831 r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET);
3833 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3834 "Calling alt-%s pre_reset handler #%d\n",
3835 ioc->name, ioc->alt_ioc->name, cb_idx));
3836 r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_PRE_RESET);
3840 /* FIXME? Examine results here? */
3844 cached_fw = (MpiFwHeader_t *)ioc->cached_fw;
3845 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
3846 cached_fw = (MpiFwHeader_t *)ioc->alt_ioc->cached_fw;
3850 /* If the DownloadBoot operation fails, the
3851 * IOC will be left unusable. This is a fatal error
3852 * case. _diag_reset will return < 0
3854 for (count = 0; count < 30; count ++) {
3855 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3856 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3860 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n",
3861 ioc->name, diag0val, count));
3863 if (sleepFlag == CAN_SLEEP) {
3869 if ((count = mpt_downloadboot(ioc, cached_fw, sleepFlag)) < 0) {
3870 printk(MYIOC_s_WARN_FMT
3871 "firmware downloadboot failure (%d)!\n", ioc->name, count);
3875 /* Wait for FW to reload and for board
3876 * to go to the READY state.
3877 * Maximum wait is 60 seconds.
3878 * If fail, no error will check again
3879 * with calling program.
3881 for (count = 0; count < 60; count ++) {
3882 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3883 doorbell &= MPI_IOC_STATE_MASK;
3885 if (doorbell == MPI_IOC_STATE_READY) {
3890 if (sleepFlag == CAN_SLEEP) {
3899 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3900 if (ioc->debug_level & MPT_DEBUG) {
3902 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3903 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3904 ioc->name, diag0val, diag1val));
3907 /* Clear RESET_HISTORY bit! Place board in the
3908 * diagnostic mode to update the diag register.
3910 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3912 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3913 /* Write magic sequence to WriteSequence register
3914 * Loop until in diagnostic mode
3916 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3917 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3918 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3919 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3920 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3921 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3924 if (sleepFlag == CAN_SLEEP) {
3932 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3933 ioc->name, diag0val);
3936 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3938 diag0val &= ~MPI_DIAG_RESET_HISTORY;
3939 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3940 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3941 if (diag0val & MPI_DIAG_RESET_HISTORY) {
3942 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3946 /* Disable Diagnostic Mode
3948 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3950 /* Check FW reload status flags.
3952 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3953 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3954 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3955 ioc->name, diag0val);
3959 if (ioc->debug_level & MPT_DEBUG) {
3961 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3962 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3963 ioc->name, diag0val, diag1val));
3967 * Reset flag that says we've enabled event notification
3969 ioc->facts.EventState = 0;
3972 ioc->alt_ioc->facts.EventState = 0;
3974 return hard_reset_done;
3977 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3979 * SendIocReset - Send IOCReset request to MPT adapter.
3980 * @ioc: Pointer to MPT_ADAPTER structure
3981 * @reset_type: reset type, expected values are
3982 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3983 * @sleepFlag: Specifies whether the process can sleep
3985 * Send IOCReset request to the MPT adapter.
3987 * Returns 0 for success, non-zero for failure.
3990 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3996 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOC reset(0x%02x)!\n",
3997 ioc->name, reset_type));
3998 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3999 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4002 /* FW ACK'd request, wait for READY state
4005 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
4007 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
4011 if (sleepFlag != CAN_SLEEP)
4014 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
4015 ioc->name, (int)((count+5)/HZ));
4019 if (sleepFlag == CAN_SLEEP) {
4022 mdelay (1); /* 1 msec delay */
4027 * Cleanup all event stuff for this IOC; re-issue EventNotification
4028 * request if needed.
4030 if (ioc->facts.Function)
4031 ioc->facts.EventState = 0;
4036 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4038 * initChainBuffers - Allocate memory for and initialize chain buffers
4039 * @ioc: Pointer to MPT_ADAPTER structure
4041 * Allocates memory for and initializes chain buffers,
4042 * chain buffer control arrays and spinlock.
4045 initChainBuffers(MPT_ADAPTER *ioc)
4048 int sz, ii, num_chain;
4049 int scale, num_sge, numSGE;
4051 /* ReqToChain size must equal the req_depth
4054 if (ioc->ReqToChain == NULL) {
4055 sz = ioc->req_depth * sizeof(int);
4056 mem = kmalloc(sz, GFP_ATOMIC);
4060 ioc->ReqToChain = (int *) mem;
4061 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReqToChain alloc @ %p, sz=%d bytes\n",
4062 ioc->name, mem, sz));
4063 mem = kmalloc(sz, GFP_ATOMIC);
4067 ioc->RequestNB = (int *) mem;
4068 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestNB alloc @ %p, sz=%d bytes\n",
4069 ioc->name, mem, sz));
4071 for (ii = 0; ii < ioc->req_depth; ii++) {
4072 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
4075 /* ChainToChain size must equal the total number
4076 * of chain buffers to be allocated.
4079 * Calculate the number of chain buffers needed(plus 1) per I/O
4080 * then multiply the maximum number of simultaneous cmds
4082 * num_sge = num sge in request frame + last chain buffer
4083 * scale = num sge per chain buffer if no chain element
4085 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
4086 if (sizeof(dma_addr_t) == sizeof(u64))
4087 num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
4089 num_sge = 1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
4091 if (sizeof(dma_addr_t) == sizeof(u64)) {
4092 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
4093 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
4095 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
4096 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
4098 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n",
4099 ioc->name, num_sge, numSGE));
4101 if ( numSGE > MPT_SCSI_SG_DEPTH )
4102 numSGE = MPT_SCSI_SG_DEPTH;
4105 while (numSGE - num_sge > 0) {
4107 num_sge += (scale - 1);
4111 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Now numSGE=%d num_sge=%d num_chain=%d\n",
4112 ioc->name, numSGE, num_sge, num_chain));
4114 if (ioc->bus_type == SPI)
4115 num_chain *= MPT_SCSI_CAN_QUEUE;
4117 num_chain *= MPT_FC_CAN_QUEUE;
4119 ioc->num_chain = num_chain;
4121 sz = num_chain * sizeof(int);
4122 if (ioc->ChainToChain == NULL) {
4123 mem = kmalloc(sz, GFP_ATOMIC);
4127 ioc->ChainToChain = (int *) mem;
4128 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainToChain alloc @ %p, sz=%d bytes\n",
4129 ioc->name, mem, sz));
4131 mem = (u8 *) ioc->ChainToChain;
4133 memset(mem, 0xFF, sz);
4137 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4139 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
4140 * @ioc: Pointer to MPT_ADAPTER structure
4142 * This routine allocates memory for the MPT reply and request frame
4143 * pools (if necessary), and primes the IOC reply FIFO with
4146 * Returns 0 for success, non-zero for failure.
4149 PrimeIocFifos(MPT_ADAPTER *ioc)
4152 unsigned long flags;
4153 dma_addr_t alloc_dma;
4155 int i, reply_sz, sz, total_size, num_chain;
4157 /* Prime reply FIFO... */
4159 if (ioc->reply_frames == NULL) {
4160 if ( (num_chain = initChainBuffers(ioc)) < 0)
4163 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
4164 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
4165 ioc->name, ioc->reply_sz, ioc->reply_depth));
4166 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d[%x] bytes\n",
4167 ioc->name, reply_sz, reply_sz));
4169 sz = (ioc->req_sz * ioc->req_depth);
4170 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d bytes, RequestDepth=%d\n",
4171 ioc->name, ioc->req_sz, ioc->req_depth));
4172 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d[%x] bytes\n",
4173 ioc->name, sz, sz));
4176 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
4177 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d bytes, ChainDepth=%d\n",
4178 ioc->name, ioc->req_sz, num_chain));
4179 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
4180 ioc->name, sz, sz, num_chain));
4183 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
4185 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
4190 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Total alloc @ %p[%p], sz=%d[%x] bytes\n",
4191 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
4193 memset(mem, 0, total_size);
4194 ioc->alloc_total += total_size;
4196 ioc->alloc_dma = alloc_dma;
4197 ioc->alloc_sz = total_size;
4198 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
4199 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4201 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4202 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4204 alloc_dma += reply_sz;
4207 /* Request FIFO - WE manage this! */
4209 ioc->req_frames = (MPT_FRAME_HDR *) mem;
4210 ioc->req_frames_dma = alloc_dma;
4212 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffers @ %p[%p]\n",
4213 ioc->name, mem, (void *)(ulong)alloc_dma));
4215 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4217 #if defined(CONFIG_MTRR) && 0
4219 * Enable Write Combining MTRR for IOC's memory region.
4220 * (at least as much as we can; "size and base must be
4221 * multiples of 4 kiB"
4223 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
4225 MTRR_TYPE_WRCOMB, 1);
4226 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MTRR region registered (base:size=%08x:%x)\n",
4227 ioc->name, ioc->req_frames_dma, sz));
4230 for (i = 0; i < ioc->req_depth; i++) {
4231 alloc_dma += ioc->req_sz;
4235 ioc->ChainBuffer = mem;
4236 ioc->ChainBufferDMA = alloc_dma;
4238 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffers @ %p(%p)\n",
4239 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
4241 /* Initialize the free chain Q.
4244 INIT_LIST_HEAD(&ioc->FreeChainQ);
4246 /* Post the chain buffers to the FreeChainQ.
4248 mem = (u8 *)ioc->ChainBuffer;
4249 for (i=0; i < num_chain; i++) {
4250 mf = (MPT_FRAME_HDR *) mem;
4251 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
4255 /* Initialize Request frames linked list
4257 alloc_dma = ioc->req_frames_dma;
4258 mem = (u8 *) ioc->req_frames;
4260 spin_lock_irqsave(&ioc->FreeQlock, flags);
4261 INIT_LIST_HEAD(&ioc->FreeQ);
4262 for (i = 0; i < ioc->req_depth; i++) {
4263 mf = (MPT_FRAME_HDR *) mem;
4265 /* Queue REQUESTs *internally*! */
4266 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
4270 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4272 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4273 ioc->sense_buf_pool =
4274 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
4275 if (ioc->sense_buf_pool == NULL) {
4276 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
4281 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
4282 ioc->alloc_total += sz;
4283 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SenseBuffers @ %p[%p]\n",
4284 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
4288 /* Post Reply frames to FIFO
4290 alloc_dma = ioc->alloc_dma;
4291 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4292 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4294 for (i = 0; i < ioc->reply_depth; i++) {
4295 /* Write each address to the IOC! */
4296 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
4297 alloc_dma += ioc->reply_sz;
4303 if (ioc->alloc != NULL) {
4305 pci_free_consistent(ioc->pcidev,
4307 ioc->alloc, ioc->alloc_dma);
4308 ioc->reply_frames = NULL;
4309 ioc->req_frames = NULL;
4310 ioc->alloc_total -= sz;
4312 if (ioc->sense_buf_pool != NULL) {
4313 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4314 pci_free_consistent(ioc->pcidev,
4316 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
4317 ioc->sense_buf_pool = NULL;
4322 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4324 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4325 * from IOC via doorbell handshake method.
4326 * @ioc: Pointer to MPT_ADAPTER structure
4327 * @reqBytes: Size of the request in bytes
4328 * @req: Pointer to MPT request frame
4329 * @replyBytes: Expected size of the reply in bytes
4330 * @u16reply: Pointer to area where reply should be written
4331 * @maxwait: Max wait time for a reply (in seconds)
4332 * @sleepFlag: Specifies whether the process can sleep
4334 * NOTES: It is the callers responsibility to byte-swap fields in the
4335 * request which are greater than 1 byte in size. It is also the
4336 * callers responsibility to byte-swap response fields which are
4337 * greater than 1 byte in size.
4339 * Returns 0 for success, non-zero for failure.
4342 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
4343 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
4345 MPIDefaultReply_t *mptReply;
4350 * Get ready to cache a handshake reply
4352 ioc->hs_reply_idx = 0;
4353 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4354 mptReply->MsgLength = 0;
4357 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4358 * then tell IOC that we want to handshake a request of N words.
4359 * (WRITE u32val to Doorbell reg).
4361 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4362 CHIPREG_WRITE32(&ioc->chip->Doorbell,
4363 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
4364 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
4367 * Wait for IOC's doorbell handshake int
4369 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4372 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4373 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4375 /* Read doorbell and check for active bit */
4376 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
4380 * Clear doorbell int (WRITE 0 to IntStatus reg),
4381 * then wait for IOC to ACKnowledge that it's ready for
4382 * our handshake request.
4384 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4385 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4390 u8 *req_as_bytes = (u8 *) req;
4393 * Stuff request words via doorbell handshake,
4394 * with ACK from IOC for each.
4396 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
4397 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
4398 (req_as_bytes[(ii*4) + 1] << 8) |
4399 (req_as_bytes[(ii*4) + 2] << 16) |
4400 (req_as_bytes[(ii*4) + 3] << 24));
4402 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
4403 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4407 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req));
4408 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req);
4410 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n",
4411 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
4414 * Wait for completion of doorbell handshake reply from the IOC
4416 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
4419 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake reply count=%d%s\n",
4420 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
4423 * Copy out the cached reply...
4425 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
4426 u16reply[ii] = ioc->hs_reply[ii];
4434 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4436 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4437 * @ioc: Pointer to MPT_ADAPTER structure
4438 * @howlong: How long to wait (in seconds)
4439 * @sleepFlag: Specifies whether the process can sleep
4441 * This routine waits (up to ~2 seconds max) for IOC doorbell
4442 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4443 * bit in its IntStatus register being clear.
4445 * Returns a negative value on failure, else wait loop count.
4448 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4454 cntdn = 1000 * howlong;
4456 if (sleepFlag == CAN_SLEEP) {
4459 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4460 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4467 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4468 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4475 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell ACK (count=%d)\n",
4480 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4481 ioc->name, count, intstat);
4485 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4487 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4488 * @ioc: Pointer to MPT_ADAPTER structure
4489 * @howlong: How long to wait (in seconds)
4490 * @sleepFlag: Specifies whether the process can sleep
4492 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4493 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4495 * Returns a negative value on failure, else wait loop count.
4498 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4504 cntdn = 1000 * howlong;
4505 if (sleepFlag == CAN_SLEEP) {
4507 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4508 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4515 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4516 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4524 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4525 ioc->name, count, howlong));
4529 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4530 ioc->name, count, intstat);
4534 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4536 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4537 * @ioc: Pointer to MPT_ADAPTER structure
4538 * @howlong: How long to wait (in seconds)
4539 * @sleepFlag: Specifies whether the process can sleep
4541 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4542 * Reply is cached to IOC private area large enough to hold a maximum
4543 * of 128 bytes of reply data.
4545 * Returns a negative value on failure, else size of reply in WORDS.
4548 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4553 u16 *hs_reply = ioc->hs_reply;
4554 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4557 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4560 * Get first two u16's so we can look at IOC's intended reply MsgLength
4563 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4566 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4567 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4568 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4571 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4572 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4576 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4577 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4578 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4581 * If no error (and IOC said MsgLength is > 0), piece together
4582 * reply 16 bits at a time.
4584 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4585 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4587 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4588 /* don't overflow our IOC hs_reply[] buffer! */
4589 if (u16cnt < ARRAY_SIZE(ioc->hs_reply))
4590 hs_reply[u16cnt] = hword;
4591 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4594 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4596 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4599 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4604 else if (u16cnt != (2 * mptReply->MsgLength)) {
4607 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4612 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name));
4613 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply);
4615 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4616 ioc->name, t, u16cnt/2));
4620 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4622 * GetLanConfigPages - Fetch LANConfig pages.
4623 * @ioc: Pointer to MPT_ADAPTER structure
4625 * Return: 0 for success
4626 * -ENOMEM if no memory available
4627 * -EPERM if not allowed due to ISR context
4628 * -EAGAIN if no msg frames currently available
4629 * -EFAULT for non-successful reply or no reply (timeout)
4632 GetLanConfigPages(MPT_ADAPTER *ioc)
4634 ConfigPageHeader_t hdr;
4636 LANPage0_t *ppage0_alloc;
4637 dma_addr_t page0_dma;
4638 LANPage1_t *ppage1_alloc;
4639 dma_addr_t page1_dma;
4644 /* Get LAN Page 0 header */
4645 hdr.PageVersion = 0;
4648 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4649 cfg.cfghdr.hdr = &hdr;
4651 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4656 if ((rc = mpt_config(ioc, &cfg)) != 0)
4659 if (hdr.PageLength > 0) {
4660 data_sz = hdr.PageLength * 4;
4661 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4664 memset((u8 *)ppage0_alloc, 0, data_sz);
4665 cfg.physAddr = page0_dma;
4666 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4668 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4670 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4671 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4675 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4678 * Normalize endianness of structure data,
4679 * by byte-swapping all > 1 byte fields!
4688 /* Get LAN Page 1 header */
4689 hdr.PageVersion = 0;
4692 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4693 cfg.cfghdr.hdr = &hdr;
4695 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4699 if ((rc = mpt_config(ioc, &cfg)) != 0)
4702 if (hdr.PageLength == 0)
4705 data_sz = hdr.PageLength * 4;
4707 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4709 memset((u8 *)ppage1_alloc, 0, data_sz);
4710 cfg.physAddr = page1_dma;
4711 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4713 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4715 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4716 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4719 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4722 * Normalize endianness of structure data,
4723 * by byte-swapping all > 1 byte fields!
4731 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4733 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
4734 * @ioc: Pointer to MPT_ADAPTER structure
4735 * @persist_opcode: see below
4737 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4738 * devices not currently present.
4739 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4741 * NOTE: Don't use not this function during interrupt time.
4743 * Returns 0 for success, non-zero error
4746 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4748 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4750 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
4751 SasIoUnitControlReply_t *sasIoUnitCntrReply;
4752 MPT_FRAME_HDR *mf = NULL;
4753 MPIHeader_t *mpi_hdr;
4756 /* insure garbage is not sent to fw */
4757 switch(persist_opcode) {
4759 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
4760 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
4768 printk("%s: persist_opcode=%x\n",__func__, persist_opcode);
4770 /* Get a MF for this command.
4772 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4773 printk("%s: no msg frames!\n",__func__);
4777 mpi_hdr = (MPIHeader_t *) mf;
4778 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
4779 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
4780 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
4781 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
4782 sasIoUnitCntrReq->Operation = persist_opcode;
4784 init_timer(&ioc->persist_timer);
4785 ioc->persist_timer.data = (unsigned long) ioc;
4786 ioc->persist_timer.function = mpt_timer_expired;
4787 ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
4788 ioc->persist_wait_done=0;
4789 add_timer(&ioc->persist_timer);
4790 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4791 wait_event(mpt_waitq, ioc->persist_wait_done);
4793 sasIoUnitCntrReply =
4794 (SasIoUnitControlReply_t *)ioc->persist_reply_frame;
4795 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
4796 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4798 sasIoUnitCntrReply->IOCStatus,
4799 sasIoUnitCntrReply->IOCLogInfo);
4803 printk("%s: success\n",__func__);
4807 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4810 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
4811 MpiEventDataRaid_t * pRaidEventData)
4820 volume = pRaidEventData->VolumeID;
4821 reason = pRaidEventData->ReasonCode;
4822 disk = pRaidEventData->PhysDiskNum;
4823 status = le32_to_cpu(pRaidEventData->SettingsStatus);
4824 flags = (status >> 0) & 0xff;
4825 state = (status >> 8) & 0xff;
4827 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
4831 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
4832 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
4833 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
4834 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
4835 ioc->name, disk, volume);
4837 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
4842 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4843 printk(MYIOC_s_INFO_FMT " volume has been created\n",
4847 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4849 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
4853 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
4854 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
4858 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4859 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
4861 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
4863 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
4865 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
4868 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
4870 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
4871 ? ", quiesced" : "",
4872 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
4873 ? ", resync in progress" : "" );
4876 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
4877 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
4881 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4882 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
4886 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4887 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
4891 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
4892 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
4896 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4897 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
4899 state == MPI_PHYSDISK0_STATUS_ONLINE
4901 : state == MPI_PHYSDISK0_STATUS_MISSING
4903 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
4905 : state == MPI_PHYSDISK0_STATUS_FAILED
4907 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
4909 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
4910 ? "offline requested"
4911 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
4912 ? "failed requested"
4913 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
4916 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
4917 ? ", out of sync" : "",
4918 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
4919 ? ", quiesced" : "" );
4922 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
4923 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
4927 case MPI_EVENT_RAID_RC_SMART_DATA:
4928 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
4929 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
4932 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
4933 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
4939 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4941 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4942 * @ioc: Pointer to MPT_ADAPTER structure
4944 * Returns: 0 for success
4945 * -ENOMEM if no memory available
4946 * -EPERM if not allowed due to ISR context
4947 * -EAGAIN if no msg frames currently available
4948 * -EFAULT for non-successful reply or no reply (timeout)
4951 GetIoUnitPage2(MPT_ADAPTER *ioc)
4953 ConfigPageHeader_t hdr;
4955 IOUnitPage2_t *ppage_alloc;
4956 dma_addr_t page_dma;
4960 /* Get the page header */
4961 hdr.PageVersion = 0;
4964 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4965 cfg.cfghdr.hdr = &hdr;
4967 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4972 if ((rc = mpt_config(ioc, &cfg)) != 0)
4975 if (hdr.PageLength == 0)
4978 /* Read the config page */
4979 data_sz = hdr.PageLength * 4;
4981 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4983 memset((u8 *)ppage_alloc, 0, data_sz);
4984 cfg.physAddr = page_dma;
4985 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4987 /* If Good, save data */
4988 if ((rc = mpt_config(ioc, &cfg)) == 0)
4989 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4991 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4997 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4999 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
5000 * @ioc: Pointer to a Adapter Strucutre
5001 * @portnum: IOC port number
5003 * Return: -EFAULT if read of config page header fails
5005 * If read of SCSI Port Page 0 fails,
5006 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5007 * Adapter settings: async, narrow
5009 * If read of SCSI Port Page 2 fails,
5010 * Adapter settings valid
5011 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5016 * CHECK - what type of locking mechanisms should be used????
5019 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
5024 ConfigPageHeader_t header;
5030 if (!ioc->spi_data.nvram) {
5033 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
5034 mem = kmalloc(sz, GFP_ATOMIC);
5038 ioc->spi_data.nvram = (int *) mem;
5040 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
5041 ioc->name, ioc->spi_data.nvram, sz));
5044 /* Invalidate NVRAM information
5046 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5047 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
5050 /* Read SPP0 header, allocate memory, then read page.
5052 header.PageVersion = 0;
5053 header.PageLength = 0;
5054 header.PageNumber = 0;
5055 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5056 cfg.cfghdr.hdr = &header;
5058 cfg.pageAddr = portnum;
5059 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5061 cfg.timeout = 0; /* use default */
5062 if (mpt_config(ioc, &cfg) != 0)
5065 if (header.PageLength > 0) {
5066 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5068 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5069 cfg.physAddr = buf_dma;
5070 if (mpt_config(ioc, &cfg) != 0) {
5071 ioc->spi_data.maxBusWidth = MPT_NARROW;
5072 ioc->spi_data.maxSyncOffset = 0;
5073 ioc->spi_data.minSyncFactor = MPT_ASYNC;
5074 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
5076 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5077 "Unable to read PortPage0 minSyncFactor=%x\n",
5078 ioc->name, ioc->spi_data.minSyncFactor));
5080 /* Save the Port Page 0 data
5082 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
5083 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
5084 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
5086 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
5087 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
5088 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5089 "noQas due to Capabilities=%x\n",
5090 ioc->name, pPP0->Capabilities));
5092 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
5093 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
5095 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
5096 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
5097 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
5098 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5099 "PortPage0 minSyncFactor=%x\n",
5100 ioc->name, ioc->spi_data.minSyncFactor));
5102 ioc->spi_data.maxSyncOffset = 0;
5103 ioc->spi_data.minSyncFactor = MPT_ASYNC;
5106 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
5108 /* Update the minSyncFactor based on bus type.
5110 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
5111 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
5113 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
5114 ioc->spi_data.minSyncFactor = MPT_ULTRA;
5115 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5116 "HVD or SE detected, minSyncFactor=%x\n",
5117 ioc->name, ioc->spi_data.minSyncFactor));
5122 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5127 /* SCSI Port Page 2 - Read the header then the page.
5129 header.PageVersion = 0;
5130 header.PageLength = 0;
5131 header.PageNumber = 2;
5132 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5133 cfg.cfghdr.hdr = &header;
5135 cfg.pageAddr = portnum;
5136 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5138 if (mpt_config(ioc, &cfg) != 0)
5141 if (header.PageLength > 0) {
5142 /* Allocate memory and read SCSI Port Page 2
5144 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5146 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
5147 cfg.physAddr = buf_dma;
5148 if (mpt_config(ioc, &cfg) != 0) {
5149 /* Nvram data is left with INVALID mark
5152 } else if (ioc->pcidev->vendor == PCI_VENDOR_ID_ATTO) {
5154 /* This is an ATTO adapter, read Page2 accordingly
5156 ATTO_SCSIPortPage2_t *pPP2 = (ATTO_SCSIPortPage2_t *) pbuf;
5157 ATTODeviceInfo_t *pdevice = NULL;
5160 /* Save the Port Page 2 data
5161 * (reformat into a 32bit quantity)
5163 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5164 pdevice = &pPP2->DeviceSettings[ii];
5165 ATTOFlags = le16_to_cpu(pdevice->ATTOFlags);
5168 /* Translate ATTO device flags to LSI format
5170 if (ATTOFlags & ATTOFLAG_DISC)
5171 data |= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE);
5172 if (ATTOFlags & ATTOFLAG_ID_ENB)
5173 data |= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE);
5174 if (ATTOFlags & ATTOFLAG_LUN_ENB)
5175 data |= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE);
5176 if (ATTOFlags & ATTOFLAG_TAGGED)
5177 data |= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE);
5178 if (!(ATTOFlags & ATTOFLAG_WIDE_ENB))
5179 data |= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE);
5181 data = (data << 16) | (pdevice->Period << 8) | 10;
5182 ioc->spi_data.nvram[ii] = data;
5185 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
5186 MpiDeviceInfo_t *pdevice = NULL;
5189 * Save "Set to Avoid SCSI Bus Resets" flag
5191 ioc->spi_data.bus_reset =
5192 (le32_to_cpu(pPP2->PortFlags) &
5193 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
5196 /* Save the Port Page 2 data
5197 * (reformat into a 32bit quantity)
5199 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
5200 ioc->spi_data.PortFlags = data;
5201 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5202 pdevice = &pPP2->DeviceSettings[ii];
5203 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
5204 (pdevice->SyncFactor << 8) | pdevice->Timeout;
5205 ioc->spi_data.nvram[ii] = data;
5209 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5213 /* Update Adapter limits with those from NVRAM
5214 * Comment: Don't need to do this. Target performance
5215 * parameters will never exceed the adapters limits.
5221 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5223 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
5224 * @ioc: Pointer to a Adapter Strucutre
5225 * @portnum: IOC port number
5227 * Return: -EFAULT if read of config page header fails
5231 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
5234 ConfigPageHeader_t header;
5236 /* Read the SCSI Device Page 1 header
5238 header.PageVersion = 0;
5239 header.PageLength = 0;
5240 header.PageNumber = 1;
5241 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5242 cfg.cfghdr.hdr = &header;
5244 cfg.pageAddr = portnum;
5245 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5248 if (mpt_config(ioc, &cfg) != 0)
5251 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
5252 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
5254 header.PageVersion = 0;
5255 header.PageLength = 0;
5256 header.PageNumber = 0;
5257 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5258 if (mpt_config(ioc, &cfg) != 0)
5261 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
5262 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
5264 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 0: version %d length %d\n",
5265 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
5267 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 1: version %d length %d\n",
5268 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
5273 * mpt_inactive_raid_list_free - This clears this link list.
5274 * @ioc : pointer to per adapter structure
5277 mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
5279 struct inactive_raid_component_info *component_info, *pNext;
5281 if (list_empty(&ioc->raid_data.inactive_list))
5284 mutex_lock(&ioc->raid_data.inactive_list_mutex);
5285 list_for_each_entry_safe(component_info, pNext,
5286 &ioc->raid_data.inactive_list, list) {
5287 list_del(&component_info->list);
5288 kfree(component_info);
5290 mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5294 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5296 * @ioc : pointer to per adapter structure
5297 * @channel : volume channel
5298 * @id : volume target id
5301 mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
5304 ConfigPageHeader_t hdr;
5305 dma_addr_t dma_handle;
5306 pRaidVolumePage0_t buffer = NULL;
5308 RaidPhysDiskPage0_t phys_disk;
5309 struct inactive_raid_component_info *component_info;
5310 int handle_inactive_volumes;
5312 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5313 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5314 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
5315 cfg.pageAddr = (channel << 8) + id;
5316 cfg.cfghdr.hdr = &hdr;
5317 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5319 if (mpt_config(ioc, &cfg) != 0)
5322 if (!hdr.PageLength)
5325 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5331 cfg.physAddr = dma_handle;
5332 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5334 if (mpt_config(ioc, &cfg) != 0)
5337 if (!buffer->NumPhysDisks)
5340 handle_inactive_volumes =
5341 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
5342 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
5343 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
5344 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
5346 if (!handle_inactive_volumes)
5349 mutex_lock(&ioc->raid_data.inactive_list_mutex);
5350 for (i = 0; i < buffer->NumPhysDisks; i++) {
5351 if(mpt_raid_phys_disk_pg0(ioc,
5352 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
5355 if ((component_info = kmalloc(sizeof (*component_info),
5356 GFP_KERNEL)) == NULL)
5359 component_info->volumeID = id;
5360 component_info->volumeBus = channel;
5361 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
5362 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
5363 component_info->d.PhysDiskID = phys_disk.PhysDiskID;
5364 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
5366 list_add_tail(&component_info->list,
5367 &ioc->raid_data.inactive_list);
5369 mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5373 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5378 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5379 * @ioc: Pointer to a Adapter Structure
5380 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5381 * @phys_disk: requested payload data returned
5385 * -EFAULT if read of config page header fails or data pointer not NULL
5386 * -ENOMEM if pci_alloc failed
5389 mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk)
5392 ConfigPageHeader_t hdr;
5393 dma_addr_t dma_handle;
5394 pRaidPhysDiskPage0_t buffer = NULL;
5397 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5398 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5400 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5401 cfg.cfghdr.hdr = &hdr;
5403 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5405 if (mpt_config(ioc, &cfg) != 0) {
5410 if (!hdr.PageLength) {
5415 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5423 cfg.physAddr = dma_handle;
5424 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5425 cfg.pageAddr = phys_disk_num;
5427 if (mpt_config(ioc, &cfg) != 0) {
5433 memcpy(phys_disk, buffer, sizeof(*buffer));
5434 phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
5439 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5446 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5447 * @ioc: Pointer to a Adapter Strucutre
5451 * -EFAULT if read of config page header fails or data pointer not NULL
5452 * -ENOMEM if pci_alloc failed
5455 mpt_findImVolumes(MPT_ADAPTER *ioc)
5459 dma_addr_t ioc2_dma;
5461 ConfigPageHeader_t header;
5466 if (!ioc->ir_firmware)
5469 /* Free the old page
5471 kfree(ioc->raid_data.pIocPg2);
5472 ioc->raid_data.pIocPg2 = NULL;
5473 mpt_inactive_raid_list_free(ioc);
5475 /* Read IOCP2 header then the page.
5477 header.PageVersion = 0;
5478 header.PageLength = 0;
5479 header.PageNumber = 2;
5480 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5481 cfg.cfghdr.hdr = &header;
5484 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5487 if (mpt_config(ioc, &cfg) != 0)
5490 if (header.PageLength == 0)
5493 iocpage2sz = header.PageLength * 4;
5494 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
5498 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5499 cfg.physAddr = ioc2_dma;
5500 if (mpt_config(ioc, &cfg) != 0)
5503 mem = kmalloc(iocpage2sz, GFP_KERNEL);
5507 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
5508 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
5510 mpt_read_ioc_pg_3(ioc);
5512 for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
5513 mpt_inactive_raid_volumes(ioc,
5514 pIoc2->RaidVolume[i].VolumeBus,
5515 pIoc2->RaidVolume[i].VolumeID);
5518 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
5524 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
5529 ConfigPageHeader_t header;
5530 dma_addr_t ioc3_dma;
5533 /* Free the old page
5535 kfree(ioc->raid_data.pIocPg3);
5536 ioc->raid_data.pIocPg3 = NULL;
5538 /* There is at least one physical disk.
5539 * Read and save IOC Page 3
5541 header.PageVersion = 0;
5542 header.PageLength = 0;
5543 header.PageNumber = 3;
5544 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5545 cfg.cfghdr.hdr = &header;
5548 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5551 if (mpt_config(ioc, &cfg) != 0)
5554 if (header.PageLength == 0)
5557 /* Read Header good, alloc memory
5559 iocpage3sz = header.PageLength * 4;
5560 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
5564 /* Read the Page and save the data
5565 * into malloc'd memory.
5567 cfg.physAddr = ioc3_dma;
5568 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5569 if (mpt_config(ioc, &cfg) == 0) {
5570 mem = kmalloc(iocpage3sz, GFP_KERNEL);
5572 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
5573 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
5577 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
5583 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
5587 ConfigPageHeader_t header;
5588 dma_addr_t ioc4_dma;
5591 /* Read and save IOC Page 4
5593 header.PageVersion = 0;
5594 header.PageLength = 0;
5595 header.PageNumber = 4;
5596 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5597 cfg.cfghdr.hdr = &header;
5600 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5603 if (mpt_config(ioc, &cfg) != 0)
5606 if (header.PageLength == 0)
5609 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
5610 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
5611 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
5614 ioc->alloc_total += iocpage4sz;
5616 ioc4_dma = ioc->spi_data.IocPg4_dma;
5617 iocpage4sz = ioc->spi_data.IocPg4Sz;
5620 /* Read the Page into dma memory.
5622 cfg.physAddr = ioc4_dma;
5623 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5624 if (mpt_config(ioc, &cfg) == 0) {
5625 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
5626 ioc->spi_data.IocPg4_dma = ioc4_dma;
5627 ioc->spi_data.IocPg4Sz = iocpage4sz;
5629 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
5630 ioc->spi_data.pIocPg4 = NULL;
5631 ioc->alloc_total -= iocpage4sz;
5636 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
5640 ConfigPageHeader_t header;
5641 dma_addr_t ioc1_dma;
5645 /* Check the Coalescing Timeout in IOC Page 1
5647 header.PageVersion = 0;
5648 header.PageLength = 0;
5649 header.PageNumber = 1;
5650 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5651 cfg.cfghdr.hdr = &header;
5654 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5657 if (mpt_config(ioc, &cfg) != 0)
5660 if (header.PageLength == 0)
5663 /* Read Header good, alloc memory
5665 iocpage1sz = header.PageLength * 4;
5666 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
5670 /* Read the Page and check coalescing timeout
5672 cfg.physAddr = ioc1_dma;
5673 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5674 if (mpt_config(ioc, &cfg) == 0) {
5676 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
5677 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
5678 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
5680 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Coalescing Enabled Timeout = %d\n",
5683 if (tmp > MPT_COALESCING_TIMEOUT) {
5684 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
5686 /* Write NVRAM and current
5689 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5690 if (mpt_config(ioc, &cfg) == 0) {
5691 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Reset Current Coalescing Timeout to = %d\n",
5692 ioc->name, MPT_COALESCING_TIMEOUT));
5694 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
5695 if (mpt_config(ioc, &cfg) == 0) {
5696 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5697 "Reset NVRAM Coalescing Timeout to = %d\n",
5698 ioc->name, MPT_COALESCING_TIMEOUT));
5700 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5701 "Reset NVRAM Coalescing Timeout Failed\n",
5706 dprintk(ioc, printk(MYIOC_s_WARN_FMT
5707 "Reset of Current Coalescing Timeout Failed!\n",
5713 dprintk(ioc, printk(MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
5717 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
5723 mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
5726 ConfigPageHeader_t hdr;
5728 ManufacturingPage0_t *pbuf = NULL;
5730 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5731 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5733 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
5734 cfg.cfghdr.hdr = &hdr;
5736 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5739 if (mpt_config(ioc, &cfg) != 0)
5742 if (!cfg.cfghdr.hdr->PageLength)
5745 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5746 pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
5750 cfg.physAddr = buf_dma;
5752 if (mpt_config(ioc, &cfg) != 0)
5755 memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name));
5756 memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
5757 memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
5762 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
5765 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5767 * SendEventNotification - Send EventNotification (on or off) request to adapter
5768 * @ioc: Pointer to MPT_ADAPTER structure
5769 * @EvSwitch: Event switch flags
5772 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
5774 EventNotification_t *evnp;
5776 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
5778 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
5782 memset(evnp, 0, sizeof(*evnp));
5784 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
5786 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
5787 evnp->ChainOffset = 0;
5789 evnp->Switch = EvSwitch;
5791 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
5796 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5798 * SendEventAck - Send EventAck request to MPT adapter.
5799 * @ioc: Pointer to MPT_ADAPTER structure
5800 * @evnp: Pointer to original EventNotification request
5803 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
5807 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5808 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
5809 ioc->name,__func__));
5813 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventAck\n", ioc->name));
5815 pAck->Function = MPI_FUNCTION_EVENT_ACK;
5816 pAck->ChainOffset = 0;
5817 pAck->Reserved[0] = pAck->Reserved[1] = 0;
5819 pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
5820 pAck->Event = evnp->Event;
5821 pAck->EventContext = evnp->EventContext;
5823 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
5828 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5830 * mpt_config - Generic function to issue config message
5831 * @ioc: Pointer to an adapter structure
5832 * @pCfg: Pointer to a configuration structure. Struct contains
5833 * action, page address, direction, physical address
5834 * and pointer to a configuration page header
5835 * Page header is updated.
5837 * Returns 0 for success
5838 * -EPERM if not allowed due to ISR context
5839 * -EAGAIN if no msg frames currently available
5840 * -EFAULT for non-successful reply or no reply (timeout)
5843 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5846 ConfigExtendedPageHeader_t *pExtHdr = NULL;
5848 unsigned long flags;
5853 /* Prevent calling wait_event() (below), if caller happens
5854 * to be in ISR context, because that is fatal!
5856 in_isr = in_interrupt();
5858 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
5863 /* Get and Populate a free Frame
5865 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5866 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
5870 pReq = (Config_t *)mf;
5871 pReq->Action = pCfg->action;
5873 pReq->ChainOffset = 0;
5874 pReq->Function = MPI_FUNCTION_CONFIG;
5876 /* Assume page type is not extended and clear "reserved" fields. */
5877 pReq->ExtPageLength = 0;
5878 pReq->ExtPageType = 0;
5881 for (ii=0; ii < 8; ii++)
5882 pReq->Reserved2[ii] = 0;
5884 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
5885 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
5886 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
5887 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
5889 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5890 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
5891 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
5892 pReq->ExtPageType = pExtHdr->ExtPageType;
5893 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
5895 /* Page Length must be treated as a reserved field for the extended header. */
5896 pReq->Header.PageLength = 0;
5899 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
5901 /* Add a SGE to the config request.
5904 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
5906 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
5908 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5909 flagsLength |= pExtHdr->ExtPageLength * 4;
5911 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n",
5912 ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action));
5915 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
5917 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n",
5918 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
5921 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
5923 /* Append pCfg pointer to end of mf
5925 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5927 /* Initalize the timer
5929 init_timer(&pCfg->timer);
5930 pCfg->timer.data = (unsigned long) ioc;
5931 pCfg->timer.function = mpt_timer_expired;
5932 pCfg->wait_done = 0;
5934 /* Set the timer; ensure 10 second minimum */
5935 if (pCfg->timeout < 10)
5936 pCfg->timer.expires = jiffies + HZ*10;
5938 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5940 /* Add to end of Q, set timer and then issue this command */
5941 spin_lock_irqsave(&ioc->FreeQlock, flags);
5942 list_add_tail(&pCfg->linkage, &ioc->configQ);
5943 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5945 add_timer(&pCfg->timer);
5946 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5947 wait_event(mpt_waitq, pCfg->wait_done);
5949 /* mf has been freed - do not access */
5956 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5958 * mpt_timer_expired - Callback for timer process.
5959 * Used only internal config functionality.
5960 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5963 mpt_timer_expired(unsigned long data)
5965 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
5967 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired! \n", ioc->name));
5969 /* Perform a FW reload */
5970 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
5971 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
5973 /* No more processing.
5974 * Hard reset clean-up will wake up
5975 * process and free all resources.
5977 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired complete!\n", ioc->name));
5982 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5984 * mpt_ioc_reset - Base cleanup for hard reset
5985 * @ioc: Pointer to the adapter structure
5986 * @reset_phase: Indicates pre- or post-reset functionality
5988 * Remark: Frees resources with internally generated commands.
5991 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
5994 unsigned long flags;
5996 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5997 ": IOC %s_reset routed to MPT base driver!\n",
5998 ioc->name, reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
5999 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
6001 if (reset_phase == MPT_IOC_SETUP_RESET) {
6003 } else if (reset_phase == MPT_IOC_PRE_RESET) {
6004 /* If the internal config Q is not empty -
6005 * delete timer. MF resources will be freed when
6006 * the FIFO's are primed.
6008 spin_lock_irqsave(&ioc->FreeQlock, flags);
6009 list_for_each_entry(pCfg, &ioc->configQ, linkage)
6010 del_timer(&pCfg->timer);
6011 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
6016 /* Search the configQ for internal commands.
6017 * Flush the Q, and wake up all suspended threads.
6019 spin_lock_irqsave(&ioc->FreeQlock, flags);
6020 list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
6021 list_del(&pCfg->linkage);
6023 pCfg->status = MPT_CONFIG_ERROR;
6024 pCfg->wait_done = 1;
6025 wake_up(&mpt_waitq);
6027 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
6030 return 1; /* currently means nothing really */
6034 #ifdef CONFIG_PROC_FS /* { */
6035 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6037 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
6039 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6041 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
6043 * Returns 0 for success, non-zero for failure.
6046 procmpt_create(void)
6048 struct proc_dir_entry *ent;
6050 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
6051 if (mpt_proc_root_dir == NULL)
6054 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
6056 ent->read_proc = procmpt_summary_read;
6058 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
6060 ent->read_proc = procmpt_version_read;
6065 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6067 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
6069 * Returns 0 for success, non-zero for failure.
6072 procmpt_destroy(void)
6074 remove_proc_entry("version", mpt_proc_root_dir);
6075 remove_proc_entry("summary", mpt_proc_root_dir);
6076 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
6079 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6081 * procmpt_summary_read - Handle read request of a summary file
6082 * @buf: Pointer to area to write information
6083 * @start: Pointer to start pointer
6084 * @offset: Offset to start writing
6085 * @request: Amount of read data requested
6086 * @eof: Pointer to EOF integer
6089 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
6090 * Returns number of characters written to process performing the read.
6093 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6103 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
6107 list_for_each_entry(ioc, &ioc_list, list) {
6110 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
6113 if ((out-buf) >= request)
6120 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6123 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6125 * procmpt_version_read - Handle read request from /proc/mpt/version.
6126 * @buf: Pointer to area to write information
6127 * @start: Pointer to start pointer
6128 * @offset: Offset to start writing
6129 * @request: Amount of read data requested
6130 * @eof: Pointer to EOF integer
6133 * Returns number of characters written to process performing the read.
6136 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6139 int scsi, fc, sas, lan, ctl, targ, dmp;
6143 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
6144 len += sprintf(buf+len, " Fusion MPT base driver\n");
6146 scsi = fc = sas = lan = ctl = targ = dmp = 0;
6147 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6149 if (MptCallbacks[cb_idx]) {
6150 switch (MptDriverClass[cb_idx]) {
6152 if (!scsi++) drvname = "SPI host";
6155 if (!fc++) drvname = "FC host";
6158 if (!sas++) drvname = "SAS host";
6161 if (!lan++) drvname = "LAN";
6164 if (!targ++) drvname = "SCSI target";
6167 if (!ctl++) drvname = "ioctl";
6172 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
6176 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6179 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6181 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
6182 * @buf: Pointer to area to write information
6183 * @start: Pointer to start pointer
6184 * @offset: Offset to start writing
6185 * @request: Amount of read data requested
6186 * @eof: Pointer to EOF integer
6189 * Returns number of characters written to process performing the read.
6192 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6194 MPT_ADAPTER *ioc = data;
6200 mpt_get_fw_exp_ver(expVer, ioc);
6202 len = sprintf(buf, "%s:", ioc->name);
6203 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
6204 len += sprintf(buf+len, " (f/w download boot flag set)");
6205 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6206 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
6208 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
6209 ioc->facts.ProductID,
6211 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
6212 if (ioc->facts.FWImageSize)
6213 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
6214 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
6215 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
6216 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
6218 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
6219 ioc->facts.CurrentHostMfaHighAddr);
6220 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
6221 ioc->facts.CurrentSenseBufferHighAddr);
6223 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
6224 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
6226 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6227 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
6229 * Rounding UP to nearest 4-kB boundary here...
6231 sz = (ioc->req_sz * ioc->req_depth) + 128;
6232 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
6233 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6234 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
6235 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
6236 4*ioc->facts.RequestFrameSize,
6237 ioc->facts.GlobalCredits);
6239 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
6240 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
6241 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
6242 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6243 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
6244 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
6245 ioc->facts.CurReplyFrameSize,
6246 ioc->facts.ReplyQueueDepth);
6248 len += sprintf(buf+len, " MaxDevices = %d\n",
6249 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
6250 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
6253 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
6254 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
6256 ioc->facts.NumberOfPorts);
6257 if (ioc->bus_type == FC) {
6258 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
6259 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6260 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6261 a[5], a[4], a[3], a[2], a[1], a[0]);
6263 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
6264 ioc->fc_port_page0[p].WWNN.High,
6265 ioc->fc_port_page0[p].WWNN.Low,
6266 ioc->fc_port_page0[p].WWPN.High,
6267 ioc->fc_port_page0[p].WWPN.Low);
6271 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6274 #endif /* CONFIG_PROC_FS } */
6276 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6278 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
6281 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
6282 sprintf(buf, " (Exp %02d%02d)",
6283 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
6284 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
6287 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
6288 strcat(buf, " [MDBG]");
6292 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6294 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6295 * @ioc: Pointer to MPT_ADAPTER structure
6296 * @buffer: Pointer to buffer where IOC summary info should be written
6297 * @size: Pointer to number of bytes we wrote (set by this routine)
6298 * @len: Offset at which to start writing in buffer
6299 * @showlan: Display LAN stuff?
6301 * This routine writes (english readable) ASCII text, which represents
6302 * a summary of IOC information, to a buffer.
6305 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
6310 mpt_get_fw_exp_ver(expVer, ioc);
6313 * Shorter summary of attached ioc's...
6315 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6318 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
6319 ioc->facts.FWVersion.Word,
6321 ioc->facts.NumberOfPorts,
6324 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6325 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6326 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6327 a[5], a[4], a[3], a[2], a[1], a[0]);
6330 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
6333 y += sprintf(buffer+len+y, " (disabled)");
6335 y += sprintf(buffer+len+y, "\n");
6340 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6344 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6346 * mpt_HardResetHandler - Generic reset handler
6347 * @ioc: Pointer to MPT_ADAPTER structure
6348 * @sleepFlag: Indicates if sleep or schedule must be called.
6350 * Issues SCSI Task Management call based on input arg values.
6351 * If TaskMgmt fails, returns associated SCSI request.
6353 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
6354 * or a non-interrupt thread. In the former, must not call schedule().
6356 * Note: A return of -1 is a FATAL error case, as it means a
6357 * FW reload/initialization failed.
6359 * Returns 0 for SUCCESS or -1 if FAILED.
6362 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6365 unsigned long flags;
6367 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name));
6369 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
6370 printk("MF count 0x%x !\n", ioc->mfcnt);
6373 /* Reset the adapter. Prevent more than 1 call to
6374 * mpt_do_ioc_recovery at any instant in time.
6376 spin_lock_irqsave(&ioc->diagLock, flags);
6377 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
6378 spin_unlock_irqrestore(&ioc->diagLock, flags);
6381 ioc->diagPending = 1;
6383 spin_unlock_irqrestore(&ioc->diagLock, flags);
6385 /* FIXME: If do_ioc_recovery fails, repeat....
6388 /* The SCSI driver needs to adjust timeouts on all current
6389 * commands prior to the diagnostic reset being issued.
6390 * Prevents timeouts occurring during a diagnostic reset...very bad.
6391 * For all other protocol drivers, this is a no-op.
6397 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6398 if (MptResetHandlers[cb_idx]) {
6399 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling IOC reset_setup handler #%d\n",
6400 ioc->name, cb_idx));
6401 r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
6403 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling alt-%s setup reset handler #%d\n",
6404 ioc->name, ioc->alt_ioc->name, cb_idx));
6405 r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_SETUP_RESET);
6411 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
6412 printk(MYIOC_s_WARN_FMT "Cannot recover rc = %d!\n", ioc->name, rc);
6416 ioc->alt_ioc->reload_fw = 0;
6418 spin_lock_irqsave(&ioc->diagLock, flags);
6419 ioc->diagPending = 0;
6421 ioc->alt_ioc->diagPending = 0;
6422 spin_unlock_irqrestore(&ioc->diagLock, flags);
6424 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
6429 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6431 EventDescriptionStr(u8 event, u32 evData0, char *evStr)
6436 case MPI_EVENT_NONE:
6439 case MPI_EVENT_LOG_DATA:
6442 case MPI_EVENT_STATE_CHANGE:
6443 ds = "State Change";
6445 case MPI_EVENT_UNIT_ATTENTION:
6446 ds = "Unit Attention";
6448 case MPI_EVENT_IOC_BUS_RESET:
6449 ds = "IOC Bus Reset";
6451 case MPI_EVENT_EXT_BUS_RESET:
6452 ds = "External Bus Reset";
6454 case MPI_EVENT_RESCAN:
6455 ds = "Bus Rescan Event";
6457 case MPI_EVENT_LINK_STATUS_CHANGE:
6458 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
6459 ds = "Link Status(FAILURE) Change";
6461 ds = "Link Status(ACTIVE) Change";
6463 case MPI_EVENT_LOOP_STATE_CHANGE:
6464 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
6465 ds = "Loop State(LIP) Change";
6466 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
6467 ds = "Loop State(LPE) Change"; /* ??? */
6469 ds = "Loop State(LPB) Change"; /* ??? */
6471 case MPI_EVENT_LOGOUT:
6474 case MPI_EVENT_EVENT_CHANGE:
6480 case MPI_EVENT_INTEGRATED_RAID:
6482 u8 ReasonCode = (u8)(evData0 >> 16);
6483 switch (ReasonCode) {
6484 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
6485 ds = "Integrated Raid: Volume Created";
6487 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
6488 ds = "Integrated Raid: Volume Deleted";
6490 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
6491 ds = "Integrated Raid: Volume Settings Changed";
6493 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
6494 ds = "Integrated Raid: Volume Status Changed";
6496 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
6497 ds = "Integrated Raid: Volume Physdisk Changed";
6499 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
6500 ds = "Integrated Raid: Physdisk Created";
6502 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
6503 ds = "Integrated Raid: Physdisk Deleted";
6505 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
6506 ds = "Integrated Raid: Physdisk Settings Changed";
6508 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
6509 ds = "Integrated Raid: Physdisk Status Changed";
6511 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
6512 ds = "Integrated Raid: Domain Validation Needed";
6514 case MPI_EVENT_RAID_RC_SMART_DATA :
6515 ds = "Integrated Raid; Smart Data";
6517 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
6518 ds = "Integrated Raid: Replace Action Started";
6521 ds = "Integrated Raid";
6526 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
6527 ds = "SCSI Device Status Change";
6529 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
6531 u8 id = (u8)(evData0);
6532 u8 channel = (u8)(evData0 >> 8);
6533 u8 ReasonCode = (u8)(evData0 >> 16);
6534 switch (ReasonCode) {
6535 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
6536 snprintf(evStr, EVENT_DESCR_STR_SZ,
6537 "SAS Device Status Change: Added: "
6538 "id=%d channel=%d", id, channel);
6540 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
6541 snprintf(evStr, EVENT_DESCR_STR_SZ,
6542 "SAS Device Status Change: Deleted: "
6543 "id=%d channel=%d", id, channel);
6545 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
6546 snprintf(evStr, EVENT_DESCR_STR_SZ,
6547 "SAS Device Status Change: SMART Data: "
6548 "id=%d channel=%d", id, channel);
6550 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
6551 snprintf(evStr, EVENT_DESCR_STR_SZ,
6552 "SAS Device Status Change: No Persistancy: "
6553 "id=%d channel=%d", id, channel);
6555 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
6556 snprintf(evStr, EVENT_DESCR_STR_SZ,
6557 "SAS Device Status Change: Unsupported Device "
6558 "Discovered : id=%d channel=%d", id, channel);
6560 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
6561 snprintf(evStr, EVENT_DESCR_STR_SZ,
6562 "SAS Device Status Change: Internal Device "
6563 "Reset : id=%d channel=%d", id, channel);
6565 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
6566 snprintf(evStr, EVENT_DESCR_STR_SZ,
6567 "SAS Device Status Change: Internal Task "
6568 "Abort : id=%d channel=%d", id, channel);
6570 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
6571 snprintf(evStr, EVENT_DESCR_STR_SZ,
6572 "SAS Device Status Change: Internal Abort "
6573 "Task Set : id=%d channel=%d", id, channel);
6575 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
6576 snprintf(evStr, EVENT_DESCR_STR_SZ,
6577 "SAS Device Status Change: Internal Clear "
6578 "Task Set : id=%d channel=%d", id, channel);
6580 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
6581 snprintf(evStr, EVENT_DESCR_STR_SZ,
6582 "SAS Device Status Change: Internal Query "
6583 "Task : id=%d channel=%d", id, channel);
6586 snprintf(evStr, EVENT_DESCR_STR_SZ,
6587 "SAS Device Status Change: Unknown: "
6588 "id=%d channel=%d", id, channel);
6593 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
6594 ds = "Bus Timer Expired";
6596 case MPI_EVENT_QUEUE_FULL:
6598 u16 curr_depth = (u16)(evData0 >> 16);
6599 u8 channel = (u8)(evData0 >> 8);
6600 u8 id = (u8)(evData0);
6602 snprintf(evStr, EVENT_DESCR_STR_SZ,
6603 "Queue Full: channel=%d id=%d depth=%d",
6604 channel, id, curr_depth);
6607 case MPI_EVENT_SAS_SES:
6608 ds = "SAS SES Event";
6610 case MPI_EVENT_PERSISTENT_TABLE_FULL:
6611 ds = "Persistent Table Full";
6613 case MPI_EVENT_SAS_PHY_LINK_STATUS:
6615 u8 LinkRates = (u8)(evData0 >> 8);
6616 u8 PhyNumber = (u8)(evData0);
6617 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
6618 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
6619 switch (LinkRates) {
6620 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
6621 snprintf(evStr, EVENT_DESCR_STR_SZ,
6622 "SAS PHY Link Status: Phy=%d:"
6623 " Rate Unknown",PhyNumber);
6625 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
6626 snprintf(evStr, EVENT_DESCR_STR_SZ,
6627 "SAS PHY Link Status: Phy=%d:"
6628 " Phy Disabled",PhyNumber);
6630 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
6631 snprintf(evStr, EVENT_DESCR_STR_SZ,
6632 "SAS PHY Link Status: Phy=%d:"
6633 " Failed Speed Nego",PhyNumber);
6635 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
6636 snprintf(evStr, EVENT_DESCR_STR_SZ,
6637 "SAS PHY Link Status: Phy=%d:"
6638 " Sata OOB Completed",PhyNumber);
6640 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
6641 snprintf(evStr, EVENT_DESCR_STR_SZ,
6642 "SAS PHY Link Status: Phy=%d:"
6643 " Rate 1.5 Gbps",PhyNumber);
6645 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
6646 snprintf(evStr, EVENT_DESCR_STR_SZ,
6647 "SAS PHY Link Status: Phy=%d:"
6648 " Rate 3.0 Gpbs",PhyNumber);
6651 snprintf(evStr, EVENT_DESCR_STR_SZ,
6652 "SAS PHY Link Status: Phy=%d", PhyNumber);
6657 case MPI_EVENT_SAS_DISCOVERY_ERROR:
6658 ds = "SAS Discovery Error";
6660 case MPI_EVENT_IR_RESYNC_UPDATE:
6662 u8 resync_complete = (u8)(evData0 >> 16);
6663 snprintf(evStr, EVENT_DESCR_STR_SZ,
6664 "IR Resync Update: Complete = %d:",resync_complete);
6669 u8 ReasonCode = (u8)(evData0 >> 16);
6670 switch (ReasonCode) {
6671 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
6672 ds = "IR2: LD State Changed";
6674 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
6675 ds = "IR2: PD State Changed";
6677 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
6678 ds = "IR2: Bad Block Table Full";
6680 case MPI_EVENT_IR2_RC_PD_INSERTED:
6681 ds = "IR2: PD Inserted";
6683 case MPI_EVENT_IR2_RC_PD_REMOVED:
6684 ds = "IR2: PD Removed";
6686 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
6687 ds = "IR2: Foreign CFG Detected";
6689 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
6690 ds = "IR2: Rebuild Medium Error";
6698 case MPI_EVENT_SAS_DISCOVERY:
6701 ds = "SAS Discovery: Start";
6703 ds = "SAS Discovery: Stop";
6706 case MPI_EVENT_LOG_ENTRY_ADDED:
6707 ds = "SAS Log Entry Added";
6710 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
6712 u8 phy_num = (u8)(evData0);
6713 u8 port_num = (u8)(evData0 >> 8);
6714 u8 port_width = (u8)(evData0 >> 16);
6715 u8 primative = (u8)(evData0 >> 24);
6716 snprintf(evStr, EVENT_DESCR_STR_SZ,
6717 "SAS Broadcase Primative: phy=%d port=%d "
6718 "width=%d primative=0x%02x",
6719 phy_num, port_num, port_width, primative);
6723 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
6725 u8 reason = (u8)(evData0);
6726 u8 port_num = (u8)(evData0 >> 8);
6727 u16 handle = le16_to_cpu(evData0 >> 16);
6729 snprintf(evStr, EVENT_DESCR_STR_SZ,
6730 "SAS Initiator Device Status Change: reason=0x%02x "
6731 "port=%d handle=0x%04x",
6732 reason, port_num, handle);
6736 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
6738 u8 max_init = (u8)(evData0);
6739 u8 current_init = (u8)(evData0 >> 8);
6741 snprintf(evStr, EVENT_DESCR_STR_SZ,
6742 "SAS Initiator Device Table Overflow: max initiators=%02d "
6743 "current initators=%02d",
6744 max_init, current_init);
6747 case MPI_EVENT_SAS_SMP_ERROR:
6749 u8 status = (u8)(evData0);
6750 u8 port_num = (u8)(evData0 >> 8);
6751 u8 result = (u8)(evData0 >> 16);
6753 if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
6754 snprintf(evStr, EVENT_DESCR_STR_SZ,
6755 "SAS SMP Error: port=%d result=0x%02x",
6757 else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
6758 snprintf(evStr, EVENT_DESCR_STR_SZ,
6759 "SAS SMP Error: port=%d : CRC Error",
6761 else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
6762 snprintf(evStr, EVENT_DESCR_STR_SZ,
6763 "SAS SMP Error: port=%d : Timeout",
6765 else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
6766 snprintf(evStr, EVENT_DESCR_STR_SZ,
6767 "SAS SMP Error: port=%d : No Destination",
6769 else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
6770 snprintf(evStr, EVENT_DESCR_STR_SZ,
6771 "SAS SMP Error: port=%d : Bad Destination",
6774 snprintf(evStr, EVENT_DESCR_STR_SZ,
6775 "SAS SMP Error: port=%d : status=0x%02x",
6781 * MPT base "custom" events may be added here...
6788 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
6791 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6793 * ProcessEventNotification - Route EventNotificationReply to all event handlers
6794 * @ioc: Pointer to MPT_ADAPTER structure
6795 * @pEventReply: Pointer to EventNotification reply frame
6796 * @evHandlers: Pointer to integer, number of event handlers
6798 * Routes a received EventNotificationReply to all currently registered
6800 * Returns sum of event handlers return values.
6803 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
6812 char evStr[EVENT_DESCR_STR_SZ];
6816 * Do platform normalization of values
6818 event = le32_to_cpu(pEventReply->Event) & 0xFF;
6819 // evCtx = le32_to_cpu(pEventReply->EventContext);
6820 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
6822 evData0 = le32_to_cpu(pEventReply->Data[0]);
6825 EventDescriptionStr(event, evData0, evStr);
6826 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event:(%02Xh) : %s\n",
6831 #ifdef CONFIG_FUSION_LOGGING
6832 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6833 ": Event data:\n", ioc->name));
6834 for (ii = 0; ii < evDataLen; ii++)
6835 devtverboseprintk(ioc, printk(" %08x",
6836 le32_to_cpu(pEventReply->Data[ii])));
6837 devtverboseprintk(ioc, printk("\n"));
6841 * Do general / base driver event processing
6844 case MPI_EVENT_EVENT_CHANGE: /* 0A */
6846 u8 evState = evData0 & 0xFF;
6848 /* CHECKME! What if evState unexpectedly says OFF (0)? */
6850 /* Update EventState field in cached IocFacts */
6851 if (ioc->facts.Function) {
6852 ioc->facts.EventState = evState;
6856 case MPI_EVENT_INTEGRATED_RAID:
6857 mptbase_raid_process_event_data(ioc,
6858 (MpiEventDataRaid_t *)pEventReply->Data);
6865 * Should this event be logged? Events are written sequentially.
6866 * When buffer is full, start again at the top.
6868 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
6871 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
6873 ioc->events[idx].event = event;
6874 ioc->events[idx].eventContext = ioc->eventContext;
6876 for (ii = 0; ii < 2; ii++) {
6878 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
6880 ioc->events[idx].data[ii] = 0;
6883 ioc->eventContext++;
6888 * Call each currently registered protocol event handler.
6890 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6891 if (MptEvHandlers[cb_idx]) {
6892 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Routing Event to event handler #%d\n",
6893 ioc->name, cb_idx));
6894 r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply);
6898 /* FIXME? Examine results here? */
6901 * If needed, send (a single) EventAck.
6903 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
6904 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6905 "EventAck required\n",ioc->name));
6906 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
6907 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SendEventAck returned %d\n",
6912 *evHandlers = handlers;
6916 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6918 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
6919 * @ioc: Pointer to MPT_ADAPTER structure
6920 * @log_info: U32 LogInfo reply word from the IOC
6922 * Refer to lsi/mpi_log_fc.h.
6925 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
6927 char *desc = "unknown";
6929 switch (log_info & 0xFF000000) {
6930 case MPI_IOCLOGINFO_FC_INIT_BASE:
6931 desc = "FCP Initiator";
6933 case MPI_IOCLOGINFO_FC_TARGET_BASE:
6934 desc = "FCP Target";
6936 case MPI_IOCLOGINFO_FC_LAN_BASE:
6939 case MPI_IOCLOGINFO_FC_MSG_BASE:
6940 desc = "MPI Message Layer";
6942 case MPI_IOCLOGINFO_FC_LINK_BASE:
6945 case MPI_IOCLOGINFO_FC_CTX_BASE:
6946 desc = "Context Manager";
6948 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
6949 desc = "Invalid Field Offset";
6951 case MPI_IOCLOGINFO_FC_STATE_CHANGE:
6952 desc = "State Change Info";
6956 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
6957 ioc->name, log_info, desc, (log_info & 0xFFFFFF));
6960 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6962 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
6963 * @ioc: Pointer to MPT_ADAPTER structure
6964 * @log_info: U32 LogInfo word from the IOC
6966 * Refer to lsi/sp_log.h.
6969 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
6971 u32 info = log_info & 0x00FF0000;
6972 char *desc = "unknown";
6976 desc = "bug! MID not found";
6977 if (ioc->reload_fw == 0)
6982 desc = "Parity Error";
6986 desc = "ASYNC Outbound Overrun";
6990 desc = "SYNC Offset Error";
6998 desc = "Msg In Overflow";
7006 desc = "Outbound DMA Overrun";
7010 desc = "Task Management";
7014 desc = "Device Problem";
7018 desc = "Invalid Phase Change";
7022 desc = "Untagged Table Size";
7027 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
7030 /* strings for sas loginfo */
7031 static char *originator_str[] = {
7036 static char *iop_code_str[] = {
7038 "Invalid SAS Address", /* 01h */
7040 "Invalid Page", /* 03h */
7041 "Diag Message Error", /* 04h */
7042 "Task Terminated", /* 05h */
7043 "Enclosure Management", /* 06h */
7044 "Target Mode" /* 07h */
7046 static char *pl_code_str[] = {
7048 "Open Failure", /* 01h */
7049 "Invalid Scatter Gather List", /* 02h */
7050 "Wrong Relative Offset or Frame Length", /* 03h */
7051 "Frame Transfer Error", /* 04h */
7052 "Transmit Frame Connected Low", /* 05h */
7053 "SATA Non-NCQ RW Error Bit Set", /* 06h */
7054 "SATA Read Log Receive Data Error", /* 07h */
7055 "SATA NCQ Fail All Commands After Error", /* 08h */
7056 "SATA Error in Receive Set Device Bit FIS", /* 09h */
7057 "Receive Frame Invalid Message", /* 0Ah */
7058 "Receive Context Message Valid Error", /* 0Bh */
7059 "Receive Frame Current Frame Error", /* 0Ch */
7060 "SATA Link Down", /* 0Dh */
7061 "Discovery SATA Init W IOS", /* 0Eh */
7062 "Config Invalid Page", /* 0Fh */
7063 "Discovery SATA Init Timeout", /* 10h */
7066 "IO Not Yet Executed", /* 13h */
7067 "IO Executed", /* 14h */
7068 "Persistent Reservation Out Not Affiliation "
7070 "Open Transmit DMA Abort", /* 16h */
7071 "IO Device Missing Delay Retry", /* 17h */
7072 "IO Cancelled Due to Recieve Error", /* 18h */
7080 "Enclosure Management" /* 20h */
7082 static char *ir_code_str[] = {
7083 "Raid Action Error", /* 00h */
7093 static char *raid_sub_code_str[] = {
7095 "Volume Creation Failed: Data Passed too "
7097 "Volume Creation Failed: Duplicate Volumes "
7098 "Attempted", /* 02h */
7099 "Volume Creation Failed: Max Number "
7100 "Supported Volumes Exceeded", /* 03h */
7101 "Volume Creation Failed: DMA Error", /* 04h */
7102 "Volume Creation Failed: Invalid Volume Type", /* 05h */
7103 "Volume Creation Failed: Error Reading "
7104 "MFG Page 4", /* 06h */
7105 "Volume Creation Failed: Creating Internal "
7106 "Structures", /* 07h */
7115 "Activation failed: Already Active Volume", /* 10h */
7116 "Activation failed: Unsupported Volume Type", /* 11h */
7117 "Activation failed: Too Many Active Volumes", /* 12h */
7118 "Activation failed: Volume ID in Use", /* 13h */
7119 "Activation failed: Reported Failure", /* 14h */
7120 "Activation failed: Importing a Volume", /* 15h */
7131 "Phys Disk failed: Too Many Phys Disks", /* 20h */
7132 "Phys Disk failed: Data Passed too Large", /* 21h */
7133 "Phys Disk failed: DMA Error", /* 22h */
7134 "Phys Disk failed: Invalid <channel:id>", /* 23h */
7135 "Phys Disk failed: Creating Phys Disk Config "
7148 "Compatibility Error: IR Disabled", /* 30h */
7149 "Compatibility Error: Inquiry Comand Failed", /* 31h */
7150 "Compatibility Error: Device not Direct Access "
7151 "Device ", /* 32h */
7152 "Compatibility Error: Removable Device Found", /* 33h */
7153 "Compatibility Error: Device SCSI Version not "
7154 "2 or Higher", /* 34h */
7155 "Compatibility Error: SATA Device, 48 BIT LBA "
7156 "not Supported", /* 35h */
7157 "Compatibility Error: Device doesn't have "
7158 "512 Byte Block Sizes", /* 36h */
7159 "Compatibility Error: Volume Type Check Failed", /* 37h */
7160 "Compatibility Error: Volume Type is "
7161 "Unsupported by FW", /* 38h */
7162 "Compatibility Error: Disk Drive too Small for "
7163 "use in Volume", /* 39h */
7164 "Compatibility Error: Phys Disk for Create "
7165 "Volume not Found", /* 3Ah */
7166 "Compatibility Error: Too Many or too Few "
7167 "Disks for Volume Type", /* 3Bh */
7168 "Compatibility Error: Disk stripe Sizes "
7169 "Must be 64KB", /* 3Ch */
7170 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
7173 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7175 * mpt_sas_log_info - Log information returned from SAS IOC.
7176 * @ioc: Pointer to MPT_ADAPTER structure
7177 * @log_info: U32 LogInfo reply word from the IOC
7179 * Refer to lsi/mpi_log_sas.h.
7182 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
7184 union loginfo_type {
7193 union loginfo_type sas_loginfo;
7194 char *originator_desc = NULL;
7195 char *code_desc = NULL;
7196 char *sub_code_desc = NULL;
7198 sas_loginfo.loginfo = log_info;
7199 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
7200 (sas_loginfo.dw.originator < ARRAY_SIZE(originator_str)))
7203 originator_desc = originator_str[sas_loginfo.dw.originator];
7205 switch (sas_loginfo.dw.originator) {
7208 if (sas_loginfo.dw.code <
7209 ARRAY_SIZE(iop_code_str))
7210 code_desc = iop_code_str[sas_loginfo.dw.code];
7213 if (sas_loginfo.dw.code <
7214 ARRAY_SIZE(pl_code_str))
7215 code_desc = pl_code_str[sas_loginfo.dw.code];
7218 if (sas_loginfo.dw.code >=
7219 ARRAY_SIZE(ir_code_str))
7221 code_desc = ir_code_str[sas_loginfo.dw.code];
7222 if (sas_loginfo.dw.subcode >=
7223 ARRAY_SIZE(raid_sub_code_str))
7225 if (sas_loginfo.dw.code == 0)
7227 raid_sub_code_str[sas_loginfo.dw.subcode];
7233 if (sub_code_desc != NULL)
7234 printk(MYIOC_s_INFO_FMT
7235 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7237 ioc->name, log_info, originator_desc, code_desc,
7239 else if (code_desc != NULL)
7240 printk(MYIOC_s_INFO_FMT
7241 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7242 " SubCode(0x%04x)\n",
7243 ioc->name, log_info, originator_desc, code_desc,
7244 sas_loginfo.dw.subcode);
7246 printk(MYIOC_s_INFO_FMT
7247 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
7248 " SubCode(0x%04x)\n",
7249 ioc->name, log_info, originator_desc,
7250 sas_loginfo.dw.code, sas_loginfo.dw.subcode);
7253 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7255 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
7256 * @ioc: Pointer to MPT_ADAPTER structure
7257 * @ioc_status: U32 IOCStatus word from IOC
7258 * @mf: Pointer to MPT request frame
7260 * Refer to lsi/mpi.h.
7263 mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7265 Config_t *pReq = (Config_t *)mf;
7266 char extend_desc[EVENT_DESCR_STR_SZ];
7271 if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
7272 page_type = pReq->ExtPageType;
7274 page_type = pReq->Header.PageType;
7277 * ignore invalid page messages for GET_NEXT_HANDLE
7279 form = le32_to_cpu(pReq->PageAddress);
7280 if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
7281 if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
7282 page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
7283 page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
7284 if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
7285 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
7288 if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
7289 if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
7290 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
7294 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
7295 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
7296 page_type, pReq->Header.PageNumber, pReq->Action, form);
7298 switch (ioc_status) {
7300 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7301 desc = "Config Page Invalid Action";
7304 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7305 desc = "Config Page Invalid Type";
7308 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7309 desc = "Config Page Invalid Page";
7312 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7313 desc = "Config Page Invalid Data";
7316 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7317 desc = "Config Page No Defaults";
7320 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7321 desc = "Config Page Can't Commit";
7328 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s: %s\n",
7329 ioc->name, ioc_status, desc, extend_desc));
7333 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
7334 * @ioc: Pointer to MPT_ADAPTER structure
7335 * @ioc_status: U32 IOCStatus word from IOC
7336 * @mf: Pointer to MPT request frame
7338 * Refer to lsi/mpi.h.
7341 mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7343 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
7348 /****************************************************************************/
7349 /* Common IOCStatus values for all replies */
7350 /****************************************************************************/
7352 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
7353 desc = "Invalid Function";
7356 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
7360 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
7361 desc = "Invalid SGL";
7364 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
7365 desc = "Internal Error";
7368 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
7372 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
7373 desc = "Insufficient Resources";
7376 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
7377 desc = "Invalid Field";
7380 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
7381 desc = "Invalid State";
7384 /****************************************************************************/
7385 /* Config IOCStatus values */
7386 /****************************************************************************/
7388 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7389 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7390 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7391 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7392 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7393 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7394 mpt_iocstatus_info_config(ioc, status, mf);
7397 /****************************************************************************/
7398 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
7400 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
7402 /****************************************************************************/
7404 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
7405 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
7406 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
7407 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
7408 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
7409 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
7410 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
7411 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
7412 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
7413 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
7414 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
7415 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
7416 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
7419 /****************************************************************************/
7420 /* SCSI Target values */
7421 /****************************************************************************/
7423 case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
7424 desc = "Target: Priority IO";
7427 case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
7428 desc = "Target: Invalid Port";
7431 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
7432 desc = "Target Invalid IO Index:";
7435 case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
7436 desc = "Target: Aborted";
7439 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
7440 desc = "Target: No Conn Retryable";
7443 case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
7444 desc = "Target: No Connection";
7447 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
7448 desc = "Target: Transfer Count Mismatch";
7451 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
7452 desc = "Target: STS Data not Sent";
7455 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
7456 desc = "Target: Data Offset Error";
7459 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
7460 desc = "Target: Too Much Write Data";
7463 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
7464 desc = "Target: IU Too Short";
7467 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
7468 desc = "Target: ACK NAK Timeout";
7471 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
7472 desc = "Target: Nak Received";
7475 /****************************************************************************/
7476 /* Fibre Channel Direct Access values */
7477 /****************************************************************************/
7479 case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
7480 desc = "FC: Aborted";
7483 case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
7484 desc = "FC: RX ID Invalid";
7487 case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
7488 desc = "FC: DID Invalid";
7491 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
7492 desc = "FC: Node Logged Out";
7495 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
7496 desc = "FC: Exchange Canceled";
7499 /****************************************************************************/
7501 /****************************************************************************/
7503 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
7504 desc = "LAN: Device not Found";
7507 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
7508 desc = "LAN: Device Failure";
7511 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
7512 desc = "LAN: Transmit Error";
7515 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
7516 desc = "LAN: Transmit Aborted";
7519 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
7520 desc = "LAN: Receive Error";
7523 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
7524 desc = "LAN: Receive Aborted";
7527 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
7528 desc = "LAN: Partial Packet";
7531 case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
7532 desc = "LAN: Canceled";
7535 /****************************************************************************/
7536 /* Serial Attached SCSI values */
7537 /****************************************************************************/
7539 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
7540 desc = "SAS: SMP Request Failed";
7543 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
7544 desc = "SAS: SMP Data Overrun";
7555 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s\n",
7556 ioc->name, status, desc));
7559 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7560 EXPORT_SYMBOL(mpt_attach);
7561 EXPORT_SYMBOL(mpt_detach);
7563 EXPORT_SYMBOL(mpt_resume);
7564 EXPORT_SYMBOL(mpt_suspend);
7566 EXPORT_SYMBOL(ioc_list);
7567 EXPORT_SYMBOL(mpt_register);
7568 EXPORT_SYMBOL(mpt_deregister);
7569 EXPORT_SYMBOL(mpt_event_register);
7570 EXPORT_SYMBOL(mpt_event_deregister);
7571 EXPORT_SYMBOL(mpt_reset_register);
7572 EXPORT_SYMBOL(mpt_reset_deregister);
7573 EXPORT_SYMBOL(mpt_device_driver_register);
7574 EXPORT_SYMBOL(mpt_device_driver_deregister);
7575 EXPORT_SYMBOL(mpt_get_msg_frame);
7576 EXPORT_SYMBOL(mpt_put_msg_frame);
7577 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri);
7578 EXPORT_SYMBOL(mpt_free_msg_frame);
7579 EXPORT_SYMBOL(mpt_add_sge);
7580 EXPORT_SYMBOL(mpt_send_handshake_request);
7581 EXPORT_SYMBOL(mpt_verify_adapter);
7582 EXPORT_SYMBOL(mpt_GetIocState);
7583 EXPORT_SYMBOL(mpt_print_ioc_summary);
7584 EXPORT_SYMBOL(mpt_HardResetHandler);
7585 EXPORT_SYMBOL(mpt_config);
7586 EXPORT_SYMBOL(mpt_findImVolumes);
7587 EXPORT_SYMBOL(mpt_alloc_fw_memory);
7588 EXPORT_SYMBOL(mpt_free_fw_memory);
7589 EXPORT_SYMBOL(mptbase_sas_persist_operation);
7590 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
7592 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7594 * fusion_init - Fusion MPT base driver initialization routine.
7596 * Returns 0 for success, non-zero for failure.
7603 show_mptmod_ver(my_NAME, my_VERSION);
7604 printk(KERN_INFO COPYRIGHT "\n");
7606 for (cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
7607 MptCallbacks[cb_idx] = NULL;
7608 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
7609 MptEvHandlers[cb_idx] = NULL;
7610 MptResetHandlers[cb_idx] = NULL;
7613 /* Register ourselves (mptbase) in order to facilitate
7614 * EventNotification handling.
7616 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
7618 /* Register for hard reset handling callbacks.
7620 mpt_reset_register(mpt_base_index, mpt_ioc_reset);
7622 #ifdef CONFIG_PROC_FS
7623 (void) procmpt_create();
7628 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7630 * fusion_exit - Perform driver unload cleanup.
7632 * This routine frees all resources associated with each MPT adapter
7633 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
7639 mpt_reset_deregister(mpt_base_index);
7641 #ifdef CONFIG_PROC_FS
7646 module_init(fusion_init);
7647 module_exit(fusion_exit);