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];
149 static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq);
152 * Driver Callback Index's
154 static u8 mpt_base_index = MPT_MAX_PROTOCOL_DRIVERS;
155 static u8 last_drv_idx;
157 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
161 static irqreturn_t mpt_interrupt(int irq, void *bus_id);
162 static int mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, 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_timer_expired(unsigned long data);
194 static void mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc);
195 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, EventNotificationReply_t *evReply, int *evHandlers);
212 static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
213 static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
214 static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
215 static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
216 static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
217 static void mpt_inactive_raid_list_free(MPT_ADAPTER *ioc);
219 /* module entry point */
220 static int __init fusion_init (void);
221 static void __exit fusion_exit (void);
223 #define CHIPREG_READ32(addr) readl_relaxed(addr)
224 #define CHIPREG_READ32_dmasync(addr) readl(addr)
225 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
226 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
227 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
230 pci_disable_io_access(struct pci_dev *pdev)
234 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
236 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
240 pci_enable_io_access(struct pci_dev *pdev)
244 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
246 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
249 static int mpt_set_debug_level(const char *val, struct kernel_param *kp)
251 int ret = param_set_int(val, kp);
257 list_for_each_entry(ioc, &ioc_list, list)
258 ioc->debug_level = mpt_debug_level;
263 * mpt_get_cb_idx - obtain cb_idx for registered driver
264 * @dclass: class driver enum
266 * Returns cb_idx, or zero means it wasn't found
269 mpt_get_cb_idx(MPT_DRIVER_CLASS dclass)
273 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--)
274 if (MptDriverClass[cb_idx] == dclass)
280 * mpt_is_discovery_complete - determine if discovery has completed
281 * @ioc: per adatper instance
283 * Returns 1 when discovery completed, else zero.
286 mpt_is_discovery_complete(MPT_ADAPTER *ioc)
288 ConfigExtendedPageHeader_t hdr;
290 SasIOUnitPage0_t *buffer;
291 dma_addr_t dma_handle;
294 memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
295 memset(&cfg, 0, sizeof(CONFIGPARMS));
296 hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
297 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
298 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
299 cfg.cfghdr.ehdr = &hdr;
300 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
302 if ((mpt_config(ioc, &cfg)))
304 if (!hdr.ExtPageLength)
307 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
312 cfg.physAddr = dma_handle;
313 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
315 if ((mpt_config(ioc, &cfg)))
316 goto out_free_consistent;
318 if (!(buffer->PhyData[0].PortFlags &
319 MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS))
323 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
330 * mpt_fault_reset_work - work performed on workq after ioc fault
331 * @work: input argument, used to derive ioc
335 mpt_fault_reset_work(struct work_struct *work)
338 container_of(work, MPT_ADAPTER, fault_reset_work.work);
343 if (ioc->diagPending || !ioc->active)
346 ioc_raw_state = mpt_GetIocState(ioc, 0);
347 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
348 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state (%04xh)!!!\n",
349 ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
350 printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n",
351 ioc->name, __func__);
352 rc = mpt_HardResetHandler(ioc, CAN_SLEEP);
353 printk(MYIOC_s_WARN_FMT "%s: HardReset: %s\n", ioc->name,
354 __func__, (rc == 0) ? "success" : "failed");
355 ioc_raw_state = mpt_GetIocState(ioc, 0);
356 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT)
357 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state after "
358 "reset (%04xh)\n", ioc->name, ioc_raw_state &
359 MPI_DOORBELL_DATA_MASK);
360 } else if (ioc->bus_type == SAS && ioc->sas_discovery_quiesce_io) {
361 if ((mpt_is_discovery_complete(ioc))) {
362 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "clearing "
363 "discovery_quiesce_io flag\n", ioc->name));
364 ioc->sas_discovery_quiesce_io = 0;
370 * Take turns polling alternate controller
375 /* rearm the timer */
376 spin_lock_irqsave(&ioc->fault_reset_work_lock, flags);
377 if (ioc->reset_work_q)
378 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
379 msecs_to_jiffies(MPT_POLLING_INTERVAL));
380 spin_unlock_irqrestore(&ioc->fault_reset_work_lock, flags);
385 * Process turbo (context) reply...
388 mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
390 MPT_FRAME_HDR *mf = NULL;
391 MPT_FRAME_HDR *mr = NULL;
395 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got TURBO reply req_idx=%08x\n",
398 switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
399 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
400 req_idx = pa & 0x0000FFFF;
401 cb_idx = (pa & 0x00FF0000) >> 16;
402 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
404 case MPI_CONTEXT_REPLY_TYPE_LAN:
405 cb_idx = mpt_get_cb_idx(MPTLAN_DRIVER);
407 * Blind set of mf to NULL here was fatal
408 * after lan_reply says "freeme"
409 * Fix sort of combined with an optimization here;
410 * added explicit check for case where lan_reply
411 * was just returning 1 and doing nothing else.
412 * For this case skip the callback, but set up
413 * proper mf value first here:-)
415 if ((pa & 0x58000000) == 0x58000000) {
416 req_idx = pa & 0x0000FFFF;
417 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
418 mpt_free_msg_frame(ioc, mf);
423 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
425 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
426 cb_idx = mpt_get_cb_idx(MPTSTM_DRIVER);
427 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
434 /* Check for (valid) IO callback! */
435 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
436 MptCallbacks[cb_idx] == NULL) {
437 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
438 __func__, ioc->name, cb_idx);
442 if (MptCallbacks[cb_idx](ioc, mf, mr))
443 mpt_free_msg_frame(ioc, mf);
449 mpt_reply(MPT_ADAPTER *ioc, u32 pa)
460 /* non-TURBO reply! Hmmm, something may be up...
461 * Newest turbo reply mechanism; get address
462 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
465 /* Map DMA address of reply header to cpu address.
466 * pa is 32 bits - but the dma address may be 32 or 64 bits
467 * get offset based only only the low addresses
470 reply_dma_low = (pa <<= 1);
471 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
472 (reply_dma_low - ioc->reply_frames_low_dma));
474 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
475 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
476 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
478 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
479 ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
480 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mr);
482 /* Check/log IOC log info
484 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
485 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
486 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
487 if (ioc->bus_type == FC)
488 mpt_fc_log_info(ioc, log_info);
489 else if (ioc->bus_type == SPI)
490 mpt_spi_log_info(ioc, log_info);
491 else if (ioc->bus_type == SAS)
492 mpt_sas_log_info(ioc, log_info);
495 if (ioc_stat & MPI_IOCSTATUS_MASK)
496 mpt_iocstatus_info(ioc, (u32)ioc_stat, mf);
498 /* Check for (valid) IO callback! */
499 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
500 MptCallbacks[cb_idx] == NULL) {
501 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
502 __func__, ioc->name, cb_idx);
507 freeme = MptCallbacks[cb_idx](ioc, mf, mr);
510 /* Flush (non-TURBO) reply with a WRITE! */
511 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
514 mpt_free_msg_frame(ioc, mf);
518 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
520 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
521 * @irq: irq number (not used)
522 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
524 * This routine is registered via the request_irq() kernel API call,
525 * and handles all interrupts generated from a specific MPT adapter
526 * (also referred to as a IO Controller or IOC).
527 * This routine must clear the interrupt from the adapter and does
528 * so by reading the reply FIFO. Multiple replies may be processed
529 * per single call to this routine.
531 * This routine handles register-level access of the adapter but
532 * dispatches (calls) a protocol-specific callback routine to handle
533 * the protocol-specific details of the MPT request completion.
536 mpt_interrupt(int irq, void *bus_id)
538 MPT_ADAPTER *ioc = bus_id;
539 u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
541 if (pa == 0xFFFFFFFF)
545 * Drain the reply FIFO!
548 if (pa & MPI_ADDRESS_REPLY_A_BIT)
551 mpt_turbo_reply(ioc, pa);
552 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
553 } while (pa != 0xFFFFFFFF);
558 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
560 * mpt_base_reply - MPT base driver's callback routine
561 * @ioc: Pointer to MPT_ADAPTER structure
562 * @mf: Pointer to original MPT request frame
563 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
565 * MPT base driver's callback routine; all base driver
566 * "internal" request/reply processing is routed here.
567 * Currently used for EventNotification and EventAck handling.
569 * Returns 1 indicating original alloc'd request frame ptr
570 * should be freed, or 0 if it shouldn't.
573 mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
578 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply() called\n", ioc->name));
579 #ifdef CONFIG_FUSION_LOGGING
580 if ((ioc->debug_level & MPT_DEBUG_MSG_FRAME) &&
581 !(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) {
582 dmfprintk(ioc, printk(MYIOC_s_INFO_FMT ": Original request frame (@%p) header\n",
584 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)mf);
588 func = reply->u.hdr.Function;
589 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply, Function=%02Xh\n",
592 if (func == MPI_FUNCTION_EVENT_NOTIFICATION) {
593 EventNotificationReply_t *pEvReply = (EventNotificationReply_t *) reply;
597 results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
598 if (results != evHandlers) {
599 /* CHECKME! Any special handling needed here? */
600 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
601 ioc->name, evHandlers, results));
605 * Hmmm... It seems that EventNotificationReply is an exception
606 * to the rule of one reply per request.
608 if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) {
611 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
612 ioc->name, pEvReply));
615 #ifdef CONFIG_PROC_FS
616 // LogEvent(ioc, pEvReply);
619 } else if (func == MPI_FUNCTION_EVENT_ACK) {
620 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply, EventAck reply received\n",
622 } else if (func == MPI_FUNCTION_CONFIG) {
626 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "config_complete (mf=%p,mr=%p)\n",
627 ioc->name, mf, reply));
629 pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *)));
632 /* disable timer and remove from linked list */
633 del_timer(&pCfg->timer);
635 spin_lock_irqsave(&ioc->FreeQlock, flags);
636 list_del(&pCfg->linkage);
637 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
640 * If IOC Status is SUCCESS, save the header
641 * and set the status code to GOOD.
643 pCfg->status = MPT_CONFIG_ERROR;
645 ConfigReply_t *pReply = (ConfigReply_t *)reply;
648 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
649 dcprintk(ioc, printk(MYIOC_s_NOTE_FMT " IOCStatus=%04xh, IOCLogInfo=%08xh\n",
650 ioc->name, status, le32_to_cpu(pReply->IOCLogInfo)));
652 pCfg->status = status;
653 if (status == MPI_IOCSTATUS_SUCCESS) {
654 if ((pReply->Header.PageType &
655 MPI_CONFIG_PAGETYPE_MASK) ==
656 MPI_CONFIG_PAGETYPE_EXTENDED) {
657 pCfg->cfghdr.ehdr->ExtPageLength =
658 le16_to_cpu(pReply->ExtPageLength);
659 pCfg->cfghdr.ehdr->ExtPageType =
662 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
664 /* If this is a regular header, save PageLength. */
665 /* LMP Do this better so not using a reserved field! */
666 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
667 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
668 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
673 * Wake up the original calling thread
678 } else if (func == MPI_FUNCTION_SAS_IO_UNIT_CONTROL) {
679 /* we should be always getting a reply frame */
680 memcpy(ioc->persist_reply_frame, reply,
681 min(MPT_DEFAULT_FRAME_SIZE,
682 4*reply->u.reply.MsgLength));
683 del_timer(&ioc->persist_timer);
684 ioc->persist_wait_done = 1;
687 printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
692 * Conditionally tell caller to free the original
693 * EventNotification/EventAck/unexpected request frame!
698 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
700 * mpt_register - Register protocol-specific main callback handler.
701 * @cbfunc: callback function pointer
702 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
704 * This routine is called by a protocol-specific driver (SCSI host,
705 * LAN, SCSI target) to register its reply callback routine. Each
706 * protocol-specific driver must do this before it will be able to
707 * use any IOC resources, such as obtaining request frames.
709 * NOTES: The SCSI protocol driver currently calls this routine thrice
710 * in order to register separate callbacks; one for "normal" SCSI IO;
711 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
713 * Returns u8 valued "handle" in the range (and S.O.D. order)
714 * {N,...,7,6,5,...,1} if successful.
715 * A return value of MPT_MAX_PROTOCOL_DRIVERS (including zero!) should be
716 * considered an error by the caller.
719 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
722 last_drv_idx = MPT_MAX_PROTOCOL_DRIVERS;
725 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
726 * (slot/handle 0 is reserved!)
728 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
729 if (MptCallbacks[cb_idx] == NULL) {
730 MptCallbacks[cb_idx] = cbfunc;
731 MptDriverClass[cb_idx] = dclass;
732 MptEvHandlers[cb_idx] = NULL;
733 last_drv_idx = cb_idx;
741 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
743 * mpt_deregister - Deregister a protocol drivers resources.
744 * @cb_idx: previously registered callback handle
746 * Each protocol-specific driver should call this routine when its
747 * module is unloaded.
750 mpt_deregister(u8 cb_idx)
752 if (cb_idx && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
753 MptCallbacks[cb_idx] = NULL;
754 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
755 MptEvHandlers[cb_idx] = NULL;
761 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
763 * mpt_event_register - Register protocol-specific event callback handler.
764 * @cb_idx: previously registered (via mpt_register) callback handle
765 * @ev_cbfunc: callback function
767 * This routine can be called by one or more protocol-specific drivers
768 * if/when they choose to be notified of MPT events.
770 * Returns 0 for success.
773 mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc)
775 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
778 MptEvHandlers[cb_idx] = ev_cbfunc;
782 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
784 * mpt_event_deregister - Deregister protocol-specific event callback handler
785 * @cb_idx: previously registered callback handle
787 * Each protocol-specific driver should call this routine
788 * when it does not (or can no longer) handle events,
789 * or when its module is unloaded.
792 mpt_event_deregister(u8 cb_idx)
794 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
797 MptEvHandlers[cb_idx] = NULL;
800 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
802 * mpt_reset_register - Register protocol-specific IOC reset handler.
803 * @cb_idx: previously registered (via mpt_register) callback handle
804 * @reset_func: reset function
806 * This routine can be called by one or more protocol-specific drivers
807 * if/when they choose to be notified of IOC resets.
809 * Returns 0 for success.
812 mpt_reset_register(u8 cb_idx, MPT_RESETHANDLER reset_func)
814 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
817 MptResetHandlers[cb_idx] = reset_func;
821 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
823 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
824 * @cb_idx: previously registered callback handle
826 * Each protocol-specific driver should call this routine
827 * when it does not (or can no longer) handle IOC reset handling,
828 * or when its module is unloaded.
831 mpt_reset_deregister(u8 cb_idx)
833 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
836 MptResetHandlers[cb_idx] = NULL;
839 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
841 * mpt_device_driver_register - Register device driver hooks
842 * @dd_cbfunc: driver callbacks struct
843 * @cb_idx: MPT protocol driver index
846 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, u8 cb_idx)
849 const struct pci_device_id *id;
851 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
854 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
856 /* call per pci device probe entry point */
857 list_for_each_entry(ioc, &ioc_list, list) {
858 id = ioc->pcidev->driver ?
859 ioc->pcidev->driver->id_table : NULL;
860 if (dd_cbfunc->probe)
861 dd_cbfunc->probe(ioc->pcidev, id);
867 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
869 * mpt_device_driver_deregister - DeRegister device driver hooks
870 * @cb_idx: MPT protocol driver index
873 mpt_device_driver_deregister(u8 cb_idx)
875 struct mpt_pci_driver *dd_cbfunc;
878 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
881 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
883 list_for_each_entry(ioc, &ioc_list, list) {
884 if (dd_cbfunc->remove)
885 dd_cbfunc->remove(ioc->pcidev);
888 MptDeviceDriverHandlers[cb_idx] = NULL;
892 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
894 * mpt_get_msg_frame - Obtain an MPT request frame from the pool
895 * @cb_idx: Handle of registered MPT protocol driver
896 * @ioc: Pointer to MPT adapter structure
898 * Obtain an MPT request frame from the pool (of 1024) that are
899 * allocated per MPT adapter.
901 * Returns pointer to a MPT request frame or %NULL if none are available
902 * or IOC is not active.
905 mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc)
909 u16 req_idx; /* Request index */
911 /* validate handle and ioc identifier */
915 printk(MYIOC_s_WARN_FMT "IOC Not Active! mpt_get_msg_frame "
916 "returning NULL!\n", ioc->name);
919 /* If interrupts are not attached, do not return a request frame */
923 spin_lock_irqsave(&ioc->FreeQlock, flags);
924 if (!list_empty(&ioc->FreeQ)) {
927 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
928 u.frame.linkage.list);
929 list_del(&mf->u.frame.linkage.list);
930 mf->u.frame.linkage.arg1 = 0;
931 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
932 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
934 req_idx = req_offset / ioc->req_sz;
935 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
936 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
937 /* Default, will be changed if necessary in SG generation */
938 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame;
945 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
949 printk(MYIOC_s_WARN_FMT "IOC Active. No free Msg Frames! "
950 "Count 0x%x Max 0x%x\n", ioc->name, ioc->mfcnt,
953 if (mfcounter == PRINT_MF_COUNT)
954 printk(MYIOC_s_INFO_FMT "MF Count 0x%x Max 0x%x \n", ioc->name,
955 ioc->mfcnt, ioc->req_depth);
958 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_get_msg_frame(%d,%d), got mf=%p\n",
959 ioc->name, cb_idx, ioc->id, mf));
963 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
965 * mpt_put_msg_frame - Send a protocol-specific MPT request frame to an IOC
966 * @cb_idx: Handle of registered MPT protocol driver
967 * @ioc: Pointer to MPT adapter structure
968 * @mf: Pointer to MPT request frame
970 * This routine posts an MPT request frame to the request post FIFO of a
971 * specific MPT adapter.
974 mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
978 u16 req_idx; /* Request index */
980 /* ensure values are reset properly! */
981 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
982 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
984 req_idx = req_offset / ioc->req_sz;
985 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
986 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
988 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
990 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
991 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d "
992 "RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx,
993 ioc->RequestNB[req_idx]));
994 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
998 * mpt_put_msg_frame_hi_pri - Send a hi-pri protocol-specific MPT request frame
999 * @cb_idx: Handle of registered MPT protocol driver
1000 * @ioc: Pointer to MPT adapter structure
1001 * @mf: Pointer to MPT request frame
1003 * Send a protocol-specific MPT request frame to an IOC using
1004 * hi-priority request queue.
1006 * This routine posts an MPT request frame to the request post FIFO of a
1007 * specific MPT adapter.
1010 mpt_put_msg_frame_hi_pri(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
1014 u16 req_idx; /* Request index */
1016 /* ensure values are reset properly! */
1017 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
1018 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
1019 req_idx = req_offset / ioc->req_sz;
1020 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
1021 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
1023 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
1025 mf_dma_addr = (ioc->req_frames_low_dma + req_offset);
1026 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d\n",
1027 ioc->name, mf_dma_addr, req_idx));
1028 CHIPREG_WRITE32(&ioc->chip->RequestHiPriFifo, mf_dma_addr);
1031 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1033 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
1034 * @ioc: Pointer to MPT adapter structure
1035 * @mf: Pointer to MPT request frame
1037 * This routine places a MPT request frame back on the MPT adapter's
1041 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
1043 unsigned long flags;
1045 /* Put Request back on FreeQ! */
1046 spin_lock_irqsave(&ioc->FreeQlock, flags);
1047 mf->u.frame.linkage.arg1 = 0xdeadbeaf; /* signature to know if this mf is freed */
1048 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
1052 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1055 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1057 * mpt_add_sge - Place a simple 32 bit SGE at address pAddr.
1058 * @pAddr: virtual address for SGE
1059 * @flagslength: SGE flags and data transfer length
1060 * @dma_addr: Physical address
1062 * This routine places a MPT request frame back on the MPT adapter's
1066 mpt_add_sge(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1068 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
1069 pSge->FlagsLength = cpu_to_le32(flagslength);
1070 pSge->Address = cpu_to_le32(dma_addr);
1074 * mpt_add_sge_64bit - Place a simple 64 bit SGE at address pAddr.
1075 * @pAddr: virtual address for SGE
1076 * @flagslength: SGE flags and data transfer length
1077 * @dma_addr: Physical address
1079 * This routine places a MPT request frame back on the MPT adapter's
1083 mpt_add_sge_64bit(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1085 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1086 pSge->Address.Low = cpu_to_le32
1087 (lower_32_bits((unsigned long)(dma_addr)));
1088 pSge->Address.High = cpu_to_le32
1089 (upper_32_bits((unsigned long)dma_addr));
1090 pSge->FlagsLength = cpu_to_le32
1091 ((flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1095 * mpt_add_sge_64bit_1078 - Place a simple 64 bit SGE at address pAddr
1096 * (1078 workaround).
1097 * @pAddr: virtual address for SGE
1098 * @flagslength: SGE flags and data transfer length
1099 * @dma_addr: Physical address
1101 * This routine places a MPT request frame back on the MPT adapter's
1105 mpt_add_sge_64bit_1078(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1107 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1110 pSge->Address.Low = cpu_to_le32
1111 (lower_32_bits((unsigned long)(dma_addr)));
1112 tmp = (u32)(upper_32_bits((unsigned long)dma_addr));
1115 * 1078 errata workaround for the 36GB limitation
1117 if ((((u64)dma_addr + MPI_SGE_LENGTH(flagslength)) >> 32) == 9) {
1119 MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_LOCAL_ADDRESS);
1121 if (mpt_debug_level & MPT_DEBUG_36GB_MEM)
1122 printk(KERN_DEBUG "1078 P0M2 addressing for "
1123 "addr = 0x%llx len = %d\n",
1124 (unsigned long long)dma_addr,
1125 MPI_SGE_LENGTH(flagslength));
1128 pSge->Address.High = cpu_to_le32(tmp);
1129 pSge->FlagsLength = cpu_to_le32(
1130 (flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1133 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1135 * mpt_add_chain - Place a 32 bit chain SGE at address pAddr.
1136 * @pAddr: virtual address for SGE
1137 * @next: nextChainOffset value (u32's)
1138 * @length: length of next SGL segment
1139 * @dma_addr: Physical address
1143 mpt_add_chain(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1145 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
1146 pChain->Length = cpu_to_le16(length);
1147 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT;
1148 pChain->NextChainOffset = next;
1149 pChain->Address = cpu_to_le32(dma_addr);
1152 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1154 * mpt_add_chain_64bit - Place a 64 bit chain SGE at address pAddr.
1155 * @pAddr: virtual address for SGE
1156 * @next: nextChainOffset value (u32's)
1157 * @length: length of next SGL segment
1158 * @dma_addr: Physical address
1162 mpt_add_chain_64bit(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1164 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
1165 u32 tmp = dma_addr & 0xFFFFFFFF;
1167 pChain->Length = cpu_to_le16(length);
1168 pChain->Flags = (MPI_SGE_FLAGS_CHAIN_ELEMENT |
1169 MPI_SGE_FLAGS_64_BIT_ADDRESSING);
1171 pChain->NextChainOffset = next;
1173 pChain->Address.Low = cpu_to_le32(tmp);
1174 tmp = (u32)(upper_32_bits((unsigned long)dma_addr));
1175 pChain->Address.High = cpu_to_le32(tmp);
1178 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1180 * mpt_send_handshake_request - Send MPT request via doorbell handshake method.
1181 * @cb_idx: Handle of registered MPT protocol driver
1182 * @ioc: Pointer to MPT adapter structure
1183 * @reqBytes: Size of the request in bytes
1184 * @req: Pointer to MPT request frame
1185 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1187 * This routine is used exclusively to send MptScsiTaskMgmt
1188 * requests since they are required to be sent via doorbell handshake.
1190 * NOTE: It is the callers responsibility to byte-swap fields in the
1191 * request which are greater than 1 byte in size.
1193 * Returns 0 for success, non-zero for failure.
1196 mpt_send_handshake_request(u8 cb_idx, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
1202 /* State is known to be good upon entering
1203 * this function so issue the bus reset
1208 * Emulate what mpt_put_msg_frame() does /wrt to sanity
1209 * setting cb_idx/req_idx. But ONLY if this request
1210 * is in proper (pre-alloc'd) request buffer range...
1212 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
1213 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
1214 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
1215 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
1216 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
1219 /* Make sure there are no doorbells */
1220 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1222 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1223 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
1224 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
1226 /* Wait for IOC doorbell int */
1227 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
1231 /* Read doorbell and check for active bit */
1232 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
1235 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_send_handshake_request start, WaitCnt=%d\n",
1238 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1240 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1244 /* Send request via doorbell handshake */
1245 req_as_bytes = (u8 *) req;
1246 for (ii = 0; ii < reqBytes/4; ii++) {
1249 word = ((req_as_bytes[(ii*4) + 0] << 0) |
1250 (req_as_bytes[(ii*4) + 1] << 8) |
1251 (req_as_bytes[(ii*4) + 2] << 16) |
1252 (req_as_bytes[(ii*4) + 3] << 24));
1253 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
1254 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1260 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
1265 /* Make sure there are no doorbells */
1266 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1271 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1273 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
1274 * @ioc: Pointer to MPT adapter structure
1275 * @access_control_value: define bits below
1276 * @sleepFlag: Specifies whether the process can sleep
1278 * Provides mechanism for the host driver to control the IOC's
1279 * Host Page Buffer access.
1281 * Access Control Value - bits[15:12]
1283 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1284 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1285 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1287 * Returns 0 for success, non-zero for failure.
1291 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1295 /* return if in use */
1296 if (CHIPREG_READ32(&ioc->chip->Doorbell)
1297 & MPI_DOORBELL_ACTIVE)
1300 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1302 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1303 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1304 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1305 (access_control_value<<12)));
1307 /* Wait for IOC to clear Doorbell Status bit */
1308 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1314 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1316 * mpt_host_page_alloc - allocate system memory for the fw
1317 * @ioc: Pointer to pointer to IOC adapter
1318 * @ioc_init: Pointer to ioc init config page
1320 * If we already allocated memory in past, then resend the same pointer.
1321 * Returns 0 for success, non-zero for failure.
1324 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1328 u32 host_page_buffer_sz=0;
1330 if(!ioc->HostPageBuffer) {
1332 host_page_buffer_sz =
1333 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1335 if(!host_page_buffer_sz)
1336 return 0; /* fw doesn't need any host buffers */
1338 /* spin till we get enough memory */
1339 while(host_page_buffer_sz > 0) {
1341 if((ioc->HostPageBuffer = pci_alloc_consistent(
1343 host_page_buffer_sz,
1344 &ioc->HostPageBuffer_dma)) != NULL) {
1346 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1347 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1348 ioc->name, ioc->HostPageBuffer,
1349 (u32)ioc->HostPageBuffer_dma,
1350 host_page_buffer_sz));
1351 ioc->alloc_total += host_page_buffer_sz;
1352 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1356 host_page_buffer_sz -= (4*1024);
1360 if(!ioc->HostPageBuffer) {
1361 printk(MYIOC_s_ERR_FMT
1362 "Failed to alloc memory for host_page_buffer!\n",
1367 psge = (char *)&ioc_init->HostPageBufferSGE;
1368 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1369 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1370 MPI_SGE_FLAGS_32_BIT_ADDRESSING |
1371 MPI_SGE_FLAGS_HOST_TO_IOC |
1372 MPI_SGE_FLAGS_END_OF_BUFFER;
1373 if (sizeof(dma_addr_t) == sizeof(u64)) {
1374 flags_length |= MPI_SGE_FLAGS_64_BIT_ADDRESSING;
1376 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1377 flags_length |= ioc->HostPageBuffer_sz;
1378 ioc->add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1379 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1384 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1386 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1387 * @iocid: IOC unique identifier (integer)
1388 * @iocpp: Pointer to pointer to IOC adapter
1390 * Given a unique IOC identifier, set pointer to the associated MPT
1391 * adapter structure.
1393 * Returns iocid and sets iocpp if iocid is found.
1394 * Returns -1 if iocid is not found.
1397 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1401 list_for_each_entry(ioc,&ioc_list,list) {
1402 if (ioc->id == iocid) {
1413 * mpt_get_product_name - returns product string
1414 * @vendor: pci vendor id
1415 * @device: pci device id
1416 * @revision: pci revision id
1417 * @prod_name: string returned
1419 * Returns product string displayed when driver loads,
1420 * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1424 mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name)
1426 char *product_str = NULL;
1428 if (vendor == PCI_VENDOR_ID_BROCADE) {
1431 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1435 product_str = "BRE040 A0";
1438 product_str = "BRE040 A1";
1441 product_str = "BRE040";
1451 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1452 product_str = "LSIFC909 B1";
1454 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1455 product_str = "LSIFC919 B0";
1457 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1458 product_str = "LSIFC929 B0";
1460 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1461 if (revision < 0x80)
1462 product_str = "LSIFC919X A0";
1464 product_str = "LSIFC919XL A1";
1466 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1467 if (revision < 0x80)
1468 product_str = "LSIFC929X A0";
1470 product_str = "LSIFC929XL A1";
1472 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1473 product_str = "LSIFC939X A1";
1475 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1476 product_str = "LSIFC949X A1";
1478 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1482 product_str = "LSIFC949E A0";
1485 product_str = "LSIFC949E A1";
1488 product_str = "LSIFC949E";
1492 case MPI_MANUFACTPAGE_DEVID_53C1030:
1496 product_str = "LSI53C1030 A0";
1499 product_str = "LSI53C1030 B0";
1502 product_str = "LSI53C1030 B1";
1505 product_str = "LSI53C1030 B2";
1508 product_str = "LSI53C1030 C0";
1511 product_str = "LSI53C1030T A0";
1514 product_str = "LSI53C1030T A2";
1517 product_str = "LSI53C1030T A3";
1520 product_str = "LSI53C1020A A1";
1523 product_str = "LSI53C1030";
1527 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1531 product_str = "LSI53C1035 A2";
1534 product_str = "LSI53C1035 B0";
1537 product_str = "LSI53C1035";
1541 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1545 product_str = "LSISAS1064 A1";
1548 product_str = "LSISAS1064 A2";
1551 product_str = "LSISAS1064 A3";
1554 product_str = "LSISAS1064 A4";
1557 product_str = "LSISAS1064";
1561 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1565 product_str = "LSISAS1064E A0";
1568 product_str = "LSISAS1064E B0";
1571 product_str = "LSISAS1064E B1";
1574 product_str = "LSISAS1064E B2";
1577 product_str = "LSISAS1064E B3";
1580 product_str = "LSISAS1064E";
1584 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1588 product_str = "LSISAS1068 A0";
1591 product_str = "LSISAS1068 B0";
1594 product_str = "LSISAS1068 B1";
1597 product_str = "LSISAS1068";
1601 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1605 product_str = "LSISAS1068E A0";
1608 product_str = "LSISAS1068E B0";
1611 product_str = "LSISAS1068E B1";
1614 product_str = "LSISAS1068E B2";
1617 product_str = "LSISAS1068E B3";
1620 product_str = "LSISAS1068E";
1624 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1628 product_str = "LSISAS1078 A0";
1631 product_str = "LSISAS1078 B0";
1634 product_str = "LSISAS1078 C0";
1637 product_str = "LSISAS1078 C1";
1640 product_str = "LSISAS1078 C2";
1643 product_str = "LSISAS1078";
1651 sprintf(prod_name, "%s", product_str);
1655 * mpt_mapresources - map in memory mapped io
1656 * @ioc: Pointer to pointer to IOC adapter
1660 mpt_mapresources(MPT_ADAPTER *ioc)
1664 unsigned long mem_phys;
1670 struct pci_dev *pdev;
1673 ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
1674 if (pci_enable_device_mem(pdev)) {
1675 printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() "
1676 "failed\n", ioc->name);
1679 if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) {
1680 printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with "
1681 "MEM failed\n", ioc->name);
1685 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1687 if (sizeof(dma_addr_t) > 4) {
1688 const uint64_t required_mask = dma_get_required_mask
1690 if (required_mask > DMA_BIT_MASK(32)
1691 && !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
1692 && !pci_set_consistent_dma_mask(pdev,
1693 DMA_BIT_MASK(64))) {
1694 ioc->dma_mask = DMA_BIT_MASK(64);
1695 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1696 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1698 } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1699 && !pci_set_consistent_dma_mask(pdev,
1700 DMA_BIT_MASK(32))) {
1701 ioc->dma_mask = DMA_BIT_MASK(32);
1702 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1703 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1706 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1707 ioc->name, pci_name(pdev));
1711 if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1712 && !pci_set_consistent_dma_mask(pdev,
1713 DMA_BIT_MASK(32))) {
1714 ioc->dma_mask = DMA_BIT_MASK(32);
1715 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1716 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1719 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1720 ioc->name, pci_name(pdev));
1725 mem_phys = msize = 0;
1727 for (ii = 0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1728 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1731 /* Get I/O space! */
1732 port = pci_resource_start(pdev, ii);
1733 psize = pci_resource_len(pdev, ii);
1738 mem_phys = pci_resource_start(pdev, ii);
1739 msize = pci_resource_len(pdev, ii);
1742 ioc->mem_size = msize;
1745 /* Get logical ptr for PciMem0 space */
1746 /*mem = ioremap(mem_phys, msize);*/
1747 mem = ioremap(mem_phys, msize);
1749 printk(MYIOC_s_ERR_FMT ": ERROR - Unable to map adapter"
1750 " memory!\n", ioc->name);
1754 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %lx\n",
1755 ioc->name, mem, mem_phys));
1757 ioc->mem_phys = mem_phys;
1758 ioc->chip = (SYSIF_REGS __iomem *)mem;
1760 /* Save Port IO values in case we need to do downloadboot */
1761 ioc->pio_mem_phys = port;
1762 ioc->pio_chip = (SYSIF_REGS __iomem *)port;
1767 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1769 * mpt_attach - Install a PCI intelligent MPT adapter.
1770 * @pdev: Pointer to pci_dev structure
1771 * @id: PCI device ID information
1773 * This routine performs all the steps necessary to bring the IOC of
1774 * a MPT adapter to a OPERATIONAL state. This includes registering
1775 * memory regions, registering the interrupt, and allocating request
1776 * and reply memory pools.
1778 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1781 * Returns 0 for success, non-zero for failure.
1783 * TODO: Add support for polled controllers
1786 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1793 static int mpt_ids = 0;
1794 #ifdef CONFIG_PROC_FS
1795 struct proc_dir_entry *dent, *ent;
1798 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1800 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1804 ioc->id = mpt_ids++;
1805 sprintf(ioc->name, "ioc%d", ioc->id);
1808 * set initial debug level
1809 * (refer to mptdebug.h)
1812 ioc->debug_level = mpt_debug_level;
1813 if (mpt_debug_level)
1814 printk(KERN_INFO "mpt_debug_level=%xh\n", mpt_debug_level);
1816 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name));
1819 if (mpt_mapresources(ioc)) {
1825 * Setting up proper handlers for scatter gather handling
1827 if (ioc->dma_mask == DMA_BIT_MASK(64)) {
1828 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
1829 ioc->add_sge = &mpt_add_sge_64bit_1078;
1831 ioc->add_sge = &mpt_add_sge_64bit;
1832 ioc->add_chain = &mpt_add_chain_64bit;
1833 ioc->sg_addr_size = 8;
1835 ioc->add_sge = &mpt_add_sge;
1836 ioc->add_chain = &mpt_add_chain;
1837 ioc->sg_addr_size = 4;
1839 ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
1841 ioc->alloc_total = sizeof(MPT_ADAPTER);
1842 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1843 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1846 ioc->diagPending = 0;
1847 spin_lock_init(&ioc->diagLock);
1848 spin_lock_init(&ioc->initializing_hba_lock);
1850 /* Initialize the event logging.
1852 ioc->eventTypes = 0; /* None */
1853 ioc->eventContext = 0;
1854 ioc->eventLogSize = 0;
1861 ioc->cached_fw = NULL;
1863 /* Initilize SCSI Config Data structure
1865 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1867 /* Initialize the running configQ head.
1869 INIT_LIST_HEAD(&ioc->configQ);
1871 /* Initialize the fc rport list head.
1873 INIT_LIST_HEAD(&ioc->fc_rports);
1875 /* Find lookup slot. */
1876 INIT_LIST_HEAD(&ioc->list);
1879 /* Initialize workqueue */
1880 INIT_DELAYED_WORK(&ioc->fault_reset_work, mpt_fault_reset_work);
1881 spin_lock_init(&ioc->fault_reset_work_lock);
1883 snprintf(ioc->reset_work_q_name, sizeof(ioc->reset_work_q_name),
1884 "mpt_poll_%d", ioc->id);
1886 create_singlethread_workqueue(ioc->reset_work_q_name);
1887 if (!ioc->reset_work_q) {
1888 printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n",
1890 pci_release_selected_regions(pdev, ioc->bars);
1895 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",
1896 ioc->name, &ioc->facts, &ioc->pfacts[0]));
1898 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1899 mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name);
1901 switch (pdev->device)
1903 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1904 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1905 ioc->errata_flag_1064 = 1;
1906 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1907 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1908 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1909 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1913 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1914 if (revision < XL_929) {
1915 /* 929X Chip Fix. Set Split transactions level
1916 * for PCIX. Set MOST bits to zero.
1918 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1920 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1922 /* 929XL Chip Fix. Set MMRBC to 0x08.
1924 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1926 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1931 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1932 /* 919X Chip Fix. Set Split transactions level
1933 * for PCIX. Set MOST bits to zero.
1935 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1937 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1941 case MPI_MANUFACTPAGE_DEVID_53C1030:
1942 /* 1030 Chip Fix. Disable Split transactions
1943 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1945 if (revision < C0_1030) {
1946 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1948 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1951 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1952 ioc->bus_type = SPI;
1955 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1956 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1957 ioc->errata_flag_1064 = 1;
1959 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1960 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1961 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1962 ioc->bus_type = SAS;
1966 switch (ioc->bus_type) {
1969 ioc->msi_enable = mpt_msi_enable_sas;
1973 ioc->msi_enable = mpt_msi_enable_spi;
1977 ioc->msi_enable = mpt_msi_enable_fc;
1981 ioc->msi_enable = 0;
1984 if (ioc->errata_flag_1064)
1985 pci_disable_io_access(pdev);
1987 spin_lock_init(&ioc->FreeQlock);
1990 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1992 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1994 /* Set IOC ptr in the pcidev's driver data. */
1995 pci_set_drvdata(ioc->pcidev, ioc);
1997 /* Set lookup ptr. */
1998 list_add_tail(&ioc->list, &ioc_list);
2000 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
2002 mpt_detect_bound_ports(ioc, pdev);
2004 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
2006 printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",
2009 list_del(&ioc->list);
2011 ioc->alt_ioc->alt_ioc = NULL;
2012 iounmap(ioc->memmap);
2014 pci_release_selected_regions(pdev, ioc->bars);
2016 destroy_workqueue(ioc->reset_work_q);
2017 ioc->reset_work_q = NULL;
2020 pci_set_drvdata(pdev, NULL);
2024 /* call per device driver probe entry point */
2025 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
2026 if(MptDeviceDriverHandlers[cb_idx] &&
2027 MptDeviceDriverHandlers[cb_idx]->probe) {
2028 MptDeviceDriverHandlers[cb_idx]->probe(pdev,id);
2032 #ifdef CONFIG_PROC_FS
2034 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
2036 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
2038 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
2040 ent->read_proc = procmpt_iocinfo_read;
2043 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
2045 ent->read_proc = procmpt_summary_read;
2052 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
2053 msecs_to_jiffies(MPT_POLLING_INTERVAL));
2058 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2060 * mpt_detach - Remove a PCI intelligent MPT adapter.
2061 * @pdev: Pointer to pci_dev structure
2065 mpt_detach(struct pci_dev *pdev)
2067 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2070 unsigned long flags;
2071 struct workqueue_struct *wq;
2074 * Stop polling ioc for fault condition
2076 spin_lock_irqsave(&ioc->fault_reset_work_lock, flags);
2077 wq = ioc->reset_work_q;
2078 ioc->reset_work_q = NULL;
2079 spin_unlock_irqrestore(&ioc->fault_reset_work_lock, flags);
2080 cancel_delayed_work(&ioc->fault_reset_work);
2081 destroy_workqueue(wq);
2084 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
2085 remove_proc_entry(pname, NULL);
2086 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
2087 remove_proc_entry(pname, NULL);
2088 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
2089 remove_proc_entry(pname, NULL);
2091 /* call per device driver remove entry point */
2092 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
2093 if(MptDeviceDriverHandlers[cb_idx] &&
2094 MptDeviceDriverHandlers[cb_idx]->remove) {
2095 MptDeviceDriverHandlers[cb_idx]->remove(pdev);
2099 /* Disable interrupts! */
2100 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2103 synchronize_irq(pdev->irq);
2105 /* Clear any lingering interrupt */
2106 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2108 CHIPREG_READ32(&ioc->chip->IntStatus);
2110 mpt_adapter_dispose(ioc);
2112 pci_set_drvdata(pdev, NULL);
2115 /**************************************************************************
2119 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2121 * mpt_suspend - Fusion MPT base driver suspend routine.
2122 * @pdev: Pointer to pci_dev structure
2123 * @state: new state to enter
2126 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
2129 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2131 device_state = pci_choose_state(pdev, state);
2132 printk(MYIOC_s_INFO_FMT "pci-suspend: pdev=0x%p, slot=%s, Entering "
2133 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2136 /* put ioc into READY_STATE */
2137 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
2138 printk(MYIOC_s_ERR_FMT
2139 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
2142 /* disable interrupts */
2143 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2146 /* Clear any lingering interrupt */
2147 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2149 free_irq(ioc->pci_irq, ioc);
2150 if (ioc->msi_enable)
2151 pci_disable_msi(ioc->pcidev);
2153 pci_save_state(pdev);
2154 pci_disable_device(pdev);
2155 pci_release_selected_regions(pdev, ioc->bars);
2156 pci_set_power_state(pdev, device_state);
2160 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2162 * mpt_resume - Fusion MPT base driver resume routine.
2163 * @pdev: Pointer to pci_dev structure
2166 mpt_resume(struct pci_dev *pdev)
2168 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2169 u32 device_state = pdev->current_state;
2173 printk(MYIOC_s_INFO_FMT "pci-resume: pdev=0x%p, slot=%s, Previous "
2174 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2177 pci_set_power_state(pdev, PCI_D0);
2178 pci_enable_wake(pdev, PCI_D0, 0);
2179 pci_restore_state(pdev);
2181 err = mpt_mapresources(ioc);
2185 if (ioc->dma_mask == DMA_BIT_MASK(64)) {
2186 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
2187 ioc->add_sge = &mpt_add_sge_64bit_1078;
2189 ioc->add_sge = &mpt_add_sge_64bit;
2190 ioc->add_chain = &mpt_add_chain_64bit;
2191 ioc->sg_addr_size = 8;
2194 ioc->add_sge = &mpt_add_sge;
2195 ioc->add_chain = &mpt_add_chain;
2196 ioc->sg_addr_size = 4;
2198 ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
2200 printk(MYIOC_s_INFO_FMT "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
2201 ioc->name, (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
2202 CHIPREG_READ32(&ioc->chip->Doorbell));
2205 * Errata workaround for SAS pci express:
2206 * Upon returning to the D0 state, the contents of the doorbell will be
2207 * stale data, and this will incorrectly signal to the host driver that
2208 * the firmware is ready to process mpt commands. The workaround is
2209 * to issue a diagnostic reset.
2211 if (ioc->bus_type == SAS && (pdev->device ==
2212 MPI_MANUFACTPAGE_DEVID_SAS1068E || pdev->device ==
2213 MPI_MANUFACTPAGE_DEVID_SAS1064E)) {
2214 if (KickStart(ioc, 1, CAN_SLEEP) < 0) {
2215 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover\n",
2221 /* bring ioc to operational state */
2222 printk(MYIOC_s_INFO_FMT "Sending mpt_do_ioc_recovery\n", ioc->name);
2223 recovery_state = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
2225 if (recovery_state != 0)
2226 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover, "
2227 "error:[%x]\n", ioc->name, recovery_state);
2229 printk(MYIOC_s_INFO_FMT
2230 "pci-resume: success\n", ioc->name);
2238 mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase)
2240 if ((MptDriverClass[index] == MPTSPI_DRIVER &&
2241 ioc->bus_type != SPI) ||
2242 (MptDriverClass[index] == MPTFC_DRIVER &&
2243 ioc->bus_type != FC) ||
2244 (MptDriverClass[index] == MPTSAS_DRIVER &&
2245 ioc->bus_type != SAS))
2246 /* make sure we only call the relevant reset handler
2249 return (MptResetHandlers[index])(ioc, reset_phase);
2252 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2254 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
2255 * @ioc: Pointer to MPT adapter structure
2256 * @reason: Event word / reason
2257 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
2259 * This routine performs all the steps necessary to bring the IOC
2260 * to a OPERATIONAL state.
2262 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
2267 * -1 if failed to get board READY
2268 * -2 if READY but IOCFacts Failed
2269 * -3 if READY but PrimeIOCFifos Failed
2270 * -4 if READY but IOCInit Failed
2271 * -5 if failed to enable_device and/or request_selected_regions
2272 * -6 if failed to upload firmware
2275 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2277 int hard_reset_done = 0;
2278 int alt_ioc_ready = 0;
2285 int reset_alt_ioc_active = 0;
2286 int irq_allocated = 0;
2289 printk(MYIOC_s_INFO_FMT "Initiating %s\n", ioc->name,
2290 reason == MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
2292 /* Disable reply interrupts (also blocks FreeQ) */
2293 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2297 if (ioc->alt_ioc->active)
2298 reset_alt_ioc_active = 1;
2300 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
2301 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
2302 ioc->alt_ioc->active = 0;
2306 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
2309 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
2310 if (hard_reset_done == -4) {
2311 printk(MYIOC_s_WARN_FMT "Owned by PEER..skipping!\n",
2314 if (reset_alt_ioc_active && ioc->alt_ioc) {
2315 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
2316 dprintk(ioc, printk(MYIOC_s_INFO_FMT
2317 "alt_ioc reply irq re-enabled\n", ioc->alt_ioc->name));
2318 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2319 ioc->alt_ioc->active = 1;
2323 printk(MYIOC_s_WARN_FMT "NOT READY!\n", ioc->name);
2328 /* hard_reset_done = 0 if a soft reset was performed
2329 * and 1 if a hard reset was performed.
2331 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
2332 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
2335 printk(MYIOC_s_WARN_FMT "alt_ioc not ready!\n", ioc->alt_ioc->name);
2338 for (ii=0; ii<5; ii++) {
2339 /* Get IOC facts! Allow 5 retries */
2340 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
2346 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2347 "Retry IocFacts failed rc=%x\n", ioc->name, rc));
2349 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2350 MptDisplayIocCapabilities(ioc);
2353 if (alt_ioc_ready) {
2354 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
2355 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2356 "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
2357 /* Retry - alt IOC was initialized once
2359 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
2362 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2363 "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
2365 reset_alt_ioc_active = 0;
2366 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2367 MptDisplayIocCapabilities(ioc->alt_ioc);
2371 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP) &&
2372 (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)) {
2373 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2374 ioc->bars = pci_select_bars(ioc->pcidev, IORESOURCE_MEM |
2376 if (pci_enable_device(ioc->pcidev))
2378 if (pci_request_selected_regions(ioc->pcidev, ioc->bars,
2384 * Device is reset now. It must have de-asserted the interrupt line
2385 * (if it was asserted) and it should be safe to register for the
2388 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2390 if (ioc->pcidev->irq) {
2391 if (ioc->msi_enable && !pci_enable_msi(ioc->pcidev))
2392 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
2395 ioc->msi_enable = 0;
2396 rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
2397 IRQF_SHARED, ioc->name, ioc);
2399 printk(MYIOC_s_ERR_FMT "Unable to allocate "
2400 "interrupt %d!\n", ioc->name, ioc->pcidev->irq);
2401 if (ioc->msi_enable)
2402 pci_disable_msi(ioc->pcidev);
2406 ioc->pci_irq = ioc->pcidev->irq;
2407 pci_set_master(ioc->pcidev); /* ?? */
2408 dprintk(ioc, printk(MYIOC_s_INFO_FMT "installed at interrupt "
2409 "%d\n", ioc->name, ioc->pcidev->irq));
2413 /* Prime reply & request queues!
2414 * (mucho alloc's) Must be done prior to
2415 * init as upper addresses are needed for init.
2416 * If fails, continue with alt-ioc processing
2418 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
2421 /* May need to check/upload firmware & data here!
2422 * If fails, continue with alt-ioc processing
2424 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
2427 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
2428 printk(MYIOC_s_WARN_FMT ": alt_ioc (%d) FIFO mgmt alloc!\n",
2429 ioc->alt_ioc->name, rc);
2431 reset_alt_ioc_active = 0;
2434 if (alt_ioc_ready) {
2435 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
2437 reset_alt_ioc_active = 0;
2438 printk(MYIOC_s_WARN_FMT "alt_ioc (%d) init failure!\n",
2439 ioc->alt_ioc->name, rc);
2443 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
2444 if (ioc->upload_fw) {
2445 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2446 "firmware upload required!\n", ioc->name));
2448 /* Controller is not operational, cannot do upload
2451 rc = mpt_do_upload(ioc, sleepFlag);
2453 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2455 * Maintain only one pointer to FW memory
2456 * so there will not be two attempt to
2457 * downloadboot onboard dual function
2458 * chips (mpt_adapter_disable,
2461 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2462 "mpt_upload: alt_%s has cached_fw=%p \n",
2463 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
2464 ioc->cached_fw = NULL;
2467 printk(MYIOC_s_WARN_FMT
2468 "firmware upload failure!\n", ioc->name);
2476 /* Enable! (reply interrupt) */
2477 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
2481 if (reset_alt_ioc_active && ioc->alt_ioc) {
2482 /* (re)Enable alt-IOC! (reply interrupt) */
2483 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "alt_ioc reply irq re-enabled\n",
2484 ioc->alt_ioc->name));
2485 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2486 ioc->alt_ioc->active = 1;
2489 /* Enable MPT base driver management of EventNotification
2490 * and EventAck handling.
2492 if ((ret == 0) && (!ioc->facts.EventState))
2493 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
2495 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2496 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
2498 /* Add additional "reason" check before call to GetLanConfigPages
2499 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2500 * recursive scenario; GetLanConfigPages times out, timer expired
2501 * routine calls HardResetHandler, which calls into here again,
2502 * and we try GetLanConfigPages again...
2504 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2507 * Initalize link list for inactive raid volumes.
2509 mutex_init(&ioc->raid_data.inactive_list_mutex);
2510 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2512 if (ioc->bus_type == SAS) {
2514 /* clear persistency table */
2515 if(ioc->facts.IOCExceptions &
2516 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
2517 ret = mptbase_sas_persist_operation(ioc,
2518 MPI_SAS_OP_CLEAR_NOT_PRESENT);
2525 mpt_findImVolumes(ioc);
2527 } else if (ioc->bus_type == FC) {
2528 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
2529 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2531 * Pre-fetch the ports LAN MAC address!
2532 * (LANPage1_t stuff)
2534 (void) GetLanConfigPages(ioc);
2535 a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2536 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2537 "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
2538 ioc->name, a[5], a[4], a[3], a[2], a[1], a[0]));
2542 /* Get NVRAM and adapter maximums from SPP 0 and 2
2544 mpt_GetScsiPortSettings(ioc, 0);
2546 /* Get version and length of SDP 1
2548 mpt_readScsiDevicePageHeaders(ioc, 0);
2552 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
2553 mpt_findImVolumes(ioc);
2555 /* Check, and possibly reset, the coalescing value
2557 mpt_read_ioc_pg_1(ioc);
2559 mpt_read_ioc_pg_4(ioc);
2562 GetIoUnitPage2(ioc);
2563 mpt_get_manufacturing_pg_0(ioc);
2567 * Call each currently registered protocol IOC reset handler
2568 * with post-reset indication.
2569 * NOTE: If we're doing _IOC_BRINGUP, there can be no
2570 * MptResetHandlers[] registered yet.
2572 if (hard_reset_done) {
2574 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
2575 if ((ret == 0) && MptResetHandlers[cb_idx]) {
2576 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2577 "Calling IOC post_reset handler #%d\n",
2578 ioc->name, cb_idx));
2579 rc += mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET);
2583 if (alt_ioc_ready && MptResetHandlers[cb_idx]) {
2584 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2585 "Calling IOC post_reset handler #%d\n",
2586 ioc->alt_ioc->name, cb_idx));
2587 rc += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_POST_RESET);
2591 /* FIXME? Examine results here? */
2595 if ((ret != 0) && irq_allocated) {
2596 free_irq(ioc->pci_irq, ioc);
2597 if (ioc->msi_enable)
2598 pci_disable_msi(ioc->pcidev);
2603 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2605 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2606 * @ioc: Pointer to MPT adapter structure
2607 * @pdev: Pointer to (struct pci_dev) structure
2609 * Search for PCI bus/dev_function which matches
2610 * PCI bus/dev_function (+/-1) for newly discovered 929,
2611 * 929X, 1030 or 1035.
2613 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2614 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2617 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
2619 struct pci_dev *peer=NULL;
2620 unsigned int slot = PCI_SLOT(pdev->devfn);
2621 unsigned int func = PCI_FUNC(pdev->devfn);
2622 MPT_ADAPTER *ioc_srch;
2624 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PCI device %s devfn=%x/%x,"
2625 " searching for devfn match on %x or %x\n",
2626 ioc->name, pci_name(pdev), pdev->bus->number,
2627 pdev->devfn, func-1, func+1));
2629 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
2631 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
2636 list_for_each_entry(ioc_srch, &ioc_list, list) {
2637 struct pci_dev *_pcidev = ioc_srch->pcidev;
2638 if (_pcidev == peer) {
2639 /* Paranoia checks */
2640 if (ioc->alt_ioc != NULL) {
2641 printk(MYIOC_s_WARN_FMT "Oops, already bound to %s!\n",
2642 ioc->name, ioc->alt_ioc->name);
2644 } else if (ioc_srch->alt_ioc != NULL) {
2645 printk(MYIOC_s_WARN_FMT "Oops, already bound to %s!\n",
2646 ioc_srch->name, ioc_srch->alt_ioc->name);
2649 dprintk(ioc, printk(MYIOC_s_INFO_FMT "FOUND! binding to %s\n",
2650 ioc->name, ioc_srch->name));
2651 ioc_srch->alt_ioc = ioc;
2652 ioc->alt_ioc = ioc_srch;
2658 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2660 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2661 * @ioc: Pointer to MPT adapter structure
2664 mpt_adapter_disable(MPT_ADAPTER *ioc)
2669 if (ioc->cached_fw != NULL) {
2670 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: Pushing FW onto "
2671 "adapter\n", __func__, ioc->name));
2672 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)
2673 ioc->cached_fw, CAN_SLEEP)) < 0) {
2674 printk(MYIOC_s_WARN_FMT
2675 ": firmware downloadboot failure (%d)!\n",
2680 /* Disable adapter interrupts! */
2681 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2683 /* Clear any lingering interrupt */
2684 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2686 if (ioc->alloc != NULL) {
2688 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "free @ %p, sz=%d bytes\n",
2689 ioc->name, ioc->alloc, ioc->alloc_sz));
2690 pci_free_consistent(ioc->pcidev, sz,
2691 ioc->alloc, ioc->alloc_dma);
2692 ioc->reply_frames = NULL;
2693 ioc->req_frames = NULL;
2695 ioc->alloc_total -= sz;
2698 if (ioc->sense_buf_pool != NULL) {
2699 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2700 pci_free_consistent(ioc->pcidev, sz,
2701 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2702 ioc->sense_buf_pool = NULL;
2703 ioc->alloc_total -= sz;
2706 if (ioc->events != NULL){
2707 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2710 ioc->alloc_total -= sz;
2713 mpt_free_fw_memory(ioc);
2715 kfree(ioc->spi_data.nvram);
2716 mpt_inactive_raid_list_free(ioc);
2717 kfree(ioc->raid_data.pIocPg2);
2718 kfree(ioc->raid_data.pIocPg3);
2719 ioc->spi_data.nvram = NULL;
2720 ioc->raid_data.pIocPg3 = NULL;
2722 if (ioc->spi_data.pIocPg4 != NULL) {
2723 sz = ioc->spi_data.IocPg4Sz;
2724 pci_free_consistent(ioc->pcidev, sz,
2725 ioc->spi_data.pIocPg4,
2726 ioc->spi_data.IocPg4_dma);
2727 ioc->spi_data.pIocPg4 = NULL;
2728 ioc->alloc_total -= sz;
2731 if (ioc->ReqToChain != NULL) {
2732 kfree(ioc->ReqToChain);
2733 kfree(ioc->RequestNB);
2734 ioc->ReqToChain = NULL;
2737 kfree(ioc->ChainToChain);
2738 ioc->ChainToChain = NULL;
2740 if (ioc->HostPageBuffer != NULL) {
2741 if((ret = mpt_host_page_access_control(ioc,
2742 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2743 printk(MYIOC_s_ERR_FMT
2744 "host page buffers free failed (%d)!\n",
2747 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "HostPageBuffer free @ %p, sz=%d bytes\n",
2748 ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
2749 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2750 ioc->HostPageBuffer, ioc->HostPageBuffer_dma);
2751 ioc->HostPageBuffer = NULL;
2752 ioc->HostPageBuffer_sz = 0;
2753 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2757 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2759 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2760 * @ioc: Pointer to MPT adapter structure
2762 * This routine unregisters h/w resources and frees all alloc'd memory
2763 * associated with a MPT adapter structure.
2766 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2768 int sz_first, sz_last;
2773 sz_first = ioc->alloc_total;
2775 mpt_adapter_disable(ioc);
2777 if (ioc->pci_irq != -1) {
2778 free_irq(ioc->pci_irq, ioc);
2779 if (ioc->msi_enable)
2780 pci_disable_msi(ioc->pcidev);
2784 if (ioc->memmap != NULL) {
2785 iounmap(ioc->memmap);
2789 pci_disable_device(ioc->pcidev);
2790 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2792 #if defined(CONFIG_MTRR) && 0
2793 if (ioc->mtrr_reg > 0) {
2794 mtrr_del(ioc->mtrr_reg, 0, 0);
2795 dprintk(ioc, printk(MYIOC_s_INFO_FMT "MTRR region de-registered\n", ioc->name));
2799 /* Zap the adapter lookup ptr! */
2800 list_del(&ioc->list);
2802 sz_last = ioc->alloc_total;
2803 dprintk(ioc, printk(MYIOC_s_INFO_FMT "free'd %d of %d bytes\n",
2804 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2807 ioc->alt_ioc->alt_ioc = NULL;
2812 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2814 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2815 * @ioc: Pointer to MPT adapter structure
2818 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2822 printk(KERN_INFO "%s: ", ioc->name);
2824 printk("%s: ", ioc->prod_name);
2825 printk("Capabilities={");
2827 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2828 printk("Initiator");
2832 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2833 printk("%sTarget", i ? "," : "");
2837 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2838 printk("%sLAN", i ? "," : "");
2844 * This would probably evoke more questions than it's worth
2846 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2847 printk("%sLogBusAddr", i ? "," : "");
2855 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2857 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2858 * @ioc: Pointer to MPT_ADAPTER structure
2859 * @force: Force hard KickStart of IOC
2860 * @sleepFlag: Specifies whether the process can sleep
2863 * 1 - DIAG reset and READY
2864 * 0 - READY initially OR soft reset and READY
2865 * -1 - Any failure on KickStart
2866 * -2 - Msg Unit Reset Failed
2867 * -3 - IO Unit Reset Failed
2868 * -4 - IOC owned by a PEER
2871 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2876 int hard_reset_done = 0;
2881 /* Get current [raw] IOC state */
2882 ioc_state = mpt_GetIocState(ioc, 0);
2883 dhsprintk(ioc, printk(MYIOC_s_INFO_FMT "MakeIocReady [raw] state=%08x\n", ioc->name, ioc_state));
2886 * Check to see if IOC got left/stuck in doorbell handshake
2887 * grip of death. If so, hard reset the IOC.
2889 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2891 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2895 /* Is it already READY? */
2896 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
2900 * Check to see if IOC is in FAULT state.
2902 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2904 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2906 printk(MYIOC_s_WARN_FMT " FAULT code = %04xh\n",
2907 ioc->name, ioc_state & MPI_DOORBELL_DATA_MASK);
2911 * Hmmm... Did it get left operational?
2913 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2914 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC operational unexpected\n",
2918 * If PCI Peer, exit.
2919 * Else, if no fault conditions are present, issue a MessageUnitReset
2920 * Else, fall through to KickStart case
2922 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2923 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2924 "whoinit 0x%x statefault %d force %d\n",
2925 ioc->name, whoinit, statefault, force));
2926 if (whoinit == MPI_WHOINIT_PCI_PEER)
2929 if ((statefault == 0 ) && (force == 0)) {
2930 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2937 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2938 if (hard_reset_done < 0)
2942 * Loop here waiting for IOC to come READY.
2945 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2947 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2948 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2950 * BIOS or previous driver load left IOC in OP state.
2951 * Reset messaging FIFOs.
2953 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2954 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2957 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2959 * Something is wrong. Try to get IOC back
2962 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2963 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2970 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2971 ioc->name, (int)((ii+5)/HZ));
2975 if (sleepFlag == CAN_SLEEP) {
2978 mdelay (1); /* 1 msec delay */
2983 if (statefault < 3) {
2984 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2986 statefault==1 ? "stuck handshake" : "IOC FAULT");
2989 return hard_reset_done;
2992 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2994 * mpt_GetIocState - Get the current state of a MPT adapter.
2995 * @ioc: Pointer to MPT_ADAPTER structure
2996 * @cooked: Request raw or cooked IOC state
2998 * Returns all IOC Doorbell register bits if cooked==0, else just the
2999 * Doorbell bits in MPI_IOC_STATE_MASK.
3002 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
3007 s = CHIPREG_READ32(&ioc->chip->Doorbell);
3008 sc = s & MPI_IOC_STATE_MASK;
3011 ioc->last_state = sc;
3013 return cooked ? sc : s;
3016 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3018 * GetIocFacts - Send IOCFacts request to MPT adapter.
3019 * @ioc: Pointer to MPT_ADAPTER structure
3020 * @sleepFlag: Specifies whether the process can sleep
3021 * @reason: If recovery, only update facts.
3023 * Returns 0 for success, non-zero for failure.
3026 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
3028 IOCFacts_t get_facts;
3029 IOCFactsReply_t *facts;
3037 /* IOC *must* NOT be in RESET state! */
3038 if (ioc->last_state == MPI_IOC_STATE_RESET) {
3039 printk(MYIOC_s_ERR_FMT "Can't get IOCFacts NOT READY! (%08x)\n",
3040 ioc->name, ioc->last_state );
3044 facts = &ioc->facts;
3046 /* Destination (reply area)... */
3047 reply_sz = sizeof(*facts);
3048 memset(facts, 0, reply_sz);
3050 /* Request area (get_facts on the stack right now!) */
3051 req_sz = sizeof(get_facts);
3052 memset(&get_facts, 0, req_sz);
3054 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
3055 /* Assert: All other get_facts fields are zero! */
3057 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3058 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
3059 ioc->name, req_sz, reply_sz));
3061 /* No non-zero fields in the get_facts request are greater than
3062 * 1 byte in size, so we can just fire it off as is.
3064 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
3065 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
3070 * Now byte swap (GRRR) the necessary fields before any further
3071 * inspection of reply contents.
3073 * But need to do some sanity checks on MsgLength (byte) field
3074 * to make sure we don't zero IOC's req_sz!
3076 /* Did we get a valid reply? */
3077 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
3078 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
3080 * If not been here, done that, save off first WhoInit value
3082 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
3083 ioc->FirstWhoInit = facts->WhoInit;
3086 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
3087 facts->MsgContext = le32_to_cpu(facts->MsgContext);
3088 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
3089 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
3090 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
3091 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
3092 /* CHECKME! IOCStatus, IOCLogInfo */
3094 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
3095 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
3098 * FC f/w version changed between 1.1 and 1.2
3099 * Old: u16{Major(4),Minor(4),SubMinor(8)}
3100 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
3102 if (facts->MsgVersion < 0x0102) {
3104 * Handle old FC f/w style, convert to new...
3106 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
3107 facts->FWVersion.Word =
3108 ((oldv<<12) & 0xFF000000) |
3109 ((oldv<<8) & 0x000FFF00);
3111 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
3113 facts->ProductID = le16_to_cpu(facts->ProductID);
3114 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
3115 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
3116 ioc->ir_firmware = 1;
3117 facts->CurrentHostMfaHighAddr =
3118 le32_to_cpu(facts->CurrentHostMfaHighAddr);
3119 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
3120 facts->CurrentSenseBufferHighAddr =
3121 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
3122 facts->CurReplyFrameSize =
3123 le16_to_cpu(facts->CurReplyFrameSize);
3124 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
3127 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
3128 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
3129 * to 14 in MPI-1.01.0x.
3131 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
3132 facts->MsgVersion > 0x0100) {
3133 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
3136 sz = facts->FWImageSize;
3141 facts->FWImageSize = sz;
3143 if (!facts->RequestFrameSize) {
3144 /* Something is wrong! */
3145 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
3150 r = sz = facts->BlockSize;
3151 vv = ((63 / (sz * 4)) + 1) & 0x03;
3152 ioc->NB_for_64_byte_frame = vv;
3158 ioc->NBShiftFactor = shiftFactor;
3159 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3160 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
3161 ioc->name, vv, shiftFactor, r));
3163 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
3165 * Set values for this IOC's request & reply frame sizes,
3166 * and request & reply queue depths...
3168 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
3169 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
3170 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
3171 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
3173 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "reply_sz=%3d, reply_depth=%4d\n",
3174 ioc->name, ioc->reply_sz, ioc->reply_depth));
3175 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "req_sz =%3d, req_depth =%4d\n",
3176 ioc->name, ioc->req_sz, ioc->req_depth));
3178 /* Get port facts! */
3179 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
3183 printk(MYIOC_s_ERR_FMT
3184 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
3185 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
3186 RequestFrameSize)/sizeof(u32)));
3193 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3195 * GetPortFacts - Send PortFacts request to MPT adapter.
3196 * @ioc: Pointer to MPT_ADAPTER structure
3197 * @portnum: Port number
3198 * @sleepFlag: Specifies whether the process can sleep
3200 * Returns 0 for success, non-zero for failure.
3203 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3205 PortFacts_t get_pfacts;
3206 PortFactsReply_t *pfacts;
3212 /* IOC *must* NOT be in RESET state! */
3213 if (ioc->last_state == MPI_IOC_STATE_RESET) {
3214 printk(MYIOC_s_ERR_FMT "Can't get PortFacts NOT READY! (%08x)\n",
3215 ioc->name, ioc->last_state );
3219 pfacts = &ioc->pfacts[portnum];
3221 /* Destination (reply area)... */
3222 reply_sz = sizeof(*pfacts);
3223 memset(pfacts, 0, reply_sz);
3225 /* Request area (get_pfacts on the stack right now!) */
3226 req_sz = sizeof(get_pfacts);
3227 memset(&get_pfacts, 0, req_sz);
3229 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
3230 get_pfacts.PortNumber = portnum;
3231 /* Assert: All other get_pfacts fields are zero! */
3233 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending get PortFacts(%d) request\n",
3234 ioc->name, portnum));
3236 /* No non-zero fields in the get_pfacts request are greater than
3237 * 1 byte in size, so we can just fire it off as is.
3239 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
3240 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
3244 /* Did we get a valid reply? */
3246 /* Now byte swap the necessary fields in the response. */
3247 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
3248 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
3249 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
3250 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
3251 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
3252 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
3253 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
3254 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
3255 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
3257 max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
3259 ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
3260 ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
3263 * Place all the devices on channels
3267 if (mpt_channel_mapping) {
3268 ioc->devices_per_bus = 1;
3269 ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
3275 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3277 * SendIocInit - Send IOCInit request to MPT adapter.
3278 * @ioc: Pointer to MPT_ADAPTER structure
3279 * @sleepFlag: Specifies whether the process can sleep
3281 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
3283 * Returns 0 for success, non-zero for failure.
3286 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
3289 MPIDefaultReply_t init_reply;
3295 memset(&ioc_init, 0, sizeof(ioc_init));
3296 memset(&init_reply, 0, sizeof(init_reply));
3298 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
3299 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
3301 /* If we are in a recovery mode and we uploaded the FW image,
3302 * then this pointer is not NULL. Skip the upload a second time.
3303 * Set this flag if cached_fw set for either IOC.
3305 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
3309 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "upload_fw %d facts.Flags=%x\n",
3310 ioc->name, ioc->upload_fw, ioc->facts.Flags));
3312 ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
3313 ioc_init.MaxBuses = (U8)ioc->number_of_buses;
3314 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n",
3315 ioc->name, ioc->facts.MsgVersion));
3316 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
3317 // set MsgVersion and HeaderVersion host driver was built with
3318 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
3319 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
3321 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
3322 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
3323 } else if(mpt_host_page_alloc(ioc, &ioc_init))
3326 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
3328 if (sizeof(dma_addr_t) == sizeof(u64)) {
3329 /* Save the upper 32-bits of the request
3330 * (reply) and sense buffers.
3332 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
3333 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
3335 /* Force 32-bit addressing */
3336 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
3337 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
3340 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
3341 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
3342 ioc->facts.MaxDevices = ioc_init.MaxDevices;
3343 ioc->facts.MaxBuses = ioc_init.MaxBuses;
3345 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOCInit (req @ %p)\n",
3346 ioc->name, &ioc_init));
3348 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
3349 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
3351 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
3355 /* No need to byte swap the multibyte fields in the reply
3356 * since we don't even look at its contents.
3359 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending PortEnable (req @ %p)\n",
3360 ioc->name, &ioc_init));
3362 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
3363 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
3367 /* YIKES! SUPER IMPORTANT!!!
3368 * Poll IocState until _OPERATIONAL while IOC is doing
3369 * LoopInit and TargetDiscovery!
3372 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
3373 state = mpt_GetIocState(ioc, 1);
3374 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
3375 if (sleepFlag == CAN_SLEEP) {
3382 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
3383 ioc->name, (int)((count+5)/HZ));
3387 state = mpt_GetIocState(ioc, 1);
3390 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wait IOC_OPERATIONAL state (cnt=%d)\n",
3393 ioc->aen_event_read_flag=0;
3397 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3399 * SendPortEnable - Send PortEnable request to MPT adapter port.
3400 * @ioc: Pointer to MPT_ADAPTER structure
3401 * @portnum: Port number to enable
3402 * @sleepFlag: Specifies whether the process can sleep
3404 * Send PortEnable to bring IOC to OPERATIONAL state.
3406 * Returns 0 for success, non-zero for failure.
3409 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3411 PortEnable_t port_enable;
3412 MPIDefaultReply_t reply_buf;
3417 /* Destination... */
3418 reply_sz = sizeof(MPIDefaultReply_t);
3419 memset(&reply_buf, 0, reply_sz);
3421 req_sz = sizeof(PortEnable_t);
3422 memset(&port_enable, 0, req_sz);
3424 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
3425 port_enable.PortNumber = portnum;
3426 /* port_enable.ChainOffset = 0; */
3427 /* port_enable.MsgFlags = 0; */
3428 /* port_enable.MsgContext = 0; */
3430 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Port(%d)Enable (req @ %p)\n",
3431 ioc->name, portnum, &port_enable));
3433 /* RAID FW may take a long time to enable
3435 if (ioc->ir_firmware || ioc->bus_type == SAS) {
3436 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3437 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3438 300 /*seconds*/, sleepFlag);
3440 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3441 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3442 30 /*seconds*/, sleepFlag);
3448 * mpt_alloc_fw_memory - allocate firmware memory
3449 * @ioc: Pointer to MPT_ADAPTER structure
3450 * @size: total FW bytes
3452 * If memory has already been allocated, the same (cached) value
3455 * Return 0 if successfull, or non-zero for failure
3458 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
3462 if (ioc->cached_fw) {
3463 rc = 0; /* use already allocated memory */
3466 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
3467 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
3468 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
3472 ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma);
3473 if (!ioc->cached_fw) {
3474 printk(MYIOC_s_ERR_FMT "Unable to allocate memory for the cached firmware image!\n",
3478 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Image @ %p[%p], sz=%d[%x] bytes\n",
3479 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, size, size));
3480 ioc->alloc_total += size;
3488 * mpt_free_fw_memory - free firmware memory
3489 * @ioc: Pointer to MPT_ADAPTER structure
3491 * If alt_img is NULL, delete from ioc structure.
3492 * Else, delete a secondary image in same format.
3495 mpt_free_fw_memory(MPT_ADAPTER *ioc)
3499 if (!ioc->cached_fw)
3502 sz = ioc->facts.FWImageSize;
3503 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3504 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3505 pci_free_consistent(ioc->pcidev, sz, ioc->cached_fw, ioc->cached_fw_dma);
3506 ioc->alloc_total -= sz;
3507 ioc->cached_fw = NULL;
3510 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3512 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3513 * @ioc: Pointer to MPT_ADAPTER structure
3514 * @sleepFlag: Specifies whether the process can sleep
3516 * Returns 0 for success, >0 for handshake failure
3517 * <0 for fw upload failure.
3519 * Remark: If bound IOC and a successful FWUpload was performed
3520 * on the bound IOC, the second image is discarded
3521 * and memory is free'd. Both channels must upload to prevent
3522 * IOC from running in degraded mode.
3525 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3527 u8 reply[sizeof(FWUploadReply_t)];
3528 FWUpload_t *prequest;
3529 FWUploadReply_t *preply;
3530 FWUploadTCSGE_t *ptcsge;
3532 int ii, sz, reply_sz;
3535 /* If the image size is 0, we are done.
3537 if ((sz = ioc->facts.FWImageSize) == 0)
3540 if (mpt_alloc_fw_memory(ioc, ioc->facts.FWImageSize) != 0)
3543 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3544 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3546 prequest = (sleepFlag == NO_SLEEP) ? kzalloc(ioc->req_sz, GFP_ATOMIC) :
3547 kzalloc(ioc->req_sz, GFP_KERNEL);
3549 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed "
3550 "while allocating memory \n", ioc->name));
3551 mpt_free_fw_memory(ioc);
3555 preply = (FWUploadReply_t *)&reply;
3557 reply_sz = sizeof(reply);
3558 memset(preply, 0, reply_sz);
3560 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
3561 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
3563 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
3564 ptcsge->DetailsLength = 12;
3565 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
3566 ptcsge->ImageSize = cpu_to_le32(sz);
3569 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3570 ioc->add_sge((char *)ptcsge, flagsLength, ioc->cached_fw_dma);
3571 request_size = offsetof(FWUpload_t, SGL) + sizeof(FWUploadTCSGE_t) +
3573 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending FW Upload "
3574 " (req @ %p) fw_size=%d mf_request_size=%d\n", ioc->name, prequest,
3575 ioc->facts.FWImageSize, request_size));
3576 DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest);
3578 ii = mpt_handshake_req_reply_wait(ioc, request_size, (u32 *)prequest,
3579 reply_sz, (u16 *)preply, 65 /*seconds*/, sleepFlag);
3581 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Upload completed rc=%x \n", ioc->name, ii));
3583 cmdStatus = -EFAULT;
3585 /* Handshake transfer was complete and successful.
3586 * Check the Reply Frame.
3588 int status, transfer_sz;
3589 status = le16_to_cpu(preply->IOCStatus);
3590 if (status == MPI_IOCSTATUS_SUCCESS) {
3591 transfer_sz = le32_to_cpu(preply->ActualImageSize);
3592 if (transfer_sz == sz)
3596 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n",
3597 ioc->name, cmdStatus));
3602 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": fw upload failed, freeing image \n",
3604 mpt_free_fw_memory(ioc);
3611 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3613 * mpt_downloadboot - DownloadBoot code
3614 * @ioc: Pointer to MPT_ADAPTER structure
3615 * @pFwHeader: Pointer to firmware header info
3616 * @sleepFlag: Specifies whether the process can sleep
3618 * FwDownloadBoot requires Programmed IO access.
3620 * Returns 0 for success
3621 * -1 FW Image size is 0
3622 * -2 No valid cached_fw Pointer
3623 * <0 for fw upload failure.
3626 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3628 MpiExtImageHeader_t *pExtImage;
3638 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3639 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
3641 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3642 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3643 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3644 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3645 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3646 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3648 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
3651 if (sleepFlag == CAN_SLEEP) {
3657 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3658 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3660 for (count = 0; count < 30; count ++) {
3661 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3662 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3663 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESET_ADAPTER cleared, count=%d\n",
3668 if (sleepFlag == CAN_SLEEP) {
3675 if ( count == 30 ) {
3676 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot failed! "
3677 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3678 ioc->name, diag0val));
3682 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3683 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3684 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3685 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3686 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3687 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3689 /* Set the DiagRwEn and Disable ARM bits */
3690 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3692 fwSize = (pFwHeader->ImageSize + 3)/4;
3693 ptrFw = (u32 *) pFwHeader;
3695 /* Write the LoadStartAddress to the DiagRw Address Register
3696 * using Programmed IO
3698 if (ioc->errata_flag_1064)
3699 pci_enable_io_access(ioc->pcidev);
3701 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3702 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "LoadStart addr written 0x%x \n",
3703 ioc->name, pFwHeader->LoadStartAddress));
3705 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write FW Image: 0x%x bytes @ %p\n",
3706 ioc->name, fwSize*4, ptrFw));
3708 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3711 nextImage = pFwHeader->NextImageHeaderOffset;
3713 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3715 load_addr = pExtImage->LoadStartAddress;
3717 fwSize = (pExtImage->ImageSize + 3) >> 2;
3718 ptrFw = (u32 *)pExtImage;
3720 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3721 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3722 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3725 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3727 nextImage = pExtImage->NextImageHeaderOffset;
3730 /* Write the IopResetVectorRegAddr */
3731 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
3732 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3734 /* Write the IopResetVectorValue */
3735 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3736 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3738 /* Clear the internal flash bad bit - autoincrementing register,
3739 * so must do two writes.
3741 if (ioc->bus_type == SPI) {
3743 * 1030 and 1035 H/W errata, workaround to access
3744 * the ClearFlashBadSignatureBit
3746 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3747 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3748 diagRwData |= 0x40000000;
3749 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3750 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3752 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3753 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3754 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3755 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3758 if (sleepFlag == CAN_SLEEP) {
3765 if (ioc->errata_flag_1064)
3766 pci_disable_io_access(ioc->pcidev);
3768 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3769 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot diag0val=%x, "
3770 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3771 ioc->name, diag0val));
3772 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3773 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot now diag0val=%x\n",
3774 ioc->name, diag0val));
3775 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3777 /* Write 0xFF to reset the sequencer */
3778 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3780 if (ioc->bus_type == SAS) {
3781 ioc_state = mpt_GetIocState(ioc, 0);
3782 if ( (GetIocFacts(ioc, sleepFlag,
3783 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3784 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "GetIocFacts failed: IocState=%x\n",
3785 ioc->name, ioc_state));
3790 for (count=0; count<HZ*20; count++) {
3791 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3792 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3793 "downloadboot successful! (count=%d) IocState=%x\n",
3794 ioc->name, count, ioc_state));
3795 if (ioc->bus_type == SAS) {
3798 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3799 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3800 "downloadboot: SendIocInit failed\n",
3804 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3805 "downloadboot: SendIocInit successful\n",
3809 if (sleepFlag == CAN_SLEEP) {
3815 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3816 "downloadboot failed! IocState=%x\n",ioc->name, ioc_state));
3820 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3822 * KickStart - Perform hard reset of MPT adapter.
3823 * @ioc: Pointer to MPT_ADAPTER structure
3824 * @force: Force hard reset
3825 * @sleepFlag: Specifies whether the process can sleep
3827 * This routine places MPT adapter in diagnostic mode via the
3828 * WriteSequence register, and then performs a hard reset of adapter
3829 * via the Diagnostic register.
3831 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3832 * or NO_SLEEP (interrupt thread, use mdelay)
3833 * force - 1 if doorbell active, board fault state
3834 * board operational, IOC_RECOVERY or
3835 * IOC_BRINGUP and there is an alt_ioc.
3839 * 1 - hard reset, READY
3840 * 0 - no reset due to History bit, READY
3841 * -1 - no reset due to History bit but not READY
3842 * OR reset but failed to come READY
3843 * -2 - no reset, could not enter DIAG mode
3844 * -3 - reset but bad FW bit
3847 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3849 int hard_reset_done = 0;
3853 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStarting!\n", ioc->name));
3854 if (ioc->bus_type == SPI) {
3855 /* Always issue a Msg Unit Reset first. This will clear some
3856 * SCSI bus hang conditions.
3858 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3860 if (sleepFlag == CAN_SLEEP) {
3867 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3868 if (hard_reset_done < 0)
3869 return hard_reset_done;
3871 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n",
3874 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3875 for (cnt=0; cnt<cntdn; cnt++) {
3876 ioc_state = mpt_GetIocState(ioc, 1);
3877 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3878 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStart successful! (cnt=%d)\n",
3880 return hard_reset_done;
3882 if (sleepFlag == CAN_SLEEP) {
3889 dinitprintk(ioc, printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3890 ioc->name, mpt_GetIocState(ioc, 0)));
3894 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3896 * mpt_diag_reset - Perform hard reset of the adapter.
3897 * @ioc: Pointer to MPT_ADAPTER structure
3898 * @ignore: Set if to honor and clear to ignore
3899 * the reset history bit
3900 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3901 * else set to NO_SLEEP (use mdelay instead)
3903 * This routine places the adapter in diagnostic mode via the
3904 * WriteSequence register and then performs a hard reset of adapter
3905 * via the Diagnostic register. Adapter should be in ready state
3906 * upon successful completion.
3908 * Returns: 1 hard reset successful
3909 * 0 no reset performed because reset history bit set
3910 * -2 enabling diagnostic mode failed
3911 * -3 diagnostic reset failed
3914 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3918 int hard_reset_done = 0;
3921 MpiFwHeader_t *cached_fw; /* Pointer to FW */
3923 /* Clear any existing interrupts */
3924 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3926 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3927 drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3928 "address=%p\n", ioc->name, __func__,
3929 &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3930 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3931 if (sleepFlag == CAN_SLEEP)
3936 for (count = 0; count < 60; count ++) {
3937 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3938 doorbell &= MPI_IOC_STATE_MASK;
3940 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3941 "looking for READY STATE: doorbell=%x"
3943 ioc->name, doorbell, count));
3944 if (doorbell == MPI_IOC_STATE_READY) {
3949 if (sleepFlag == CAN_SLEEP)
3957 /* Use "Diagnostic reset" method! (only thing available!) */
3958 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3960 if (ioc->debug_level & MPT_DEBUG) {
3962 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3963 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3964 ioc->name, diag0val, diag1val));
3967 /* Do the reset if we are told to ignore the reset history
3968 * or if the reset history is 0
3970 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3971 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3972 /* Write magic sequence to WriteSequence register
3973 * Loop until in diagnostic mode
3975 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3976 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3977 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3978 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3979 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3980 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3983 if (sleepFlag == CAN_SLEEP) {
3991 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3992 ioc->name, diag0val);
3997 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3999 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
4000 ioc->name, diag0val));
4003 if (ioc->debug_level & MPT_DEBUG) {
4005 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4006 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG2: diag0=%08x, diag1=%08x\n",
4007 ioc->name, diag0val, diag1val));
4010 * Disable the ARM (Bug fix)
4013 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
4017 * Now hit the reset bit in the Diagnostic register
4018 * (THE BIG HAMMER!) (Clears DRWE bit).
4020 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
4021 hard_reset_done = 1;
4022 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset performed\n",
4026 * Call each currently registered protocol IOC reset handler
4027 * with pre-reset indication.
4028 * NOTE: If we're doing _IOC_BRINGUP, there can be no
4029 * MptResetHandlers[] registered yet.
4035 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
4036 if (MptResetHandlers[cb_idx]) {
4037 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4038 "Calling IOC pre_reset handler #%d\n",
4039 ioc->name, cb_idx));
4040 r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET);
4042 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4043 "Calling alt-%s pre_reset handler #%d\n",
4044 ioc->name, ioc->alt_ioc->name, cb_idx));
4045 r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_PRE_RESET);
4049 /* FIXME? Examine results here? */
4053 cached_fw = (MpiFwHeader_t *)ioc->cached_fw;
4054 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
4055 cached_fw = (MpiFwHeader_t *)ioc->alt_ioc->cached_fw;
4059 /* If the DownloadBoot operation fails, the
4060 * IOC will be left unusable. This is a fatal error
4061 * case. _diag_reset will return < 0
4063 for (count = 0; count < 30; count ++) {
4064 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4065 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
4069 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n",
4070 ioc->name, diag0val, count));
4072 if (sleepFlag == CAN_SLEEP) {
4078 if ((count = mpt_downloadboot(ioc, cached_fw, sleepFlag)) < 0) {
4079 printk(MYIOC_s_WARN_FMT
4080 "firmware downloadboot failure (%d)!\n", ioc->name, count);
4084 /* Wait for FW to reload and for board
4085 * to go to the READY state.
4086 * Maximum wait is 60 seconds.
4087 * If fail, no error will check again
4088 * with calling program.
4090 for (count = 0; count < 60; count ++) {
4091 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
4092 doorbell &= MPI_IOC_STATE_MASK;
4094 if (doorbell == MPI_IOC_STATE_READY) {
4099 if (sleepFlag == CAN_SLEEP) {
4108 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4109 if (ioc->debug_level & MPT_DEBUG) {
4111 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4112 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG3: diag0=%08x, diag1=%08x\n",
4113 ioc->name, diag0val, diag1val));
4116 /* Clear RESET_HISTORY bit! Place board in the
4117 * diagnostic mode to update the diag register.
4119 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4121 while ((diag0val & MPI_DIAG_DRWE) == 0) {
4122 /* Write magic sequence to WriteSequence register
4123 * Loop until in diagnostic mode
4125 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
4126 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
4127 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
4128 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
4129 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
4130 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
4133 if (sleepFlag == CAN_SLEEP) {
4141 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
4142 ioc->name, diag0val);
4145 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4147 diag0val &= ~MPI_DIAG_RESET_HISTORY;
4148 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
4149 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4150 if (diag0val & MPI_DIAG_RESET_HISTORY) {
4151 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
4155 /* Disable Diagnostic Mode
4157 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
4159 /* Check FW reload status flags.
4161 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4162 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
4163 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
4164 ioc->name, diag0val);
4168 if (ioc->debug_level & MPT_DEBUG) {
4170 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4171 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG4: diag0=%08x, diag1=%08x\n",
4172 ioc->name, diag0val, diag1val));
4176 * Reset flag that says we've enabled event notification
4178 ioc->facts.EventState = 0;
4181 ioc->alt_ioc->facts.EventState = 0;
4183 return hard_reset_done;
4186 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4188 * SendIocReset - Send IOCReset request to MPT adapter.
4189 * @ioc: Pointer to MPT_ADAPTER structure
4190 * @reset_type: reset type, expected values are
4191 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
4192 * @sleepFlag: Specifies whether the process can sleep
4194 * Send IOCReset request to the MPT adapter.
4196 * Returns 0 for success, non-zero for failure.
4199 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
4205 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOC reset(0x%02x)!\n",
4206 ioc->name, reset_type));
4207 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
4208 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4211 /* FW ACK'd request, wait for READY state
4214 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
4216 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
4220 if (sleepFlag != CAN_SLEEP)
4223 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
4224 ioc->name, (int)((count+5)/HZ));
4228 if (sleepFlag == CAN_SLEEP) {
4231 mdelay (1); /* 1 msec delay */
4236 * Cleanup all event stuff for this IOC; re-issue EventNotification
4237 * request if needed.
4239 if (ioc->facts.Function)
4240 ioc->facts.EventState = 0;
4245 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4247 * initChainBuffers - Allocate memory for and initialize chain buffers
4248 * @ioc: Pointer to MPT_ADAPTER structure
4250 * Allocates memory for and initializes chain buffers,
4251 * chain buffer control arrays and spinlock.
4254 initChainBuffers(MPT_ADAPTER *ioc)
4257 int sz, ii, num_chain;
4258 int scale, num_sge, numSGE;
4260 /* ReqToChain size must equal the req_depth
4263 if (ioc->ReqToChain == NULL) {
4264 sz = ioc->req_depth * sizeof(int);
4265 mem = kmalloc(sz, GFP_ATOMIC);
4269 ioc->ReqToChain = (int *) mem;
4270 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReqToChain alloc @ %p, sz=%d bytes\n",
4271 ioc->name, mem, sz));
4272 mem = kmalloc(sz, GFP_ATOMIC);
4276 ioc->RequestNB = (int *) mem;
4277 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestNB alloc @ %p, sz=%d bytes\n",
4278 ioc->name, mem, sz));
4280 for (ii = 0; ii < ioc->req_depth; ii++) {
4281 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
4284 /* ChainToChain size must equal the total number
4285 * of chain buffers to be allocated.
4288 * Calculate the number of chain buffers needed(plus 1) per I/O
4289 * then multiply the maximum number of simultaneous cmds
4291 * num_sge = num sge in request frame + last chain buffer
4292 * scale = num sge per chain buffer if no chain element
4294 scale = ioc->req_sz / ioc->SGE_size;
4295 if (ioc->sg_addr_size == sizeof(u64))
4296 num_sge = scale + (ioc->req_sz - 60) / ioc->SGE_size;
4298 num_sge = 1 + scale + (ioc->req_sz - 64) / ioc->SGE_size;
4300 if (ioc->sg_addr_size == sizeof(u64)) {
4301 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
4302 (ioc->req_sz - 60) / ioc->SGE_size;
4304 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) +
4305 scale + (ioc->req_sz - 64) / ioc->SGE_size;
4307 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n",
4308 ioc->name, num_sge, numSGE));
4310 if ( numSGE > MPT_SCSI_SG_DEPTH )
4311 numSGE = MPT_SCSI_SG_DEPTH;
4314 while (numSGE - num_sge > 0) {
4316 num_sge += (scale - 1);
4320 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Now numSGE=%d num_sge=%d num_chain=%d\n",
4321 ioc->name, numSGE, num_sge, num_chain));
4323 if (ioc->bus_type == SPI)
4324 num_chain *= MPT_SCSI_CAN_QUEUE;
4326 num_chain *= MPT_FC_CAN_QUEUE;
4328 ioc->num_chain = num_chain;
4330 sz = num_chain * sizeof(int);
4331 if (ioc->ChainToChain == NULL) {
4332 mem = kmalloc(sz, GFP_ATOMIC);
4336 ioc->ChainToChain = (int *) mem;
4337 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainToChain alloc @ %p, sz=%d bytes\n",
4338 ioc->name, mem, sz));
4340 mem = (u8 *) ioc->ChainToChain;
4342 memset(mem, 0xFF, sz);
4346 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4348 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
4349 * @ioc: Pointer to MPT_ADAPTER structure
4351 * This routine allocates memory for the MPT reply and request frame
4352 * pools (if necessary), and primes the IOC reply FIFO with
4355 * Returns 0 for success, non-zero for failure.
4358 PrimeIocFifos(MPT_ADAPTER *ioc)
4361 unsigned long flags;
4362 dma_addr_t alloc_dma;
4364 int i, reply_sz, sz, total_size, num_chain;
4369 /* Prime reply FIFO... */
4371 if (ioc->reply_frames == NULL) {
4372 if ( (num_chain = initChainBuffers(ioc)) < 0)
4375 * 1078 errata workaround for the 36GB limitation
4377 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078 &&
4378 ioc->dma_mask > DMA_35BIT_MASK) {
4379 if (!pci_set_dma_mask(ioc->pcidev, DMA_BIT_MASK(32))
4380 && !pci_set_consistent_dma_mask(ioc->pcidev,
4381 DMA_BIT_MASK(32))) {
4382 dma_mask = DMA_35BIT_MASK;
4383 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4384 "setting 35 bit addressing for "
4385 "Request/Reply/Chain and Sense Buffers\n",
4388 /*Reseting DMA mask to 64 bit*/
4389 pci_set_dma_mask(ioc->pcidev,
4391 pci_set_consistent_dma_mask(ioc->pcidev,
4394 printk(MYIOC_s_ERR_FMT
4395 "failed setting 35 bit addressing for "
4396 "Request/Reply/Chain and Sense Buffers\n",
4402 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
4403 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
4404 ioc->name, ioc->reply_sz, ioc->reply_depth));
4405 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d[%x] bytes\n",
4406 ioc->name, reply_sz, reply_sz));
4408 sz = (ioc->req_sz * ioc->req_depth);
4409 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d bytes, RequestDepth=%d\n",
4410 ioc->name, ioc->req_sz, ioc->req_depth));
4411 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d[%x] bytes\n",
4412 ioc->name, sz, sz));
4415 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
4416 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d bytes, ChainDepth=%d\n",
4417 ioc->name, ioc->req_sz, num_chain));
4418 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
4419 ioc->name, sz, sz, num_chain));
4422 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
4424 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
4429 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Total alloc @ %p[%p], sz=%d[%x] bytes\n",
4430 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
4432 memset(mem, 0, total_size);
4433 ioc->alloc_total += total_size;
4435 ioc->alloc_dma = alloc_dma;
4436 ioc->alloc_sz = total_size;
4437 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
4438 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4440 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4441 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4443 alloc_dma += reply_sz;
4446 /* Request FIFO - WE manage this! */
4448 ioc->req_frames = (MPT_FRAME_HDR *) mem;
4449 ioc->req_frames_dma = alloc_dma;
4451 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffers @ %p[%p]\n",
4452 ioc->name, mem, (void *)(ulong)alloc_dma));
4454 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4456 #if defined(CONFIG_MTRR) && 0
4458 * Enable Write Combining MTRR for IOC's memory region.
4459 * (at least as much as we can; "size and base must be
4460 * multiples of 4 kiB"
4462 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
4464 MTRR_TYPE_WRCOMB, 1);
4465 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MTRR region registered (base:size=%08x:%x)\n",
4466 ioc->name, ioc->req_frames_dma, sz));
4469 for (i = 0; i < ioc->req_depth; i++) {
4470 alloc_dma += ioc->req_sz;
4474 ioc->ChainBuffer = mem;
4475 ioc->ChainBufferDMA = alloc_dma;
4477 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffers @ %p(%p)\n",
4478 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
4480 /* Initialize the free chain Q.
4483 INIT_LIST_HEAD(&ioc->FreeChainQ);
4485 /* Post the chain buffers to the FreeChainQ.
4487 mem = (u8 *)ioc->ChainBuffer;
4488 for (i=0; i < num_chain; i++) {
4489 mf = (MPT_FRAME_HDR *) mem;
4490 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
4494 /* Initialize Request frames linked list
4496 alloc_dma = ioc->req_frames_dma;
4497 mem = (u8 *) ioc->req_frames;
4499 spin_lock_irqsave(&ioc->FreeQlock, flags);
4500 INIT_LIST_HEAD(&ioc->FreeQ);
4501 for (i = 0; i < ioc->req_depth; i++) {
4502 mf = (MPT_FRAME_HDR *) mem;
4504 /* Queue REQUESTs *internally*! */
4505 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
4509 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4511 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4512 ioc->sense_buf_pool =
4513 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
4514 if (ioc->sense_buf_pool == NULL) {
4515 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
4520 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
4521 ioc->alloc_total += sz;
4522 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SenseBuffers @ %p[%p]\n",
4523 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
4527 /* Post Reply frames to FIFO
4529 alloc_dma = ioc->alloc_dma;
4530 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4531 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4533 for (i = 0; i < ioc->reply_depth; i++) {
4534 /* Write each address to the IOC! */
4535 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
4536 alloc_dma += ioc->reply_sz;
4539 if (dma_mask == DMA_35BIT_MASK && !pci_set_dma_mask(ioc->pcidev,
4540 ioc->dma_mask) && !pci_set_consistent_dma_mask(ioc->pcidev,
4542 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4543 "restoring 64 bit addressing\n", ioc->name));
4548 if (ioc->alloc != NULL) {
4550 pci_free_consistent(ioc->pcidev,
4552 ioc->alloc, ioc->alloc_dma);
4553 ioc->reply_frames = NULL;
4554 ioc->req_frames = NULL;
4555 ioc->alloc_total -= sz;
4557 if (ioc->sense_buf_pool != NULL) {
4558 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4559 pci_free_consistent(ioc->pcidev,
4561 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
4562 ioc->sense_buf_pool = NULL;
4565 if (dma_mask == DMA_35BIT_MASK && !pci_set_dma_mask(ioc->pcidev,
4566 DMA_BIT_MASK(64)) && !pci_set_consistent_dma_mask(ioc->pcidev,
4568 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4569 "restoring 64 bit addressing\n", ioc->name));
4574 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4576 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4577 * from IOC via doorbell handshake method.
4578 * @ioc: Pointer to MPT_ADAPTER structure
4579 * @reqBytes: Size of the request in bytes
4580 * @req: Pointer to MPT request frame
4581 * @replyBytes: Expected size of the reply in bytes
4582 * @u16reply: Pointer to area where reply should be written
4583 * @maxwait: Max wait time for a reply (in seconds)
4584 * @sleepFlag: Specifies whether the process can sleep
4586 * NOTES: It is the callers responsibility to byte-swap fields in the
4587 * request which are greater than 1 byte in size. It is also the
4588 * callers responsibility to byte-swap response fields which are
4589 * greater than 1 byte in size.
4591 * Returns 0 for success, non-zero for failure.
4594 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
4595 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
4597 MPIDefaultReply_t *mptReply;
4602 * Get ready to cache a handshake reply
4604 ioc->hs_reply_idx = 0;
4605 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4606 mptReply->MsgLength = 0;
4609 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4610 * then tell IOC that we want to handshake a request of N words.
4611 * (WRITE u32val to Doorbell reg).
4613 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4614 CHIPREG_WRITE32(&ioc->chip->Doorbell,
4615 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
4616 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
4619 * Wait for IOC's doorbell handshake int
4621 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4624 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4625 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4627 /* Read doorbell and check for active bit */
4628 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
4632 * Clear doorbell int (WRITE 0 to IntStatus reg),
4633 * then wait for IOC to ACKnowledge that it's ready for
4634 * our handshake request.
4636 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4637 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4642 u8 *req_as_bytes = (u8 *) req;
4645 * Stuff request words via doorbell handshake,
4646 * with ACK from IOC for each.
4648 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
4649 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
4650 (req_as_bytes[(ii*4) + 1] << 8) |
4651 (req_as_bytes[(ii*4) + 2] << 16) |
4652 (req_as_bytes[(ii*4) + 3] << 24));
4654 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
4655 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4659 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req));
4660 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req);
4662 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n",
4663 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
4666 * Wait for completion of doorbell handshake reply from the IOC
4668 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
4671 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake reply count=%d%s\n",
4672 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
4675 * Copy out the cached reply...
4677 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
4678 u16reply[ii] = ioc->hs_reply[ii];
4686 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4688 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4689 * @ioc: Pointer to MPT_ADAPTER structure
4690 * @howlong: How long to wait (in seconds)
4691 * @sleepFlag: Specifies whether the process can sleep
4693 * This routine waits (up to ~2 seconds max) for IOC doorbell
4694 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4695 * bit in its IntStatus register being clear.
4697 * Returns a negative value on failure, else wait loop count.
4700 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4706 cntdn = 1000 * howlong;
4708 if (sleepFlag == CAN_SLEEP) {
4711 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4712 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4719 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4720 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4727 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell ACK (count=%d)\n",
4732 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4733 ioc->name, count, intstat);
4737 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4739 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4740 * @ioc: Pointer to MPT_ADAPTER structure
4741 * @howlong: How long to wait (in seconds)
4742 * @sleepFlag: Specifies whether the process can sleep
4744 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4745 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4747 * Returns a negative value on failure, else wait loop count.
4750 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4756 cntdn = 1000 * howlong;
4757 if (sleepFlag == CAN_SLEEP) {
4759 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4760 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4767 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4768 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4776 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4777 ioc->name, count, howlong));
4781 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4782 ioc->name, count, intstat);
4786 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4788 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4789 * @ioc: Pointer to MPT_ADAPTER structure
4790 * @howlong: How long to wait (in seconds)
4791 * @sleepFlag: Specifies whether the process can sleep
4793 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4794 * Reply is cached to IOC private area large enough to hold a maximum
4795 * of 128 bytes of reply data.
4797 * Returns a negative value on failure, else size of reply in WORDS.
4800 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4805 u16 *hs_reply = ioc->hs_reply;
4806 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4809 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4812 * Get first two u16's so we can look at IOC's intended reply MsgLength
4815 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4818 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4819 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4820 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4823 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4824 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4828 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4829 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4830 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4833 * If no error (and IOC said MsgLength is > 0), piece together
4834 * reply 16 bits at a time.
4836 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4837 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4839 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4840 /* don't overflow our IOC hs_reply[] buffer! */
4841 if (u16cnt < ARRAY_SIZE(ioc->hs_reply))
4842 hs_reply[u16cnt] = hword;
4843 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4846 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4848 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4851 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4856 else if (u16cnt != (2 * mptReply->MsgLength)) {
4859 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4864 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name));
4865 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply);
4867 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4868 ioc->name, t, u16cnt/2));
4872 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4874 * GetLanConfigPages - Fetch LANConfig pages.
4875 * @ioc: Pointer to MPT_ADAPTER structure
4877 * Return: 0 for success
4878 * -ENOMEM if no memory available
4879 * -EPERM if not allowed due to ISR context
4880 * -EAGAIN if no msg frames currently available
4881 * -EFAULT for non-successful reply or no reply (timeout)
4884 GetLanConfigPages(MPT_ADAPTER *ioc)
4886 ConfigPageHeader_t hdr;
4888 LANPage0_t *ppage0_alloc;
4889 dma_addr_t page0_dma;
4890 LANPage1_t *ppage1_alloc;
4891 dma_addr_t page1_dma;
4896 /* Get LAN Page 0 header */
4897 hdr.PageVersion = 0;
4900 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4901 cfg.cfghdr.hdr = &hdr;
4903 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4908 if ((rc = mpt_config(ioc, &cfg)) != 0)
4911 if (hdr.PageLength > 0) {
4912 data_sz = hdr.PageLength * 4;
4913 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4916 memset((u8 *)ppage0_alloc, 0, data_sz);
4917 cfg.physAddr = page0_dma;
4918 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4920 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4922 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4923 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4927 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4930 * Normalize endianness of structure data,
4931 * by byte-swapping all > 1 byte fields!
4940 /* Get LAN Page 1 header */
4941 hdr.PageVersion = 0;
4944 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4945 cfg.cfghdr.hdr = &hdr;
4947 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4951 if ((rc = mpt_config(ioc, &cfg)) != 0)
4954 if (hdr.PageLength == 0)
4957 data_sz = hdr.PageLength * 4;
4959 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4961 memset((u8 *)ppage1_alloc, 0, data_sz);
4962 cfg.physAddr = page1_dma;
4963 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4965 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4967 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4968 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4971 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4974 * Normalize endianness of structure data,
4975 * by byte-swapping all > 1 byte fields!
4983 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4985 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
4986 * @ioc: Pointer to MPT_ADAPTER structure
4987 * @persist_opcode: see below
4989 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4990 * devices not currently present.
4991 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4993 * NOTE: Don't use not this function during interrupt time.
4995 * Returns 0 for success, non-zero error
4998 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5000 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
5002 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
5003 SasIoUnitControlReply_t *sasIoUnitCntrReply;
5004 MPT_FRAME_HDR *mf = NULL;
5005 MPIHeader_t *mpi_hdr;
5008 /* insure garbage is not sent to fw */
5009 switch(persist_opcode) {
5011 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
5012 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
5020 printk("%s: persist_opcode=%x\n",__func__, persist_opcode);
5022 /* Get a MF for this command.
5024 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5025 printk("%s: no msg frames!\n",__func__);
5029 mpi_hdr = (MPIHeader_t *) mf;
5030 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
5031 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
5032 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
5033 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
5034 sasIoUnitCntrReq->Operation = persist_opcode;
5036 init_timer(&ioc->persist_timer);
5037 ioc->persist_timer.data = (unsigned long) ioc;
5038 ioc->persist_timer.function = mpt_timer_expired;
5039 ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
5040 ioc->persist_wait_done=0;
5041 add_timer(&ioc->persist_timer);
5042 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5043 wait_event(mpt_waitq, ioc->persist_wait_done);
5045 sasIoUnitCntrReply =
5046 (SasIoUnitControlReply_t *)ioc->persist_reply_frame;
5047 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
5048 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
5050 sasIoUnitCntrReply->IOCStatus,
5051 sasIoUnitCntrReply->IOCLogInfo);
5055 printk("%s: success\n",__func__);
5059 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5062 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
5063 MpiEventDataRaid_t * pRaidEventData)
5072 volume = pRaidEventData->VolumeID;
5073 reason = pRaidEventData->ReasonCode;
5074 disk = pRaidEventData->PhysDiskNum;
5075 status = le32_to_cpu(pRaidEventData->SettingsStatus);
5076 flags = (status >> 0) & 0xff;
5077 state = (status >> 8) & 0xff;
5079 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
5083 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
5084 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
5085 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
5086 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
5087 ioc->name, disk, volume);
5089 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
5094 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
5095 printk(MYIOC_s_INFO_FMT " volume has been created\n",
5099 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
5101 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
5105 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
5106 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
5110 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
5111 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
5113 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
5115 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
5117 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
5120 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
5122 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
5123 ? ", quiesced" : "",
5124 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
5125 ? ", resync in progress" : "" );
5128 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
5129 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
5133 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
5134 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
5138 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
5139 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
5143 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
5144 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
5148 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
5149 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
5151 state == MPI_PHYSDISK0_STATUS_ONLINE
5153 : state == MPI_PHYSDISK0_STATUS_MISSING
5155 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
5157 : state == MPI_PHYSDISK0_STATUS_FAILED
5159 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
5161 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
5162 ? "offline requested"
5163 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
5164 ? "failed requested"
5165 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
5168 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
5169 ? ", out of sync" : "",
5170 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
5171 ? ", quiesced" : "" );
5174 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
5175 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
5179 case MPI_EVENT_RAID_RC_SMART_DATA:
5180 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
5181 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
5184 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
5185 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
5191 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5193 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
5194 * @ioc: Pointer to MPT_ADAPTER structure
5196 * Returns: 0 for success
5197 * -ENOMEM if no memory available
5198 * -EPERM if not allowed due to ISR context
5199 * -EAGAIN if no msg frames currently available
5200 * -EFAULT for non-successful reply or no reply (timeout)
5203 GetIoUnitPage2(MPT_ADAPTER *ioc)
5205 ConfigPageHeader_t hdr;
5207 IOUnitPage2_t *ppage_alloc;
5208 dma_addr_t page_dma;
5212 /* Get the page header */
5213 hdr.PageVersion = 0;
5216 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
5217 cfg.cfghdr.hdr = &hdr;
5219 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5224 if ((rc = mpt_config(ioc, &cfg)) != 0)
5227 if (hdr.PageLength == 0)
5230 /* Read the config page */
5231 data_sz = hdr.PageLength * 4;
5233 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
5235 memset((u8 *)ppage_alloc, 0, data_sz);
5236 cfg.physAddr = page_dma;
5237 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5239 /* If Good, save data */
5240 if ((rc = mpt_config(ioc, &cfg)) == 0)
5241 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
5243 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
5249 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5251 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
5252 * @ioc: Pointer to a Adapter Strucutre
5253 * @portnum: IOC port number
5255 * Return: -EFAULT if read of config page header fails
5257 * If read of SCSI Port Page 0 fails,
5258 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5259 * Adapter settings: async, narrow
5261 * If read of SCSI Port Page 2 fails,
5262 * Adapter settings valid
5263 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5268 * CHECK - what type of locking mechanisms should be used????
5271 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
5276 ConfigPageHeader_t header;
5282 if (!ioc->spi_data.nvram) {
5285 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
5286 mem = kmalloc(sz, GFP_ATOMIC);
5290 ioc->spi_data.nvram = (int *) mem;
5292 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
5293 ioc->name, ioc->spi_data.nvram, sz));
5296 /* Invalidate NVRAM information
5298 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5299 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
5302 /* Read SPP0 header, allocate memory, then read page.
5304 header.PageVersion = 0;
5305 header.PageLength = 0;
5306 header.PageNumber = 0;
5307 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5308 cfg.cfghdr.hdr = &header;
5310 cfg.pageAddr = portnum;
5311 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5313 cfg.timeout = 0; /* use default */
5314 if (mpt_config(ioc, &cfg) != 0)
5317 if (header.PageLength > 0) {
5318 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5320 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5321 cfg.physAddr = buf_dma;
5322 if (mpt_config(ioc, &cfg) != 0) {
5323 ioc->spi_data.maxBusWidth = MPT_NARROW;
5324 ioc->spi_data.maxSyncOffset = 0;
5325 ioc->spi_data.minSyncFactor = MPT_ASYNC;
5326 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
5328 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5329 "Unable to read PortPage0 minSyncFactor=%x\n",
5330 ioc->name, ioc->spi_data.minSyncFactor));
5332 /* Save the Port Page 0 data
5334 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
5335 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
5336 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
5338 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
5339 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
5340 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5341 "noQas due to Capabilities=%x\n",
5342 ioc->name, pPP0->Capabilities));
5344 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
5345 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
5347 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
5348 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
5349 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
5350 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5351 "PortPage0 minSyncFactor=%x\n",
5352 ioc->name, ioc->spi_data.minSyncFactor));
5354 ioc->spi_data.maxSyncOffset = 0;
5355 ioc->spi_data.minSyncFactor = MPT_ASYNC;
5358 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
5360 /* Update the minSyncFactor based on bus type.
5362 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
5363 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
5365 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
5366 ioc->spi_data.minSyncFactor = MPT_ULTRA;
5367 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5368 "HVD or SE detected, minSyncFactor=%x\n",
5369 ioc->name, ioc->spi_data.minSyncFactor));
5374 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5379 /* SCSI Port Page 2 - Read the header then the page.
5381 header.PageVersion = 0;
5382 header.PageLength = 0;
5383 header.PageNumber = 2;
5384 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5385 cfg.cfghdr.hdr = &header;
5387 cfg.pageAddr = portnum;
5388 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5390 if (mpt_config(ioc, &cfg) != 0)
5393 if (header.PageLength > 0) {
5394 /* Allocate memory and read SCSI Port Page 2
5396 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5398 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
5399 cfg.physAddr = buf_dma;
5400 if (mpt_config(ioc, &cfg) != 0) {
5401 /* Nvram data is left with INVALID mark
5404 } else if (ioc->pcidev->vendor == PCI_VENDOR_ID_ATTO) {
5406 /* This is an ATTO adapter, read Page2 accordingly
5408 ATTO_SCSIPortPage2_t *pPP2 = (ATTO_SCSIPortPage2_t *) pbuf;
5409 ATTODeviceInfo_t *pdevice = NULL;
5412 /* Save the Port Page 2 data
5413 * (reformat into a 32bit quantity)
5415 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5416 pdevice = &pPP2->DeviceSettings[ii];
5417 ATTOFlags = le16_to_cpu(pdevice->ATTOFlags);
5420 /* Translate ATTO device flags to LSI format
5422 if (ATTOFlags & ATTOFLAG_DISC)
5423 data |= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE);
5424 if (ATTOFlags & ATTOFLAG_ID_ENB)
5425 data |= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE);
5426 if (ATTOFlags & ATTOFLAG_LUN_ENB)
5427 data |= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE);
5428 if (ATTOFlags & ATTOFLAG_TAGGED)
5429 data |= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE);
5430 if (!(ATTOFlags & ATTOFLAG_WIDE_ENB))
5431 data |= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE);
5433 data = (data << 16) | (pdevice->Period << 8) | 10;
5434 ioc->spi_data.nvram[ii] = data;
5437 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
5438 MpiDeviceInfo_t *pdevice = NULL;
5441 * Save "Set to Avoid SCSI Bus Resets" flag
5443 ioc->spi_data.bus_reset =
5444 (le32_to_cpu(pPP2->PortFlags) &
5445 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
5448 /* Save the Port Page 2 data
5449 * (reformat into a 32bit quantity)
5451 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
5452 ioc->spi_data.PortFlags = data;
5453 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5454 pdevice = &pPP2->DeviceSettings[ii];
5455 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
5456 (pdevice->SyncFactor << 8) | pdevice->Timeout;
5457 ioc->spi_data.nvram[ii] = data;
5461 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5465 /* Update Adapter limits with those from NVRAM
5466 * Comment: Don't need to do this. Target performance
5467 * parameters will never exceed the adapters limits.
5473 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5475 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
5476 * @ioc: Pointer to a Adapter Strucutre
5477 * @portnum: IOC port number
5479 * Return: -EFAULT if read of config page header fails
5483 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
5486 ConfigPageHeader_t header;
5488 /* Read the SCSI Device Page 1 header
5490 header.PageVersion = 0;
5491 header.PageLength = 0;
5492 header.PageNumber = 1;
5493 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5494 cfg.cfghdr.hdr = &header;
5496 cfg.pageAddr = portnum;
5497 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5500 if (mpt_config(ioc, &cfg) != 0)
5503 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
5504 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
5506 header.PageVersion = 0;
5507 header.PageLength = 0;
5508 header.PageNumber = 0;
5509 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5510 if (mpt_config(ioc, &cfg) != 0)
5513 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
5514 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
5516 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 0: version %d length %d\n",
5517 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
5519 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 1: version %d length %d\n",
5520 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
5525 * mpt_inactive_raid_list_free - This clears this link list.
5526 * @ioc : pointer to per adapter structure
5529 mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
5531 struct inactive_raid_component_info *component_info, *pNext;
5533 if (list_empty(&ioc->raid_data.inactive_list))
5536 mutex_lock(&ioc->raid_data.inactive_list_mutex);
5537 list_for_each_entry_safe(component_info, pNext,
5538 &ioc->raid_data.inactive_list, list) {
5539 list_del(&component_info->list);
5540 kfree(component_info);
5542 mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5546 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5548 * @ioc : pointer to per adapter structure
5549 * @channel : volume channel
5550 * @id : volume target id
5553 mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
5556 ConfigPageHeader_t hdr;
5557 dma_addr_t dma_handle;
5558 pRaidVolumePage0_t buffer = NULL;
5560 RaidPhysDiskPage0_t phys_disk;
5561 struct inactive_raid_component_info *component_info;
5562 int handle_inactive_volumes;
5564 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5565 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5566 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
5567 cfg.pageAddr = (channel << 8) + id;
5568 cfg.cfghdr.hdr = &hdr;
5569 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5571 if (mpt_config(ioc, &cfg) != 0)
5574 if (!hdr.PageLength)
5577 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5583 cfg.physAddr = dma_handle;
5584 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5586 if (mpt_config(ioc, &cfg) != 0)
5589 if (!buffer->NumPhysDisks)
5592 handle_inactive_volumes =
5593 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
5594 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
5595 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
5596 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
5598 if (!handle_inactive_volumes)
5601 mutex_lock(&ioc->raid_data.inactive_list_mutex);
5602 for (i = 0; i < buffer->NumPhysDisks; i++) {
5603 if(mpt_raid_phys_disk_pg0(ioc,
5604 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
5607 if ((component_info = kmalloc(sizeof (*component_info),
5608 GFP_KERNEL)) == NULL)
5611 component_info->volumeID = id;
5612 component_info->volumeBus = channel;
5613 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
5614 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
5615 component_info->d.PhysDiskID = phys_disk.PhysDiskID;
5616 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
5618 list_add_tail(&component_info->list,
5619 &ioc->raid_data.inactive_list);
5621 mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5625 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5630 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5631 * @ioc: Pointer to a Adapter Structure
5632 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5633 * @phys_disk: requested payload data returned
5637 * -EFAULT if read of config page header fails or data pointer not NULL
5638 * -ENOMEM if pci_alloc failed
5641 mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk)
5644 ConfigPageHeader_t hdr;
5645 dma_addr_t dma_handle;
5646 pRaidPhysDiskPage0_t buffer = NULL;
5649 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5650 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5652 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5653 cfg.cfghdr.hdr = &hdr;
5655 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5657 if (mpt_config(ioc, &cfg) != 0) {
5662 if (!hdr.PageLength) {
5667 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5675 cfg.physAddr = dma_handle;
5676 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5677 cfg.pageAddr = phys_disk_num;
5679 if (mpt_config(ioc, &cfg) != 0) {
5685 memcpy(phys_disk, buffer, sizeof(*buffer));
5686 phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
5691 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5698 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5699 * @ioc: Pointer to a Adapter Strucutre
5703 * -EFAULT if read of config page header fails or data pointer not NULL
5704 * -ENOMEM if pci_alloc failed
5707 mpt_findImVolumes(MPT_ADAPTER *ioc)
5711 dma_addr_t ioc2_dma;
5713 ConfigPageHeader_t header;
5718 if (!ioc->ir_firmware)
5721 /* Free the old page
5723 kfree(ioc->raid_data.pIocPg2);
5724 ioc->raid_data.pIocPg2 = NULL;
5725 mpt_inactive_raid_list_free(ioc);
5727 /* Read IOCP2 header then the page.
5729 header.PageVersion = 0;
5730 header.PageLength = 0;
5731 header.PageNumber = 2;
5732 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5733 cfg.cfghdr.hdr = &header;
5736 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5739 if (mpt_config(ioc, &cfg) != 0)
5742 if (header.PageLength == 0)
5745 iocpage2sz = header.PageLength * 4;
5746 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
5750 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5751 cfg.physAddr = ioc2_dma;
5752 if (mpt_config(ioc, &cfg) != 0)
5755 mem = kmalloc(iocpage2sz, GFP_KERNEL);
5759 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
5760 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
5762 mpt_read_ioc_pg_3(ioc);
5764 for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
5765 mpt_inactive_raid_volumes(ioc,
5766 pIoc2->RaidVolume[i].VolumeBus,
5767 pIoc2->RaidVolume[i].VolumeID);
5770 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
5776 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
5781 ConfigPageHeader_t header;
5782 dma_addr_t ioc3_dma;
5785 /* Free the old page
5787 kfree(ioc->raid_data.pIocPg3);
5788 ioc->raid_data.pIocPg3 = NULL;
5790 /* There is at least one physical disk.
5791 * Read and save IOC Page 3
5793 header.PageVersion = 0;
5794 header.PageLength = 0;
5795 header.PageNumber = 3;
5796 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5797 cfg.cfghdr.hdr = &header;
5800 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5803 if (mpt_config(ioc, &cfg) != 0)
5806 if (header.PageLength == 0)
5809 /* Read Header good, alloc memory
5811 iocpage3sz = header.PageLength * 4;
5812 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
5816 /* Read the Page and save the data
5817 * into malloc'd memory.
5819 cfg.physAddr = ioc3_dma;
5820 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5821 if (mpt_config(ioc, &cfg) == 0) {
5822 mem = kmalloc(iocpage3sz, GFP_KERNEL);
5824 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
5825 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
5829 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
5835 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
5839 ConfigPageHeader_t header;
5840 dma_addr_t ioc4_dma;
5843 /* Read and save IOC Page 4
5845 header.PageVersion = 0;
5846 header.PageLength = 0;
5847 header.PageNumber = 4;
5848 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5849 cfg.cfghdr.hdr = &header;
5852 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5855 if (mpt_config(ioc, &cfg) != 0)
5858 if (header.PageLength == 0)
5861 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
5862 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
5863 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
5866 ioc->alloc_total += iocpage4sz;
5868 ioc4_dma = ioc->spi_data.IocPg4_dma;
5869 iocpage4sz = ioc->spi_data.IocPg4Sz;
5872 /* Read the Page into dma memory.
5874 cfg.physAddr = ioc4_dma;
5875 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5876 if (mpt_config(ioc, &cfg) == 0) {
5877 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
5878 ioc->spi_data.IocPg4_dma = ioc4_dma;
5879 ioc->spi_data.IocPg4Sz = iocpage4sz;
5881 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
5882 ioc->spi_data.pIocPg4 = NULL;
5883 ioc->alloc_total -= iocpage4sz;
5888 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
5892 ConfigPageHeader_t header;
5893 dma_addr_t ioc1_dma;
5897 /* Check the Coalescing Timeout in IOC Page 1
5899 header.PageVersion = 0;
5900 header.PageLength = 0;
5901 header.PageNumber = 1;
5902 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5903 cfg.cfghdr.hdr = &header;
5906 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5909 if (mpt_config(ioc, &cfg) != 0)
5912 if (header.PageLength == 0)
5915 /* Read Header good, alloc memory
5917 iocpage1sz = header.PageLength * 4;
5918 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
5922 /* Read the Page and check coalescing timeout
5924 cfg.physAddr = ioc1_dma;
5925 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5926 if (mpt_config(ioc, &cfg) == 0) {
5928 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
5929 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
5930 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
5932 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Coalescing Enabled Timeout = %d\n",
5935 if (tmp > MPT_COALESCING_TIMEOUT) {
5936 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
5938 /* Write NVRAM and current
5941 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5942 if (mpt_config(ioc, &cfg) == 0) {
5943 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Reset Current Coalescing Timeout to = %d\n",
5944 ioc->name, MPT_COALESCING_TIMEOUT));
5946 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
5947 if (mpt_config(ioc, &cfg) == 0) {
5948 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5949 "Reset NVRAM Coalescing Timeout to = %d\n",
5950 ioc->name, MPT_COALESCING_TIMEOUT));
5952 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5953 "Reset NVRAM Coalescing Timeout Failed\n",
5958 dprintk(ioc, printk(MYIOC_s_WARN_FMT
5959 "Reset of Current Coalescing Timeout Failed!\n",
5965 dprintk(ioc, printk(MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
5969 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
5975 mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
5978 ConfigPageHeader_t hdr;
5980 ManufacturingPage0_t *pbuf = NULL;
5982 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5983 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5985 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
5986 cfg.cfghdr.hdr = &hdr;
5988 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5991 if (mpt_config(ioc, &cfg) != 0)
5994 if (!cfg.cfghdr.hdr->PageLength)
5997 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5998 pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
6002 cfg.physAddr = buf_dma;
6004 if (mpt_config(ioc, &cfg) != 0)
6007 memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name));
6008 memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
6009 memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
6014 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
6017 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6019 * SendEventNotification - Send EventNotification (on or off) request to adapter
6020 * @ioc: Pointer to MPT_ADAPTER structure
6021 * @EvSwitch: Event switch flags
6024 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
6026 EventNotification_t *evnp;
6028 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
6030 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
6034 memset(evnp, 0, sizeof(*evnp));
6036 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
6038 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
6039 evnp->ChainOffset = 0;
6041 evnp->Switch = EvSwitch;
6043 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
6048 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6050 * SendEventAck - Send EventAck request to MPT adapter.
6051 * @ioc: Pointer to MPT_ADAPTER structure
6052 * @evnp: Pointer to original EventNotification request
6055 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
6059 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
6060 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
6061 ioc->name,__func__));
6065 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventAck\n", ioc->name));
6067 pAck->Function = MPI_FUNCTION_EVENT_ACK;
6068 pAck->ChainOffset = 0;
6069 pAck->Reserved[0] = pAck->Reserved[1] = 0;
6071 pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
6072 pAck->Event = evnp->Event;
6073 pAck->EventContext = evnp->EventContext;
6075 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
6080 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6082 * mpt_config - Generic function to issue config message
6083 * @ioc: Pointer to an adapter structure
6084 * @pCfg: Pointer to a configuration structure. Struct contains
6085 * action, page address, direction, physical address
6086 * and pointer to a configuration page header
6087 * Page header is updated.
6089 * Returns 0 for success
6090 * -EPERM if not allowed due to ISR context
6091 * -EAGAIN if no msg frames currently available
6092 * -EFAULT for non-successful reply or no reply (timeout)
6095 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
6098 ConfigExtendedPageHeader_t *pExtHdr = NULL;
6100 unsigned long flags;
6105 /* Prevent calling wait_event() (below), if caller happens
6106 * to be in ISR context, because that is fatal!
6108 in_isr = in_interrupt();
6110 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
6115 /* Get and Populate a free Frame
6117 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
6118 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
6122 pReq = (Config_t *)mf;
6123 pReq->Action = pCfg->action;
6125 pReq->ChainOffset = 0;
6126 pReq->Function = MPI_FUNCTION_CONFIG;
6128 /* Assume page type is not extended and clear "reserved" fields. */
6129 pReq->ExtPageLength = 0;
6130 pReq->ExtPageType = 0;
6133 for (ii=0; ii < 8; ii++)
6134 pReq->Reserved2[ii] = 0;
6136 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
6137 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
6138 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
6139 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
6141 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
6142 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
6143 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
6144 pReq->ExtPageType = pExtHdr->ExtPageType;
6145 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
6147 /* Page Length must be treated as a reserved field for the extended header. */
6148 pReq->Header.PageLength = 0;
6151 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
6153 /* Add a SGE to the config request.
6156 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
6158 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
6160 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
6161 flagsLength |= pExtHdr->ExtPageLength * 4;
6163 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n",
6164 ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action));
6167 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
6169 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n",
6170 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
6173 ioc->add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
6175 /* Append pCfg pointer to end of mf
6177 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
6179 /* Initalize the timer
6181 init_timer_on_stack(&pCfg->timer);
6182 pCfg->timer.data = (unsigned long) ioc;
6183 pCfg->timer.function = mpt_timer_expired;
6184 pCfg->wait_done = 0;
6186 /* Set the timer; ensure 10 second minimum */
6187 if (pCfg->timeout < 10)
6188 pCfg->timer.expires = jiffies + HZ*10;
6190 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
6192 /* Add to end of Q, set timer and then issue this command */
6193 spin_lock_irqsave(&ioc->FreeQlock, flags);
6194 list_add_tail(&pCfg->linkage, &ioc->configQ);
6195 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
6197 add_timer(&pCfg->timer);
6198 mpt_put_msg_frame(mpt_base_index, ioc, mf);
6199 wait_event(mpt_waitq, pCfg->wait_done);
6201 /* mf has been freed - do not access */
6208 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6210 * mpt_timer_expired - Callback for timer process.
6211 * Used only internal config functionality.
6212 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
6215 mpt_timer_expired(unsigned long data)
6217 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
6219 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired! \n", ioc->name));
6221 /* Perform a FW reload */
6222 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
6223 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
6225 /* No more processing.
6226 * Hard reset clean-up will wake up
6227 * process and free all resources.
6229 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired complete!\n", ioc->name));
6234 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6236 * mpt_ioc_reset - Base cleanup for hard reset
6237 * @ioc: Pointer to the adapter structure
6238 * @reset_phase: Indicates pre- or post-reset functionality
6240 * Remark: Frees resources with internally generated commands.
6243 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
6246 unsigned long flags;
6248 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6249 ": IOC %s_reset routed to MPT base driver!\n",
6250 ioc->name, reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
6251 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
6253 if (reset_phase == MPT_IOC_SETUP_RESET) {
6255 } else if (reset_phase == MPT_IOC_PRE_RESET) {
6256 /* If the internal config Q is not empty -
6257 * delete timer. MF resources will be freed when
6258 * the FIFO's are primed.
6260 spin_lock_irqsave(&ioc->FreeQlock, flags);
6261 list_for_each_entry(pCfg, &ioc->configQ, linkage)
6262 del_timer(&pCfg->timer);
6263 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
6268 /* Search the configQ for internal commands.
6269 * Flush the Q, and wake up all suspended threads.
6271 spin_lock_irqsave(&ioc->FreeQlock, flags);
6272 list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
6273 list_del(&pCfg->linkage);
6275 pCfg->status = MPT_CONFIG_ERROR;
6276 pCfg->wait_done = 1;
6277 wake_up(&mpt_waitq);
6279 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
6282 return 1; /* currently means nothing really */
6286 #ifdef CONFIG_PROC_FS /* { */
6287 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6289 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
6291 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6293 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
6295 * Returns 0 for success, non-zero for failure.
6298 procmpt_create(void)
6300 struct proc_dir_entry *ent;
6302 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
6303 if (mpt_proc_root_dir == NULL)
6306 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
6308 ent->read_proc = procmpt_summary_read;
6310 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
6312 ent->read_proc = procmpt_version_read;
6317 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6319 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
6321 * Returns 0 for success, non-zero for failure.
6324 procmpt_destroy(void)
6326 remove_proc_entry("version", mpt_proc_root_dir);
6327 remove_proc_entry("summary", mpt_proc_root_dir);
6328 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
6331 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6333 * procmpt_summary_read - Handle read request of a summary file
6334 * @buf: Pointer to area to write information
6335 * @start: Pointer to start pointer
6336 * @offset: Offset to start writing
6337 * @request: Amount of read data requested
6338 * @eof: Pointer to EOF integer
6341 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
6342 * Returns number of characters written to process performing the read.
6345 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6355 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
6359 list_for_each_entry(ioc, &ioc_list, list) {
6362 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
6365 if ((out-buf) >= request)
6372 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6375 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6377 * procmpt_version_read - Handle read request from /proc/mpt/version.
6378 * @buf: Pointer to area to write information
6379 * @start: Pointer to start pointer
6380 * @offset: Offset to start writing
6381 * @request: Amount of read data requested
6382 * @eof: Pointer to EOF integer
6385 * Returns number of characters written to process performing the read.
6388 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6391 int scsi, fc, sas, lan, ctl, targ, dmp;
6395 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
6396 len += sprintf(buf+len, " Fusion MPT base driver\n");
6398 scsi = fc = sas = lan = ctl = targ = dmp = 0;
6399 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6401 if (MptCallbacks[cb_idx]) {
6402 switch (MptDriverClass[cb_idx]) {
6404 if (!scsi++) drvname = "SPI host";
6407 if (!fc++) drvname = "FC host";
6410 if (!sas++) drvname = "SAS host";
6413 if (!lan++) drvname = "LAN";
6416 if (!targ++) drvname = "SCSI target";
6419 if (!ctl++) drvname = "ioctl";
6424 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
6428 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6431 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6433 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
6434 * @buf: Pointer to area to write information
6435 * @start: Pointer to start pointer
6436 * @offset: Offset to start writing
6437 * @request: Amount of read data requested
6438 * @eof: Pointer to EOF integer
6441 * Returns number of characters written to process performing the read.
6444 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6446 MPT_ADAPTER *ioc = data;
6452 mpt_get_fw_exp_ver(expVer, ioc);
6454 len = sprintf(buf, "%s:", ioc->name);
6455 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
6456 len += sprintf(buf+len, " (f/w download boot flag set)");
6457 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6458 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
6460 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
6461 ioc->facts.ProductID,
6463 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
6464 if (ioc->facts.FWImageSize)
6465 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
6466 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
6467 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
6468 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
6470 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
6471 ioc->facts.CurrentHostMfaHighAddr);
6472 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
6473 ioc->facts.CurrentSenseBufferHighAddr);
6475 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
6476 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
6478 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6479 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
6481 * Rounding UP to nearest 4-kB boundary here...
6483 sz = (ioc->req_sz * ioc->req_depth) + 128;
6484 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
6485 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6486 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
6487 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
6488 4*ioc->facts.RequestFrameSize,
6489 ioc->facts.GlobalCredits);
6491 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
6492 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
6493 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
6494 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6495 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
6496 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
6497 ioc->facts.CurReplyFrameSize,
6498 ioc->facts.ReplyQueueDepth);
6500 len += sprintf(buf+len, " MaxDevices = %d\n",
6501 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
6502 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
6505 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
6506 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
6508 ioc->facts.NumberOfPorts);
6509 if (ioc->bus_type == FC) {
6510 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
6511 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6512 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6513 a[5], a[4], a[3], a[2], a[1], a[0]);
6515 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
6516 ioc->fc_port_page0[p].WWNN.High,
6517 ioc->fc_port_page0[p].WWNN.Low,
6518 ioc->fc_port_page0[p].WWPN.High,
6519 ioc->fc_port_page0[p].WWPN.Low);
6523 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6526 #endif /* CONFIG_PROC_FS } */
6528 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6530 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
6533 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
6534 sprintf(buf, " (Exp %02d%02d)",
6535 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
6536 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
6539 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
6540 strcat(buf, " [MDBG]");
6544 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6546 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6547 * @ioc: Pointer to MPT_ADAPTER structure
6548 * @buffer: Pointer to buffer where IOC summary info should be written
6549 * @size: Pointer to number of bytes we wrote (set by this routine)
6550 * @len: Offset at which to start writing in buffer
6551 * @showlan: Display LAN stuff?
6553 * This routine writes (english readable) ASCII text, which represents
6554 * a summary of IOC information, to a buffer.
6557 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
6562 mpt_get_fw_exp_ver(expVer, ioc);
6565 * Shorter summary of attached ioc's...
6567 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6570 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
6571 ioc->facts.FWVersion.Word,
6573 ioc->facts.NumberOfPorts,
6576 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6577 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6578 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6579 a[5], a[4], a[3], a[2], a[1], a[0]);
6582 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
6585 y += sprintf(buffer+len+y, " (disabled)");
6587 y += sprintf(buffer+len+y, "\n");
6594 * mpt_halt_firmware - Halts the firmware if it is operational and panic
6596 * @ioc: Pointer to MPT_ADAPTER structure
6600 mpt_halt_firmware(MPT_ADAPTER *ioc)
6604 ioc_raw_state = mpt_GetIocState(ioc, 0);
6606 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
6607 printk(MYIOC_s_ERR_FMT "IOC is in FAULT state (%04xh)!!!\n",
6608 ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
6609 panic("%s: IOC Fault (%04xh)!!!\n", ioc->name,
6610 ioc_raw_state & MPI_DOORBELL_DATA_MASK);
6612 CHIPREG_WRITE32(&ioc->chip->Doorbell, 0xC0FFEE00);
6613 panic("%s: Firmware is halted due to command timeout\n",
6617 EXPORT_SYMBOL(mpt_halt_firmware);
6619 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6623 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6625 * mpt_HardResetHandler - Generic reset handler
6626 * @ioc: Pointer to MPT_ADAPTER structure
6627 * @sleepFlag: Indicates if sleep or schedule must be called.
6629 * Issues SCSI Task Management call based on input arg values.
6630 * If TaskMgmt fails, returns associated SCSI request.
6632 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
6633 * or a non-interrupt thread. In the former, must not call schedule().
6635 * Note: A return of -1 is a FATAL error case, as it means a
6636 * FW reload/initialization failed.
6638 * Returns 0 for SUCCESS or -1 if FAILED.
6641 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6644 unsigned long flags;
6646 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name));
6648 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
6649 printk("MF count 0x%x !\n", ioc->mfcnt);
6651 if (mpt_fwfault_debug)
6652 mpt_halt_firmware(ioc);
6654 /* Reset the adapter. Prevent more than 1 call to
6655 * mpt_do_ioc_recovery at any instant in time.
6657 spin_lock_irqsave(&ioc->diagLock, flags);
6658 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
6659 spin_unlock_irqrestore(&ioc->diagLock, flags);
6662 ioc->diagPending = 1;
6664 spin_unlock_irqrestore(&ioc->diagLock, flags);
6666 /* FIXME: If do_ioc_recovery fails, repeat....
6669 /* The SCSI driver needs to adjust timeouts on all current
6670 * commands prior to the diagnostic reset being issued.
6671 * Prevents timeouts occurring during a diagnostic reset...very bad.
6672 * For all other protocol drivers, this is a no-op.
6678 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6679 if (MptResetHandlers[cb_idx]) {
6680 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling IOC reset_setup handler #%d\n",
6681 ioc->name, cb_idx));
6682 r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
6684 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling alt-%s setup reset handler #%d\n",
6685 ioc->name, ioc->alt_ioc->name, cb_idx));
6686 r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_SETUP_RESET);
6692 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
6693 printk(MYIOC_s_WARN_FMT "Cannot recover rc = %d!\n", ioc->name, rc);
6697 ioc->alt_ioc->reload_fw = 0;
6699 spin_lock_irqsave(&ioc->diagLock, flags);
6700 ioc->diagPending = 0;
6702 ioc->alt_ioc->diagPending = 0;
6703 spin_unlock_irqrestore(&ioc->diagLock, flags);
6705 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
6710 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6712 EventDescriptionStr(u8 event, u32 evData0, char *evStr)
6717 case MPI_EVENT_NONE:
6720 case MPI_EVENT_LOG_DATA:
6723 case MPI_EVENT_STATE_CHANGE:
6724 ds = "State Change";
6726 case MPI_EVENT_UNIT_ATTENTION:
6727 ds = "Unit Attention";
6729 case MPI_EVENT_IOC_BUS_RESET:
6730 ds = "IOC Bus Reset";
6732 case MPI_EVENT_EXT_BUS_RESET:
6733 ds = "External Bus Reset";
6735 case MPI_EVENT_RESCAN:
6736 ds = "Bus Rescan Event";
6738 case MPI_EVENT_LINK_STATUS_CHANGE:
6739 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
6740 ds = "Link Status(FAILURE) Change";
6742 ds = "Link Status(ACTIVE) Change";
6744 case MPI_EVENT_LOOP_STATE_CHANGE:
6745 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
6746 ds = "Loop State(LIP) Change";
6747 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
6748 ds = "Loop State(LPE) Change"; /* ??? */
6750 ds = "Loop State(LPB) Change"; /* ??? */
6752 case MPI_EVENT_LOGOUT:
6755 case MPI_EVENT_EVENT_CHANGE:
6761 case MPI_EVENT_INTEGRATED_RAID:
6763 u8 ReasonCode = (u8)(evData0 >> 16);
6764 switch (ReasonCode) {
6765 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
6766 ds = "Integrated Raid: Volume Created";
6768 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
6769 ds = "Integrated Raid: Volume Deleted";
6771 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
6772 ds = "Integrated Raid: Volume Settings Changed";
6774 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
6775 ds = "Integrated Raid: Volume Status Changed";
6777 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
6778 ds = "Integrated Raid: Volume Physdisk Changed";
6780 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
6781 ds = "Integrated Raid: Physdisk Created";
6783 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
6784 ds = "Integrated Raid: Physdisk Deleted";
6786 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
6787 ds = "Integrated Raid: Physdisk Settings Changed";
6789 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
6790 ds = "Integrated Raid: Physdisk Status Changed";
6792 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
6793 ds = "Integrated Raid: Domain Validation Needed";
6795 case MPI_EVENT_RAID_RC_SMART_DATA :
6796 ds = "Integrated Raid; Smart Data";
6798 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
6799 ds = "Integrated Raid: Replace Action Started";
6802 ds = "Integrated Raid";
6807 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
6808 ds = "SCSI Device Status Change";
6810 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
6812 u8 id = (u8)(evData0);
6813 u8 channel = (u8)(evData0 >> 8);
6814 u8 ReasonCode = (u8)(evData0 >> 16);
6815 switch (ReasonCode) {
6816 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
6817 snprintf(evStr, EVENT_DESCR_STR_SZ,
6818 "SAS Device Status Change: Added: "
6819 "id=%d channel=%d", id, channel);
6821 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
6822 snprintf(evStr, EVENT_DESCR_STR_SZ,
6823 "SAS Device Status Change: Deleted: "
6824 "id=%d channel=%d", id, channel);
6826 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
6827 snprintf(evStr, EVENT_DESCR_STR_SZ,
6828 "SAS Device Status Change: SMART Data: "
6829 "id=%d channel=%d", id, channel);
6831 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
6832 snprintf(evStr, EVENT_DESCR_STR_SZ,
6833 "SAS Device Status Change: No Persistancy: "
6834 "id=%d channel=%d", id, channel);
6836 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
6837 snprintf(evStr, EVENT_DESCR_STR_SZ,
6838 "SAS Device Status Change: Unsupported Device "
6839 "Discovered : id=%d channel=%d", id, channel);
6841 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
6842 snprintf(evStr, EVENT_DESCR_STR_SZ,
6843 "SAS Device Status Change: Internal Device "
6844 "Reset : id=%d channel=%d", id, channel);
6846 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
6847 snprintf(evStr, EVENT_DESCR_STR_SZ,
6848 "SAS Device Status Change: Internal Task "
6849 "Abort : id=%d channel=%d", id, channel);
6851 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
6852 snprintf(evStr, EVENT_DESCR_STR_SZ,
6853 "SAS Device Status Change: Internal Abort "
6854 "Task Set : id=%d channel=%d", id, channel);
6856 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
6857 snprintf(evStr, EVENT_DESCR_STR_SZ,
6858 "SAS Device Status Change: Internal Clear "
6859 "Task Set : id=%d channel=%d", id, channel);
6861 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
6862 snprintf(evStr, EVENT_DESCR_STR_SZ,
6863 "SAS Device Status Change: Internal Query "
6864 "Task : id=%d channel=%d", id, channel);
6867 snprintf(evStr, EVENT_DESCR_STR_SZ,
6868 "SAS Device Status Change: Unknown: "
6869 "id=%d channel=%d", id, channel);
6874 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
6875 ds = "Bus Timer Expired";
6877 case MPI_EVENT_QUEUE_FULL:
6879 u16 curr_depth = (u16)(evData0 >> 16);
6880 u8 channel = (u8)(evData0 >> 8);
6881 u8 id = (u8)(evData0);
6883 snprintf(evStr, EVENT_DESCR_STR_SZ,
6884 "Queue Full: channel=%d id=%d depth=%d",
6885 channel, id, curr_depth);
6888 case MPI_EVENT_SAS_SES:
6889 ds = "SAS SES Event";
6891 case MPI_EVENT_PERSISTENT_TABLE_FULL:
6892 ds = "Persistent Table Full";
6894 case MPI_EVENT_SAS_PHY_LINK_STATUS:
6896 u8 LinkRates = (u8)(evData0 >> 8);
6897 u8 PhyNumber = (u8)(evData0);
6898 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
6899 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
6900 switch (LinkRates) {
6901 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
6902 snprintf(evStr, EVENT_DESCR_STR_SZ,
6903 "SAS PHY Link Status: Phy=%d:"
6904 " Rate Unknown",PhyNumber);
6906 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
6907 snprintf(evStr, EVENT_DESCR_STR_SZ,
6908 "SAS PHY Link Status: Phy=%d:"
6909 " Phy Disabled",PhyNumber);
6911 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
6912 snprintf(evStr, EVENT_DESCR_STR_SZ,
6913 "SAS PHY Link Status: Phy=%d:"
6914 " Failed Speed Nego",PhyNumber);
6916 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
6917 snprintf(evStr, EVENT_DESCR_STR_SZ,
6918 "SAS PHY Link Status: Phy=%d:"
6919 " Sata OOB Completed",PhyNumber);
6921 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
6922 snprintf(evStr, EVENT_DESCR_STR_SZ,
6923 "SAS PHY Link Status: Phy=%d:"
6924 " Rate 1.5 Gbps",PhyNumber);
6926 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
6927 snprintf(evStr, EVENT_DESCR_STR_SZ,
6928 "SAS PHY Link Status: Phy=%d:"
6929 " Rate 3.0 Gpbs",PhyNumber);
6932 snprintf(evStr, EVENT_DESCR_STR_SZ,
6933 "SAS PHY Link Status: Phy=%d", PhyNumber);
6938 case MPI_EVENT_SAS_DISCOVERY_ERROR:
6939 ds = "SAS Discovery Error";
6941 case MPI_EVENT_IR_RESYNC_UPDATE:
6943 u8 resync_complete = (u8)(evData0 >> 16);
6944 snprintf(evStr, EVENT_DESCR_STR_SZ,
6945 "IR Resync Update: Complete = %d:",resync_complete);
6950 u8 ReasonCode = (u8)(evData0 >> 16);
6951 switch (ReasonCode) {
6952 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
6953 ds = "IR2: LD State Changed";
6955 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
6956 ds = "IR2: PD State Changed";
6958 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
6959 ds = "IR2: Bad Block Table Full";
6961 case MPI_EVENT_IR2_RC_PD_INSERTED:
6962 ds = "IR2: PD Inserted";
6964 case MPI_EVENT_IR2_RC_PD_REMOVED:
6965 ds = "IR2: PD Removed";
6967 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
6968 ds = "IR2: Foreign CFG Detected";
6970 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
6971 ds = "IR2: Rebuild Medium Error";
6979 case MPI_EVENT_SAS_DISCOVERY:
6982 ds = "SAS Discovery: Start";
6984 ds = "SAS Discovery: Stop";
6987 case MPI_EVENT_LOG_ENTRY_ADDED:
6988 ds = "SAS Log Entry Added";
6991 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
6993 u8 phy_num = (u8)(evData0);
6994 u8 port_num = (u8)(evData0 >> 8);
6995 u8 port_width = (u8)(evData0 >> 16);
6996 u8 primative = (u8)(evData0 >> 24);
6997 snprintf(evStr, EVENT_DESCR_STR_SZ,
6998 "SAS Broadcase Primative: phy=%d port=%d "
6999 "width=%d primative=0x%02x",
7000 phy_num, port_num, port_width, primative);
7004 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
7006 u8 reason = (u8)(evData0);
7007 u8 port_num = (u8)(evData0 >> 8);
7008 u16 handle = le16_to_cpu(evData0 >> 16);
7010 snprintf(evStr, EVENT_DESCR_STR_SZ,
7011 "SAS Initiator Device Status Change: reason=0x%02x "
7012 "port=%d handle=0x%04x",
7013 reason, port_num, handle);
7017 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
7019 u8 max_init = (u8)(evData0);
7020 u8 current_init = (u8)(evData0 >> 8);
7022 snprintf(evStr, EVENT_DESCR_STR_SZ,
7023 "SAS Initiator Device Table Overflow: max initiators=%02d "
7024 "current initators=%02d",
7025 max_init, current_init);
7028 case MPI_EVENT_SAS_SMP_ERROR:
7030 u8 status = (u8)(evData0);
7031 u8 port_num = (u8)(evData0 >> 8);
7032 u8 result = (u8)(evData0 >> 16);
7034 if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
7035 snprintf(evStr, EVENT_DESCR_STR_SZ,
7036 "SAS SMP Error: port=%d result=0x%02x",
7038 else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
7039 snprintf(evStr, EVENT_DESCR_STR_SZ,
7040 "SAS SMP Error: port=%d : CRC Error",
7042 else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
7043 snprintf(evStr, EVENT_DESCR_STR_SZ,
7044 "SAS SMP Error: port=%d : Timeout",
7046 else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
7047 snprintf(evStr, EVENT_DESCR_STR_SZ,
7048 "SAS SMP Error: port=%d : No Destination",
7050 else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
7051 snprintf(evStr, EVENT_DESCR_STR_SZ,
7052 "SAS SMP Error: port=%d : Bad Destination",
7055 snprintf(evStr, EVENT_DESCR_STR_SZ,
7056 "SAS SMP Error: port=%d : status=0x%02x",
7062 * MPT base "custom" events may be added here...
7069 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
7072 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7074 * ProcessEventNotification - Route EventNotificationReply to all event handlers
7075 * @ioc: Pointer to MPT_ADAPTER structure
7076 * @pEventReply: Pointer to EventNotification reply frame
7077 * @evHandlers: Pointer to integer, number of event handlers
7079 * Routes a received EventNotificationReply to all currently registered
7081 * Returns sum of event handlers return values.
7084 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
7093 char evStr[EVENT_DESCR_STR_SZ];
7097 * Do platform normalization of values
7099 event = le32_to_cpu(pEventReply->Event) & 0xFF;
7100 // evCtx = le32_to_cpu(pEventReply->EventContext);
7101 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
7103 evData0 = le32_to_cpu(pEventReply->Data[0]);
7106 EventDescriptionStr(event, evData0, evStr);
7107 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event:(%02Xh) : %s\n",
7112 #ifdef CONFIG_FUSION_LOGGING
7113 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7114 ": Event data:\n", ioc->name));
7115 for (ii = 0; ii < evDataLen; ii++)
7116 devtverboseprintk(ioc, printk(" %08x",
7117 le32_to_cpu(pEventReply->Data[ii])));
7118 devtverboseprintk(ioc, printk("\n"));
7122 * Do general / base driver event processing
7125 case MPI_EVENT_EVENT_CHANGE: /* 0A */
7127 u8 evState = evData0 & 0xFF;
7129 /* CHECKME! What if evState unexpectedly says OFF (0)? */
7131 /* Update EventState field in cached IocFacts */
7132 if (ioc->facts.Function) {
7133 ioc->facts.EventState = evState;
7137 case MPI_EVENT_INTEGRATED_RAID:
7138 mptbase_raid_process_event_data(ioc,
7139 (MpiEventDataRaid_t *)pEventReply->Data);
7146 * Should this event be logged? Events are written sequentially.
7147 * When buffer is full, start again at the top.
7149 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
7152 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
7154 ioc->events[idx].event = event;
7155 ioc->events[idx].eventContext = ioc->eventContext;
7157 for (ii = 0; ii < 2; ii++) {
7159 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
7161 ioc->events[idx].data[ii] = 0;
7164 ioc->eventContext++;
7169 * Call each currently registered protocol event handler.
7171 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7172 if (MptEvHandlers[cb_idx]) {
7173 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Routing Event to event handler #%d\n",
7174 ioc->name, cb_idx));
7175 r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply);
7179 /* FIXME? Examine results here? */
7182 * If needed, send (a single) EventAck.
7184 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
7185 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7186 "EventAck required\n",ioc->name));
7187 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
7188 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SendEventAck returned %d\n",
7193 *evHandlers = handlers;
7197 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7199 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
7200 * @ioc: Pointer to MPT_ADAPTER structure
7201 * @log_info: U32 LogInfo reply word from the IOC
7203 * Refer to lsi/mpi_log_fc.h.
7206 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
7208 char *desc = "unknown";
7210 switch (log_info & 0xFF000000) {
7211 case MPI_IOCLOGINFO_FC_INIT_BASE:
7212 desc = "FCP Initiator";
7214 case MPI_IOCLOGINFO_FC_TARGET_BASE:
7215 desc = "FCP Target";
7217 case MPI_IOCLOGINFO_FC_LAN_BASE:
7220 case MPI_IOCLOGINFO_FC_MSG_BASE:
7221 desc = "MPI Message Layer";
7223 case MPI_IOCLOGINFO_FC_LINK_BASE:
7226 case MPI_IOCLOGINFO_FC_CTX_BASE:
7227 desc = "Context Manager";
7229 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
7230 desc = "Invalid Field Offset";
7232 case MPI_IOCLOGINFO_FC_STATE_CHANGE:
7233 desc = "State Change Info";
7237 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
7238 ioc->name, log_info, desc, (log_info & 0xFFFFFF));
7241 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7243 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
7244 * @ioc: Pointer to MPT_ADAPTER structure
7245 * @log_info: U32 LogInfo word from the IOC
7247 * Refer to lsi/sp_log.h.
7250 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
7252 u32 info = log_info & 0x00FF0000;
7253 char *desc = "unknown";
7257 desc = "bug! MID not found";
7258 if (ioc->reload_fw == 0)
7263 desc = "Parity Error";
7267 desc = "ASYNC Outbound Overrun";
7271 desc = "SYNC Offset Error";
7279 desc = "Msg In Overflow";
7287 desc = "Outbound DMA Overrun";
7291 desc = "Task Management";
7295 desc = "Device Problem";
7299 desc = "Invalid Phase Change";
7303 desc = "Untagged Table Size";
7308 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
7311 /* strings for sas loginfo */
7312 static char *originator_str[] = {
7317 static char *iop_code_str[] = {
7319 "Invalid SAS Address", /* 01h */
7321 "Invalid Page", /* 03h */
7322 "Diag Message Error", /* 04h */
7323 "Task Terminated", /* 05h */
7324 "Enclosure Management", /* 06h */
7325 "Target Mode" /* 07h */
7327 static char *pl_code_str[] = {
7329 "Open Failure", /* 01h */
7330 "Invalid Scatter Gather List", /* 02h */
7331 "Wrong Relative Offset or Frame Length", /* 03h */
7332 "Frame Transfer Error", /* 04h */
7333 "Transmit Frame Connected Low", /* 05h */
7334 "SATA Non-NCQ RW Error Bit Set", /* 06h */
7335 "SATA Read Log Receive Data Error", /* 07h */
7336 "SATA NCQ Fail All Commands After Error", /* 08h */
7337 "SATA Error in Receive Set Device Bit FIS", /* 09h */
7338 "Receive Frame Invalid Message", /* 0Ah */
7339 "Receive Context Message Valid Error", /* 0Bh */
7340 "Receive Frame Current Frame Error", /* 0Ch */
7341 "SATA Link Down", /* 0Dh */
7342 "Discovery SATA Init W IOS", /* 0Eh */
7343 "Config Invalid Page", /* 0Fh */
7344 "Discovery SATA Init Timeout", /* 10h */
7347 "IO Not Yet Executed", /* 13h */
7348 "IO Executed", /* 14h */
7349 "Persistent Reservation Out Not Affiliation "
7351 "Open Transmit DMA Abort", /* 16h */
7352 "IO Device Missing Delay Retry", /* 17h */
7353 "IO Cancelled Due to Recieve Error", /* 18h */
7361 "Enclosure Management" /* 20h */
7363 static char *ir_code_str[] = {
7364 "Raid Action Error", /* 00h */
7374 static char *raid_sub_code_str[] = {
7376 "Volume Creation Failed: Data Passed too "
7378 "Volume Creation Failed: Duplicate Volumes "
7379 "Attempted", /* 02h */
7380 "Volume Creation Failed: Max Number "
7381 "Supported Volumes Exceeded", /* 03h */
7382 "Volume Creation Failed: DMA Error", /* 04h */
7383 "Volume Creation Failed: Invalid Volume Type", /* 05h */
7384 "Volume Creation Failed: Error Reading "
7385 "MFG Page 4", /* 06h */
7386 "Volume Creation Failed: Creating Internal "
7387 "Structures", /* 07h */
7396 "Activation failed: Already Active Volume", /* 10h */
7397 "Activation failed: Unsupported Volume Type", /* 11h */
7398 "Activation failed: Too Many Active Volumes", /* 12h */
7399 "Activation failed: Volume ID in Use", /* 13h */
7400 "Activation failed: Reported Failure", /* 14h */
7401 "Activation failed: Importing a Volume", /* 15h */
7412 "Phys Disk failed: Too Many Phys Disks", /* 20h */
7413 "Phys Disk failed: Data Passed too Large", /* 21h */
7414 "Phys Disk failed: DMA Error", /* 22h */
7415 "Phys Disk failed: Invalid <channel:id>", /* 23h */
7416 "Phys Disk failed: Creating Phys Disk Config "
7429 "Compatibility Error: IR Disabled", /* 30h */
7430 "Compatibility Error: Inquiry Comand Failed", /* 31h */
7431 "Compatibility Error: Device not Direct Access "
7432 "Device ", /* 32h */
7433 "Compatibility Error: Removable Device Found", /* 33h */
7434 "Compatibility Error: Device SCSI Version not "
7435 "2 or Higher", /* 34h */
7436 "Compatibility Error: SATA Device, 48 BIT LBA "
7437 "not Supported", /* 35h */
7438 "Compatibility Error: Device doesn't have "
7439 "512 Byte Block Sizes", /* 36h */
7440 "Compatibility Error: Volume Type Check Failed", /* 37h */
7441 "Compatibility Error: Volume Type is "
7442 "Unsupported by FW", /* 38h */
7443 "Compatibility Error: Disk Drive too Small for "
7444 "use in Volume", /* 39h */
7445 "Compatibility Error: Phys Disk for Create "
7446 "Volume not Found", /* 3Ah */
7447 "Compatibility Error: Too Many or too Few "
7448 "Disks for Volume Type", /* 3Bh */
7449 "Compatibility Error: Disk stripe Sizes "
7450 "Must be 64KB", /* 3Ch */
7451 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
7454 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7456 * mpt_sas_log_info - Log information returned from SAS IOC.
7457 * @ioc: Pointer to MPT_ADAPTER structure
7458 * @log_info: U32 LogInfo reply word from the IOC
7460 * Refer to lsi/mpi_log_sas.h.
7463 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
7465 union loginfo_type {
7474 union loginfo_type sas_loginfo;
7475 char *originator_desc = NULL;
7476 char *code_desc = NULL;
7477 char *sub_code_desc = NULL;
7479 sas_loginfo.loginfo = log_info;
7480 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
7481 (sas_loginfo.dw.originator < ARRAY_SIZE(originator_str)))
7484 originator_desc = originator_str[sas_loginfo.dw.originator];
7486 switch (sas_loginfo.dw.originator) {
7489 if (sas_loginfo.dw.code <
7490 ARRAY_SIZE(iop_code_str))
7491 code_desc = iop_code_str[sas_loginfo.dw.code];
7494 if (sas_loginfo.dw.code <
7495 ARRAY_SIZE(pl_code_str))
7496 code_desc = pl_code_str[sas_loginfo.dw.code];
7499 if (sas_loginfo.dw.code >=
7500 ARRAY_SIZE(ir_code_str))
7502 code_desc = ir_code_str[sas_loginfo.dw.code];
7503 if (sas_loginfo.dw.subcode >=
7504 ARRAY_SIZE(raid_sub_code_str))
7506 if (sas_loginfo.dw.code == 0)
7508 raid_sub_code_str[sas_loginfo.dw.subcode];
7514 if (sub_code_desc != NULL)
7515 printk(MYIOC_s_INFO_FMT
7516 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7518 ioc->name, log_info, originator_desc, code_desc,
7520 else if (code_desc != NULL)
7521 printk(MYIOC_s_INFO_FMT
7522 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7523 " SubCode(0x%04x)\n",
7524 ioc->name, log_info, originator_desc, code_desc,
7525 sas_loginfo.dw.subcode);
7527 printk(MYIOC_s_INFO_FMT
7528 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
7529 " SubCode(0x%04x)\n",
7530 ioc->name, log_info, originator_desc,
7531 sas_loginfo.dw.code, sas_loginfo.dw.subcode);
7534 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7536 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
7537 * @ioc: Pointer to MPT_ADAPTER structure
7538 * @ioc_status: U32 IOCStatus word from IOC
7539 * @mf: Pointer to MPT request frame
7541 * Refer to lsi/mpi.h.
7544 mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7546 Config_t *pReq = (Config_t *)mf;
7547 char extend_desc[EVENT_DESCR_STR_SZ];
7552 if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
7553 page_type = pReq->ExtPageType;
7555 page_type = pReq->Header.PageType;
7558 * ignore invalid page messages for GET_NEXT_HANDLE
7560 form = le32_to_cpu(pReq->PageAddress);
7561 if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
7562 if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
7563 page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
7564 page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
7565 if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
7566 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
7569 if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
7570 if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
7571 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
7575 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
7576 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
7577 page_type, pReq->Header.PageNumber, pReq->Action, form);
7579 switch (ioc_status) {
7581 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7582 desc = "Config Page Invalid Action";
7585 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7586 desc = "Config Page Invalid Type";
7589 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7590 desc = "Config Page Invalid Page";
7593 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7594 desc = "Config Page Invalid Data";
7597 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7598 desc = "Config Page No Defaults";
7601 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7602 desc = "Config Page Can't Commit";
7609 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s: %s\n",
7610 ioc->name, ioc_status, desc, extend_desc));
7614 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
7615 * @ioc: Pointer to MPT_ADAPTER structure
7616 * @ioc_status: U32 IOCStatus word from IOC
7617 * @mf: Pointer to MPT request frame
7619 * Refer to lsi/mpi.h.
7622 mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7624 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
7629 /****************************************************************************/
7630 /* Common IOCStatus values for all replies */
7631 /****************************************************************************/
7633 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
7634 desc = "Invalid Function";
7637 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
7641 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
7642 desc = "Invalid SGL";
7645 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
7646 desc = "Internal Error";
7649 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
7653 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
7654 desc = "Insufficient Resources";
7657 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
7658 desc = "Invalid Field";
7661 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
7662 desc = "Invalid State";
7665 /****************************************************************************/
7666 /* Config IOCStatus values */
7667 /****************************************************************************/
7669 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7670 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7671 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7672 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7673 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7674 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7675 mpt_iocstatus_info_config(ioc, status, mf);
7678 /****************************************************************************/
7679 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
7681 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
7683 /****************************************************************************/
7685 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
7686 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
7687 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
7688 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
7689 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
7690 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
7691 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
7692 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
7693 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
7694 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
7695 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
7696 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
7697 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
7700 /****************************************************************************/
7701 /* SCSI Target values */
7702 /****************************************************************************/
7704 case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
7705 desc = "Target: Priority IO";
7708 case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
7709 desc = "Target: Invalid Port";
7712 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
7713 desc = "Target Invalid IO Index:";
7716 case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
7717 desc = "Target: Aborted";
7720 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
7721 desc = "Target: No Conn Retryable";
7724 case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
7725 desc = "Target: No Connection";
7728 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
7729 desc = "Target: Transfer Count Mismatch";
7732 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
7733 desc = "Target: STS Data not Sent";
7736 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
7737 desc = "Target: Data Offset Error";
7740 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
7741 desc = "Target: Too Much Write Data";
7744 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
7745 desc = "Target: IU Too Short";
7748 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
7749 desc = "Target: ACK NAK Timeout";
7752 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
7753 desc = "Target: Nak Received";
7756 /****************************************************************************/
7757 /* Fibre Channel Direct Access values */
7758 /****************************************************************************/
7760 case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
7761 desc = "FC: Aborted";
7764 case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
7765 desc = "FC: RX ID Invalid";
7768 case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
7769 desc = "FC: DID Invalid";
7772 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
7773 desc = "FC: Node Logged Out";
7776 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
7777 desc = "FC: Exchange Canceled";
7780 /****************************************************************************/
7782 /****************************************************************************/
7784 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
7785 desc = "LAN: Device not Found";
7788 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
7789 desc = "LAN: Device Failure";
7792 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
7793 desc = "LAN: Transmit Error";
7796 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
7797 desc = "LAN: Transmit Aborted";
7800 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
7801 desc = "LAN: Receive Error";
7804 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
7805 desc = "LAN: Receive Aborted";
7808 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
7809 desc = "LAN: Partial Packet";
7812 case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
7813 desc = "LAN: Canceled";
7816 /****************************************************************************/
7817 /* Serial Attached SCSI values */
7818 /****************************************************************************/
7820 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
7821 desc = "SAS: SMP Request Failed";
7824 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
7825 desc = "SAS: SMP Data Overrun";
7836 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s\n",
7837 ioc->name, status, desc));
7840 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7841 EXPORT_SYMBOL(mpt_attach);
7842 EXPORT_SYMBOL(mpt_detach);
7844 EXPORT_SYMBOL(mpt_resume);
7845 EXPORT_SYMBOL(mpt_suspend);
7847 EXPORT_SYMBOL(ioc_list);
7848 EXPORT_SYMBOL(mpt_register);
7849 EXPORT_SYMBOL(mpt_deregister);
7850 EXPORT_SYMBOL(mpt_event_register);
7851 EXPORT_SYMBOL(mpt_event_deregister);
7852 EXPORT_SYMBOL(mpt_reset_register);
7853 EXPORT_SYMBOL(mpt_reset_deregister);
7854 EXPORT_SYMBOL(mpt_device_driver_register);
7855 EXPORT_SYMBOL(mpt_device_driver_deregister);
7856 EXPORT_SYMBOL(mpt_get_msg_frame);
7857 EXPORT_SYMBOL(mpt_put_msg_frame);
7858 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri);
7859 EXPORT_SYMBOL(mpt_free_msg_frame);
7860 EXPORT_SYMBOL(mpt_send_handshake_request);
7861 EXPORT_SYMBOL(mpt_verify_adapter);
7862 EXPORT_SYMBOL(mpt_GetIocState);
7863 EXPORT_SYMBOL(mpt_print_ioc_summary);
7864 EXPORT_SYMBOL(mpt_HardResetHandler);
7865 EXPORT_SYMBOL(mpt_config);
7866 EXPORT_SYMBOL(mpt_findImVolumes);
7867 EXPORT_SYMBOL(mpt_alloc_fw_memory);
7868 EXPORT_SYMBOL(mpt_free_fw_memory);
7869 EXPORT_SYMBOL(mptbase_sas_persist_operation);
7870 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
7872 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7874 * fusion_init - Fusion MPT base driver initialization routine.
7876 * Returns 0 for success, non-zero for failure.
7883 show_mptmod_ver(my_NAME, my_VERSION);
7884 printk(KERN_INFO COPYRIGHT "\n");
7886 for (cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
7887 MptCallbacks[cb_idx] = NULL;
7888 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
7889 MptEvHandlers[cb_idx] = NULL;
7890 MptResetHandlers[cb_idx] = NULL;
7893 /* Register ourselves (mptbase) in order to facilitate
7894 * EventNotification handling.
7896 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
7898 /* Register for hard reset handling callbacks.
7900 mpt_reset_register(mpt_base_index, mpt_ioc_reset);
7902 #ifdef CONFIG_PROC_FS
7903 (void) procmpt_create();
7908 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7910 * fusion_exit - Perform driver unload cleanup.
7912 * This routine frees all resources associated with each MPT adapter
7913 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
7919 mpt_reset_deregister(mpt_base_index);
7921 #ifdef CONFIG_PROC_FS
7926 module_init(fusion_init);
7927 module_exit(fusion_exit);