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, 0);
95 MODULE_PARM_DESC(mpt_msi_enable_sas, " Enable MSI Support for SAS \
96 controllers (default=0)");
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 \
110 int mpt_fwfault_debug;
111 EXPORT_SYMBOL(mpt_fwfault_debug);
112 module_param_call(mpt_fwfault_debug, param_set_int, param_get_int,
113 &mpt_fwfault_debug, 0600);
114 MODULE_PARM_DESC(mpt_fwfault_debug, "Enable detection of Firmware fault"
115 " and halt Firmware on fault - (default=0)");
120 static int mfcounter = 0;
121 #define PRINT_MF_COUNT 20000
124 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
129 static struct proc_dir_entry *mpt_proc_root_dir;
131 #define WHOINIT_UNKNOWN 0xAA
133 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
137 /* Adapter link list */
139 /* Callback lookup table */
140 static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
141 /* Protocol driver class lookup table */
142 static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
143 /* Event handler lookup table */
144 static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
145 /* Reset handler lookup table */
146 static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
147 static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
151 * Driver Callback Index's
153 static u8 mpt_base_index = MPT_MAX_PROTOCOL_DRIVERS;
154 static u8 last_drv_idx;
156 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
160 static irqreturn_t mpt_interrupt(int irq, void *bus_id);
161 static int mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
162 MPT_FRAME_HDR *reply);
163 static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
164 u32 *req, int replyBytes, u16 *u16reply, int maxwait,
166 static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
167 static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
168 static void mpt_adapter_disable(MPT_ADAPTER *ioc);
169 static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
171 static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
172 static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
173 static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
174 static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
175 static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
176 static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
177 static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
178 static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
179 static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
180 static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
181 static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
182 static int PrimeIocFifos(MPT_ADAPTER *ioc);
183 static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
184 static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
185 static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
186 static int GetLanConfigPages(MPT_ADAPTER *ioc);
187 static int GetIoUnitPage2(MPT_ADAPTER *ioc);
188 int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
189 static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
190 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
191 static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
192 static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
193 static void mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc);
194 static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch,
196 static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
197 static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
198 static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
200 #ifdef CONFIG_PROC_FS
201 static int procmpt_summary_read(char *buf, char **start, off_t offset,
202 int request, int *eof, void *data);
203 static int procmpt_version_read(char *buf, char **start, off_t offset,
204 int request, int *eof, void *data);
205 static int procmpt_iocinfo_read(char *buf, char **start, off_t offset,
206 int request, int *eof, void *data);
208 static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
210 //int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
211 static int ProcessEventNotification(MPT_ADAPTER *ioc,
212 EventNotificationReply_t *evReply, int *evHandlers);
213 static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
214 static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
215 static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
216 static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
217 static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
218 static void mpt_inactive_raid_list_free(MPT_ADAPTER *ioc);
220 /* module entry point */
221 static int __init fusion_init (void);
222 static void __exit fusion_exit (void);
224 #define CHIPREG_READ32(addr) readl_relaxed(addr)
225 #define CHIPREG_READ32_dmasync(addr) readl(addr)
226 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
227 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
228 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
231 pci_disable_io_access(struct pci_dev *pdev)
235 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
237 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
241 pci_enable_io_access(struct pci_dev *pdev)
245 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
247 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
250 static int mpt_set_debug_level(const char *val, struct kernel_param *kp)
252 int ret = param_set_int(val, kp);
258 list_for_each_entry(ioc, &ioc_list, list)
259 ioc->debug_level = mpt_debug_level;
264 * mpt_get_cb_idx - obtain cb_idx for registered driver
265 * @dclass: class driver enum
267 * Returns cb_idx, or zero means it wasn't found
270 mpt_get_cb_idx(MPT_DRIVER_CLASS dclass)
274 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--)
275 if (MptDriverClass[cb_idx] == dclass)
281 * mpt_is_discovery_complete - determine if discovery has completed
282 * @ioc: per adatper instance
284 * Returns 1 when discovery completed, else zero.
287 mpt_is_discovery_complete(MPT_ADAPTER *ioc)
289 ConfigExtendedPageHeader_t hdr;
291 SasIOUnitPage0_t *buffer;
292 dma_addr_t dma_handle;
295 memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
296 memset(&cfg, 0, sizeof(CONFIGPARMS));
297 hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
298 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
299 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
300 cfg.cfghdr.ehdr = &hdr;
301 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
303 if ((mpt_config(ioc, &cfg)))
305 if (!hdr.ExtPageLength)
308 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
313 cfg.physAddr = dma_handle;
314 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
316 if ((mpt_config(ioc, &cfg)))
317 goto out_free_consistent;
319 if (!(buffer->PhyData[0].PortFlags &
320 MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS))
324 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
331 * mpt_fault_reset_work - work performed on workq after ioc fault
332 * @work: input argument, used to derive ioc
336 mpt_fault_reset_work(struct work_struct *work)
339 container_of(work, MPT_ADAPTER, fault_reset_work.work);
344 if (ioc->ioc_reset_in_progress || !ioc->active)
347 ioc_raw_state = mpt_GetIocState(ioc, 0);
348 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
349 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state (%04xh)!!!\n",
350 ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
351 printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n",
352 ioc->name, __func__);
353 rc = mpt_HardResetHandler(ioc, CAN_SLEEP);
354 printk(MYIOC_s_WARN_FMT "%s: HardReset: %s\n", ioc->name,
355 __func__, (rc == 0) ? "success" : "failed");
356 ioc_raw_state = mpt_GetIocState(ioc, 0);
357 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT)
358 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state after "
359 "reset (%04xh)\n", ioc->name, ioc_raw_state &
360 MPI_DOORBELL_DATA_MASK);
361 } else if (ioc->bus_type == SAS && ioc->sas_discovery_quiesce_io) {
362 if ((mpt_is_discovery_complete(ioc))) {
363 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "clearing "
364 "discovery_quiesce_io flag\n", ioc->name));
365 ioc->sas_discovery_quiesce_io = 0;
371 * Take turns polling alternate controller
376 /* rearm the timer */
377 spin_lock_irqsave(&ioc->fault_reset_work_lock, flags);
378 if (ioc->reset_work_q)
379 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
380 msecs_to_jiffies(MPT_POLLING_INTERVAL));
381 spin_unlock_irqrestore(&ioc->fault_reset_work_lock, flags);
386 * Process turbo (context) reply...
389 mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
391 MPT_FRAME_HDR *mf = NULL;
392 MPT_FRAME_HDR *mr = NULL;
396 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got TURBO reply req_idx=%08x\n",
399 switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
400 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
401 req_idx = pa & 0x0000FFFF;
402 cb_idx = (pa & 0x00FF0000) >> 16;
403 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
405 case MPI_CONTEXT_REPLY_TYPE_LAN:
406 cb_idx = mpt_get_cb_idx(MPTLAN_DRIVER);
408 * Blind set of mf to NULL here was fatal
409 * after lan_reply says "freeme"
410 * Fix sort of combined with an optimization here;
411 * added explicit check for case where lan_reply
412 * was just returning 1 and doing nothing else.
413 * For this case skip the callback, but set up
414 * proper mf value first here:-)
416 if ((pa & 0x58000000) == 0x58000000) {
417 req_idx = pa & 0x0000FFFF;
418 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
419 mpt_free_msg_frame(ioc, mf);
424 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
426 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
427 cb_idx = mpt_get_cb_idx(MPTSTM_DRIVER);
428 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
435 /* Check for (valid) IO callback! */
436 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
437 MptCallbacks[cb_idx] == NULL) {
438 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
439 __func__, ioc->name, cb_idx);
443 if (MptCallbacks[cb_idx](ioc, mf, mr))
444 mpt_free_msg_frame(ioc, mf);
450 mpt_reply(MPT_ADAPTER *ioc, u32 pa)
461 /* non-TURBO reply! Hmmm, something may be up...
462 * Newest turbo reply mechanism; get address
463 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
466 /* Map DMA address of reply header to cpu address.
467 * pa is 32 bits - but the dma address may be 32 or 64 bits
468 * get offset based only only the low addresses
471 reply_dma_low = (pa <<= 1);
472 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
473 (reply_dma_low - ioc->reply_frames_low_dma));
475 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
476 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
477 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
479 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
480 ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
481 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mr);
483 /* Check/log IOC log info
485 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
486 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
487 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
488 if (ioc->bus_type == FC)
489 mpt_fc_log_info(ioc, log_info);
490 else if (ioc->bus_type == SPI)
491 mpt_spi_log_info(ioc, log_info);
492 else if (ioc->bus_type == SAS)
493 mpt_sas_log_info(ioc, log_info);
496 if (ioc_stat & MPI_IOCSTATUS_MASK)
497 mpt_iocstatus_info(ioc, (u32)ioc_stat, mf);
499 /* Check for (valid) IO callback! */
500 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
501 MptCallbacks[cb_idx] == NULL) {
502 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
503 __func__, ioc->name, cb_idx);
508 freeme = MptCallbacks[cb_idx](ioc, mf, mr);
511 /* Flush (non-TURBO) reply with a WRITE! */
512 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
515 mpt_free_msg_frame(ioc, mf);
519 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
521 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
522 * @irq: irq number (not used)
523 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
525 * This routine is registered via the request_irq() kernel API call,
526 * and handles all interrupts generated from a specific MPT adapter
527 * (also referred to as a IO Controller or IOC).
528 * This routine must clear the interrupt from the adapter and does
529 * so by reading the reply FIFO. Multiple replies may be processed
530 * per single call to this routine.
532 * This routine handles register-level access of the adapter but
533 * dispatches (calls) a protocol-specific callback routine to handle
534 * the protocol-specific details of the MPT request completion.
537 mpt_interrupt(int irq, void *bus_id)
539 MPT_ADAPTER *ioc = bus_id;
540 u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
542 if (pa == 0xFFFFFFFF)
546 * Drain the reply FIFO!
549 if (pa & MPI_ADDRESS_REPLY_A_BIT)
552 mpt_turbo_reply(ioc, pa);
553 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
554 } while (pa != 0xFFFFFFFF);
559 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
561 * mptbase_reply - MPT base driver's callback routine
562 * @ioc: Pointer to MPT_ADAPTER structure
563 * @req: Pointer to original MPT request frame
564 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
566 * MPT base driver's callback routine; all base driver
567 * "internal" request/reply processing is routed here.
568 * Currently used for EventNotification and EventAck handling.
570 * Returns 1 indicating original alloc'd request frame ptr
571 * should be freed, or 0 if it shouldn't.
574 mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
576 EventNotificationReply_t *pEventReply;
581 switch (reply->u.hdr.Function) {
582 case MPI_FUNCTION_EVENT_NOTIFICATION:
583 pEventReply = (EventNotificationReply_t *)reply;
585 ProcessEventNotification(ioc, pEventReply, &evHandlers);
586 event = le32_to_cpu(pEventReply->Event) & 0xFF;
587 if (pEventReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)
589 if (event != MPI_EVENT_EVENT_CHANGE)
591 case MPI_FUNCTION_CONFIG:
592 case MPI_FUNCTION_SAS_IO_UNIT_CONTROL:
593 ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
595 ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
596 memcpy(ioc->mptbase_cmds.reply, reply,
597 min(MPT_DEFAULT_FRAME_SIZE,
598 4 * reply->u.reply.MsgLength));
600 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) {
601 ioc->mptbase_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
602 complete(&ioc->mptbase_cmds.done);
605 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_FREE_MF)
608 case MPI_FUNCTION_EVENT_ACK:
609 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
610 "EventAck reply received\n", ioc->name));
613 printk(MYIOC_s_ERR_FMT
614 "Unexpected msg function (=%02Xh) reply received!\n",
615 ioc->name, reply->u.hdr.Function);
620 * Conditionally tell caller to free the original
621 * EventNotification/EventAck/unexpected request frame!
626 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
628 * mpt_register - Register protocol-specific main callback handler.
629 * @cbfunc: callback function pointer
630 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
632 * This routine is called by a protocol-specific driver (SCSI host,
633 * LAN, SCSI target) to register its reply callback routine. Each
634 * protocol-specific driver must do this before it will be able to
635 * use any IOC resources, such as obtaining request frames.
637 * NOTES: The SCSI protocol driver currently calls this routine thrice
638 * in order to register separate callbacks; one for "normal" SCSI IO;
639 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
641 * Returns u8 valued "handle" in the range (and S.O.D. order)
642 * {N,...,7,6,5,...,1} if successful.
643 * A return value of MPT_MAX_PROTOCOL_DRIVERS (including zero!) should be
644 * considered an error by the caller.
647 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
650 last_drv_idx = MPT_MAX_PROTOCOL_DRIVERS;
653 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
654 * (slot/handle 0 is reserved!)
656 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
657 if (MptCallbacks[cb_idx] == NULL) {
658 MptCallbacks[cb_idx] = cbfunc;
659 MptDriverClass[cb_idx] = dclass;
660 MptEvHandlers[cb_idx] = NULL;
661 last_drv_idx = cb_idx;
669 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
671 * mpt_deregister - Deregister a protocol drivers resources.
672 * @cb_idx: previously registered callback handle
674 * Each protocol-specific driver should call this routine when its
675 * module is unloaded.
678 mpt_deregister(u8 cb_idx)
680 if (cb_idx && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
681 MptCallbacks[cb_idx] = NULL;
682 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
683 MptEvHandlers[cb_idx] = NULL;
689 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
691 * mpt_event_register - Register protocol-specific event callback handler.
692 * @cb_idx: previously registered (via mpt_register) callback handle
693 * @ev_cbfunc: callback function
695 * This routine can be called by one or more protocol-specific drivers
696 * if/when they choose to be notified of MPT events.
698 * Returns 0 for success.
701 mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc)
703 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
706 MptEvHandlers[cb_idx] = ev_cbfunc;
710 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
712 * mpt_event_deregister - Deregister protocol-specific event callback handler
713 * @cb_idx: previously registered callback handle
715 * Each protocol-specific driver should call this routine
716 * when it does not (or can no longer) handle events,
717 * or when its module is unloaded.
720 mpt_event_deregister(u8 cb_idx)
722 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
725 MptEvHandlers[cb_idx] = NULL;
728 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
730 * mpt_reset_register - Register protocol-specific IOC reset handler.
731 * @cb_idx: previously registered (via mpt_register) callback handle
732 * @reset_func: reset function
734 * This routine can be called by one or more protocol-specific drivers
735 * if/when they choose to be notified of IOC resets.
737 * Returns 0 for success.
740 mpt_reset_register(u8 cb_idx, MPT_RESETHANDLER reset_func)
742 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
745 MptResetHandlers[cb_idx] = reset_func;
749 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
751 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
752 * @cb_idx: previously registered callback handle
754 * Each protocol-specific driver should call this routine
755 * when it does not (or can no longer) handle IOC reset handling,
756 * or when its module is unloaded.
759 mpt_reset_deregister(u8 cb_idx)
761 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
764 MptResetHandlers[cb_idx] = NULL;
767 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
769 * mpt_device_driver_register - Register device driver hooks
770 * @dd_cbfunc: driver callbacks struct
771 * @cb_idx: MPT protocol driver index
774 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, u8 cb_idx)
777 const struct pci_device_id *id;
779 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
782 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
784 /* call per pci device probe entry point */
785 list_for_each_entry(ioc, &ioc_list, list) {
786 id = ioc->pcidev->driver ?
787 ioc->pcidev->driver->id_table : NULL;
788 if (dd_cbfunc->probe)
789 dd_cbfunc->probe(ioc->pcidev, id);
795 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
797 * mpt_device_driver_deregister - DeRegister device driver hooks
798 * @cb_idx: MPT protocol driver index
801 mpt_device_driver_deregister(u8 cb_idx)
803 struct mpt_pci_driver *dd_cbfunc;
806 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
809 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
811 list_for_each_entry(ioc, &ioc_list, list) {
812 if (dd_cbfunc->remove)
813 dd_cbfunc->remove(ioc->pcidev);
816 MptDeviceDriverHandlers[cb_idx] = NULL;
820 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
822 * mpt_get_msg_frame - Obtain an MPT request frame from the pool
823 * @cb_idx: Handle of registered MPT protocol driver
824 * @ioc: Pointer to MPT adapter structure
826 * Obtain an MPT request frame from the pool (of 1024) that are
827 * allocated per MPT adapter.
829 * Returns pointer to a MPT request frame or %NULL if none are available
830 * or IOC is not active.
833 mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc)
837 u16 req_idx; /* Request index */
839 /* validate handle and ioc identifier */
843 printk(MYIOC_s_WARN_FMT "IOC Not Active! mpt_get_msg_frame "
844 "returning NULL!\n", ioc->name);
847 /* If interrupts are not attached, do not return a request frame */
851 spin_lock_irqsave(&ioc->FreeQlock, flags);
852 if (!list_empty(&ioc->FreeQ)) {
855 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
856 u.frame.linkage.list);
857 list_del(&mf->u.frame.linkage.list);
858 mf->u.frame.linkage.arg1 = 0;
859 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
860 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
862 req_idx = req_offset / ioc->req_sz;
863 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
864 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
865 /* Default, will be changed if necessary in SG generation */
866 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame;
873 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
877 printk(MYIOC_s_WARN_FMT "IOC Active. No free Msg Frames! "
878 "Count 0x%x Max 0x%x\n", ioc->name, ioc->mfcnt,
881 if (mfcounter == PRINT_MF_COUNT)
882 printk(MYIOC_s_INFO_FMT "MF Count 0x%x Max 0x%x \n", ioc->name,
883 ioc->mfcnt, ioc->req_depth);
886 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_get_msg_frame(%d,%d), got mf=%p\n",
887 ioc->name, cb_idx, ioc->id, mf));
891 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
893 * mpt_put_msg_frame - Send a protocol-specific MPT request frame to an IOC
894 * @cb_idx: Handle of registered MPT protocol driver
895 * @ioc: Pointer to MPT adapter structure
896 * @mf: Pointer to MPT request frame
898 * This routine posts an MPT request frame to the request post FIFO of a
899 * specific MPT adapter.
902 mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
906 u16 req_idx; /* Request index */
908 /* ensure values are reset properly! */
909 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
910 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
912 req_idx = req_offset / ioc->req_sz;
913 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
914 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
916 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
918 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
919 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d "
920 "RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx,
921 ioc->RequestNB[req_idx]));
922 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
926 * mpt_put_msg_frame_hi_pri - Send a hi-pri protocol-specific MPT request frame
927 * @cb_idx: Handle of registered MPT protocol driver
928 * @ioc: Pointer to MPT adapter structure
929 * @mf: Pointer to MPT request frame
931 * Send a protocol-specific MPT request frame to an IOC using
932 * hi-priority request queue.
934 * This routine posts an MPT request frame to the request post FIFO of a
935 * specific MPT adapter.
938 mpt_put_msg_frame_hi_pri(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
942 u16 req_idx; /* Request index */
944 /* ensure values are reset properly! */
945 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
946 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
947 req_idx = req_offset / ioc->req_sz;
948 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
949 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
951 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
953 mf_dma_addr = (ioc->req_frames_low_dma + req_offset);
954 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d\n",
955 ioc->name, mf_dma_addr, req_idx));
956 CHIPREG_WRITE32(&ioc->chip->RequestHiPriFifo, mf_dma_addr);
959 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
961 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
962 * @ioc: Pointer to MPT adapter structure
963 * @mf: Pointer to MPT request frame
965 * This routine places a MPT request frame back on the MPT adapter's
969 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
973 /* Put Request back on FreeQ! */
974 spin_lock_irqsave(&ioc->FreeQlock, flags);
975 mf->u.frame.linkage.arg1 = 0xdeadbeaf; /* signature to know if this mf is freed */
976 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
980 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
983 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
985 * mpt_add_sge - Place a simple 32 bit SGE at address pAddr.
986 * @pAddr: virtual address for SGE
987 * @flagslength: SGE flags and data transfer length
988 * @dma_addr: Physical address
990 * This routine places a MPT request frame back on the MPT adapter's
994 mpt_add_sge(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
996 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
997 pSge->FlagsLength = cpu_to_le32(flagslength);
998 pSge->Address = cpu_to_le32(dma_addr);
1002 * mpt_add_sge_64bit - Place a simple 64 bit SGE at address pAddr.
1003 * @pAddr: virtual address for SGE
1004 * @flagslength: SGE flags and data transfer length
1005 * @dma_addr: Physical address
1007 * This routine places a MPT request frame back on the MPT adapter's
1011 mpt_add_sge_64bit(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1013 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1014 pSge->Address.Low = cpu_to_le32
1015 (lower_32_bits((unsigned long)(dma_addr)));
1016 pSge->Address.High = cpu_to_le32
1017 (upper_32_bits((unsigned long)dma_addr));
1018 pSge->FlagsLength = cpu_to_le32
1019 ((flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1023 * mpt_add_sge_64bit_1078 - Place a simple 64 bit SGE at address pAddr
1024 * (1078 workaround).
1025 * @pAddr: virtual address for SGE
1026 * @flagslength: SGE flags and data transfer length
1027 * @dma_addr: Physical address
1029 * This routine places a MPT request frame back on the MPT adapter's
1033 mpt_add_sge_64bit_1078(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1035 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1038 pSge->Address.Low = cpu_to_le32
1039 (lower_32_bits((unsigned long)(dma_addr)));
1040 tmp = (u32)(upper_32_bits((unsigned long)dma_addr));
1043 * 1078 errata workaround for the 36GB limitation
1045 if ((((u64)dma_addr + MPI_SGE_LENGTH(flagslength)) >> 32) == 9) {
1047 MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_LOCAL_ADDRESS);
1049 if (mpt_debug_level & MPT_DEBUG_36GB_MEM)
1050 printk(KERN_DEBUG "1078 P0M2 addressing for "
1051 "addr = 0x%llx len = %d\n",
1052 (unsigned long long)dma_addr,
1053 MPI_SGE_LENGTH(flagslength));
1056 pSge->Address.High = cpu_to_le32(tmp);
1057 pSge->FlagsLength = cpu_to_le32(
1058 (flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1061 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1063 * mpt_add_chain - Place a 32 bit chain SGE at address pAddr.
1064 * @pAddr: virtual address for SGE
1065 * @next: nextChainOffset value (u32's)
1066 * @length: length of next SGL segment
1067 * @dma_addr: Physical address
1071 mpt_add_chain(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1073 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
1074 pChain->Length = cpu_to_le16(length);
1075 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT;
1076 pChain->NextChainOffset = next;
1077 pChain->Address = cpu_to_le32(dma_addr);
1080 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1082 * mpt_add_chain_64bit - Place a 64 bit chain SGE at address pAddr.
1083 * @pAddr: virtual address for SGE
1084 * @next: nextChainOffset value (u32's)
1085 * @length: length of next SGL segment
1086 * @dma_addr: Physical address
1090 mpt_add_chain_64bit(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1092 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
1093 u32 tmp = dma_addr & 0xFFFFFFFF;
1095 pChain->Length = cpu_to_le16(length);
1096 pChain->Flags = (MPI_SGE_FLAGS_CHAIN_ELEMENT |
1097 MPI_SGE_FLAGS_64_BIT_ADDRESSING);
1099 pChain->NextChainOffset = next;
1101 pChain->Address.Low = cpu_to_le32(tmp);
1102 tmp = (u32)(upper_32_bits((unsigned long)dma_addr));
1103 pChain->Address.High = cpu_to_le32(tmp);
1106 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1108 * mpt_send_handshake_request - Send MPT request via doorbell handshake method.
1109 * @cb_idx: Handle of registered MPT protocol driver
1110 * @ioc: Pointer to MPT adapter structure
1111 * @reqBytes: Size of the request in bytes
1112 * @req: Pointer to MPT request frame
1113 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1115 * This routine is used exclusively to send MptScsiTaskMgmt
1116 * requests since they are required to be sent via doorbell handshake.
1118 * NOTE: It is the callers responsibility to byte-swap fields in the
1119 * request which are greater than 1 byte in size.
1121 * Returns 0 for success, non-zero for failure.
1124 mpt_send_handshake_request(u8 cb_idx, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
1130 /* State is known to be good upon entering
1131 * this function so issue the bus reset
1136 * Emulate what mpt_put_msg_frame() does /wrt to sanity
1137 * setting cb_idx/req_idx. But ONLY if this request
1138 * is in proper (pre-alloc'd) request buffer range...
1140 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
1141 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
1142 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
1143 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
1144 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
1147 /* Make sure there are no doorbells */
1148 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1150 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1151 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
1152 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
1154 /* Wait for IOC doorbell int */
1155 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
1159 /* Read doorbell and check for active bit */
1160 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
1163 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_send_handshake_request start, WaitCnt=%d\n",
1166 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1168 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1172 /* Send request via doorbell handshake */
1173 req_as_bytes = (u8 *) req;
1174 for (ii = 0; ii < reqBytes/4; ii++) {
1177 word = ((req_as_bytes[(ii*4) + 0] << 0) |
1178 (req_as_bytes[(ii*4) + 1] << 8) |
1179 (req_as_bytes[(ii*4) + 2] << 16) |
1180 (req_as_bytes[(ii*4) + 3] << 24));
1181 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
1182 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1188 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
1193 /* Make sure there are no doorbells */
1194 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1199 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1201 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
1202 * @ioc: Pointer to MPT adapter structure
1203 * @access_control_value: define bits below
1204 * @sleepFlag: Specifies whether the process can sleep
1206 * Provides mechanism for the host driver to control the IOC's
1207 * Host Page Buffer access.
1209 * Access Control Value - bits[15:12]
1211 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1212 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1213 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1215 * Returns 0 for success, non-zero for failure.
1219 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1223 /* return if in use */
1224 if (CHIPREG_READ32(&ioc->chip->Doorbell)
1225 & MPI_DOORBELL_ACTIVE)
1228 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1230 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1231 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1232 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1233 (access_control_value<<12)));
1235 /* Wait for IOC to clear Doorbell Status bit */
1236 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1242 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1244 * mpt_host_page_alloc - allocate system memory for the fw
1245 * @ioc: Pointer to pointer to IOC adapter
1246 * @ioc_init: Pointer to ioc init config page
1248 * If we already allocated memory in past, then resend the same pointer.
1249 * Returns 0 for success, non-zero for failure.
1252 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1256 u32 host_page_buffer_sz=0;
1258 if(!ioc->HostPageBuffer) {
1260 host_page_buffer_sz =
1261 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1263 if(!host_page_buffer_sz)
1264 return 0; /* fw doesn't need any host buffers */
1266 /* spin till we get enough memory */
1267 while(host_page_buffer_sz > 0) {
1269 if((ioc->HostPageBuffer = pci_alloc_consistent(
1271 host_page_buffer_sz,
1272 &ioc->HostPageBuffer_dma)) != NULL) {
1274 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1275 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1276 ioc->name, ioc->HostPageBuffer,
1277 (u32)ioc->HostPageBuffer_dma,
1278 host_page_buffer_sz));
1279 ioc->alloc_total += host_page_buffer_sz;
1280 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1284 host_page_buffer_sz -= (4*1024);
1288 if(!ioc->HostPageBuffer) {
1289 printk(MYIOC_s_ERR_FMT
1290 "Failed to alloc memory for host_page_buffer!\n",
1295 psge = (char *)&ioc_init->HostPageBufferSGE;
1296 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1297 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1298 MPI_SGE_FLAGS_32_BIT_ADDRESSING |
1299 MPI_SGE_FLAGS_HOST_TO_IOC |
1300 MPI_SGE_FLAGS_END_OF_BUFFER;
1301 if (sizeof(dma_addr_t) == sizeof(u64)) {
1302 flags_length |= MPI_SGE_FLAGS_64_BIT_ADDRESSING;
1304 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1305 flags_length |= ioc->HostPageBuffer_sz;
1306 ioc->add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1307 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1312 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1314 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1315 * @iocid: IOC unique identifier (integer)
1316 * @iocpp: Pointer to pointer to IOC adapter
1318 * Given a unique IOC identifier, set pointer to the associated MPT
1319 * adapter structure.
1321 * Returns iocid and sets iocpp if iocid is found.
1322 * Returns -1 if iocid is not found.
1325 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1329 list_for_each_entry(ioc,&ioc_list,list) {
1330 if (ioc->id == iocid) {
1341 * mpt_get_product_name - returns product string
1342 * @vendor: pci vendor id
1343 * @device: pci device id
1344 * @revision: pci revision id
1345 * @prod_name: string returned
1347 * Returns product string displayed when driver loads,
1348 * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1352 mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name)
1354 char *product_str = NULL;
1356 if (vendor == PCI_VENDOR_ID_BROCADE) {
1359 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1363 product_str = "BRE040 A0";
1366 product_str = "BRE040 A1";
1369 product_str = "BRE040";
1379 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1380 product_str = "LSIFC909 B1";
1382 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1383 product_str = "LSIFC919 B0";
1385 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1386 product_str = "LSIFC929 B0";
1388 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1389 if (revision < 0x80)
1390 product_str = "LSIFC919X A0";
1392 product_str = "LSIFC919XL A1";
1394 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1395 if (revision < 0x80)
1396 product_str = "LSIFC929X A0";
1398 product_str = "LSIFC929XL A1";
1400 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1401 product_str = "LSIFC939X A1";
1403 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1404 product_str = "LSIFC949X A1";
1406 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1410 product_str = "LSIFC949E A0";
1413 product_str = "LSIFC949E A1";
1416 product_str = "LSIFC949E";
1420 case MPI_MANUFACTPAGE_DEVID_53C1030:
1424 product_str = "LSI53C1030 A0";
1427 product_str = "LSI53C1030 B0";
1430 product_str = "LSI53C1030 B1";
1433 product_str = "LSI53C1030 B2";
1436 product_str = "LSI53C1030 C0";
1439 product_str = "LSI53C1030T A0";
1442 product_str = "LSI53C1030T A2";
1445 product_str = "LSI53C1030T A3";
1448 product_str = "LSI53C1020A A1";
1451 product_str = "LSI53C1030";
1455 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1459 product_str = "LSI53C1035 A2";
1462 product_str = "LSI53C1035 B0";
1465 product_str = "LSI53C1035";
1469 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1473 product_str = "LSISAS1064 A1";
1476 product_str = "LSISAS1064 A2";
1479 product_str = "LSISAS1064 A3";
1482 product_str = "LSISAS1064 A4";
1485 product_str = "LSISAS1064";
1489 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1493 product_str = "LSISAS1064E A0";
1496 product_str = "LSISAS1064E B0";
1499 product_str = "LSISAS1064E B1";
1502 product_str = "LSISAS1064E B2";
1505 product_str = "LSISAS1064E B3";
1508 product_str = "LSISAS1064E";
1512 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1516 product_str = "LSISAS1068 A0";
1519 product_str = "LSISAS1068 B0";
1522 product_str = "LSISAS1068 B1";
1525 product_str = "LSISAS1068";
1529 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1533 product_str = "LSISAS1068E A0";
1536 product_str = "LSISAS1068E B0";
1539 product_str = "LSISAS1068E B1";
1542 product_str = "LSISAS1068E B2";
1545 product_str = "LSISAS1068E B3";
1548 product_str = "LSISAS1068E";
1552 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1556 product_str = "LSISAS1078 A0";
1559 product_str = "LSISAS1078 B0";
1562 product_str = "LSISAS1078 C0";
1565 product_str = "LSISAS1078 C1";
1568 product_str = "LSISAS1078 C2";
1571 product_str = "LSISAS1078";
1579 sprintf(prod_name, "%s", product_str);
1583 * mpt_mapresources - map in memory mapped io
1584 * @ioc: Pointer to pointer to IOC adapter
1588 mpt_mapresources(MPT_ADAPTER *ioc)
1592 unsigned long mem_phys;
1598 struct pci_dev *pdev;
1601 ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
1602 if (pci_enable_device_mem(pdev)) {
1603 printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() "
1604 "failed\n", ioc->name);
1607 if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) {
1608 printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with "
1609 "MEM failed\n", ioc->name);
1613 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1615 if (sizeof(dma_addr_t) > 4) {
1616 const uint64_t required_mask = dma_get_required_mask
1618 if (required_mask > DMA_BIT_MASK(32)
1619 && !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
1620 && !pci_set_consistent_dma_mask(pdev,
1621 DMA_BIT_MASK(64))) {
1622 ioc->dma_mask = DMA_BIT_MASK(64);
1623 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1624 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1626 } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1627 && !pci_set_consistent_dma_mask(pdev,
1628 DMA_BIT_MASK(32))) {
1629 ioc->dma_mask = DMA_BIT_MASK(32);
1630 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1631 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1634 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1635 ioc->name, pci_name(pdev));
1639 if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1640 && !pci_set_consistent_dma_mask(pdev,
1641 DMA_BIT_MASK(32))) {
1642 ioc->dma_mask = DMA_BIT_MASK(32);
1643 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1644 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1647 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1648 ioc->name, pci_name(pdev));
1653 mem_phys = msize = 0;
1655 for (ii = 0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1656 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1659 /* Get I/O space! */
1660 port = pci_resource_start(pdev, ii);
1661 psize = pci_resource_len(pdev, ii);
1666 mem_phys = pci_resource_start(pdev, ii);
1667 msize = pci_resource_len(pdev, ii);
1670 ioc->mem_size = msize;
1673 /* Get logical ptr for PciMem0 space */
1674 /*mem = ioremap(mem_phys, msize);*/
1675 mem = ioremap(mem_phys, msize);
1677 printk(MYIOC_s_ERR_FMT ": ERROR - Unable to map adapter"
1678 " memory!\n", ioc->name);
1682 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %lx\n",
1683 ioc->name, mem, mem_phys));
1685 ioc->mem_phys = mem_phys;
1686 ioc->chip = (SYSIF_REGS __iomem *)mem;
1688 /* Save Port IO values in case we need to do downloadboot */
1689 ioc->pio_mem_phys = port;
1690 ioc->pio_chip = (SYSIF_REGS __iomem *)port;
1695 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1697 * mpt_attach - Install a PCI intelligent MPT adapter.
1698 * @pdev: Pointer to pci_dev structure
1699 * @id: PCI device ID information
1701 * This routine performs all the steps necessary to bring the IOC of
1702 * a MPT adapter to a OPERATIONAL state. This includes registering
1703 * memory regions, registering the interrupt, and allocating request
1704 * and reply memory pools.
1706 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1709 * Returns 0 for success, non-zero for failure.
1711 * TODO: Add support for polled controllers
1714 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1721 static int mpt_ids = 0;
1722 #ifdef CONFIG_PROC_FS
1723 struct proc_dir_entry *dent, *ent;
1726 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1728 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1732 ioc->id = mpt_ids++;
1733 sprintf(ioc->name, "ioc%d", ioc->id);
1736 * set initial debug level
1737 * (refer to mptdebug.h)
1740 ioc->debug_level = mpt_debug_level;
1741 if (mpt_debug_level)
1742 printk(KERN_INFO "mpt_debug_level=%xh\n", mpt_debug_level);
1744 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name));
1747 if (mpt_mapresources(ioc)) {
1753 * Setting up proper handlers for scatter gather handling
1755 if (ioc->dma_mask == DMA_BIT_MASK(64)) {
1756 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
1757 ioc->add_sge = &mpt_add_sge_64bit_1078;
1759 ioc->add_sge = &mpt_add_sge_64bit;
1760 ioc->add_chain = &mpt_add_chain_64bit;
1761 ioc->sg_addr_size = 8;
1763 ioc->add_sge = &mpt_add_sge;
1764 ioc->add_chain = &mpt_add_chain;
1765 ioc->sg_addr_size = 4;
1767 ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
1769 ioc->alloc_total = sizeof(MPT_ADAPTER);
1770 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1771 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1774 spin_lock_init(&ioc->initializing_hba_lock);
1776 spin_lock_init(&ioc->taskmgmt_lock);
1777 mutex_init(&ioc->internal_cmds.mutex);
1778 init_completion(&ioc->internal_cmds.done);
1779 mutex_init(&ioc->mptbase_cmds.mutex);
1780 init_completion(&ioc->mptbase_cmds.done);
1781 mutex_init(&ioc->taskmgmt_cmds.mutex);
1782 init_completion(&ioc->taskmgmt_cmds.done);
1784 /* Initialize the event logging.
1786 ioc->eventTypes = 0; /* None */
1787 ioc->eventContext = 0;
1788 ioc->eventLogSize = 0;
1795 ioc->cached_fw = NULL;
1797 /* Initilize SCSI Config Data structure
1799 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1801 /* Initialize the fc rport list head.
1803 INIT_LIST_HEAD(&ioc->fc_rports);
1805 /* Find lookup slot. */
1806 INIT_LIST_HEAD(&ioc->list);
1809 /* Initialize workqueue */
1810 INIT_DELAYED_WORK(&ioc->fault_reset_work, mpt_fault_reset_work);
1811 spin_lock_init(&ioc->fault_reset_work_lock);
1813 snprintf(ioc->reset_work_q_name, sizeof(ioc->reset_work_q_name),
1814 "mpt_poll_%d", ioc->id);
1816 create_singlethread_workqueue(ioc->reset_work_q_name);
1817 if (!ioc->reset_work_q) {
1818 printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n",
1820 pci_release_selected_regions(pdev, ioc->bars);
1825 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",
1826 ioc->name, &ioc->facts, &ioc->pfacts[0]));
1828 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1829 mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name);
1831 switch (pdev->device)
1833 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1834 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1835 ioc->errata_flag_1064 = 1;
1836 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1837 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1838 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1839 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1843 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1844 if (revision < XL_929) {
1845 /* 929X Chip Fix. Set Split transactions level
1846 * for PCIX. Set MOST bits to zero.
1848 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1850 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1852 /* 929XL Chip Fix. Set MMRBC to 0x08.
1854 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1856 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1861 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1862 /* 919X Chip Fix. Set Split transactions level
1863 * for PCIX. Set MOST bits to zero.
1865 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1867 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1871 case MPI_MANUFACTPAGE_DEVID_53C1030:
1872 /* 1030 Chip Fix. Disable Split transactions
1873 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1875 if (revision < C0_1030) {
1876 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1878 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1881 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1882 ioc->bus_type = SPI;
1885 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1886 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1887 ioc->errata_flag_1064 = 1;
1889 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1890 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1891 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1892 ioc->bus_type = SAS;
1896 switch (ioc->bus_type) {
1899 ioc->msi_enable = mpt_msi_enable_sas;
1903 ioc->msi_enable = mpt_msi_enable_spi;
1907 ioc->msi_enable = mpt_msi_enable_fc;
1911 ioc->msi_enable = 0;
1914 if (ioc->errata_flag_1064)
1915 pci_disable_io_access(pdev);
1917 spin_lock_init(&ioc->FreeQlock);
1920 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1922 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1924 /* Set IOC ptr in the pcidev's driver data. */
1925 pci_set_drvdata(ioc->pcidev, ioc);
1927 /* Set lookup ptr. */
1928 list_add_tail(&ioc->list, &ioc_list);
1930 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1932 mpt_detect_bound_ports(ioc, pdev);
1934 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1936 printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",
1939 list_del(&ioc->list);
1941 ioc->alt_ioc->alt_ioc = NULL;
1942 iounmap(ioc->memmap);
1944 pci_release_selected_regions(pdev, ioc->bars);
1946 destroy_workqueue(ioc->reset_work_q);
1947 ioc->reset_work_q = NULL;
1950 pci_set_drvdata(pdev, NULL);
1954 /* call per device driver probe entry point */
1955 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
1956 if(MptDeviceDriverHandlers[cb_idx] &&
1957 MptDeviceDriverHandlers[cb_idx]->probe) {
1958 MptDeviceDriverHandlers[cb_idx]->probe(pdev,id);
1962 #ifdef CONFIG_PROC_FS
1964 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1966 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1968 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1970 ent->read_proc = procmpt_iocinfo_read;
1973 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1975 ent->read_proc = procmpt_summary_read;
1982 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
1983 msecs_to_jiffies(MPT_POLLING_INTERVAL));
1988 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1990 * mpt_detach - Remove a PCI intelligent MPT adapter.
1991 * @pdev: Pointer to pci_dev structure
1995 mpt_detach(struct pci_dev *pdev)
1997 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2000 unsigned long flags;
2001 struct workqueue_struct *wq;
2004 * Stop polling ioc for fault condition
2006 spin_lock_irqsave(&ioc->fault_reset_work_lock, flags);
2007 wq = ioc->reset_work_q;
2008 ioc->reset_work_q = NULL;
2009 spin_unlock_irqrestore(&ioc->fault_reset_work_lock, flags);
2010 cancel_delayed_work(&ioc->fault_reset_work);
2011 destroy_workqueue(wq);
2014 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
2015 remove_proc_entry(pname, NULL);
2016 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
2017 remove_proc_entry(pname, NULL);
2018 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
2019 remove_proc_entry(pname, NULL);
2021 /* call per device driver remove entry point */
2022 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
2023 if(MptDeviceDriverHandlers[cb_idx] &&
2024 MptDeviceDriverHandlers[cb_idx]->remove) {
2025 MptDeviceDriverHandlers[cb_idx]->remove(pdev);
2029 /* Disable interrupts! */
2030 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2033 synchronize_irq(pdev->irq);
2035 /* Clear any lingering interrupt */
2036 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2038 CHIPREG_READ32(&ioc->chip->IntStatus);
2040 mpt_adapter_dispose(ioc);
2042 pci_set_drvdata(pdev, NULL);
2045 /**************************************************************************
2049 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2051 * mpt_suspend - Fusion MPT base driver suspend routine.
2052 * @pdev: Pointer to pci_dev structure
2053 * @state: new state to enter
2056 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
2059 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2061 device_state = pci_choose_state(pdev, state);
2062 printk(MYIOC_s_INFO_FMT "pci-suspend: pdev=0x%p, slot=%s, Entering "
2063 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2066 /* put ioc into READY_STATE */
2067 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
2068 printk(MYIOC_s_ERR_FMT
2069 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
2072 /* disable interrupts */
2073 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2076 /* Clear any lingering interrupt */
2077 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2079 free_irq(ioc->pci_irq, ioc);
2080 if (ioc->msi_enable)
2081 pci_disable_msi(ioc->pcidev);
2083 pci_save_state(pdev);
2084 pci_disable_device(pdev);
2085 pci_release_selected_regions(pdev, ioc->bars);
2086 pci_set_power_state(pdev, device_state);
2090 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2092 * mpt_resume - Fusion MPT base driver resume routine.
2093 * @pdev: Pointer to pci_dev structure
2096 mpt_resume(struct pci_dev *pdev)
2098 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2099 u32 device_state = pdev->current_state;
2103 printk(MYIOC_s_INFO_FMT "pci-resume: pdev=0x%p, slot=%s, Previous "
2104 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2107 pci_set_power_state(pdev, PCI_D0);
2108 pci_enable_wake(pdev, PCI_D0, 0);
2109 pci_restore_state(pdev);
2111 err = mpt_mapresources(ioc);
2115 if (ioc->dma_mask == DMA_BIT_MASK(64)) {
2116 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
2117 ioc->add_sge = &mpt_add_sge_64bit_1078;
2119 ioc->add_sge = &mpt_add_sge_64bit;
2120 ioc->add_chain = &mpt_add_chain_64bit;
2121 ioc->sg_addr_size = 8;
2124 ioc->add_sge = &mpt_add_sge;
2125 ioc->add_chain = &mpt_add_chain;
2126 ioc->sg_addr_size = 4;
2128 ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
2130 printk(MYIOC_s_INFO_FMT "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
2131 ioc->name, (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
2132 CHIPREG_READ32(&ioc->chip->Doorbell));
2135 * Errata workaround for SAS pci express:
2136 * Upon returning to the D0 state, the contents of the doorbell will be
2137 * stale data, and this will incorrectly signal to the host driver that
2138 * the firmware is ready to process mpt commands. The workaround is
2139 * to issue a diagnostic reset.
2141 if (ioc->bus_type == SAS && (pdev->device ==
2142 MPI_MANUFACTPAGE_DEVID_SAS1068E || pdev->device ==
2143 MPI_MANUFACTPAGE_DEVID_SAS1064E)) {
2144 if (KickStart(ioc, 1, CAN_SLEEP) < 0) {
2145 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover\n",
2151 /* bring ioc to operational state */
2152 printk(MYIOC_s_INFO_FMT "Sending mpt_do_ioc_recovery\n", ioc->name);
2153 recovery_state = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
2155 if (recovery_state != 0)
2156 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover, "
2157 "error:[%x]\n", ioc->name, recovery_state);
2159 printk(MYIOC_s_INFO_FMT
2160 "pci-resume: success\n", ioc->name);
2168 mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase)
2170 if ((MptDriverClass[index] == MPTSPI_DRIVER &&
2171 ioc->bus_type != SPI) ||
2172 (MptDriverClass[index] == MPTFC_DRIVER &&
2173 ioc->bus_type != FC) ||
2174 (MptDriverClass[index] == MPTSAS_DRIVER &&
2175 ioc->bus_type != SAS))
2176 /* make sure we only call the relevant reset handler
2179 return (MptResetHandlers[index])(ioc, reset_phase);
2182 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2184 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
2185 * @ioc: Pointer to MPT adapter structure
2186 * @reason: Event word / reason
2187 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
2189 * This routine performs all the steps necessary to bring the IOC
2190 * to a OPERATIONAL state.
2192 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
2197 * -1 if failed to get board READY
2198 * -2 if READY but IOCFacts Failed
2199 * -3 if READY but PrimeIOCFifos Failed
2200 * -4 if READY but IOCInit Failed
2201 * -5 if failed to enable_device and/or request_selected_regions
2202 * -6 if failed to upload firmware
2205 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2207 int hard_reset_done = 0;
2208 int alt_ioc_ready = 0;
2215 int reset_alt_ioc_active = 0;
2216 int irq_allocated = 0;
2219 printk(MYIOC_s_INFO_FMT "Initiating %s\n", ioc->name,
2220 reason == MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
2222 /* Disable reply interrupts (also blocks FreeQ) */
2223 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2227 if (ioc->alt_ioc->active)
2228 reset_alt_ioc_active = 1;
2230 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
2231 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
2232 ioc->alt_ioc->active = 0;
2236 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
2239 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
2240 if (hard_reset_done == -4) {
2241 printk(MYIOC_s_WARN_FMT "Owned by PEER..skipping!\n",
2244 if (reset_alt_ioc_active && ioc->alt_ioc) {
2245 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
2246 dprintk(ioc, printk(MYIOC_s_INFO_FMT
2247 "alt_ioc reply irq re-enabled\n", ioc->alt_ioc->name));
2248 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2249 ioc->alt_ioc->active = 1;
2253 printk(MYIOC_s_WARN_FMT "NOT READY!\n", ioc->name);
2258 /* hard_reset_done = 0 if a soft reset was performed
2259 * and 1 if a hard reset was performed.
2261 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
2262 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
2265 printk(MYIOC_s_WARN_FMT "alt_ioc not ready!\n", ioc->alt_ioc->name);
2268 for (ii=0; ii<5; ii++) {
2269 /* Get IOC facts! Allow 5 retries */
2270 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
2276 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2277 "Retry IocFacts failed rc=%x\n", ioc->name, rc));
2279 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2280 MptDisplayIocCapabilities(ioc);
2283 if (alt_ioc_ready) {
2284 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
2285 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2286 "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
2287 /* Retry - alt IOC was initialized once
2289 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
2292 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2293 "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
2295 reset_alt_ioc_active = 0;
2296 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2297 MptDisplayIocCapabilities(ioc->alt_ioc);
2301 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP) &&
2302 (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)) {
2303 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2304 ioc->bars = pci_select_bars(ioc->pcidev, IORESOURCE_MEM |
2306 if (pci_enable_device(ioc->pcidev))
2308 if (pci_request_selected_regions(ioc->pcidev, ioc->bars,
2314 * Device is reset now. It must have de-asserted the interrupt line
2315 * (if it was asserted) and it should be safe to register for the
2318 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2320 if (ioc->pcidev->irq) {
2321 if (ioc->msi_enable && !pci_enable_msi(ioc->pcidev))
2322 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
2325 ioc->msi_enable = 0;
2326 rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
2327 IRQF_SHARED, ioc->name, ioc);
2329 printk(MYIOC_s_ERR_FMT "Unable to allocate "
2330 "interrupt %d!\n", ioc->name, ioc->pcidev->irq);
2331 if (ioc->msi_enable)
2332 pci_disable_msi(ioc->pcidev);
2336 ioc->pci_irq = ioc->pcidev->irq;
2337 pci_set_master(ioc->pcidev); /* ?? */
2338 dprintk(ioc, printk(MYIOC_s_INFO_FMT "installed at interrupt "
2339 "%d\n", ioc->name, ioc->pcidev->irq));
2343 /* Prime reply & request queues!
2344 * (mucho alloc's) Must be done prior to
2345 * init as upper addresses are needed for init.
2346 * If fails, continue with alt-ioc processing
2348 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
2351 /* May need to check/upload firmware & data here!
2352 * If fails, continue with alt-ioc processing
2354 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
2357 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
2358 printk(MYIOC_s_WARN_FMT ": alt_ioc (%d) FIFO mgmt alloc!\n",
2359 ioc->alt_ioc->name, rc);
2361 reset_alt_ioc_active = 0;
2364 if (alt_ioc_ready) {
2365 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
2367 reset_alt_ioc_active = 0;
2368 printk(MYIOC_s_WARN_FMT "alt_ioc (%d) init failure!\n",
2369 ioc->alt_ioc->name, rc);
2373 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
2374 if (ioc->upload_fw) {
2375 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2376 "firmware upload required!\n", ioc->name));
2378 /* Controller is not operational, cannot do upload
2381 rc = mpt_do_upload(ioc, sleepFlag);
2383 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2385 * Maintain only one pointer to FW memory
2386 * so there will not be two attempt to
2387 * downloadboot onboard dual function
2388 * chips (mpt_adapter_disable,
2391 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2392 "mpt_upload: alt_%s has cached_fw=%p \n",
2393 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
2394 ioc->cached_fw = NULL;
2397 printk(MYIOC_s_WARN_FMT
2398 "firmware upload failure!\n", ioc->name);
2405 /* Enable MPT base driver management of EventNotification
2406 * and EventAck handling.
2408 if ((ret == 0) && (!ioc->facts.EventState)) {
2409 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2410 "SendEventNotification\n",
2412 ret = SendEventNotification(ioc, 1, sleepFlag); /* 1=Enable */
2415 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2416 rc = SendEventNotification(ioc->alt_ioc, 1, sleepFlag);
2419 /* Enable! (reply interrupt) */
2420 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
2423 if (rc == 0) { /* alt ioc */
2424 if (reset_alt_ioc_active && ioc->alt_ioc) {
2425 /* (re)Enable alt-IOC! (reply interrupt) */
2426 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "alt-ioc"
2427 "reply irq re-enabled\n",
2428 ioc->alt_ioc->name));
2429 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask,
2431 ioc->alt_ioc->active = 1;
2436 /* Add additional "reason" check before call to GetLanConfigPages
2437 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2438 * recursive scenario; GetLanConfigPages times out, timer expired
2439 * routine calls HardResetHandler, which calls into here again,
2440 * and we try GetLanConfigPages again...
2442 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2445 * Initalize link list for inactive raid volumes.
2447 mutex_init(&ioc->raid_data.inactive_list_mutex);
2448 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2450 if (ioc->bus_type == SAS) {
2452 /* clear persistency table */
2453 if(ioc->facts.IOCExceptions &
2454 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
2455 ret = mptbase_sas_persist_operation(ioc,
2456 MPI_SAS_OP_CLEAR_NOT_PRESENT);
2463 mpt_findImVolumes(ioc);
2465 } else if (ioc->bus_type == FC) {
2466 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
2467 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2469 * Pre-fetch the ports LAN MAC address!
2470 * (LANPage1_t stuff)
2472 (void) GetLanConfigPages(ioc);
2473 a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2474 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2475 "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
2476 ioc->name, a[5], a[4], a[3], a[2], a[1], a[0]));
2480 /* Get NVRAM and adapter maximums from SPP 0 and 2
2482 mpt_GetScsiPortSettings(ioc, 0);
2484 /* Get version and length of SDP 1
2486 mpt_readScsiDevicePageHeaders(ioc, 0);
2490 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
2491 mpt_findImVolumes(ioc);
2493 /* Check, and possibly reset, the coalescing value
2495 mpt_read_ioc_pg_1(ioc);
2497 mpt_read_ioc_pg_4(ioc);
2500 GetIoUnitPage2(ioc);
2501 mpt_get_manufacturing_pg_0(ioc);
2505 * Call each currently registered protocol IOC reset handler
2506 * with post-reset indication.
2507 * NOTE: If we're doing _IOC_BRINGUP, there can be no
2508 * MptResetHandlers[] registered yet.
2510 if (hard_reset_done) {
2512 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
2513 if ((ret == 0) && MptResetHandlers[cb_idx]) {
2514 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2515 "Calling IOC post_reset handler #%d\n",
2516 ioc->name, cb_idx));
2517 rc += mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET);
2521 if (alt_ioc_ready && MptResetHandlers[cb_idx]) {
2522 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2523 "Calling IOC post_reset handler #%d\n",
2524 ioc->alt_ioc->name, cb_idx));
2525 rc += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_POST_RESET);
2529 /* FIXME? Examine results here? */
2533 if ((ret != 0) && irq_allocated) {
2534 free_irq(ioc->pci_irq, ioc);
2535 if (ioc->msi_enable)
2536 pci_disable_msi(ioc->pcidev);
2541 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2543 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2544 * @ioc: Pointer to MPT adapter structure
2545 * @pdev: Pointer to (struct pci_dev) structure
2547 * Search for PCI bus/dev_function which matches
2548 * PCI bus/dev_function (+/-1) for newly discovered 929,
2549 * 929X, 1030 or 1035.
2551 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2552 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2555 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
2557 struct pci_dev *peer=NULL;
2558 unsigned int slot = PCI_SLOT(pdev->devfn);
2559 unsigned int func = PCI_FUNC(pdev->devfn);
2560 MPT_ADAPTER *ioc_srch;
2562 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PCI device %s devfn=%x/%x,"
2563 " searching for devfn match on %x or %x\n",
2564 ioc->name, pci_name(pdev), pdev->bus->number,
2565 pdev->devfn, func-1, func+1));
2567 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
2569 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
2574 list_for_each_entry(ioc_srch, &ioc_list, list) {
2575 struct pci_dev *_pcidev = ioc_srch->pcidev;
2576 if (_pcidev == peer) {
2577 /* Paranoia checks */
2578 if (ioc->alt_ioc != NULL) {
2579 printk(MYIOC_s_WARN_FMT "Oops, already bound to %s!\n",
2580 ioc->name, ioc->alt_ioc->name);
2582 } else if (ioc_srch->alt_ioc != NULL) {
2583 printk(MYIOC_s_WARN_FMT "Oops, already bound to %s!\n",
2584 ioc_srch->name, ioc_srch->alt_ioc->name);
2587 dprintk(ioc, printk(MYIOC_s_INFO_FMT "FOUND! binding to %s\n",
2588 ioc->name, ioc_srch->name));
2589 ioc_srch->alt_ioc = ioc;
2590 ioc->alt_ioc = ioc_srch;
2596 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2598 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2599 * @ioc: Pointer to MPT adapter structure
2602 mpt_adapter_disable(MPT_ADAPTER *ioc)
2607 if (ioc->cached_fw != NULL) {
2608 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: Pushing FW onto "
2609 "adapter\n", __func__, ioc->name));
2610 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)
2611 ioc->cached_fw, CAN_SLEEP)) < 0) {
2612 printk(MYIOC_s_WARN_FMT
2613 ": firmware downloadboot failure (%d)!\n",
2618 /* Disable adapter interrupts! */
2619 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2621 /* Clear any lingering interrupt */
2622 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2624 if (ioc->alloc != NULL) {
2626 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "free @ %p, sz=%d bytes\n",
2627 ioc->name, ioc->alloc, ioc->alloc_sz));
2628 pci_free_consistent(ioc->pcidev, sz,
2629 ioc->alloc, ioc->alloc_dma);
2630 ioc->reply_frames = NULL;
2631 ioc->req_frames = NULL;
2633 ioc->alloc_total -= sz;
2636 if (ioc->sense_buf_pool != NULL) {
2637 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2638 pci_free_consistent(ioc->pcidev, sz,
2639 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2640 ioc->sense_buf_pool = NULL;
2641 ioc->alloc_total -= sz;
2644 if (ioc->events != NULL){
2645 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2648 ioc->alloc_total -= sz;
2651 mpt_free_fw_memory(ioc);
2653 kfree(ioc->spi_data.nvram);
2654 mpt_inactive_raid_list_free(ioc);
2655 kfree(ioc->raid_data.pIocPg2);
2656 kfree(ioc->raid_data.pIocPg3);
2657 ioc->spi_data.nvram = NULL;
2658 ioc->raid_data.pIocPg3 = NULL;
2660 if (ioc->spi_data.pIocPg4 != NULL) {
2661 sz = ioc->spi_data.IocPg4Sz;
2662 pci_free_consistent(ioc->pcidev, sz,
2663 ioc->spi_data.pIocPg4,
2664 ioc->spi_data.IocPg4_dma);
2665 ioc->spi_data.pIocPg4 = NULL;
2666 ioc->alloc_total -= sz;
2669 if (ioc->ReqToChain != NULL) {
2670 kfree(ioc->ReqToChain);
2671 kfree(ioc->RequestNB);
2672 ioc->ReqToChain = NULL;
2675 kfree(ioc->ChainToChain);
2676 ioc->ChainToChain = NULL;
2678 if (ioc->HostPageBuffer != NULL) {
2679 if((ret = mpt_host_page_access_control(ioc,
2680 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2681 printk(MYIOC_s_ERR_FMT
2682 "host page buffers free failed (%d)!\n",
2685 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "HostPageBuffer free @ %p, sz=%d bytes\n",
2686 ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
2687 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2688 ioc->HostPageBuffer, ioc->HostPageBuffer_dma);
2689 ioc->HostPageBuffer = NULL;
2690 ioc->HostPageBuffer_sz = 0;
2691 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2695 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2697 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2698 * @ioc: Pointer to MPT adapter structure
2700 * This routine unregisters h/w resources and frees all alloc'd memory
2701 * associated with a MPT adapter structure.
2704 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2706 int sz_first, sz_last;
2711 sz_first = ioc->alloc_total;
2713 mpt_adapter_disable(ioc);
2715 if (ioc->pci_irq != -1) {
2716 free_irq(ioc->pci_irq, ioc);
2717 if (ioc->msi_enable)
2718 pci_disable_msi(ioc->pcidev);
2722 if (ioc->memmap != NULL) {
2723 iounmap(ioc->memmap);
2727 pci_disable_device(ioc->pcidev);
2728 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2730 #if defined(CONFIG_MTRR) && 0
2731 if (ioc->mtrr_reg > 0) {
2732 mtrr_del(ioc->mtrr_reg, 0, 0);
2733 dprintk(ioc, printk(MYIOC_s_INFO_FMT "MTRR region de-registered\n", ioc->name));
2737 /* Zap the adapter lookup ptr! */
2738 list_del(&ioc->list);
2740 sz_last = ioc->alloc_total;
2741 dprintk(ioc, printk(MYIOC_s_INFO_FMT "free'd %d of %d bytes\n",
2742 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2745 ioc->alt_ioc->alt_ioc = NULL;
2750 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2752 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2753 * @ioc: Pointer to MPT adapter structure
2756 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2760 printk(KERN_INFO "%s: ", ioc->name);
2762 printk("%s: ", ioc->prod_name);
2763 printk("Capabilities={");
2765 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2766 printk("Initiator");
2770 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2771 printk("%sTarget", i ? "," : "");
2775 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2776 printk("%sLAN", i ? "," : "");
2782 * This would probably evoke more questions than it's worth
2784 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2785 printk("%sLogBusAddr", i ? "," : "");
2793 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2795 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2796 * @ioc: Pointer to MPT_ADAPTER structure
2797 * @force: Force hard KickStart of IOC
2798 * @sleepFlag: Specifies whether the process can sleep
2801 * 1 - DIAG reset and READY
2802 * 0 - READY initially OR soft reset and READY
2803 * -1 - Any failure on KickStart
2804 * -2 - Msg Unit Reset Failed
2805 * -3 - IO Unit Reset Failed
2806 * -4 - IOC owned by a PEER
2809 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2814 int hard_reset_done = 0;
2819 /* Get current [raw] IOC state */
2820 ioc_state = mpt_GetIocState(ioc, 0);
2821 dhsprintk(ioc, printk(MYIOC_s_INFO_FMT "MakeIocReady [raw] state=%08x\n", ioc->name, ioc_state));
2824 * Check to see if IOC got left/stuck in doorbell handshake
2825 * grip of death. If so, hard reset the IOC.
2827 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2829 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2833 /* Is it already READY? */
2834 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
2838 * Check to see if IOC is in FAULT state.
2840 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2842 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2844 printk(MYIOC_s_WARN_FMT " FAULT code = %04xh\n",
2845 ioc->name, ioc_state & MPI_DOORBELL_DATA_MASK);
2849 * Hmmm... Did it get left operational?
2851 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2852 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC operational unexpected\n",
2856 * If PCI Peer, exit.
2857 * Else, if no fault conditions are present, issue a MessageUnitReset
2858 * Else, fall through to KickStart case
2860 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2861 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2862 "whoinit 0x%x statefault %d force %d\n",
2863 ioc->name, whoinit, statefault, force));
2864 if (whoinit == MPI_WHOINIT_PCI_PEER)
2867 if ((statefault == 0 ) && (force == 0)) {
2868 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2875 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2876 if (hard_reset_done < 0)
2880 * Loop here waiting for IOC to come READY.
2883 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2885 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2886 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2888 * BIOS or previous driver load left IOC in OP state.
2889 * Reset messaging FIFOs.
2891 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2892 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2895 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2897 * Something is wrong. Try to get IOC back
2900 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2901 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2908 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2909 ioc->name, (int)((ii+5)/HZ));
2913 if (sleepFlag == CAN_SLEEP) {
2916 mdelay (1); /* 1 msec delay */
2921 if (statefault < 3) {
2922 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2924 statefault==1 ? "stuck handshake" : "IOC FAULT");
2927 return hard_reset_done;
2930 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2932 * mpt_GetIocState - Get the current state of a MPT adapter.
2933 * @ioc: Pointer to MPT_ADAPTER structure
2934 * @cooked: Request raw or cooked IOC state
2936 * Returns all IOC Doorbell register bits if cooked==0, else just the
2937 * Doorbell bits in MPI_IOC_STATE_MASK.
2940 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2945 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2946 sc = s & MPI_IOC_STATE_MASK;
2949 ioc->last_state = sc;
2951 return cooked ? sc : s;
2954 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2956 * GetIocFacts - Send IOCFacts request to MPT adapter.
2957 * @ioc: Pointer to MPT_ADAPTER structure
2958 * @sleepFlag: Specifies whether the process can sleep
2959 * @reason: If recovery, only update facts.
2961 * Returns 0 for success, non-zero for failure.
2964 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2966 IOCFacts_t get_facts;
2967 IOCFactsReply_t *facts;
2975 /* IOC *must* NOT be in RESET state! */
2976 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2977 printk(MYIOC_s_ERR_FMT "Can't get IOCFacts NOT READY! (%08x)\n",
2978 ioc->name, ioc->last_state );
2982 facts = &ioc->facts;
2984 /* Destination (reply area)... */
2985 reply_sz = sizeof(*facts);
2986 memset(facts, 0, reply_sz);
2988 /* Request area (get_facts on the stack right now!) */
2989 req_sz = sizeof(get_facts);
2990 memset(&get_facts, 0, req_sz);
2992 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2993 /* Assert: All other get_facts fields are zero! */
2995 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2996 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2997 ioc->name, req_sz, reply_sz));
2999 /* No non-zero fields in the get_facts request are greater than
3000 * 1 byte in size, so we can just fire it off as is.
3002 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
3003 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
3008 * Now byte swap (GRRR) the necessary fields before any further
3009 * inspection of reply contents.
3011 * But need to do some sanity checks on MsgLength (byte) field
3012 * to make sure we don't zero IOC's req_sz!
3014 /* Did we get a valid reply? */
3015 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
3016 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
3018 * If not been here, done that, save off first WhoInit value
3020 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
3021 ioc->FirstWhoInit = facts->WhoInit;
3024 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
3025 facts->MsgContext = le32_to_cpu(facts->MsgContext);
3026 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
3027 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
3028 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
3029 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
3030 /* CHECKME! IOCStatus, IOCLogInfo */
3032 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
3033 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
3036 * FC f/w version changed between 1.1 and 1.2
3037 * Old: u16{Major(4),Minor(4),SubMinor(8)}
3038 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
3040 if (facts->MsgVersion < 0x0102) {
3042 * Handle old FC f/w style, convert to new...
3044 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
3045 facts->FWVersion.Word =
3046 ((oldv<<12) & 0xFF000000) |
3047 ((oldv<<8) & 0x000FFF00);
3049 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
3051 facts->ProductID = le16_to_cpu(facts->ProductID);
3052 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
3053 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
3054 ioc->ir_firmware = 1;
3055 facts->CurrentHostMfaHighAddr =
3056 le32_to_cpu(facts->CurrentHostMfaHighAddr);
3057 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
3058 facts->CurrentSenseBufferHighAddr =
3059 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
3060 facts->CurReplyFrameSize =
3061 le16_to_cpu(facts->CurReplyFrameSize);
3062 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
3065 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
3066 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
3067 * to 14 in MPI-1.01.0x.
3069 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
3070 facts->MsgVersion > 0x0100) {
3071 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
3074 sz = facts->FWImageSize;
3079 facts->FWImageSize = sz;
3081 if (!facts->RequestFrameSize) {
3082 /* Something is wrong! */
3083 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
3088 r = sz = facts->BlockSize;
3089 vv = ((63 / (sz * 4)) + 1) & 0x03;
3090 ioc->NB_for_64_byte_frame = vv;
3096 ioc->NBShiftFactor = shiftFactor;
3097 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3098 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
3099 ioc->name, vv, shiftFactor, r));
3101 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
3103 * Set values for this IOC's request & reply frame sizes,
3104 * and request & reply queue depths...
3106 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
3107 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
3108 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
3109 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
3111 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "reply_sz=%3d, reply_depth=%4d\n",
3112 ioc->name, ioc->reply_sz, ioc->reply_depth));
3113 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "req_sz =%3d, req_depth =%4d\n",
3114 ioc->name, ioc->req_sz, ioc->req_depth));
3116 /* Get port facts! */
3117 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
3121 printk(MYIOC_s_ERR_FMT
3122 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
3123 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
3124 RequestFrameSize)/sizeof(u32)));
3131 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3133 * GetPortFacts - Send PortFacts request to MPT adapter.
3134 * @ioc: Pointer to MPT_ADAPTER structure
3135 * @portnum: Port number
3136 * @sleepFlag: Specifies whether the process can sleep
3138 * Returns 0 for success, non-zero for failure.
3141 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3143 PortFacts_t get_pfacts;
3144 PortFactsReply_t *pfacts;
3150 /* IOC *must* NOT be in RESET state! */
3151 if (ioc->last_state == MPI_IOC_STATE_RESET) {
3152 printk(MYIOC_s_ERR_FMT "Can't get PortFacts NOT READY! (%08x)\n",
3153 ioc->name, ioc->last_state );
3157 pfacts = &ioc->pfacts[portnum];
3159 /* Destination (reply area)... */
3160 reply_sz = sizeof(*pfacts);
3161 memset(pfacts, 0, reply_sz);
3163 /* Request area (get_pfacts on the stack right now!) */
3164 req_sz = sizeof(get_pfacts);
3165 memset(&get_pfacts, 0, req_sz);
3167 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
3168 get_pfacts.PortNumber = portnum;
3169 /* Assert: All other get_pfacts fields are zero! */
3171 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending get PortFacts(%d) request\n",
3172 ioc->name, portnum));
3174 /* No non-zero fields in the get_pfacts request are greater than
3175 * 1 byte in size, so we can just fire it off as is.
3177 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
3178 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
3182 /* Did we get a valid reply? */
3184 /* Now byte swap the necessary fields in the response. */
3185 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
3186 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
3187 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
3188 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
3189 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
3190 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
3191 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
3192 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
3193 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
3195 max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
3197 ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
3198 ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
3201 * Place all the devices on channels
3205 if (mpt_channel_mapping) {
3206 ioc->devices_per_bus = 1;
3207 ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
3213 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3215 * SendIocInit - Send IOCInit request to MPT adapter.
3216 * @ioc: Pointer to MPT_ADAPTER structure
3217 * @sleepFlag: Specifies whether the process can sleep
3219 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
3221 * Returns 0 for success, non-zero for failure.
3224 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
3227 MPIDefaultReply_t init_reply;
3233 memset(&ioc_init, 0, sizeof(ioc_init));
3234 memset(&init_reply, 0, sizeof(init_reply));
3236 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
3237 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
3239 /* If we are in a recovery mode and we uploaded the FW image,
3240 * then this pointer is not NULL. Skip the upload a second time.
3241 * Set this flag if cached_fw set for either IOC.
3243 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
3247 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "upload_fw %d facts.Flags=%x\n",
3248 ioc->name, ioc->upload_fw, ioc->facts.Flags));
3250 ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
3251 ioc_init.MaxBuses = (U8)ioc->number_of_buses;
3252 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n",
3253 ioc->name, ioc->facts.MsgVersion));
3254 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
3255 // set MsgVersion and HeaderVersion host driver was built with
3256 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
3257 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
3259 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
3260 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
3261 } else if(mpt_host_page_alloc(ioc, &ioc_init))
3264 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
3266 if (sizeof(dma_addr_t) == sizeof(u64)) {
3267 /* Save the upper 32-bits of the request
3268 * (reply) and sense buffers.
3270 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
3271 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
3273 /* Force 32-bit addressing */
3274 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
3275 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
3278 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
3279 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
3280 ioc->facts.MaxDevices = ioc_init.MaxDevices;
3281 ioc->facts.MaxBuses = ioc_init.MaxBuses;
3283 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOCInit (req @ %p)\n",
3284 ioc->name, &ioc_init));
3286 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
3287 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
3289 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
3293 /* No need to byte swap the multibyte fields in the reply
3294 * since we don't even look at its contents.
3297 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending PortEnable (req @ %p)\n",
3298 ioc->name, &ioc_init));
3300 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
3301 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
3305 /* YIKES! SUPER IMPORTANT!!!
3306 * Poll IocState until _OPERATIONAL while IOC is doing
3307 * LoopInit and TargetDiscovery!
3310 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
3311 state = mpt_GetIocState(ioc, 1);
3312 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
3313 if (sleepFlag == CAN_SLEEP) {
3320 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
3321 ioc->name, (int)((count+5)/HZ));
3325 state = mpt_GetIocState(ioc, 1);
3328 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wait IOC_OPERATIONAL state (cnt=%d)\n",
3331 ioc->aen_event_read_flag=0;
3335 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3337 * SendPortEnable - Send PortEnable request to MPT adapter port.
3338 * @ioc: Pointer to MPT_ADAPTER structure
3339 * @portnum: Port number to enable
3340 * @sleepFlag: Specifies whether the process can sleep
3342 * Send PortEnable to bring IOC to OPERATIONAL state.
3344 * Returns 0 for success, non-zero for failure.
3347 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3349 PortEnable_t port_enable;
3350 MPIDefaultReply_t reply_buf;
3355 /* Destination... */
3356 reply_sz = sizeof(MPIDefaultReply_t);
3357 memset(&reply_buf, 0, reply_sz);
3359 req_sz = sizeof(PortEnable_t);
3360 memset(&port_enable, 0, req_sz);
3362 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
3363 port_enable.PortNumber = portnum;
3364 /* port_enable.ChainOffset = 0; */
3365 /* port_enable.MsgFlags = 0; */
3366 /* port_enable.MsgContext = 0; */
3368 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Port(%d)Enable (req @ %p)\n",
3369 ioc->name, portnum, &port_enable));
3371 /* RAID FW may take a long time to enable
3373 if (ioc->ir_firmware || ioc->bus_type == SAS) {
3374 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3375 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3376 300 /*seconds*/, sleepFlag);
3378 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3379 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3380 30 /*seconds*/, sleepFlag);
3386 * mpt_alloc_fw_memory - allocate firmware memory
3387 * @ioc: Pointer to MPT_ADAPTER structure
3388 * @size: total FW bytes
3390 * If memory has already been allocated, the same (cached) value
3393 * Return 0 if successfull, or non-zero for failure
3396 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
3400 if (ioc->cached_fw) {
3401 rc = 0; /* use already allocated memory */
3404 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
3405 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
3406 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
3410 ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma);
3411 if (!ioc->cached_fw) {
3412 printk(MYIOC_s_ERR_FMT "Unable to allocate memory for the cached firmware image!\n",
3416 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Image @ %p[%p], sz=%d[%x] bytes\n",
3417 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, size, size));
3418 ioc->alloc_total += size;
3426 * mpt_free_fw_memory - free firmware memory
3427 * @ioc: Pointer to MPT_ADAPTER structure
3429 * If alt_img is NULL, delete from ioc structure.
3430 * Else, delete a secondary image in same format.
3433 mpt_free_fw_memory(MPT_ADAPTER *ioc)
3437 if (!ioc->cached_fw)
3440 sz = ioc->facts.FWImageSize;
3441 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3442 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3443 pci_free_consistent(ioc->pcidev, sz, ioc->cached_fw, ioc->cached_fw_dma);
3444 ioc->alloc_total -= sz;
3445 ioc->cached_fw = NULL;
3448 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3450 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3451 * @ioc: Pointer to MPT_ADAPTER structure
3452 * @sleepFlag: Specifies whether the process can sleep
3454 * Returns 0 for success, >0 for handshake failure
3455 * <0 for fw upload failure.
3457 * Remark: If bound IOC and a successful FWUpload was performed
3458 * on the bound IOC, the second image is discarded
3459 * and memory is free'd. Both channels must upload to prevent
3460 * IOC from running in degraded mode.
3463 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3465 u8 reply[sizeof(FWUploadReply_t)];
3466 FWUpload_t *prequest;
3467 FWUploadReply_t *preply;
3468 FWUploadTCSGE_t *ptcsge;
3470 int ii, sz, reply_sz;
3473 /* If the image size is 0, we are done.
3475 if ((sz = ioc->facts.FWImageSize) == 0)
3478 if (mpt_alloc_fw_memory(ioc, ioc->facts.FWImageSize) != 0)
3481 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3482 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3484 prequest = (sleepFlag == NO_SLEEP) ? kzalloc(ioc->req_sz, GFP_ATOMIC) :
3485 kzalloc(ioc->req_sz, GFP_KERNEL);
3487 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed "
3488 "while allocating memory \n", ioc->name));
3489 mpt_free_fw_memory(ioc);
3493 preply = (FWUploadReply_t *)&reply;
3495 reply_sz = sizeof(reply);
3496 memset(preply, 0, reply_sz);
3498 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
3499 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
3501 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
3502 ptcsge->DetailsLength = 12;
3503 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
3504 ptcsge->ImageSize = cpu_to_le32(sz);
3507 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3508 ioc->add_sge((char *)ptcsge, flagsLength, ioc->cached_fw_dma);
3509 request_size = offsetof(FWUpload_t, SGL) + sizeof(FWUploadTCSGE_t) +
3511 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending FW Upload "
3512 " (req @ %p) fw_size=%d mf_request_size=%d\n", ioc->name, prequest,
3513 ioc->facts.FWImageSize, request_size));
3514 DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest);
3516 ii = mpt_handshake_req_reply_wait(ioc, request_size, (u32 *)prequest,
3517 reply_sz, (u16 *)preply, 65 /*seconds*/, sleepFlag);
3519 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Upload completed rc=%x \n", ioc->name, ii));
3521 cmdStatus = -EFAULT;
3523 /* Handshake transfer was complete and successful.
3524 * Check the Reply Frame.
3526 int status, transfer_sz;
3527 status = le16_to_cpu(preply->IOCStatus);
3528 if (status == MPI_IOCSTATUS_SUCCESS) {
3529 transfer_sz = le32_to_cpu(preply->ActualImageSize);
3530 if (transfer_sz == sz)
3534 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n",
3535 ioc->name, cmdStatus));
3540 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": fw upload failed, freeing image \n",
3542 mpt_free_fw_memory(ioc);
3549 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3551 * mpt_downloadboot - DownloadBoot code
3552 * @ioc: Pointer to MPT_ADAPTER structure
3553 * @pFwHeader: Pointer to firmware header info
3554 * @sleepFlag: Specifies whether the process can sleep
3556 * FwDownloadBoot requires Programmed IO access.
3558 * Returns 0 for success
3559 * -1 FW Image size is 0
3560 * -2 No valid cached_fw Pointer
3561 * <0 for fw upload failure.
3564 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3566 MpiExtImageHeader_t *pExtImage;
3576 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3577 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
3579 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3580 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3581 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3582 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3583 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3584 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3586 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
3589 if (sleepFlag == CAN_SLEEP) {
3595 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3596 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3598 for (count = 0; count < 30; count ++) {
3599 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3600 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3601 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESET_ADAPTER cleared, count=%d\n",
3606 if (sleepFlag == CAN_SLEEP) {
3613 if ( count == 30 ) {
3614 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot failed! "
3615 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3616 ioc->name, diag0val));
3620 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3621 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3622 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3623 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3624 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3625 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3627 /* Set the DiagRwEn and Disable ARM bits */
3628 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3630 fwSize = (pFwHeader->ImageSize + 3)/4;
3631 ptrFw = (u32 *) pFwHeader;
3633 /* Write the LoadStartAddress to the DiagRw Address Register
3634 * using Programmed IO
3636 if (ioc->errata_flag_1064)
3637 pci_enable_io_access(ioc->pcidev);
3639 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3640 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "LoadStart addr written 0x%x \n",
3641 ioc->name, pFwHeader->LoadStartAddress));
3643 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write FW Image: 0x%x bytes @ %p\n",
3644 ioc->name, fwSize*4, ptrFw));
3646 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3649 nextImage = pFwHeader->NextImageHeaderOffset;
3651 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3653 load_addr = pExtImage->LoadStartAddress;
3655 fwSize = (pExtImage->ImageSize + 3) >> 2;
3656 ptrFw = (u32 *)pExtImage;
3658 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3659 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3660 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3663 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3665 nextImage = pExtImage->NextImageHeaderOffset;
3668 /* Write the IopResetVectorRegAddr */
3669 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
3670 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3672 /* Write the IopResetVectorValue */
3673 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3674 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3676 /* Clear the internal flash bad bit - autoincrementing register,
3677 * so must do two writes.
3679 if (ioc->bus_type == SPI) {
3681 * 1030 and 1035 H/W errata, workaround to access
3682 * the ClearFlashBadSignatureBit
3684 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3685 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3686 diagRwData |= 0x40000000;
3687 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3688 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3690 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3691 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3692 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3693 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3696 if (sleepFlag == CAN_SLEEP) {
3703 if (ioc->errata_flag_1064)
3704 pci_disable_io_access(ioc->pcidev);
3706 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3707 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot diag0val=%x, "
3708 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3709 ioc->name, diag0val));
3710 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3711 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot now diag0val=%x\n",
3712 ioc->name, diag0val));
3713 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3715 /* Write 0xFF to reset the sequencer */
3716 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3718 if (ioc->bus_type == SAS) {
3719 ioc_state = mpt_GetIocState(ioc, 0);
3720 if ( (GetIocFacts(ioc, sleepFlag,
3721 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3722 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "GetIocFacts failed: IocState=%x\n",
3723 ioc->name, ioc_state));
3728 for (count=0; count<HZ*20; count++) {
3729 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3730 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3731 "downloadboot successful! (count=%d) IocState=%x\n",
3732 ioc->name, count, ioc_state));
3733 if (ioc->bus_type == SAS) {
3736 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3737 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3738 "downloadboot: SendIocInit failed\n",
3742 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3743 "downloadboot: SendIocInit successful\n",
3747 if (sleepFlag == CAN_SLEEP) {
3753 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3754 "downloadboot failed! IocState=%x\n",ioc->name, ioc_state));
3758 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3760 * KickStart - Perform hard reset of MPT adapter.
3761 * @ioc: Pointer to MPT_ADAPTER structure
3762 * @force: Force hard reset
3763 * @sleepFlag: Specifies whether the process can sleep
3765 * This routine places MPT adapter in diagnostic mode via the
3766 * WriteSequence register, and then performs a hard reset of adapter
3767 * via the Diagnostic register.
3769 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3770 * or NO_SLEEP (interrupt thread, use mdelay)
3771 * force - 1 if doorbell active, board fault state
3772 * board operational, IOC_RECOVERY or
3773 * IOC_BRINGUP and there is an alt_ioc.
3777 * 1 - hard reset, READY
3778 * 0 - no reset due to History bit, READY
3779 * -1 - no reset due to History bit but not READY
3780 * OR reset but failed to come READY
3781 * -2 - no reset, could not enter DIAG mode
3782 * -3 - reset but bad FW bit
3785 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3787 int hard_reset_done = 0;
3791 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStarting!\n", ioc->name));
3792 if (ioc->bus_type == SPI) {
3793 /* Always issue a Msg Unit Reset first. This will clear some
3794 * SCSI bus hang conditions.
3796 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3798 if (sleepFlag == CAN_SLEEP) {
3805 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3806 if (hard_reset_done < 0)
3807 return hard_reset_done;
3809 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n",
3812 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3813 for (cnt=0; cnt<cntdn; cnt++) {
3814 ioc_state = mpt_GetIocState(ioc, 1);
3815 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3816 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStart successful! (cnt=%d)\n",
3818 return hard_reset_done;
3820 if (sleepFlag == CAN_SLEEP) {
3827 dinitprintk(ioc, printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3828 ioc->name, mpt_GetIocState(ioc, 0)));
3832 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3834 * mpt_diag_reset - Perform hard reset of the adapter.
3835 * @ioc: Pointer to MPT_ADAPTER structure
3836 * @ignore: Set if to honor and clear to ignore
3837 * the reset history bit
3838 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3839 * else set to NO_SLEEP (use mdelay instead)
3841 * This routine places the adapter in diagnostic mode via the
3842 * WriteSequence register and then performs a hard reset of adapter
3843 * via the Diagnostic register. Adapter should be in ready state
3844 * upon successful completion.
3846 * Returns: 1 hard reset successful
3847 * 0 no reset performed because reset history bit set
3848 * -2 enabling diagnostic mode failed
3849 * -3 diagnostic reset failed
3852 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3856 int hard_reset_done = 0;
3859 MpiFwHeader_t *cached_fw; /* Pointer to FW */
3861 /* Clear any existing interrupts */
3862 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3864 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3865 drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3866 "address=%p\n", ioc->name, __func__,
3867 &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3868 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3869 if (sleepFlag == CAN_SLEEP)
3874 for (count = 0; count < 60; count ++) {
3875 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3876 doorbell &= MPI_IOC_STATE_MASK;
3878 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3879 "looking for READY STATE: doorbell=%x"
3881 ioc->name, doorbell, count));
3882 if (doorbell == MPI_IOC_STATE_READY) {
3887 if (sleepFlag == CAN_SLEEP)
3895 /* Use "Diagnostic reset" method! (only thing available!) */
3896 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3898 if (ioc->debug_level & MPT_DEBUG) {
3900 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3901 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3902 ioc->name, diag0val, diag1val));
3905 /* Do the reset if we are told to ignore the reset history
3906 * or if the reset history is 0
3908 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3909 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3910 /* Write magic sequence to WriteSequence register
3911 * Loop until in diagnostic mode
3913 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3914 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3915 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3916 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3917 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3918 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3921 if (sleepFlag == CAN_SLEEP) {
3929 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3930 ioc->name, diag0val);
3935 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3937 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3938 ioc->name, diag0val));
3941 if (ioc->debug_level & MPT_DEBUG) {
3943 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3944 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3945 ioc->name, diag0val, diag1val));
3948 * Disable the ARM (Bug fix)
3951 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3955 * Now hit the reset bit in the Diagnostic register
3956 * (THE BIG HAMMER!) (Clears DRWE bit).
3958 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3959 hard_reset_done = 1;
3960 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset performed\n",
3964 * Call each currently registered protocol IOC reset handler
3965 * with pre-reset indication.
3966 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3967 * MptResetHandlers[] registered yet.
3973 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
3974 if (MptResetHandlers[cb_idx]) {
3975 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3976 "Calling IOC pre_reset handler #%d\n",
3977 ioc->name, cb_idx));
3978 r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET);
3980 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3981 "Calling alt-%s pre_reset handler #%d\n",
3982 ioc->name, ioc->alt_ioc->name, cb_idx));
3983 r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_PRE_RESET);
3987 /* FIXME? Examine results here? */
3991 cached_fw = (MpiFwHeader_t *)ioc->cached_fw;
3992 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
3993 cached_fw = (MpiFwHeader_t *)ioc->alt_ioc->cached_fw;
3997 /* If the DownloadBoot operation fails, the
3998 * IOC will be left unusable. This is a fatal error
3999 * case. _diag_reset will return < 0
4001 for (count = 0; count < 30; count ++) {
4002 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4003 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
4007 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n",
4008 ioc->name, diag0val, count));
4010 if (sleepFlag == CAN_SLEEP) {
4016 if ((count = mpt_downloadboot(ioc, cached_fw, sleepFlag)) < 0) {
4017 printk(MYIOC_s_WARN_FMT
4018 "firmware downloadboot failure (%d)!\n", ioc->name, count);
4022 /* Wait for FW to reload and for board
4023 * to go to the READY state.
4024 * Maximum wait is 60 seconds.
4025 * If fail, no error will check again
4026 * with calling program.
4028 for (count = 0; count < 60; count ++) {
4029 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
4030 doorbell &= MPI_IOC_STATE_MASK;
4032 if (doorbell == MPI_IOC_STATE_READY) {
4037 if (sleepFlag == CAN_SLEEP) {
4046 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4047 if (ioc->debug_level & MPT_DEBUG) {
4049 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4050 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG3: diag0=%08x, diag1=%08x\n",
4051 ioc->name, diag0val, diag1val));
4054 /* Clear RESET_HISTORY bit! Place board in the
4055 * diagnostic mode to update the diag register.
4057 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4059 while ((diag0val & MPI_DIAG_DRWE) == 0) {
4060 /* Write magic sequence to WriteSequence register
4061 * Loop until in diagnostic mode
4063 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
4064 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
4065 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
4066 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
4067 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
4068 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
4071 if (sleepFlag == CAN_SLEEP) {
4079 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
4080 ioc->name, diag0val);
4083 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4085 diag0val &= ~MPI_DIAG_RESET_HISTORY;
4086 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
4087 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4088 if (diag0val & MPI_DIAG_RESET_HISTORY) {
4089 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
4093 /* Disable Diagnostic Mode
4095 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
4097 /* Check FW reload status flags.
4099 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4100 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
4101 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
4102 ioc->name, diag0val);
4106 if (ioc->debug_level & MPT_DEBUG) {
4108 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4109 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG4: diag0=%08x, diag1=%08x\n",
4110 ioc->name, diag0val, diag1val));
4114 * Reset flag that says we've enabled event notification
4116 ioc->facts.EventState = 0;
4119 ioc->alt_ioc->facts.EventState = 0;
4121 return hard_reset_done;
4124 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4126 * SendIocReset - Send IOCReset request to MPT adapter.
4127 * @ioc: Pointer to MPT_ADAPTER structure
4128 * @reset_type: reset type, expected values are
4129 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
4130 * @sleepFlag: Specifies whether the process can sleep
4132 * Send IOCReset request to the MPT adapter.
4134 * Returns 0 for success, non-zero for failure.
4137 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
4143 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOC reset(0x%02x)!\n",
4144 ioc->name, reset_type));
4145 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
4146 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4149 /* FW ACK'd request, wait for READY state
4152 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
4154 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
4158 if (sleepFlag != CAN_SLEEP)
4161 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
4162 ioc->name, (int)((count+5)/HZ));
4166 if (sleepFlag == CAN_SLEEP) {
4169 mdelay (1); /* 1 msec delay */
4174 * Cleanup all event stuff for this IOC; re-issue EventNotification
4175 * request if needed.
4177 if (ioc->facts.Function)
4178 ioc->facts.EventState = 0;
4183 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4185 * initChainBuffers - Allocate memory for and initialize chain buffers
4186 * @ioc: Pointer to MPT_ADAPTER structure
4188 * Allocates memory for and initializes chain buffers,
4189 * chain buffer control arrays and spinlock.
4192 initChainBuffers(MPT_ADAPTER *ioc)
4195 int sz, ii, num_chain;
4196 int scale, num_sge, numSGE;
4198 /* ReqToChain size must equal the req_depth
4201 if (ioc->ReqToChain == NULL) {
4202 sz = ioc->req_depth * sizeof(int);
4203 mem = kmalloc(sz, GFP_ATOMIC);
4207 ioc->ReqToChain = (int *) mem;
4208 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReqToChain alloc @ %p, sz=%d bytes\n",
4209 ioc->name, mem, sz));
4210 mem = kmalloc(sz, GFP_ATOMIC);
4214 ioc->RequestNB = (int *) mem;
4215 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestNB alloc @ %p, sz=%d bytes\n",
4216 ioc->name, mem, sz));
4218 for (ii = 0; ii < ioc->req_depth; ii++) {
4219 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
4222 /* ChainToChain size must equal the total number
4223 * of chain buffers to be allocated.
4226 * Calculate the number of chain buffers needed(plus 1) per I/O
4227 * then multiply the maximum number of simultaneous cmds
4229 * num_sge = num sge in request frame + last chain buffer
4230 * scale = num sge per chain buffer if no chain element
4232 scale = ioc->req_sz / ioc->SGE_size;
4233 if (ioc->sg_addr_size == sizeof(u64))
4234 num_sge = scale + (ioc->req_sz - 60) / ioc->SGE_size;
4236 num_sge = 1 + scale + (ioc->req_sz - 64) / ioc->SGE_size;
4238 if (ioc->sg_addr_size == sizeof(u64)) {
4239 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
4240 (ioc->req_sz - 60) / ioc->SGE_size;
4242 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) +
4243 scale + (ioc->req_sz - 64) / ioc->SGE_size;
4245 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n",
4246 ioc->name, num_sge, numSGE));
4248 if ( numSGE > MPT_SCSI_SG_DEPTH )
4249 numSGE = MPT_SCSI_SG_DEPTH;
4252 while (numSGE - num_sge > 0) {
4254 num_sge += (scale - 1);
4258 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Now numSGE=%d num_sge=%d num_chain=%d\n",
4259 ioc->name, numSGE, num_sge, num_chain));
4261 if (ioc->bus_type == SPI)
4262 num_chain *= MPT_SCSI_CAN_QUEUE;
4264 num_chain *= MPT_FC_CAN_QUEUE;
4266 ioc->num_chain = num_chain;
4268 sz = num_chain * sizeof(int);
4269 if (ioc->ChainToChain == NULL) {
4270 mem = kmalloc(sz, GFP_ATOMIC);
4274 ioc->ChainToChain = (int *) mem;
4275 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainToChain alloc @ %p, sz=%d bytes\n",
4276 ioc->name, mem, sz));
4278 mem = (u8 *) ioc->ChainToChain;
4280 memset(mem, 0xFF, sz);
4284 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4286 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
4287 * @ioc: Pointer to MPT_ADAPTER structure
4289 * This routine allocates memory for the MPT reply and request frame
4290 * pools (if necessary), and primes the IOC reply FIFO with
4293 * Returns 0 for success, non-zero for failure.
4296 PrimeIocFifos(MPT_ADAPTER *ioc)
4299 unsigned long flags;
4300 dma_addr_t alloc_dma;
4302 int i, reply_sz, sz, total_size, num_chain;
4307 /* Prime reply FIFO... */
4309 if (ioc->reply_frames == NULL) {
4310 if ( (num_chain = initChainBuffers(ioc)) < 0)
4313 * 1078 errata workaround for the 36GB limitation
4315 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078 &&
4316 ioc->dma_mask > DMA_35BIT_MASK) {
4317 if (!pci_set_dma_mask(ioc->pcidev, DMA_BIT_MASK(32))
4318 && !pci_set_consistent_dma_mask(ioc->pcidev,
4319 DMA_BIT_MASK(32))) {
4320 dma_mask = DMA_35BIT_MASK;
4321 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4322 "setting 35 bit addressing for "
4323 "Request/Reply/Chain and Sense Buffers\n",
4326 /*Reseting DMA mask to 64 bit*/
4327 pci_set_dma_mask(ioc->pcidev,
4329 pci_set_consistent_dma_mask(ioc->pcidev,
4332 printk(MYIOC_s_ERR_FMT
4333 "failed setting 35 bit addressing for "
4334 "Request/Reply/Chain and Sense Buffers\n",
4340 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
4341 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
4342 ioc->name, ioc->reply_sz, ioc->reply_depth));
4343 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d[%x] bytes\n",
4344 ioc->name, reply_sz, reply_sz));
4346 sz = (ioc->req_sz * ioc->req_depth);
4347 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d bytes, RequestDepth=%d\n",
4348 ioc->name, ioc->req_sz, ioc->req_depth));
4349 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d[%x] bytes\n",
4350 ioc->name, sz, sz));
4353 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
4354 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d bytes, ChainDepth=%d\n",
4355 ioc->name, ioc->req_sz, num_chain));
4356 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
4357 ioc->name, sz, sz, num_chain));
4360 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
4362 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
4367 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Total alloc @ %p[%p], sz=%d[%x] bytes\n",
4368 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
4370 memset(mem, 0, total_size);
4371 ioc->alloc_total += total_size;
4373 ioc->alloc_dma = alloc_dma;
4374 ioc->alloc_sz = total_size;
4375 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
4376 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4378 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4379 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4381 alloc_dma += reply_sz;
4384 /* Request FIFO - WE manage this! */
4386 ioc->req_frames = (MPT_FRAME_HDR *) mem;
4387 ioc->req_frames_dma = alloc_dma;
4389 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffers @ %p[%p]\n",
4390 ioc->name, mem, (void *)(ulong)alloc_dma));
4392 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4394 #if defined(CONFIG_MTRR) && 0
4396 * Enable Write Combining MTRR for IOC's memory region.
4397 * (at least as much as we can; "size and base must be
4398 * multiples of 4 kiB"
4400 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
4402 MTRR_TYPE_WRCOMB, 1);
4403 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MTRR region registered (base:size=%08x:%x)\n",
4404 ioc->name, ioc->req_frames_dma, sz));
4407 for (i = 0; i < ioc->req_depth; i++) {
4408 alloc_dma += ioc->req_sz;
4412 ioc->ChainBuffer = mem;
4413 ioc->ChainBufferDMA = alloc_dma;
4415 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffers @ %p(%p)\n",
4416 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
4418 /* Initialize the free chain Q.
4421 INIT_LIST_HEAD(&ioc->FreeChainQ);
4423 /* Post the chain buffers to the FreeChainQ.
4425 mem = (u8 *)ioc->ChainBuffer;
4426 for (i=0; i < num_chain; i++) {
4427 mf = (MPT_FRAME_HDR *) mem;
4428 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
4432 /* Initialize Request frames linked list
4434 alloc_dma = ioc->req_frames_dma;
4435 mem = (u8 *) ioc->req_frames;
4437 spin_lock_irqsave(&ioc->FreeQlock, flags);
4438 INIT_LIST_HEAD(&ioc->FreeQ);
4439 for (i = 0; i < ioc->req_depth; i++) {
4440 mf = (MPT_FRAME_HDR *) mem;
4442 /* Queue REQUESTs *internally*! */
4443 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
4447 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4449 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4450 ioc->sense_buf_pool =
4451 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
4452 if (ioc->sense_buf_pool == NULL) {
4453 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
4458 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
4459 ioc->alloc_total += sz;
4460 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SenseBuffers @ %p[%p]\n",
4461 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
4465 /* Post Reply frames to FIFO
4467 alloc_dma = ioc->alloc_dma;
4468 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4469 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4471 for (i = 0; i < ioc->reply_depth; i++) {
4472 /* Write each address to the IOC! */
4473 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
4474 alloc_dma += ioc->reply_sz;
4477 if (dma_mask == DMA_35BIT_MASK && !pci_set_dma_mask(ioc->pcidev,
4478 ioc->dma_mask) && !pci_set_consistent_dma_mask(ioc->pcidev,
4480 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4481 "restoring 64 bit addressing\n", ioc->name));
4486 if (ioc->alloc != NULL) {
4488 pci_free_consistent(ioc->pcidev,
4490 ioc->alloc, ioc->alloc_dma);
4491 ioc->reply_frames = NULL;
4492 ioc->req_frames = NULL;
4493 ioc->alloc_total -= sz;
4495 if (ioc->sense_buf_pool != NULL) {
4496 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4497 pci_free_consistent(ioc->pcidev,
4499 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
4500 ioc->sense_buf_pool = NULL;
4503 if (dma_mask == DMA_35BIT_MASK && !pci_set_dma_mask(ioc->pcidev,
4504 DMA_BIT_MASK(64)) && !pci_set_consistent_dma_mask(ioc->pcidev,
4506 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4507 "restoring 64 bit addressing\n", ioc->name));
4512 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4514 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4515 * from IOC via doorbell handshake method.
4516 * @ioc: Pointer to MPT_ADAPTER structure
4517 * @reqBytes: Size of the request in bytes
4518 * @req: Pointer to MPT request frame
4519 * @replyBytes: Expected size of the reply in bytes
4520 * @u16reply: Pointer to area where reply should be written
4521 * @maxwait: Max wait time for a reply (in seconds)
4522 * @sleepFlag: Specifies whether the process can sleep
4524 * NOTES: It is the callers responsibility to byte-swap fields in the
4525 * request which are greater than 1 byte in size. It is also the
4526 * callers responsibility to byte-swap response fields which are
4527 * greater than 1 byte in size.
4529 * Returns 0 for success, non-zero for failure.
4532 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
4533 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
4535 MPIDefaultReply_t *mptReply;
4540 * Get ready to cache a handshake reply
4542 ioc->hs_reply_idx = 0;
4543 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4544 mptReply->MsgLength = 0;
4547 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4548 * then tell IOC that we want to handshake a request of N words.
4549 * (WRITE u32val to Doorbell reg).
4551 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4552 CHIPREG_WRITE32(&ioc->chip->Doorbell,
4553 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
4554 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
4557 * Wait for IOC's doorbell handshake int
4559 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4562 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4563 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4565 /* Read doorbell and check for active bit */
4566 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
4570 * Clear doorbell int (WRITE 0 to IntStatus reg),
4571 * then wait for IOC to ACKnowledge that it's ready for
4572 * our handshake request.
4574 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4575 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4580 u8 *req_as_bytes = (u8 *) req;
4583 * Stuff request words via doorbell handshake,
4584 * with ACK from IOC for each.
4586 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
4587 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
4588 (req_as_bytes[(ii*4) + 1] << 8) |
4589 (req_as_bytes[(ii*4) + 2] << 16) |
4590 (req_as_bytes[(ii*4) + 3] << 24));
4592 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
4593 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4597 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req));
4598 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req);
4600 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n",
4601 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
4604 * Wait for completion of doorbell handshake reply from the IOC
4606 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
4609 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake reply count=%d%s\n",
4610 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
4613 * Copy out the cached reply...
4615 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
4616 u16reply[ii] = ioc->hs_reply[ii];
4624 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4626 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4627 * @ioc: Pointer to MPT_ADAPTER structure
4628 * @howlong: How long to wait (in seconds)
4629 * @sleepFlag: Specifies whether the process can sleep
4631 * This routine waits (up to ~2 seconds max) for IOC doorbell
4632 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4633 * bit in its IntStatus register being clear.
4635 * Returns a negative value on failure, else wait loop count.
4638 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4644 cntdn = 1000 * howlong;
4646 if (sleepFlag == CAN_SLEEP) {
4649 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4650 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4657 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4658 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4665 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell ACK (count=%d)\n",
4670 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4671 ioc->name, count, intstat);
4675 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4677 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4678 * @ioc: Pointer to MPT_ADAPTER structure
4679 * @howlong: How long to wait (in seconds)
4680 * @sleepFlag: Specifies whether the process can sleep
4682 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4683 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4685 * Returns a negative value on failure, else wait loop count.
4688 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4694 cntdn = 1000 * howlong;
4695 if (sleepFlag == CAN_SLEEP) {
4697 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4698 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4705 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4706 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4714 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4715 ioc->name, count, howlong));
4719 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4720 ioc->name, count, intstat);
4724 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4726 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4727 * @ioc: Pointer to MPT_ADAPTER structure
4728 * @howlong: How long to wait (in seconds)
4729 * @sleepFlag: Specifies whether the process can sleep
4731 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4732 * Reply is cached to IOC private area large enough to hold a maximum
4733 * of 128 bytes of reply data.
4735 * Returns a negative value on failure, else size of reply in WORDS.
4738 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4743 u16 *hs_reply = ioc->hs_reply;
4744 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4747 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4750 * Get first two u16's so we can look at IOC's intended reply MsgLength
4753 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4756 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4757 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4758 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4761 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4762 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4766 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4767 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4768 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4771 * If no error (and IOC said MsgLength is > 0), piece together
4772 * reply 16 bits at a time.
4774 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4775 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4777 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4778 /* don't overflow our IOC hs_reply[] buffer! */
4779 if (u16cnt < ARRAY_SIZE(ioc->hs_reply))
4780 hs_reply[u16cnt] = hword;
4781 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4784 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4786 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4789 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4794 else if (u16cnt != (2 * mptReply->MsgLength)) {
4797 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4802 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name));
4803 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply);
4805 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4806 ioc->name, t, u16cnt/2));
4810 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4812 * GetLanConfigPages - Fetch LANConfig pages.
4813 * @ioc: Pointer to MPT_ADAPTER structure
4815 * Return: 0 for success
4816 * -ENOMEM if no memory available
4817 * -EPERM if not allowed due to ISR context
4818 * -EAGAIN if no msg frames currently available
4819 * -EFAULT for non-successful reply or no reply (timeout)
4822 GetLanConfigPages(MPT_ADAPTER *ioc)
4824 ConfigPageHeader_t hdr;
4826 LANPage0_t *ppage0_alloc;
4827 dma_addr_t page0_dma;
4828 LANPage1_t *ppage1_alloc;
4829 dma_addr_t page1_dma;
4834 /* Get LAN Page 0 header */
4835 hdr.PageVersion = 0;
4838 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4839 cfg.cfghdr.hdr = &hdr;
4841 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4846 if ((rc = mpt_config(ioc, &cfg)) != 0)
4849 if (hdr.PageLength > 0) {
4850 data_sz = hdr.PageLength * 4;
4851 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4854 memset((u8 *)ppage0_alloc, 0, data_sz);
4855 cfg.physAddr = page0_dma;
4856 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4858 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4860 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4861 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4865 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4868 * Normalize endianness of structure data,
4869 * by byte-swapping all > 1 byte fields!
4878 /* Get LAN Page 1 header */
4879 hdr.PageVersion = 0;
4882 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4883 cfg.cfghdr.hdr = &hdr;
4885 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4889 if ((rc = mpt_config(ioc, &cfg)) != 0)
4892 if (hdr.PageLength == 0)
4895 data_sz = hdr.PageLength * 4;
4897 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4899 memset((u8 *)ppage1_alloc, 0, data_sz);
4900 cfg.physAddr = page1_dma;
4901 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4903 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4905 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4906 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4909 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4912 * Normalize endianness of structure data,
4913 * by byte-swapping all > 1 byte fields!
4921 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4923 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
4924 * @ioc: Pointer to MPT_ADAPTER structure
4925 * @persist_opcode: see below
4927 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4928 * devices not currently present.
4929 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4931 * NOTE: Don't use not this function during interrupt time.
4933 * Returns 0 for success, non-zero error
4936 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4938 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4940 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
4941 SasIoUnitControlReply_t *sasIoUnitCntrReply;
4942 MPT_FRAME_HDR *mf = NULL;
4943 MPIHeader_t *mpi_hdr;
4945 unsigned long timeleft;
4947 mutex_lock(&ioc->mptbase_cmds.mutex);
4949 /* init the internal cmd struct */
4950 memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE);
4951 INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status)
4953 /* insure garbage is not sent to fw */
4954 switch(persist_opcode) {
4956 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
4957 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
4965 printk(KERN_DEBUG "%s: persist_opcode=%x\n",
4966 __func__, persist_opcode);
4968 /* Get a MF for this command.
4970 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4971 printk(KERN_DEBUG "%s: no msg frames!\n", __func__);
4976 mpi_hdr = (MPIHeader_t *) mf;
4977 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
4978 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
4979 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
4980 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
4981 sasIoUnitCntrReq->Operation = persist_opcode;
4983 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4984 timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done, 10*HZ);
4985 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
4987 printk(KERN_DEBUG "%s: failed\n", __func__);
4988 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
4991 printk(KERN_DEBUG "%s: Issuing Reset from %s!!\n",
4992 ioc->name, __func__);
4993 mpt_HardResetHandler(ioc, CAN_SLEEP);
4994 mpt_free_msg_frame(ioc, mf);
4999 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
5004 sasIoUnitCntrReply =
5005 (SasIoUnitControlReply_t *)ioc->mptbase_cmds.reply;
5006 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
5007 printk(KERN_DEBUG "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
5008 __func__, sasIoUnitCntrReply->IOCStatus,
5009 sasIoUnitCntrReply->IOCLogInfo);
5010 printk(KERN_DEBUG "%s: failed\n", __func__);
5013 printk(KERN_DEBUG "%s: success\n", __func__);
5016 CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status)
5017 mutex_unlock(&ioc->mptbase_cmds.mutex);
5021 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5024 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
5025 MpiEventDataRaid_t * pRaidEventData)
5034 volume = pRaidEventData->VolumeID;
5035 reason = pRaidEventData->ReasonCode;
5036 disk = pRaidEventData->PhysDiskNum;
5037 status = le32_to_cpu(pRaidEventData->SettingsStatus);
5038 flags = (status >> 0) & 0xff;
5039 state = (status >> 8) & 0xff;
5041 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
5045 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
5046 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
5047 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
5048 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
5049 ioc->name, disk, volume);
5051 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
5056 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
5057 printk(MYIOC_s_INFO_FMT " volume has been created\n",
5061 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
5063 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
5067 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
5068 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
5072 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
5073 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
5075 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
5077 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
5079 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
5082 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
5084 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
5085 ? ", quiesced" : "",
5086 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
5087 ? ", resync in progress" : "" );
5090 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
5091 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
5095 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
5096 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
5100 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
5101 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
5105 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
5106 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
5110 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
5111 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
5113 state == MPI_PHYSDISK0_STATUS_ONLINE
5115 : state == MPI_PHYSDISK0_STATUS_MISSING
5117 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
5119 : state == MPI_PHYSDISK0_STATUS_FAILED
5121 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
5123 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
5124 ? "offline requested"
5125 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
5126 ? "failed requested"
5127 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
5130 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
5131 ? ", out of sync" : "",
5132 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
5133 ? ", quiesced" : "" );
5136 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
5137 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
5141 case MPI_EVENT_RAID_RC_SMART_DATA:
5142 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
5143 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
5146 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
5147 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
5153 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5155 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
5156 * @ioc: Pointer to MPT_ADAPTER structure
5158 * Returns: 0 for success
5159 * -ENOMEM if no memory available
5160 * -EPERM if not allowed due to ISR context
5161 * -EAGAIN if no msg frames currently available
5162 * -EFAULT for non-successful reply or no reply (timeout)
5165 GetIoUnitPage2(MPT_ADAPTER *ioc)
5167 ConfigPageHeader_t hdr;
5169 IOUnitPage2_t *ppage_alloc;
5170 dma_addr_t page_dma;
5174 /* Get the page header */
5175 hdr.PageVersion = 0;
5178 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
5179 cfg.cfghdr.hdr = &hdr;
5181 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5186 if ((rc = mpt_config(ioc, &cfg)) != 0)
5189 if (hdr.PageLength == 0)
5192 /* Read the config page */
5193 data_sz = hdr.PageLength * 4;
5195 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
5197 memset((u8 *)ppage_alloc, 0, data_sz);
5198 cfg.physAddr = page_dma;
5199 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5201 /* If Good, save data */
5202 if ((rc = mpt_config(ioc, &cfg)) == 0)
5203 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
5205 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
5211 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5213 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
5214 * @ioc: Pointer to a Adapter Strucutre
5215 * @portnum: IOC port number
5217 * Return: -EFAULT if read of config page header fails
5219 * If read of SCSI Port Page 0 fails,
5220 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5221 * Adapter settings: async, narrow
5223 * If read of SCSI Port Page 2 fails,
5224 * Adapter settings valid
5225 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5230 * CHECK - what type of locking mechanisms should be used????
5233 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
5238 ConfigPageHeader_t header;
5244 if (!ioc->spi_data.nvram) {
5247 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
5248 mem = kmalloc(sz, GFP_ATOMIC);
5252 ioc->spi_data.nvram = (int *) mem;
5254 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
5255 ioc->name, ioc->spi_data.nvram, sz));
5258 /* Invalidate NVRAM information
5260 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5261 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
5264 /* Read SPP0 header, allocate memory, then read page.
5266 header.PageVersion = 0;
5267 header.PageLength = 0;
5268 header.PageNumber = 0;
5269 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5270 cfg.cfghdr.hdr = &header;
5272 cfg.pageAddr = portnum;
5273 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5275 cfg.timeout = 0; /* use default */
5276 if (mpt_config(ioc, &cfg) != 0)
5279 if (header.PageLength > 0) {
5280 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5282 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5283 cfg.physAddr = buf_dma;
5284 if (mpt_config(ioc, &cfg) != 0) {
5285 ioc->spi_data.maxBusWidth = MPT_NARROW;
5286 ioc->spi_data.maxSyncOffset = 0;
5287 ioc->spi_data.minSyncFactor = MPT_ASYNC;
5288 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
5290 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5291 "Unable to read PortPage0 minSyncFactor=%x\n",
5292 ioc->name, ioc->spi_data.minSyncFactor));
5294 /* Save the Port Page 0 data
5296 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
5297 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
5298 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
5300 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
5301 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
5302 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5303 "noQas due to Capabilities=%x\n",
5304 ioc->name, pPP0->Capabilities));
5306 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
5307 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
5309 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
5310 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
5311 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
5312 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5313 "PortPage0 minSyncFactor=%x\n",
5314 ioc->name, ioc->spi_data.minSyncFactor));
5316 ioc->spi_data.maxSyncOffset = 0;
5317 ioc->spi_data.minSyncFactor = MPT_ASYNC;
5320 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
5322 /* Update the minSyncFactor based on bus type.
5324 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
5325 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
5327 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
5328 ioc->spi_data.minSyncFactor = MPT_ULTRA;
5329 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5330 "HVD or SE detected, minSyncFactor=%x\n",
5331 ioc->name, ioc->spi_data.minSyncFactor));
5336 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5341 /* SCSI Port Page 2 - Read the header then the page.
5343 header.PageVersion = 0;
5344 header.PageLength = 0;
5345 header.PageNumber = 2;
5346 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5347 cfg.cfghdr.hdr = &header;
5349 cfg.pageAddr = portnum;
5350 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5352 if (mpt_config(ioc, &cfg) != 0)
5355 if (header.PageLength > 0) {
5356 /* Allocate memory and read SCSI Port Page 2
5358 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5360 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
5361 cfg.physAddr = buf_dma;
5362 if (mpt_config(ioc, &cfg) != 0) {
5363 /* Nvram data is left with INVALID mark
5366 } else if (ioc->pcidev->vendor == PCI_VENDOR_ID_ATTO) {
5368 /* This is an ATTO adapter, read Page2 accordingly
5370 ATTO_SCSIPortPage2_t *pPP2 = (ATTO_SCSIPortPage2_t *) pbuf;
5371 ATTODeviceInfo_t *pdevice = NULL;
5374 /* Save the Port Page 2 data
5375 * (reformat into a 32bit quantity)
5377 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5378 pdevice = &pPP2->DeviceSettings[ii];
5379 ATTOFlags = le16_to_cpu(pdevice->ATTOFlags);
5382 /* Translate ATTO device flags to LSI format
5384 if (ATTOFlags & ATTOFLAG_DISC)
5385 data |= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE);
5386 if (ATTOFlags & ATTOFLAG_ID_ENB)
5387 data |= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE);
5388 if (ATTOFlags & ATTOFLAG_LUN_ENB)
5389 data |= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE);
5390 if (ATTOFlags & ATTOFLAG_TAGGED)
5391 data |= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE);
5392 if (!(ATTOFlags & ATTOFLAG_WIDE_ENB))
5393 data |= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE);
5395 data = (data << 16) | (pdevice->Period << 8) | 10;
5396 ioc->spi_data.nvram[ii] = data;
5399 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
5400 MpiDeviceInfo_t *pdevice = NULL;
5403 * Save "Set to Avoid SCSI Bus Resets" flag
5405 ioc->spi_data.bus_reset =
5406 (le32_to_cpu(pPP2->PortFlags) &
5407 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
5410 /* Save the Port Page 2 data
5411 * (reformat into a 32bit quantity)
5413 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
5414 ioc->spi_data.PortFlags = data;
5415 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5416 pdevice = &pPP2->DeviceSettings[ii];
5417 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
5418 (pdevice->SyncFactor << 8) | pdevice->Timeout;
5419 ioc->spi_data.nvram[ii] = data;
5423 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5427 /* Update Adapter limits with those from NVRAM
5428 * Comment: Don't need to do this. Target performance
5429 * parameters will never exceed the adapters limits.
5435 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5437 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
5438 * @ioc: Pointer to a Adapter Strucutre
5439 * @portnum: IOC port number
5441 * Return: -EFAULT if read of config page header fails
5445 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
5448 ConfigPageHeader_t header;
5450 /* Read the SCSI Device Page 1 header
5452 header.PageVersion = 0;
5453 header.PageLength = 0;
5454 header.PageNumber = 1;
5455 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5456 cfg.cfghdr.hdr = &header;
5458 cfg.pageAddr = portnum;
5459 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5462 if (mpt_config(ioc, &cfg) != 0)
5465 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
5466 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
5468 header.PageVersion = 0;
5469 header.PageLength = 0;
5470 header.PageNumber = 0;
5471 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5472 if (mpt_config(ioc, &cfg) != 0)
5475 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
5476 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
5478 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 0: version %d length %d\n",
5479 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
5481 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 1: version %d length %d\n",
5482 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
5487 * mpt_inactive_raid_list_free - This clears this link list.
5488 * @ioc : pointer to per adapter structure
5491 mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
5493 struct inactive_raid_component_info *component_info, *pNext;
5495 if (list_empty(&ioc->raid_data.inactive_list))
5498 mutex_lock(&ioc->raid_data.inactive_list_mutex);
5499 list_for_each_entry_safe(component_info, pNext,
5500 &ioc->raid_data.inactive_list, list) {
5501 list_del(&component_info->list);
5502 kfree(component_info);
5504 mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5508 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5510 * @ioc : pointer to per adapter structure
5511 * @channel : volume channel
5512 * @id : volume target id
5515 mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
5518 ConfigPageHeader_t hdr;
5519 dma_addr_t dma_handle;
5520 pRaidVolumePage0_t buffer = NULL;
5522 RaidPhysDiskPage0_t phys_disk;
5523 struct inactive_raid_component_info *component_info;
5524 int handle_inactive_volumes;
5526 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5527 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5528 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
5529 cfg.pageAddr = (channel << 8) + id;
5530 cfg.cfghdr.hdr = &hdr;
5531 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5533 if (mpt_config(ioc, &cfg) != 0)
5536 if (!hdr.PageLength)
5539 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5545 cfg.physAddr = dma_handle;
5546 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5548 if (mpt_config(ioc, &cfg) != 0)
5551 if (!buffer->NumPhysDisks)
5554 handle_inactive_volumes =
5555 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
5556 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
5557 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
5558 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
5560 if (!handle_inactive_volumes)
5563 mutex_lock(&ioc->raid_data.inactive_list_mutex);
5564 for (i = 0; i < buffer->NumPhysDisks; i++) {
5565 if(mpt_raid_phys_disk_pg0(ioc,
5566 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
5569 if ((component_info = kmalloc(sizeof (*component_info),
5570 GFP_KERNEL)) == NULL)
5573 component_info->volumeID = id;
5574 component_info->volumeBus = channel;
5575 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
5576 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
5577 component_info->d.PhysDiskID = phys_disk.PhysDiskID;
5578 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
5580 list_add_tail(&component_info->list,
5581 &ioc->raid_data.inactive_list);
5583 mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5587 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5592 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5593 * @ioc: Pointer to a Adapter Structure
5594 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5595 * @phys_disk: requested payload data returned
5599 * -EFAULT if read of config page header fails or data pointer not NULL
5600 * -ENOMEM if pci_alloc failed
5603 mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk)
5606 ConfigPageHeader_t hdr;
5607 dma_addr_t dma_handle;
5608 pRaidPhysDiskPage0_t buffer = NULL;
5611 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5612 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5614 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5615 cfg.cfghdr.hdr = &hdr;
5617 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5619 if (mpt_config(ioc, &cfg) != 0) {
5624 if (!hdr.PageLength) {
5629 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5637 cfg.physAddr = dma_handle;
5638 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5639 cfg.pageAddr = phys_disk_num;
5641 if (mpt_config(ioc, &cfg) != 0) {
5647 memcpy(phys_disk, buffer, sizeof(*buffer));
5648 phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
5653 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5660 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5661 * @ioc: Pointer to a Adapter Strucutre
5665 * -EFAULT if read of config page header fails or data pointer not NULL
5666 * -ENOMEM if pci_alloc failed
5669 mpt_findImVolumes(MPT_ADAPTER *ioc)
5673 dma_addr_t ioc2_dma;
5675 ConfigPageHeader_t header;
5680 if (!ioc->ir_firmware)
5683 /* Free the old page
5685 kfree(ioc->raid_data.pIocPg2);
5686 ioc->raid_data.pIocPg2 = NULL;
5687 mpt_inactive_raid_list_free(ioc);
5689 /* Read IOCP2 header then the page.
5691 header.PageVersion = 0;
5692 header.PageLength = 0;
5693 header.PageNumber = 2;
5694 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5695 cfg.cfghdr.hdr = &header;
5698 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5701 if (mpt_config(ioc, &cfg) != 0)
5704 if (header.PageLength == 0)
5707 iocpage2sz = header.PageLength * 4;
5708 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
5712 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5713 cfg.physAddr = ioc2_dma;
5714 if (mpt_config(ioc, &cfg) != 0)
5717 mem = kmalloc(iocpage2sz, GFP_KERNEL);
5721 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
5722 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
5724 mpt_read_ioc_pg_3(ioc);
5726 for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
5727 mpt_inactive_raid_volumes(ioc,
5728 pIoc2->RaidVolume[i].VolumeBus,
5729 pIoc2->RaidVolume[i].VolumeID);
5732 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
5738 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
5743 ConfigPageHeader_t header;
5744 dma_addr_t ioc3_dma;
5747 /* Free the old page
5749 kfree(ioc->raid_data.pIocPg3);
5750 ioc->raid_data.pIocPg3 = NULL;
5752 /* There is at least one physical disk.
5753 * Read and save IOC Page 3
5755 header.PageVersion = 0;
5756 header.PageLength = 0;
5757 header.PageNumber = 3;
5758 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5759 cfg.cfghdr.hdr = &header;
5762 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5765 if (mpt_config(ioc, &cfg) != 0)
5768 if (header.PageLength == 0)
5771 /* Read Header good, alloc memory
5773 iocpage3sz = header.PageLength * 4;
5774 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
5778 /* Read the Page and save the data
5779 * into malloc'd memory.
5781 cfg.physAddr = ioc3_dma;
5782 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5783 if (mpt_config(ioc, &cfg) == 0) {
5784 mem = kmalloc(iocpage3sz, GFP_KERNEL);
5786 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
5787 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
5791 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
5797 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
5801 ConfigPageHeader_t header;
5802 dma_addr_t ioc4_dma;
5805 /* Read and save IOC Page 4
5807 header.PageVersion = 0;
5808 header.PageLength = 0;
5809 header.PageNumber = 4;
5810 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5811 cfg.cfghdr.hdr = &header;
5814 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5817 if (mpt_config(ioc, &cfg) != 0)
5820 if (header.PageLength == 0)
5823 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
5824 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
5825 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
5828 ioc->alloc_total += iocpage4sz;
5830 ioc4_dma = ioc->spi_data.IocPg4_dma;
5831 iocpage4sz = ioc->spi_data.IocPg4Sz;
5834 /* Read the Page into dma memory.
5836 cfg.physAddr = ioc4_dma;
5837 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5838 if (mpt_config(ioc, &cfg) == 0) {
5839 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
5840 ioc->spi_data.IocPg4_dma = ioc4_dma;
5841 ioc->spi_data.IocPg4Sz = iocpage4sz;
5843 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
5844 ioc->spi_data.pIocPg4 = NULL;
5845 ioc->alloc_total -= iocpage4sz;
5850 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
5854 ConfigPageHeader_t header;
5855 dma_addr_t ioc1_dma;
5859 /* Check the Coalescing Timeout in IOC Page 1
5861 header.PageVersion = 0;
5862 header.PageLength = 0;
5863 header.PageNumber = 1;
5864 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5865 cfg.cfghdr.hdr = &header;
5868 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5871 if (mpt_config(ioc, &cfg) != 0)
5874 if (header.PageLength == 0)
5877 /* Read Header good, alloc memory
5879 iocpage1sz = header.PageLength * 4;
5880 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
5884 /* Read the Page and check coalescing timeout
5886 cfg.physAddr = ioc1_dma;
5887 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5888 if (mpt_config(ioc, &cfg) == 0) {
5890 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
5891 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
5892 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
5894 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Coalescing Enabled Timeout = %d\n",
5897 if (tmp > MPT_COALESCING_TIMEOUT) {
5898 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
5900 /* Write NVRAM and current
5903 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5904 if (mpt_config(ioc, &cfg) == 0) {
5905 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Reset Current Coalescing Timeout to = %d\n",
5906 ioc->name, MPT_COALESCING_TIMEOUT));
5908 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
5909 if (mpt_config(ioc, &cfg) == 0) {
5910 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5911 "Reset NVRAM Coalescing Timeout to = %d\n",
5912 ioc->name, MPT_COALESCING_TIMEOUT));
5914 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5915 "Reset NVRAM Coalescing Timeout Failed\n",
5920 dprintk(ioc, printk(MYIOC_s_WARN_FMT
5921 "Reset of Current Coalescing Timeout Failed!\n",
5927 dprintk(ioc, printk(MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
5931 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
5937 mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
5940 ConfigPageHeader_t hdr;
5942 ManufacturingPage0_t *pbuf = NULL;
5944 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5945 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5947 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
5948 cfg.cfghdr.hdr = &hdr;
5950 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5953 if (mpt_config(ioc, &cfg) != 0)
5956 if (!cfg.cfghdr.hdr->PageLength)
5959 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5960 pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
5964 cfg.physAddr = buf_dma;
5966 if (mpt_config(ioc, &cfg) != 0)
5969 memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name));
5970 memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
5971 memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
5976 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
5979 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5981 * SendEventNotification - Send EventNotification (on or off) request to adapter
5982 * @ioc: Pointer to MPT_ADAPTER structure
5983 * @EvSwitch: Event switch flags
5984 * @sleepFlag: Specifies whether the process can sleep
5987 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch, int sleepFlag)
5989 EventNotification_t evn;
5990 MPIDefaultReply_t reply_buf;
5992 memset(&evn, 0, sizeof(EventNotification_t));
5993 memset(&reply_buf, 0, sizeof(MPIDefaultReply_t));
5995 evn.Function = MPI_FUNCTION_EVENT_NOTIFICATION;
5996 evn.Switch = EvSwitch;
5997 evn.MsgContext = cpu_to_le32(mpt_base_index << 16);
5999 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6000 "Sending EventNotification (%d) request %p\n",
6001 ioc->name, EvSwitch, &evn));
6003 return mpt_handshake_req_reply_wait(ioc, sizeof(EventNotification_t),
6004 (u32 *)&evn, sizeof(MPIDefaultReply_t), (u16 *)&reply_buf, 30,
6008 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6010 * SendEventAck - Send EventAck request to MPT adapter.
6011 * @ioc: Pointer to MPT_ADAPTER structure
6012 * @evnp: Pointer to original EventNotification request
6015 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
6019 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
6020 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
6021 ioc->name, __func__));
6025 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventAck\n", ioc->name));
6027 pAck->Function = MPI_FUNCTION_EVENT_ACK;
6028 pAck->ChainOffset = 0;
6029 pAck->Reserved[0] = pAck->Reserved[1] = 0;
6031 pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
6032 pAck->Event = evnp->Event;
6033 pAck->EventContext = evnp->EventContext;
6035 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
6040 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6042 * mpt_config - Generic function to issue config message
6043 * @ioc: Pointer to an adapter structure
6044 * @pCfg: Pointer to a configuration structure. Struct contains
6045 * action, page address, direction, physical address
6046 * and pointer to a configuration page header
6047 * Page header is updated.
6049 * Returns 0 for success
6050 * -EPERM if not allowed due to ISR context
6051 * -EAGAIN if no msg frames currently available
6052 * -EFAULT for non-successful reply or no reply (timeout)
6055 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
6058 ConfigReply_t *pReply;
6059 ConfigExtendedPageHeader_t *pExtHdr = NULL;
6065 u8 page_type = 0, extend_page;
6066 unsigned long timeleft;
6068 u8 issue_hard_reset = 0;
6071 /* Prevent calling wait_event() (below), if caller happens
6072 * to be in ISR context, because that is fatal!
6074 in_isr = in_interrupt();
6076 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
6081 /* don't send if no chance of success */
6083 mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_OPERATIONAL) {
6084 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6085 "%s: ioc not operational, %d, %xh\n",
6086 ioc->name, __func__, ioc->active,
6087 mpt_GetIocState(ioc, 0)));
6092 mutex_lock(&ioc->mptbase_cmds.mutex);
6093 /* init the internal cmd struct */
6094 memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE);
6095 INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status)
6097 /* Get and Populate a free Frame
6099 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
6100 dcprintk(ioc, printk(MYIOC_s_WARN_FMT
6101 "mpt_config: no msg frames!\n", ioc->name));
6106 pReq = (Config_t *)mf;
6107 pReq->Action = pCfg->action;
6109 pReq->ChainOffset = 0;
6110 pReq->Function = MPI_FUNCTION_CONFIG;
6112 /* Assume page type is not extended and clear "reserved" fields. */
6113 pReq->ExtPageLength = 0;
6114 pReq->ExtPageType = 0;
6117 for (ii=0; ii < 8; ii++)
6118 pReq->Reserved2[ii] = 0;
6120 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
6121 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
6122 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
6123 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
6125 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
6126 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
6127 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
6128 pReq->ExtPageType = pExtHdr->ExtPageType;
6129 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
6131 /* Page Length must be treated as a reserved field for the
6134 pReq->Header.PageLength = 0;
6137 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
6139 /* Add a SGE to the config request.
6142 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
6144 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
6146 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) ==
6147 MPI_CONFIG_PAGETYPE_EXTENDED) {
6148 flagsLength |= pExtHdr->ExtPageLength * 4;
6149 page_type = pReq->ExtPageType;
6152 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
6153 page_type = pReq->Header.PageType;
6157 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6158 "Sending Config request type 0x%x, page 0x%x and action %d\n",
6159 ioc->name, page_type, pReq->Header.PageNumber, pReq->Action));
6161 ioc->add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
6162 timeout = (pCfg->timeout < 15) ? HZ*15 : HZ*pCfg->timeout;
6163 mpt_put_msg_frame(mpt_base_index, ioc, mf);
6164 timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done,
6166 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
6168 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6169 "Failed Sending Config request type 0x%x, page 0x%x,"
6170 " action %d, status %xh, time left %ld\n\n",
6171 ioc->name, page_type, pReq->Header.PageNumber,
6172 pReq->Action, ioc->mptbase_cmds.status, timeleft));
6173 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
6176 issue_hard_reset = 1;
6180 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
6184 pReply = (ConfigReply_t *)ioc->mptbase_cmds.reply;
6185 ret = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
6186 if (ret == MPI_IOCSTATUS_SUCCESS) {
6188 pCfg->cfghdr.ehdr->ExtPageLength =
6189 le16_to_cpu(pReply->ExtPageLength);
6190 pCfg->cfghdr.ehdr->ExtPageType =
6191 pReply->ExtPageType;
6193 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
6194 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
6195 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
6196 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
6201 printk(MYIOC_s_INFO_FMT "Retry completed "
6202 "ret=0x%x timeleft=%ld\n",
6203 ioc->name, ret, timeleft);
6205 dcprintk(ioc, printk(KERN_DEBUG "IOCStatus=%04xh, IOCLogInfo=%08xh\n",
6206 ret, le32_to_cpu(pReply->IOCLogInfo)));
6210 CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status)
6211 mutex_unlock(&ioc->mptbase_cmds.mutex);
6212 if (issue_hard_reset) {
6213 issue_hard_reset = 0;
6214 printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n",
6215 ioc->name, __func__);
6216 mpt_HardResetHandler(ioc, CAN_SLEEP);
6217 mpt_free_msg_frame(ioc, mf);
6218 /* attempt one retry for a timed out command */
6220 printk(MYIOC_s_INFO_FMT
6221 "Attempting Retry Config request"
6222 " type 0x%x, page 0x%x,"
6223 " action %d\n", ioc->name, page_type,
6224 pCfg->cfghdr.hdr->PageNumber, pCfg->action);
6233 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6235 * mpt_ioc_reset - Base cleanup for hard reset
6236 * @ioc: Pointer to the adapter structure
6237 * @reset_phase: Indicates pre- or post-reset functionality
6239 * Remark: Frees resources with internally generated commands.
6242 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
6244 switch (reset_phase) {
6245 case MPT_IOC_SETUP_RESET:
6246 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6247 "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
6249 case MPT_IOC_PRE_RESET:
6250 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6251 "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
6253 case MPT_IOC_POST_RESET:
6254 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6255 "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
6256 /* wake up mptbase_cmds */
6257 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) {
6258 ioc->mptbase_cmds.status |=
6259 MPT_MGMT_STATUS_DID_IOCRESET;
6260 complete(&ioc->mptbase_cmds.done);
6267 return 1; /* currently means nothing really */
6271 #ifdef CONFIG_PROC_FS /* { */
6272 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6274 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
6276 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6278 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
6280 * Returns 0 for success, non-zero for failure.
6283 procmpt_create(void)
6285 struct proc_dir_entry *ent;
6287 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
6288 if (mpt_proc_root_dir == NULL)
6291 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
6293 ent->read_proc = procmpt_summary_read;
6295 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
6297 ent->read_proc = procmpt_version_read;
6302 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6304 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
6306 * Returns 0 for success, non-zero for failure.
6309 procmpt_destroy(void)
6311 remove_proc_entry("version", mpt_proc_root_dir);
6312 remove_proc_entry("summary", mpt_proc_root_dir);
6313 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
6316 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6318 * procmpt_summary_read - Handle read request of a summary file
6319 * @buf: Pointer to area to write information
6320 * @start: Pointer to start pointer
6321 * @offset: Offset to start writing
6322 * @request: Amount of read data requested
6323 * @eof: Pointer to EOF integer
6326 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
6327 * Returns number of characters written to process performing the read.
6330 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6340 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
6344 list_for_each_entry(ioc, &ioc_list, list) {
6347 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
6350 if ((out-buf) >= request)
6357 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6360 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6362 * procmpt_version_read - Handle read request from /proc/mpt/version.
6363 * @buf: Pointer to area to write information
6364 * @start: Pointer to start pointer
6365 * @offset: Offset to start writing
6366 * @request: Amount of read data requested
6367 * @eof: Pointer to EOF integer
6370 * Returns number of characters written to process performing the read.
6373 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6376 int scsi, fc, sas, lan, ctl, targ, dmp;
6380 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
6381 len += sprintf(buf+len, " Fusion MPT base driver\n");
6383 scsi = fc = sas = lan = ctl = targ = dmp = 0;
6384 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6386 if (MptCallbacks[cb_idx]) {
6387 switch (MptDriverClass[cb_idx]) {
6389 if (!scsi++) drvname = "SPI host";
6392 if (!fc++) drvname = "FC host";
6395 if (!sas++) drvname = "SAS host";
6398 if (!lan++) drvname = "LAN";
6401 if (!targ++) drvname = "SCSI target";
6404 if (!ctl++) drvname = "ioctl";
6409 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
6413 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6416 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6418 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
6419 * @buf: Pointer to area to write information
6420 * @start: Pointer to start pointer
6421 * @offset: Offset to start writing
6422 * @request: Amount of read data requested
6423 * @eof: Pointer to EOF integer
6426 * Returns number of characters written to process performing the read.
6429 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6431 MPT_ADAPTER *ioc = data;
6437 mpt_get_fw_exp_ver(expVer, ioc);
6439 len = sprintf(buf, "%s:", ioc->name);
6440 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
6441 len += sprintf(buf+len, " (f/w download boot flag set)");
6442 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6443 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
6445 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
6446 ioc->facts.ProductID,
6448 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
6449 if (ioc->facts.FWImageSize)
6450 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
6451 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
6452 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
6453 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
6455 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
6456 ioc->facts.CurrentHostMfaHighAddr);
6457 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
6458 ioc->facts.CurrentSenseBufferHighAddr);
6460 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
6461 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
6463 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6464 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
6466 * Rounding UP to nearest 4-kB boundary here...
6468 sz = (ioc->req_sz * ioc->req_depth) + 128;
6469 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
6470 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6471 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
6472 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
6473 4*ioc->facts.RequestFrameSize,
6474 ioc->facts.GlobalCredits);
6476 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
6477 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
6478 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
6479 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6480 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
6481 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
6482 ioc->facts.CurReplyFrameSize,
6483 ioc->facts.ReplyQueueDepth);
6485 len += sprintf(buf+len, " MaxDevices = %d\n",
6486 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
6487 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
6490 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
6491 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
6493 ioc->facts.NumberOfPorts);
6494 if (ioc->bus_type == FC) {
6495 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
6496 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6497 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6498 a[5], a[4], a[3], a[2], a[1], a[0]);
6500 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
6501 ioc->fc_port_page0[p].WWNN.High,
6502 ioc->fc_port_page0[p].WWNN.Low,
6503 ioc->fc_port_page0[p].WWPN.High,
6504 ioc->fc_port_page0[p].WWPN.Low);
6508 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6511 #endif /* CONFIG_PROC_FS } */
6513 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6515 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
6518 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
6519 sprintf(buf, " (Exp %02d%02d)",
6520 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
6521 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
6524 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
6525 strcat(buf, " [MDBG]");
6529 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6531 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6532 * @ioc: Pointer to MPT_ADAPTER structure
6533 * @buffer: Pointer to buffer where IOC summary info should be written
6534 * @size: Pointer to number of bytes we wrote (set by this routine)
6535 * @len: Offset at which to start writing in buffer
6536 * @showlan: Display LAN stuff?
6538 * This routine writes (english readable) ASCII text, which represents
6539 * a summary of IOC information, to a buffer.
6542 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
6547 mpt_get_fw_exp_ver(expVer, ioc);
6550 * Shorter summary of attached ioc's...
6552 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6555 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
6556 ioc->facts.FWVersion.Word,
6558 ioc->facts.NumberOfPorts,
6561 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6562 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6563 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6564 a[5], a[4], a[3], a[2], a[1], a[0]);
6567 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
6570 y += sprintf(buffer+len+y, " (disabled)");
6572 y += sprintf(buffer+len+y, "\n");
6577 * mpt_set_taskmgmt_in_progress_flag - set flags associated with task managment
6578 * @ioc: Pointer to MPT_ADAPTER structure
6580 * Returns 0 for SUCCESS or -1 if FAILED.
6582 * If -1 is return, then it was not possible to set the flags
6585 mpt_set_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc)
6587 unsigned long flags;
6590 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6591 if (ioc->ioc_reset_in_progress || ioc->taskmgmt_in_progress ||
6592 (ioc->alt_ioc && ioc->alt_ioc->taskmgmt_in_progress)) {
6597 ioc->taskmgmt_in_progress = 1;
6599 ioc->alt_ioc->taskmgmt_in_progress = 1;
6601 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6604 EXPORT_SYMBOL(mpt_set_taskmgmt_in_progress_flag);
6607 * mpt_clear_taskmgmt_in_progress_flag - clear flags associated with task managment
6608 * @ioc: Pointer to MPT_ADAPTER structure
6612 mpt_clear_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc)
6614 unsigned long flags;
6616 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6617 ioc->taskmgmt_in_progress = 0;
6619 ioc->alt_ioc->taskmgmt_in_progress = 0;
6620 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6622 EXPORT_SYMBOL(mpt_clear_taskmgmt_in_progress_flag);
6626 * mpt_halt_firmware - Halts the firmware if it is operational and panic
6628 * @ioc: Pointer to MPT_ADAPTER structure
6632 mpt_halt_firmware(MPT_ADAPTER *ioc)
6636 ioc_raw_state = mpt_GetIocState(ioc, 0);
6638 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
6639 printk(MYIOC_s_ERR_FMT "IOC is in FAULT state (%04xh)!!!\n",
6640 ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
6641 panic("%s: IOC Fault (%04xh)!!!\n", ioc->name,
6642 ioc_raw_state & MPI_DOORBELL_DATA_MASK);
6644 CHIPREG_WRITE32(&ioc->chip->Doorbell, 0xC0FFEE00);
6645 panic("%s: Firmware is halted due to command timeout\n",
6649 EXPORT_SYMBOL(mpt_halt_firmware);
6651 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6655 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6657 * mpt_HardResetHandler - Generic reset handler
6658 * @ioc: Pointer to MPT_ADAPTER structure
6659 * @sleepFlag: Indicates if sleep or schedule must be called.
6661 * Issues SCSI Task Management call based on input arg values.
6662 * If TaskMgmt fails, returns associated SCSI request.
6664 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
6665 * or a non-interrupt thread. In the former, must not call schedule().
6667 * Note: A return of -1 is a FATAL error case, as it means a
6668 * FW reload/initialization failed.
6670 * Returns 0 for SUCCESS or -1 if FAILED.
6673 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6676 unsigned long flags;
6678 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name));
6680 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
6681 printk("MF count 0x%x !\n", ioc->mfcnt);
6683 if (mpt_fwfault_debug)
6684 mpt_halt_firmware(ioc);
6686 /* Reset the adapter. Prevent more than 1 call to
6687 * mpt_do_ioc_recovery at any instant in time.
6689 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6690 if (ioc->ioc_reset_in_progress) {
6691 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6694 ioc->ioc_reset_in_progress = 1;
6696 ioc->alt_ioc->ioc_reset_in_progress = 1;
6697 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6699 /* FIXME: If do_ioc_recovery fails, repeat....
6702 /* The SCSI driver needs to adjust timeouts on all current
6703 * commands prior to the diagnostic reset being issued.
6704 * Prevents timeouts occurring during a diagnostic reset...very bad.
6705 * For all other protocol drivers, this is a no-op.
6711 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6712 if (MptResetHandlers[cb_idx]) {
6713 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling IOC reset_setup handler #%d\n",
6714 ioc->name, cb_idx));
6715 r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
6717 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling alt-%s setup reset handler #%d\n",
6718 ioc->name, ioc->alt_ioc->name, cb_idx));
6719 r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_SETUP_RESET);
6725 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
6726 printk(MYIOC_s_WARN_FMT "Cannot recover rc = %d!\n", ioc->name, rc);
6730 ioc->alt_ioc->reload_fw = 0;
6732 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6733 ioc->ioc_reset_in_progress = 0;
6734 ioc->taskmgmt_in_progress = 0;
6736 ioc->alt_ioc->ioc_reset_in_progress = 0;
6737 ioc->alt_ioc->taskmgmt_in_progress = 0;
6739 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6741 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
6746 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6748 EventDescriptionStr(u8 event, u32 evData0, char *evStr)
6753 case MPI_EVENT_NONE:
6756 case MPI_EVENT_LOG_DATA:
6759 case MPI_EVENT_STATE_CHANGE:
6760 ds = "State Change";
6762 case MPI_EVENT_UNIT_ATTENTION:
6763 ds = "Unit Attention";
6765 case MPI_EVENT_IOC_BUS_RESET:
6766 ds = "IOC Bus Reset";
6768 case MPI_EVENT_EXT_BUS_RESET:
6769 ds = "External Bus Reset";
6771 case MPI_EVENT_RESCAN:
6772 ds = "Bus Rescan Event";
6774 case MPI_EVENT_LINK_STATUS_CHANGE:
6775 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
6776 ds = "Link Status(FAILURE) Change";
6778 ds = "Link Status(ACTIVE) Change";
6780 case MPI_EVENT_LOOP_STATE_CHANGE:
6781 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
6782 ds = "Loop State(LIP) Change";
6783 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
6784 ds = "Loop State(LPE) Change"; /* ??? */
6786 ds = "Loop State(LPB) Change"; /* ??? */
6788 case MPI_EVENT_LOGOUT:
6791 case MPI_EVENT_EVENT_CHANGE:
6797 case MPI_EVENT_INTEGRATED_RAID:
6799 u8 ReasonCode = (u8)(evData0 >> 16);
6800 switch (ReasonCode) {
6801 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
6802 ds = "Integrated Raid: Volume Created";
6804 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
6805 ds = "Integrated Raid: Volume Deleted";
6807 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
6808 ds = "Integrated Raid: Volume Settings Changed";
6810 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
6811 ds = "Integrated Raid: Volume Status Changed";
6813 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
6814 ds = "Integrated Raid: Volume Physdisk Changed";
6816 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
6817 ds = "Integrated Raid: Physdisk Created";
6819 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
6820 ds = "Integrated Raid: Physdisk Deleted";
6822 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
6823 ds = "Integrated Raid: Physdisk Settings Changed";
6825 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
6826 ds = "Integrated Raid: Physdisk Status Changed";
6828 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
6829 ds = "Integrated Raid: Domain Validation Needed";
6831 case MPI_EVENT_RAID_RC_SMART_DATA :
6832 ds = "Integrated Raid; Smart Data";
6834 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
6835 ds = "Integrated Raid: Replace Action Started";
6838 ds = "Integrated Raid";
6843 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
6844 ds = "SCSI Device Status Change";
6846 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
6848 u8 id = (u8)(evData0);
6849 u8 channel = (u8)(evData0 >> 8);
6850 u8 ReasonCode = (u8)(evData0 >> 16);
6851 switch (ReasonCode) {
6852 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
6853 snprintf(evStr, EVENT_DESCR_STR_SZ,
6854 "SAS Device Status Change: Added: "
6855 "id=%d channel=%d", id, channel);
6857 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
6858 snprintf(evStr, EVENT_DESCR_STR_SZ,
6859 "SAS Device Status Change: Deleted: "
6860 "id=%d channel=%d", id, channel);
6862 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
6863 snprintf(evStr, EVENT_DESCR_STR_SZ,
6864 "SAS Device Status Change: SMART Data: "
6865 "id=%d channel=%d", id, channel);
6867 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
6868 snprintf(evStr, EVENT_DESCR_STR_SZ,
6869 "SAS Device Status Change: No Persistancy: "
6870 "id=%d channel=%d", id, channel);
6872 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
6873 snprintf(evStr, EVENT_DESCR_STR_SZ,
6874 "SAS Device Status Change: Unsupported Device "
6875 "Discovered : id=%d channel=%d", id, channel);
6877 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
6878 snprintf(evStr, EVENT_DESCR_STR_SZ,
6879 "SAS Device Status Change: Internal Device "
6880 "Reset : id=%d channel=%d", id, channel);
6882 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
6883 snprintf(evStr, EVENT_DESCR_STR_SZ,
6884 "SAS Device Status Change: Internal Task "
6885 "Abort : id=%d channel=%d", id, channel);
6887 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
6888 snprintf(evStr, EVENT_DESCR_STR_SZ,
6889 "SAS Device Status Change: Internal Abort "
6890 "Task Set : id=%d channel=%d", id, channel);
6892 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
6893 snprintf(evStr, EVENT_DESCR_STR_SZ,
6894 "SAS Device Status Change: Internal Clear "
6895 "Task Set : id=%d channel=%d", id, channel);
6897 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
6898 snprintf(evStr, EVENT_DESCR_STR_SZ,
6899 "SAS Device Status Change: Internal Query "
6900 "Task : id=%d channel=%d", id, channel);
6903 snprintf(evStr, EVENT_DESCR_STR_SZ,
6904 "SAS Device Status Change: Unknown: "
6905 "id=%d channel=%d", id, channel);
6910 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
6911 ds = "Bus Timer Expired";
6913 case MPI_EVENT_QUEUE_FULL:
6915 u16 curr_depth = (u16)(evData0 >> 16);
6916 u8 channel = (u8)(evData0 >> 8);
6917 u8 id = (u8)(evData0);
6919 snprintf(evStr, EVENT_DESCR_STR_SZ,
6920 "Queue Full: channel=%d id=%d depth=%d",
6921 channel, id, curr_depth);
6924 case MPI_EVENT_SAS_SES:
6925 ds = "SAS SES Event";
6927 case MPI_EVENT_PERSISTENT_TABLE_FULL:
6928 ds = "Persistent Table Full";
6930 case MPI_EVENT_SAS_PHY_LINK_STATUS:
6932 u8 LinkRates = (u8)(evData0 >> 8);
6933 u8 PhyNumber = (u8)(evData0);
6934 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
6935 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
6936 switch (LinkRates) {
6937 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
6938 snprintf(evStr, EVENT_DESCR_STR_SZ,
6939 "SAS PHY Link Status: Phy=%d:"
6940 " Rate Unknown",PhyNumber);
6942 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
6943 snprintf(evStr, EVENT_DESCR_STR_SZ,
6944 "SAS PHY Link Status: Phy=%d:"
6945 " Phy Disabled",PhyNumber);
6947 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
6948 snprintf(evStr, EVENT_DESCR_STR_SZ,
6949 "SAS PHY Link Status: Phy=%d:"
6950 " Failed Speed Nego",PhyNumber);
6952 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
6953 snprintf(evStr, EVENT_DESCR_STR_SZ,
6954 "SAS PHY Link Status: Phy=%d:"
6955 " Sata OOB Completed",PhyNumber);
6957 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
6958 snprintf(evStr, EVENT_DESCR_STR_SZ,
6959 "SAS PHY Link Status: Phy=%d:"
6960 " Rate 1.5 Gbps",PhyNumber);
6962 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
6963 snprintf(evStr, EVENT_DESCR_STR_SZ,
6964 "SAS PHY Link Status: Phy=%d:"
6965 " Rate 3.0 Gpbs",PhyNumber);
6968 snprintf(evStr, EVENT_DESCR_STR_SZ,
6969 "SAS PHY Link Status: Phy=%d", PhyNumber);
6974 case MPI_EVENT_SAS_DISCOVERY_ERROR:
6975 ds = "SAS Discovery Error";
6977 case MPI_EVENT_IR_RESYNC_UPDATE:
6979 u8 resync_complete = (u8)(evData0 >> 16);
6980 snprintf(evStr, EVENT_DESCR_STR_SZ,
6981 "IR Resync Update: Complete = %d:",resync_complete);
6986 u8 ReasonCode = (u8)(evData0 >> 16);
6987 switch (ReasonCode) {
6988 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
6989 ds = "IR2: LD State Changed";
6991 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
6992 ds = "IR2: PD State Changed";
6994 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
6995 ds = "IR2: Bad Block Table Full";
6997 case MPI_EVENT_IR2_RC_PD_INSERTED:
6998 ds = "IR2: PD Inserted";
7000 case MPI_EVENT_IR2_RC_PD_REMOVED:
7001 ds = "IR2: PD Removed";
7003 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
7004 ds = "IR2: Foreign CFG Detected";
7006 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
7007 ds = "IR2: Rebuild Medium Error";
7015 case MPI_EVENT_SAS_DISCOVERY:
7018 ds = "SAS Discovery: Start";
7020 ds = "SAS Discovery: Stop";
7023 case MPI_EVENT_LOG_ENTRY_ADDED:
7024 ds = "SAS Log Entry Added";
7027 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
7029 u8 phy_num = (u8)(evData0);
7030 u8 port_num = (u8)(evData0 >> 8);
7031 u8 port_width = (u8)(evData0 >> 16);
7032 u8 primative = (u8)(evData0 >> 24);
7033 snprintf(evStr, EVENT_DESCR_STR_SZ,
7034 "SAS Broadcase Primative: phy=%d port=%d "
7035 "width=%d primative=0x%02x",
7036 phy_num, port_num, port_width, primative);
7040 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
7042 u8 reason = (u8)(evData0);
7043 u8 port_num = (u8)(evData0 >> 8);
7044 u16 handle = le16_to_cpu(evData0 >> 16);
7046 snprintf(evStr, EVENT_DESCR_STR_SZ,
7047 "SAS Initiator Device Status Change: reason=0x%02x "
7048 "port=%d handle=0x%04x",
7049 reason, port_num, handle);
7053 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
7055 u8 max_init = (u8)(evData0);
7056 u8 current_init = (u8)(evData0 >> 8);
7058 snprintf(evStr, EVENT_DESCR_STR_SZ,
7059 "SAS Initiator Device Table Overflow: max initiators=%02d "
7060 "current initators=%02d",
7061 max_init, current_init);
7064 case MPI_EVENT_SAS_SMP_ERROR:
7066 u8 status = (u8)(evData0);
7067 u8 port_num = (u8)(evData0 >> 8);
7068 u8 result = (u8)(evData0 >> 16);
7070 if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
7071 snprintf(evStr, EVENT_DESCR_STR_SZ,
7072 "SAS SMP Error: port=%d result=0x%02x",
7074 else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
7075 snprintf(evStr, EVENT_DESCR_STR_SZ,
7076 "SAS SMP Error: port=%d : CRC Error",
7078 else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
7079 snprintf(evStr, EVENT_DESCR_STR_SZ,
7080 "SAS SMP Error: port=%d : Timeout",
7082 else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
7083 snprintf(evStr, EVENT_DESCR_STR_SZ,
7084 "SAS SMP Error: port=%d : No Destination",
7086 else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
7087 snprintf(evStr, EVENT_DESCR_STR_SZ,
7088 "SAS SMP Error: port=%d : Bad Destination",
7091 snprintf(evStr, EVENT_DESCR_STR_SZ,
7092 "SAS SMP Error: port=%d : status=0x%02x",
7098 * MPT base "custom" events may be added here...
7105 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
7108 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7110 * ProcessEventNotification - Route EventNotificationReply to all event handlers
7111 * @ioc: Pointer to MPT_ADAPTER structure
7112 * @pEventReply: Pointer to EventNotification reply frame
7113 * @evHandlers: Pointer to integer, number of event handlers
7115 * Routes a received EventNotificationReply to all currently registered
7117 * Returns sum of event handlers return values.
7120 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
7129 char evStr[EVENT_DESCR_STR_SZ];
7133 * Do platform normalization of values
7135 event = le32_to_cpu(pEventReply->Event) & 0xFF;
7136 // evCtx = le32_to_cpu(pEventReply->EventContext);
7137 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
7139 evData0 = le32_to_cpu(pEventReply->Data[0]);
7142 EventDescriptionStr(event, evData0, evStr);
7143 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event:(%02Xh) : %s\n",
7148 #ifdef CONFIG_FUSION_LOGGING
7149 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7150 ": Event data:\n", ioc->name));
7151 for (ii = 0; ii < evDataLen; ii++)
7152 devtverboseprintk(ioc, printk(" %08x",
7153 le32_to_cpu(pEventReply->Data[ii])));
7154 devtverboseprintk(ioc, printk("\n"));
7158 * Do general / base driver event processing
7161 case MPI_EVENT_EVENT_CHANGE: /* 0A */
7163 u8 evState = evData0 & 0xFF;
7165 /* CHECKME! What if evState unexpectedly says OFF (0)? */
7167 /* Update EventState field in cached IocFacts */
7168 if (ioc->facts.Function) {
7169 ioc->facts.EventState = evState;
7173 case MPI_EVENT_INTEGRATED_RAID:
7174 mptbase_raid_process_event_data(ioc,
7175 (MpiEventDataRaid_t *)pEventReply->Data);
7182 * Should this event be logged? Events are written sequentially.
7183 * When buffer is full, start again at the top.
7185 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
7188 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
7190 ioc->events[idx].event = event;
7191 ioc->events[idx].eventContext = ioc->eventContext;
7193 for (ii = 0; ii < 2; ii++) {
7195 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
7197 ioc->events[idx].data[ii] = 0;
7200 ioc->eventContext++;
7205 * Call each currently registered protocol event handler.
7207 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7208 if (MptEvHandlers[cb_idx]) {
7209 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Routing Event to event handler #%d\n",
7210 ioc->name, cb_idx));
7211 r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply);
7215 /* FIXME? Examine results here? */
7218 * If needed, send (a single) EventAck.
7220 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
7221 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7222 "EventAck required\n",ioc->name));
7223 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
7224 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SendEventAck returned %d\n",
7229 *evHandlers = handlers;
7233 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7235 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
7236 * @ioc: Pointer to MPT_ADAPTER structure
7237 * @log_info: U32 LogInfo reply word from the IOC
7239 * Refer to lsi/mpi_log_fc.h.
7242 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
7244 char *desc = "unknown";
7246 switch (log_info & 0xFF000000) {
7247 case MPI_IOCLOGINFO_FC_INIT_BASE:
7248 desc = "FCP Initiator";
7250 case MPI_IOCLOGINFO_FC_TARGET_BASE:
7251 desc = "FCP Target";
7253 case MPI_IOCLOGINFO_FC_LAN_BASE:
7256 case MPI_IOCLOGINFO_FC_MSG_BASE:
7257 desc = "MPI Message Layer";
7259 case MPI_IOCLOGINFO_FC_LINK_BASE:
7262 case MPI_IOCLOGINFO_FC_CTX_BASE:
7263 desc = "Context Manager";
7265 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
7266 desc = "Invalid Field Offset";
7268 case MPI_IOCLOGINFO_FC_STATE_CHANGE:
7269 desc = "State Change Info";
7273 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
7274 ioc->name, log_info, desc, (log_info & 0xFFFFFF));
7277 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7279 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
7280 * @ioc: Pointer to MPT_ADAPTER structure
7281 * @log_info: U32 LogInfo word from the IOC
7283 * Refer to lsi/sp_log.h.
7286 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
7288 u32 info = log_info & 0x00FF0000;
7289 char *desc = "unknown";
7293 desc = "bug! MID not found";
7294 if (ioc->reload_fw == 0)
7299 desc = "Parity Error";
7303 desc = "ASYNC Outbound Overrun";
7307 desc = "SYNC Offset Error";
7315 desc = "Msg In Overflow";
7323 desc = "Outbound DMA Overrun";
7327 desc = "Task Management";
7331 desc = "Device Problem";
7335 desc = "Invalid Phase Change";
7339 desc = "Untagged Table Size";
7344 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
7347 /* strings for sas loginfo */
7348 static char *originator_str[] = {
7353 static char *iop_code_str[] = {
7355 "Invalid SAS Address", /* 01h */
7357 "Invalid Page", /* 03h */
7358 "Diag Message Error", /* 04h */
7359 "Task Terminated", /* 05h */
7360 "Enclosure Management", /* 06h */
7361 "Target Mode" /* 07h */
7363 static char *pl_code_str[] = {
7365 "Open Failure", /* 01h */
7366 "Invalid Scatter Gather List", /* 02h */
7367 "Wrong Relative Offset or Frame Length", /* 03h */
7368 "Frame Transfer Error", /* 04h */
7369 "Transmit Frame Connected Low", /* 05h */
7370 "SATA Non-NCQ RW Error Bit Set", /* 06h */
7371 "SATA Read Log Receive Data Error", /* 07h */
7372 "SATA NCQ Fail All Commands After Error", /* 08h */
7373 "SATA Error in Receive Set Device Bit FIS", /* 09h */
7374 "Receive Frame Invalid Message", /* 0Ah */
7375 "Receive Context Message Valid Error", /* 0Bh */
7376 "Receive Frame Current Frame Error", /* 0Ch */
7377 "SATA Link Down", /* 0Dh */
7378 "Discovery SATA Init W IOS", /* 0Eh */
7379 "Config Invalid Page", /* 0Fh */
7380 "Discovery SATA Init Timeout", /* 10h */
7383 "IO Not Yet Executed", /* 13h */
7384 "IO Executed", /* 14h */
7385 "Persistent Reservation Out Not Affiliation "
7387 "Open Transmit DMA Abort", /* 16h */
7388 "IO Device Missing Delay Retry", /* 17h */
7389 "IO Cancelled Due to Recieve Error", /* 18h */
7397 "Enclosure Management" /* 20h */
7399 static char *ir_code_str[] = {
7400 "Raid Action Error", /* 00h */
7410 static char *raid_sub_code_str[] = {
7412 "Volume Creation Failed: Data Passed too "
7414 "Volume Creation Failed: Duplicate Volumes "
7415 "Attempted", /* 02h */
7416 "Volume Creation Failed: Max Number "
7417 "Supported Volumes Exceeded", /* 03h */
7418 "Volume Creation Failed: DMA Error", /* 04h */
7419 "Volume Creation Failed: Invalid Volume Type", /* 05h */
7420 "Volume Creation Failed: Error Reading "
7421 "MFG Page 4", /* 06h */
7422 "Volume Creation Failed: Creating Internal "
7423 "Structures", /* 07h */
7432 "Activation failed: Already Active Volume", /* 10h */
7433 "Activation failed: Unsupported Volume Type", /* 11h */
7434 "Activation failed: Too Many Active Volumes", /* 12h */
7435 "Activation failed: Volume ID in Use", /* 13h */
7436 "Activation failed: Reported Failure", /* 14h */
7437 "Activation failed: Importing a Volume", /* 15h */
7448 "Phys Disk failed: Too Many Phys Disks", /* 20h */
7449 "Phys Disk failed: Data Passed too Large", /* 21h */
7450 "Phys Disk failed: DMA Error", /* 22h */
7451 "Phys Disk failed: Invalid <channel:id>", /* 23h */
7452 "Phys Disk failed: Creating Phys Disk Config "
7465 "Compatibility Error: IR Disabled", /* 30h */
7466 "Compatibility Error: Inquiry Comand Failed", /* 31h */
7467 "Compatibility Error: Device not Direct Access "
7468 "Device ", /* 32h */
7469 "Compatibility Error: Removable Device Found", /* 33h */
7470 "Compatibility Error: Device SCSI Version not "
7471 "2 or Higher", /* 34h */
7472 "Compatibility Error: SATA Device, 48 BIT LBA "
7473 "not Supported", /* 35h */
7474 "Compatibility Error: Device doesn't have "
7475 "512 Byte Block Sizes", /* 36h */
7476 "Compatibility Error: Volume Type Check Failed", /* 37h */
7477 "Compatibility Error: Volume Type is "
7478 "Unsupported by FW", /* 38h */
7479 "Compatibility Error: Disk Drive too Small for "
7480 "use in Volume", /* 39h */
7481 "Compatibility Error: Phys Disk for Create "
7482 "Volume not Found", /* 3Ah */
7483 "Compatibility Error: Too Many or too Few "
7484 "Disks for Volume Type", /* 3Bh */
7485 "Compatibility Error: Disk stripe Sizes "
7486 "Must be 64KB", /* 3Ch */
7487 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
7490 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7492 * mpt_sas_log_info - Log information returned from SAS IOC.
7493 * @ioc: Pointer to MPT_ADAPTER structure
7494 * @log_info: U32 LogInfo reply word from the IOC
7496 * Refer to lsi/mpi_log_sas.h.
7499 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
7501 union loginfo_type {
7510 union loginfo_type sas_loginfo;
7511 char *originator_desc = NULL;
7512 char *code_desc = NULL;
7513 char *sub_code_desc = NULL;
7515 sas_loginfo.loginfo = log_info;
7516 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
7517 (sas_loginfo.dw.originator < ARRAY_SIZE(originator_str)))
7520 originator_desc = originator_str[sas_loginfo.dw.originator];
7522 switch (sas_loginfo.dw.originator) {
7525 if (sas_loginfo.dw.code <
7526 ARRAY_SIZE(iop_code_str))
7527 code_desc = iop_code_str[sas_loginfo.dw.code];
7530 if (sas_loginfo.dw.code <
7531 ARRAY_SIZE(pl_code_str))
7532 code_desc = pl_code_str[sas_loginfo.dw.code];
7535 if (sas_loginfo.dw.code >=
7536 ARRAY_SIZE(ir_code_str))
7538 code_desc = ir_code_str[sas_loginfo.dw.code];
7539 if (sas_loginfo.dw.subcode >=
7540 ARRAY_SIZE(raid_sub_code_str))
7542 if (sas_loginfo.dw.code == 0)
7544 raid_sub_code_str[sas_loginfo.dw.subcode];
7550 if (sub_code_desc != NULL)
7551 printk(MYIOC_s_INFO_FMT
7552 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7554 ioc->name, log_info, originator_desc, code_desc,
7556 else if (code_desc != NULL)
7557 printk(MYIOC_s_INFO_FMT
7558 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7559 " SubCode(0x%04x)\n",
7560 ioc->name, log_info, originator_desc, code_desc,
7561 sas_loginfo.dw.subcode);
7563 printk(MYIOC_s_INFO_FMT
7564 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
7565 " SubCode(0x%04x)\n",
7566 ioc->name, log_info, originator_desc,
7567 sas_loginfo.dw.code, sas_loginfo.dw.subcode);
7570 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7572 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
7573 * @ioc: Pointer to MPT_ADAPTER structure
7574 * @ioc_status: U32 IOCStatus word from IOC
7575 * @mf: Pointer to MPT request frame
7577 * Refer to lsi/mpi.h.
7580 mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7582 Config_t *pReq = (Config_t *)mf;
7583 char extend_desc[EVENT_DESCR_STR_SZ];
7588 if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
7589 page_type = pReq->ExtPageType;
7591 page_type = pReq->Header.PageType;
7594 * ignore invalid page messages for GET_NEXT_HANDLE
7596 form = le32_to_cpu(pReq->PageAddress);
7597 if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
7598 if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
7599 page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
7600 page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
7601 if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
7602 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
7605 if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
7606 if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
7607 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
7611 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
7612 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
7613 page_type, pReq->Header.PageNumber, pReq->Action, form);
7615 switch (ioc_status) {
7617 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7618 desc = "Config Page Invalid Action";
7621 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7622 desc = "Config Page Invalid Type";
7625 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7626 desc = "Config Page Invalid Page";
7629 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7630 desc = "Config Page Invalid Data";
7633 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7634 desc = "Config Page No Defaults";
7637 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7638 desc = "Config Page Can't Commit";
7645 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s: %s\n",
7646 ioc->name, ioc_status, desc, extend_desc));
7650 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
7651 * @ioc: Pointer to MPT_ADAPTER structure
7652 * @ioc_status: U32 IOCStatus word from IOC
7653 * @mf: Pointer to MPT request frame
7655 * Refer to lsi/mpi.h.
7658 mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7660 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
7665 /****************************************************************************/
7666 /* Common IOCStatus values for all replies */
7667 /****************************************************************************/
7669 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
7670 desc = "Invalid Function";
7673 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
7677 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
7678 desc = "Invalid SGL";
7681 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
7682 desc = "Internal Error";
7685 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
7689 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
7690 desc = "Insufficient Resources";
7693 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
7694 desc = "Invalid Field";
7697 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
7698 desc = "Invalid State";
7701 /****************************************************************************/
7702 /* Config IOCStatus values */
7703 /****************************************************************************/
7705 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7706 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7707 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7708 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7709 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7710 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7711 mpt_iocstatus_info_config(ioc, status, mf);
7714 /****************************************************************************/
7715 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
7717 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
7719 /****************************************************************************/
7721 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
7722 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
7723 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
7724 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
7725 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
7726 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
7727 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
7728 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
7729 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
7730 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
7731 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
7732 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
7733 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
7736 /****************************************************************************/
7737 /* SCSI Target values */
7738 /****************************************************************************/
7740 case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
7741 desc = "Target: Priority IO";
7744 case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
7745 desc = "Target: Invalid Port";
7748 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
7749 desc = "Target Invalid IO Index:";
7752 case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
7753 desc = "Target: Aborted";
7756 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
7757 desc = "Target: No Conn Retryable";
7760 case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
7761 desc = "Target: No Connection";
7764 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
7765 desc = "Target: Transfer Count Mismatch";
7768 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
7769 desc = "Target: STS Data not Sent";
7772 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
7773 desc = "Target: Data Offset Error";
7776 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
7777 desc = "Target: Too Much Write Data";
7780 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
7781 desc = "Target: IU Too Short";
7784 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
7785 desc = "Target: ACK NAK Timeout";
7788 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
7789 desc = "Target: Nak Received";
7792 /****************************************************************************/
7793 /* Fibre Channel Direct Access values */
7794 /****************************************************************************/
7796 case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
7797 desc = "FC: Aborted";
7800 case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
7801 desc = "FC: RX ID Invalid";
7804 case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
7805 desc = "FC: DID Invalid";
7808 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
7809 desc = "FC: Node Logged Out";
7812 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
7813 desc = "FC: Exchange Canceled";
7816 /****************************************************************************/
7818 /****************************************************************************/
7820 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
7821 desc = "LAN: Device not Found";
7824 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
7825 desc = "LAN: Device Failure";
7828 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
7829 desc = "LAN: Transmit Error";
7832 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
7833 desc = "LAN: Transmit Aborted";
7836 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
7837 desc = "LAN: Receive Error";
7840 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
7841 desc = "LAN: Receive Aborted";
7844 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
7845 desc = "LAN: Partial Packet";
7848 case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
7849 desc = "LAN: Canceled";
7852 /****************************************************************************/
7853 /* Serial Attached SCSI values */
7854 /****************************************************************************/
7856 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
7857 desc = "SAS: SMP Request Failed";
7860 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
7861 desc = "SAS: SMP Data Overrun";
7872 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s\n",
7873 ioc->name, status, desc));
7876 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7877 EXPORT_SYMBOL(mpt_attach);
7878 EXPORT_SYMBOL(mpt_detach);
7880 EXPORT_SYMBOL(mpt_resume);
7881 EXPORT_SYMBOL(mpt_suspend);
7883 EXPORT_SYMBOL(ioc_list);
7884 EXPORT_SYMBOL(mpt_register);
7885 EXPORT_SYMBOL(mpt_deregister);
7886 EXPORT_SYMBOL(mpt_event_register);
7887 EXPORT_SYMBOL(mpt_event_deregister);
7888 EXPORT_SYMBOL(mpt_reset_register);
7889 EXPORT_SYMBOL(mpt_reset_deregister);
7890 EXPORT_SYMBOL(mpt_device_driver_register);
7891 EXPORT_SYMBOL(mpt_device_driver_deregister);
7892 EXPORT_SYMBOL(mpt_get_msg_frame);
7893 EXPORT_SYMBOL(mpt_put_msg_frame);
7894 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri);
7895 EXPORT_SYMBOL(mpt_free_msg_frame);
7896 EXPORT_SYMBOL(mpt_send_handshake_request);
7897 EXPORT_SYMBOL(mpt_verify_adapter);
7898 EXPORT_SYMBOL(mpt_GetIocState);
7899 EXPORT_SYMBOL(mpt_print_ioc_summary);
7900 EXPORT_SYMBOL(mpt_HardResetHandler);
7901 EXPORT_SYMBOL(mpt_config);
7902 EXPORT_SYMBOL(mpt_findImVolumes);
7903 EXPORT_SYMBOL(mpt_alloc_fw_memory);
7904 EXPORT_SYMBOL(mpt_free_fw_memory);
7905 EXPORT_SYMBOL(mptbase_sas_persist_operation);
7906 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
7908 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7910 * fusion_init - Fusion MPT base driver initialization routine.
7912 * Returns 0 for success, non-zero for failure.
7919 show_mptmod_ver(my_NAME, my_VERSION);
7920 printk(KERN_INFO COPYRIGHT "\n");
7922 for (cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
7923 MptCallbacks[cb_idx] = NULL;
7924 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
7925 MptEvHandlers[cb_idx] = NULL;
7926 MptResetHandlers[cb_idx] = NULL;
7929 /* Register ourselves (mptbase) in order to facilitate
7930 * EventNotification handling.
7932 mpt_base_index = mpt_register(mptbase_reply, MPTBASE_DRIVER);
7934 /* Register for hard reset handling callbacks.
7936 mpt_reset_register(mpt_base_index, mpt_ioc_reset);
7938 #ifdef CONFIG_PROC_FS
7939 (void) procmpt_create();
7944 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7946 * fusion_exit - Perform driver unload cleanup.
7948 * This routine frees all resources associated with each MPT adapter
7949 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
7955 mpt_reset_deregister(mpt_base_index);
7957 #ifdef CONFIG_PROC_FS
7962 module_init(fusion_init);
7963 module_exit(fusion_exit);