2 * linux/drivers/message/fusion/mptbase.c
3 * This is the Fusion MPT base driver which supports multiple
4 * (SCSI + LAN) specialized protocol drivers.
5 * For use with LSI PCI chip/adapter(s)
6 * running LSI Fusion MPT (Message Passing Technology) firmware.
8 * Copyright (c) 1999-2008 LSI Corporation
9 * (mailto:DL-MPTFusionLinux@lsi.com)
12 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; version 2 of the License.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
24 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
25 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
26 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
27 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
28 solely responsible for determining the appropriateness of using and
29 distributing the Program and assumes all risks associated with its
30 exercise of rights under this Agreement, including but not limited to
31 the risks and costs of program errors, damage to or loss of data,
32 programs or equipment, and unavailability or interruption of operations.
34 DISCLAIMER OF LIABILITY
35 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
36 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
38 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
39 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
40 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
41 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
43 You should have received a copy of the GNU General Public License
44 along with this program; if not, write to the Free Software
45 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
47 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
49 #include <linux/kernel.h>
50 #include <linux/module.h>
51 #include <linux/errno.h>
52 #include <linux/init.h>
53 #include <linux/slab.h>
54 #include <linux/types.h>
55 #include <linux/pci.h>
56 #include <linux/kdev_t.h>
57 #include <linux/blkdev.h>
58 #include <linux/delay.h>
59 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
60 #include <linux/dma-mapping.h>
67 #include "lsi/mpi_log_fc.h"
69 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
70 #define my_NAME "Fusion MPT base driver"
71 #define my_VERSION MPT_LINUX_VERSION_COMMON
72 #define MYNAM "mptbase"
74 MODULE_AUTHOR(MODULEAUTHOR);
75 MODULE_DESCRIPTION(my_NAME);
76 MODULE_LICENSE("GPL");
77 MODULE_VERSION(my_VERSION);
83 static int mpt_msi_enable_spi;
84 module_param(mpt_msi_enable_spi, int, 0);
85 MODULE_PARM_DESC(mpt_msi_enable_spi, " Enable MSI Support for SPI \
86 controllers (default=0)");
88 static int mpt_msi_enable_fc;
89 module_param(mpt_msi_enable_fc, int, 0);
90 MODULE_PARM_DESC(mpt_msi_enable_fc, " Enable MSI Support for FC \
91 controllers (default=0)");
93 static int mpt_msi_enable_sas;
94 module_param(mpt_msi_enable_sas, int, 0);
95 MODULE_PARM_DESC(mpt_msi_enable_sas, " Enable MSI Support for SAS \
96 controllers (default=0)");
99 static int mpt_channel_mapping;
100 module_param(mpt_channel_mapping, int, 0);
101 MODULE_PARM_DESC(mpt_channel_mapping, " Mapping id's to channels (default=0)");
103 static int mpt_debug_level;
104 static int mpt_set_debug_level(const char *val, struct kernel_param *kp);
105 module_param_call(mpt_debug_level, mpt_set_debug_level, param_get_int,
106 &mpt_debug_level, 0600);
107 MODULE_PARM_DESC(mpt_debug_level, " debug level - refer to mptdebug.h \
110 int mpt_fwfault_debug;
111 EXPORT_SYMBOL(mpt_fwfault_debug);
112 module_param_call(mpt_fwfault_debug, param_set_int, param_get_int,
113 &mpt_fwfault_debug, 0600);
114 MODULE_PARM_DESC(mpt_fwfault_debug, "Enable detection of Firmware fault"
115 " and halt Firmware on fault - (default=0)");
120 static int mfcounter = 0;
121 #define PRINT_MF_COUNT 20000
124 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
129 static struct proc_dir_entry *mpt_proc_root_dir;
131 #define WHOINIT_UNKNOWN 0xAA
133 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
137 /* Adapter link list */
139 /* Callback lookup table */
140 static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
141 /* Protocol driver class lookup table */
142 static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
143 /* Event handler lookup table */
144 static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
145 /* Reset handler lookup table */
146 static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
147 static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
151 * Driver Callback Index's
153 static u8 mpt_base_index = MPT_MAX_PROTOCOL_DRIVERS;
154 static u8 last_drv_idx;
156 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
160 static irqreturn_t mpt_interrupt(int irq, void *bus_id);
161 static int mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
162 MPT_FRAME_HDR *reply);
163 static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
164 u32 *req, int replyBytes, u16 *u16reply, int maxwait,
166 static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
167 static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
168 static void mpt_adapter_disable(MPT_ADAPTER *ioc);
169 static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
171 static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
172 static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
173 static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
174 static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
175 static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
176 static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
177 static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
178 static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
179 static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
180 static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
181 static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
182 static int PrimeIocFifos(MPT_ADAPTER *ioc);
183 static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
184 static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
185 static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
186 static int GetLanConfigPages(MPT_ADAPTER *ioc);
187 static int GetIoUnitPage2(MPT_ADAPTER *ioc);
188 int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
189 static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
190 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
191 static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
192 static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
193 static void mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc);
194 static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch,
196 static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
197 static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
198 static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
200 #ifdef CONFIG_PROC_FS
201 static int procmpt_summary_read(char *buf, char **start, off_t offset,
202 int request, int *eof, void *data);
203 static int procmpt_version_read(char *buf, char **start, off_t offset,
204 int request, int *eof, void *data);
205 static int procmpt_iocinfo_read(char *buf, char **start, off_t offset,
206 int request, int *eof, void *data);
208 static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
210 static int ProcessEventNotification(MPT_ADAPTER *ioc,
211 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->ioc_reset_in_progress || !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->taskmgmt_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->taskmgmt_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 * mptbase_reply - MPT base driver's callback routine
561 * @ioc: Pointer to MPT_ADAPTER structure
562 * @req: 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 mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
575 EventNotificationReply_t *pEventReply;
580 switch (reply->u.hdr.Function) {
581 case MPI_FUNCTION_EVENT_NOTIFICATION:
582 pEventReply = (EventNotificationReply_t *)reply;
584 ProcessEventNotification(ioc, pEventReply, &evHandlers);
585 event = le32_to_cpu(pEventReply->Event) & 0xFF;
586 if (pEventReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)
588 if (event != MPI_EVENT_EVENT_CHANGE)
590 case MPI_FUNCTION_CONFIG:
591 case MPI_FUNCTION_SAS_IO_UNIT_CONTROL:
592 ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
594 ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
595 memcpy(ioc->mptbase_cmds.reply, reply,
596 min(MPT_DEFAULT_FRAME_SIZE,
597 4 * reply->u.reply.MsgLength));
599 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) {
600 ioc->mptbase_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
601 complete(&ioc->mptbase_cmds.done);
604 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_FREE_MF)
607 case MPI_FUNCTION_EVENT_ACK:
608 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
609 "EventAck reply received\n", ioc->name));
612 printk(MYIOC_s_ERR_FMT
613 "Unexpected msg function (=%02Xh) reply received!\n",
614 ioc->name, reply->u.hdr.Function);
619 * Conditionally tell caller to free the original
620 * EventNotification/EventAck/unexpected request frame!
625 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
627 * mpt_register - Register protocol-specific main callback handler.
628 * @cbfunc: callback function pointer
629 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
631 * This routine is called by a protocol-specific driver (SCSI host,
632 * LAN, SCSI target) to register its reply callback routine. Each
633 * protocol-specific driver must do this before it will be able to
634 * use any IOC resources, such as obtaining request frames.
636 * NOTES: The SCSI protocol driver currently calls this routine thrice
637 * in order to register separate callbacks; one for "normal" SCSI IO;
638 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
640 * Returns u8 valued "handle" in the range (and S.O.D. order)
641 * {N,...,7,6,5,...,1} if successful.
642 * A return value of MPT_MAX_PROTOCOL_DRIVERS (including zero!) should be
643 * considered an error by the caller.
646 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
649 last_drv_idx = MPT_MAX_PROTOCOL_DRIVERS;
652 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
653 * (slot/handle 0 is reserved!)
655 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
656 if (MptCallbacks[cb_idx] == NULL) {
657 MptCallbacks[cb_idx] = cbfunc;
658 MptDriverClass[cb_idx] = dclass;
659 MptEvHandlers[cb_idx] = NULL;
660 last_drv_idx = cb_idx;
668 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
670 * mpt_deregister - Deregister a protocol drivers resources.
671 * @cb_idx: previously registered callback handle
673 * Each protocol-specific driver should call this routine when its
674 * module is unloaded.
677 mpt_deregister(u8 cb_idx)
679 if (cb_idx && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
680 MptCallbacks[cb_idx] = NULL;
681 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
682 MptEvHandlers[cb_idx] = NULL;
688 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
690 * mpt_event_register - Register protocol-specific event callback handler.
691 * @cb_idx: previously registered (via mpt_register) callback handle
692 * @ev_cbfunc: callback function
694 * This routine can be called by one or more protocol-specific drivers
695 * if/when they choose to be notified of MPT events.
697 * Returns 0 for success.
700 mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc)
702 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
705 MptEvHandlers[cb_idx] = ev_cbfunc;
709 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
711 * mpt_event_deregister - Deregister protocol-specific event callback handler
712 * @cb_idx: previously registered callback handle
714 * Each protocol-specific driver should call this routine
715 * when it does not (or can no longer) handle events,
716 * or when its module is unloaded.
719 mpt_event_deregister(u8 cb_idx)
721 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
724 MptEvHandlers[cb_idx] = NULL;
727 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
729 * mpt_reset_register - Register protocol-specific IOC reset handler.
730 * @cb_idx: previously registered (via mpt_register) callback handle
731 * @reset_func: reset function
733 * This routine can be called by one or more protocol-specific drivers
734 * if/when they choose to be notified of IOC resets.
736 * Returns 0 for success.
739 mpt_reset_register(u8 cb_idx, MPT_RESETHANDLER reset_func)
741 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
744 MptResetHandlers[cb_idx] = reset_func;
748 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
750 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
751 * @cb_idx: previously registered callback handle
753 * Each protocol-specific driver should call this routine
754 * when it does not (or can no longer) handle IOC reset handling,
755 * or when its module is unloaded.
758 mpt_reset_deregister(u8 cb_idx)
760 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
763 MptResetHandlers[cb_idx] = NULL;
766 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
768 * mpt_device_driver_register - Register device driver hooks
769 * @dd_cbfunc: driver callbacks struct
770 * @cb_idx: MPT protocol driver index
773 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, u8 cb_idx)
776 const struct pci_device_id *id;
778 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
781 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
783 /* call per pci device probe entry point */
784 list_for_each_entry(ioc, &ioc_list, list) {
785 id = ioc->pcidev->driver ?
786 ioc->pcidev->driver->id_table : NULL;
787 if (dd_cbfunc->probe)
788 dd_cbfunc->probe(ioc->pcidev, id);
794 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
796 * mpt_device_driver_deregister - DeRegister device driver hooks
797 * @cb_idx: MPT protocol driver index
800 mpt_device_driver_deregister(u8 cb_idx)
802 struct mpt_pci_driver *dd_cbfunc;
805 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
808 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
810 list_for_each_entry(ioc, &ioc_list, list) {
811 if (dd_cbfunc->remove)
812 dd_cbfunc->remove(ioc->pcidev);
815 MptDeviceDriverHandlers[cb_idx] = NULL;
819 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
821 * mpt_get_msg_frame - Obtain an MPT request frame from the pool
822 * @cb_idx: Handle of registered MPT protocol driver
823 * @ioc: Pointer to MPT adapter structure
825 * Obtain an MPT request frame from the pool (of 1024) that are
826 * allocated per MPT adapter.
828 * Returns pointer to a MPT request frame or %NULL if none are available
829 * or IOC is not active.
832 mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc)
836 u16 req_idx; /* Request index */
838 /* validate handle and ioc identifier */
842 printk(MYIOC_s_WARN_FMT "IOC Not Active! mpt_get_msg_frame "
843 "returning NULL!\n", ioc->name);
846 /* If interrupts are not attached, do not return a request frame */
850 spin_lock_irqsave(&ioc->FreeQlock, flags);
851 if (!list_empty(&ioc->FreeQ)) {
854 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
855 u.frame.linkage.list);
856 list_del(&mf->u.frame.linkage.list);
857 mf->u.frame.linkage.arg1 = 0;
858 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
859 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
861 req_idx = req_offset / ioc->req_sz;
862 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
863 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
864 /* Default, will be changed if necessary in SG generation */
865 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame;
872 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
876 printk(MYIOC_s_WARN_FMT "IOC Active. No free Msg Frames! "
877 "Count 0x%x Max 0x%x\n", ioc->name, ioc->mfcnt,
880 if (mfcounter == PRINT_MF_COUNT)
881 printk(MYIOC_s_INFO_FMT "MF Count 0x%x Max 0x%x \n", ioc->name,
882 ioc->mfcnt, ioc->req_depth);
885 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_get_msg_frame(%d,%d), got mf=%p\n",
886 ioc->name, cb_idx, ioc->id, mf));
890 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
892 * mpt_put_msg_frame - Send a protocol-specific MPT request frame to an IOC
893 * @cb_idx: Handle of registered MPT protocol driver
894 * @ioc: Pointer to MPT adapter structure
895 * @mf: Pointer to MPT request frame
897 * This routine posts an MPT request frame to the request post FIFO of a
898 * specific MPT adapter.
901 mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
905 u16 req_idx; /* Request index */
907 /* ensure values are reset properly! */
908 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
909 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
911 req_idx = req_offset / ioc->req_sz;
912 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
913 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
915 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
917 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
918 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d "
919 "RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx,
920 ioc->RequestNB[req_idx]));
921 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
925 * mpt_put_msg_frame_hi_pri - Send a hi-pri protocol-specific MPT request frame
926 * @cb_idx: Handle of registered MPT protocol driver
927 * @ioc: Pointer to MPT adapter structure
928 * @mf: Pointer to MPT request frame
930 * Send a protocol-specific MPT request frame to an IOC using
931 * hi-priority request queue.
933 * This routine posts an MPT request frame to the request post FIFO of a
934 * specific MPT adapter.
937 mpt_put_msg_frame_hi_pri(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
941 u16 req_idx; /* Request index */
943 /* ensure values are reset properly! */
944 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
945 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
946 req_idx = req_offset / ioc->req_sz;
947 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
948 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
950 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
952 mf_dma_addr = (ioc->req_frames_low_dma + req_offset);
953 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d\n",
954 ioc->name, mf_dma_addr, req_idx));
955 CHIPREG_WRITE32(&ioc->chip->RequestHiPriFifo, mf_dma_addr);
958 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
960 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
961 * @ioc: Pointer to MPT adapter structure
962 * @mf: Pointer to MPT request frame
964 * This routine places a MPT request frame back on the MPT adapter's
968 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
972 /* Put Request back on FreeQ! */
973 spin_lock_irqsave(&ioc->FreeQlock, flags);
974 if (cpu_to_le32(mf->u.frame.linkage.arg1) == 0xdeadbeaf)
976 /* signature to know if this mf is freed */
977 mf->u.frame.linkage.arg1 = cpu_to_le32(0xdeadbeaf);
978 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
983 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
986 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
988 * mpt_add_sge - Place a simple 32 bit SGE at address pAddr.
989 * @pAddr: virtual address for SGE
990 * @flagslength: SGE flags and data transfer length
991 * @dma_addr: Physical address
993 * This routine places a MPT request frame back on the MPT adapter's
997 mpt_add_sge(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
999 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
1000 pSge->FlagsLength = cpu_to_le32(flagslength);
1001 pSge->Address = cpu_to_le32(dma_addr);
1005 * mpt_add_sge_64bit - Place a simple 64 bit SGE at address pAddr.
1006 * @pAddr: virtual address for SGE
1007 * @flagslength: SGE flags and data transfer length
1008 * @dma_addr: Physical address
1010 * This routine places a MPT request frame back on the MPT adapter's
1014 mpt_add_sge_64bit(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1016 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1017 pSge->Address.Low = cpu_to_le32
1018 (lower_32_bits((unsigned long)(dma_addr)));
1019 pSge->Address.High = cpu_to_le32
1020 (upper_32_bits((unsigned long)dma_addr));
1021 pSge->FlagsLength = cpu_to_le32
1022 ((flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1026 * mpt_add_sge_64bit_1078 - Place a simple 64 bit SGE at address pAddr
1027 * (1078 workaround).
1028 * @pAddr: virtual address for SGE
1029 * @flagslength: SGE flags and data transfer length
1030 * @dma_addr: Physical address
1032 * This routine places a MPT request frame back on the MPT adapter's
1036 mpt_add_sge_64bit_1078(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1038 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1041 pSge->Address.Low = cpu_to_le32
1042 (lower_32_bits((unsigned long)(dma_addr)));
1043 tmp = (u32)(upper_32_bits((unsigned long)dma_addr));
1046 * 1078 errata workaround for the 36GB limitation
1048 if ((((u64)dma_addr + MPI_SGE_LENGTH(flagslength)) >> 32) == 9) {
1050 MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_LOCAL_ADDRESS);
1052 if (mpt_debug_level & MPT_DEBUG_36GB_MEM)
1053 printk(KERN_DEBUG "1078 P0M2 addressing for "
1054 "addr = 0x%llx len = %d\n",
1055 (unsigned long long)dma_addr,
1056 MPI_SGE_LENGTH(flagslength));
1059 pSge->Address.High = cpu_to_le32(tmp);
1060 pSge->FlagsLength = cpu_to_le32(
1061 (flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1064 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1066 * mpt_add_chain - Place a 32 bit chain SGE at address pAddr.
1067 * @pAddr: virtual address for SGE
1068 * @next: nextChainOffset value (u32's)
1069 * @length: length of next SGL segment
1070 * @dma_addr: Physical address
1074 mpt_add_chain(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1076 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
1077 pChain->Length = cpu_to_le16(length);
1078 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT;
1079 pChain->NextChainOffset = next;
1080 pChain->Address = cpu_to_le32(dma_addr);
1083 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1085 * mpt_add_chain_64bit - Place a 64 bit chain SGE at address pAddr.
1086 * @pAddr: virtual address for SGE
1087 * @next: nextChainOffset value (u32's)
1088 * @length: length of next SGL segment
1089 * @dma_addr: Physical address
1093 mpt_add_chain_64bit(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1095 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
1096 u32 tmp = dma_addr & 0xFFFFFFFF;
1098 pChain->Length = cpu_to_le16(length);
1099 pChain->Flags = (MPI_SGE_FLAGS_CHAIN_ELEMENT |
1100 MPI_SGE_FLAGS_64_BIT_ADDRESSING);
1102 pChain->NextChainOffset = next;
1104 pChain->Address.Low = cpu_to_le32(tmp);
1105 tmp = (u32)(upper_32_bits((unsigned long)dma_addr));
1106 pChain->Address.High = cpu_to_le32(tmp);
1109 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1111 * mpt_send_handshake_request - Send MPT request via doorbell handshake method.
1112 * @cb_idx: Handle of registered MPT protocol driver
1113 * @ioc: Pointer to MPT adapter structure
1114 * @reqBytes: Size of the request in bytes
1115 * @req: Pointer to MPT request frame
1116 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1118 * This routine is used exclusively to send MptScsiTaskMgmt
1119 * requests since they are required to be sent via doorbell handshake.
1121 * NOTE: It is the callers responsibility to byte-swap fields in the
1122 * request which are greater than 1 byte in size.
1124 * Returns 0 for success, non-zero for failure.
1127 mpt_send_handshake_request(u8 cb_idx, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
1133 /* State is known to be good upon entering
1134 * this function so issue the bus reset
1139 * Emulate what mpt_put_msg_frame() does /wrt to sanity
1140 * setting cb_idx/req_idx. But ONLY if this request
1141 * is in proper (pre-alloc'd) request buffer range...
1143 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
1144 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
1145 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
1146 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
1147 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
1150 /* Make sure there are no doorbells */
1151 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1153 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1154 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
1155 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
1157 /* Wait for IOC doorbell int */
1158 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
1162 /* Read doorbell and check for active bit */
1163 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
1166 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_send_handshake_request start, WaitCnt=%d\n",
1169 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1171 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1175 /* Send request via doorbell handshake */
1176 req_as_bytes = (u8 *) req;
1177 for (ii = 0; ii < reqBytes/4; ii++) {
1180 word = ((req_as_bytes[(ii*4) + 0] << 0) |
1181 (req_as_bytes[(ii*4) + 1] << 8) |
1182 (req_as_bytes[(ii*4) + 2] << 16) |
1183 (req_as_bytes[(ii*4) + 3] << 24));
1184 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
1185 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1191 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
1196 /* Make sure there are no doorbells */
1197 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1202 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1204 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
1205 * @ioc: Pointer to MPT adapter structure
1206 * @access_control_value: define bits below
1207 * @sleepFlag: Specifies whether the process can sleep
1209 * Provides mechanism for the host driver to control the IOC's
1210 * Host Page Buffer access.
1212 * Access Control Value - bits[15:12]
1214 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1215 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1216 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1218 * Returns 0 for success, non-zero for failure.
1222 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1226 /* return if in use */
1227 if (CHIPREG_READ32(&ioc->chip->Doorbell)
1228 & MPI_DOORBELL_ACTIVE)
1231 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1233 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1234 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1235 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1236 (access_control_value<<12)));
1238 /* Wait for IOC to clear Doorbell Status bit */
1239 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1245 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1247 * mpt_host_page_alloc - allocate system memory for the fw
1248 * @ioc: Pointer to pointer to IOC adapter
1249 * @ioc_init: Pointer to ioc init config page
1251 * If we already allocated memory in past, then resend the same pointer.
1252 * Returns 0 for success, non-zero for failure.
1255 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1259 u32 host_page_buffer_sz=0;
1261 if(!ioc->HostPageBuffer) {
1263 host_page_buffer_sz =
1264 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1266 if(!host_page_buffer_sz)
1267 return 0; /* fw doesn't need any host buffers */
1269 /* spin till we get enough memory */
1270 while(host_page_buffer_sz > 0) {
1272 if((ioc->HostPageBuffer = pci_alloc_consistent(
1274 host_page_buffer_sz,
1275 &ioc->HostPageBuffer_dma)) != NULL) {
1277 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1278 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1279 ioc->name, ioc->HostPageBuffer,
1280 (u32)ioc->HostPageBuffer_dma,
1281 host_page_buffer_sz));
1282 ioc->alloc_total += host_page_buffer_sz;
1283 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1287 host_page_buffer_sz -= (4*1024);
1291 if(!ioc->HostPageBuffer) {
1292 printk(MYIOC_s_ERR_FMT
1293 "Failed to alloc memory for host_page_buffer!\n",
1298 psge = (char *)&ioc_init->HostPageBufferSGE;
1299 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1300 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1301 MPI_SGE_FLAGS_32_BIT_ADDRESSING |
1302 MPI_SGE_FLAGS_HOST_TO_IOC |
1303 MPI_SGE_FLAGS_END_OF_BUFFER;
1304 if (sizeof(dma_addr_t) == sizeof(u64)) {
1305 flags_length |= MPI_SGE_FLAGS_64_BIT_ADDRESSING;
1307 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1308 flags_length |= ioc->HostPageBuffer_sz;
1309 ioc->add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1310 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1315 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1317 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1318 * @iocid: IOC unique identifier (integer)
1319 * @iocpp: Pointer to pointer to IOC adapter
1321 * Given a unique IOC identifier, set pointer to the associated MPT
1322 * adapter structure.
1324 * Returns iocid and sets iocpp if iocid is found.
1325 * Returns -1 if iocid is not found.
1328 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1332 list_for_each_entry(ioc,&ioc_list,list) {
1333 if (ioc->id == iocid) {
1344 * mpt_get_product_name - returns product string
1345 * @vendor: pci vendor id
1346 * @device: pci device id
1347 * @revision: pci revision id
1348 * @prod_name: string returned
1350 * Returns product string displayed when driver loads,
1351 * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1355 mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name)
1357 char *product_str = NULL;
1359 if (vendor == PCI_VENDOR_ID_BROCADE) {
1362 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1366 product_str = "BRE040 A0";
1369 product_str = "BRE040 A1";
1372 product_str = "BRE040";
1382 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1383 product_str = "LSIFC909 B1";
1385 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1386 product_str = "LSIFC919 B0";
1388 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1389 product_str = "LSIFC929 B0";
1391 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1392 if (revision < 0x80)
1393 product_str = "LSIFC919X A0";
1395 product_str = "LSIFC919XL A1";
1397 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1398 if (revision < 0x80)
1399 product_str = "LSIFC929X A0";
1401 product_str = "LSIFC929XL A1";
1403 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1404 product_str = "LSIFC939X A1";
1406 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1407 product_str = "LSIFC949X A1";
1409 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1413 product_str = "LSIFC949E A0";
1416 product_str = "LSIFC949E A1";
1419 product_str = "LSIFC949E";
1423 case MPI_MANUFACTPAGE_DEVID_53C1030:
1427 product_str = "LSI53C1030 A0";
1430 product_str = "LSI53C1030 B0";
1433 product_str = "LSI53C1030 B1";
1436 product_str = "LSI53C1030 B2";
1439 product_str = "LSI53C1030 C0";
1442 product_str = "LSI53C1030T A0";
1445 product_str = "LSI53C1030T A2";
1448 product_str = "LSI53C1030T A3";
1451 product_str = "LSI53C1020A A1";
1454 product_str = "LSI53C1030";
1458 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1462 product_str = "LSI53C1035 A2";
1465 product_str = "LSI53C1035 B0";
1468 product_str = "LSI53C1035";
1472 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1476 product_str = "LSISAS1064 A1";
1479 product_str = "LSISAS1064 A2";
1482 product_str = "LSISAS1064 A3";
1485 product_str = "LSISAS1064 A4";
1488 product_str = "LSISAS1064";
1492 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1496 product_str = "LSISAS1064E A0";
1499 product_str = "LSISAS1064E B0";
1502 product_str = "LSISAS1064E B1";
1505 product_str = "LSISAS1064E B2";
1508 product_str = "LSISAS1064E B3";
1511 product_str = "LSISAS1064E";
1515 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1519 product_str = "LSISAS1068 A0";
1522 product_str = "LSISAS1068 B0";
1525 product_str = "LSISAS1068 B1";
1528 product_str = "LSISAS1068";
1532 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1536 product_str = "LSISAS1068E A0";
1539 product_str = "LSISAS1068E B0";
1542 product_str = "LSISAS1068E B1";
1545 product_str = "LSISAS1068E B2";
1548 product_str = "LSISAS1068E B3";
1551 product_str = "LSISAS1068E";
1555 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1559 product_str = "LSISAS1078 A0";
1562 product_str = "LSISAS1078 B0";
1565 product_str = "LSISAS1078 C0";
1568 product_str = "LSISAS1078 C1";
1571 product_str = "LSISAS1078 C2";
1574 product_str = "LSISAS1078";
1582 sprintf(prod_name, "%s", product_str);
1586 * mpt_mapresources - map in memory mapped io
1587 * @ioc: Pointer to pointer to IOC adapter
1591 mpt_mapresources(MPT_ADAPTER *ioc)
1595 unsigned long mem_phys;
1601 struct pci_dev *pdev;
1604 ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
1605 if (pci_enable_device_mem(pdev)) {
1606 printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() "
1607 "failed\n", ioc->name);
1610 if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) {
1611 printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with "
1612 "MEM failed\n", ioc->name);
1616 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1618 if (sizeof(dma_addr_t) > 4) {
1619 const uint64_t required_mask = dma_get_required_mask
1621 if (required_mask > DMA_BIT_MASK(32)
1622 && !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
1623 && !pci_set_consistent_dma_mask(pdev,
1624 DMA_BIT_MASK(64))) {
1625 ioc->dma_mask = DMA_BIT_MASK(64);
1626 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1627 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1629 } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1630 && !pci_set_consistent_dma_mask(pdev,
1631 DMA_BIT_MASK(32))) {
1632 ioc->dma_mask = DMA_BIT_MASK(32);
1633 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1634 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1637 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1638 ioc->name, pci_name(pdev));
1642 if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1643 && !pci_set_consistent_dma_mask(pdev,
1644 DMA_BIT_MASK(32))) {
1645 ioc->dma_mask = DMA_BIT_MASK(32);
1646 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1647 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1650 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1651 ioc->name, pci_name(pdev));
1656 mem_phys = msize = 0;
1658 for (ii = 0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1659 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1662 /* Get I/O space! */
1663 port = pci_resource_start(pdev, ii);
1664 psize = pci_resource_len(pdev, ii);
1669 mem_phys = pci_resource_start(pdev, ii);
1670 msize = pci_resource_len(pdev, ii);
1673 ioc->mem_size = msize;
1676 /* Get logical ptr for PciMem0 space */
1677 /*mem = ioremap(mem_phys, msize);*/
1678 mem = ioremap(mem_phys, msize);
1680 printk(MYIOC_s_ERR_FMT ": ERROR - Unable to map adapter"
1681 " memory!\n", ioc->name);
1685 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %lx\n",
1686 ioc->name, mem, mem_phys));
1688 ioc->mem_phys = mem_phys;
1689 ioc->chip = (SYSIF_REGS __iomem *)mem;
1691 /* Save Port IO values in case we need to do downloadboot */
1692 ioc->pio_mem_phys = port;
1693 ioc->pio_chip = (SYSIF_REGS __iomem *)port;
1698 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1700 * mpt_attach - Install a PCI intelligent MPT adapter.
1701 * @pdev: Pointer to pci_dev structure
1702 * @id: PCI device ID information
1704 * This routine performs all the steps necessary to bring the IOC of
1705 * a MPT adapter to a OPERATIONAL state. This includes registering
1706 * memory regions, registering the interrupt, and allocating request
1707 * and reply memory pools.
1709 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1712 * Returns 0 for success, non-zero for failure.
1714 * TODO: Add support for polled controllers
1717 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1724 static int mpt_ids = 0;
1725 #ifdef CONFIG_PROC_FS
1726 struct proc_dir_entry *dent, *ent;
1729 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1731 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1735 ioc->id = mpt_ids++;
1736 sprintf(ioc->name, "ioc%d", ioc->id);
1737 dinitprintk(ioc, printk(KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1740 * set initial debug level
1741 * (refer to mptdebug.h)
1744 ioc->debug_level = mpt_debug_level;
1745 if (mpt_debug_level)
1746 printk(KERN_INFO "mpt_debug_level=%xh\n", mpt_debug_level);
1748 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name));
1751 if (mpt_mapresources(ioc)) {
1757 * Setting up proper handlers for scatter gather handling
1759 if (ioc->dma_mask == DMA_BIT_MASK(64)) {
1760 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
1761 ioc->add_sge = &mpt_add_sge_64bit_1078;
1763 ioc->add_sge = &mpt_add_sge_64bit;
1764 ioc->add_chain = &mpt_add_chain_64bit;
1765 ioc->sg_addr_size = 8;
1767 ioc->add_sge = &mpt_add_sge;
1768 ioc->add_chain = &mpt_add_chain;
1769 ioc->sg_addr_size = 4;
1771 ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
1773 ioc->alloc_total = sizeof(MPT_ADAPTER);
1774 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1775 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1779 spin_lock_init(&ioc->taskmgmt_lock);
1780 mutex_init(&ioc->internal_cmds.mutex);
1781 init_completion(&ioc->internal_cmds.done);
1782 mutex_init(&ioc->mptbase_cmds.mutex);
1783 init_completion(&ioc->mptbase_cmds.done);
1784 mutex_init(&ioc->taskmgmt_cmds.mutex);
1785 init_completion(&ioc->taskmgmt_cmds.done);
1787 /* Initialize the event logging.
1789 ioc->eventTypes = 0; /* None */
1790 ioc->eventContext = 0;
1791 ioc->eventLogSize = 0;
1799 ioc->cached_fw = NULL;
1801 /* Initilize SCSI Config Data structure
1803 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1805 /* Initialize the fc rport list head.
1807 INIT_LIST_HEAD(&ioc->fc_rports);
1809 /* Find lookup slot. */
1810 INIT_LIST_HEAD(&ioc->list);
1813 /* Initialize workqueue */
1814 INIT_DELAYED_WORK(&ioc->fault_reset_work, mpt_fault_reset_work);
1816 snprintf(ioc->reset_work_q_name, MPT_KOBJ_NAME_LEN,
1817 "mpt_poll_%d", ioc->id);
1819 create_singlethread_workqueue(ioc->reset_work_q_name);
1820 if (!ioc->reset_work_q) {
1821 printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n",
1823 pci_release_selected_regions(pdev, ioc->bars);
1828 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",
1829 ioc->name, &ioc->facts, &ioc->pfacts[0]));
1831 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1832 mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name);
1834 switch (pdev->device)
1836 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1837 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1838 ioc->errata_flag_1064 = 1;
1839 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1840 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1841 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1842 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1846 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1847 if (revision < XL_929) {
1848 /* 929X Chip Fix. Set Split transactions level
1849 * for PCIX. Set MOST bits to zero.
1851 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1853 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1855 /* 929XL Chip Fix. Set MMRBC to 0x08.
1857 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1859 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1864 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1865 /* 919X Chip Fix. Set Split transactions level
1866 * for PCIX. Set MOST bits to zero.
1868 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1870 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1874 case MPI_MANUFACTPAGE_DEVID_53C1030:
1875 /* 1030 Chip Fix. Disable Split transactions
1876 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1878 if (revision < C0_1030) {
1879 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1881 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1884 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1885 ioc->bus_type = SPI;
1888 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1889 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1890 ioc->errata_flag_1064 = 1;
1891 ioc->bus_type = SAS;
1894 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1895 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1896 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1897 ioc->bus_type = SAS;
1902 switch (ioc->bus_type) {
1905 ioc->msi_enable = mpt_msi_enable_sas;
1909 ioc->msi_enable = mpt_msi_enable_spi;
1913 ioc->msi_enable = mpt_msi_enable_fc;
1917 ioc->msi_enable = 0;
1920 if (ioc->errata_flag_1064)
1921 pci_disable_io_access(pdev);
1923 spin_lock_init(&ioc->FreeQlock);
1926 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1928 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1930 /* Set IOC ptr in the pcidev's driver data. */
1931 pci_set_drvdata(ioc->pcidev, ioc);
1933 /* Set lookup ptr. */
1934 list_add_tail(&ioc->list, &ioc_list);
1936 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1938 mpt_detect_bound_ports(ioc, pdev);
1940 INIT_LIST_HEAD(&ioc->fw_event_list);
1941 spin_lock_init(&ioc->fw_event_lock);
1942 snprintf(ioc->fw_event_q_name, MPT_KOBJ_NAME_LEN, "mpt/%d", ioc->id);
1943 ioc->fw_event_q = create_singlethread_workqueue(ioc->fw_event_q_name);
1945 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1947 printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",
1950 list_del(&ioc->list);
1952 ioc->alt_ioc->alt_ioc = NULL;
1953 iounmap(ioc->memmap);
1955 pci_release_selected_regions(pdev, ioc->bars);
1957 destroy_workqueue(ioc->reset_work_q);
1958 ioc->reset_work_q = NULL;
1961 pci_set_drvdata(pdev, NULL);
1965 /* call per device driver probe entry point */
1966 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
1967 if(MptDeviceDriverHandlers[cb_idx] &&
1968 MptDeviceDriverHandlers[cb_idx]->probe) {
1969 MptDeviceDriverHandlers[cb_idx]->probe(pdev,id);
1973 #ifdef CONFIG_PROC_FS
1975 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1977 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1979 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1981 ent->read_proc = procmpt_iocinfo_read;
1984 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1986 ent->read_proc = procmpt_summary_read;
1993 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
1994 msecs_to_jiffies(MPT_POLLING_INTERVAL));
1999 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2001 * mpt_detach - Remove a PCI intelligent MPT adapter.
2002 * @pdev: Pointer to pci_dev structure
2006 mpt_detach(struct pci_dev *pdev)
2008 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2011 unsigned long flags;
2012 struct workqueue_struct *wq;
2015 * Stop polling ioc for fault condition
2017 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2018 wq = ioc->reset_work_q;
2019 ioc->reset_work_q = NULL;
2020 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2021 cancel_delayed_work(&ioc->fault_reset_work);
2022 destroy_workqueue(wq);
2024 spin_lock_irqsave(&ioc->fw_event_lock, flags);
2025 wq = ioc->fw_event_q;
2026 ioc->fw_event_q = NULL;
2027 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2028 destroy_workqueue(wq);
2030 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
2031 remove_proc_entry(pname, NULL);
2032 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
2033 remove_proc_entry(pname, NULL);
2034 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
2035 remove_proc_entry(pname, NULL);
2037 /* call per device driver remove entry point */
2038 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
2039 if(MptDeviceDriverHandlers[cb_idx] &&
2040 MptDeviceDriverHandlers[cb_idx]->remove) {
2041 MptDeviceDriverHandlers[cb_idx]->remove(pdev);
2045 /* Disable interrupts! */
2046 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2049 synchronize_irq(pdev->irq);
2051 /* Clear any lingering interrupt */
2052 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2054 CHIPREG_READ32(&ioc->chip->IntStatus);
2056 mpt_adapter_dispose(ioc);
2058 pci_set_drvdata(pdev, NULL);
2061 /**************************************************************************
2065 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2067 * mpt_suspend - Fusion MPT base driver suspend routine.
2068 * @pdev: Pointer to pci_dev structure
2069 * @state: new state to enter
2072 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
2075 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2077 device_state = pci_choose_state(pdev, state);
2078 printk(MYIOC_s_INFO_FMT "pci-suspend: pdev=0x%p, slot=%s, Entering "
2079 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2082 /* put ioc into READY_STATE */
2083 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
2084 printk(MYIOC_s_ERR_FMT
2085 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
2088 /* disable interrupts */
2089 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2092 /* Clear any lingering interrupt */
2093 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2095 free_irq(ioc->pci_irq, ioc);
2096 if (ioc->msi_enable)
2097 pci_disable_msi(ioc->pcidev);
2099 pci_save_state(pdev);
2100 pci_disable_device(pdev);
2101 pci_release_selected_regions(pdev, ioc->bars);
2102 pci_set_power_state(pdev, device_state);
2106 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2108 * mpt_resume - Fusion MPT base driver resume routine.
2109 * @pdev: Pointer to pci_dev structure
2112 mpt_resume(struct pci_dev *pdev)
2114 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2115 u32 device_state = pdev->current_state;
2119 printk(MYIOC_s_INFO_FMT "pci-resume: pdev=0x%p, slot=%s, Previous "
2120 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2123 pci_set_power_state(pdev, PCI_D0);
2124 pci_enable_wake(pdev, PCI_D0, 0);
2125 pci_restore_state(pdev);
2127 err = mpt_mapresources(ioc);
2131 if (ioc->dma_mask == DMA_BIT_MASK(64)) {
2132 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
2133 ioc->add_sge = &mpt_add_sge_64bit_1078;
2135 ioc->add_sge = &mpt_add_sge_64bit;
2136 ioc->add_chain = &mpt_add_chain_64bit;
2137 ioc->sg_addr_size = 8;
2140 ioc->add_sge = &mpt_add_sge;
2141 ioc->add_chain = &mpt_add_chain;
2142 ioc->sg_addr_size = 4;
2144 ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
2146 printk(MYIOC_s_INFO_FMT "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
2147 ioc->name, (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
2148 CHIPREG_READ32(&ioc->chip->Doorbell));
2151 * Errata workaround for SAS pci express:
2152 * Upon returning to the D0 state, the contents of the doorbell will be
2153 * stale data, and this will incorrectly signal to the host driver that
2154 * the firmware is ready to process mpt commands. The workaround is
2155 * to issue a diagnostic reset.
2157 if (ioc->bus_type == SAS && (pdev->device ==
2158 MPI_MANUFACTPAGE_DEVID_SAS1068E || pdev->device ==
2159 MPI_MANUFACTPAGE_DEVID_SAS1064E)) {
2160 if (KickStart(ioc, 1, CAN_SLEEP) < 0) {
2161 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover\n",
2167 /* bring ioc to operational state */
2168 printk(MYIOC_s_INFO_FMT "Sending mpt_do_ioc_recovery\n", ioc->name);
2169 recovery_state = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
2171 if (recovery_state != 0)
2172 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover, "
2173 "error:[%x]\n", ioc->name, recovery_state);
2175 printk(MYIOC_s_INFO_FMT
2176 "pci-resume: success\n", ioc->name);
2184 mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase)
2186 if ((MptDriverClass[index] == MPTSPI_DRIVER &&
2187 ioc->bus_type != SPI) ||
2188 (MptDriverClass[index] == MPTFC_DRIVER &&
2189 ioc->bus_type != FC) ||
2190 (MptDriverClass[index] == MPTSAS_DRIVER &&
2191 ioc->bus_type != SAS))
2192 /* make sure we only call the relevant reset handler
2195 return (MptResetHandlers[index])(ioc, reset_phase);
2198 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2200 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
2201 * @ioc: Pointer to MPT adapter structure
2202 * @reason: Event word / reason
2203 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
2205 * This routine performs all the steps necessary to bring the IOC
2206 * to a OPERATIONAL state.
2208 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
2213 * -1 if failed to get board READY
2214 * -2 if READY but IOCFacts Failed
2215 * -3 if READY but PrimeIOCFifos Failed
2216 * -4 if READY but IOCInit Failed
2217 * -5 if failed to enable_device and/or request_selected_regions
2218 * -6 if failed to upload firmware
2221 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2223 int hard_reset_done = 0;
2224 int alt_ioc_ready = 0;
2231 int reset_alt_ioc_active = 0;
2232 int irq_allocated = 0;
2235 printk(MYIOC_s_INFO_FMT "Initiating %s\n", ioc->name,
2236 reason == MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
2238 /* Disable reply interrupts (also blocks FreeQ) */
2239 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2243 if (ioc->alt_ioc->active ||
2244 reason == MPT_HOSTEVENT_IOC_RECOVER) {
2245 reset_alt_ioc_active = 1;
2246 /* Disable alt-IOC's reply interrupts
2247 * (and FreeQ) for a bit
2249 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask,
2251 ioc->alt_ioc->active = 0;
2256 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
2259 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
2260 if (hard_reset_done == -4) {
2261 printk(MYIOC_s_WARN_FMT "Owned by PEER..skipping!\n",
2264 if (reset_alt_ioc_active && ioc->alt_ioc) {
2265 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
2266 dprintk(ioc, printk(MYIOC_s_INFO_FMT
2267 "alt_ioc reply irq re-enabled\n", ioc->alt_ioc->name));
2268 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2269 ioc->alt_ioc->active = 1;
2273 printk(MYIOC_s_WARN_FMT
2274 "NOT READY WARNING!\n", ioc->name);
2280 /* hard_reset_done = 0 if a soft reset was performed
2281 * and 1 if a hard reset was performed.
2283 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
2284 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
2287 printk(MYIOC_s_WARN_FMT
2288 ": alt-ioc Not ready WARNING!\n",
2289 ioc->alt_ioc->name);
2292 for (ii=0; ii<5; ii++) {
2293 /* Get IOC facts! Allow 5 retries */
2294 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
2300 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2301 "Retry IocFacts failed rc=%x\n", ioc->name, rc));
2303 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2304 MptDisplayIocCapabilities(ioc);
2307 if (alt_ioc_ready) {
2308 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
2309 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2310 "Initial Alt IocFacts failed rc=%x\n",
2312 /* Retry - alt IOC was initialized once
2314 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
2317 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2318 "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
2320 reset_alt_ioc_active = 0;
2321 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2322 MptDisplayIocCapabilities(ioc->alt_ioc);
2326 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP) &&
2327 (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)) {
2328 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2329 ioc->bars = pci_select_bars(ioc->pcidev, IORESOURCE_MEM |
2331 if (pci_enable_device(ioc->pcidev))
2333 if (pci_request_selected_regions(ioc->pcidev, ioc->bars,
2339 * Device is reset now. It must have de-asserted the interrupt line
2340 * (if it was asserted) and it should be safe to register for the
2343 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2345 if (ioc->pcidev->irq) {
2346 if (ioc->msi_enable && !pci_enable_msi(ioc->pcidev))
2347 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
2350 ioc->msi_enable = 0;
2351 rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
2352 IRQF_SHARED, ioc->name, ioc);
2354 printk(MYIOC_s_ERR_FMT "Unable to allocate "
2356 ioc->name, ioc->pcidev->irq);
2357 if (ioc->msi_enable)
2358 pci_disable_msi(ioc->pcidev);
2363 ioc->pci_irq = ioc->pcidev->irq;
2364 pci_set_master(ioc->pcidev); /* ?? */
2365 pci_set_drvdata(ioc->pcidev, ioc);
2366 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2367 "installed at interrupt %d\n", ioc->name,
2372 /* Prime reply & request queues!
2373 * (mucho alloc's) Must be done prior to
2374 * init as upper addresses are needed for init.
2375 * If fails, continue with alt-ioc processing
2377 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "PrimeIocFifos\n",
2379 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
2382 /* May need to check/upload firmware & data here!
2383 * If fails, continue with alt-ioc processing
2385 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "SendIocInit\n",
2387 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
2390 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
2391 printk(MYIOC_s_WARN_FMT
2392 ": alt-ioc (%d) FIFO mgmt alloc WARNING!\n",
2393 ioc->alt_ioc->name, rc);
2395 reset_alt_ioc_active = 0;
2398 if (alt_ioc_ready) {
2399 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
2401 reset_alt_ioc_active = 0;
2402 printk(MYIOC_s_WARN_FMT
2403 ": alt-ioc: (%d) init failure WARNING!\n",
2404 ioc->alt_ioc->name, rc);
2408 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
2409 if (ioc->upload_fw) {
2410 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2411 "firmware upload required!\n", ioc->name));
2413 /* Controller is not operational, cannot do upload
2416 rc = mpt_do_upload(ioc, sleepFlag);
2418 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2420 * Maintain only one pointer to FW memory
2421 * so there will not be two attempt to
2422 * downloadboot onboard dual function
2423 * chips (mpt_adapter_disable,
2426 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2427 "mpt_upload: alt_%s has cached_fw=%p \n",
2428 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
2429 ioc->cached_fw = NULL;
2432 printk(MYIOC_s_WARN_FMT
2433 "firmware upload failure!\n", ioc->name);
2440 /* Enable MPT base driver management of EventNotification
2441 * and EventAck handling.
2443 if ((ret == 0) && (!ioc->facts.EventState)) {
2444 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2445 "SendEventNotification\n",
2447 ret = SendEventNotification(ioc, 1, sleepFlag); /* 1=Enable */
2450 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2451 rc = SendEventNotification(ioc->alt_ioc, 1, sleepFlag);
2454 /* Enable! (reply interrupt) */
2455 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
2458 if (rc == 0) { /* alt ioc */
2459 if (reset_alt_ioc_active && ioc->alt_ioc) {
2460 /* (re)Enable alt-IOC! (reply interrupt) */
2461 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "alt-ioc"
2462 "reply irq re-enabled\n",
2463 ioc->alt_ioc->name));
2464 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask,
2466 ioc->alt_ioc->active = 1;
2471 /* Add additional "reason" check before call to GetLanConfigPages
2472 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2473 * recursive scenario; GetLanConfigPages times out, timer expired
2474 * routine calls HardResetHandler, which calls into here again,
2475 * and we try GetLanConfigPages again...
2477 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2480 * Initalize link list for inactive raid volumes.
2482 mutex_init(&ioc->raid_data.inactive_list_mutex);
2483 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2485 switch (ioc->bus_type) {
2488 /* clear persistency table */
2489 if(ioc->facts.IOCExceptions &
2490 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
2491 ret = mptbase_sas_persist_operation(ioc,
2492 MPI_SAS_OP_CLEAR_NOT_PRESENT);
2499 mpt_findImVolumes(ioc);
2501 /* Check, and possibly reset, the coalescing value
2503 mpt_read_ioc_pg_1(ioc);
2508 if ((ioc->pfacts[0].ProtocolFlags &
2509 MPI_PORTFACTS_PROTOCOL_LAN) &&
2510 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2512 * Pre-fetch the ports LAN MAC address!
2513 * (LANPage1_t stuff)
2515 (void) GetLanConfigPages(ioc);
2516 a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2517 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2518 "LanAddr = %02X:%02X:%02X"
2519 ":%02X:%02X:%02X\n",
2520 ioc->name, a[5], a[4],
2521 a[3], a[2], a[1], a[0]));
2526 /* Get NVRAM and adapter maximums from SPP 0 and 2
2528 mpt_GetScsiPortSettings(ioc, 0);
2530 /* Get version and length of SDP 1
2532 mpt_readScsiDevicePageHeaders(ioc, 0);
2536 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
2537 mpt_findImVolumes(ioc);
2539 /* Check, and possibly reset, the coalescing value
2541 mpt_read_ioc_pg_1(ioc);
2543 mpt_read_ioc_pg_4(ioc);
2548 GetIoUnitPage2(ioc);
2549 mpt_get_manufacturing_pg_0(ioc);
2553 * Call each currently registered protocol IOC reset handler
2554 * with post-reset indication.
2555 * NOTE: If we're doing _IOC_BRINGUP, there can be no
2556 * MptResetHandlers[] registered yet.
2558 if (hard_reset_done) {
2560 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
2561 if ((ret == 0) && MptResetHandlers[cb_idx]) {
2562 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2563 "Calling IOC post_reset handler #%d\n",
2564 ioc->name, cb_idx));
2565 rc += mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET);
2569 if (alt_ioc_ready && MptResetHandlers[cb_idx]) {
2570 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2571 "Calling IOC post_reset handler #%d\n",
2572 ioc->alt_ioc->name, cb_idx));
2573 rc += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_POST_RESET);
2577 /* FIXME? Examine results here? */
2581 if ((ret != 0) && irq_allocated) {
2582 free_irq(ioc->pci_irq, ioc);
2583 if (ioc->msi_enable)
2584 pci_disable_msi(ioc->pcidev);
2589 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2591 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2592 * @ioc: Pointer to MPT adapter structure
2593 * @pdev: Pointer to (struct pci_dev) structure
2595 * Search for PCI bus/dev_function which matches
2596 * PCI bus/dev_function (+/-1) for newly discovered 929,
2597 * 929X, 1030 or 1035.
2599 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2600 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2603 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
2605 struct pci_dev *peer=NULL;
2606 unsigned int slot = PCI_SLOT(pdev->devfn);
2607 unsigned int func = PCI_FUNC(pdev->devfn);
2608 MPT_ADAPTER *ioc_srch;
2610 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PCI device %s devfn=%x/%x,"
2611 " searching for devfn match on %x or %x\n",
2612 ioc->name, pci_name(pdev), pdev->bus->number,
2613 pdev->devfn, func-1, func+1));
2615 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
2617 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
2622 list_for_each_entry(ioc_srch, &ioc_list, list) {
2623 struct pci_dev *_pcidev = ioc_srch->pcidev;
2624 if (_pcidev == peer) {
2625 /* Paranoia checks */
2626 if (ioc->alt_ioc != NULL) {
2627 printk(MYIOC_s_WARN_FMT
2628 "Oops, already bound (%s <==> %s)!\n",
2629 ioc->name, ioc->name, ioc->alt_ioc->name);
2631 } else if (ioc_srch->alt_ioc != NULL) {
2632 printk(MYIOC_s_WARN_FMT
2633 "Oops, already bound (%s <==> %s)!\n",
2634 ioc_srch->name, ioc_srch->name,
2635 ioc_srch->alt_ioc->name);
2638 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2639 "FOUND! binding %s <==> %s\n",
2640 ioc->name, ioc->name, ioc_srch->name));
2641 ioc_srch->alt_ioc = ioc;
2642 ioc->alt_ioc = ioc_srch;
2648 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2650 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2651 * @ioc: Pointer to MPT adapter structure
2654 mpt_adapter_disable(MPT_ADAPTER *ioc)
2659 if (ioc->cached_fw != NULL) {
2660 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2661 "%s: Pushing FW onto adapter\n", __func__, ioc->name));
2662 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)
2663 ioc->cached_fw, CAN_SLEEP)) < 0) {
2664 printk(MYIOC_s_WARN_FMT
2665 ": firmware downloadboot failure (%d)!\n",
2670 /* Disable adapter interrupts! */
2671 synchronize_irq(ioc->pcidev->irq);
2672 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2675 /* Clear any lingering interrupt */
2676 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2677 CHIPREG_READ32(&ioc->chip->IntStatus);
2679 if (ioc->alloc != NULL) {
2681 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "free @ %p, sz=%d bytes\n",
2682 ioc->name, ioc->alloc, ioc->alloc_sz));
2683 pci_free_consistent(ioc->pcidev, sz,
2684 ioc->alloc, ioc->alloc_dma);
2685 ioc->reply_frames = NULL;
2686 ioc->req_frames = NULL;
2688 ioc->alloc_total -= sz;
2691 if (ioc->sense_buf_pool != NULL) {
2692 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2693 pci_free_consistent(ioc->pcidev, sz,
2694 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2695 ioc->sense_buf_pool = NULL;
2696 ioc->alloc_total -= sz;
2699 if (ioc->events != NULL){
2700 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2703 ioc->alloc_total -= sz;
2706 mpt_free_fw_memory(ioc);
2708 kfree(ioc->spi_data.nvram);
2709 mpt_inactive_raid_list_free(ioc);
2710 kfree(ioc->raid_data.pIocPg2);
2711 kfree(ioc->raid_data.pIocPg3);
2712 ioc->spi_data.nvram = NULL;
2713 ioc->raid_data.pIocPg3 = NULL;
2715 if (ioc->spi_data.pIocPg4 != NULL) {
2716 sz = ioc->spi_data.IocPg4Sz;
2717 pci_free_consistent(ioc->pcidev, sz,
2718 ioc->spi_data.pIocPg4,
2719 ioc->spi_data.IocPg4_dma);
2720 ioc->spi_data.pIocPg4 = NULL;
2721 ioc->alloc_total -= sz;
2724 if (ioc->ReqToChain != NULL) {
2725 kfree(ioc->ReqToChain);
2726 kfree(ioc->RequestNB);
2727 ioc->ReqToChain = NULL;
2730 kfree(ioc->ChainToChain);
2731 ioc->ChainToChain = NULL;
2733 if (ioc->HostPageBuffer != NULL) {
2734 if((ret = mpt_host_page_access_control(ioc,
2735 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2736 printk(MYIOC_s_ERR_FMT
2737 ": %s: host page buffers free failed (%d)!\n",
2738 ioc->name, __func__, ret);
2740 dexitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2741 "HostPageBuffer free @ %p, sz=%d bytes\n",
2742 ioc->name, ioc->HostPageBuffer,
2743 ioc->HostPageBuffer_sz));
2744 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2745 ioc->HostPageBuffer, ioc->HostPageBuffer_dma);
2746 ioc->HostPageBuffer = NULL;
2747 ioc->HostPageBuffer_sz = 0;
2748 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2751 pci_set_drvdata(ioc->pcidev, NULL);
2753 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2755 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2756 * @ioc: Pointer to MPT adapter structure
2758 * This routine unregisters h/w resources and frees all alloc'd memory
2759 * associated with a MPT adapter structure.
2762 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2764 int sz_first, sz_last;
2769 sz_first = ioc->alloc_total;
2771 mpt_adapter_disable(ioc);
2773 if (ioc->pci_irq != -1) {
2774 free_irq(ioc->pci_irq, ioc);
2775 if (ioc->msi_enable)
2776 pci_disable_msi(ioc->pcidev);
2780 if (ioc->memmap != NULL) {
2781 iounmap(ioc->memmap);
2785 pci_disable_device(ioc->pcidev);
2786 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2788 #if defined(CONFIG_MTRR) && 0
2789 if (ioc->mtrr_reg > 0) {
2790 mtrr_del(ioc->mtrr_reg, 0, 0);
2791 dprintk(ioc, printk(MYIOC_s_INFO_FMT "MTRR region de-registered\n", ioc->name));
2795 /* Zap the adapter lookup ptr! */
2796 list_del(&ioc->list);
2798 sz_last = ioc->alloc_total;
2799 dprintk(ioc, printk(MYIOC_s_INFO_FMT "free'd %d of %d bytes\n",
2800 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2803 ioc->alt_ioc->alt_ioc = NULL;
2808 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2810 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2811 * @ioc: Pointer to MPT adapter structure
2814 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2818 printk(KERN_INFO "%s: ", ioc->name);
2820 printk("%s: ", ioc->prod_name);
2821 printk("Capabilities={");
2823 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2824 printk("Initiator");
2828 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2829 printk("%sTarget", i ? "," : "");
2833 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2834 printk("%sLAN", i ? "," : "");
2840 * This would probably evoke more questions than it's worth
2842 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2843 printk("%sLogBusAddr", i ? "," : "");
2851 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2853 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2854 * @ioc: Pointer to MPT_ADAPTER structure
2855 * @force: Force hard KickStart of IOC
2856 * @sleepFlag: Specifies whether the process can sleep
2859 * 1 - DIAG reset and READY
2860 * 0 - READY initially OR soft reset and READY
2861 * -1 - Any failure on KickStart
2862 * -2 - Msg Unit Reset Failed
2863 * -3 - IO Unit Reset Failed
2864 * -4 - IOC owned by a PEER
2867 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2872 int hard_reset_done = 0;
2877 /* Get current [raw] IOC state */
2878 ioc_state = mpt_GetIocState(ioc, 0);
2879 dhsprintk(ioc, printk(MYIOC_s_INFO_FMT "MakeIocReady [raw] state=%08x\n", ioc->name, ioc_state));
2882 * Check to see if IOC got left/stuck in doorbell handshake
2883 * grip of death. If so, hard reset the IOC.
2885 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2887 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2891 /* Is it already READY? */
2893 ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)) {
2894 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2895 "IOC is in READY state\n", ioc->name));
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
2971 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
2972 ioc->name, ioc_state, (int)((ii+5)/HZ));
2976 if (sleepFlag == CAN_SLEEP) {
2979 mdelay (1); /* 1 msec delay */
2984 if (statefault < 3) {
2985 printk(MYIOC_s_INFO_FMT "Recovered from %s\n", ioc->name,
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(KERN_ERR MYNAM
3040 ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
3041 ioc->name, ioc->last_state);
3045 facts = &ioc->facts;
3047 /* Destination (reply area)... */
3048 reply_sz = sizeof(*facts);
3049 memset(facts, 0, reply_sz);
3051 /* Request area (get_facts on the stack right now!) */
3052 req_sz = sizeof(get_facts);
3053 memset(&get_facts, 0, req_sz);
3055 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
3056 /* Assert: All other get_facts fields are zero! */
3058 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3059 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
3060 ioc->name, req_sz, reply_sz));
3062 /* No non-zero fields in the get_facts request are greater than
3063 * 1 byte in size, so we can just fire it off as is.
3065 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
3066 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
3071 * Now byte swap (GRRR) the necessary fields before any further
3072 * inspection of reply contents.
3074 * But need to do some sanity checks on MsgLength (byte) field
3075 * to make sure we don't zero IOC's req_sz!
3077 /* Did we get a valid reply? */
3078 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
3079 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
3081 * If not been here, done that, save off first WhoInit value
3083 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
3084 ioc->FirstWhoInit = facts->WhoInit;
3087 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
3088 facts->MsgContext = le32_to_cpu(facts->MsgContext);
3089 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
3090 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
3091 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
3092 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
3093 /* CHECKME! IOCStatus, IOCLogInfo */
3095 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
3096 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
3099 * FC f/w version changed between 1.1 and 1.2
3100 * Old: u16{Major(4),Minor(4),SubMinor(8)}
3101 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
3103 if (facts->MsgVersion < MPI_VERSION_01_02) {
3105 * Handle old FC f/w style, convert to new...
3107 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
3108 facts->FWVersion.Word =
3109 ((oldv<<12) & 0xFF000000) |
3110 ((oldv<<8) & 0x000FFF00);
3112 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
3114 facts->ProductID = le16_to_cpu(facts->ProductID);
3116 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
3117 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
3118 ioc->ir_firmware = 1;
3120 facts->CurrentHostMfaHighAddr =
3121 le32_to_cpu(facts->CurrentHostMfaHighAddr);
3122 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
3123 facts->CurrentSenseBufferHighAddr =
3124 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
3125 facts->CurReplyFrameSize =
3126 le16_to_cpu(facts->CurReplyFrameSize);
3127 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
3130 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
3131 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
3132 * to 14 in MPI-1.01.0x.
3134 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
3135 facts->MsgVersion > MPI_VERSION_01_00) {
3136 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
3139 sz = facts->FWImageSize;
3144 facts->FWImageSize = sz;
3146 if (!facts->RequestFrameSize) {
3147 /* Something is wrong! */
3148 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
3153 r = sz = facts->BlockSize;
3154 vv = ((63 / (sz * 4)) + 1) & 0x03;
3155 ioc->NB_for_64_byte_frame = vv;
3161 ioc->NBShiftFactor = shiftFactor;
3162 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3163 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
3164 ioc->name, vv, shiftFactor, r));
3166 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
3168 * Set values for this IOC's request & reply frame sizes,
3169 * and request & reply queue depths...
3171 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
3172 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
3173 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
3174 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
3176 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "reply_sz=%3d, reply_depth=%4d\n",
3177 ioc->name, ioc->reply_sz, ioc->reply_depth));
3178 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "req_sz =%3d, req_depth =%4d\n",
3179 ioc->name, ioc->req_sz, ioc->req_depth));
3181 /* Get port facts! */
3182 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
3186 printk(MYIOC_s_ERR_FMT
3187 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
3188 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
3189 RequestFrameSize)/sizeof(u32)));
3196 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3198 * GetPortFacts - Send PortFacts request to MPT adapter.
3199 * @ioc: Pointer to MPT_ADAPTER structure
3200 * @portnum: Port number
3201 * @sleepFlag: Specifies whether the process can sleep
3203 * Returns 0 for success, non-zero for failure.
3206 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3208 PortFacts_t get_pfacts;
3209 PortFactsReply_t *pfacts;
3215 /* IOC *must* NOT be in RESET state! */
3216 if (ioc->last_state == MPI_IOC_STATE_RESET) {
3217 printk(MYIOC_s_ERR_FMT "Can't get PortFacts NOT READY! (%08x)\n",
3218 ioc->name, ioc->last_state );
3222 pfacts = &ioc->pfacts[portnum];
3224 /* Destination (reply area)... */
3225 reply_sz = sizeof(*pfacts);
3226 memset(pfacts, 0, reply_sz);
3228 /* Request area (get_pfacts on the stack right now!) */
3229 req_sz = sizeof(get_pfacts);
3230 memset(&get_pfacts, 0, req_sz);
3232 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
3233 get_pfacts.PortNumber = portnum;
3234 /* Assert: All other get_pfacts fields are zero! */
3236 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending get PortFacts(%d) request\n",
3237 ioc->name, portnum));
3239 /* No non-zero fields in the get_pfacts request are greater than
3240 * 1 byte in size, so we can just fire it off as is.
3242 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
3243 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
3247 /* Did we get a valid reply? */
3249 /* Now byte swap the necessary fields in the response. */
3250 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
3251 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
3252 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
3253 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
3254 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
3255 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
3256 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
3257 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
3258 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
3260 max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
3262 ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
3263 ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
3266 * Place all the devices on channels
3270 if (mpt_channel_mapping) {
3271 ioc->devices_per_bus = 1;
3272 ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
3278 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3280 * SendIocInit - Send IOCInit request to MPT adapter.
3281 * @ioc: Pointer to MPT_ADAPTER structure
3282 * @sleepFlag: Specifies whether the process can sleep
3284 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
3286 * Returns 0 for success, non-zero for failure.
3289 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
3292 MPIDefaultReply_t init_reply;
3298 memset(&ioc_init, 0, sizeof(ioc_init));
3299 memset(&init_reply, 0, sizeof(init_reply));
3301 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
3302 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
3304 /* If we are in a recovery mode and we uploaded the FW image,
3305 * then this pointer is not NULL. Skip the upload a second time.
3306 * Set this flag if cached_fw set for either IOC.
3308 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
3312 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "upload_fw %d facts.Flags=%x\n",
3313 ioc->name, ioc->upload_fw, ioc->facts.Flags));
3315 ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
3316 ioc_init.MaxBuses = (U8)ioc->number_of_buses;
3318 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n",
3319 ioc->name, ioc->facts.MsgVersion));
3320 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
3321 // set MsgVersion and HeaderVersion host driver was built with
3322 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
3323 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
3325 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
3326 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
3327 } else if(mpt_host_page_alloc(ioc, &ioc_init))
3330 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
3332 if (ioc->sg_addr_size == sizeof(u64)) {
3333 /* Save the upper 32-bits of the request
3334 * (reply) and sense buffers.
3336 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
3337 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
3339 /* Force 32-bit addressing */
3340 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
3341 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
3344 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
3345 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
3346 ioc->facts.MaxDevices = ioc_init.MaxDevices;
3347 ioc->facts.MaxBuses = ioc_init.MaxBuses;
3349 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOCInit (req @ %p)\n",
3350 ioc->name, &ioc_init));
3352 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
3353 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
3355 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
3359 /* No need to byte swap the multibyte fields in the reply
3360 * since we don't even look at its contents.
3363 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending PortEnable (req @ %p)\n",
3364 ioc->name, &ioc_init));
3366 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
3367 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
3371 /* YIKES! SUPER IMPORTANT!!!
3372 * Poll IocState until _OPERATIONAL while IOC is doing
3373 * LoopInit and TargetDiscovery!
3376 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
3377 state = mpt_GetIocState(ioc, 1);
3378 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
3379 if (sleepFlag == CAN_SLEEP) {
3386 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
3387 ioc->name, (int)((count+5)/HZ));
3391 state = mpt_GetIocState(ioc, 1);
3394 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wait IOC_OPERATIONAL state (cnt=%d)\n",
3397 ioc->aen_event_read_flag=0;
3401 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3403 * SendPortEnable - Send PortEnable request to MPT adapter port.
3404 * @ioc: Pointer to MPT_ADAPTER structure
3405 * @portnum: Port number to enable
3406 * @sleepFlag: Specifies whether the process can sleep
3408 * Send PortEnable to bring IOC to OPERATIONAL state.
3410 * Returns 0 for success, non-zero for failure.
3413 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3415 PortEnable_t port_enable;
3416 MPIDefaultReply_t reply_buf;
3421 /* Destination... */
3422 reply_sz = sizeof(MPIDefaultReply_t);
3423 memset(&reply_buf, 0, reply_sz);
3425 req_sz = sizeof(PortEnable_t);
3426 memset(&port_enable, 0, req_sz);
3428 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
3429 port_enable.PortNumber = portnum;
3430 /* port_enable.ChainOffset = 0; */
3431 /* port_enable.MsgFlags = 0; */
3432 /* port_enable.MsgContext = 0; */
3434 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Port(%d)Enable (req @ %p)\n",
3435 ioc->name, portnum, &port_enable));
3437 /* RAID FW may take a long time to enable
3439 if (ioc->ir_firmware || ioc->bus_type == SAS) {
3440 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3441 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3442 300 /*seconds*/, sleepFlag);
3444 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3445 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3446 30 /*seconds*/, sleepFlag);
3452 * mpt_alloc_fw_memory - allocate firmware memory
3453 * @ioc: Pointer to MPT_ADAPTER structure
3454 * @size: total FW bytes
3456 * If memory has already been allocated, the same (cached) value
3459 * Return 0 if successfull, or non-zero for failure
3462 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
3466 if (ioc->cached_fw) {
3467 rc = 0; /* use already allocated memory */
3470 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
3471 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
3472 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
3476 ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma);
3477 if (!ioc->cached_fw) {
3478 printk(MYIOC_s_ERR_FMT "Unable to allocate memory for the cached firmware image!\n",
3482 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Image @ %p[%p], sz=%d[%x] bytes\n",
3483 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, size, size));
3484 ioc->alloc_total += size;
3492 * mpt_free_fw_memory - free firmware memory
3493 * @ioc: Pointer to MPT_ADAPTER structure
3495 * If alt_img is NULL, delete from ioc structure.
3496 * Else, delete a secondary image in same format.
3499 mpt_free_fw_memory(MPT_ADAPTER *ioc)
3503 if (!ioc->cached_fw)
3506 sz = ioc->facts.FWImageSize;
3507 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3508 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3509 pci_free_consistent(ioc->pcidev, sz, ioc->cached_fw, ioc->cached_fw_dma);
3510 ioc->alloc_total -= sz;
3511 ioc->cached_fw = NULL;
3514 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3516 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3517 * @ioc: Pointer to MPT_ADAPTER structure
3518 * @sleepFlag: Specifies whether the process can sleep
3520 * Returns 0 for success, >0 for handshake failure
3521 * <0 for fw upload failure.
3523 * Remark: If bound IOC and a successful FWUpload was performed
3524 * on the bound IOC, the second image is discarded
3525 * and memory is free'd. Both channels must upload to prevent
3526 * IOC from running in degraded mode.
3529 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3531 u8 reply[sizeof(FWUploadReply_t)];
3532 FWUpload_t *prequest;
3533 FWUploadReply_t *preply;
3534 FWUploadTCSGE_t *ptcsge;
3536 int ii, sz, reply_sz;
3539 /* If the image size is 0, we are done.
3541 if ((sz = ioc->facts.FWImageSize) == 0)
3544 if (mpt_alloc_fw_memory(ioc, ioc->facts.FWImageSize) != 0)
3547 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3548 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3550 prequest = (sleepFlag == NO_SLEEP) ? kzalloc(ioc->req_sz, GFP_ATOMIC) :
3551 kzalloc(ioc->req_sz, GFP_KERNEL);
3553 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed "
3554 "while allocating memory \n", ioc->name));
3555 mpt_free_fw_memory(ioc);
3559 preply = (FWUploadReply_t *)&reply;
3561 reply_sz = sizeof(reply);
3562 memset(preply, 0, reply_sz);
3564 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
3565 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
3567 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
3568 ptcsge->DetailsLength = 12;
3569 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
3570 ptcsge->ImageSize = cpu_to_le32(sz);
3573 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3574 ioc->add_sge((char *)ptcsge, flagsLength, ioc->cached_fw_dma);
3575 request_size = offsetof(FWUpload_t, SGL) + sizeof(FWUploadTCSGE_t) +
3577 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending FW Upload "
3578 " (req @ %p) fw_size=%d mf_request_size=%d\n", ioc->name, prequest,
3579 ioc->facts.FWImageSize, request_size));
3580 DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest);
3582 ii = mpt_handshake_req_reply_wait(ioc, request_size, (u32 *)prequest,
3583 reply_sz, (u16 *)preply, 65 /*seconds*/, sleepFlag);
3585 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Upload completed "
3586 "rc=%x \n", ioc->name, ii));
3588 cmdStatus = -EFAULT;
3590 /* Handshake transfer was complete and successful.
3591 * Check the Reply Frame.
3594 status = le16_to_cpu(preply->IOCStatus) &
3596 if (status == MPI_IOCSTATUS_SUCCESS &&
3597 ioc->facts.FWImageSize ==
3598 le32_to_cpu(preply->ActualImageSize))
3601 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n",
3602 ioc->name, cmdStatus));
3606 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed, "
3607 "freeing image \n", ioc->name));
3608 mpt_free_fw_memory(ioc);
3615 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3617 * mpt_downloadboot - DownloadBoot code
3618 * @ioc: Pointer to MPT_ADAPTER structure
3619 * @pFwHeader: Pointer to firmware header info
3620 * @sleepFlag: Specifies whether the process can sleep
3622 * FwDownloadBoot requires Programmed IO access.
3624 * Returns 0 for success
3625 * -1 FW Image size is 0
3626 * -2 No valid cached_fw Pointer
3627 * <0 for fw upload failure.
3630 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3632 MpiExtImageHeader_t *pExtImage;
3642 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3643 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
3645 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3646 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3647 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3648 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3649 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3650 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3652 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
3655 if (sleepFlag == CAN_SLEEP) {
3661 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3662 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3664 for (count = 0; count < 30; count ++) {
3665 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3666 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3667 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESET_ADAPTER cleared, count=%d\n",
3672 if (sleepFlag == CAN_SLEEP) {
3679 if ( count == 30 ) {
3680 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot failed! "
3681 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3682 ioc->name, diag0val));
3686 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3687 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3688 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3689 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3690 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3691 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3693 /* Set the DiagRwEn and Disable ARM bits */
3694 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3696 fwSize = (pFwHeader->ImageSize + 3)/4;
3697 ptrFw = (u32 *) pFwHeader;
3699 /* Write the LoadStartAddress to the DiagRw Address Register
3700 * using Programmed IO
3702 if (ioc->errata_flag_1064)
3703 pci_enable_io_access(ioc->pcidev);
3705 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3706 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "LoadStart addr written 0x%x \n",
3707 ioc->name, pFwHeader->LoadStartAddress));
3709 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write FW Image: 0x%x bytes @ %p\n",
3710 ioc->name, fwSize*4, ptrFw));
3712 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3715 nextImage = pFwHeader->NextImageHeaderOffset;
3717 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3719 load_addr = pExtImage->LoadStartAddress;
3721 fwSize = (pExtImage->ImageSize + 3) >> 2;
3722 ptrFw = (u32 *)pExtImage;
3724 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3725 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3726 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3729 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3731 nextImage = pExtImage->NextImageHeaderOffset;
3734 /* Write the IopResetVectorRegAddr */
3735 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
3736 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3738 /* Write the IopResetVectorValue */
3739 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3740 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3742 /* Clear the internal flash bad bit - autoincrementing register,
3743 * so must do two writes.
3745 if (ioc->bus_type == SPI) {
3747 * 1030 and 1035 H/W errata, workaround to access
3748 * the ClearFlashBadSignatureBit
3750 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3751 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3752 diagRwData |= 0x40000000;
3753 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3754 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3756 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3757 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3758 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3759 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3762 if (sleepFlag == CAN_SLEEP) {
3769 if (ioc->errata_flag_1064)
3770 pci_disable_io_access(ioc->pcidev);
3772 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3773 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot diag0val=%x, "
3774 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3775 ioc->name, diag0val));
3776 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3777 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot now diag0val=%x\n",
3778 ioc->name, diag0val));
3779 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3781 /* Write 0xFF to reset the sequencer */
3782 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3784 if (ioc->bus_type == SAS) {
3785 ioc_state = mpt_GetIocState(ioc, 0);
3786 if ( (GetIocFacts(ioc, sleepFlag,
3787 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3788 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "GetIocFacts failed: IocState=%x\n",
3789 ioc->name, ioc_state));
3794 for (count=0; count<HZ*20; count++) {
3795 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3796 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3797 "downloadboot successful! (count=%d) IocState=%x\n",
3798 ioc->name, count, ioc_state));
3799 if (ioc->bus_type == SAS) {
3802 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3803 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3804 "downloadboot: SendIocInit failed\n",
3808 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3809 "downloadboot: SendIocInit successful\n",
3813 if (sleepFlag == CAN_SLEEP) {
3819 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3820 "downloadboot failed! IocState=%x\n",ioc->name, ioc_state));
3824 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3826 * KickStart - Perform hard reset of MPT adapter.
3827 * @ioc: Pointer to MPT_ADAPTER structure
3828 * @force: Force hard reset
3829 * @sleepFlag: Specifies whether the process can sleep
3831 * This routine places MPT adapter in diagnostic mode via the
3832 * WriteSequence register, and then performs a hard reset of adapter
3833 * via the Diagnostic register.
3835 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3836 * or NO_SLEEP (interrupt thread, use mdelay)
3837 * force - 1 if doorbell active, board fault state
3838 * board operational, IOC_RECOVERY or
3839 * IOC_BRINGUP and there is an alt_ioc.
3843 * 1 - hard reset, READY
3844 * 0 - no reset due to History bit, READY
3845 * -1 - no reset due to History bit but not READY
3846 * OR reset but failed to come READY
3847 * -2 - no reset, could not enter DIAG mode
3848 * -3 - reset but bad FW bit
3851 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3853 int hard_reset_done = 0;
3857 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStarting!\n", ioc->name));
3858 if (ioc->bus_type == SPI) {
3859 /* Always issue a Msg Unit Reset first. This will clear some
3860 * SCSI bus hang conditions.
3862 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3864 if (sleepFlag == CAN_SLEEP) {
3871 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3872 if (hard_reset_done < 0)
3873 return hard_reset_done;
3875 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n",
3878 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3879 for (cnt=0; cnt<cntdn; cnt++) {
3880 ioc_state = mpt_GetIocState(ioc, 1);
3881 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3882 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStart successful! (cnt=%d)\n",
3884 return hard_reset_done;
3886 if (sleepFlag == CAN_SLEEP) {
3893 dinitprintk(ioc, printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3894 ioc->name, mpt_GetIocState(ioc, 0)));
3898 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3900 * mpt_diag_reset - Perform hard reset of the adapter.
3901 * @ioc: Pointer to MPT_ADAPTER structure
3902 * @ignore: Set if to honor and clear to ignore
3903 * the reset history bit
3904 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3905 * else set to NO_SLEEP (use mdelay instead)
3907 * This routine places the adapter in diagnostic mode via the
3908 * WriteSequence register and then performs a hard reset of adapter
3909 * via the Diagnostic register. Adapter should be in ready state
3910 * upon successful completion.
3912 * Returns: 1 hard reset successful
3913 * 0 no reset performed because reset history bit set
3914 * -2 enabling diagnostic mode failed
3915 * -3 diagnostic reset failed
3918 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3922 int hard_reset_done = 0;
3925 MpiFwHeader_t *cached_fw; /* Pointer to FW */
3927 /* Clear any existing interrupts */
3928 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3930 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3935 drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3936 "address=%p\n", ioc->name, __func__,
3937 &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3938 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3939 if (sleepFlag == CAN_SLEEP)
3944 for (count = 0; count < 60; count ++) {
3945 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3946 doorbell &= MPI_IOC_STATE_MASK;
3948 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3949 "looking for READY STATE: doorbell=%x"
3951 ioc->name, doorbell, count));
3953 if (doorbell == MPI_IOC_STATE_READY) {
3958 if (sleepFlag == CAN_SLEEP)
3966 /* Use "Diagnostic reset" method! (only thing available!) */
3967 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3969 if (ioc->debug_level & MPT_DEBUG) {
3971 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3972 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3973 ioc->name, diag0val, diag1val));
3976 /* Do the reset if we are told to ignore the reset history
3977 * or if the reset history is 0
3979 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3980 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3981 /* Write magic sequence to WriteSequence register
3982 * Loop until in diagnostic mode
3984 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3985 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3986 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3987 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3988 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3989 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3992 if (sleepFlag == CAN_SLEEP) {
4000 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
4001 ioc->name, diag0val);
4006 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4008 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
4009 ioc->name, diag0val));
4012 if (ioc->debug_level & MPT_DEBUG) {
4014 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4015 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG2: diag0=%08x, diag1=%08x\n",
4016 ioc->name, diag0val, diag1val));
4019 * Disable the ARM (Bug fix)
4022 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
4026 * Now hit the reset bit in the Diagnostic register
4027 * (THE BIG HAMMER!) (Clears DRWE bit).
4029 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
4030 hard_reset_done = 1;
4031 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset performed\n",
4035 * Call each currently registered protocol IOC reset handler
4036 * with pre-reset indication.
4037 * NOTE: If we're doing _IOC_BRINGUP, there can be no
4038 * MptResetHandlers[] registered yet.
4044 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
4045 if (MptResetHandlers[cb_idx]) {
4046 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4047 "Calling IOC pre_reset handler #%d\n",
4048 ioc->name, cb_idx));
4049 r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET);
4051 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4052 "Calling alt-%s pre_reset handler #%d\n",
4053 ioc->name, ioc->alt_ioc->name, cb_idx));
4054 r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_PRE_RESET);
4058 /* FIXME? Examine results here? */
4062 cached_fw = (MpiFwHeader_t *)ioc->cached_fw;
4063 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
4064 cached_fw = (MpiFwHeader_t *)ioc->alt_ioc->cached_fw;
4068 /* If the DownloadBoot operation fails, the
4069 * IOC will be left unusable. This is a fatal error
4070 * case. _diag_reset will return < 0
4072 for (count = 0; count < 30; count ++) {
4073 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4074 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
4078 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n",
4079 ioc->name, diag0val, count));
4081 if (sleepFlag == CAN_SLEEP) {
4087 if ((count = mpt_downloadboot(ioc, cached_fw, sleepFlag)) < 0) {
4088 printk(MYIOC_s_WARN_FMT
4089 "firmware downloadboot failure (%d)!\n", ioc->name, count);
4093 /* Wait for FW to reload and for board
4094 * to go to the READY state.
4095 * Maximum wait is 60 seconds.
4096 * If fail, no error will check again
4097 * with calling program.
4099 for (count = 0; count < 60; count ++) {
4100 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
4101 doorbell &= MPI_IOC_STATE_MASK;
4103 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4104 "looking for READY STATE: doorbell=%x"
4105 " count=%d\n", ioc->name, doorbell, count));
4107 if (doorbell == MPI_IOC_STATE_READY) {
4112 if (sleepFlag == CAN_SLEEP) {
4119 if (doorbell != MPI_IOC_STATE_READY)
4120 printk(MYIOC_s_ERR_FMT "Failed to come READY "
4121 "after reset! IocState=%x", ioc->name,
4126 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4127 if (ioc->debug_level & MPT_DEBUG) {
4129 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4130 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG3: diag0=%08x, diag1=%08x\n",
4131 ioc->name, diag0val, diag1val));
4134 /* Clear RESET_HISTORY bit! Place board in the
4135 * diagnostic mode to update the diag register.
4137 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4139 while ((diag0val & MPI_DIAG_DRWE) == 0) {
4140 /* Write magic sequence to WriteSequence register
4141 * Loop until in diagnostic mode
4143 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
4144 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
4145 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
4146 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
4147 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
4148 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
4151 if (sleepFlag == CAN_SLEEP) {
4159 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
4160 ioc->name, diag0val);
4163 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4165 diag0val &= ~MPI_DIAG_RESET_HISTORY;
4166 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
4167 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4168 if (diag0val & MPI_DIAG_RESET_HISTORY) {
4169 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
4173 /* Disable Diagnostic Mode
4175 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
4177 /* Check FW reload status flags.
4179 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4180 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
4181 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
4182 ioc->name, diag0val);
4186 if (ioc->debug_level & MPT_DEBUG) {
4188 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4189 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG4: diag0=%08x, diag1=%08x\n",
4190 ioc->name, diag0val, diag1val));
4194 * Reset flag that says we've enabled event notification
4196 ioc->facts.EventState = 0;
4199 ioc->alt_ioc->facts.EventState = 0;
4201 return hard_reset_done;
4204 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4206 * SendIocReset - Send IOCReset request to MPT adapter.
4207 * @ioc: Pointer to MPT_ADAPTER structure
4208 * @reset_type: reset type, expected values are
4209 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
4210 * @sleepFlag: Specifies whether the process can sleep
4212 * Send IOCReset request to the MPT adapter.
4214 * Returns 0 for success, non-zero for failure.
4217 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
4223 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOC reset(0x%02x)!\n",
4224 ioc->name, reset_type));
4225 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
4226 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4229 /* FW ACK'd request, wait for READY state
4232 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
4234 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
4238 if (sleepFlag != CAN_SLEEP)
4241 printk(MYIOC_s_ERR_FMT
4242 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
4243 ioc->name, state, (int)((count+5)/HZ));
4247 if (sleepFlag == CAN_SLEEP) {
4250 mdelay (1); /* 1 msec delay */
4255 * Cleanup all event stuff for this IOC; re-issue EventNotification
4256 * request if needed.
4258 if (ioc->facts.Function)
4259 ioc->facts.EventState = 0;
4264 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4266 * initChainBuffers - Allocate memory for and initialize chain buffers
4267 * @ioc: Pointer to MPT_ADAPTER structure
4269 * Allocates memory for and initializes chain buffers,
4270 * chain buffer control arrays and spinlock.
4273 initChainBuffers(MPT_ADAPTER *ioc)
4276 int sz, ii, num_chain;
4277 int scale, num_sge, numSGE;
4279 /* ReqToChain size must equal the req_depth
4282 if (ioc->ReqToChain == NULL) {
4283 sz = ioc->req_depth * sizeof(int);
4284 mem = kmalloc(sz, GFP_ATOMIC);
4288 ioc->ReqToChain = (int *) mem;
4289 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReqToChain alloc @ %p, sz=%d bytes\n",
4290 ioc->name, mem, sz));
4291 mem = kmalloc(sz, GFP_ATOMIC);
4295 ioc->RequestNB = (int *) mem;
4296 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestNB alloc @ %p, sz=%d bytes\n",
4297 ioc->name, mem, sz));
4299 for (ii = 0; ii < ioc->req_depth; ii++) {
4300 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
4303 /* ChainToChain size must equal the total number
4304 * of chain buffers to be allocated.
4307 * Calculate the number of chain buffers needed(plus 1) per I/O
4308 * then multiply the maximum number of simultaneous cmds
4310 * num_sge = num sge in request frame + last chain buffer
4311 * scale = num sge per chain buffer if no chain element
4313 scale = ioc->req_sz / ioc->SGE_size;
4314 if (ioc->sg_addr_size == sizeof(u64))
4315 num_sge = scale + (ioc->req_sz - 60) / ioc->SGE_size;
4317 num_sge = 1 + scale + (ioc->req_sz - 64) / ioc->SGE_size;
4319 if (ioc->sg_addr_size == sizeof(u64)) {
4320 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
4321 (ioc->req_sz - 60) / ioc->SGE_size;
4323 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) +
4324 scale + (ioc->req_sz - 64) / ioc->SGE_size;
4326 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n",
4327 ioc->name, num_sge, numSGE));
4329 if (ioc->bus_type == FC) {
4330 if (numSGE > MPT_SCSI_FC_SG_DEPTH)
4331 numSGE = MPT_SCSI_FC_SG_DEPTH;
4333 if (numSGE > MPT_SCSI_SG_DEPTH)
4334 numSGE = MPT_SCSI_SG_DEPTH;
4338 while (numSGE - num_sge > 0) {
4340 num_sge += (scale - 1);
4344 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Now numSGE=%d num_sge=%d num_chain=%d\n",
4345 ioc->name, numSGE, num_sge, num_chain));
4347 if (ioc->bus_type == SPI)
4348 num_chain *= MPT_SCSI_CAN_QUEUE;
4350 num_chain *= MPT_FC_CAN_QUEUE;
4352 ioc->num_chain = num_chain;
4354 sz = num_chain * sizeof(int);
4355 if (ioc->ChainToChain == NULL) {
4356 mem = kmalloc(sz, GFP_ATOMIC);
4360 ioc->ChainToChain = (int *) mem;
4361 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainToChain alloc @ %p, sz=%d bytes\n",
4362 ioc->name, mem, sz));
4364 mem = (u8 *) ioc->ChainToChain;
4366 memset(mem, 0xFF, sz);
4370 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4372 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
4373 * @ioc: Pointer to MPT_ADAPTER structure
4375 * This routine allocates memory for the MPT reply and request frame
4376 * pools (if necessary), and primes the IOC reply FIFO with
4379 * Returns 0 for success, non-zero for failure.
4382 PrimeIocFifos(MPT_ADAPTER *ioc)
4385 unsigned long flags;
4386 dma_addr_t alloc_dma;
4388 int i, reply_sz, sz, total_size, num_chain;
4393 /* Prime reply FIFO... */
4395 if (ioc->reply_frames == NULL) {
4396 if ( (num_chain = initChainBuffers(ioc)) < 0)
4399 * 1078 errata workaround for the 36GB limitation
4401 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078 &&
4402 ioc->dma_mask > DMA_35BIT_MASK) {
4403 if (!pci_set_dma_mask(ioc->pcidev, DMA_BIT_MASK(32))
4404 && !pci_set_consistent_dma_mask(ioc->pcidev,
4405 DMA_BIT_MASK(32))) {
4406 dma_mask = DMA_35BIT_MASK;
4407 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4408 "setting 35 bit addressing for "
4409 "Request/Reply/Chain and Sense Buffers\n",
4412 /*Reseting DMA mask to 64 bit*/
4413 pci_set_dma_mask(ioc->pcidev,
4415 pci_set_consistent_dma_mask(ioc->pcidev,
4418 printk(MYIOC_s_ERR_FMT
4419 "failed setting 35 bit addressing for "
4420 "Request/Reply/Chain and Sense Buffers\n",
4426 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
4427 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
4428 ioc->name, ioc->reply_sz, ioc->reply_depth));
4429 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d[%x] bytes\n",
4430 ioc->name, reply_sz, reply_sz));
4432 sz = (ioc->req_sz * ioc->req_depth);
4433 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d bytes, RequestDepth=%d\n",
4434 ioc->name, ioc->req_sz, ioc->req_depth));
4435 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d[%x] bytes\n",
4436 ioc->name, sz, sz));
4439 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
4440 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d bytes, ChainDepth=%d\n",
4441 ioc->name, ioc->req_sz, num_chain));
4442 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
4443 ioc->name, sz, sz, num_chain));
4446 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
4448 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
4453 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Total alloc @ %p[%p], sz=%d[%x] bytes\n",
4454 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
4456 memset(mem, 0, total_size);
4457 ioc->alloc_total += total_size;
4459 ioc->alloc_dma = alloc_dma;
4460 ioc->alloc_sz = total_size;
4461 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
4462 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4464 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4465 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4467 alloc_dma += reply_sz;
4470 /* Request FIFO - WE manage this! */
4472 ioc->req_frames = (MPT_FRAME_HDR *) mem;
4473 ioc->req_frames_dma = alloc_dma;
4475 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffers @ %p[%p]\n",
4476 ioc->name, mem, (void *)(ulong)alloc_dma));
4478 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4480 #if defined(CONFIG_MTRR) && 0
4482 * Enable Write Combining MTRR for IOC's memory region.
4483 * (at least as much as we can; "size and base must be
4484 * multiples of 4 kiB"
4486 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
4488 MTRR_TYPE_WRCOMB, 1);
4489 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MTRR region registered (base:size=%08x:%x)\n",
4490 ioc->name, ioc->req_frames_dma, sz));
4493 for (i = 0; i < ioc->req_depth; i++) {
4494 alloc_dma += ioc->req_sz;
4498 ioc->ChainBuffer = mem;
4499 ioc->ChainBufferDMA = alloc_dma;
4501 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffers @ %p(%p)\n",
4502 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
4504 /* Initialize the free chain Q.
4507 INIT_LIST_HEAD(&ioc->FreeChainQ);
4509 /* Post the chain buffers to the FreeChainQ.
4511 mem = (u8 *)ioc->ChainBuffer;
4512 for (i=0; i < num_chain; i++) {
4513 mf = (MPT_FRAME_HDR *) mem;
4514 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
4518 /* Initialize Request frames linked list
4520 alloc_dma = ioc->req_frames_dma;
4521 mem = (u8 *) ioc->req_frames;
4523 spin_lock_irqsave(&ioc->FreeQlock, flags);
4524 INIT_LIST_HEAD(&ioc->FreeQ);
4525 for (i = 0; i < ioc->req_depth; i++) {
4526 mf = (MPT_FRAME_HDR *) mem;
4528 /* Queue REQUESTs *internally*! */
4529 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
4533 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4535 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4536 ioc->sense_buf_pool =
4537 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
4538 if (ioc->sense_buf_pool == NULL) {
4539 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
4544 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
4545 ioc->alloc_total += sz;
4546 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SenseBuffers @ %p[%p]\n",
4547 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
4551 /* Post Reply frames to FIFO
4553 alloc_dma = ioc->alloc_dma;
4554 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4555 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4557 for (i = 0; i < ioc->reply_depth; i++) {
4558 /* Write each address to the IOC! */
4559 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
4560 alloc_dma += ioc->reply_sz;
4563 if (dma_mask == DMA_35BIT_MASK && !pci_set_dma_mask(ioc->pcidev,
4564 ioc->dma_mask) && !pci_set_consistent_dma_mask(ioc->pcidev,
4566 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4567 "restoring 64 bit addressing\n", ioc->name));
4573 if (ioc->alloc != NULL) {
4575 pci_free_consistent(ioc->pcidev,
4577 ioc->alloc, ioc->alloc_dma);
4578 ioc->reply_frames = NULL;
4579 ioc->req_frames = NULL;
4580 ioc->alloc_total -= sz;
4582 if (ioc->sense_buf_pool != NULL) {
4583 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4584 pci_free_consistent(ioc->pcidev,
4586 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
4587 ioc->sense_buf_pool = NULL;
4590 if (dma_mask == DMA_35BIT_MASK && !pci_set_dma_mask(ioc->pcidev,
4591 DMA_BIT_MASK(64)) && !pci_set_consistent_dma_mask(ioc->pcidev,
4593 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4594 "restoring 64 bit addressing\n", ioc->name));
4599 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4601 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4602 * from IOC via doorbell handshake method.
4603 * @ioc: Pointer to MPT_ADAPTER structure
4604 * @reqBytes: Size of the request in bytes
4605 * @req: Pointer to MPT request frame
4606 * @replyBytes: Expected size of the reply in bytes
4607 * @u16reply: Pointer to area where reply should be written
4608 * @maxwait: Max wait time for a reply (in seconds)
4609 * @sleepFlag: Specifies whether the process can sleep
4611 * NOTES: It is the callers responsibility to byte-swap fields in the
4612 * request which are greater than 1 byte in size. It is also the
4613 * callers responsibility to byte-swap response fields which are
4614 * greater than 1 byte in size.
4616 * Returns 0 for success, non-zero for failure.
4619 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
4620 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
4622 MPIDefaultReply_t *mptReply;
4627 * Get ready to cache a handshake reply
4629 ioc->hs_reply_idx = 0;
4630 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4631 mptReply->MsgLength = 0;
4634 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4635 * then tell IOC that we want to handshake a request of N words.
4636 * (WRITE u32val to Doorbell reg).
4638 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4639 CHIPREG_WRITE32(&ioc->chip->Doorbell,
4640 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
4641 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
4644 * Wait for IOC's doorbell handshake int
4646 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4649 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4650 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4652 /* Read doorbell and check for active bit */
4653 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
4657 * Clear doorbell int (WRITE 0 to IntStatus reg),
4658 * then wait for IOC to ACKnowledge that it's ready for
4659 * our handshake request.
4661 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4662 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4667 u8 *req_as_bytes = (u8 *) req;
4670 * Stuff request words via doorbell handshake,
4671 * with ACK from IOC for each.
4673 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
4674 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
4675 (req_as_bytes[(ii*4) + 1] << 8) |
4676 (req_as_bytes[(ii*4) + 2] << 16) |
4677 (req_as_bytes[(ii*4) + 3] << 24));
4679 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
4680 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4684 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req));
4685 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req);
4687 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n",
4688 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
4691 * Wait for completion of doorbell handshake reply from the IOC
4693 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
4696 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake reply count=%d%s\n",
4697 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
4700 * Copy out the cached reply...
4702 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
4703 u16reply[ii] = ioc->hs_reply[ii];
4711 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4713 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4714 * @ioc: Pointer to MPT_ADAPTER structure
4715 * @howlong: How long to wait (in seconds)
4716 * @sleepFlag: Specifies whether the process can sleep
4718 * This routine waits (up to ~2 seconds max) for IOC doorbell
4719 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4720 * bit in its IntStatus register being clear.
4722 * Returns a negative value on failure, else wait loop count.
4725 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4731 cntdn = 1000 * howlong;
4733 if (sleepFlag == CAN_SLEEP) {
4736 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4737 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4744 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4745 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4752 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell ACK (count=%d)\n",
4757 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4758 ioc->name, count, intstat);
4762 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4764 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4765 * @ioc: Pointer to MPT_ADAPTER structure
4766 * @howlong: How long to wait (in seconds)
4767 * @sleepFlag: Specifies whether the process can sleep
4769 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4770 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4772 * Returns a negative value on failure, else wait loop count.
4775 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4781 cntdn = 1000 * howlong;
4782 if (sleepFlag == CAN_SLEEP) {
4784 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4785 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4792 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4793 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4801 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4802 ioc->name, count, howlong));
4806 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4807 ioc->name, count, intstat);
4811 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4813 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4814 * @ioc: Pointer to MPT_ADAPTER structure
4815 * @howlong: How long to wait (in seconds)
4816 * @sleepFlag: Specifies whether the process can sleep
4818 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4819 * Reply is cached to IOC private area large enough to hold a maximum
4820 * of 128 bytes of reply data.
4822 * Returns a negative value on failure, else size of reply in WORDS.
4825 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4830 u16 *hs_reply = ioc->hs_reply;
4831 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4834 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4837 * Get first two u16's so we can look at IOC's intended reply MsgLength
4840 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4843 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4844 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4845 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4848 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4849 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4853 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4854 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4855 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4858 * If no error (and IOC said MsgLength is > 0), piece together
4859 * reply 16 bits at a time.
4861 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4862 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4864 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4865 /* don't overflow our IOC hs_reply[] buffer! */
4866 if (u16cnt < ARRAY_SIZE(ioc->hs_reply))
4867 hs_reply[u16cnt] = hword;
4868 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4871 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4873 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4876 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4881 else if (u16cnt != (2 * mptReply->MsgLength)) {
4884 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4889 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name));
4890 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply);
4892 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4893 ioc->name, t, u16cnt/2));
4897 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4899 * GetLanConfigPages - Fetch LANConfig pages.
4900 * @ioc: Pointer to MPT_ADAPTER structure
4902 * Return: 0 for success
4903 * -ENOMEM if no memory available
4904 * -EPERM if not allowed due to ISR context
4905 * -EAGAIN if no msg frames currently available
4906 * -EFAULT for non-successful reply or no reply (timeout)
4909 GetLanConfigPages(MPT_ADAPTER *ioc)
4911 ConfigPageHeader_t hdr;
4913 LANPage0_t *ppage0_alloc;
4914 dma_addr_t page0_dma;
4915 LANPage1_t *ppage1_alloc;
4916 dma_addr_t page1_dma;
4921 /* Get LAN Page 0 header */
4922 hdr.PageVersion = 0;
4925 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4926 cfg.cfghdr.hdr = &hdr;
4928 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4933 if ((rc = mpt_config(ioc, &cfg)) != 0)
4936 if (hdr.PageLength > 0) {
4937 data_sz = hdr.PageLength * 4;
4938 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4941 memset((u8 *)ppage0_alloc, 0, data_sz);
4942 cfg.physAddr = page0_dma;
4943 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4945 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4947 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4948 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4952 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4955 * Normalize endianness of structure data,
4956 * by byte-swapping all > 1 byte fields!
4965 /* Get LAN Page 1 header */
4966 hdr.PageVersion = 0;
4969 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4970 cfg.cfghdr.hdr = &hdr;
4972 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4976 if ((rc = mpt_config(ioc, &cfg)) != 0)
4979 if (hdr.PageLength == 0)
4982 data_sz = hdr.PageLength * 4;
4984 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4986 memset((u8 *)ppage1_alloc, 0, data_sz);
4987 cfg.physAddr = page1_dma;
4988 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4990 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4992 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4993 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4996 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4999 * Normalize endianness of structure data,
5000 * by byte-swapping all > 1 byte fields!
5008 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5010 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
5011 * @ioc: Pointer to MPT_ADAPTER structure
5012 * @persist_opcode: see below
5014 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
5015 * devices not currently present.
5016 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
5018 * NOTE: Don't use not this function during interrupt time.
5020 * Returns 0 for success, non-zero error
5023 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5025 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
5027 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
5028 SasIoUnitControlReply_t *sasIoUnitCntrReply;
5029 MPT_FRAME_HDR *mf = NULL;
5030 MPIHeader_t *mpi_hdr;
5032 unsigned long timeleft;
5034 mutex_lock(&ioc->mptbase_cmds.mutex);
5036 /* init the internal cmd struct */
5037 memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE);
5038 INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status)
5040 /* insure garbage is not sent to fw */
5041 switch(persist_opcode) {
5043 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
5044 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
5052 printk(KERN_DEBUG "%s: persist_opcode=%x\n",
5053 __func__, persist_opcode);
5055 /* Get a MF for this command.
5057 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5058 printk(KERN_DEBUG "%s: no msg frames!\n", __func__);
5063 mpi_hdr = (MPIHeader_t *) mf;
5064 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
5065 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
5066 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
5067 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
5068 sasIoUnitCntrReq->Operation = persist_opcode;
5070 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5071 timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done, 10*HZ);
5072 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
5074 printk(KERN_DEBUG "%s: failed\n", __func__);
5075 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
5078 printk(KERN_DEBUG "%s: Issuing Reset from %s!!\n",
5079 ioc->name, __func__);
5080 mpt_HardResetHandler(ioc, CAN_SLEEP);
5081 mpt_free_msg_frame(ioc, mf);
5086 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
5091 sasIoUnitCntrReply =
5092 (SasIoUnitControlReply_t *)ioc->mptbase_cmds.reply;
5093 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
5094 printk(KERN_DEBUG "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
5095 __func__, sasIoUnitCntrReply->IOCStatus,
5096 sasIoUnitCntrReply->IOCLogInfo);
5097 printk(KERN_DEBUG "%s: failed\n", __func__);
5100 printk(KERN_DEBUG "%s: success\n", __func__);
5103 CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status)
5104 mutex_unlock(&ioc->mptbase_cmds.mutex);
5108 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5111 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
5112 MpiEventDataRaid_t * pRaidEventData)
5121 volume = pRaidEventData->VolumeID;
5122 reason = pRaidEventData->ReasonCode;
5123 disk = pRaidEventData->PhysDiskNum;
5124 status = le32_to_cpu(pRaidEventData->SettingsStatus);
5125 flags = (status >> 0) & 0xff;
5126 state = (status >> 8) & 0xff;
5128 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
5132 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
5133 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
5134 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
5135 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
5136 ioc->name, disk, volume);
5138 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
5143 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
5144 printk(MYIOC_s_INFO_FMT " volume has been created\n",
5148 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
5150 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
5154 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
5155 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
5159 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
5160 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
5162 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
5164 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
5166 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
5169 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
5171 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
5172 ? ", quiesced" : "",
5173 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
5174 ? ", resync in progress" : "" );
5177 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
5178 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
5182 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
5183 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
5187 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
5188 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
5192 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
5193 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
5197 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
5198 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
5200 state == MPI_PHYSDISK0_STATUS_ONLINE
5202 : state == MPI_PHYSDISK0_STATUS_MISSING
5204 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
5206 : state == MPI_PHYSDISK0_STATUS_FAILED
5208 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
5210 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
5211 ? "offline requested"
5212 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
5213 ? "failed requested"
5214 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
5217 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
5218 ? ", out of sync" : "",
5219 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
5220 ? ", quiesced" : "" );
5223 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
5224 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
5228 case MPI_EVENT_RAID_RC_SMART_DATA:
5229 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
5230 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
5233 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
5234 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
5240 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5242 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
5243 * @ioc: Pointer to MPT_ADAPTER structure
5245 * Returns: 0 for success
5246 * -ENOMEM if no memory available
5247 * -EPERM if not allowed due to ISR context
5248 * -EAGAIN if no msg frames currently available
5249 * -EFAULT for non-successful reply or no reply (timeout)
5252 GetIoUnitPage2(MPT_ADAPTER *ioc)
5254 ConfigPageHeader_t hdr;
5256 IOUnitPage2_t *ppage_alloc;
5257 dma_addr_t page_dma;
5261 /* Get the page header */
5262 hdr.PageVersion = 0;
5265 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
5266 cfg.cfghdr.hdr = &hdr;
5268 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5273 if ((rc = mpt_config(ioc, &cfg)) != 0)
5276 if (hdr.PageLength == 0)
5279 /* Read the config page */
5280 data_sz = hdr.PageLength * 4;
5282 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
5284 memset((u8 *)ppage_alloc, 0, data_sz);
5285 cfg.physAddr = page_dma;
5286 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5288 /* If Good, save data */
5289 if ((rc = mpt_config(ioc, &cfg)) == 0)
5290 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
5292 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
5298 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5300 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
5301 * @ioc: Pointer to a Adapter Strucutre
5302 * @portnum: IOC port number
5304 * Return: -EFAULT if read of config page header fails
5306 * If read of SCSI Port Page 0 fails,
5307 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5308 * Adapter settings: async, narrow
5310 * If read of SCSI Port Page 2 fails,
5311 * Adapter settings valid
5312 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5317 * CHECK - what type of locking mechanisms should be used????
5320 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
5325 ConfigPageHeader_t header;
5331 if (!ioc->spi_data.nvram) {
5334 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
5335 mem = kmalloc(sz, GFP_ATOMIC);
5339 ioc->spi_data.nvram = (int *) mem;
5341 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
5342 ioc->name, ioc->spi_data.nvram, sz));
5345 /* Invalidate NVRAM information
5347 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5348 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
5351 /* Read SPP0 header, allocate memory, then read page.
5353 header.PageVersion = 0;
5354 header.PageLength = 0;
5355 header.PageNumber = 0;
5356 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5357 cfg.cfghdr.hdr = &header;
5359 cfg.pageAddr = portnum;
5360 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5362 cfg.timeout = 0; /* use default */
5363 if (mpt_config(ioc, &cfg) != 0)
5366 if (header.PageLength > 0) {
5367 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5369 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5370 cfg.physAddr = buf_dma;
5371 if (mpt_config(ioc, &cfg) != 0) {
5372 ioc->spi_data.maxBusWidth = MPT_NARROW;
5373 ioc->spi_data.maxSyncOffset = 0;
5374 ioc->spi_data.minSyncFactor = MPT_ASYNC;
5375 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
5377 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5378 "Unable to read PortPage0 minSyncFactor=%x\n",
5379 ioc->name, ioc->spi_data.minSyncFactor));
5381 /* Save the Port Page 0 data
5383 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
5384 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
5385 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
5387 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
5388 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
5389 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5390 "noQas due to Capabilities=%x\n",
5391 ioc->name, pPP0->Capabilities));
5393 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
5394 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
5396 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
5397 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
5398 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
5399 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5400 "PortPage0 minSyncFactor=%x\n",
5401 ioc->name, ioc->spi_data.minSyncFactor));
5403 ioc->spi_data.maxSyncOffset = 0;
5404 ioc->spi_data.minSyncFactor = MPT_ASYNC;
5407 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
5409 /* Update the minSyncFactor based on bus type.
5411 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
5412 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
5414 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
5415 ioc->spi_data.minSyncFactor = MPT_ULTRA;
5416 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5417 "HVD or SE detected, minSyncFactor=%x\n",
5418 ioc->name, ioc->spi_data.minSyncFactor));
5423 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5428 /* SCSI Port Page 2 - Read the header then the page.
5430 header.PageVersion = 0;
5431 header.PageLength = 0;
5432 header.PageNumber = 2;
5433 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5434 cfg.cfghdr.hdr = &header;
5436 cfg.pageAddr = portnum;
5437 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5439 if (mpt_config(ioc, &cfg) != 0)
5442 if (header.PageLength > 0) {
5443 /* Allocate memory and read SCSI Port Page 2
5445 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5447 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
5448 cfg.physAddr = buf_dma;
5449 if (mpt_config(ioc, &cfg) != 0) {
5450 /* Nvram data is left with INVALID mark
5453 } else if (ioc->pcidev->vendor == PCI_VENDOR_ID_ATTO) {
5455 /* This is an ATTO adapter, read Page2 accordingly
5457 ATTO_SCSIPortPage2_t *pPP2 = (ATTO_SCSIPortPage2_t *) pbuf;
5458 ATTODeviceInfo_t *pdevice = NULL;
5461 /* Save the Port Page 2 data
5462 * (reformat into a 32bit quantity)
5464 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5465 pdevice = &pPP2->DeviceSettings[ii];
5466 ATTOFlags = le16_to_cpu(pdevice->ATTOFlags);
5469 /* Translate ATTO device flags to LSI format
5471 if (ATTOFlags & ATTOFLAG_DISC)
5472 data |= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE);
5473 if (ATTOFlags & ATTOFLAG_ID_ENB)
5474 data |= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE);
5475 if (ATTOFlags & ATTOFLAG_LUN_ENB)
5476 data |= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE);
5477 if (ATTOFlags & ATTOFLAG_TAGGED)
5478 data |= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE);
5479 if (!(ATTOFlags & ATTOFLAG_WIDE_ENB))
5480 data |= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE);
5482 data = (data << 16) | (pdevice->Period << 8) | 10;
5483 ioc->spi_data.nvram[ii] = data;
5486 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
5487 MpiDeviceInfo_t *pdevice = NULL;
5490 * Save "Set to Avoid SCSI Bus Resets" flag
5492 ioc->spi_data.bus_reset =
5493 (le32_to_cpu(pPP2->PortFlags) &
5494 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
5497 /* Save the Port Page 2 data
5498 * (reformat into a 32bit quantity)
5500 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
5501 ioc->spi_data.PortFlags = data;
5502 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5503 pdevice = &pPP2->DeviceSettings[ii];
5504 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
5505 (pdevice->SyncFactor << 8) | pdevice->Timeout;
5506 ioc->spi_data.nvram[ii] = data;
5510 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5514 /* Update Adapter limits with those from NVRAM
5515 * Comment: Don't need to do this. Target performance
5516 * parameters will never exceed the adapters limits.
5522 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5524 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
5525 * @ioc: Pointer to a Adapter Strucutre
5526 * @portnum: IOC port number
5528 * Return: -EFAULT if read of config page header fails
5532 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
5535 ConfigPageHeader_t header;
5537 /* Read the SCSI Device Page 1 header
5539 header.PageVersion = 0;
5540 header.PageLength = 0;
5541 header.PageNumber = 1;
5542 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5543 cfg.cfghdr.hdr = &header;
5545 cfg.pageAddr = portnum;
5546 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5549 if (mpt_config(ioc, &cfg) != 0)
5552 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
5553 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
5555 header.PageVersion = 0;
5556 header.PageLength = 0;
5557 header.PageNumber = 0;
5558 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5559 if (mpt_config(ioc, &cfg) != 0)
5562 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
5563 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
5565 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 0: version %d length %d\n",
5566 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
5568 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 1: version %d length %d\n",
5569 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
5574 * mpt_inactive_raid_list_free - This clears this link list.
5575 * @ioc : pointer to per adapter structure
5578 mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
5580 struct inactive_raid_component_info *component_info, *pNext;
5582 if (list_empty(&ioc->raid_data.inactive_list))
5585 mutex_lock(&ioc->raid_data.inactive_list_mutex);
5586 list_for_each_entry_safe(component_info, pNext,
5587 &ioc->raid_data.inactive_list, list) {
5588 list_del(&component_info->list);
5589 kfree(component_info);
5591 mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5595 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5597 * @ioc : pointer to per adapter structure
5598 * @channel : volume channel
5599 * @id : volume target id
5602 mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
5605 ConfigPageHeader_t hdr;
5606 dma_addr_t dma_handle;
5607 pRaidVolumePage0_t buffer = NULL;
5609 RaidPhysDiskPage0_t phys_disk;
5610 struct inactive_raid_component_info *component_info;
5611 int handle_inactive_volumes;
5613 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5614 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5615 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
5616 cfg.pageAddr = (channel << 8) + id;
5617 cfg.cfghdr.hdr = &hdr;
5618 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5620 if (mpt_config(ioc, &cfg) != 0)
5623 if (!hdr.PageLength)
5626 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5632 cfg.physAddr = dma_handle;
5633 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5635 if (mpt_config(ioc, &cfg) != 0)
5638 if (!buffer->NumPhysDisks)
5641 handle_inactive_volumes =
5642 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
5643 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
5644 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
5645 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
5647 if (!handle_inactive_volumes)
5650 mutex_lock(&ioc->raid_data.inactive_list_mutex);
5651 for (i = 0; i < buffer->NumPhysDisks; i++) {
5652 if(mpt_raid_phys_disk_pg0(ioc,
5653 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
5656 if ((component_info = kmalloc(sizeof (*component_info),
5657 GFP_KERNEL)) == NULL)
5660 component_info->volumeID = id;
5661 component_info->volumeBus = channel;
5662 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
5663 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
5664 component_info->d.PhysDiskID = phys_disk.PhysDiskID;
5665 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
5667 list_add_tail(&component_info->list,
5668 &ioc->raid_data.inactive_list);
5670 mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5674 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5679 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5680 * @ioc: Pointer to a Adapter Structure
5681 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5682 * @phys_disk: requested payload data returned
5686 * -EFAULT if read of config page header fails or data pointer not NULL
5687 * -ENOMEM if pci_alloc failed
5690 mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num,
5691 RaidPhysDiskPage0_t *phys_disk)
5694 ConfigPageHeader_t hdr;
5695 dma_addr_t dma_handle;
5696 pRaidPhysDiskPage0_t buffer = NULL;
5699 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5700 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5701 memset(phys_disk, 0, sizeof(RaidPhysDiskPage0_t));
5703 hdr.PageVersion = MPI_RAIDPHYSDISKPAGE0_PAGEVERSION;
5704 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5705 cfg.cfghdr.hdr = &hdr;
5707 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5709 if (mpt_config(ioc, &cfg) != 0) {
5714 if (!hdr.PageLength) {
5719 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5727 cfg.physAddr = dma_handle;
5728 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5729 cfg.pageAddr = phys_disk_num;
5731 if (mpt_config(ioc, &cfg) != 0) {
5737 memcpy(phys_disk, buffer, sizeof(*buffer));
5738 phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
5743 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5750 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5751 * @ioc: Pointer to a Adapter Strucutre
5755 * -EFAULT if read of config page header fails or data pointer not NULL
5756 * -ENOMEM if pci_alloc failed
5759 mpt_findImVolumes(MPT_ADAPTER *ioc)
5763 dma_addr_t ioc2_dma;
5765 ConfigPageHeader_t header;
5770 if (!ioc->ir_firmware)
5773 /* Free the old page
5775 kfree(ioc->raid_data.pIocPg2);
5776 ioc->raid_data.pIocPg2 = NULL;
5777 mpt_inactive_raid_list_free(ioc);
5779 /* Read IOCP2 header then the page.
5781 header.PageVersion = 0;
5782 header.PageLength = 0;
5783 header.PageNumber = 2;
5784 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5785 cfg.cfghdr.hdr = &header;
5788 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5791 if (mpt_config(ioc, &cfg) != 0)
5794 if (header.PageLength == 0)
5797 iocpage2sz = header.PageLength * 4;
5798 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
5802 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5803 cfg.physAddr = ioc2_dma;
5804 if (mpt_config(ioc, &cfg) != 0)
5807 mem = kmalloc(iocpage2sz, GFP_KERNEL);
5811 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
5812 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
5814 mpt_read_ioc_pg_3(ioc);
5816 for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
5817 mpt_inactive_raid_volumes(ioc,
5818 pIoc2->RaidVolume[i].VolumeBus,
5819 pIoc2->RaidVolume[i].VolumeID);
5822 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
5828 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
5833 ConfigPageHeader_t header;
5834 dma_addr_t ioc3_dma;
5837 /* Free the old page
5839 kfree(ioc->raid_data.pIocPg3);
5840 ioc->raid_data.pIocPg3 = NULL;
5842 /* There is at least one physical disk.
5843 * Read and save IOC Page 3
5845 header.PageVersion = 0;
5846 header.PageLength = 0;
5847 header.PageNumber = 3;
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 /* Read Header good, alloc memory
5863 iocpage3sz = header.PageLength * 4;
5864 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
5868 /* Read the Page and save the data
5869 * into malloc'd memory.
5871 cfg.physAddr = ioc3_dma;
5872 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5873 if (mpt_config(ioc, &cfg) == 0) {
5874 mem = kmalloc(iocpage3sz, GFP_KERNEL);
5876 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
5877 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
5881 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
5887 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
5891 ConfigPageHeader_t header;
5892 dma_addr_t ioc4_dma;
5895 /* Read and save IOC Page 4
5897 header.PageVersion = 0;
5898 header.PageLength = 0;
5899 header.PageNumber = 4;
5900 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5901 cfg.cfghdr.hdr = &header;
5904 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5907 if (mpt_config(ioc, &cfg) != 0)
5910 if (header.PageLength == 0)
5913 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
5914 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
5915 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
5918 ioc->alloc_total += iocpage4sz;
5920 ioc4_dma = ioc->spi_data.IocPg4_dma;
5921 iocpage4sz = ioc->spi_data.IocPg4Sz;
5924 /* Read the Page into dma memory.
5926 cfg.physAddr = ioc4_dma;
5927 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5928 if (mpt_config(ioc, &cfg) == 0) {
5929 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
5930 ioc->spi_data.IocPg4_dma = ioc4_dma;
5931 ioc->spi_data.IocPg4Sz = iocpage4sz;
5933 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
5934 ioc->spi_data.pIocPg4 = NULL;
5935 ioc->alloc_total -= iocpage4sz;
5940 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
5944 ConfigPageHeader_t header;
5945 dma_addr_t ioc1_dma;
5949 /* Check the Coalescing Timeout in IOC Page 1
5951 header.PageVersion = 0;
5952 header.PageLength = 0;
5953 header.PageNumber = 1;
5954 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5955 cfg.cfghdr.hdr = &header;
5958 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5961 if (mpt_config(ioc, &cfg) != 0)
5964 if (header.PageLength == 0)
5967 /* Read Header good, alloc memory
5969 iocpage1sz = header.PageLength * 4;
5970 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
5974 /* Read the Page and check coalescing timeout
5976 cfg.physAddr = ioc1_dma;
5977 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5978 if (mpt_config(ioc, &cfg) == 0) {
5980 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
5981 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
5982 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
5984 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Coalescing Enabled Timeout = %d\n",
5987 if (tmp > MPT_COALESCING_TIMEOUT) {
5988 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
5990 /* Write NVRAM and current
5993 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5994 if (mpt_config(ioc, &cfg) == 0) {
5995 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Reset Current Coalescing Timeout to = %d\n",
5996 ioc->name, MPT_COALESCING_TIMEOUT));
5998 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
5999 if (mpt_config(ioc, &cfg) == 0) {
6000 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6001 "Reset NVRAM Coalescing Timeout to = %d\n",
6002 ioc->name, MPT_COALESCING_TIMEOUT));
6004 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6005 "Reset NVRAM Coalescing Timeout Failed\n",
6010 dprintk(ioc, printk(MYIOC_s_WARN_FMT
6011 "Reset of Current Coalescing Timeout Failed!\n",
6017 dprintk(ioc, printk(MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
6021 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
6027 mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
6030 ConfigPageHeader_t hdr;
6032 ManufacturingPage0_t *pbuf = NULL;
6034 memset(&cfg, 0 , sizeof(CONFIGPARMS));
6035 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
6037 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
6038 cfg.cfghdr.hdr = &hdr;
6040 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6043 if (mpt_config(ioc, &cfg) != 0)
6046 if (!cfg.cfghdr.hdr->PageLength)
6049 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6050 pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
6054 cfg.physAddr = buf_dma;
6056 if (mpt_config(ioc, &cfg) != 0)
6059 memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name));
6060 memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
6061 memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
6066 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
6069 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6071 * SendEventNotification - Send EventNotification (on or off) request to adapter
6072 * @ioc: Pointer to MPT_ADAPTER structure
6073 * @EvSwitch: Event switch flags
6074 * @sleepFlag: Specifies whether the process can sleep
6077 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch, int sleepFlag)
6079 EventNotification_t evn;
6080 MPIDefaultReply_t reply_buf;
6082 memset(&evn, 0, sizeof(EventNotification_t));
6083 memset(&reply_buf, 0, sizeof(MPIDefaultReply_t));
6085 evn.Function = MPI_FUNCTION_EVENT_NOTIFICATION;
6086 evn.Switch = EvSwitch;
6087 evn.MsgContext = cpu_to_le32(mpt_base_index << 16);
6089 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6090 "Sending EventNotification (%d) request %p\n",
6091 ioc->name, EvSwitch, &evn));
6093 return mpt_handshake_req_reply_wait(ioc, sizeof(EventNotification_t),
6094 (u32 *)&evn, sizeof(MPIDefaultReply_t), (u16 *)&reply_buf, 30,
6098 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6100 * SendEventAck - Send EventAck request to MPT adapter.
6101 * @ioc: Pointer to MPT_ADAPTER structure
6102 * @evnp: Pointer to original EventNotification request
6105 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
6109 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
6110 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
6111 ioc->name, __func__));
6115 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventAck\n", ioc->name));
6117 pAck->Function = MPI_FUNCTION_EVENT_ACK;
6118 pAck->ChainOffset = 0;
6119 pAck->Reserved[0] = pAck->Reserved[1] = 0;
6121 pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
6122 pAck->Event = evnp->Event;
6123 pAck->EventContext = evnp->EventContext;
6125 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
6130 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6132 * mpt_config - Generic function to issue config message
6133 * @ioc: Pointer to an adapter structure
6134 * @pCfg: Pointer to a configuration structure. Struct contains
6135 * action, page address, direction, physical address
6136 * and pointer to a configuration page header
6137 * Page header is updated.
6139 * Returns 0 for success
6140 * -EPERM if not allowed due to ISR context
6141 * -EAGAIN if no msg frames currently available
6142 * -EFAULT for non-successful reply or no reply (timeout)
6145 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
6148 ConfigReply_t *pReply;
6149 ConfigExtendedPageHeader_t *pExtHdr = NULL;
6155 u8 page_type = 0, extend_page;
6156 unsigned long timeleft;
6157 unsigned long flags;
6159 u8 issue_hard_reset = 0;
6162 /* Prevent calling wait_event() (below), if caller happens
6163 * to be in ISR context, because that is fatal!
6165 in_isr = in_interrupt();
6167 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
6172 /* don't send a config page during diag reset */
6173 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6174 if (ioc->ioc_reset_in_progress) {
6175 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6176 "%s: busy with host reset\n", ioc->name, __func__));
6177 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6180 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6182 /* don't send if no chance of success */
6184 mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_OPERATIONAL) {
6185 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6186 "%s: ioc not operational, %d, %xh\n",
6187 ioc->name, __func__, ioc->active,
6188 mpt_GetIocState(ioc, 0)));
6193 mutex_lock(&ioc->mptbase_cmds.mutex);
6194 /* init the internal cmd struct */
6195 memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE);
6196 INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status)
6198 /* Get and Populate a free Frame
6200 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
6201 dcprintk(ioc, printk(MYIOC_s_WARN_FMT
6202 "mpt_config: no msg frames!\n", ioc->name));
6207 pReq = (Config_t *)mf;
6208 pReq->Action = pCfg->action;
6210 pReq->ChainOffset = 0;
6211 pReq->Function = MPI_FUNCTION_CONFIG;
6213 /* Assume page type is not extended and clear "reserved" fields. */
6214 pReq->ExtPageLength = 0;
6215 pReq->ExtPageType = 0;
6218 for (ii=0; ii < 8; ii++)
6219 pReq->Reserved2[ii] = 0;
6221 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
6222 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
6223 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
6224 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
6226 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
6227 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
6228 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
6229 pReq->ExtPageType = pExtHdr->ExtPageType;
6230 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
6232 /* Page Length must be treated as a reserved field for the
6235 pReq->Header.PageLength = 0;
6238 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
6240 /* Add a SGE to the config request.
6243 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
6245 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
6247 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) ==
6248 MPI_CONFIG_PAGETYPE_EXTENDED) {
6249 flagsLength |= pExtHdr->ExtPageLength * 4;
6250 page_type = pReq->ExtPageType;
6253 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
6254 page_type = pReq->Header.PageType;
6258 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6259 "Sending Config request type 0x%x, page 0x%x and action %d\n",
6260 ioc->name, page_type, pReq->Header.PageNumber, pReq->Action));
6262 ioc->add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
6263 timeout = (pCfg->timeout < 15) ? HZ*15 : HZ*pCfg->timeout;
6264 mpt_put_msg_frame(mpt_base_index, ioc, mf);
6265 timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done,
6267 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
6269 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6270 "Failed Sending Config request type 0x%x, page 0x%x,"
6271 " action %d, status %xh, time left %ld\n\n",
6272 ioc->name, page_type, pReq->Header.PageNumber,
6273 pReq->Action, ioc->mptbase_cmds.status, timeleft));
6274 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
6277 issue_hard_reset = 1;
6281 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
6285 pReply = (ConfigReply_t *)ioc->mptbase_cmds.reply;
6286 ret = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
6287 if (ret == MPI_IOCSTATUS_SUCCESS) {
6289 pCfg->cfghdr.ehdr->ExtPageLength =
6290 le16_to_cpu(pReply->ExtPageLength);
6291 pCfg->cfghdr.ehdr->ExtPageType =
6292 pReply->ExtPageType;
6294 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
6295 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
6296 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
6297 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
6302 printk(MYIOC_s_INFO_FMT "Retry completed "
6303 "ret=0x%x timeleft=%ld\n",
6304 ioc->name, ret, timeleft);
6306 dcprintk(ioc, printk(KERN_DEBUG "IOCStatus=%04xh, IOCLogInfo=%08xh\n",
6307 ret, le32_to_cpu(pReply->IOCLogInfo)));
6311 CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status)
6312 mutex_unlock(&ioc->mptbase_cmds.mutex);
6313 if (issue_hard_reset) {
6314 issue_hard_reset = 0;
6315 printk(MYIOC_s_WARN_FMT "Issuing Reset from %s!!\n",
6316 ioc->name, __func__);
6317 mpt_HardResetHandler(ioc, CAN_SLEEP);
6318 mpt_free_msg_frame(ioc, mf);
6319 /* attempt one retry for a timed out command */
6321 printk(MYIOC_s_INFO_FMT
6322 "Attempting Retry Config request"
6323 " type 0x%x, page 0x%x,"
6324 " action %d\n", ioc->name, page_type,
6325 pCfg->cfghdr.hdr->PageNumber, pCfg->action);
6334 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6336 * mpt_ioc_reset - Base cleanup for hard reset
6337 * @ioc: Pointer to the adapter structure
6338 * @reset_phase: Indicates pre- or post-reset functionality
6340 * Remark: Frees resources with internally generated commands.
6343 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
6345 switch (reset_phase) {
6346 case MPT_IOC_SETUP_RESET:
6347 ioc->taskmgmt_quiesce_io = 1;
6348 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6349 "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
6351 case MPT_IOC_PRE_RESET:
6352 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6353 "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
6355 case MPT_IOC_POST_RESET:
6356 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6357 "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
6358 /* wake up mptbase_cmds */
6359 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) {
6360 ioc->mptbase_cmds.status |=
6361 MPT_MGMT_STATUS_DID_IOCRESET;
6362 complete(&ioc->mptbase_cmds.done);
6364 /* wake up taskmgmt_cmds */
6365 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
6366 ioc->taskmgmt_cmds.status |=
6367 MPT_MGMT_STATUS_DID_IOCRESET;
6368 complete(&ioc->taskmgmt_cmds.done);
6375 return 1; /* currently means nothing really */
6379 #ifdef CONFIG_PROC_FS /* { */
6380 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6382 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
6384 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6386 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
6388 * Returns 0 for success, non-zero for failure.
6391 procmpt_create(void)
6393 struct proc_dir_entry *ent;
6395 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
6396 if (mpt_proc_root_dir == NULL)
6399 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
6401 ent->read_proc = procmpt_summary_read;
6403 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
6405 ent->read_proc = procmpt_version_read;
6410 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6412 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
6414 * Returns 0 for success, non-zero for failure.
6417 procmpt_destroy(void)
6419 remove_proc_entry("version", mpt_proc_root_dir);
6420 remove_proc_entry("summary", mpt_proc_root_dir);
6421 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
6424 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6426 * procmpt_summary_read - Handle read request of a summary file
6427 * @buf: Pointer to area to write information
6428 * @start: Pointer to start pointer
6429 * @offset: Offset to start writing
6430 * @request: Amount of read data requested
6431 * @eof: Pointer to EOF integer
6434 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
6435 * Returns number of characters written to process performing the read.
6438 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6448 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
6452 list_for_each_entry(ioc, &ioc_list, list) {
6455 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
6458 if ((out-buf) >= request)
6465 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6468 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6470 * procmpt_version_read - Handle read request from /proc/mpt/version.
6471 * @buf: Pointer to area to write information
6472 * @start: Pointer to start pointer
6473 * @offset: Offset to start writing
6474 * @request: Amount of read data requested
6475 * @eof: Pointer to EOF integer
6478 * Returns number of characters written to process performing the read.
6481 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6484 int scsi, fc, sas, lan, ctl, targ, dmp;
6488 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
6489 len += sprintf(buf+len, " Fusion MPT base driver\n");
6491 scsi = fc = sas = lan = ctl = targ = dmp = 0;
6492 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6494 if (MptCallbacks[cb_idx]) {
6495 switch (MptDriverClass[cb_idx]) {
6497 if (!scsi++) drvname = "SPI host";
6500 if (!fc++) drvname = "FC host";
6503 if (!sas++) drvname = "SAS host";
6506 if (!lan++) drvname = "LAN";
6509 if (!targ++) drvname = "SCSI target";
6512 if (!ctl++) drvname = "ioctl";
6517 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
6521 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6524 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6526 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
6527 * @buf: Pointer to area to write information
6528 * @start: Pointer to start pointer
6529 * @offset: Offset to start writing
6530 * @request: Amount of read data requested
6531 * @eof: Pointer to EOF integer
6534 * Returns number of characters written to process performing the read.
6537 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6539 MPT_ADAPTER *ioc = data;
6545 mpt_get_fw_exp_ver(expVer, ioc);
6547 len = sprintf(buf, "%s:", ioc->name);
6548 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
6549 len += sprintf(buf+len, " (f/w download boot flag set)");
6550 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6551 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
6553 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
6554 ioc->facts.ProductID,
6556 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
6557 if (ioc->facts.FWImageSize)
6558 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
6559 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
6560 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
6561 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
6563 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
6564 ioc->facts.CurrentHostMfaHighAddr);
6565 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
6566 ioc->facts.CurrentSenseBufferHighAddr);
6568 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
6569 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
6571 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6572 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
6574 * Rounding UP to nearest 4-kB boundary here...
6576 sz = (ioc->req_sz * ioc->req_depth) + 128;
6577 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
6578 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6579 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
6580 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
6581 4*ioc->facts.RequestFrameSize,
6582 ioc->facts.GlobalCredits);
6584 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
6585 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
6586 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
6587 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6588 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
6589 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
6590 ioc->facts.CurReplyFrameSize,
6591 ioc->facts.ReplyQueueDepth);
6593 len += sprintf(buf+len, " MaxDevices = %d\n",
6594 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
6595 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
6598 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
6599 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
6601 ioc->facts.NumberOfPorts);
6602 if (ioc->bus_type == FC) {
6603 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
6604 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6605 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6606 a[5], a[4], a[3], a[2], a[1], a[0]);
6608 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
6609 ioc->fc_port_page0[p].WWNN.High,
6610 ioc->fc_port_page0[p].WWNN.Low,
6611 ioc->fc_port_page0[p].WWPN.High,
6612 ioc->fc_port_page0[p].WWPN.Low);
6616 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6619 #endif /* CONFIG_PROC_FS } */
6621 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6623 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
6626 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
6627 sprintf(buf, " (Exp %02d%02d)",
6628 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
6629 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
6632 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
6633 strcat(buf, " [MDBG]");
6637 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6639 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6640 * @ioc: Pointer to MPT_ADAPTER structure
6641 * @buffer: Pointer to buffer where IOC summary info should be written
6642 * @size: Pointer to number of bytes we wrote (set by this routine)
6643 * @len: Offset at which to start writing in buffer
6644 * @showlan: Display LAN stuff?
6646 * This routine writes (english readable) ASCII text, which represents
6647 * a summary of IOC information, to a buffer.
6650 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
6655 mpt_get_fw_exp_ver(expVer, ioc);
6658 * Shorter summary of attached ioc's...
6660 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6663 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
6664 ioc->facts.FWVersion.Word,
6666 ioc->facts.NumberOfPorts,
6669 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6670 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6671 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6672 a[5], a[4], a[3], a[2], a[1], a[0]);
6675 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
6678 y += sprintf(buffer+len+y, " (disabled)");
6680 y += sprintf(buffer+len+y, "\n");
6685 * mpt_set_taskmgmt_in_progress_flag - set flags associated with task managment
6686 * @ioc: Pointer to MPT_ADAPTER structure
6688 * Returns 0 for SUCCESS or -1 if FAILED.
6690 * If -1 is return, then it was not possible to set the flags
6693 mpt_set_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc)
6695 unsigned long flags;
6698 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6699 if (ioc->ioc_reset_in_progress || ioc->taskmgmt_in_progress ||
6700 (ioc->alt_ioc && ioc->alt_ioc->taskmgmt_in_progress)) {
6705 ioc->taskmgmt_in_progress = 1;
6706 ioc->taskmgmt_quiesce_io = 1;
6708 ioc->alt_ioc->taskmgmt_in_progress = 1;
6709 ioc->alt_ioc->taskmgmt_quiesce_io = 1;
6712 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6715 EXPORT_SYMBOL(mpt_set_taskmgmt_in_progress_flag);
6718 * mpt_clear_taskmgmt_in_progress_flag - clear flags associated with task managment
6719 * @ioc: Pointer to MPT_ADAPTER structure
6723 mpt_clear_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc)
6725 unsigned long flags;
6727 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6728 ioc->taskmgmt_in_progress = 0;
6729 ioc->taskmgmt_quiesce_io = 0;
6731 ioc->alt_ioc->taskmgmt_in_progress = 0;
6732 ioc->alt_ioc->taskmgmt_quiesce_io = 0;
6734 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6736 EXPORT_SYMBOL(mpt_clear_taskmgmt_in_progress_flag);
6740 * mpt_halt_firmware - Halts the firmware if it is operational and panic
6742 * @ioc: Pointer to MPT_ADAPTER structure
6746 mpt_halt_firmware(MPT_ADAPTER *ioc)
6750 ioc_raw_state = mpt_GetIocState(ioc, 0);
6752 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
6753 printk(MYIOC_s_ERR_FMT "IOC is in FAULT state (%04xh)!!!\n",
6754 ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
6755 panic("%s: IOC Fault (%04xh)!!!\n", ioc->name,
6756 ioc_raw_state & MPI_DOORBELL_DATA_MASK);
6758 CHIPREG_WRITE32(&ioc->chip->Doorbell, 0xC0FFEE00);
6759 panic("%s: Firmware is halted due to command timeout\n",
6763 EXPORT_SYMBOL(mpt_halt_firmware);
6765 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6769 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6771 * mpt_HardResetHandler - Generic reset handler
6772 * @ioc: Pointer to MPT_ADAPTER structure
6773 * @sleepFlag: Indicates if sleep or schedule must be called.
6775 * Issues SCSI Task Management call based on input arg values.
6776 * If TaskMgmt fails, returns associated SCSI request.
6778 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
6779 * or a non-interrupt thread. In the former, must not call schedule().
6781 * Note: A return of -1 is a FATAL error case, as it means a
6782 * FW reload/initialization failed.
6784 * Returns 0 for SUCCESS or -1 if FAILED.
6787 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6791 unsigned long flags;
6792 unsigned long time_count;
6794 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name));
6796 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
6797 printk("MF count 0x%x !\n", ioc->mfcnt);
6799 if (mpt_fwfault_debug)
6800 mpt_halt_firmware(ioc);
6802 /* Reset the adapter. Prevent more than 1 call to
6803 * mpt_do_ioc_recovery at any instant in time.
6805 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6806 if (ioc->ioc_reset_in_progress) {
6807 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6810 ioc->ioc_reset_in_progress = 1;
6812 ioc->alt_ioc->ioc_reset_in_progress = 1;
6813 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6815 /* FIXME: If do_ioc_recovery fails, repeat....
6818 /* The SCSI driver needs to adjust timeouts on all current
6819 * commands prior to the diagnostic reset being issued.
6820 * Prevents timeouts occurring during a diagnostic reset...very bad.
6821 * For all other protocol drivers, this is a no-op.
6823 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6824 if (MptResetHandlers[cb_idx]) {
6825 mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
6827 mpt_signal_reset(cb_idx, ioc->alt_ioc,
6828 MPT_IOC_SETUP_RESET);
6832 time_count = jiffies;
6833 rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag);
6835 printk(KERN_WARNING MYNAM
6836 ": WARNING - (%d) Cannot recover %s\n", rc, ioc->name);
6838 if (ioc->hard_resets < -1)
6842 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6843 ioc->ioc_reset_in_progress = 0;
6844 ioc->taskmgmt_quiesce_io = 0;
6845 ioc->taskmgmt_in_progress = 0;
6847 ioc->alt_ioc->ioc_reset_in_progress = 0;
6848 ioc->alt_ioc->taskmgmt_quiesce_io = 0;
6849 ioc->alt_ioc->taskmgmt_in_progress = 0;
6851 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6854 printk(MYIOC_s_DEBUG_FMT
6855 "HardResetHandler: completed (%d seconds): %s\n", ioc->name,
6856 jiffies_to_msecs(jiffies - time_count)/1000, ((rc == 0) ?
6857 "SUCCESS" : "FAILED")));
6862 #ifdef CONFIG_FUSION_LOGGING
6864 mpt_display_event_info(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply)
6870 char *evStr = ioc->evStr;
6872 event = le32_to_cpu(pEventReply->Event) & 0xFF;
6873 evData0 = le32_to_cpu(pEventReply->Data[0]);
6876 case MPI_EVENT_NONE:
6879 case MPI_EVENT_LOG_DATA:
6882 case MPI_EVENT_STATE_CHANGE:
6883 ds = "State Change";
6885 case MPI_EVENT_UNIT_ATTENTION:
6886 ds = "Unit Attention";
6888 case MPI_EVENT_IOC_BUS_RESET:
6889 ds = "IOC Bus Reset";
6891 case MPI_EVENT_EXT_BUS_RESET:
6892 ds = "External Bus Reset";
6894 case MPI_EVENT_RESCAN:
6895 ds = "Bus Rescan Event";
6897 case MPI_EVENT_LINK_STATUS_CHANGE:
6898 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
6899 ds = "Link Status(FAILURE) Change";
6901 ds = "Link Status(ACTIVE) Change";
6903 case MPI_EVENT_LOOP_STATE_CHANGE:
6904 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
6905 ds = "Loop State(LIP) Change";
6906 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
6907 ds = "Loop State(LPE) Change";
6909 ds = "Loop State(LPB) Change";
6911 case MPI_EVENT_LOGOUT:
6914 case MPI_EVENT_EVENT_CHANGE:
6920 case MPI_EVENT_INTEGRATED_RAID:
6922 u8 ReasonCode = (u8)(evData0 >> 16);
6923 switch (ReasonCode) {
6924 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
6925 ds = "Integrated Raid: Volume Created";
6927 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
6928 ds = "Integrated Raid: Volume Deleted";
6930 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
6931 ds = "Integrated Raid: Volume Settings Changed";
6933 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
6934 ds = "Integrated Raid: Volume Status Changed";
6936 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
6937 ds = "Integrated Raid: Volume Physdisk Changed";
6939 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
6940 ds = "Integrated Raid: Physdisk Created";
6942 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
6943 ds = "Integrated Raid: Physdisk Deleted";
6945 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
6946 ds = "Integrated Raid: Physdisk Settings Changed";
6948 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
6949 ds = "Integrated Raid: Physdisk Status Changed";
6951 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
6952 ds = "Integrated Raid: Domain Validation Needed";
6954 case MPI_EVENT_RAID_RC_SMART_DATA :
6955 ds = "Integrated Raid; Smart Data";
6957 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
6958 ds = "Integrated Raid: Replace Action Started";
6961 ds = "Integrated Raid";
6966 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
6967 ds = "SCSI Device Status Change";
6969 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
6971 u8 id = (u8)(evData0);
6972 u8 channel = (u8)(evData0 >> 8);
6973 u8 ReasonCode = (u8)(evData0 >> 16);
6974 switch (ReasonCode) {
6975 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
6976 snprintf(evStr, EVENT_DESCR_STR_SZ,
6977 "SAS Device Status Change: Added: "
6978 "id=%d channel=%d", id, channel);
6980 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
6981 snprintf(evStr, EVENT_DESCR_STR_SZ,
6982 "SAS Device Status Change: Deleted: "
6983 "id=%d channel=%d", id, channel);
6985 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
6986 snprintf(evStr, EVENT_DESCR_STR_SZ,
6987 "SAS Device Status Change: SMART Data: "
6988 "id=%d channel=%d", id, channel);
6990 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
6991 snprintf(evStr, EVENT_DESCR_STR_SZ,
6992 "SAS Device Status Change: No Persistancy: "
6993 "id=%d channel=%d", id, channel);
6995 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
6996 snprintf(evStr, EVENT_DESCR_STR_SZ,
6997 "SAS Device Status Change: Unsupported Device "
6998 "Discovered : id=%d channel=%d", id, channel);
7000 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
7001 snprintf(evStr, EVENT_DESCR_STR_SZ,
7002 "SAS Device Status Change: Internal Device "
7003 "Reset : id=%d channel=%d", id, channel);
7005 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
7006 snprintf(evStr, EVENT_DESCR_STR_SZ,
7007 "SAS Device Status Change: Internal Task "
7008 "Abort : id=%d channel=%d", id, channel);
7010 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
7011 snprintf(evStr, EVENT_DESCR_STR_SZ,
7012 "SAS Device Status Change: Internal Abort "
7013 "Task Set : id=%d channel=%d", id, channel);
7015 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
7016 snprintf(evStr, EVENT_DESCR_STR_SZ,
7017 "SAS Device Status Change: Internal Clear "
7018 "Task Set : id=%d channel=%d", id, channel);
7020 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
7021 snprintf(evStr, EVENT_DESCR_STR_SZ,
7022 "SAS Device Status Change: Internal Query "
7023 "Task : id=%d channel=%d", id, channel);
7026 snprintf(evStr, EVENT_DESCR_STR_SZ,
7027 "SAS Device Status Change: Unknown: "
7028 "id=%d channel=%d", id, channel);
7033 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
7034 ds = "Bus Timer Expired";
7036 case MPI_EVENT_QUEUE_FULL:
7038 u16 curr_depth = (u16)(evData0 >> 16);
7039 u8 channel = (u8)(evData0 >> 8);
7040 u8 id = (u8)(evData0);
7042 snprintf(evStr, EVENT_DESCR_STR_SZ,
7043 "Queue Full: channel=%d id=%d depth=%d",
7044 channel, id, curr_depth);
7047 case MPI_EVENT_SAS_SES:
7048 ds = "SAS SES Event";
7050 case MPI_EVENT_PERSISTENT_TABLE_FULL:
7051 ds = "Persistent Table Full";
7053 case MPI_EVENT_SAS_PHY_LINK_STATUS:
7055 u8 LinkRates = (u8)(evData0 >> 8);
7056 u8 PhyNumber = (u8)(evData0);
7057 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
7058 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
7059 switch (LinkRates) {
7060 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
7061 snprintf(evStr, EVENT_DESCR_STR_SZ,
7062 "SAS PHY Link Status: Phy=%d:"
7063 " Rate Unknown",PhyNumber);
7065 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
7066 snprintf(evStr, EVENT_DESCR_STR_SZ,
7067 "SAS PHY Link Status: Phy=%d:"
7068 " Phy Disabled",PhyNumber);
7070 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
7071 snprintf(evStr, EVENT_DESCR_STR_SZ,
7072 "SAS PHY Link Status: Phy=%d:"
7073 " Failed Speed Nego",PhyNumber);
7075 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
7076 snprintf(evStr, EVENT_DESCR_STR_SZ,
7077 "SAS PHY Link Status: Phy=%d:"
7078 " Sata OOB Completed",PhyNumber);
7080 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
7081 snprintf(evStr, EVENT_DESCR_STR_SZ,
7082 "SAS PHY Link Status: Phy=%d:"
7083 " Rate 1.5 Gbps",PhyNumber);
7085 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
7086 snprintf(evStr, EVENT_DESCR_STR_SZ,
7087 "SAS PHY Link Status: Phy=%d:"
7088 " Rate 3.0 Gpbs",PhyNumber);
7091 snprintf(evStr, EVENT_DESCR_STR_SZ,
7092 "SAS PHY Link Status: Phy=%d", PhyNumber);
7097 case MPI_EVENT_SAS_DISCOVERY_ERROR:
7098 ds = "SAS Discovery Error";
7100 case MPI_EVENT_IR_RESYNC_UPDATE:
7102 u8 resync_complete = (u8)(evData0 >> 16);
7103 snprintf(evStr, EVENT_DESCR_STR_SZ,
7104 "IR Resync Update: Complete = %d:",resync_complete);
7109 u8 id = (u8)(evData0);
7110 u8 channel = (u8)(evData0 >> 8);
7111 u8 phys_num = (u8)(evData0 >> 24);
7112 u8 ReasonCode = (u8)(evData0 >> 16);
7114 switch (ReasonCode) {
7115 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
7116 snprintf(evStr, EVENT_DESCR_STR_SZ,
7117 "IR2: LD State Changed: "
7118 "id=%d channel=%d phys_num=%d",
7119 id, channel, phys_num);
7121 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
7122 snprintf(evStr, EVENT_DESCR_STR_SZ,
7123 "IR2: PD State Changed "
7124 "id=%d channel=%d phys_num=%d",
7125 id, channel, phys_num);
7127 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
7128 snprintf(evStr, EVENT_DESCR_STR_SZ,
7129 "IR2: Bad Block Table Full: "
7130 "id=%d channel=%d phys_num=%d",
7131 id, channel, phys_num);
7133 case MPI_EVENT_IR2_RC_PD_INSERTED:
7134 snprintf(evStr, EVENT_DESCR_STR_SZ,
7135 "IR2: PD Inserted: "
7136 "id=%d channel=%d phys_num=%d",
7137 id, channel, phys_num);
7139 case MPI_EVENT_IR2_RC_PD_REMOVED:
7140 snprintf(evStr, EVENT_DESCR_STR_SZ,
7142 "id=%d channel=%d phys_num=%d",
7143 id, channel, phys_num);
7145 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
7146 snprintf(evStr, EVENT_DESCR_STR_SZ,
7147 "IR2: Foreign CFG Detected: "
7148 "id=%d channel=%d phys_num=%d",
7149 id, channel, phys_num);
7151 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
7152 snprintf(evStr, EVENT_DESCR_STR_SZ,
7153 "IR2: Rebuild Medium Error: "
7154 "id=%d channel=%d phys_num=%d",
7155 id, channel, phys_num);
7163 case MPI_EVENT_SAS_DISCOVERY:
7166 ds = "SAS Discovery: Start";
7168 ds = "SAS Discovery: Stop";
7171 case MPI_EVENT_LOG_ENTRY_ADDED:
7172 ds = "SAS Log Entry Added";
7175 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
7177 u8 phy_num = (u8)(evData0);
7178 u8 port_num = (u8)(evData0 >> 8);
7179 u8 port_width = (u8)(evData0 >> 16);
7180 u8 primative = (u8)(evData0 >> 24);
7181 snprintf(evStr, EVENT_DESCR_STR_SZ,
7182 "SAS Broadcase Primative: phy=%d port=%d "
7183 "width=%d primative=0x%02x",
7184 phy_num, port_num, port_width, primative);
7188 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
7190 u8 reason = (u8)(evData0);
7193 case MPI_EVENT_SAS_INIT_RC_ADDED:
7194 ds = "SAS Initiator Status Change: Added";
7196 case MPI_EVENT_SAS_INIT_RC_REMOVED:
7197 ds = "SAS Initiator Status Change: Deleted";
7200 ds = "SAS Initiator Status Change";
7206 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
7208 u8 max_init = (u8)(evData0);
7209 u8 current_init = (u8)(evData0 >> 8);
7211 snprintf(evStr, EVENT_DESCR_STR_SZ,
7212 "SAS Initiator Device Table Overflow: max initiators=%02d "
7213 "current initators=%02d",
7214 max_init, current_init);
7217 case MPI_EVENT_SAS_SMP_ERROR:
7219 u8 status = (u8)(evData0);
7220 u8 port_num = (u8)(evData0 >> 8);
7221 u8 result = (u8)(evData0 >> 16);
7223 if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
7224 snprintf(evStr, EVENT_DESCR_STR_SZ,
7225 "SAS SMP Error: port=%d result=0x%02x",
7227 else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
7228 snprintf(evStr, EVENT_DESCR_STR_SZ,
7229 "SAS SMP Error: port=%d : CRC Error",
7231 else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
7232 snprintf(evStr, EVENT_DESCR_STR_SZ,
7233 "SAS SMP Error: port=%d : Timeout",
7235 else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
7236 snprintf(evStr, EVENT_DESCR_STR_SZ,
7237 "SAS SMP Error: port=%d : No Destination",
7239 else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
7240 snprintf(evStr, EVENT_DESCR_STR_SZ,
7241 "SAS SMP Error: port=%d : Bad Destination",
7244 snprintf(evStr, EVENT_DESCR_STR_SZ,
7245 "SAS SMP Error: port=%d : status=0x%02x",
7250 case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
7252 u8 reason = (u8)(evData0);
7255 case MPI_EVENT_SAS_EXP_RC_ADDED:
7256 ds = "Expander Status Change: Added";
7258 case MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING:
7259 ds = "Expander Status Change: Deleted";
7262 ds = "Expander Status Change";
7269 * MPT base "custom" events may be added here...
7276 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
7279 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7280 "MPT event:(%02Xh) : %s\n",
7281 ioc->name, event, evStr));
7283 devtverboseprintk(ioc, printk(KERN_DEBUG MYNAM
7284 ": Event data:\n"));
7285 for (ii = 0; ii < le16_to_cpu(pEventReply->EventDataLength); ii++)
7286 devtverboseprintk(ioc, printk(" %08x",
7287 le32_to_cpu(pEventReply->Data[ii])));
7288 devtverboseprintk(ioc, printk(KERN_DEBUG "\n"));
7291 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7293 * ProcessEventNotification - Route EventNotificationReply to all event handlers
7294 * @ioc: Pointer to MPT_ADAPTER structure
7295 * @pEventReply: Pointer to EventNotification reply frame
7296 * @evHandlers: Pointer to integer, number of event handlers
7298 * Routes a received EventNotificationReply to all currently registered
7300 * Returns sum of event handlers return values.
7303 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
7314 * Do platform normalization of values
7316 event = le32_to_cpu(pEventReply->Event) & 0xFF;
7317 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
7319 evData0 = le32_to_cpu(pEventReply->Data[0]);
7322 #ifdef CONFIG_FUSION_LOGGING
7324 mpt_display_event_info(ioc, pEventReply);
7328 * Do general / base driver event processing
7331 case MPI_EVENT_EVENT_CHANGE: /* 0A */
7333 u8 evState = evData0 & 0xFF;
7335 /* CHECKME! What if evState unexpectedly says OFF (0)? */
7337 /* Update EventState field in cached IocFacts */
7338 if (ioc->facts.Function) {
7339 ioc->facts.EventState = evState;
7343 case MPI_EVENT_INTEGRATED_RAID:
7344 mptbase_raid_process_event_data(ioc,
7345 (MpiEventDataRaid_t *)pEventReply->Data);
7352 * Should this event be logged? Events are written sequentially.
7353 * When buffer is full, start again at the top.
7355 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
7358 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
7360 ioc->events[idx].event = event;
7361 ioc->events[idx].eventContext = ioc->eventContext;
7363 for (ii = 0; ii < 2; ii++) {
7365 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
7367 ioc->events[idx].data[ii] = 0;
7370 ioc->eventContext++;
7375 * Call each currently registered protocol event handler.
7377 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7378 if (MptEvHandlers[cb_idx]) {
7379 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7380 "Routing Event to event handler #%d\n",
7381 ioc->name, cb_idx));
7382 r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply);
7386 /* FIXME? Examine results here? */
7389 * If needed, send (a single) EventAck.
7391 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
7392 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7393 "EventAck required\n",ioc->name));
7394 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
7395 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SendEventAck returned %d\n",
7400 *evHandlers = handlers;
7404 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7406 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
7407 * @ioc: Pointer to MPT_ADAPTER structure
7408 * @log_info: U32 LogInfo reply word from the IOC
7410 * Refer to lsi/mpi_log_fc.h.
7413 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
7415 char *desc = "unknown";
7417 switch (log_info & 0xFF000000) {
7418 case MPI_IOCLOGINFO_FC_INIT_BASE:
7419 desc = "FCP Initiator";
7421 case MPI_IOCLOGINFO_FC_TARGET_BASE:
7422 desc = "FCP Target";
7424 case MPI_IOCLOGINFO_FC_LAN_BASE:
7427 case MPI_IOCLOGINFO_FC_MSG_BASE:
7428 desc = "MPI Message Layer";
7430 case MPI_IOCLOGINFO_FC_LINK_BASE:
7433 case MPI_IOCLOGINFO_FC_CTX_BASE:
7434 desc = "Context Manager";
7436 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
7437 desc = "Invalid Field Offset";
7439 case MPI_IOCLOGINFO_FC_STATE_CHANGE:
7440 desc = "State Change Info";
7444 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
7445 ioc->name, log_info, desc, (log_info & 0xFFFFFF));
7448 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7450 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
7451 * @ioc: Pointer to MPT_ADAPTER structure
7452 * @log_info: U32 LogInfo word from the IOC
7454 * Refer to lsi/sp_log.h.
7457 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
7459 u32 info = log_info & 0x00FF0000;
7460 char *desc = "unknown";
7464 desc = "bug! MID not found";
7468 desc = "Parity Error";
7472 desc = "ASYNC Outbound Overrun";
7476 desc = "SYNC Offset Error";
7484 desc = "Msg In Overflow";
7492 desc = "Outbound DMA Overrun";
7496 desc = "Task Management";
7500 desc = "Device Problem";
7504 desc = "Invalid Phase Change";
7508 desc = "Untagged Table Size";
7513 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
7516 /* strings for sas loginfo */
7517 static char *originator_str[] = {
7522 static char *iop_code_str[] = {
7524 "Invalid SAS Address", /* 01h */
7526 "Invalid Page", /* 03h */
7527 "Diag Message Error", /* 04h */
7528 "Task Terminated", /* 05h */
7529 "Enclosure Management", /* 06h */
7530 "Target Mode" /* 07h */
7532 static char *pl_code_str[] = {
7534 "Open Failure", /* 01h */
7535 "Invalid Scatter Gather List", /* 02h */
7536 "Wrong Relative Offset or Frame Length", /* 03h */
7537 "Frame Transfer Error", /* 04h */
7538 "Transmit Frame Connected Low", /* 05h */
7539 "SATA Non-NCQ RW Error Bit Set", /* 06h */
7540 "SATA Read Log Receive Data Error", /* 07h */
7541 "SATA NCQ Fail All Commands After Error", /* 08h */
7542 "SATA Error in Receive Set Device Bit FIS", /* 09h */
7543 "Receive Frame Invalid Message", /* 0Ah */
7544 "Receive Context Message Valid Error", /* 0Bh */
7545 "Receive Frame Current Frame Error", /* 0Ch */
7546 "SATA Link Down", /* 0Dh */
7547 "Discovery SATA Init W IOS", /* 0Eh */
7548 "Config Invalid Page", /* 0Fh */
7549 "Discovery SATA Init Timeout", /* 10h */
7552 "IO Not Yet Executed", /* 13h */
7553 "IO Executed", /* 14h */
7554 "Persistent Reservation Out Not Affiliation "
7556 "Open Transmit DMA Abort", /* 16h */
7557 "IO Device Missing Delay Retry", /* 17h */
7558 "IO Cancelled Due to Recieve Error", /* 18h */
7566 "Enclosure Management" /* 20h */
7568 static char *ir_code_str[] = {
7569 "Raid Action Error", /* 00h */
7579 static char *raid_sub_code_str[] = {
7581 "Volume Creation Failed: Data Passed too "
7583 "Volume Creation Failed: Duplicate Volumes "
7584 "Attempted", /* 02h */
7585 "Volume Creation Failed: Max Number "
7586 "Supported Volumes Exceeded", /* 03h */
7587 "Volume Creation Failed: DMA Error", /* 04h */
7588 "Volume Creation Failed: Invalid Volume Type", /* 05h */
7589 "Volume Creation Failed: Error Reading "
7590 "MFG Page 4", /* 06h */
7591 "Volume Creation Failed: Creating Internal "
7592 "Structures", /* 07h */
7601 "Activation failed: Already Active Volume", /* 10h */
7602 "Activation failed: Unsupported Volume Type", /* 11h */
7603 "Activation failed: Too Many Active Volumes", /* 12h */
7604 "Activation failed: Volume ID in Use", /* 13h */
7605 "Activation failed: Reported Failure", /* 14h */
7606 "Activation failed: Importing a Volume", /* 15h */
7617 "Phys Disk failed: Too Many Phys Disks", /* 20h */
7618 "Phys Disk failed: Data Passed too Large", /* 21h */
7619 "Phys Disk failed: DMA Error", /* 22h */
7620 "Phys Disk failed: Invalid <channel:id>", /* 23h */
7621 "Phys Disk failed: Creating Phys Disk Config "
7634 "Compatibility Error: IR Disabled", /* 30h */
7635 "Compatibility Error: Inquiry Comand Failed", /* 31h */
7636 "Compatibility Error: Device not Direct Access "
7637 "Device ", /* 32h */
7638 "Compatibility Error: Removable Device Found", /* 33h */
7639 "Compatibility Error: Device SCSI Version not "
7640 "2 or Higher", /* 34h */
7641 "Compatibility Error: SATA Device, 48 BIT LBA "
7642 "not Supported", /* 35h */
7643 "Compatibility Error: Device doesn't have "
7644 "512 Byte Block Sizes", /* 36h */
7645 "Compatibility Error: Volume Type Check Failed", /* 37h */
7646 "Compatibility Error: Volume Type is "
7647 "Unsupported by FW", /* 38h */
7648 "Compatibility Error: Disk Drive too Small for "
7649 "use in Volume", /* 39h */
7650 "Compatibility Error: Phys Disk for Create "
7651 "Volume not Found", /* 3Ah */
7652 "Compatibility Error: Too Many or too Few "
7653 "Disks for Volume Type", /* 3Bh */
7654 "Compatibility Error: Disk stripe Sizes "
7655 "Must be 64KB", /* 3Ch */
7656 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
7659 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7661 * mpt_sas_log_info - Log information returned from SAS IOC.
7662 * @ioc: Pointer to MPT_ADAPTER structure
7663 * @log_info: U32 LogInfo reply word from the IOC
7665 * Refer to lsi/mpi_log_sas.h.
7668 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
7670 union loginfo_type {
7679 union loginfo_type sas_loginfo;
7680 char *originator_desc = NULL;
7681 char *code_desc = NULL;
7682 char *sub_code_desc = NULL;
7684 sas_loginfo.loginfo = log_info;
7685 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
7686 (sas_loginfo.dw.originator < ARRAY_SIZE(originator_str)))
7689 originator_desc = originator_str[sas_loginfo.dw.originator];
7691 switch (sas_loginfo.dw.originator) {
7694 if (sas_loginfo.dw.code <
7695 ARRAY_SIZE(iop_code_str))
7696 code_desc = iop_code_str[sas_loginfo.dw.code];
7699 if (sas_loginfo.dw.code <
7700 ARRAY_SIZE(pl_code_str))
7701 code_desc = pl_code_str[sas_loginfo.dw.code];
7704 if (sas_loginfo.dw.code >=
7705 ARRAY_SIZE(ir_code_str))
7707 code_desc = ir_code_str[sas_loginfo.dw.code];
7708 if (sas_loginfo.dw.subcode >=
7709 ARRAY_SIZE(raid_sub_code_str))
7711 if (sas_loginfo.dw.code == 0)
7713 raid_sub_code_str[sas_loginfo.dw.subcode];
7719 if (sub_code_desc != NULL)
7720 printk(MYIOC_s_INFO_FMT
7721 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7723 ioc->name, log_info, originator_desc, code_desc,
7725 else if (code_desc != NULL)
7726 printk(MYIOC_s_INFO_FMT
7727 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7728 " SubCode(0x%04x)\n",
7729 ioc->name, log_info, originator_desc, code_desc,
7730 sas_loginfo.dw.subcode);
7732 printk(MYIOC_s_INFO_FMT
7733 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
7734 " SubCode(0x%04x)\n",
7735 ioc->name, log_info, originator_desc,
7736 sas_loginfo.dw.code, sas_loginfo.dw.subcode);
7739 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7741 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
7742 * @ioc: Pointer to MPT_ADAPTER structure
7743 * @ioc_status: U32 IOCStatus word from IOC
7744 * @mf: Pointer to MPT request frame
7746 * Refer to lsi/mpi.h.
7749 mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7751 Config_t *pReq = (Config_t *)mf;
7752 char extend_desc[EVENT_DESCR_STR_SZ];
7757 if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
7758 page_type = pReq->ExtPageType;
7760 page_type = pReq->Header.PageType;
7763 * ignore invalid page messages for GET_NEXT_HANDLE
7765 form = le32_to_cpu(pReq->PageAddress);
7766 if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
7767 if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
7768 page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
7769 page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
7770 if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
7771 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
7774 if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
7775 if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
7776 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
7780 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
7781 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
7782 page_type, pReq->Header.PageNumber, pReq->Action, form);
7784 switch (ioc_status) {
7786 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7787 desc = "Config Page Invalid Action";
7790 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7791 desc = "Config Page Invalid Type";
7794 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7795 desc = "Config Page Invalid Page";
7798 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7799 desc = "Config Page Invalid Data";
7802 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7803 desc = "Config Page No Defaults";
7806 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7807 desc = "Config Page Can't Commit";
7814 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s: %s\n",
7815 ioc->name, ioc_status, desc, extend_desc));
7819 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
7820 * @ioc: Pointer to MPT_ADAPTER structure
7821 * @ioc_status: U32 IOCStatus word from IOC
7822 * @mf: Pointer to MPT request frame
7824 * Refer to lsi/mpi.h.
7827 mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7829 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
7834 /****************************************************************************/
7835 /* Common IOCStatus values for all replies */
7836 /****************************************************************************/
7838 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
7839 desc = "Invalid Function";
7842 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
7846 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
7847 desc = "Invalid SGL";
7850 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
7851 desc = "Internal Error";
7854 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
7858 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
7859 desc = "Insufficient Resources";
7862 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
7863 desc = "Invalid Field";
7866 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
7867 desc = "Invalid State";
7870 /****************************************************************************/
7871 /* Config IOCStatus values */
7872 /****************************************************************************/
7874 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7875 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7876 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7877 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7878 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7879 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7880 mpt_iocstatus_info_config(ioc, status, mf);
7883 /****************************************************************************/
7884 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
7886 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
7888 /****************************************************************************/
7890 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
7891 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
7892 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
7893 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
7894 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
7895 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
7896 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
7897 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
7898 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
7899 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
7900 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
7901 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
7902 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
7905 /****************************************************************************/
7906 /* SCSI Target values */
7907 /****************************************************************************/
7909 case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
7910 desc = "Target: Priority IO";
7913 case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
7914 desc = "Target: Invalid Port";
7917 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
7918 desc = "Target Invalid IO Index:";
7921 case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
7922 desc = "Target: Aborted";
7925 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
7926 desc = "Target: No Conn Retryable";
7929 case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
7930 desc = "Target: No Connection";
7933 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
7934 desc = "Target: Transfer Count Mismatch";
7937 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
7938 desc = "Target: STS Data not Sent";
7941 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
7942 desc = "Target: Data Offset Error";
7945 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
7946 desc = "Target: Too Much Write Data";
7949 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
7950 desc = "Target: IU Too Short";
7953 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
7954 desc = "Target: ACK NAK Timeout";
7957 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
7958 desc = "Target: Nak Received";
7961 /****************************************************************************/
7962 /* Fibre Channel Direct Access values */
7963 /****************************************************************************/
7965 case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
7966 desc = "FC: Aborted";
7969 case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
7970 desc = "FC: RX ID Invalid";
7973 case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
7974 desc = "FC: DID Invalid";
7977 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
7978 desc = "FC: Node Logged Out";
7981 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
7982 desc = "FC: Exchange Canceled";
7985 /****************************************************************************/
7987 /****************************************************************************/
7989 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
7990 desc = "LAN: Device not Found";
7993 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
7994 desc = "LAN: Device Failure";
7997 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
7998 desc = "LAN: Transmit Error";
8001 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
8002 desc = "LAN: Transmit Aborted";
8005 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
8006 desc = "LAN: Receive Error";
8009 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
8010 desc = "LAN: Receive Aborted";
8013 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
8014 desc = "LAN: Partial Packet";
8017 case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
8018 desc = "LAN: Canceled";
8021 /****************************************************************************/
8022 /* Serial Attached SCSI values */
8023 /****************************************************************************/
8025 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
8026 desc = "SAS: SMP Request Failed";
8029 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
8030 desc = "SAS: SMP Data Overrun";
8041 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s\n",
8042 ioc->name, status, desc));
8045 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8046 EXPORT_SYMBOL(mpt_attach);
8047 EXPORT_SYMBOL(mpt_detach);
8049 EXPORT_SYMBOL(mpt_resume);
8050 EXPORT_SYMBOL(mpt_suspend);
8052 EXPORT_SYMBOL(ioc_list);
8053 EXPORT_SYMBOL(mpt_register);
8054 EXPORT_SYMBOL(mpt_deregister);
8055 EXPORT_SYMBOL(mpt_event_register);
8056 EXPORT_SYMBOL(mpt_event_deregister);
8057 EXPORT_SYMBOL(mpt_reset_register);
8058 EXPORT_SYMBOL(mpt_reset_deregister);
8059 EXPORT_SYMBOL(mpt_device_driver_register);
8060 EXPORT_SYMBOL(mpt_device_driver_deregister);
8061 EXPORT_SYMBOL(mpt_get_msg_frame);
8062 EXPORT_SYMBOL(mpt_put_msg_frame);
8063 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri);
8064 EXPORT_SYMBOL(mpt_free_msg_frame);
8065 EXPORT_SYMBOL(mpt_send_handshake_request);
8066 EXPORT_SYMBOL(mpt_verify_adapter);
8067 EXPORT_SYMBOL(mpt_GetIocState);
8068 EXPORT_SYMBOL(mpt_print_ioc_summary);
8069 EXPORT_SYMBOL(mpt_HardResetHandler);
8070 EXPORT_SYMBOL(mpt_config);
8071 EXPORT_SYMBOL(mpt_findImVolumes);
8072 EXPORT_SYMBOL(mpt_alloc_fw_memory);
8073 EXPORT_SYMBOL(mpt_free_fw_memory);
8074 EXPORT_SYMBOL(mptbase_sas_persist_operation);
8075 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
8077 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8079 * fusion_init - Fusion MPT base driver initialization routine.
8081 * Returns 0 for success, non-zero for failure.
8088 show_mptmod_ver(my_NAME, my_VERSION);
8089 printk(KERN_INFO COPYRIGHT "\n");
8091 for (cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
8092 MptCallbacks[cb_idx] = NULL;
8093 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
8094 MptEvHandlers[cb_idx] = NULL;
8095 MptResetHandlers[cb_idx] = NULL;
8098 /* Register ourselves (mptbase) in order to facilitate
8099 * EventNotification handling.
8101 mpt_base_index = mpt_register(mptbase_reply, MPTBASE_DRIVER);
8103 /* Register for hard reset handling callbacks.
8105 mpt_reset_register(mpt_base_index, mpt_ioc_reset);
8107 #ifdef CONFIG_PROC_FS
8108 (void) procmpt_create();
8113 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8115 * fusion_exit - Perform driver unload cleanup.
8117 * This routine frees all resources associated with each MPT adapter
8118 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
8124 mpt_reset_deregister(mpt_base_index);
8126 #ifdef CONFIG_PROC_FS
8131 module_init(fusion_init);
8132 module_exit(fusion_exit);