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-2007 LSI Corporation
9 * (mailto:DL-MPTFusionLinux@lsi.com)
12 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; version 2 of the License.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
24 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
25 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
26 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
27 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
28 solely responsible for determining the appropriateness of using and
29 distributing the Program and assumes all risks associated with its
30 exercise of rights under this Agreement, including but not limited to
31 the risks and costs of program errors, damage to or loss of data,
32 programs or equipment, and unavailability or interruption of operations.
34 DISCLAIMER OF LIABILITY
35 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
36 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
38 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
39 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
40 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
41 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
43 You should have received a copy of the GNU General Public License
44 along with this program; if not, write to the Free Software
45 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
47 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
49 #include <linux/kernel.h>
50 #include <linux/module.h>
51 #include <linux/errno.h>
52 #include <linux/init.h>
53 #include <linux/slab.h>
54 #include <linux/types.h>
55 #include <linux/pci.h>
56 #include <linux/kdev_t.h>
57 #include <linux/blkdev.h>
58 #include <linux/delay.h>
59 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
60 #include <linux/dma-mapping.h>
67 #include "lsi/mpi_log_fc.h"
69 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
70 #define my_NAME "Fusion MPT base driver"
71 #define my_VERSION MPT_LINUX_VERSION_COMMON
72 #define MYNAM "mptbase"
74 MODULE_AUTHOR(MODULEAUTHOR);
75 MODULE_DESCRIPTION(my_NAME);
76 MODULE_LICENSE("GPL");
77 MODULE_VERSION(my_VERSION);
82 static int mpt_msi_enable = -1;
83 module_param(mpt_msi_enable, int, 0);
84 MODULE_PARM_DESC(mpt_msi_enable, " MSI Support Enable (default=0)");
86 static int mpt_channel_mapping;
87 module_param(mpt_channel_mapping, int, 0);
88 MODULE_PARM_DESC(mpt_channel_mapping, " Mapping id's to channels (default=0)");
90 static int mpt_debug_level;
91 static int mpt_set_debug_level(const char *val, struct kernel_param *kp);
92 module_param_call(mpt_debug_level, mpt_set_debug_level, param_get_int,
93 &mpt_debug_level, 0600);
94 MODULE_PARM_DESC(mpt_debug_level, " debug level - refer to mptdebug.h - (default=0)");
97 static int mfcounter = 0;
98 #define PRINT_MF_COUNT 20000
101 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
106 static struct proc_dir_entry *mpt_proc_root_dir;
108 #define WHOINIT_UNKNOWN 0xAA
110 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
114 /* Adapter link list */
116 /* Callback lookup table */
117 static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
118 /* Protocol driver class lookup table */
119 static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
120 /* Event handler lookup table */
121 static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
122 /* Reset handler lookup table */
123 static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
124 static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
126 static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq);
129 * Driver Callback Index's
131 static u8 mpt_base_index = MPT_MAX_PROTOCOL_DRIVERS;
132 static u8 last_drv_idx;
134 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
138 static irqreturn_t mpt_interrupt(int irq, void *bus_id);
139 static int mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
140 static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
141 u32 *req, int replyBytes, u16 *u16reply, int maxwait,
143 static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
144 static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
145 static void mpt_adapter_disable(MPT_ADAPTER *ioc);
146 static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
148 static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
149 static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
150 static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
151 static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
152 static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
153 static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
154 static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
155 static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
156 static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
157 static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
158 static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
159 static int PrimeIocFifos(MPT_ADAPTER *ioc);
160 static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
161 static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
162 static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
163 static int GetLanConfigPages(MPT_ADAPTER *ioc);
164 static int GetIoUnitPage2(MPT_ADAPTER *ioc);
165 int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
166 static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
167 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
168 static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
169 static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
170 static void mpt_timer_expired(unsigned long data);
171 static void mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc);
172 static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
173 static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
174 static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
175 static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
177 #ifdef CONFIG_PROC_FS
178 static int procmpt_summary_read(char *buf, char **start, off_t offset,
179 int request, int *eof, void *data);
180 static int procmpt_version_read(char *buf, char **start, off_t offset,
181 int request, int *eof, void *data);
182 static int procmpt_iocinfo_read(char *buf, char **start, off_t offset,
183 int request, int *eof, void *data);
185 static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
187 //int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
188 static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers);
189 static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
190 static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
191 static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
192 static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
193 static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
194 static void mpt_inactive_raid_list_free(MPT_ADAPTER *ioc);
196 /* module entry point */
197 static int __init fusion_init (void);
198 static void __exit fusion_exit (void);
200 #define CHIPREG_READ32(addr) readl_relaxed(addr)
201 #define CHIPREG_READ32_dmasync(addr) readl(addr)
202 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
203 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
204 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
207 pci_disable_io_access(struct pci_dev *pdev)
211 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
213 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
217 pci_enable_io_access(struct pci_dev *pdev)
221 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
223 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
226 static int mpt_set_debug_level(const char *val, struct kernel_param *kp)
228 int ret = param_set_int(val, kp);
234 list_for_each_entry(ioc, &ioc_list, list)
235 ioc->debug_level = mpt_debug_level;
240 * mpt_get_cb_idx - obtain cb_idx for registered driver
241 * @dclass: class driver enum
243 * Returns cb_idx, or zero means it wasn't found
246 mpt_get_cb_idx(MPT_DRIVER_CLASS dclass)
250 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--)
251 if (MptDriverClass[cb_idx] == dclass)
257 * Process turbo (context) reply...
260 mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
262 MPT_FRAME_HDR *mf = NULL;
263 MPT_FRAME_HDR *mr = NULL;
267 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got TURBO reply req_idx=%08x\n",
270 switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
271 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
272 req_idx = pa & 0x0000FFFF;
273 cb_idx = (pa & 0x00FF0000) >> 16;
274 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
276 case MPI_CONTEXT_REPLY_TYPE_LAN:
277 cb_idx = mpt_get_cb_idx(MPTLAN_DRIVER);
279 * Blind set of mf to NULL here was fatal
280 * after lan_reply says "freeme"
281 * Fix sort of combined with an optimization here;
282 * added explicit check for case where lan_reply
283 * was just returning 1 and doing nothing else.
284 * For this case skip the callback, but set up
285 * proper mf value first here:-)
287 if ((pa & 0x58000000) == 0x58000000) {
288 req_idx = pa & 0x0000FFFF;
289 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
290 mpt_free_msg_frame(ioc, mf);
295 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
297 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
298 cb_idx = mpt_get_cb_idx(MPTSTM_DRIVER);
299 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
306 /* Check for (valid) IO callback! */
307 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
308 MptCallbacks[cb_idx] == NULL) {
309 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
310 __FUNCTION__, ioc->name, cb_idx);
314 if (MptCallbacks[cb_idx](ioc, mf, mr))
315 mpt_free_msg_frame(ioc, mf);
321 mpt_reply(MPT_ADAPTER *ioc, u32 pa)
332 /* non-TURBO reply! Hmmm, something may be up...
333 * Newest turbo reply mechanism; get address
334 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
337 /* Map DMA address of reply header to cpu address.
338 * pa is 32 bits - but the dma address may be 32 or 64 bits
339 * get offset based only only the low addresses
342 reply_dma_low = (pa <<= 1);
343 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
344 (reply_dma_low - ioc->reply_frames_low_dma));
346 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
347 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
348 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
350 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
351 ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
352 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mr);
354 /* Check/log IOC log info
356 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
357 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
358 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
359 if (ioc->bus_type == FC)
360 mpt_fc_log_info(ioc, log_info);
361 else if (ioc->bus_type == SPI)
362 mpt_spi_log_info(ioc, log_info);
363 else if (ioc->bus_type == SAS)
364 mpt_sas_log_info(ioc, log_info);
367 if (ioc_stat & MPI_IOCSTATUS_MASK)
368 mpt_iocstatus_info(ioc, (u32)ioc_stat, mf);
370 /* Check for (valid) IO callback! */
371 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
372 MptCallbacks[cb_idx] == NULL) {
373 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
374 __FUNCTION__, ioc->name, cb_idx);
379 freeme = MptCallbacks[cb_idx](ioc, mf, mr);
382 /* Flush (non-TURBO) reply with a WRITE! */
383 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
386 mpt_free_msg_frame(ioc, mf);
390 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
392 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
393 * @irq: irq number (not used)
394 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
396 * This routine is registered via the request_irq() kernel API call,
397 * and handles all interrupts generated from a specific MPT adapter
398 * (also referred to as a IO Controller or IOC).
399 * This routine must clear the interrupt from the adapter and does
400 * so by reading the reply FIFO. Multiple replies may be processed
401 * per single call to this routine.
403 * This routine handles register-level access of the adapter but
404 * dispatches (calls) a protocol-specific callback routine to handle
405 * the protocol-specific details of the MPT request completion.
408 mpt_interrupt(int irq, void *bus_id)
410 MPT_ADAPTER *ioc = bus_id;
411 u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
413 if (pa == 0xFFFFFFFF)
417 * Drain the reply FIFO!
420 if (pa & MPI_ADDRESS_REPLY_A_BIT)
423 mpt_turbo_reply(ioc, pa);
424 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
425 } while (pa != 0xFFFFFFFF);
430 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
432 * mpt_base_reply - MPT base driver's callback routine
433 * @ioc: Pointer to MPT_ADAPTER structure
434 * @mf: Pointer to original MPT request frame
435 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
437 * MPT base driver's callback routine; all base driver
438 * "internal" request/reply processing is routed here.
439 * Currently used for EventNotification and EventAck handling.
441 * Returns 1 indicating original alloc'd request frame ptr
442 * should be freed, or 0 if it shouldn't.
445 mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
450 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply() called\n", ioc->name));
451 #ifdef CONFIG_FUSION_LOGGING
452 if ((ioc->debug_level & MPT_DEBUG_MSG_FRAME) &&
453 !(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) {
454 dmfprintk(ioc, printk(MYIOC_s_INFO_FMT ": Original request frame (@%p) header\n",
456 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)mf);
460 func = reply->u.hdr.Function;
461 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply, Function=%02Xh\n",
464 if (func == MPI_FUNCTION_EVENT_NOTIFICATION) {
465 EventNotificationReply_t *pEvReply = (EventNotificationReply_t *) reply;
469 results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
470 if (results != evHandlers) {
471 /* CHECKME! Any special handling needed here? */
472 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
473 ioc->name, evHandlers, results));
477 * Hmmm... It seems that EventNotificationReply is an exception
478 * to the rule of one reply per request.
480 if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) {
483 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
484 ioc->name, pEvReply));
487 #ifdef CONFIG_PROC_FS
488 // LogEvent(ioc, pEvReply);
491 } else if (func == MPI_FUNCTION_EVENT_ACK) {
492 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply, EventAck reply received\n",
494 } else if (func == MPI_FUNCTION_CONFIG) {
498 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "config_complete (mf=%p,mr=%p)\n",
499 ioc->name, mf, reply));
501 pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *)));
504 /* disable timer and remove from linked list */
505 del_timer(&pCfg->timer);
507 spin_lock_irqsave(&ioc->FreeQlock, flags);
508 list_del(&pCfg->linkage);
509 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
512 * If IOC Status is SUCCESS, save the header
513 * and set the status code to GOOD.
515 pCfg->status = MPT_CONFIG_ERROR;
517 ConfigReply_t *pReply = (ConfigReply_t *)reply;
520 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
521 dcprintk(ioc, printk(MYIOC_s_NOTE_FMT " IOCStatus=%04xh, IOCLogInfo=%08xh\n",
522 ioc->name, status, le32_to_cpu(pReply->IOCLogInfo)));
524 pCfg->status = status;
525 if (status == MPI_IOCSTATUS_SUCCESS) {
526 if ((pReply->Header.PageType &
527 MPI_CONFIG_PAGETYPE_MASK) ==
528 MPI_CONFIG_PAGETYPE_EXTENDED) {
529 pCfg->cfghdr.ehdr->ExtPageLength =
530 le16_to_cpu(pReply->ExtPageLength);
531 pCfg->cfghdr.ehdr->ExtPageType =
534 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
536 /* If this is a regular header, save PageLength. */
537 /* LMP Do this better so not using a reserved field! */
538 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
539 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
540 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
545 * Wake up the original calling thread
550 } else if (func == MPI_FUNCTION_SAS_IO_UNIT_CONTROL) {
551 /* we should be always getting a reply frame */
552 memcpy(ioc->persist_reply_frame, reply,
553 min(MPT_DEFAULT_FRAME_SIZE,
554 4*reply->u.reply.MsgLength));
555 del_timer(&ioc->persist_timer);
556 ioc->persist_wait_done = 1;
559 printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
564 * Conditionally tell caller to free the original
565 * EventNotification/EventAck/unexpected request frame!
570 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
572 * mpt_register - Register protocol-specific main callback handler.
573 * @cbfunc: callback function pointer
574 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
576 * This routine is called by a protocol-specific driver (SCSI host,
577 * LAN, SCSI target) to register its reply callback routine. Each
578 * protocol-specific driver must do this before it will be able to
579 * use any IOC resources, such as obtaining request frames.
581 * NOTES: The SCSI protocol driver currently calls this routine thrice
582 * in order to register separate callbacks; one for "normal" SCSI IO;
583 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
585 * Returns u8 valued "handle" in the range (and S.O.D. order)
586 * {N,...,7,6,5,...,1} if successful.
587 * A return value of MPT_MAX_PROTOCOL_DRIVERS (including zero!) should be
588 * considered an error by the caller.
591 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
594 last_drv_idx = MPT_MAX_PROTOCOL_DRIVERS;
597 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
598 * (slot/handle 0 is reserved!)
600 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
601 if (MptCallbacks[cb_idx] == NULL) {
602 MptCallbacks[cb_idx] = cbfunc;
603 MptDriverClass[cb_idx] = dclass;
604 MptEvHandlers[cb_idx] = NULL;
605 last_drv_idx = cb_idx;
613 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
615 * mpt_deregister - Deregister a protocol drivers resources.
616 * @cb_idx: previously registered callback handle
618 * Each protocol-specific driver should call this routine when its
619 * module is unloaded.
622 mpt_deregister(u8 cb_idx)
624 if (cb_idx && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
625 MptCallbacks[cb_idx] = NULL;
626 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
627 MptEvHandlers[cb_idx] = NULL;
633 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
635 * mpt_event_register - Register protocol-specific event callback handler.
636 * @cb_idx: previously registered (via mpt_register) callback handle
637 * @ev_cbfunc: callback function
639 * This routine can be called by one or more protocol-specific drivers
640 * if/when they choose to be notified of MPT events.
642 * Returns 0 for success.
645 mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc)
647 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
650 MptEvHandlers[cb_idx] = ev_cbfunc;
654 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
656 * mpt_event_deregister - Deregister protocol-specific event callback handler
657 * @cb_idx: previously registered callback handle
659 * Each protocol-specific driver should call this routine
660 * when it does not (or can no longer) handle events,
661 * or when its module is unloaded.
664 mpt_event_deregister(u8 cb_idx)
666 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
669 MptEvHandlers[cb_idx] = NULL;
672 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
674 * mpt_reset_register - Register protocol-specific IOC reset handler.
675 * @cb_idx: previously registered (via mpt_register) callback handle
676 * @reset_func: reset function
678 * This routine can be called by one or more protocol-specific drivers
679 * if/when they choose to be notified of IOC resets.
681 * Returns 0 for success.
684 mpt_reset_register(u8 cb_idx, MPT_RESETHANDLER reset_func)
686 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
689 MptResetHandlers[cb_idx] = reset_func;
693 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
695 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
696 * @cb_idx: previously registered callback handle
698 * Each protocol-specific driver should call this routine
699 * when it does not (or can no longer) handle IOC reset handling,
700 * or when its module is unloaded.
703 mpt_reset_deregister(u8 cb_idx)
705 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
708 MptResetHandlers[cb_idx] = NULL;
711 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
713 * mpt_device_driver_register - Register device driver hooks
714 * @dd_cbfunc: driver callbacks struct
715 * @cb_idx: MPT protocol driver index
718 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, u8 cb_idx)
721 const struct pci_device_id *id;
723 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
726 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
728 /* call per pci device probe entry point */
729 list_for_each_entry(ioc, &ioc_list, list) {
730 id = ioc->pcidev->driver ?
731 ioc->pcidev->driver->id_table : NULL;
732 if (dd_cbfunc->probe)
733 dd_cbfunc->probe(ioc->pcidev, id);
739 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
741 * mpt_device_driver_deregister - DeRegister device driver hooks
742 * @cb_idx: MPT protocol driver index
745 mpt_device_driver_deregister(u8 cb_idx)
747 struct mpt_pci_driver *dd_cbfunc;
750 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
753 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
755 list_for_each_entry(ioc, &ioc_list, list) {
756 if (dd_cbfunc->remove)
757 dd_cbfunc->remove(ioc->pcidev);
760 MptDeviceDriverHandlers[cb_idx] = NULL;
764 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
766 * mpt_get_msg_frame - Obtain an MPT request frame from the pool
767 * @cb_idx: Handle of registered MPT protocol driver
768 * @ioc: Pointer to MPT adapter structure
770 * Obtain an MPT request frame from the pool (of 1024) that are
771 * allocated per MPT adapter.
773 * Returns pointer to a MPT request frame or %NULL if none are available
774 * or IOC is not active.
777 mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc)
781 u16 req_idx; /* Request index */
783 /* validate handle and ioc identifier */
787 printk(MYIOC_s_WARN_FMT "IOC Not Active! mpt_get_msg_frame "
788 "returning NULL!\n", ioc->name);
791 /* If interrupts are not attached, do not return a request frame */
795 spin_lock_irqsave(&ioc->FreeQlock, flags);
796 if (!list_empty(&ioc->FreeQ)) {
799 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
800 u.frame.linkage.list);
801 list_del(&mf->u.frame.linkage.list);
802 mf->u.frame.linkage.arg1 = 0;
803 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
804 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
806 req_idx = req_offset / ioc->req_sz;
807 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
808 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
809 /* Default, will be changed if necessary in SG generation */
810 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame;
817 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
821 printk(MYIOC_s_WARN_FMT "IOC Active. No free Msg Frames! "
822 "Count 0x%x Max 0x%x\n", ioc->name, ioc->mfcnt,
825 if (mfcounter == PRINT_MF_COUNT)
826 printk(MYIOC_s_INFO_FMT "MF Count 0x%x Max 0x%x \n", ioc->name,
827 ioc->mfcnt, ioc->req_depth);
830 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_get_msg_frame(%d,%d), got mf=%p\n",
831 ioc->name, cb_idx, ioc->id, mf));
835 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
837 * mpt_put_msg_frame - Send a protocol-specific MPT request frame to an IOC
838 * @cb_idx: Handle of registered MPT protocol driver
839 * @ioc: Pointer to MPT adapter structure
840 * @mf: Pointer to MPT request frame
842 * This routine posts an MPT request frame to the request post FIFO of a
843 * specific MPT adapter.
846 mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
850 u16 req_idx; /* Request index */
852 /* ensure values are reset properly! */
853 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
854 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
856 req_idx = req_offset / ioc->req_sz;
857 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
858 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
860 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
862 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
863 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d "
864 "RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx,
865 ioc->RequestNB[req_idx]));
866 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
870 * mpt_put_msg_frame_hi_pri - Send a hi-pri protocol-specific MPT request frame
871 * @cb_idx: Handle of registered MPT protocol driver
872 * @ioc: Pointer to MPT adapter structure
873 * @mf: Pointer to MPT request frame
875 * Send a protocol-specific MPT request frame to an IOC using
876 * hi-priority request queue.
878 * This routine posts an MPT request frame to the request post FIFO of a
879 * specific MPT adapter.
882 mpt_put_msg_frame_hi_pri(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
886 u16 req_idx; /* Request index */
888 /* ensure values are reset properly! */
889 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
890 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
891 req_idx = req_offset / ioc->req_sz;
892 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
893 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
895 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
897 mf_dma_addr = (ioc->req_frames_low_dma + req_offset);
898 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d\n",
899 ioc->name, mf_dma_addr, req_idx));
900 CHIPREG_WRITE32(&ioc->chip->RequestHiPriFifo, mf_dma_addr);
903 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
905 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
906 * @handle: Handle of registered MPT protocol driver
907 * @ioc: Pointer to MPT adapter structure
908 * @mf: Pointer to MPT request frame
910 * This routine places a MPT request frame back on the MPT adapter's
914 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
918 /* Put Request back on FreeQ! */
919 spin_lock_irqsave(&ioc->FreeQlock, flags);
920 mf->u.frame.linkage.arg1 = 0xdeadbeaf; /* signature to know if this mf is freed */
921 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
925 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
928 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
930 * mpt_add_sge - Place a simple SGE at address pAddr.
931 * @pAddr: virtual address for SGE
932 * @flagslength: SGE flags and data transfer length
933 * @dma_addr: Physical address
935 * This routine places a MPT request frame back on the MPT adapter's
939 mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
941 if (sizeof(dma_addr_t) == sizeof(u64)) {
942 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
943 u32 tmp = dma_addr & 0xFFFFFFFF;
945 pSge->FlagsLength = cpu_to_le32(flagslength);
946 pSge->Address.Low = cpu_to_le32(tmp);
947 tmp = (u32) ((u64)dma_addr >> 32);
948 pSge->Address.High = cpu_to_le32(tmp);
951 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
952 pSge->FlagsLength = cpu_to_le32(flagslength);
953 pSge->Address = cpu_to_le32(dma_addr);
957 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
959 * mpt_send_handshake_request - Send MPT request via doorbell handshake method.
960 * @cb_idx: Handle of registered MPT protocol driver
961 * @ioc: Pointer to MPT adapter structure
962 * @reqBytes: Size of the request in bytes
963 * @req: Pointer to MPT request frame
964 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
966 * This routine is used exclusively to send MptScsiTaskMgmt
967 * requests since they are required to be sent via doorbell handshake.
969 * NOTE: It is the callers responsibility to byte-swap fields in the
970 * request which are greater than 1 byte in size.
972 * Returns 0 for success, non-zero for failure.
975 mpt_send_handshake_request(u8 cb_idx, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
981 /* State is known to be good upon entering
982 * this function so issue the bus reset
987 * Emulate what mpt_put_msg_frame() does /wrt to sanity
988 * setting cb_idx/req_idx. But ONLY if this request
989 * is in proper (pre-alloc'd) request buffer range...
991 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
992 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
993 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
994 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
995 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
998 /* Make sure there are no doorbells */
999 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1001 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1002 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
1003 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
1005 /* Wait for IOC doorbell int */
1006 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
1010 /* Read doorbell and check for active bit */
1011 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
1014 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_send_handshake_request start, WaitCnt=%d\n",
1017 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1019 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1023 /* Send request via doorbell handshake */
1024 req_as_bytes = (u8 *) req;
1025 for (ii = 0; ii < reqBytes/4; ii++) {
1028 word = ((req_as_bytes[(ii*4) + 0] << 0) |
1029 (req_as_bytes[(ii*4) + 1] << 8) |
1030 (req_as_bytes[(ii*4) + 2] << 16) |
1031 (req_as_bytes[(ii*4) + 3] << 24));
1032 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
1033 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1039 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
1044 /* Make sure there are no doorbells */
1045 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1050 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1052 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
1053 * @ioc: Pointer to MPT adapter structure
1054 * @access_control_value: define bits below
1055 * @sleepFlag: Specifies whether the process can sleep
1057 * Provides mechanism for the host driver to control the IOC's
1058 * Host Page Buffer access.
1060 * Access Control Value - bits[15:12]
1062 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1063 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1064 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1066 * Returns 0 for success, non-zero for failure.
1070 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1074 /* return if in use */
1075 if (CHIPREG_READ32(&ioc->chip->Doorbell)
1076 & MPI_DOORBELL_ACTIVE)
1079 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1081 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1082 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1083 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1084 (access_control_value<<12)));
1086 /* Wait for IOC to clear Doorbell Status bit */
1087 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1093 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1095 * mpt_host_page_alloc - allocate system memory for the fw
1096 * @ioc: Pointer to pointer to IOC adapter
1097 * @ioc_init: Pointer to ioc init config page
1099 * If we already allocated memory in past, then resend the same pointer.
1100 * Returns 0 for success, non-zero for failure.
1103 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1107 u32 host_page_buffer_sz=0;
1109 if(!ioc->HostPageBuffer) {
1111 host_page_buffer_sz =
1112 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1114 if(!host_page_buffer_sz)
1115 return 0; /* fw doesn't need any host buffers */
1117 /* spin till we get enough memory */
1118 while(host_page_buffer_sz > 0) {
1120 if((ioc->HostPageBuffer = pci_alloc_consistent(
1122 host_page_buffer_sz,
1123 &ioc->HostPageBuffer_dma)) != NULL) {
1125 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1126 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1127 ioc->name, ioc->HostPageBuffer,
1128 (u32)ioc->HostPageBuffer_dma,
1129 host_page_buffer_sz));
1130 ioc->alloc_total += host_page_buffer_sz;
1131 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1135 host_page_buffer_sz -= (4*1024);
1139 if(!ioc->HostPageBuffer) {
1140 printk(MYIOC_s_ERR_FMT
1141 "Failed to alloc memory for host_page_buffer!\n",
1146 psge = (char *)&ioc_init->HostPageBufferSGE;
1147 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1148 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1149 MPI_SGE_FLAGS_32_BIT_ADDRESSING |
1150 MPI_SGE_FLAGS_HOST_TO_IOC |
1151 MPI_SGE_FLAGS_END_OF_BUFFER;
1152 if (sizeof(dma_addr_t) == sizeof(u64)) {
1153 flags_length |= MPI_SGE_FLAGS_64_BIT_ADDRESSING;
1155 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1156 flags_length |= ioc->HostPageBuffer_sz;
1157 mpt_add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1158 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1163 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1165 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1166 * @iocid: IOC unique identifier (integer)
1167 * @iocpp: Pointer to pointer to IOC adapter
1169 * Given a unique IOC identifier, set pointer to the associated MPT
1170 * adapter structure.
1172 * Returns iocid and sets iocpp if iocid is found.
1173 * Returns -1 if iocid is not found.
1176 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1180 list_for_each_entry(ioc,&ioc_list,list) {
1181 if (ioc->id == iocid) {
1192 * mpt_get_product_name - returns product string
1193 * @vendor: pci vendor id
1194 * @device: pci device id
1195 * @revision: pci revision id
1196 * @prod_name: string returned
1198 * Returns product string displayed when driver loads,
1199 * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1203 mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name)
1205 char *product_str = NULL;
1207 if (vendor == PCI_VENDOR_ID_BROCADE) {
1210 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1214 product_str = "BRE040 A0";
1217 product_str = "BRE040 A1";
1220 product_str = "BRE040";
1230 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1231 product_str = "LSIFC909 B1";
1233 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1234 product_str = "LSIFC919 B0";
1236 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1237 product_str = "LSIFC929 B0";
1239 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1240 if (revision < 0x80)
1241 product_str = "LSIFC919X A0";
1243 product_str = "LSIFC919XL A1";
1245 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1246 if (revision < 0x80)
1247 product_str = "LSIFC929X A0";
1249 product_str = "LSIFC929XL A1";
1251 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1252 product_str = "LSIFC939X A1";
1254 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1255 product_str = "LSIFC949X A1";
1257 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1261 product_str = "LSIFC949E A0";
1264 product_str = "LSIFC949E A1";
1267 product_str = "LSIFC949E";
1271 case MPI_MANUFACTPAGE_DEVID_53C1030:
1275 product_str = "LSI53C1030 A0";
1278 product_str = "LSI53C1030 B0";
1281 product_str = "LSI53C1030 B1";
1284 product_str = "LSI53C1030 B2";
1287 product_str = "LSI53C1030 C0";
1290 product_str = "LSI53C1030T A0";
1293 product_str = "LSI53C1030T A2";
1296 product_str = "LSI53C1030T A3";
1299 product_str = "LSI53C1020A A1";
1302 product_str = "LSI53C1030";
1306 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1310 product_str = "LSI53C1035 A2";
1313 product_str = "LSI53C1035 B0";
1316 product_str = "LSI53C1035";
1320 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1324 product_str = "LSISAS1064 A1";
1327 product_str = "LSISAS1064 A2";
1330 product_str = "LSISAS1064 A3";
1333 product_str = "LSISAS1064 A4";
1336 product_str = "LSISAS1064";
1340 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1344 product_str = "LSISAS1064E A0";
1347 product_str = "LSISAS1064E B0";
1350 product_str = "LSISAS1064E B1";
1353 product_str = "LSISAS1064E B2";
1356 product_str = "LSISAS1064E B3";
1359 product_str = "LSISAS1064E";
1363 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1367 product_str = "LSISAS1068 A0";
1370 product_str = "LSISAS1068 B0";
1373 product_str = "LSISAS1068 B1";
1376 product_str = "LSISAS1068";
1380 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1384 product_str = "LSISAS1068E A0";
1387 product_str = "LSISAS1068E B0";
1390 product_str = "LSISAS1068E B1";
1393 product_str = "LSISAS1068E B2";
1396 product_str = "LSISAS1068E B3";
1399 product_str = "LSISAS1068E";
1403 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1407 product_str = "LSISAS1078 A0";
1410 product_str = "LSISAS1078 B0";
1413 product_str = "LSISAS1078 C0";
1416 product_str = "LSISAS1078 C1";
1419 product_str = "LSISAS1078 C2";
1422 product_str = "LSISAS1078";
1430 sprintf(prod_name, "%s", product_str);
1434 * mpt_mapresources - map in memory mapped io
1435 * @ioc: Pointer to pointer to IOC adapter
1439 mpt_mapresources(MPT_ADAPTER *ioc)
1443 unsigned long mem_phys;
1449 struct pci_dev *pdev;
1452 ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
1453 if (pci_enable_device_mem(pdev)) {
1454 printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() "
1455 "failed\n", ioc->name);
1458 if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) {
1459 printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with "
1460 "MEM failed\n", ioc->name);
1464 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1466 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)
1467 && !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
1468 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1469 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1471 } else if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)
1472 && !pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
1473 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1474 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1477 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1478 ioc->name, pci_name(pdev));
1479 pci_release_selected_regions(pdev, ioc->bars);
1483 mem_phys = msize = 0;
1485 for (ii = 0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1486 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1489 /* Get I/O space! */
1490 port = pci_resource_start(pdev, ii);
1491 psize = pci_resource_len(pdev, ii);
1496 mem_phys = pci_resource_start(pdev, ii);
1497 msize = pci_resource_len(pdev, ii);
1500 ioc->mem_size = msize;
1503 /* Get logical ptr for PciMem0 space */
1504 /*mem = ioremap(mem_phys, msize);*/
1505 mem = ioremap(mem_phys, msize);
1507 printk(MYIOC_s_ERR_FMT ": ERROR - Unable to map adapter"
1508 " memory!\n", ioc->name);
1512 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %lx\n",
1513 ioc->name, mem, mem_phys));
1515 ioc->mem_phys = mem_phys;
1516 ioc->chip = (SYSIF_REGS __iomem *)mem;
1518 /* Save Port IO values in case we need to do downloadboot */
1519 ioc->pio_mem_phys = port;
1520 ioc->pio_chip = (SYSIF_REGS __iomem *)port;
1525 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1527 * mpt_attach - Install a PCI intelligent MPT adapter.
1528 * @pdev: Pointer to pci_dev structure
1529 * @id: PCI device ID information
1531 * This routine performs all the steps necessary to bring the IOC of
1532 * a MPT adapter to a OPERATIONAL state. This includes registering
1533 * memory regions, registering the interrupt, and allocating request
1534 * and reply memory pools.
1536 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1539 * Returns 0 for success, non-zero for failure.
1541 * TODO: Add support for polled controllers
1544 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1551 static int mpt_ids = 0;
1552 #ifdef CONFIG_PROC_FS
1553 struct proc_dir_entry *dent, *ent;
1556 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1558 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1562 ioc->id = mpt_ids++;
1563 sprintf(ioc->name, "ioc%d", ioc->id);
1566 * set initial debug level
1567 * (refer to mptdebug.h)
1570 ioc->debug_level = mpt_debug_level;
1571 if (mpt_debug_level)
1572 printk(KERN_INFO "mpt_debug_level=%xh\n", mpt_debug_level);
1574 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name));
1577 if (mpt_mapresources(ioc)) {
1582 ioc->alloc_total = sizeof(MPT_ADAPTER);
1583 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1584 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1587 ioc->diagPending = 0;
1588 spin_lock_init(&ioc->diagLock);
1589 spin_lock_init(&ioc->initializing_hba_lock);
1591 /* Initialize the event logging.
1593 ioc->eventTypes = 0; /* None */
1594 ioc->eventContext = 0;
1595 ioc->eventLogSize = 0;
1602 ioc->cached_fw = NULL;
1604 /* Initilize SCSI Config Data structure
1606 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1608 /* Initialize the running configQ head.
1610 INIT_LIST_HEAD(&ioc->configQ);
1612 /* Initialize the fc rport list head.
1614 INIT_LIST_HEAD(&ioc->fc_rports);
1616 /* Find lookup slot. */
1617 INIT_LIST_HEAD(&ioc->list);
1619 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",
1620 ioc->name, &ioc->facts, &ioc->pfacts[0]));
1622 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1623 mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name);
1625 switch (pdev->device)
1627 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1628 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1629 ioc->errata_flag_1064 = 1;
1630 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1631 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1632 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1633 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1637 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1638 if (revision < XL_929) {
1639 /* 929X Chip Fix. Set Split transactions level
1640 * for PCIX. Set MOST bits to zero.
1642 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1644 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1646 /* 929XL Chip Fix. Set MMRBC to 0x08.
1648 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1650 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1655 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1656 /* 919X Chip Fix. Set Split transactions level
1657 * for PCIX. Set MOST bits to zero.
1659 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1661 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1665 case MPI_MANUFACTPAGE_DEVID_53C1030:
1666 /* 1030 Chip Fix. Disable Split transactions
1667 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1669 if (revision < C0_1030) {
1670 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1672 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1675 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1676 ioc->bus_type = SPI;
1679 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1680 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1681 ioc->errata_flag_1064 = 1;
1683 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1684 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1685 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1686 ioc->bus_type = SAS;
1689 if (ioc->bus_type == SAS && mpt_msi_enable == -1)
1690 ioc->msi_enable = 1;
1692 ioc->msi_enable = mpt_msi_enable;
1694 if (ioc->errata_flag_1064)
1695 pci_disable_io_access(pdev);
1697 spin_lock_init(&ioc->FreeQlock);
1700 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1702 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1704 /* Set IOC ptr in the pcidev's driver data. */
1705 pci_set_drvdata(ioc->pcidev, ioc);
1707 /* Set lookup ptr. */
1708 list_add_tail(&ioc->list, &ioc_list);
1710 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1712 mpt_detect_bound_ports(ioc, pdev);
1714 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1716 printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",
1719 list_del(&ioc->list);
1721 ioc->alt_ioc->alt_ioc = NULL;
1722 iounmap(ioc->memmap);
1724 pci_release_selected_regions(pdev, ioc->bars);
1726 pci_set_drvdata(pdev, NULL);
1730 /* call per device driver probe entry point */
1731 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
1732 if(MptDeviceDriverHandlers[cb_idx] &&
1733 MptDeviceDriverHandlers[cb_idx]->probe) {
1734 MptDeviceDriverHandlers[cb_idx]->probe(pdev,id);
1738 #ifdef CONFIG_PROC_FS
1740 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1742 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1744 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1746 ent->read_proc = procmpt_iocinfo_read;
1749 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1751 ent->read_proc = procmpt_summary_read;
1760 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1762 * mpt_detach - Remove a PCI intelligent MPT adapter.
1763 * @pdev: Pointer to pci_dev structure
1767 mpt_detach(struct pci_dev *pdev)
1769 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1773 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
1774 remove_proc_entry(pname, NULL);
1775 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
1776 remove_proc_entry(pname, NULL);
1777 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
1778 remove_proc_entry(pname, NULL);
1780 /* call per device driver remove entry point */
1781 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
1782 if(MptDeviceDriverHandlers[cb_idx] &&
1783 MptDeviceDriverHandlers[cb_idx]->remove) {
1784 MptDeviceDriverHandlers[cb_idx]->remove(pdev);
1788 /* Disable interrupts! */
1789 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1792 synchronize_irq(pdev->irq);
1794 /* Clear any lingering interrupt */
1795 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1797 CHIPREG_READ32(&ioc->chip->IntStatus);
1799 mpt_adapter_dispose(ioc);
1801 pci_set_drvdata(pdev, NULL);
1804 /**************************************************************************
1808 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1810 * mpt_suspend - Fusion MPT base driver suspend routine.
1811 * @pdev: Pointer to pci_dev structure
1812 * @state: new state to enter
1815 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
1818 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1820 device_state = pci_choose_state(pdev, state);
1821 printk(MYIOC_s_INFO_FMT "pci-suspend: pdev=0x%p, slot=%s, Entering "
1822 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
1825 /* put ioc into READY_STATE */
1826 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
1827 printk(MYIOC_s_ERR_FMT
1828 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
1831 /* disable interrupts */
1832 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1835 /* Clear any lingering interrupt */
1836 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1838 free_irq(ioc->pci_irq, ioc);
1839 if (ioc->msi_enable)
1840 pci_disable_msi(ioc->pcidev);
1842 pci_save_state(pdev);
1843 pci_disable_device(pdev);
1844 pci_release_selected_regions(pdev, ioc->bars);
1845 pci_set_power_state(pdev, device_state);
1849 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1851 * mpt_resume - Fusion MPT base driver resume routine.
1852 * @pdev: Pointer to pci_dev structure
1855 mpt_resume(struct pci_dev *pdev)
1857 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1858 u32 device_state = pdev->current_state;
1862 printk(MYIOC_s_INFO_FMT "pci-resume: pdev=0x%p, slot=%s, Previous "
1863 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
1866 pci_set_power_state(pdev, PCI_D0);
1867 pci_enable_wake(pdev, PCI_D0, 0);
1868 pci_restore_state(pdev);
1870 err = mpt_mapresources(ioc);
1874 printk(MYIOC_s_INFO_FMT "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1875 ioc->name, (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1876 CHIPREG_READ32(&ioc->chip->Doorbell));
1879 * Errata workaround for SAS pci express:
1880 * Upon returning to the D0 state, the contents of the doorbell will be
1881 * stale data, and this will incorrectly signal to the host driver that
1882 * the firmware is ready to process mpt commands. The workaround is
1883 * to issue a diagnostic reset.
1885 if (ioc->bus_type == SAS && (pdev->device ==
1886 MPI_MANUFACTPAGE_DEVID_SAS1068E || pdev->device ==
1887 MPI_MANUFACTPAGE_DEVID_SAS1064E)) {
1888 if (KickStart(ioc, 1, CAN_SLEEP) < 0) {
1889 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover\n",
1895 /* bring ioc to operational state */
1896 printk(MYIOC_s_INFO_FMT "Sending mpt_do_ioc_recovery\n", ioc->name);
1897 recovery_state = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1899 if (recovery_state != 0)
1900 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover, "
1901 "error:[%x]\n", ioc->name, recovery_state);
1903 printk(MYIOC_s_INFO_FMT
1904 "pci-resume: success\n", ioc->name);
1912 mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase)
1914 if ((MptDriverClass[index] == MPTSPI_DRIVER &&
1915 ioc->bus_type != SPI) ||
1916 (MptDriverClass[index] == MPTFC_DRIVER &&
1917 ioc->bus_type != FC) ||
1918 (MptDriverClass[index] == MPTSAS_DRIVER &&
1919 ioc->bus_type != SAS))
1920 /* make sure we only call the relevant reset handler
1923 return (MptResetHandlers[index])(ioc, reset_phase);
1926 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1928 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1929 * @ioc: Pointer to MPT adapter structure
1930 * @reason: Event word / reason
1931 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1933 * This routine performs all the steps necessary to bring the IOC
1934 * to a OPERATIONAL state.
1936 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1941 * -1 if failed to get board READY
1942 * -2 if READY but IOCFacts Failed
1943 * -3 if READY but PrimeIOCFifos Failed
1944 * -4 if READY but IOCInit Failed
1945 * -5 if failed to enable_device and/or request_selected_regions
1946 * -6 if failed to upload firmware
1949 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1951 int hard_reset_done = 0;
1952 int alt_ioc_ready = 0;
1959 int reset_alt_ioc_active = 0;
1960 int irq_allocated = 0;
1963 printk(MYIOC_s_INFO_FMT "Initiating %s\n", ioc->name,
1964 reason == MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
1966 /* Disable reply interrupts (also blocks FreeQ) */
1967 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1971 if (ioc->alt_ioc->active)
1972 reset_alt_ioc_active = 1;
1974 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1975 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
1976 ioc->alt_ioc->active = 0;
1980 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
1983 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
1984 if (hard_reset_done == -4) {
1985 printk(MYIOC_s_WARN_FMT "Owned by PEER..skipping!\n",
1988 if (reset_alt_ioc_active && ioc->alt_ioc) {
1989 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1990 dprintk(ioc, printk(MYIOC_s_INFO_FMT
1991 "alt_ioc reply irq re-enabled\n", ioc->alt_ioc->name));
1992 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
1993 ioc->alt_ioc->active = 1;
1997 printk(MYIOC_s_WARN_FMT "NOT READY!\n", ioc->name);
2002 /* hard_reset_done = 0 if a soft reset was performed
2003 * and 1 if a hard reset was performed.
2005 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
2006 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
2009 printk(MYIOC_s_WARN_FMT "alt_ioc not ready!\n", ioc->alt_ioc->name);
2012 for (ii=0; ii<5; ii++) {
2013 /* Get IOC facts! Allow 5 retries */
2014 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
2020 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2021 "Retry IocFacts failed rc=%x\n", ioc->name, rc));
2023 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2024 MptDisplayIocCapabilities(ioc);
2027 if (alt_ioc_ready) {
2028 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
2029 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2030 "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
2031 /* Retry - alt IOC was initialized once
2033 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
2036 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2037 "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
2039 reset_alt_ioc_active = 0;
2040 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2041 MptDisplayIocCapabilities(ioc->alt_ioc);
2045 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP) &&
2046 (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)) {
2047 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2048 ioc->bars = pci_select_bars(ioc->pcidev, IORESOURCE_MEM |
2050 if (pci_enable_device(ioc->pcidev))
2052 if (pci_request_selected_regions(ioc->pcidev, ioc->bars,
2058 * Device is reset now. It must have de-asserted the interrupt line
2059 * (if it was asserted) and it should be safe to register for the
2062 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2064 if (ioc->pcidev->irq) {
2065 if (ioc->msi_enable && !pci_enable_msi(ioc->pcidev))
2066 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
2069 ioc->msi_enable = 0;
2070 rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
2071 IRQF_SHARED, ioc->name, ioc);
2073 printk(MYIOC_s_ERR_FMT "Unable to allocate "
2074 "interrupt %d!\n", ioc->name, ioc->pcidev->irq);
2075 if (ioc->msi_enable)
2076 pci_disable_msi(ioc->pcidev);
2080 ioc->pci_irq = ioc->pcidev->irq;
2081 pci_set_master(ioc->pcidev); /* ?? */
2082 dprintk(ioc, printk(MYIOC_s_INFO_FMT "installed at interrupt "
2083 "%d\n", ioc->name, ioc->pcidev->irq));
2087 /* Prime reply & request queues!
2088 * (mucho alloc's) Must be done prior to
2089 * init as upper addresses are needed for init.
2090 * If fails, continue with alt-ioc processing
2092 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
2095 /* May need to check/upload firmware & data here!
2096 * If fails, continue with alt-ioc processing
2098 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
2101 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
2102 printk(MYIOC_s_WARN_FMT ": alt_ioc (%d) FIFO mgmt alloc!\n",
2103 ioc->alt_ioc->name, rc);
2105 reset_alt_ioc_active = 0;
2108 if (alt_ioc_ready) {
2109 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
2111 reset_alt_ioc_active = 0;
2112 printk(MYIOC_s_WARN_FMT "alt_ioc (%d) init failure!\n",
2113 ioc->alt_ioc->name, rc);
2117 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
2118 if (ioc->upload_fw) {
2119 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2120 "firmware upload required!\n", ioc->name));
2122 /* Controller is not operational, cannot do upload
2125 rc = mpt_do_upload(ioc, sleepFlag);
2127 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2129 * Maintain only one pointer to FW memory
2130 * so there will not be two attempt to
2131 * downloadboot onboard dual function
2132 * chips (mpt_adapter_disable,
2135 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2136 "mpt_upload: alt_%s has cached_fw=%p \n",
2137 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
2138 ioc->cached_fw = NULL;
2141 printk(MYIOC_s_WARN_FMT
2142 "firmware upload failure!\n", ioc->name);
2150 /* Enable! (reply interrupt) */
2151 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
2155 if (reset_alt_ioc_active && ioc->alt_ioc) {
2156 /* (re)Enable alt-IOC! (reply interrupt) */
2157 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "alt_ioc reply irq re-enabled\n",
2158 ioc->alt_ioc->name));
2159 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2160 ioc->alt_ioc->active = 1;
2163 /* Enable MPT base driver management of EventNotification
2164 * and EventAck handling.
2166 if ((ret == 0) && (!ioc->facts.EventState))
2167 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
2169 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2170 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
2172 /* Add additional "reason" check before call to GetLanConfigPages
2173 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2174 * recursive scenario; GetLanConfigPages times out, timer expired
2175 * routine calls HardResetHandler, which calls into here again,
2176 * and we try GetLanConfigPages again...
2178 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2181 * Initalize link list for inactive raid volumes.
2183 mutex_init(&ioc->raid_data.inactive_list_mutex);
2184 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2186 if (ioc->bus_type == SAS) {
2188 /* clear persistency table */
2189 if(ioc->facts.IOCExceptions &
2190 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
2191 ret = mptbase_sas_persist_operation(ioc,
2192 MPI_SAS_OP_CLEAR_NOT_PRESENT);
2199 mpt_findImVolumes(ioc);
2201 } else if (ioc->bus_type == FC) {
2202 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
2203 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2205 * Pre-fetch the ports LAN MAC address!
2206 * (LANPage1_t stuff)
2208 (void) GetLanConfigPages(ioc);
2209 a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2210 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2211 "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
2212 ioc->name, a[5], a[4], a[3], a[2], a[1], a[0]));
2216 /* Get NVRAM and adapter maximums from SPP 0 and 2
2218 mpt_GetScsiPortSettings(ioc, 0);
2220 /* Get version and length of SDP 1
2222 mpt_readScsiDevicePageHeaders(ioc, 0);
2226 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
2227 mpt_findImVolumes(ioc);
2229 /* Check, and possibly reset, the coalescing value
2231 mpt_read_ioc_pg_1(ioc);
2233 mpt_read_ioc_pg_4(ioc);
2236 GetIoUnitPage2(ioc);
2237 mpt_get_manufacturing_pg_0(ioc);
2241 * Call each currently registered protocol IOC reset handler
2242 * with post-reset indication.
2243 * NOTE: If we're doing _IOC_BRINGUP, there can be no
2244 * MptResetHandlers[] registered yet.
2246 if (hard_reset_done) {
2248 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
2249 if ((ret == 0) && MptResetHandlers[cb_idx]) {
2250 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2251 "Calling IOC post_reset handler #%d\n",
2252 ioc->name, cb_idx));
2253 rc += mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET);
2257 if (alt_ioc_ready && MptResetHandlers[cb_idx]) {
2258 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2259 "Calling IOC post_reset handler #%d\n",
2260 ioc->alt_ioc->name, cb_idx));
2261 rc += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_POST_RESET);
2265 /* FIXME? Examine results here? */
2269 if ((ret != 0) && irq_allocated) {
2270 free_irq(ioc->pci_irq, ioc);
2271 if (ioc->msi_enable)
2272 pci_disable_msi(ioc->pcidev);
2277 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2279 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2280 * @ioc: Pointer to MPT adapter structure
2281 * @pdev: Pointer to (struct pci_dev) structure
2283 * Search for PCI bus/dev_function which matches
2284 * PCI bus/dev_function (+/-1) for newly discovered 929,
2285 * 929X, 1030 or 1035.
2287 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2288 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2291 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
2293 struct pci_dev *peer=NULL;
2294 unsigned int slot = PCI_SLOT(pdev->devfn);
2295 unsigned int func = PCI_FUNC(pdev->devfn);
2296 MPT_ADAPTER *ioc_srch;
2298 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PCI device %s devfn=%x/%x,"
2299 " searching for devfn match on %x or %x\n",
2300 ioc->name, pci_name(pdev), pdev->bus->number,
2301 pdev->devfn, func-1, func+1));
2303 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
2305 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
2310 list_for_each_entry(ioc_srch, &ioc_list, list) {
2311 struct pci_dev *_pcidev = ioc_srch->pcidev;
2312 if (_pcidev == peer) {
2313 /* Paranoia checks */
2314 if (ioc->alt_ioc != NULL) {
2315 printk(MYIOC_s_WARN_FMT "Oops, already bound to %s!\n",
2316 ioc->name, ioc->alt_ioc->name);
2318 } else if (ioc_srch->alt_ioc != NULL) {
2319 printk(MYIOC_s_WARN_FMT "Oops, already bound to %s!\n",
2320 ioc_srch->name, ioc_srch->alt_ioc->name);
2323 dprintk(ioc, printk(MYIOC_s_INFO_FMT "FOUND! binding to %s\n",
2324 ioc->name, ioc_srch->name));
2325 ioc_srch->alt_ioc = ioc;
2326 ioc->alt_ioc = ioc_srch;
2332 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2334 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2335 * @ioc: Pointer to MPT adapter structure
2338 mpt_adapter_disable(MPT_ADAPTER *ioc)
2343 if (ioc->cached_fw != NULL) {
2344 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: Pushing FW onto "
2345 "adapter\n", __FUNCTION__, ioc->name));
2346 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)
2347 ioc->cached_fw, CAN_SLEEP)) < 0) {
2348 printk(MYIOC_s_WARN_FMT
2349 ": firmware downloadboot failure (%d)!\n",
2354 /* Disable adapter interrupts! */
2355 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2357 /* Clear any lingering interrupt */
2358 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2360 if (ioc->alloc != NULL) {
2362 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "free @ %p, sz=%d bytes\n",
2363 ioc->name, ioc->alloc, ioc->alloc_sz));
2364 pci_free_consistent(ioc->pcidev, sz,
2365 ioc->alloc, ioc->alloc_dma);
2366 ioc->reply_frames = NULL;
2367 ioc->req_frames = NULL;
2369 ioc->alloc_total -= sz;
2372 if (ioc->sense_buf_pool != NULL) {
2373 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2374 pci_free_consistent(ioc->pcidev, sz,
2375 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2376 ioc->sense_buf_pool = NULL;
2377 ioc->alloc_total -= sz;
2380 if (ioc->events != NULL){
2381 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2384 ioc->alloc_total -= sz;
2387 mpt_free_fw_memory(ioc);
2389 kfree(ioc->spi_data.nvram);
2390 mpt_inactive_raid_list_free(ioc);
2391 kfree(ioc->raid_data.pIocPg2);
2392 kfree(ioc->raid_data.pIocPg3);
2393 ioc->spi_data.nvram = NULL;
2394 ioc->raid_data.pIocPg3 = NULL;
2396 if (ioc->spi_data.pIocPg4 != NULL) {
2397 sz = ioc->spi_data.IocPg4Sz;
2398 pci_free_consistent(ioc->pcidev, sz,
2399 ioc->spi_data.pIocPg4,
2400 ioc->spi_data.IocPg4_dma);
2401 ioc->spi_data.pIocPg4 = NULL;
2402 ioc->alloc_total -= sz;
2405 if (ioc->ReqToChain != NULL) {
2406 kfree(ioc->ReqToChain);
2407 kfree(ioc->RequestNB);
2408 ioc->ReqToChain = NULL;
2411 kfree(ioc->ChainToChain);
2412 ioc->ChainToChain = NULL;
2414 if (ioc->HostPageBuffer != NULL) {
2415 if((ret = mpt_host_page_access_control(ioc,
2416 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2417 printk(MYIOC_s_ERR_FMT
2418 "host page buffers free failed (%d)!\n",
2421 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "HostPageBuffer free @ %p, sz=%d bytes\n",
2422 ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
2423 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2424 ioc->HostPageBuffer, ioc->HostPageBuffer_dma);
2425 ioc->HostPageBuffer = NULL;
2426 ioc->HostPageBuffer_sz = 0;
2427 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2431 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2433 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2434 * @ioc: Pointer to MPT adapter structure
2436 * This routine unregisters h/w resources and frees all alloc'd memory
2437 * associated with a MPT adapter structure.
2440 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2442 int sz_first, sz_last;
2447 sz_first = ioc->alloc_total;
2449 mpt_adapter_disable(ioc);
2451 if (ioc->pci_irq != -1) {
2452 free_irq(ioc->pci_irq, ioc);
2453 if (ioc->msi_enable)
2454 pci_disable_msi(ioc->pcidev);
2458 if (ioc->memmap != NULL) {
2459 iounmap(ioc->memmap);
2463 pci_disable_device(ioc->pcidev);
2464 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2466 #if defined(CONFIG_MTRR) && 0
2467 if (ioc->mtrr_reg > 0) {
2468 mtrr_del(ioc->mtrr_reg, 0, 0);
2469 dprintk(ioc, printk(MYIOC_s_INFO_FMT "MTRR region de-registered\n", ioc->name));
2473 /* Zap the adapter lookup ptr! */
2474 list_del(&ioc->list);
2476 sz_last = ioc->alloc_total;
2477 dprintk(ioc, printk(MYIOC_s_INFO_FMT "free'd %d of %d bytes\n",
2478 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2481 ioc->alt_ioc->alt_ioc = NULL;
2486 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2488 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2489 * @ioc: Pointer to MPT adapter structure
2492 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2496 printk(KERN_INFO "%s: ", ioc->name);
2498 printk("%s: ", ioc->prod_name);
2499 printk("Capabilities={");
2501 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2502 printk("Initiator");
2506 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2507 printk("%sTarget", i ? "," : "");
2511 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2512 printk("%sLAN", i ? "," : "");
2518 * This would probably evoke more questions than it's worth
2520 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2521 printk("%sLogBusAddr", i ? "," : "");
2529 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2531 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2532 * @ioc: Pointer to MPT_ADAPTER structure
2533 * @force: Force hard KickStart of IOC
2534 * @sleepFlag: Specifies whether the process can sleep
2537 * 1 - DIAG reset and READY
2538 * 0 - READY initially OR soft reset and READY
2539 * -1 - Any failure on KickStart
2540 * -2 - Msg Unit Reset Failed
2541 * -3 - IO Unit Reset Failed
2542 * -4 - IOC owned by a PEER
2545 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2550 int hard_reset_done = 0;
2555 /* Get current [raw] IOC state */
2556 ioc_state = mpt_GetIocState(ioc, 0);
2557 dhsprintk(ioc, printk(MYIOC_s_INFO_FMT "MakeIocReady [raw] state=%08x\n", ioc->name, ioc_state));
2560 * Check to see if IOC got left/stuck in doorbell handshake
2561 * grip of death. If so, hard reset the IOC.
2563 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2565 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2569 /* Is it already READY? */
2570 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
2574 * Check to see if IOC is in FAULT state.
2576 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2578 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2580 printk(MYIOC_s_WARN_FMT " FAULT code = %04xh\n",
2581 ioc->name, ioc_state & MPI_DOORBELL_DATA_MASK);
2585 * Hmmm... Did it get left operational?
2587 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2588 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC operational unexpected\n",
2592 * If PCI Peer, exit.
2593 * Else, if no fault conditions are present, issue a MessageUnitReset
2594 * Else, fall through to KickStart case
2596 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2597 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2598 "whoinit 0x%x statefault %d force %d\n",
2599 ioc->name, whoinit, statefault, force));
2600 if (whoinit == MPI_WHOINIT_PCI_PEER)
2603 if ((statefault == 0 ) && (force == 0)) {
2604 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2611 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2612 if (hard_reset_done < 0)
2616 * Loop here waiting for IOC to come READY.
2619 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2621 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2622 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2624 * BIOS or previous driver load left IOC in OP state.
2625 * Reset messaging FIFOs.
2627 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2628 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2631 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2633 * Something is wrong. Try to get IOC back
2636 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2637 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2644 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2645 ioc->name, (int)((ii+5)/HZ));
2649 if (sleepFlag == CAN_SLEEP) {
2652 mdelay (1); /* 1 msec delay */
2657 if (statefault < 3) {
2658 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2660 statefault==1 ? "stuck handshake" : "IOC FAULT");
2663 return hard_reset_done;
2666 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2668 * mpt_GetIocState - Get the current state of a MPT adapter.
2669 * @ioc: Pointer to MPT_ADAPTER structure
2670 * @cooked: Request raw or cooked IOC state
2672 * Returns all IOC Doorbell register bits if cooked==0, else just the
2673 * Doorbell bits in MPI_IOC_STATE_MASK.
2676 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2681 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2682 sc = s & MPI_IOC_STATE_MASK;
2685 ioc->last_state = sc;
2687 return cooked ? sc : s;
2690 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2692 * GetIocFacts - Send IOCFacts request to MPT adapter.
2693 * @ioc: Pointer to MPT_ADAPTER structure
2694 * @sleepFlag: Specifies whether the process can sleep
2695 * @reason: If recovery, only update facts.
2697 * Returns 0 for success, non-zero for failure.
2700 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2702 IOCFacts_t get_facts;
2703 IOCFactsReply_t *facts;
2711 /* IOC *must* NOT be in RESET state! */
2712 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2713 printk(MYIOC_s_ERR_FMT "Can't get IOCFacts NOT READY! (%08x)\n",
2714 ioc->name, ioc->last_state );
2718 facts = &ioc->facts;
2720 /* Destination (reply area)... */
2721 reply_sz = sizeof(*facts);
2722 memset(facts, 0, reply_sz);
2724 /* Request area (get_facts on the stack right now!) */
2725 req_sz = sizeof(get_facts);
2726 memset(&get_facts, 0, req_sz);
2728 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2729 /* Assert: All other get_facts fields are zero! */
2731 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2732 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2733 ioc->name, req_sz, reply_sz));
2735 /* No non-zero fields in the get_facts request are greater than
2736 * 1 byte in size, so we can just fire it off as is.
2738 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2739 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2744 * Now byte swap (GRRR) the necessary fields before any further
2745 * inspection of reply contents.
2747 * But need to do some sanity checks on MsgLength (byte) field
2748 * to make sure we don't zero IOC's req_sz!
2750 /* Did we get a valid reply? */
2751 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2752 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2754 * If not been here, done that, save off first WhoInit value
2756 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2757 ioc->FirstWhoInit = facts->WhoInit;
2760 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2761 facts->MsgContext = le32_to_cpu(facts->MsgContext);
2762 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2763 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2764 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2765 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
2766 /* CHECKME! IOCStatus, IOCLogInfo */
2768 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2769 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2772 * FC f/w version changed between 1.1 and 1.2
2773 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2774 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2776 if (facts->MsgVersion < 0x0102) {
2778 * Handle old FC f/w style, convert to new...
2780 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2781 facts->FWVersion.Word =
2782 ((oldv<<12) & 0xFF000000) |
2783 ((oldv<<8) & 0x000FFF00);
2785 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2787 facts->ProductID = le16_to_cpu(facts->ProductID);
2788 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
2789 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
2790 ioc->ir_firmware = 1;
2791 facts->CurrentHostMfaHighAddr =
2792 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2793 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2794 facts->CurrentSenseBufferHighAddr =
2795 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2796 facts->CurReplyFrameSize =
2797 le16_to_cpu(facts->CurReplyFrameSize);
2798 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
2801 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2802 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2803 * to 14 in MPI-1.01.0x.
2805 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2806 facts->MsgVersion > 0x0100) {
2807 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2810 sz = facts->FWImageSize;
2815 facts->FWImageSize = sz;
2817 if (!facts->RequestFrameSize) {
2818 /* Something is wrong! */
2819 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2824 r = sz = facts->BlockSize;
2825 vv = ((63 / (sz * 4)) + 1) & 0x03;
2826 ioc->NB_for_64_byte_frame = vv;
2832 ioc->NBShiftFactor = shiftFactor;
2833 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2834 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2835 ioc->name, vv, shiftFactor, r));
2837 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2839 * Set values for this IOC's request & reply frame sizes,
2840 * and request & reply queue depths...
2842 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2843 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2844 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2845 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2847 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "reply_sz=%3d, reply_depth=%4d\n",
2848 ioc->name, ioc->reply_sz, ioc->reply_depth));
2849 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "req_sz =%3d, req_depth =%4d\n",
2850 ioc->name, ioc->req_sz, ioc->req_depth));
2852 /* Get port facts! */
2853 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2857 printk(MYIOC_s_ERR_FMT
2858 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2859 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2860 RequestFrameSize)/sizeof(u32)));
2867 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2869 * GetPortFacts - Send PortFacts request to MPT adapter.
2870 * @ioc: Pointer to MPT_ADAPTER structure
2871 * @portnum: Port number
2872 * @sleepFlag: Specifies whether the process can sleep
2874 * Returns 0 for success, non-zero for failure.
2877 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2879 PortFacts_t get_pfacts;
2880 PortFactsReply_t *pfacts;
2886 /* IOC *must* NOT be in RESET state! */
2887 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2888 printk(MYIOC_s_ERR_FMT "Can't get PortFacts NOT READY! (%08x)\n",
2889 ioc->name, ioc->last_state );
2893 pfacts = &ioc->pfacts[portnum];
2895 /* Destination (reply area)... */
2896 reply_sz = sizeof(*pfacts);
2897 memset(pfacts, 0, reply_sz);
2899 /* Request area (get_pfacts on the stack right now!) */
2900 req_sz = sizeof(get_pfacts);
2901 memset(&get_pfacts, 0, req_sz);
2903 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2904 get_pfacts.PortNumber = portnum;
2905 /* Assert: All other get_pfacts fields are zero! */
2907 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending get PortFacts(%d) request\n",
2908 ioc->name, portnum));
2910 /* No non-zero fields in the get_pfacts request are greater than
2911 * 1 byte in size, so we can just fire it off as is.
2913 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2914 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2918 /* Did we get a valid reply? */
2920 /* Now byte swap the necessary fields in the response. */
2921 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2922 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2923 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2924 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2925 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2926 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2927 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2928 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2929 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2931 max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
2933 ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
2934 ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
2937 * Place all the devices on channels
2941 if (mpt_channel_mapping) {
2942 ioc->devices_per_bus = 1;
2943 ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
2949 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2951 * SendIocInit - Send IOCInit request to MPT adapter.
2952 * @ioc: Pointer to MPT_ADAPTER structure
2953 * @sleepFlag: Specifies whether the process can sleep
2955 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2957 * Returns 0 for success, non-zero for failure.
2960 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2963 MPIDefaultReply_t init_reply;
2969 memset(&ioc_init, 0, sizeof(ioc_init));
2970 memset(&init_reply, 0, sizeof(init_reply));
2972 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2973 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2975 /* If we are in a recovery mode and we uploaded the FW image,
2976 * then this pointer is not NULL. Skip the upload a second time.
2977 * Set this flag if cached_fw set for either IOC.
2979 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
2983 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "upload_fw %d facts.Flags=%x\n",
2984 ioc->name, ioc->upload_fw, ioc->facts.Flags));
2986 ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
2987 ioc_init.MaxBuses = (U8)ioc->number_of_buses;
2988 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n",
2989 ioc->name, ioc->facts.MsgVersion));
2990 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
2991 // set MsgVersion and HeaderVersion host driver was built with
2992 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
2993 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
2995 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
2996 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
2997 } else if(mpt_host_page_alloc(ioc, &ioc_init))
3000 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
3002 if (sizeof(dma_addr_t) == sizeof(u64)) {
3003 /* Save the upper 32-bits of the request
3004 * (reply) and sense buffers.
3006 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
3007 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
3009 /* Force 32-bit addressing */
3010 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
3011 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
3014 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
3015 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
3016 ioc->facts.MaxDevices = ioc_init.MaxDevices;
3017 ioc->facts.MaxBuses = ioc_init.MaxBuses;
3019 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOCInit (req @ %p)\n",
3020 ioc->name, &ioc_init));
3022 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
3023 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
3025 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
3029 /* No need to byte swap the multibyte fields in the reply
3030 * since we don't even look at its contents.
3033 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending PortEnable (req @ %p)\n",
3034 ioc->name, &ioc_init));
3036 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
3037 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
3041 /* YIKES! SUPER IMPORTANT!!!
3042 * Poll IocState until _OPERATIONAL while IOC is doing
3043 * LoopInit and TargetDiscovery!
3046 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
3047 state = mpt_GetIocState(ioc, 1);
3048 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
3049 if (sleepFlag == CAN_SLEEP) {
3056 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
3057 ioc->name, (int)((count+5)/HZ));
3061 state = mpt_GetIocState(ioc, 1);
3064 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wait IOC_OPERATIONAL state (cnt=%d)\n",
3067 ioc->aen_event_read_flag=0;
3071 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3073 * SendPortEnable - Send PortEnable request to MPT adapter port.
3074 * @ioc: Pointer to MPT_ADAPTER structure
3075 * @portnum: Port number to enable
3076 * @sleepFlag: Specifies whether the process can sleep
3078 * Send PortEnable to bring IOC to OPERATIONAL state.
3080 * Returns 0 for success, non-zero for failure.
3083 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3085 PortEnable_t port_enable;
3086 MPIDefaultReply_t reply_buf;
3091 /* Destination... */
3092 reply_sz = sizeof(MPIDefaultReply_t);
3093 memset(&reply_buf, 0, reply_sz);
3095 req_sz = sizeof(PortEnable_t);
3096 memset(&port_enable, 0, req_sz);
3098 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
3099 port_enable.PortNumber = portnum;
3100 /* port_enable.ChainOffset = 0; */
3101 /* port_enable.MsgFlags = 0; */
3102 /* port_enable.MsgContext = 0; */
3104 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Port(%d)Enable (req @ %p)\n",
3105 ioc->name, portnum, &port_enable));
3107 /* RAID FW may take a long time to enable
3109 if (ioc->ir_firmware || ioc->bus_type == SAS) {
3110 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3111 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3112 300 /*seconds*/, sleepFlag);
3114 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3115 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3116 30 /*seconds*/, sleepFlag);
3122 * mpt_alloc_fw_memory - allocate firmware memory
3123 * @ioc: Pointer to MPT_ADAPTER structure
3124 * @size: total FW bytes
3126 * If memory has already been allocated, the same (cached) value
3129 * Return 0 if successfull, or non-zero for failure
3132 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
3136 if (ioc->cached_fw) {
3137 rc = 0; /* use already allocated memory */
3140 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
3141 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
3142 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
3146 ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma);
3147 if (!ioc->cached_fw) {
3148 printk(MYIOC_s_ERR_FMT "Unable to allocate memory for the cached firmware image!\n",
3152 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Image @ %p[%p], sz=%d[%x] bytes\n",
3153 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, size, size));
3154 ioc->alloc_total += size;
3162 * mpt_free_fw_memory - free firmware memory
3163 * @ioc: Pointer to MPT_ADAPTER structure
3165 * If alt_img is NULL, delete from ioc structure.
3166 * Else, delete a secondary image in same format.
3169 mpt_free_fw_memory(MPT_ADAPTER *ioc)
3173 if (!ioc->cached_fw)
3176 sz = ioc->facts.FWImageSize;
3177 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3178 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3179 pci_free_consistent(ioc->pcidev, sz, ioc->cached_fw, ioc->cached_fw_dma);
3180 ioc->alloc_total -= sz;
3181 ioc->cached_fw = NULL;
3184 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3186 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3187 * @ioc: Pointer to MPT_ADAPTER structure
3188 * @sleepFlag: Specifies whether the process can sleep
3190 * Returns 0 for success, >0 for handshake failure
3191 * <0 for fw upload failure.
3193 * Remark: If bound IOC and a successful FWUpload was performed
3194 * on the bound IOC, the second image is discarded
3195 * and memory is free'd. Both channels must upload to prevent
3196 * IOC from running in degraded mode.
3199 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3201 u8 reply[sizeof(FWUploadReply_t)];
3202 FWUpload_t *prequest;
3203 FWUploadReply_t *preply;
3204 FWUploadTCSGE_t *ptcsge;
3207 int ii, sz, reply_sz;
3210 /* If the image size is 0, we are done.
3212 if ((sz = ioc->facts.FWImageSize) == 0)
3215 if (mpt_alloc_fw_memory(ioc, ioc->facts.FWImageSize) != 0)
3218 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3219 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3221 prequest = (sleepFlag == NO_SLEEP) ? kzalloc(ioc->req_sz, GFP_ATOMIC) :
3222 kzalloc(ioc->req_sz, GFP_KERNEL);
3224 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed "
3225 "while allocating memory \n", ioc->name));
3226 mpt_free_fw_memory(ioc);
3230 preply = (FWUploadReply_t *)&reply;
3232 reply_sz = sizeof(reply);
3233 memset(preply, 0, reply_sz);
3235 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
3236 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
3238 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
3239 ptcsge->DetailsLength = 12;
3240 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
3241 ptcsge->ImageSize = cpu_to_le32(sz);
3244 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
3246 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3247 mpt_add_sge((char *)ptcsge, flagsLength, ioc->cached_fw_dma);
3249 sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
3250 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": Sending FW Upload (req @ %p) sgeoffset=%d \n",
3251 ioc->name, prequest, sgeoffset));
3252 DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest);
3254 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
3255 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
3257 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Upload completed rc=%x \n", ioc->name, ii));
3259 cmdStatus = -EFAULT;
3261 /* Handshake transfer was complete and successful.
3262 * Check the Reply Frame.
3264 int status, transfer_sz;
3265 status = le16_to_cpu(preply->IOCStatus);
3266 if (status == MPI_IOCSTATUS_SUCCESS) {
3267 transfer_sz = le32_to_cpu(preply->ActualImageSize);
3268 if (transfer_sz == sz)
3272 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n",
3273 ioc->name, cmdStatus));
3278 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": fw upload failed, freeing image \n",
3280 mpt_free_fw_memory(ioc);
3287 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3289 * mpt_downloadboot - DownloadBoot code
3290 * @ioc: Pointer to MPT_ADAPTER structure
3291 * @pFwHeader: Pointer to firmware header info
3292 * @sleepFlag: Specifies whether the process can sleep
3294 * FwDownloadBoot requires Programmed IO access.
3296 * Returns 0 for success
3297 * -1 FW Image size is 0
3298 * -2 No valid cached_fw Pointer
3299 * <0 for fw upload failure.
3302 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3304 MpiExtImageHeader_t *pExtImage;
3314 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3315 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
3317 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3318 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3319 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3320 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3321 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3322 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3324 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
3327 if (sleepFlag == CAN_SLEEP) {
3333 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3334 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3336 for (count = 0; count < 30; count ++) {
3337 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3338 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3339 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESET_ADAPTER cleared, count=%d\n",
3344 if (sleepFlag == CAN_SLEEP) {
3351 if ( count == 30 ) {
3352 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot failed! "
3353 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3354 ioc->name, diag0val));
3358 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3359 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3360 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3361 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3362 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3363 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3365 /* Set the DiagRwEn and Disable ARM bits */
3366 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3368 fwSize = (pFwHeader->ImageSize + 3)/4;
3369 ptrFw = (u32 *) pFwHeader;
3371 /* Write the LoadStartAddress to the DiagRw Address Register
3372 * using Programmed IO
3374 if (ioc->errata_flag_1064)
3375 pci_enable_io_access(ioc->pcidev);
3377 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3378 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "LoadStart addr written 0x%x \n",
3379 ioc->name, pFwHeader->LoadStartAddress));
3381 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write FW Image: 0x%x bytes @ %p\n",
3382 ioc->name, fwSize*4, ptrFw));
3384 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3387 nextImage = pFwHeader->NextImageHeaderOffset;
3389 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3391 load_addr = pExtImage->LoadStartAddress;
3393 fwSize = (pExtImage->ImageSize + 3) >> 2;
3394 ptrFw = (u32 *)pExtImage;
3396 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3397 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3398 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3401 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3403 nextImage = pExtImage->NextImageHeaderOffset;
3406 /* Write the IopResetVectorRegAddr */
3407 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
3408 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3410 /* Write the IopResetVectorValue */
3411 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3412 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3414 /* Clear the internal flash bad bit - autoincrementing register,
3415 * so must do two writes.
3417 if (ioc->bus_type == SPI) {
3419 * 1030 and 1035 H/W errata, workaround to access
3420 * the ClearFlashBadSignatureBit
3422 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3423 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3424 diagRwData |= 0x40000000;
3425 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3426 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3428 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3429 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3430 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3431 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3434 if (sleepFlag == CAN_SLEEP) {
3441 if (ioc->errata_flag_1064)
3442 pci_disable_io_access(ioc->pcidev);
3444 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3445 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot diag0val=%x, "
3446 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3447 ioc->name, diag0val));
3448 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3449 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot now diag0val=%x\n",
3450 ioc->name, diag0val));
3451 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3453 /* Write 0xFF to reset the sequencer */
3454 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3456 if (ioc->bus_type == SAS) {
3457 ioc_state = mpt_GetIocState(ioc, 0);
3458 if ( (GetIocFacts(ioc, sleepFlag,
3459 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3460 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "GetIocFacts failed: IocState=%x\n",
3461 ioc->name, ioc_state));
3466 for (count=0; count<HZ*20; count++) {
3467 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3468 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3469 "downloadboot successful! (count=%d) IocState=%x\n",
3470 ioc->name, count, ioc_state));
3471 if (ioc->bus_type == SAS) {
3474 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3475 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3476 "downloadboot: SendIocInit failed\n",
3480 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3481 "downloadboot: SendIocInit successful\n",
3485 if (sleepFlag == CAN_SLEEP) {
3491 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3492 "downloadboot failed! IocState=%x\n",ioc->name, ioc_state));
3496 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3498 * KickStart - Perform hard reset of MPT adapter.
3499 * @ioc: Pointer to MPT_ADAPTER structure
3500 * @force: Force hard reset
3501 * @sleepFlag: Specifies whether the process can sleep
3503 * This routine places MPT adapter in diagnostic mode via the
3504 * WriteSequence register, and then performs a hard reset of adapter
3505 * via the Diagnostic register.
3507 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3508 * or NO_SLEEP (interrupt thread, use mdelay)
3509 * force - 1 if doorbell active, board fault state
3510 * board operational, IOC_RECOVERY or
3511 * IOC_BRINGUP and there is an alt_ioc.
3515 * 1 - hard reset, READY
3516 * 0 - no reset due to History bit, READY
3517 * -1 - no reset due to History bit but not READY
3518 * OR reset but failed to come READY
3519 * -2 - no reset, could not enter DIAG mode
3520 * -3 - reset but bad FW bit
3523 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3525 int hard_reset_done = 0;
3529 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStarting!\n", ioc->name));
3530 if (ioc->bus_type == SPI) {
3531 /* Always issue a Msg Unit Reset first. This will clear some
3532 * SCSI bus hang conditions.
3534 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3536 if (sleepFlag == CAN_SLEEP) {
3543 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3544 if (hard_reset_done < 0)
3545 return hard_reset_done;
3547 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n",
3550 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3551 for (cnt=0; cnt<cntdn; cnt++) {
3552 ioc_state = mpt_GetIocState(ioc, 1);
3553 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3554 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStart successful! (cnt=%d)\n",
3556 return hard_reset_done;
3558 if (sleepFlag == CAN_SLEEP) {
3565 dinitprintk(ioc, printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3566 ioc->name, mpt_GetIocState(ioc, 0)));
3570 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3572 * mpt_diag_reset - Perform hard reset of the adapter.
3573 * @ioc: Pointer to MPT_ADAPTER structure
3574 * @ignore: Set if to honor and clear to ignore
3575 * the reset history bit
3576 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3577 * else set to NO_SLEEP (use mdelay instead)
3579 * This routine places the adapter in diagnostic mode via the
3580 * WriteSequence register and then performs a hard reset of adapter
3581 * via the Diagnostic register. Adapter should be in ready state
3582 * upon successful completion.
3584 * Returns: 1 hard reset successful
3585 * 0 no reset performed because reset history bit set
3586 * -2 enabling diagnostic mode failed
3587 * -3 diagnostic reset failed
3590 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3594 int hard_reset_done = 0;
3597 MpiFwHeader_t *cached_fw; /* Pointer to FW */
3599 /* Clear any existing interrupts */
3600 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3602 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3603 drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3604 "address=%p\n", ioc->name, __FUNCTION__,
3605 &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3606 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3607 if (sleepFlag == CAN_SLEEP)
3612 for (count = 0; count < 60; count ++) {
3613 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3614 doorbell &= MPI_IOC_STATE_MASK;
3616 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3617 "looking for READY STATE: doorbell=%x"
3619 ioc->name, doorbell, count));
3620 if (doorbell == MPI_IOC_STATE_READY) {
3625 if (sleepFlag == CAN_SLEEP)
3633 /* Use "Diagnostic reset" method! (only thing available!) */
3634 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3636 if (ioc->debug_level & MPT_DEBUG) {
3638 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3639 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3640 ioc->name, diag0val, diag1val));
3643 /* Do the reset if we are told to ignore the reset history
3644 * or if the reset history is 0
3646 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3647 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3648 /* Write magic sequence to WriteSequence register
3649 * Loop until in diagnostic mode
3651 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3652 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3653 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3654 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3655 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3656 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3659 if (sleepFlag == CAN_SLEEP) {
3667 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3668 ioc->name, diag0val);
3673 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3675 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3676 ioc->name, diag0val));
3679 if (ioc->debug_level & MPT_DEBUG) {
3681 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3682 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3683 ioc->name, diag0val, diag1val));
3686 * Disable the ARM (Bug fix)
3689 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3693 * Now hit the reset bit in the Diagnostic register
3694 * (THE BIG HAMMER!) (Clears DRWE bit).
3696 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3697 hard_reset_done = 1;
3698 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset performed\n",
3702 * Call each currently registered protocol IOC reset handler
3703 * with pre-reset indication.
3704 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3705 * MptResetHandlers[] registered yet.
3711 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
3712 if (MptResetHandlers[cb_idx]) {
3713 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3714 "Calling IOC pre_reset handler #%d\n",
3715 ioc->name, cb_idx));
3716 r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET);
3718 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3719 "Calling alt-%s pre_reset handler #%d\n",
3720 ioc->name, ioc->alt_ioc->name, cb_idx));
3721 r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_PRE_RESET);
3725 /* FIXME? Examine results here? */
3729 cached_fw = (MpiFwHeader_t *)ioc->cached_fw;
3730 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
3731 cached_fw = (MpiFwHeader_t *)ioc->alt_ioc->cached_fw;
3735 /* If the DownloadBoot operation fails, the
3736 * IOC will be left unusable. This is a fatal error
3737 * case. _diag_reset will return < 0
3739 for (count = 0; count < 30; count ++) {
3740 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3741 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3745 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n",
3746 ioc->name, diag0val, count));
3748 if (sleepFlag == CAN_SLEEP) {
3754 if ((count = mpt_downloadboot(ioc, cached_fw, sleepFlag)) < 0) {
3755 printk(MYIOC_s_WARN_FMT
3756 "firmware downloadboot failure (%d)!\n", ioc->name, count);
3760 /* Wait for FW to reload and for board
3761 * to go to the READY state.
3762 * Maximum wait is 60 seconds.
3763 * If fail, no error will check again
3764 * with calling program.
3766 for (count = 0; count < 60; count ++) {
3767 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3768 doorbell &= MPI_IOC_STATE_MASK;
3770 if (doorbell == MPI_IOC_STATE_READY) {
3775 if (sleepFlag == CAN_SLEEP) {
3784 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3785 if (ioc->debug_level & MPT_DEBUG) {
3787 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3788 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3789 ioc->name, diag0val, diag1val));
3792 /* Clear RESET_HISTORY bit! Place board in the
3793 * diagnostic mode to update the diag register.
3795 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3797 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3798 /* Write magic sequence to WriteSequence register
3799 * Loop until in diagnostic mode
3801 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3802 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3803 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3804 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3805 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3806 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3809 if (sleepFlag == CAN_SLEEP) {
3817 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3818 ioc->name, diag0val);
3821 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3823 diag0val &= ~MPI_DIAG_RESET_HISTORY;
3824 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3825 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3826 if (diag0val & MPI_DIAG_RESET_HISTORY) {
3827 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3831 /* Disable Diagnostic Mode
3833 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3835 /* Check FW reload status flags.
3837 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3838 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3839 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3840 ioc->name, diag0val);
3844 if (ioc->debug_level & MPT_DEBUG) {
3846 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3847 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3848 ioc->name, diag0val, diag1val));
3852 * Reset flag that says we've enabled event notification
3854 ioc->facts.EventState = 0;
3857 ioc->alt_ioc->facts.EventState = 0;
3859 return hard_reset_done;
3862 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3864 * SendIocReset - Send IOCReset request to MPT adapter.
3865 * @ioc: Pointer to MPT_ADAPTER structure
3866 * @reset_type: reset type, expected values are
3867 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3868 * @sleepFlag: Specifies whether the process can sleep
3870 * Send IOCReset request to the MPT adapter.
3872 * Returns 0 for success, non-zero for failure.
3875 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3881 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOC reset(0x%02x)!\n",
3882 ioc->name, reset_type));
3883 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3884 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3887 /* FW ACK'd request, wait for READY state
3890 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
3892 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3896 if (sleepFlag != CAN_SLEEP)
3899 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
3900 ioc->name, (int)((count+5)/HZ));
3904 if (sleepFlag == CAN_SLEEP) {
3907 mdelay (1); /* 1 msec delay */
3912 * Cleanup all event stuff for this IOC; re-issue EventNotification
3913 * request if needed.
3915 if (ioc->facts.Function)
3916 ioc->facts.EventState = 0;
3921 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3923 * initChainBuffers - Allocate memory for and initialize chain buffers
3924 * @ioc: Pointer to MPT_ADAPTER structure
3926 * Allocates memory for and initializes chain buffers,
3927 * chain buffer control arrays and spinlock.
3930 initChainBuffers(MPT_ADAPTER *ioc)
3933 int sz, ii, num_chain;
3934 int scale, num_sge, numSGE;
3936 /* ReqToChain size must equal the req_depth
3939 if (ioc->ReqToChain == NULL) {
3940 sz = ioc->req_depth * sizeof(int);
3941 mem = kmalloc(sz, GFP_ATOMIC);
3945 ioc->ReqToChain = (int *) mem;
3946 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReqToChain alloc @ %p, sz=%d bytes\n",
3947 ioc->name, mem, sz));
3948 mem = kmalloc(sz, GFP_ATOMIC);
3952 ioc->RequestNB = (int *) mem;
3953 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestNB alloc @ %p, sz=%d bytes\n",
3954 ioc->name, mem, sz));
3956 for (ii = 0; ii < ioc->req_depth; ii++) {
3957 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
3960 /* ChainToChain size must equal the total number
3961 * of chain buffers to be allocated.
3964 * Calculate the number of chain buffers needed(plus 1) per I/O
3965 * then multiply the maximum number of simultaneous cmds
3967 * num_sge = num sge in request frame + last chain buffer
3968 * scale = num sge per chain buffer if no chain element
3970 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3971 if (sizeof(dma_addr_t) == sizeof(u64))
3972 num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3974 num_sge = 1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3976 if (sizeof(dma_addr_t) == sizeof(u64)) {
3977 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3978 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3980 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3981 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3983 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n",
3984 ioc->name, num_sge, numSGE));
3986 if ( numSGE > MPT_SCSI_SG_DEPTH )
3987 numSGE = MPT_SCSI_SG_DEPTH;
3990 while (numSGE - num_sge > 0) {
3992 num_sge += (scale - 1);
3996 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Now numSGE=%d num_sge=%d num_chain=%d\n",
3997 ioc->name, numSGE, num_sge, num_chain));
3999 if (ioc->bus_type == SPI)
4000 num_chain *= MPT_SCSI_CAN_QUEUE;
4002 num_chain *= MPT_FC_CAN_QUEUE;
4004 ioc->num_chain = num_chain;
4006 sz = num_chain * sizeof(int);
4007 if (ioc->ChainToChain == NULL) {
4008 mem = kmalloc(sz, GFP_ATOMIC);
4012 ioc->ChainToChain = (int *) mem;
4013 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainToChain alloc @ %p, sz=%d bytes\n",
4014 ioc->name, mem, sz));
4016 mem = (u8 *) ioc->ChainToChain;
4018 memset(mem, 0xFF, sz);
4022 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4024 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
4025 * @ioc: Pointer to MPT_ADAPTER structure
4027 * This routine allocates memory for the MPT reply and request frame
4028 * pools (if necessary), and primes the IOC reply FIFO with
4031 * Returns 0 for success, non-zero for failure.
4034 PrimeIocFifos(MPT_ADAPTER *ioc)
4037 unsigned long flags;
4038 dma_addr_t alloc_dma;
4040 int i, reply_sz, sz, total_size, num_chain;
4042 /* Prime reply FIFO... */
4044 if (ioc->reply_frames == NULL) {
4045 if ( (num_chain = initChainBuffers(ioc)) < 0)
4048 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
4049 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
4050 ioc->name, ioc->reply_sz, ioc->reply_depth));
4051 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d[%x] bytes\n",
4052 ioc->name, reply_sz, reply_sz));
4054 sz = (ioc->req_sz * ioc->req_depth);
4055 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d bytes, RequestDepth=%d\n",
4056 ioc->name, ioc->req_sz, ioc->req_depth));
4057 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d[%x] bytes\n",
4058 ioc->name, sz, sz));
4061 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
4062 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d bytes, ChainDepth=%d\n",
4063 ioc->name, ioc->req_sz, num_chain));
4064 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
4065 ioc->name, sz, sz, num_chain));
4068 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
4070 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
4075 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Total alloc @ %p[%p], sz=%d[%x] bytes\n",
4076 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
4078 memset(mem, 0, total_size);
4079 ioc->alloc_total += total_size;
4081 ioc->alloc_dma = alloc_dma;
4082 ioc->alloc_sz = total_size;
4083 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
4084 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4086 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4087 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4089 alloc_dma += reply_sz;
4092 /* Request FIFO - WE manage this! */
4094 ioc->req_frames = (MPT_FRAME_HDR *) mem;
4095 ioc->req_frames_dma = alloc_dma;
4097 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffers @ %p[%p]\n",
4098 ioc->name, mem, (void *)(ulong)alloc_dma));
4100 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4102 #if defined(CONFIG_MTRR) && 0
4104 * Enable Write Combining MTRR for IOC's memory region.
4105 * (at least as much as we can; "size and base must be
4106 * multiples of 4 kiB"
4108 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
4110 MTRR_TYPE_WRCOMB, 1);
4111 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MTRR region registered (base:size=%08x:%x)\n",
4112 ioc->name, ioc->req_frames_dma, sz));
4115 for (i = 0; i < ioc->req_depth; i++) {
4116 alloc_dma += ioc->req_sz;
4120 ioc->ChainBuffer = mem;
4121 ioc->ChainBufferDMA = alloc_dma;
4123 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffers @ %p(%p)\n",
4124 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
4126 /* Initialize the free chain Q.
4129 INIT_LIST_HEAD(&ioc->FreeChainQ);
4131 /* Post the chain buffers to the FreeChainQ.
4133 mem = (u8 *)ioc->ChainBuffer;
4134 for (i=0; i < num_chain; i++) {
4135 mf = (MPT_FRAME_HDR *) mem;
4136 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
4140 /* Initialize Request frames linked list
4142 alloc_dma = ioc->req_frames_dma;
4143 mem = (u8 *) ioc->req_frames;
4145 spin_lock_irqsave(&ioc->FreeQlock, flags);
4146 INIT_LIST_HEAD(&ioc->FreeQ);
4147 for (i = 0; i < ioc->req_depth; i++) {
4148 mf = (MPT_FRAME_HDR *) mem;
4150 /* Queue REQUESTs *internally*! */
4151 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
4155 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4157 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4158 ioc->sense_buf_pool =
4159 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
4160 if (ioc->sense_buf_pool == NULL) {
4161 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
4166 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
4167 ioc->alloc_total += sz;
4168 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SenseBuffers @ %p[%p]\n",
4169 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
4173 /* Post Reply frames to FIFO
4175 alloc_dma = ioc->alloc_dma;
4176 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4177 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4179 for (i = 0; i < ioc->reply_depth; i++) {
4180 /* Write each address to the IOC! */
4181 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
4182 alloc_dma += ioc->reply_sz;
4188 if (ioc->alloc != NULL) {
4190 pci_free_consistent(ioc->pcidev,
4192 ioc->alloc, ioc->alloc_dma);
4193 ioc->reply_frames = NULL;
4194 ioc->req_frames = NULL;
4195 ioc->alloc_total -= sz;
4197 if (ioc->sense_buf_pool != NULL) {
4198 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4199 pci_free_consistent(ioc->pcidev,
4201 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
4202 ioc->sense_buf_pool = NULL;
4207 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4209 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4210 * from IOC via doorbell handshake method.
4211 * @ioc: Pointer to MPT_ADAPTER structure
4212 * @reqBytes: Size of the request in bytes
4213 * @req: Pointer to MPT request frame
4214 * @replyBytes: Expected size of the reply in bytes
4215 * @u16reply: Pointer to area where reply should be written
4216 * @maxwait: Max wait time for a reply (in seconds)
4217 * @sleepFlag: Specifies whether the process can sleep
4219 * NOTES: It is the callers responsibility to byte-swap fields in the
4220 * request which are greater than 1 byte in size. It is also the
4221 * callers responsibility to byte-swap response fields which are
4222 * greater than 1 byte in size.
4224 * Returns 0 for success, non-zero for failure.
4227 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
4228 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
4230 MPIDefaultReply_t *mptReply;
4235 * Get ready to cache a handshake reply
4237 ioc->hs_reply_idx = 0;
4238 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4239 mptReply->MsgLength = 0;
4242 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4243 * then tell IOC that we want to handshake a request of N words.
4244 * (WRITE u32val to Doorbell reg).
4246 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4247 CHIPREG_WRITE32(&ioc->chip->Doorbell,
4248 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
4249 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
4252 * Wait for IOC's doorbell handshake int
4254 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4257 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4258 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4260 /* Read doorbell and check for active bit */
4261 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
4265 * Clear doorbell int (WRITE 0 to IntStatus reg),
4266 * then wait for IOC to ACKnowledge that it's ready for
4267 * our handshake request.
4269 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4270 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4275 u8 *req_as_bytes = (u8 *) req;
4278 * Stuff request words via doorbell handshake,
4279 * with ACK from IOC for each.
4281 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
4282 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
4283 (req_as_bytes[(ii*4) + 1] << 8) |
4284 (req_as_bytes[(ii*4) + 2] << 16) |
4285 (req_as_bytes[(ii*4) + 3] << 24));
4287 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
4288 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4292 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req));
4293 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req);
4295 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n",
4296 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
4299 * Wait for completion of doorbell handshake reply from the IOC
4301 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
4304 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake reply count=%d%s\n",
4305 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
4308 * Copy out the cached reply...
4310 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
4311 u16reply[ii] = ioc->hs_reply[ii];
4319 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4321 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4322 * @ioc: Pointer to MPT_ADAPTER structure
4323 * @howlong: How long to wait (in seconds)
4324 * @sleepFlag: Specifies whether the process can sleep
4326 * This routine waits (up to ~2 seconds max) for IOC doorbell
4327 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4328 * bit in its IntStatus register being clear.
4330 * Returns a negative value on failure, else wait loop count.
4333 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4339 cntdn = 1000 * howlong;
4341 if (sleepFlag == CAN_SLEEP) {
4344 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4345 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4352 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4353 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4360 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell ACK (count=%d)\n",
4365 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4366 ioc->name, count, intstat);
4370 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4372 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4373 * @ioc: Pointer to MPT_ADAPTER structure
4374 * @howlong: How long to wait (in seconds)
4375 * @sleepFlag: Specifies whether the process can sleep
4377 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4378 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4380 * Returns a negative value on failure, else wait loop count.
4383 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4389 cntdn = 1000 * howlong;
4390 if (sleepFlag == CAN_SLEEP) {
4392 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4393 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4400 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4401 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4409 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4410 ioc->name, count, howlong));
4414 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4415 ioc->name, count, intstat);
4419 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4421 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4422 * @ioc: Pointer to MPT_ADAPTER structure
4423 * @howlong: How long to wait (in seconds)
4424 * @sleepFlag: Specifies whether the process can sleep
4426 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4427 * Reply is cached to IOC private area large enough to hold a maximum
4428 * of 128 bytes of reply data.
4430 * Returns a negative value on failure, else size of reply in WORDS.
4433 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4438 u16 *hs_reply = ioc->hs_reply;
4439 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4442 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4445 * Get first two u16's so we can look at IOC's intended reply MsgLength
4448 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4451 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4452 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4453 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4456 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4457 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4461 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4462 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4463 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4466 * If no error (and IOC said MsgLength is > 0), piece together
4467 * reply 16 bits at a time.
4469 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4470 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4472 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4473 /* don't overflow our IOC hs_reply[] buffer! */
4474 if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
4475 hs_reply[u16cnt] = hword;
4476 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4479 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4481 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4484 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4489 else if (u16cnt != (2 * mptReply->MsgLength)) {
4492 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4497 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name));
4498 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply);
4500 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4501 ioc->name, t, u16cnt/2));
4505 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4507 * GetLanConfigPages - Fetch LANConfig pages.
4508 * @ioc: Pointer to MPT_ADAPTER structure
4510 * Return: 0 for success
4511 * -ENOMEM if no memory available
4512 * -EPERM if not allowed due to ISR context
4513 * -EAGAIN if no msg frames currently available
4514 * -EFAULT for non-successful reply or no reply (timeout)
4517 GetLanConfigPages(MPT_ADAPTER *ioc)
4519 ConfigPageHeader_t hdr;
4521 LANPage0_t *ppage0_alloc;
4522 dma_addr_t page0_dma;
4523 LANPage1_t *ppage1_alloc;
4524 dma_addr_t page1_dma;
4529 /* Get LAN Page 0 header */
4530 hdr.PageVersion = 0;
4533 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4534 cfg.cfghdr.hdr = &hdr;
4536 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4541 if ((rc = mpt_config(ioc, &cfg)) != 0)
4544 if (hdr.PageLength > 0) {
4545 data_sz = hdr.PageLength * 4;
4546 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4549 memset((u8 *)ppage0_alloc, 0, data_sz);
4550 cfg.physAddr = page0_dma;
4551 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4553 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4555 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4556 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4560 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4563 * Normalize endianness of structure data,
4564 * by byte-swapping all > 1 byte fields!
4573 /* Get LAN Page 1 header */
4574 hdr.PageVersion = 0;
4577 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4578 cfg.cfghdr.hdr = &hdr;
4580 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4584 if ((rc = mpt_config(ioc, &cfg)) != 0)
4587 if (hdr.PageLength == 0)
4590 data_sz = hdr.PageLength * 4;
4592 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4594 memset((u8 *)ppage1_alloc, 0, data_sz);
4595 cfg.physAddr = page1_dma;
4596 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4598 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4600 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4601 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4604 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4607 * Normalize endianness of structure data,
4608 * by byte-swapping all > 1 byte fields!
4616 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4618 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
4619 * @ioc: Pointer to MPT_ADAPTER structure
4620 * @persist_opcode: see below
4622 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4623 * devices not currently present.
4624 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4626 * NOTE: Don't use not this function during interrupt time.
4628 * Returns 0 for success, non-zero error
4631 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4633 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4635 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
4636 SasIoUnitControlReply_t *sasIoUnitCntrReply;
4637 MPT_FRAME_HDR *mf = NULL;
4638 MPIHeader_t *mpi_hdr;
4641 /* insure garbage is not sent to fw */
4642 switch(persist_opcode) {
4644 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
4645 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
4653 printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode);
4655 /* Get a MF for this command.
4657 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4658 printk("%s: no msg frames!\n",__FUNCTION__);
4662 mpi_hdr = (MPIHeader_t *) mf;
4663 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
4664 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
4665 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
4666 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
4667 sasIoUnitCntrReq->Operation = persist_opcode;
4669 init_timer(&ioc->persist_timer);
4670 ioc->persist_timer.data = (unsigned long) ioc;
4671 ioc->persist_timer.function = mpt_timer_expired;
4672 ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
4673 ioc->persist_wait_done=0;
4674 add_timer(&ioc->persist_timer);
4675 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4676 wait_event(mpt_waitq, ioc->persist_wait_done);
4678 sasIoUnitCntrReply =
4679 (SasIoUnitControlReply_t *)ioc->persist_reply_frame;
4680 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
4681 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4683 sasIoUnitCntrReply->IOCStatus,
4684 sasIoUnitCntrReply->IOCLogInfo);
4688 printk("%s: success\n",__FUNCTION__);
4692 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4695 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
4696 MpiEventDataRaid_t * pRaidEventData)
4705 volume = pRaidEventData->VolumeID;
4706 reason = pRaidEventData->ReasonCode;
4707 disk = pRaidEventData->PhysDiskNum;
4708 status = le32_to_cpu(pRaidEventData->SettingsStatus);
4709 flags = (status >> 0) & 0xff;
4710 state = (status >> 8) & 0xff;
4712 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
4716 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
4717 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
4718 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
4719 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
4720 ioc->name, disk, volume);
4722 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
4727 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4728 printk(MYIOC_s_INFO_FMT " volume has been created\n",
4732 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4734 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
4738 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
4739 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
4743 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4744 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
4746 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
4748 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
4750 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
4753 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
4755 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
4756 ? ", quiesced" : "",
4757 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
4758 ? ", resync in progress" : "" );
4761 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
4762 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
4766 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4767 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
4771 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4772 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
4776 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
4777 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
4781 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4782 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
4784 state == MPI_PHYSDISK0_STATUS_ONLINE
4786 : state == MPI_PHYSDISK0_STATUS_MISSING
4788 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
4790 : state == MPI_PHYSDISK0_STATUS_FAILED
4792 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
4794 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
4795 ? "offline requested"
4796 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
4797 ? "failed requested"
4798 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
4801 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
4802 ? ", out of sync" : "",
4803 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
4804 ? ", quiesced" : "" );
4807 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
4808 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
4812 case MPI_EVENT_RAID_RC_SMART_DATA:
4813 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
4814 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
4817 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
4818 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
4824 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4826 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4827 * @ioc: Pointer to MPT_ADAPTER structure
4829 * Returns: 0 for success
4830 * -ENOMEM if no memory available
4831 * -EPERM if not allowed due to ISR context
4832 * -EAGAIN if no msg frames currently available
4833 * -EFAULT for non-successful reply or no reply (timeout)
4836 GetIoUnitPage2(MPT_ADAPTER *ioc)
4838 ConfigPageHeader_t hdr;
4840 IOUnitPage2_t *ppage_alloc;
4841 dma_addr_t page_dma;
4845 /* Get the page header */
4846 hdr.PageVersion = 0;
4849 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4850 cfg.cfghdr.hdr = &hdr;
4852 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4857 if ((rc = mpt_config(ioc, &cfg)) != 0)
4860 if (hdr.PageLength == 0)
4863 /* Read the config page */
4864 data_sz = hdr.PageLength * 4;
4866 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4868 memset((u8 *)ppage_alloc, 0, data_sz);
4869 cfg.physAddr = page_dma;
4870 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4872 /* If Good, save data */
4873 if ((rc = mpt_config(ioc, &cfg)) == 0)
4874 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4876 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4882 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4884 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4885 * @ioc: Pointer to a Adapter Strucutre
4886 * @portnum: IOC port number
4888 * Return: -EFAULT if read of config page header fails
4890 * If read of SCSI Port Page 0 fails,
4891 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4892 * Adapter settings: async, narrow
4894 * If read of SCSI Port Page 2 fails,
4895 * Adapter settings valid
4896 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4901 * CHECK - what type of locking mechanisms should be used????
4904 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4909 ConfigPageHeader_t header;
4915 if (!ioc->spi_data.nvram) {
4918 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4919 mem = kmalloc(sz, GFP_ATOMIC);
4923 ioc->spi_data.nvram = (int *) mem;
4925 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4926 ioc->name, ioc->spi_data.nvram, sz));
4929 /* Invalidate NVRAM information
4931 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4932 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4935 /* Read SPP0 header, allocate memory, then read page.
4937 header.PageVersion = 0;
4938 header.PageLength = 0;
4939 header.PageNumber = 0;
4940 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4941 cfg.cfghdr.hdr = &header;
4943 cfg.pageAddr = portnum;
4944 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4946 cfg.timeout = 0; /* use default */
4947 if (mpt_config(ioc, &cfg) != 0)
4950 if (header.PageLength > 0) {
4951 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4953 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4954 cfg.physAddr = buf_dma;
4955 if (mpt_config(ioc, &cfg) != 0) {
4956 ioc->spi_data.maxBusWidth = MPT_NARROW;
4957 ioc->spi_data.maxSyncOffset = 0;
4958 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4959 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4961 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4962 "Unable to read PortPage0 minSyncFactor=%x\n",
4963 ioc->name, ioc->spi_data.minSyncFactor));
4965 /* Save the Port Page 0 data
4967 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
4968 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4969 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4971 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
4972 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4973 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4974 "noQas due to Capabilities=%x\n",
4975 ioc->name, pPP0->Capabilities));
4977 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4978 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4980 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4981 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4982 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4983 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4984 "PortPage0 minSyncFactor=%x\n",
4985 ioc->name, ioc->spi_data.minSyncFactor));
4987 ioc->spi_data.maxSyncOffset = 0;
4988 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4991 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4993 /* Update the minSyncFactor based on bus type.
4995 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4996 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
4998 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
4999 ioc->spi_data.minSyncFactor = MPT_ULTRA;
5000 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5001 "HVD or SE detected, minSyncFactor=%x\n",
5002 ioc->name, ioc->spi_data.minSyncFactor));
5007 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5012 /* SCSI Port Page 2 - Read the header then the page.
5014 header.PageVersion = 0;
5015 header.PageLength = 0;
5016 header.PageNumber = 2;
5017 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5018 cfg.cfghdr.hdr = &header;
5020 cfg.pageAddr = portnum;
5021 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5023 if (mpt_config(ioc, &cfg) != 0)
5026 if (header.PageLength > 0) {
5027 /* Allocate memory and read SCSI Port Page 2
5029 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5031 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
5032 cfg.physAddr = buf_dma;
5033 if (mpt_config(ioc, &cfg) != 0) {
5034 /* Nvram data is left with INVALID mark
5037 } else if (ioc->pcidev->vendor == PCI_VENDOR_ID_ATTO) {
5039 /* This is an ATTO adapter, read Page2 accordingly
5041 ATTO_SCSIPortPage2_t *pPP2 = (ATTO_SCSIPortPage2_t *) pbuf;
5042 ATTODeviceInfo_t *pdevice = NULL;
5045 /* Save the Port Page 2 data
5046 * (reformat into a 32bit quantity)
5048 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5049 pdevice = &pPP2->DeviceSettings[ii];
5050 ATTOFlags = le16_to_cpu(pdevice->ATTOFlags);
5053 /* Translate ATTO device flags to LSI format
5055 if (ATTOFlags & ATTOFLAG_DISC)
5056 data |= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE);
5057 if (ATTOFlags & ATTOFLAG_ID_ENB)
5058 data |= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE);
5059 if (ATTOFlags & ATTOFLAG_LUN_ENB)
5060 data |= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE);
5061 if (ATTOFlags & ATTOFLAG_TAGGED)
5062 data |= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE);
5063 if (!(ATTOFlags & ATTOFLAG_WIDE_ENB))
5064 data |= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE);
5066 data = (data << 16) | (pdevice->Period << 8) | 10;
5067 ioc->spi_data.nvram[ii] = data;
5070 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
5071 MpiDeviceInfo_t *pdevice = NULL;
5074 * Save "Set to Avoid SCSI Bus Resets" flag
5076 ioc->spi_data.bus_reset =
5077 (le32_to_cpu(pPP2->PortFlags) &
5078 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
5081 /* Save the Port Page 2 data
5082 * (reformat into a 32bit quantity)
5084 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
5085 ioc->spi_data.PortFlags = data;
5086 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5087 pdevice = &pPP2->DeviceSettings[ii];
5088 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
5089 (pdevice->SyncFactor << 8) | pdevice->Timeout;
5090 ioc->spi_data.nvram[ii] = data;
5094 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5098 /* Update Adapter limits with those from NVRAM
5099 * Comment: Don't need to do this. Target performance
5100 * parameters will never exceed the adapters limits.
5106 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5108 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
5109 * @ioc: Pointer to a Adapter Strucutre
5110 * @portnum: IOC port number
5112 * Return: -EFAULT if read of config page header fails
5116 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
5119 ConfigPageHeader_t header;
5121 /* Read the SCSI Device Page 1 header
5123 header.PageVersion = 0;
5124 header.PageLength = 0;
5125 header.PageNumber = 1;
5126 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5127 cfg.cfghdr.hdr = &header;
5129 cfg.pageAddr = portnum;
5130 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5133 if (mpt_config(ioc, &cfg) != 0)
5136 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
5137 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
5139 header.PageVersion = 0;
5140 header.PageLength = 0;
5141 header.PageNumber = 0;
5142 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5143 if (mpt_config(ioc, &cfg) != 0)
5146 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
5147 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
5149 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 0: version %d length %d\n",
5150 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
5152 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 1: version %d length %d\n",
5153 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
5158 * mpt_inactive_raid_list_free - This clears this link list.
5159 * @ioc : pointer to per adapter structure
5162 mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
5164 struct inactive_raid_component_info *component_info, *pNext;
5166 if (list_empty(&ioc->raid_data.inactive_list))
5169 mutex_lock(&ioc->raid_data.inactive_list_mutex);
5170 list_for_each_entry_safe(component_info, pNext,
5171 &ioc->raid_data.inactive_list, list) {
5172 list_del(&component_info->list);
5173 kfree(component_info);
5175 mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5179 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5181 * @ioc : pointer to per adapter structure
5182 * @channel : volume channel
5183 * @id : volume target id
5186 mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
5189 ConfigPageHeader_t hdr;
5190 dma_addr_t dma_handle;
5191 pRaidVolumePage0_t buffer = NULL;
5193 RaidPhysDiskPage0_t phys_disk;
5194 struct inactive_raid_component_info *component_info;
5195 int handle_inactive_volumes;
5197 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5198 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5199 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
5200 cfg.pageAddr = (channel << 8) + id;
5201 cfg.cfghdr.hdr = &hdr;
5202 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5204 if (mpt_config(ioc, &cfg) != 0)
5207 if (!hdr.PageLength)
5210 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5216 cfg.physAddr = dma_handle;
5217 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5219 if (mpt_config(ioc, &cfg) != 0)
5222 if (!buffer->NumPhysDisks)
5225 handle_inactive_volumes =
5226 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
5227 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
5228 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
5229 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
5231 if (!handle_inactive_volumes)
5234 mutex_lock(&ioc->raid_data.inactive_list_mutex);
5235 for (i = 0; i < buffer->NumPhysDisks; i++) {
5236 if(mpt_raid_phys_disk_pg0(ioc,
5237 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
5240 if ((component_info = kmalloc(sizeof (*component_info),
5241 GFP_KERNEL)) == NULL)
5244 component_info->volumeID = id;
5245 component_info->volumeBus = channel;
5246 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
5247 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
5248 component_info->d.PhysDiskID = phys_disk.PhysDiskID;
5249 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
5251 list_add_tail(&component_info->list,
5252 &ioc->raid_data.inactive_list);
5254 mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5258 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5263 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5264 * @ioc: Pointer to a Adapter Structure
5265 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5266 * @phys_disk: requested payload data returned
5270 * -EFAULT if read of config page header fails or data pointer not NULL
5271 * -ENOMEM if pci_alloc failed
5274 mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk)
5277 ConfigPageHeader_t hdr;
5278 dma_addr_t dma_handle;
5279 pRaidPhysDiskPage0_t buffer = NULL;
5282 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5283 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5285 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5286 cfg.cfghdr.hdr = &hdr;
5288 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5290 if (mpt_config(ioc, &cfg) != 0) {
5295 if (!hdr.PageLength) {
5300 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5308 cfg.physAddr = dma_handle;
5309 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5310 cfg.pageAddr = phys_disk_num;
5312 if (mpt_config(ioc, &cfg) != 0) {
5318 memcpy(phys_disk, buffer, sizeof(*buffer));
5319 phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
5324 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5331 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5332 * @ioc: Pointer to a Adapter Strucutre
5333 * @portnum: IOC port number
5337 * -EFAULT if read of config page header fails or data pointer not NULL
5338 * -ENOMEM if pci_alloc failed
5341 mpt_findImVolumes(MPT_ADAPTER *ioc)
5345 dma_addr_t ioc2_dma;
5347 ConfigPageHeader_t header;
5352 if (!ioc->ir_firmware)
5355 /* Free the old page
5357 kfree(ioc->raid_data.pIocPg2);
5358 ioc->raid_data.pIocPg2 = NULL;
5359 mpt_inactive_raid_list_free(ioc);
5361 /* Read IOCP2 header then the page.
5363 header.PageVersion = 0;
5364 header.PageLength = 0;
5365 header.PageNumber = 2;
5366 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5367 cfg.cfghdr.hdr = &header;
5370 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5373 if (mpt_config(ioc, &cfg) != 0)
5376 if (header.PageLength == 0)
5379 iocpage2sz = header.PageLength * 4;
5380 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
5384 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5385 cfg.physAddr = ioc2_dma;
5386 if (mpt_config(ioc, &cfg) != 0)
5389 mem = kmalloc(iocpage2sz, GFP_KERNEL);
5393 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
5394 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
5396 mpt_read_ioc_pg_3(ioc);
5398 for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
5399 mpt_inactive_raid_volumes(ioc,
5400 pIoc2->RaidVolume[i].VolumeBus,
5401 pIoc2->RaidVolume[i].VolumeID);
5404 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
5410 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
5415 ConfigPageHeader_t header;
5416 dma_addr_t ioc3_dma;
5419 /* Free the old page
5421 kfree(ioc->raid_data.pIocPg3);
5422 ioc->raid_data.pIocPg3 = NULL;
5424 /* There is at least one physical disk.
5425 * Read and save IOC Page 3
5427 header.PageVersion = 0;
5428 header.PageLength = 0;
5429 header.PageNumber = 3;
5430 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5431 cfg.cfghdr.hdr = &header;
5434 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5437 if (mpt_config(ioc, &cfg) != 0)
5440 if (header.PageLength == 0)
5443 /* Read Header good, alloc memory
5445 iocpage3sz = header.PageLength * 4;
5446 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
5450 /* Read the Page and save the data
5451 * into malloc'd memory.
5453 cfg.physAddr = ioc3_dma;
5454 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5455 if (mpt_config(ioc, &cfg) == 0) {
5456 mem = kmalloc(iocpage3sz, GFP_KERNEL);
5458 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
5459 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
5463 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
5469 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
5473 ConfigPageHeader_t header;
5474 dma_addr_t ioc4_dma;
5477 /* Read and save IOC Page 4
5479 header.PageVersion = 0;
5480 header.PageLength = 0;
5481 header.PageNumber = 4;
5482 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5483 cfg.cfghdr.hdr = &header;
5486 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5489 if (mpt_config(ioc, &cfg) != 0)
5492 if (header.PageLength == 0)
5495 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
5496 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
5497 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
5500 ioc->alloc_total += iocpage4sz;
5502 ioc4_dma = ioc->spi_data.IocPg4_dma;
5503 iocpage4sz = ioc->spi_data.IocPg4Sz;
5506 /* Read the Page into dma memory.
5508 cfg.physAddr = ioc4_dma;
5509 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5510 if (mpt_config(ioc, &cfg) == 0) {
5511 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
5512 ioc->spi_data.IocPg4_dma = ioc4_dma;
5513 ioc->spi_data.IocPg4Sz = iocpage4sz;
5515 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
5516 ioc->spi_data.pIocPg4 = NULL;
5517 ioc->alloc_total -= iocpage4sz;
5522 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
5526 ConfigPageHeader_t header;
5527 dma_addr_t ioc1_dma;
5531 /* Check the Coalescing Timeout in IOC Page 1
5533 header.PageVersion = 0;
5534 header.PageLength = 0;
5535 header.PageNumber = 1;
5536 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5537 cfg.cfghdr.hdr = &header;
5540 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5543 if (mpt_config(ioc, &cfg) != 0)
5546 if (header.PageLength == 0)
5549 /* Read Header good, alloc memory
5551 iocpage1sz = header.PageLength * 4;
5552 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
5556 /* Read the Page and check coalescing timeout
5558 cfg.physAddr = ioc1_dma;
5559 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5560 if (mpt_config(ioc, &cfg) == 0) {
5562 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
5563 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
5564 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
5566 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Coalescing Enabled Timeout = %d\n",
5569 if (tmp > MPT_COALESCING_TIMEOUT) {
5570 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
5572 /* Write NVRAM and current
5575 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5576 if (mpt_config(ioc, &cfg) == 0) {
5577 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Reset Current Coalescing Timeout to = %d\n",
5578 ioc->name, MPT_COALESCING_TIMEOUT));
5580 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
5581 if (mpt_config(ioc, &cfg) == 0) {
5582 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5583 "Reset NVRAM Coalescing Timeout to = %d\n",
5584 ioc->name, MPT_COALESCING_TIMEOUT));
5586 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5587 "Reset NVRAM Coalescing Timeout Failed\n",
5592 dprintk(ioc, printk(MYIOC_s_WARN_FMT
5593 "Reset of Current Coalescing Timeout Failed!\n",
5599 dprintk(ioc, printk(MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
5603 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
5609 mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
5612 ConfigPageHeader_t hdr;
5614 ManufacturingPage0_t *pbuf = NULL;
5616 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5617 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5619 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
5620 cfg.cfghdr.hdr = &hdr;
5622 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5625 if (mpt_config(ioc, &cfg) != 0)
5628 if (!cfg.cfghdr.hdr->PageLength)
5631 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5632 pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
5636 cfg.physAddr = buf_dma;
5638 if (mpt_config(ioc, &cfg) != 0)
5641 memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name));
5642 memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
5643 memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
5648 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
5651 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5653 * SendEventNotification - Send EventNotification (on or off) request to adapter
5654 * @ioc: Pointer to MPT_ADAPTER structure
5655 * @EvSwitch: Event switch flags
5658 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
5660 EventNotification_t *evnp;
5662 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
5664 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
5668 memset(evnp, 0, sizeof(*evnp));
5670 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
5672 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
5673 evnp->ChainOffset = 0;
5675 evnp->Switch = EvSwitch;
5677 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
5682 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5684 * SendEventAck - Send EventAck request to MPT adapter.
5685 * @ioc: Pointer to MPT_ADAPTER structure
5686 * @evnp: Pointer to original EventNotification request
5689 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
5693 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5694 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
5695 ioc->name,__FUNCTION__));
5699 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventAck\n", ioc->name));
5701 pAck->Function = MPI_FUNCTION_EVENT_ACK;
5702 pAck->ChainOffset = 0;
5703 pAck->Reserved[0] = pAck->Reserved[1] = 0;
5705 pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
5706 pAck->Event = evnp->Event;
5707 pAck->EventContext = evnp->EventContext;
5709 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
5714 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5716 * mpt_config - Generic function to issue config message
5717 * @ioc: Pointer to an adapter structure
5718 * @pCfg: Pointer to a configuration structure. Struct contains
5719 * action, page address, direction, physical address
5720 * and pointer to a configuration page header
5721 * Page header is updated.
5723 * Returns 0 for success
5724 * -EPERM if not allowed due to ISR context
5725 * -EAGAIN if no msg frames currently available
5726 * -EFAULT for non-successful reply or no reply (timeout)
5729 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5732 ConfigExtendedPageHeader_t *pExtHdr = NULL;
5734 unsigned long flags;
5739 /* Prevent calling wait_event() (below), if caller happens
5740 * to be in ISR context, because that is fatal!
5742 in_isr = in_interrupt();
5744 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
5749 /* Get and Populate a free Frame
5751 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5752 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
5756 pReq = (Config_t *)mf;
5757 pReq->Action = pCfg->action;
5759 pReq->ChainOffset = 0;
5760 pReq->Function = MPI_FUNCTION_CONFIG;
5762 /* Assume page type is not extended and clear "reserved" fields. */
5763 pReq->ExtPageLength = 0;
5764 pReq->ExtPageType = 0;
5767 for (ii=0; ii < 8; ii++)
5768 pReq->Reserved2[ii] = 0;
5770 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
5771 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
5772 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
5773 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
5775 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5776 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
5777 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
5778 pReq->ExtPageType = pExtHdr->ExtPageType;
5779 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
5781 /* Page Length must be treated as a reserved field for the extended header. */
5782 pReq->Header.PageLength = 0;
5785 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
5787 /* Add a SGE to the config request.
5790 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
5792 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
5794 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5795 flagsLength |= pExtHdr->ExtPageLength * 4;
5797 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n",
5798 ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action));
5801 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
5803 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n",
5804 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
5807 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
5809 /* Append pCfg pointer to end of mf
5811 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5813 /* Initalize the timer
5815 init_timer(&pCfg->timer);
5816 pCfg->timer.data = (unsigned long) ioc;
5817 pCfg->timer.function = mpt_timer_expired;
5818 pCfg->wait_done = 0;
5820 /* Set the timer; ensure 10 second minimum */
5821 if (pCfg->timeout < 10)
5822 pCfg->timer.expires = jiffies + HZ*10;
5824 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5826 /* Add to end of Q, set timer and then issue this command */
5827 spin_lock_irqsave(&ioc->FreeQlock, flags);
5828 list_add_tail(&pCfg->linkage, &ioc->configQ);
5829 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5831 add_timer(&pCfg->timer);
5832 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5833 wait_event(mpt_waitq, pCfg->wait_done);
5835 /* mf has been freed - do not access */
5842 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5844 * mpt_timer_expired - Callback for timer process.
5845 * Used only internal config functionality.
5846 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5849 mpt_timer_expired(unsigned long data)
5851 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
5853 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired! \n", ioc->name));
5855 /* Perform a FW reload */
5856 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
5857 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
5859 /* No more processing.
5860 * Hard reset clean-up will wake up
5861 * process and free all resources.
5863 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired complete!\n", ioc->name));
5868 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5870 * mpt_ioc_reset - Base cleanup for hard reset
5871 * @ioc: Pointer to the adapter structure
5872 * @reset_phase: Indicates pre- or post-reset functionality
5874 * Remark: Frees resources with internally generated commands.
5877 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
5880 unsigned long flags;
5882 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5883 ": IOC %s_reset routed to MPT base driver!\n",
5884 ioc->name, reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
5885 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
5887 if (reset_phase == MPT_IOC_SETUP_RESET) {
5889 } else if (reset_phase == MPT_IOC_PRE_RESET) {
5890 /* If the internal config Q is not empty -
5891 * delete timer. MF resources will be freed when
5892 * the FIFO's are primed.
5894 spin_lock_irqsave(&ioc->FreeQlock, flags);
5895 list_for_each_entry(pCfg, &ioc->configQ, linkage)
5896 del_timer(&pCfg->timer);
5897 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5902 /* Search the configQ for internal commands.
5903 * Flush the Q, and wake up all suspended threads.
5905 spin_lock_irqsave(&ioc->FreeQlock, flags);
5906 list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
5907 list_del(&pCfg->linkage);
5909 pCfg->status = MPT_CONFIG_ERROR;
5910 pCfg->wait_done = 1;
5911 wake_up(&mpt_waitq);
5913 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5916 return 1; /* currently means nothing really */
5920 #ifdef CONFIG_PROC_FS /* { */
5921 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5923 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5925 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5927 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5929 * Returns 0 for success, non-zero for failure.
5932 procmpt_create(void)
5934 struct proc_dir_entry *ent;
5936 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
5937 if (mpt_proc_root_dir == NULL)
5940 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5942 ent->read_proc = procmpt_summary_read;
5944 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5946 ent->read_proc = procmpt_version_read;
5951 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5953 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5955 * Returns 0 for success, non-zero for failure.
5958 procmpt_destroy(void)
5960 remove_proc_entry("version", mpt_proc_root_dir);
5961 remove_proc_entry("summary", mpt_proc_root_dir);
5962 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
5965 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5967 * procmpt_summary_read - Handle read request of a summary file
5968 * @buf: Pointer to area to write information
5969 * @start: Pointer to start pointer
5970 * @offset: Offset to start writing
5971 * @request: Amount of read data requested
5972 * @eof: Pointer to EOF integer
5975 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
5976 * Returns number of characters written to process performing the read.
5979 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5989 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5993 list_for_each_entry(ioc, &ioc_list, list) {
5996 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5999 if ((out-buf) >= request)
6006 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6009 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6011 * procmpt_version_read - Handle read request from /proc/mpt/version.
6012 * @buf: Pointer to area to write information
6013 * @start: Pointer to start pointer
6014 * @offset: Offset to start writing
6015 * @request: Amount of read data requested
6016 * @eof: Pointer to EOF integer
6019 * Returns number of characters written to process performing the read.
6022 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6025 int scsi, fc, sas, lan, ctl, targ, dmp;
6029 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
6030 len += sprintf(buf+len, " Fusion MPT base driver\n");
6032 scsi = fc = sas = lan = ctl = targ = dmp = 0;
6033 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6035 if (MptCallbacks[cb_idx]) {
6036 switch (MptDriverClass[cb_idx]) {
6038 if (!scsi++) drvname = "SPI host";
6041 if (!fc++) drvname = "FC host";
6044 if (!sas++) drvname = "SAS host";
6047 if (!lan++) drvname = "LAN";
6050 if (!targ++) drvname = "SCSI target";
6053 if (!ctl++) drvname = "ioctl";
6058 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
6062 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6065 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6067 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
6068 * @buf: Pointer to area to write information
6069 * @start: Pointer to start pointer
6070 * @offset: Offset to start writing
6071 * @request: Amount of read data requested
6072 * @eof: Pointer to EOF integer
6075 * Returns number of characters written to process performing the read.
6078 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6080 MPT_ADAPTER *ioc = data;
6086 mpt_get_fw_exp_ver(expVer, ioc);
6088 len = sprintf(buf, "%s:", ioc->name);
6089 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
6090 len += sprintf(buf+len, " (f/w download boot flag set)");
6091 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6092 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
6094 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
6095 ioc->facts.ProductID,
6097 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
6098 if (ioc->facts.FWImageSize)
6099 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
6100 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
6101 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
6102 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
6104 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
6105 ioc->facts.CurrentHostMfaHighAddr);
6106 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
6107 ioc->facts.CurrentSenseBufferHighAddr);
6109 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
6110 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
6112 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6113 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
6115 * Rounding UP to nearest 4-kB boundary here...
6117 sz = (ioc->req_sz * ioc->req_depth) + 128;
6118 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
6119 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6120 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
6121 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
6122 4*ioc->facts.RequestFrameSize,
6123 ioc->facts.GlobalCredits);
6125 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
6126 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
6127 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
6128 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6129 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
6130 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
6131 ioc->facts.CurReplyFrameSize,
6132 ioc->facts.ReplyQueueDepth);
6134 len += sprintf(buf+len, " MaxDevices = %d\n",
6135 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
6136 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
6139 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
6140 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
6142 ioc->facts.NumberOfPorts);
6143 if (ioc->bus_type == FC) {
6144 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
6145 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6146 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6147 a[5], a[4], a[3], a[2], a[1], a[0]);
6149 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
6150 ioc->fc_port_page0[p].WWNN.High,
6151 ioc->fc_port_page0[p].WWNN.Low,
6152 ioc->fc_port_page0[p].WWPN.High,
6153 ioc->fc_port_page0[p].WWPN.Low);
6157 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6160 #endif /* CONFIG_PROC_FS } */
6162 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6164 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
6167 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
6168 sprintf(buf, " (Exp %02d%02d)",
6169 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
6170 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
6173 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
6174 strcat(buf, " [MDBG]");
6178 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6180 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6181 * @ioc: Pointer to MPT_ADAPTER structure
6182 * @buffer: Pointer to buffer where IOC summary info should be written
6183 * @size: Pointer to number of bytes we wrote (set by this routine)
6184 * @len: Offset at which to start writing in buffer
6185 * @showlan: Display LAN stuff?
6187 * This routine writes (english readable) ASCII text, which represents
6188 * a summary of IOC information, to a buffer.
6191 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
6196 mpt_get_fw_exp_ver(expVer, ioc);
6199 * Shorter summary of attached ioc's...
6201 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6204 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
6205 ioc->facts.FWVersion.Word,
6207 ioc->facts.NumberOfPorts,
6210 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6211 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6212 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6213 a[5], a[4], a[3], a[2], a[1], a[0]);
6216 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
6219 y += sprintf(buffer+len+y, " (disabled)");
6221 y += sprintf(buffer+len+y, "\n");
6226 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6230 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6232 * mpt_HardResetHandler - Generic reset handler
6233 * @ioc: Pointer to MPT_ADAPTER structure
6234 * @sleepFlag: Indicates if sleep or schedule must be called.
6236 * Issues SCSI Task Management call based on input arg values.
6237 * If TaskMgmt fails, returns associated SCSI request.
6239 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
6240 * or a non-interrupt thread. In the former, must not call schedule().
6242 * Note: A return of -1 is a FATAL error case, as it means a
6243 * FW reload/initialization failed.
6245 * Returns 0 for SUCCESS or -1 if FAILED.
6248 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6251 unsigned long flags;
6253 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name));
6255 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
6256 printk("MF count 0x%x !\n", ioc->mfcnt);
6259 /* Reset the adapter. Prevent more than 1 call to
6260 * mpt_do_ioc_recovery at any instant in time.
6262 spin_lock_irqsave(&ioc->diagLock, flags);
6263 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
6264 spin_unlock_irqrestore(&ioc->diagLock, flags);
6267 ioc->diagPending = 1;
6269 spin_unlock_irqrestore(&ioc->diagLock, flags);
6271 /* FIXME: If do_ioc_recovery fails, repeat....
6274 /* The SCSI driver needs to adjust timeouts on all current
6275 * commands prior to the diagnostic reset being issued.
6276 * Prevents timeouts occurring during a diagnostic reset...very bad.
6277 * For all other protocol drivers, this is a no-op.
6283 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6284 if (MptResetHandlers[cb_idx]) {
6285 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling IOC reset_setup handler #%d\n",
6286 ioc->name, cb_idx));
6287 r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
6289 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling alt-%s setup reset handler #%d\n",
6290 ioc->name, ioc->alt_ioc->name, cb_idx));
6291 r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_SETUP_RESET);
6297 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
6298 printk(MYIOC_s_WARN_FMT "Cannot recover rc = %d!\n", ioc->name, rc);
6302 ioc->alt_ioc->reload_fw = 0;
6304 spin_lock_irqsave(&ioc->diagLock, flags);
6305 ioc->diagPending = 0;
6307 ioc->alt_ioc->diagPending = 0;
6308 spin_unlock_irqrestore(&ioc->diagLock, flags);
6310 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
6315 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6317 EventDescriptionStr(u8 event, u32 evData0, char *evStr)
6322 case MPI_EVENT_NONE:
6325 case MPI_EVENT_LOG_DATA:
6328 case MPI_EVENT_STATE_CHANGE:
6329 ds = "State Change";
6331 case MPI_EVENT_UNIT_ATTENTION:
6332 ds = "Unit Attention";
6334 case MPI_EVENT_IOC_BUS_RESET:
6335 ds = "IOC Bus Reset";
6337 case MPI_EVENT_EXT_BUS_RESET:
6338 ds = "External Bus Reset";
6340 case MPI_EVENT_RESCAN:
6341 ds = "Bus Rescan Event";
6343 case MPI_EVENT_LINK_STATUS_CHANGE:
6344 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
6345 ds = "Link Status(FAILURE) Change";
6347 ds = "Link Status(ACTIVE) Change";
6349 case MPI_EVENT_LOOP_STATE_CHANGE:
6350 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
6351 ds = "Loop State(LIP) Change";
6352 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
6353 ds = "Loop State(LPE) Change"; /* ??? */
6355 ds = "Loop State(LPB) Change"; /* ??? */
6357 case MPI_EVENT_LOGOUT:
6360 case MPI_EVENT_EVENT_CHANGE:
6366 case MPI_EVENT_INTEGRATED_RAID:
6368 u8 ReasonCode = (u8)(evData0 >> 16);
6369 switch (ReasonCode) {
6370 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
6371 ds = "Integrated Raid: Volume Created";
6373 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
6374 ds = "Integrated Raid: Volume Deleted";
6376 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
6377 ds = "Integrated Raid: Volume Settings Changed";
6379 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
6380 ds = "Integrated Raid: Volume Status Changed";
6382 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
6383 ds = "Integrated Raid: Volume Physdisk Changed";
6385 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
6386 ds = "Integrated Raid: Physdisk Created";
6388 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
6389 ds = "Integrated Raid: Physdisk Deleted";
6391 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
6392 ds = "Integrated Raid: Physdisk Settings Changed";
6394 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
6395 ds = "Integrated Raid: Physdisk Status Changed";
6397 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
6398 ds = "Integrated Raid: Domain Validation Needed";
6400 case MPI_EVENT_RAID_RC_SMART_DATA :
6401 ds = "Integrated Raid; Smart Data";
6403 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
6404 ds = "Integrated Raid: Replace Action Started";
6407 ds = "Integrated Raid";
6412 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
6413 ds = "SCSI Device Status Change";
6415 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
6417 u8 id = (u8)(evData0);
6418 u8 channel = (u8)(evData0 >> 8);
6419 u8 ReasonCode = (u8)(evData0 >> 16);
6420 switch (ReasonCode) {
6421 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
6422 snprintf(evStr, EVENT_DESCR_STR_SZ,
6423 "SAS Device Status Change: Added: "
6424 "id=%d channel=%d", id, channel);
6426 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
6427 snprintf(evStr, EVENT_DESCR_STR_SZ,
6428 "SAS Device Status Change: Deleted: "
6429 "id=%d channel=%d", id, channel);
6431 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
6432 snprintf(evStr, EVENT_DESCR_STR_SZ,
6433 "SAS Device Status Change: SMART Data: "
6434 "id=%d channel=%d", id, channel);
6436 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
6437 snprintf(evStr, EVENT_DESCR_STR_SZ,
6438 "SAS Device Status Change: No Persistancy: "
6439 "id=%d channel=%d", id, channel);
6441 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
6442 snprintf(evStr, EVENT_DESCR_STR_SZ,
6443 "SAS Device Status Change: Unsupported Device "
6444 "Discovered : id=%d channel=%d", id, channel);
6446 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
6447 snprintf(evStr, EVENT_DESCR_STR_SZ,
6448 "SAS Device Status Change: Internal Device "
6449 "Reset : id=%d channel=%d", id, channel);
6451 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
6452 snprintf(evStr, EVENT_DESCR_STR_SZ,
6453 "SAS Device Status Change: Internal Task "
6454 "Abort : id=%d channel=%d", id, channel);
6456 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
6457 snprintf(evStr, EVENT_DESCR_STR_SZ,
6458 "SAS Device Status Change: Internal Abort "
6459 "Task Set : id=%d channel=%d", id, channel);
6461 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
6462 snprintf(evStr, EVENT_DESCR_STR_SZ,
6463 "SAS Device Status Change: Internal Clear "
6464 "Task Set : id=%d channel=%d", id, channel);
6466 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
6467 snprintf(evStr, EVENT_DESCR_STR_SZ,
6468 "SAS Device Status Change: Internal Query "
6469 "Task : id=%d channel=%d", id, channel);
6472 snprintf(evStr, EVENT_DESCR_STR_SZ,
6473 "SAS Device Status Change: Unknown: "
6474 "id=%d channel=%d", id, channel);
6479 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
6480 ds = "Bus Timer Expired";
6482 case MPI_EVENT_QUEUE_FULL:
6484 u16 curr_depth = (u16)(evData0 >> 16);
6485 u8 channel = (u8)(evData0 >> 8);
6486 u8 id = (u8)(evData0);
6488 snprintf(evStr, EVENT_DESCR_STR_SZ,
6489 "Queue Full: channel=%d id=%d depth=%d",
6490 channel, id, curr_depth);
6493 case MPI_EVENT_SAS_SES:
6494 ds = "SAS SES Event";
6496 case MPI_EVENT_PERSISTENT_TABLE_FULL:
6497 ds = "Persistent Table Full";
6499 case MPI_EVENT_SAS_PHY_LINK_STATUS:
6501 u8 LinkRates = (u8)(evData0 >> 8);
6502 u8 PhyNumber = (u8)(evData0);
6503 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
6504 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
6505 switch (LinkRates) {
6506 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
6507 snprintf(evStr, EVENT_DESCR_STR_SZ,
6508 "SAS PHY Link Status: Phy=%d:"
6509 " Rate Unknown",PhyNumber);
6511 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
6512 snprintf(evStr, EVENT_DESCR_STR_SZ,
6513 "SAS PHY Link Status: Phy=%d:"
6514 " Phy Disabled",PhyNumber);
6516 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
6517 snprintf(evStr, EVENT_DESCR_STR_SZ,
6518 "SAS PHY Link Status: Phy=%d:"
6519 " Failed Speed Nego",PhyNumber);
6521 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
6522 snprintf(evStr, EVENT_DESCR_STR_SZ,
6523 "SAS PHY Link Status: Phy=%d:"
6524 " Sata OOB Completed",PhyNumber);
6526 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
6527 snprintf(evStr, EVENT_DESCR_STR_SZ,
6528 "SAS PHY Link Status: Phy=%d:"
6529 " Rate 1.5 Gbps",PhyNumber);
6531 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
6532 snprintf(evStr, EVENT_DESCR_STR_SZ,
6533 "SAS PHY Link Status: Phy=%d:"
6534 " Rate 3.0 Gpbs",PhyNumber);
6537 snprintf(evStr, EVENT_DESCR_STR_SZ,
6538 "SAS PHY Link Status: Phy=%d", PhyNumber);
6543 case MPI_EVENT_SAS_DISCOVERY_ERROR:
6544 ds = "SAS Discovery Error";
6546 case MPI_EVENT_IR_RESYNC_UPDATE:
6548 u8 resync_complete = (u8)(evData0 >> 16);
6549 snprintf(evStr, EVENT_DESCR_STR_SZ,
6550 "IR Resync Update: Complete = %d:",resync_complete);
6555 u8 ReasonCode = (u8)(evData0 >> 16);
6556 switch (ReasonCode) {
6557 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
6558 ds = "IR2: LD State Changed";
6560 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
6561 ds = "IR2: PD State Changed";
6563 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
6564 ds = "IR2: Bad Block Table Full";
6566 case MPI_EVENT_IR2_RC_PD_INSERTED:
6567 ds = "IR2: PD Inserted";
6569 case MPI_EVENT_IR2_RC_PD_REMOVED:
6570 ds = "IR2: PD Removed";
6572 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
6573 ds = "IR2: Foreign CFG Detected";
6575 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
6576 ds = "IR2: Rebuild Medium Error";
6584 case MPI_EVENT_SAS_DISCOVERY:
6587 ds = "SAS Discovery: Start";
6589 ds = "SAS Discovery: Stop";
6592 case MPI_EVENT_LOG_ENTRY_ADDED:
6593 ds = "SAS Log Entry Added";
6596 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
6598 u8 phy_num = (u8)(evData0);
6599 u8 port_num = (u8)(evData0 >> 8);
6600 u8 port_width = (u8)(evData0 >> 16);
6601 u8 primative = (u8)(evData0 >> 24);
6602 snprintf(evStr, EVENT_DESCR_STR_SZ,
6603 "SAS Broadcase Primative: phy=%d port=%d "
6604 "width=%d primative=0x%02x",
6605 phy_num, port_num, port_width, primative);
6609 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
6611 u8 reason = (u8)(evData0);
6612 u8 port_num = (u8)(evData0 >> 8);
6613 u16 handle = le16_to_cpu(evData0 >> 16);
6615 snprintf(evStr, EVENT_DESCR_STR_SZ,
6616 "SAS Initiator Device Status Change: reason=0x%02x "
6617 "port=%d handle=0x%04x",
6618 reason, port_num, handle);
6622 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
6624 u8 max_init = (u8)(evData0);
6625 u8 current_init = (u8)(evData0 >> 8);
6627 snprintf(evStr, EVENT_DESCR_STR_SZ,
6628 "SAS Initiator Device Table Overflow: max initiators=%02d "
6629 "current initators=%02d",
6630 max_init, current_init);
6633 case MPI_EVENT_SAS_SMP_ERROR:
6635 u8 status = (u8)(evData0);
6636 u8 port_num = (u8)(evData0 >> 8);
6637 u8 result = (u8)(evData0 >> 16);
6639 if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
6640 snprintf(evStr, EVENT_DESCR_STR_SZ,
6641 "SAS SMP Error: port=%d result=0x%02x",
6643 else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
6644 snprintf(evStr, EVENT_DESCR_STR_SZ,
6645 "SAS SMP Error: port=%d : CRC Error",
6647 else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
6648 snprintf(evStr, EVENT_DESCR_STR_SZ,
6649 "SAS SMP Error: port=%d : Timeout",
6651 else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
6652 snprintf(evStr, EVENT_DESCR_STR_SZ,
6653 "SAS SMP Error: port=%d : No Destination",
6655 else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
6656 snprintf(evStr, EVENT_DESCR_STR_SZ,
6657 "SAS SMP Error: port=%d : Bad Destination",
6660 snprintf(evStr, EVENT_DESCR_STR_SZ,
6661 "SAS SMP Error: port=%d : status=0x%02x",
6667 * MPT base "custom" events may be added here...
6674 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
6677 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6679 * ProcessEventNotification - Route EventNotificationReply to all event handlers
6680 * @ioc: Pointer to MPT_ADAPTER structure
6681 * @pEventReply: Pointer to EventNotification reply frame
6682 * @evHandlers: Pointer to integer, number of event handlers
6684 * Routes a received EventNotificationReply to all currently registered
6686 * Returns sum of event handlers return values.
6689 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
6698 char evStr[EVENT_DESCR_STR_SZ];
6702 * Do platform normalization of values
6704 event = le32_to_cpu(pEventReply->Event) & 0xFF;
6705 // evCtx = le32_to_cpu(pEventReply->EventContext);
6706 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
6708 evData0 = le32_to_cpu(pEventReply->Data[0]);
6711 EventDescriptionStr(event, evData0, evStr);
6712 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event:(%02Xh) : %s\n",
6717 #ifdef CONFIG_FUSION_LOGGING
6718 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6719 ": Event data:\n", ioc->name));
6720 for (ii = 0; ii < evDataLen; ii++)
6721 devtverboseprintk(ioc, printk(" %08x",
6722 le32_to_cpu(pEventReply->Data[ii])));
6723 devtverboseprintk(ioc, printk("\n"));
6727 * Do general / base driver event processing
6730 case MPI_EVENT_EVENT_CHANGE: /* 0A */
6732 u8 evState = evData0 & 0xFF;
6734 /* CHECKME! What if evState unexpectedly says OFF (0)? */
6736 /* Update EventState field in cached IocFacts */
6737 if (ioc->facts.Function) {
6738 ioc->facts.EventState = evState;
6742 case MPI_EVENT_INTEGRATED_RAID:
6743 mptbase_raid_process_event_data(ioc,
6744 (MpiEventDataRaid_t *)pEventReply->Data);
6751 * Should this event be logged? Events are written sequentially.
6752 * When buffer is full, start again at the top.
6754 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
6757 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
6759 ioc->events[idx].event = event;
6760 ioc->events[idx].eventContext = ioc->eventContext;
6762 for (ii = 0; ii < 2; ii++) {
6764 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
6766 ioc->events[idx].data[ii] = 0;
6769 ioc->eventContext++;
6774 * Call each currently registered protocol event handler.
6776 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6777 if (MptEvHandlers[cb_idx]) {
6778 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Routing Event to event handler #%d\n",
6779 ioc->name, cb_idx));
6780 r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply);
6784 /* FIXME? Examine results here? */
6787 * If needed, send (a single) EventAck.
6789 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
6790 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6791 "EventAck required\n",ioc->name));
6792 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
6793 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SendEventAck returned %d\n",
6798 *evHandlers = handlers;
6802 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6804 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
6805 * @ioc: Pointer to MPT_ADAPTER structure
6806 * @log_info: U32 LogInfo reply word from the IOC
6808 * Refer to lsi/mpi_log_fc.h.
6811 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
6813 char *desc = "unknown";
6815 switch (log_info & 0xFF000000) {
6816 case MPI_IOCLOGINFO_FC_INIT_BASE:
6817 desc = "FCP Initiator";
6819 case MPI_IOCLOGINFO_FC_TARGET_BASE:
6820 desc = "FCP Target";
6822 case MPI_IOCLOGINFO_FC_LAN_BASE:
6825 case MPI_IOCLOGINFO_FC_MSG_BASE:
6826 desc = "MPI Message Layer";
6828 case MPI_IOCLOGINFO_FC_LINK_BASE:
6831 case MPI_IOCLOGINFO_FC_CTX_BASE:
6832 desc = "Context Manager";
6834 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
6835 desc = "Invalid Field Offset";
6837 case MPI_IOCLOGINFO_FC_STATE_CHANGE:
6838 desc = "State Change Info";
6842 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
6843 ioc->name, log_info, desc, (log_info & 0xFFFFFF));
6846 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6848 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
6849 * @ioc: Pointer to MPT_ADAPTER structure
6850 * @mr: Pointer to MPT reply frame
6851 * @log_info: U32 LogInfo word from the IOC
6853 * Refer to lsi/sp_log.h.
6856 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
6858 u32 info = log_info & 0x00FF0000;
6859 char *desc = "unknown";
6863 desc = "bug! MID not found";
6864 if (ioc->reload_fw == 0)
6869 desc = "Parity Error";
6873 desc = "ASYNC Outbound Overrun";
6877 desc = "SYNC Offset Error";
6885 desc = "Msg In Overflow";
6893 desc = "Outbound DMA Overrun";
6897 desc = "Task Management";
6901 desc = "Device Problem";
6905 desc = "Invalid Phase Change";
6909 desc = "Untagged Table Size";
6914 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
6917 /* strings for sas loginfo */
6918 static char *originator_str[] = {
6923 static char *iop_code_str[] = {
6925 "Invalid SAS Address", /* 01h */
6927 "Invalid Page", /* 03h */
6928 "Diag Message Error", /* 04h */
6929 "Task Terminated", /* 05h */
6930 "Enclosure Management", /* 06h */
6931 "Target Mode" /* 07h */
6933 static char *pl_code_str[] = {
6935 "Open Failure", /* 01h */
6936 "Invalid Scatter Gather List", /* 02h */
6937 "Wrong Relative Offset or Frame Length", /* 03h */
6938 "Frame Transfer Error", /* 04h */
6939 "Transmit Frame Connected Low", /* 05h */
6940 "SATA Non-NCQ RW Error Bit Set", /* 06h */
6941 "SATA Read Log Receive Data Error", /* 07h */
6942 "SATA NCQ Fail All Commands After Error", /* 08h */
6943 "SATA Error in Receive Set Device Bit FIS", /* 09h */
6944 "Receive Frame Invalid Message", /* 0Ah */
6945 "Receive Context Message Valid Error", /* 0Bh */
6946 "Receive Frame Current Frame Error", /* 0Ch */
6947 "SATA Link Down", /* 0Dh */
6948 "Discovery SATA Init W IOS", /* 0Eh */
6949 "Config Invalid Page", /* 0Fh */
6950 "Discovery SATA Init Timeout", /* 10h */
6953 "IO Not Yet Executed", /* 13h */
6954 "IO Executed", /* 14h */
6955 "Persistent Reservation Out Not Affiliation "
6957 "Open Transmit DMA Abort", /* 16h */
6958 "IO Device Missing Delay Retry", /* 17h */
6959 "IO Cancelled Due to Recieve Error", /* 18h */
6967 "Enclosure Management" /* 20h */
6969 static char *ir_code_str[] = {
6970 "Raid Action Error", /* 00h */
6980 static char *raid_sub_code_str[] = {
6982 "Volume Creation Failed: Data Passed too "
6984 "Volume Creation Failed: Duplicate Volumes "
6985 "Attempted", /* 02h */
6986 "Volume Creation Failed: Max Number "
6987 "Supported Volumes Exceeded", /* 03h */
6988 "Volume Creation Failed: DMA Error", /* 04h */
6989 "Volume Creation Failed: Invalid Volume Type", /* 05h */
6990 "Volume Creation Failed: Error Reading "
6991 "MFG Page 4", /* 06h */
6992 "Volume Creation Failed: Creating Internal "
6993 "Structures", /* 07h */
7002 "Activation failed: Already Active Volume", /* 10h */
7003 "Activation failed: Unsupported Volume Type", /* 11h */
7004 "Activation failed: Too Many Active Volumes", /* 12h */
7005 "Activation failed: Volume ID in Use", /* 13h */
7006 "Activation failed: Reported Failure", /* 14h */
7007 "Activation failed: Importing a Volume", /* 15h */
7018 "Phys Disk failed: Too Many Phys Disks", /* 20h */
7019 "Phys Disk failed: Data Passed too Large", /* 21h */
7020 "Phys Disk failed: DMA Error", /* 22h */
7021 "Phys Disk failed: Invalid <channel:id>", /* 23h */
7022 "Phys Disk failed: Creating Phys Disk Config "
7035 "Compatibility Error: IR Disabled", /* 30h */
7036 "Compatibility Error: Inquiry Comand Failed", /* 31h */
7037 "Compatibility Error: Device not Direct Access "
7038 "Device ", /* 32h */
7039 "Compatibility Error: Removable Device Found", /* 33h */
7040 "Compatibility Error: Device SCSI Version not "
7041 "2 or Higher", /* 34h */
7042 "Compatibility Error: SATA Device, 48 BIT LBA "
7043 "not Supported", /* 35h */
7044 "Compatibility Error: Device doesn't have "
7045 "512 Byte Block Sizes", /* 36h */
7046 "Compatibility Error: Volume Type Check Failed", /* 37h */
7047 "Compatibility Error: Volume Type is "
7048 "Unsupported by FW", /* 38h */
7049 "Compatibility Error: Disk Drive too Small for "
7050 "use in Volume", /* 39h */
7051 "Compatibility Error: Phys Disk for Create "
7052 "Volume not Found", /* 3Ah */
7053 "Compatibility Error: Too Many or too Few "
7054 "Disks for Volume Type", /* 3Bh */
7055 "Compatibility Error: Disk stripe Sizes "
7056 "Must be 64KB", /* 3Ch */
7057 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
7060 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7062 * mpt_sas_log_info - Log information returned from SAS IOC.
7063 * @ioc: Pointer to MPT_ADAPTER structure
7064 * @log_info: U32 LogInfo reply word from the IOC
7066 * Refer to lsi/mpi_log_sas.h.
7069 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
7071 union loginfo_type {
7080 union loginfo_type sas_loginfo;
7081 char *originator_desc = NULL;
7082 char *code_desc = NULL;
7083 char *sub_code_desc = NULL;
7085 sas_loginfo.loginfo = log_info;
7086 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
7087 (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
7090 originator_desc = originator_str[sas_loginfo.dw.originator];
7092 switch (sas_loginfo.dw.originator) {
7095 if (sas_loginfo.dw.code <
7096 sizeof(iop_code_str)/sizeof(char*))
7097 code_desc = iop_code_str[sas_loginfo.dw.code];
7100 if (sas_loginfo.dw.code <
7101 sizeof(pl_code_str)/sizeof(char*))
7102 code_desc = pl_code_str[sas_loginfo.dw.code];
7105 if (sas_loginfo.dw.code >=
7106 sizeof(ir_code_str)/sizeof(char*))
7108 code_desc = ir_code_str[sas_loginfo.dw.code];
7109 if (sas_loginfo.dw.subcode >=
7110 sizeof(raid_sub_code_str)/sizeof(char*))
7112 if (sas_loginfo.dw.code == 0)
7114 raid_sub_code_str[sas_loginfo.dw.subcode];
7120 if (sub_code_desc != NULL)
7121 printk(MYIOC_s_INFO_FMT
7122 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7124 ioc->name, log_info, originator_desc, code_desc,
7126 else if (code_desc != NULL)
7127 printk(MYIOC_s_INFO_FMT
7128 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7129 " SubCode(0x%04x)\n",
7130 ioc->name, log_info, originator_desc, code_desc,
7131 sas_loginfo.dw.subcode);
7133 printk(MYIOC_s_INFO_FMT
7134 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
7135 " SubCode(0x%04x)\n",
7136 ioc->name, log_info, originator_desc,
7137 sas_loginfo.dw.code, sas_loginfo.dw.subcode);
7140 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7142 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
7143 * @ioc: Pointer to MPT_ADAPTER structure
7144 * @ioc_status: U32 IOCStatus word from IOC
7145 * @mf: Pointer to MPT request frame
7147 * Refer to lsi/mpi.h.
7150 mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7152 Config_t *pReq = (Config_t *)mf;
7153 char extend_desc[EVENT_DESCR_STR_SZ];
7158 if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
7159 page_type = pReq->ExtPageType;
7161 page_type = pReq->Header.PageType;
7164 * ignore invalid page messages for GET_NEXT_HANDLE
7166 form = le32_to_cpu(pReq->PageAddress);
7167 if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
7168 if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
7169 page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
7170 page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
7171 if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
7172 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
7175 if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
7176 if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
7177 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
7181 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
7182 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
7183 page_type, pReq->Header.PageNumber, pReq->Action, form);
7185 switch (ioc_status) {
7187 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7188 desc = "Config Page Invalid Action";
7191 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7192 desc = "Config Page Invalid Type";
7195 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7196 desc = "Config Page Invalid Page";
7199 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7200 desc = "Config Page Invalid Data";
7203 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7204 desc = "Config Page No Defaults";
7207 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7208 desc = "Config Page Can't Commit";
7215 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s: %s\n",
7216 ioc->name, ioc_status, desc, extend_desc));
7220 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
7221 * @ioc: Pointer to MPT_ADAPTER structure
7222 * @ioc_status: U32 IOCStatus word from IOC
7223 * @mf: Pointer to MPT request frame
7225 * Refer to lsi/mpi.h.
7228 mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7230 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
7235 /****************************************************************************/
7236 /* Common IOCStatus values for all replies */
7237 /****************************************************************************/
7239 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
7240 desc = "Invalid Function";
7243 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
7247 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
7248 desc = "Invalid SGL";
7251 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
7252 desc = "Internal Error";
7255 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
7259 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
7260 desc = "Insufficient Resources";
7263 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
7264 desc = "Invalid Field";
7267 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
7268 desc = "Invalid State";
7271 /****************************************************************************/
7272 /* Config IOCStatus values */
7273 /****************************************************************************/
7275 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7276 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7277 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7278 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7279 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7280 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7281 mpt_iocstatus_info_config(ioc, status, mf);
7284 /****************************************************************************/
7285 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
7287 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
7289 /****************************************************************************/
7291 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
7292 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
7293 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
7294 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
7295 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
7296 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
7297 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
7298 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
7299 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
7300 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
7301 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
7302 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
7303 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
7306 /****************************************************************************/
7307 /* SCSI Target values */
7308 /****************************************************************************/
7310 case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
7311 desc = "Target: Priority IO";
7314 case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
7315 desc = "Target: Invalid Port";
7318 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
7319 desc = "Target Invalid IO Index:";
7322 case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
7323 desc = "Target: Aborted";
7326 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
7327 desc = "Target: No Conn Retryable";
7330 case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
7331 desc = "Target: No Connection";
7334 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
7335 desc = "Target: Transfer Count Mismatch";
7338 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
7339 desc = "Target: STS Data not Sent";
7342 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
7343 desc = "Target: Data Offset Error";
7346 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
7347 desc = "Target: Too Much Write Data";
7350 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
7351 desc = "Target: IU Too Short";
7354 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
7355 desc = "Target: ACK NAK Timeout";
7358 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
7359 desc = "Target: Nak Received";
7362 /****************************************************************************/
7363 /* Fibre Channel Direct Access values */
7364 /****************************************************************************/
7366 case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
7367 desc = "FC: Aborted";
7370 case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
7371 desc = "FC: RX ID Invalid";
7374 case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
7375 desc = "FC: DID Invalid";
7378 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
7379 desc = "FC: Node Logged Out";
7382 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
7383 desc = "FC: Exchange Canceled";
7386 /****************************************************************************/
7388 /****************************************************************************/
7390 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
7391 desc = "LAN: Device not Found";
7394 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
7395 desc = "LAN: Device Failure";
7398 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
7399 desc = "LAN: Transmit Error";
7402 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
7403 desc = "LAN: Transmit Aborted";
7406 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
7407 desc = "LAN: Receive Error";
7410 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
7411 desc = "LAN: Receive Aborted";
7414 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
7415 desc = "LAN: Partial Packet";
7418 case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
7419 desc = "LAN: Canceled";
7422 /****************************************************************************/
7423 /* Serial Attached SCSI values */
7424 /****************************************************************************/
7426 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
7427 desc = "SAS: SMP Request Failed";
7430 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
7431 desc = "SAS: SMP Data Overrun";
7442 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s\n",
7443 ioc->name, status, desc));
7446 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7447 EXPORT_SYMBOL(mpt_attach);
7448 EXPORT_SYMBOL(mpt_detach);
7450 EXPORT_SYMBOL(mpt_resume);
7451 EXPORT_SYMBOL(mpt_suspend);
7453 EXPORT_SYMBOL(ioc_list);
7454 EXPORT_SYMBOL(mpt_register);
7455 EXPORT_SYMBOL(mpt_deregister);
7456 EXPORT_SYMBOL(mpt_event_register);
7457 EXPORT_SYMBOL(mpt_event_deregister);
7458 EXPORT_SYMBOL(mpt_reset_register);
7459 EXPORT_SYMBOL(mpt_reset_deregister);
7460 EXPORT_SYMBOL(mpt_device_driver_register);
7461 EXPORT_SYMBOL(mpt_device_driver_deregister);
7462 EXPORT_SYMBOL(mpt_get_msg_frame);
7463 EXPORT_SYMBOL(mpt_put_msg_frame);
7464 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri);
7465 EXPORT_SYMBOL(mpt_free_msg_frame);
7466 EXPORT_SYMBOL(mpt_add_sge);
7467 EXPORT_SYMBOL(mpt_send_handshake_request);
7468 EXPORT_SYMBOL(mpt_verify_adapter);
7469 EXPORT_SYMBOL(mpt_GetIocState);
7470 EXPORT_SYMBOL(mpt_print_ioc_summary);
7471 EXPORT_SYMBOL(mpt_HardResetHandler);
7472 EXPORT_SYMBOL(mpt_config);
7473 EXPORT_SYMBOL(mpt_findImVolumes);
7474 EXPORT_SYMBOL(mpt_alloc_fw_memory);
7475 EXPORT_SYMBOL(mpt_free_fw_memory);
7476 EXPORT_SYMBOL(mptbase_sas_persist_operation);
7477 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
7479 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7481 * fusion_init - Fusion MPT base driver initialization routine.
7483 * Returns 0 for success, non-zero for failure.
7490 show_mptmod_ver(my_NAME, my_VERSION);
7491 printk(KERN_INFO COPYRIGHT "\n");
7493 for (cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
7494 MptCallbacks[cb_idx] = NULL;
7495 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
7496 MptEvHandlers[cb_idx] = NULL;
7497 MptResetHandlers[cb_idx] = NULL;
7500 /* Register ourselves (mptbase) in order to facilitate
7501 * EventNotification handling.
7503 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
7505 /* Register for hard reset handling callbacks.
7507 mpt_reset_register(mpt_base_index, mpt_ioc_reset);
7509 #ifdef CONFIG_PROC_FS
7510 (void) procmpt_create();
7515 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7517 * fusion_exit - Perform driver unload cleanup.
7519 * This routine frees all resources associated with each MPT adapter
7520 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
7526 mpt_reset_deregister(mpt_base_index);
7528 #ifdef CONFIG_PROC_FS
7533 module_init(fusion_init);
7534 module_exit(fusion_exit);