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 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 (mpt_msi_enable == -1) {
1690 /* Enable on SAS, disable on FC and SPI */
1691 if (ioc->bus_type == SAS)
1692 ioc->msi_enable = 1;
1694 ioc->msi_enable = 0;
1696 /* follow flag: 0 - disable; 1 - enable */
1697 ioc->msi_enable = mpt_msi_enable;
1699 if (ioc->errata_flag_1064)
1700 pci_disable_io_access(pdev);
1702 spin_lock_init(&ioc->FreeQlock);
1705 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1707 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1709 /* Set IOC ptr in the pcidev's driver data. */
1710 pci_set_drvdata(ioc->pcidev, ioc);
1712 /* Set lookup ptr. */
1713 list_add_tail(&ioc->list, &ioc_list);
1715 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1717 mpt_detect_bound_ports(ioc, pdev);
1719 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1721 printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",
1724 list_del(&ioc->list);
1726 ioc->alt_ioc->alt_ioc = NULL;
1727 iounmap(ioc->memmap);
1729 pci_release_selected_regions(pdev, ioc->bars);
1731 pci_set_drvdata(pdev, NULL);
1735 /* call per device driver probe entry point */
1736 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
1737 if(MptDeviceDriverHandlers[cb_idx] &&
1738 MptDeviceDriverHandlers[cb_idx]->probe) {
1739 MptDeviceDriverHandlers[cb_idx]->probe(pdev,id);
1743 #ifdef CONFIG_PROC_FS
1745 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1747 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1749 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1751 ent->read_proc = procmpt_iocinfo_read;
1754 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1756 ent->read_proc = procmpt_summary_read;
1765 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1767 * mpt_detach - Remove a PCI intelligent MPT adapter.
1768 * @pdev: Pointer to pci_dev structure
1772 mpt_detach(struct pci_dev *pdev)
1774 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1778 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
1779 remove_proc_entry(pname, NULL);
1780 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
1781 remove_proc_entry(pname, NULL);
1782 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
1783 remove_proc_entry(pname, NULL);
1785 /* call per device driver remove entry point */
1786 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
1787 if(MptDeviceDriverHandlers[cb_idx] &&
1788 MptDeviceDriverHandlers[cb_idx]->remove) {
1789 MptDeviceDriverHandlers[cb_idx]->remove(pdev);
1793 /* Disable interrupts! */
1794 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1797 synchronize_irq(pdev->irq);
1799 /* Clear any lingering interrupt */
1800 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1802 CHIPREG_READ32(&ioc->chip->IntStatus);
1804 mpt_adapter_dispose(ioc);
1806 pci_set_drvdata(pdev, NULL);
1809 /**************************************************************************
1813 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1815 * mpt_suspend - Fusion MPT base driver suspend routine.
1816 * @pdev: Pointer to pci_dev structure
1817 * @state: new state to enter
1820 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
1823 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1825 device_state = pci_choose_state(pdev, state);
1826 printk(MYIOC_s_INFO_FMT "pci-suspend: pdev=0x%p, slot=%s, Entering "
1827 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
1830 /* put ioc into READY_STATE */
1831 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
1832 printk(MYIOC_s_ERR_FMT
1833 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
1836 /* disable interrupts */
1837 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1840 /* Clear any lingering interrupt */
1841 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1843 free_irq(ioc->pci_irq, ioc);
1844 if (ioc->msi_enable)
1845 pci_disable_msi(ioc->pcidev);
1847 pci_save_state(pdev);
1848 pci_disable_device(pdev);
1849 pci_release_selected_regions(pdev, ioc->bars);
1850 pci_set_power_state(pdev, device_state);
1854 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1856 * mpt_resume - Fusion MPT base driver resume routine.
1857 * @pdev: Pointer to pci_dev structure
1860 mpt_resume(struct pci_dev *pdev)
1862 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1863 u32 device_state = pdev->current_state;
1867 printk(MYIOC_s_INFO_FMT "pci-resume: pdev=0x%p, slot=%s, Previous "
1868 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
1871 pci_set_power_state(pdev, PCI_D0);
1872 pci_enable_wake(pdev, PCI_D0, 0);
1873 pci_restore_state(pdev);
1875 err = mpt_mapresources(ioc);
1879 printk(MYIOC_s_INFO_FMT "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1880 ioc->name, (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1881 CHIPREG_READ32(&ioc->chip->Doorbell));
1884 * Errata workaround for SAS pci express:
1885 * Upon returning to the D0 state, the contents of the doorbell will be
1886 * stale data, and this will incorrectly signal to the host driver that
1887 * the firmware is ready to process mpt commands. The workaround is
1888 * to issue a diagnostic reset.
1890 if (ioc->bus_type == SAS && (pdev->device ==
1891 MPI_MANUFACTPAGE_DEVID_SAS1068E || pdev->device ==
1892 MPI_MANUFACTPAGE_DEVID_SAS1064E)) {
1893 if (KickStart(ioc, 1, CAN_SLEEP) < 0) {
1894 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover\n",
1900 /* bring ioc to operational state */
1901 printk(MYIOC_s_INFO_FMT "Sending mpt_do_ioc_recovery\n", ioc->name);
1902 recovery_state = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1904 if (recovery_state != 0)
1905 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover, "
1906 "error:[%x]\n", ioc->name, recovery_state);
1908 printk(MYIOC_s_INFO_FMT
1909 "pci-resume: success\n", ioc->name);
1917 mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase)
1919 if ((MptDriverClass[index] == MPTSPI_DRIVER &&
1920 ioc->bus_type != SPI) ||
1921 (MptDriverClass[index] == MPTFC_DRIVER &&
1922 ioc->bus_type != FC) ||
1923 (MptDriverClass[index] == MPTSAS_DRIVER &&
1924 ioc->bus_type != SAS))
1925 /* make sure we only call the relevant reset handler
1928 return (MptResetHandlers[index])(ioc, reset_phase);
1931 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1933 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1934 * @ioc: Pointer to MPT adapter structure
1935 * @reason: Event word / reason
1936 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1938 * This routine performs all the steps necessary to bring the IOC
1939 * to a OPERATIONAL state.
1941 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1946 * -1 if failed to get board READY
1947 * -2 if READY but IOCFacts Failed
1948 * -3 if READY but PrimeIOCFifos Failed
1949 * -4 if READY but IOCInit Failed
1950 * -5 if failed to enable_device and/or request_selected_regions
1951 * -6 if failed to upload firmware
1954 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1956 int hard_reset_done = 0;
1957 int alt_ioc_ready = 0;
1964 int reset_alt_ioc_active = 0;
1965 int irq_allocated = 0;
1968 printk(MYIOC_s_INFO_FMT "Initiating %s\n", ioc->name,
1969 reason == MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
1971 /* Disable reply interrupts (also blocks FreeQ) */
1972 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1976 if (ioc->alt_ioc->active)
1977 reset_alt_ioc_active = 1;
1979 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1980 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
1981 ioc->alt_ioc->active = 0;
1985 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
1988 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
1989 if (hard_reset_done == -4) {
1990 printk(MYIOC_s_WARN_FMT "Owned by PEER..skipping!\n",
1993 if (reset_alt_ioc_active && ioc->alt_ioc) {
1994 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1995 dprintk(ioc, printk(MYIOC_s_INFO_FMT
1996 "alt_ioc reply irq re-enabled\n", ioc->alt_ioc->name));
1997 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
1998 ioc->alt_ioc->active = 1;
2002 printk(MYIOC_s_WARN_FMT "NOT READY!\n", ioc->name);
2007 /* hard_reset_done = 0 if a soft reset was performed
2008 * and 1 if a hard reset was performed.
2010 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
2011 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
2014 printk(MYIOC_s_WARN_FMT "alt_ioc not ready!\n", ioc->alt_ioc->name);
2017 for (ii=0; ii<5; ii++) {
2018 /* Get IOC facts! Allow 5 retries */
2019 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
2025 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2026 "Retry IocFacts failed rc=%x\n", ioc->name, rc));
2028 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2029 MptDisplayIocCapabilities(ioc);
2032 if (alt_ioc_ready) {
2033 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
2034 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2035 "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
2036 /* Retry - alt IOC was initialized once
2038 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
2041 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2042 "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
2044 reset_alt_ioc_active = 0;
2045 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2046 MptDisplayIocCapabilities(ioc->alt_ioc);
2050 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP) &&
2051 (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)) {
2052 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2053 ioc->bars = pci_select_bars(ioc->pcidev, IORESOURCE_MEM |
2055 if (pci_enable_device(ioc->pcidev))
2057 if (pci_request_selected_regions(ioc->pcidev, ioc->bars,
2063 * Device is reset now. It must have de-asserted the interrupt line
2064 * (if it was asserted) and it should be safe to register for the
2067 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2069 if (ioc->pcidev->irq) {
2070 if (ioc->msi_enable && !pci_enable_msi(ioc->pcidev))
2071 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
2074 ioc->msi_enable = 0;
2075 rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
2076 IRQF_SHARED, ioc->name, ioc);
2078 printk(MYIOC_s_ERR_FMT "Unable to allocate "
2079 "interrupt %d!\n", ioc->name, ioc->pcidev->irq);
2080 if (ioc->msi_enable)
2081 pci_disable_msi(ioc->pcidev);
2085 ioc->pci_irq = ioc->pcidev->irq;
2086 pci_set_master(ioc->pcidev); /* ?? */
2087 dprintk(ioc, printk(MYIOC_s_INFO_FMT "installed at interrupt "
2088 "%d\n", ioc->name, ioc->pcidev->irq));
2092 /* Prime reply & request queues!
2093 * (mucho alloc's) Must be done prior to
2094 * init as upper addresses are needed for init.
2095 * If fails, continue with alt-ioc processing
2097 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
2100 /* May need to check/upload firmware & data here!
2101 * If fails, continue with alt-ioc processing
2103 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
2106 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
2107 printk(MYIOC_s_WARN_FMT ": alt_ioc (%d) FIFO mgmt alloc!\n",
2108 ioc->alt_ioc->name, rc);
2110 reset_alt_ioc_active = 0;
2113 if (alt_ioc_ready) {
2114 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
2116 reset_alt_ioc_active = 0;
2117 printk(MYIOC_s_WARN_FMT "alt_ioc (%d) init failure!\n",
2118 ioc->alt_ioc->name, rc);
2122 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
2123 if (ioc->upload_fw) {
2124 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2125 "firmware upload required!\n", ioc->name));
2127 /* Controller is not operational, cannot do upload
2130 rc = mpt_do_upload(ioc, sleepFlag);
2132 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2134 * Maintain only one pointer to FW memory
2135 * so there will not be two attempt to
2136 * downloadboot onboard dual function
2137 * chips (mpt_adapter_disable,
2140 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2141 "mpt_upload: alt_%s has cached_fw=%p \n",
2142 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
2143 ioc->cached_fw = NULL;
2146 printk(MYIOC_s_WARN_FMT
2147 "firmware upload failure!\n", ioc->name);
2155 /* Enable! (reply interrupt) */
2156 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
2160 if (reset_alt_ioc_active && ioc->alt_ioc) {
2161 /* (re)Enable alt-IOC! (reply interrupt) */
2162 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "alt_ioc reply irq re-enabled\n",
2163 ioc->alt_ioc->name));
2164 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2165 ioc->alt_ioc->active = 1;
2168 /* Enable MPT base driver management of EventNotification
2169 * and EventAck handling.
2171 if ((ret == 0) && (!ioc->facts.EventState))
2172 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
2174 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2175 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
2177 /* Add additional "reason" check before call to GetLanConfigPages
2178 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2179 * recursive scenario; GetLanConfigPages times out, timer expired
2180 * routine calls HardResetHandler, which calls into here again,
2181 * and we try GetLanConfigPages again...
2183 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2186 * Initalize link list for inactive raid volumes.
2188 mutex_init(&ioc->raid_data.inactive_list_mutex);
2189 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2191 if (ioc->bus_type == SAS) {
2193 /* clear persistency table */
2194 if(ioc->facts.IOCExceptions &
2195 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
2196 ret = mptbase_sas_persist_operation(ioc,
2197 MPI_SAS_OP_CLEAR_NOT_PRESENT);
2204 mpt_findImVolumes(ioc);
2206 } else if (ioc->bus_type == FC) {
2207 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
2208 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2210 * Pre-fetch the ports LAN MAC address!
2211 * (LANPage1_t stuff)
2213 (void) GetLanConfigPages(ioc);
2214 a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2215 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2216 "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
2217 ioc->name, a[5], a[4], a[3], a[2], a[1], a[0]));
2221 /* Get NVRAM and adapter maximums from SPP 0 and 2
2223 mpt_GetScsiPortSettings(ioc, 0);
2225 /* Get version and length of SDP 1
2227 mpt_readScsiDevicePageHeaders(ioc, 0);
2231 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
2232 mpt_findImVolumes(ioc);
2234 /* Check, and possibly reset, the coalescing value
2236 mpt_read_ioc_pg_1(ioc);
2238 mpt_read_ioc_pg_4(ioc);
2241 GetIoUnitPage2(ioc);
2242 mpt_get_manufacturing_pg_0(ioc);
2246 * Call each currently registered protocol IOC reset handler
2247 * with post-reset indication.
2248 * NOTE: If we're doing _IOC_BRINGUP, there can be no
2249 * MptResetHandlers[] registered yet.
2251 if (hard_reset_done) {
2253 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
2254 if ((ret == 0) && MptResetHandlers[cb_idx]) {
2255 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2256 "Calling IOC post_reset handler #%d\n",
2257 ioc->name, cb_idx));
2258 rc += mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET);
2262 if (alt_ioc_ready && MptResetHandlers[cb_idx]) {
2263 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2264 "Calling IOC post_reset handler #%d\n",
2265 ioc->alt_ioc->name, cb_idx));
2266 rc += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_POST_RESET);
2270 /* FIXME? Examine results here? */
2274 if ((ret != 0) && irq_allocated) {
2275 free_irq(ioc->pci_irq, ioc);
2276 if (ioc->msi_enable)
2277 pci_disable_msi(ioc->pcidev);
2282 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2284 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2285 * @ioc: Pointer to MPT adapter structure
2286 * @pdev: Pointer to (struct pci_dev) structure
2288 * Search for PCI bus/dev_function which matches
2289 * PCI bus/dev_function (+/-1) for newly discovered 929,
2290 * 929X, 1030 or 1035.
2292 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2293 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2296 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
2298 struct pci_dev *peer=NULL;
2299 unsigned int slot = PCI_SLOT(pdev->devfn);
2300 unsigned int func = PCI_FUNC(pdev->devfn);
2301 MPT_ADAPTER *ioc_srch;
2303 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PCI device %s devfn=%x/%x,"
2304 " searching for devfn match on %x or %x\n",
2305 ioc->name, pci_name(pdev), pdev->bus->number,
2306 pdev->devfn, func-1, func+1));
2308 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
2310 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
2315 list_for_each_entry(ioc_srch, &ioc_list, list) {
2316 struct pci_dev *_pcidev = ioc_srch->pcidev;
2317 if (_pcidev == peer) {
2318 /* Paranoia checks */
2319 if (ioc->alt_ioc != NULL) {
2320 printk(MYIOC_s_WARN_FMT "Oops, already bound to %s!\n",
2321 ioc->name, ioc->alt_ioc->name);
2323 } else if (ioc_srch->alt_ioc != NULL) {
2324 printk(MYIOC_s_WARN_FMT "Oops, already bound to %s!\n",
2325 ioc_srch->name, ioc_srch->alt_ioc->name);
2328 dprintk(ioc, printk(MYIOC_s_INFO_FMT "FOUND! binding to %s\n",
2329 ioc->name, ioc_srch->name));
2330 ioc_srch->alt_ioc = ioc;
2331 ioc->alt_ioc = ioc_srch;
2337 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2339 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2340 * @ioc: Pointer to MPT adapter structure
2343 mpt_adapter_disable(MPT_ADAPTER *ioc)
2348 if (ioc->cached_fw != NULL) {
2349 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: Pushing FW onto "
2350 "adapter\n", __FUNCTION__, ioc->name));
2351 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)
2352 ioc->cached_fw, CAN_SLEEP)) < 0) {
2353 printk(MYIOC_s_WARN_FMT
2354 ": firmware downloadboot failure (%d)!\n",
2359 /* Disable adapter interrupts! */
2360 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2362 /* Clear any lingering interrupt */
2363 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2365 if (ioc->alloc != NULL) {
2367 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "free @ %p, sz=%d bytes\n",
2368 ioc->name, ioc->alloc, ioc->alloc_sz));
2369 pci_free_consistent(ioc->pcidev, sz,
2370 ioc->alloc, ioc->alloc_dma);
2371 ioc->reply_frames = NULL;
2372 ioc->req_frames = NULL;
2374 ioc->alloc_total -= sz;
2377 if (ioc->sense_buf_pool != NULL) {
2378 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2379 pci_free_consistent(ioc->pcidev, sz,
2380 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2381 ioc->sense_buf_pool = NULL;
2382 ioc->alloc_total -= sz;
2385 if (ioc->events != NULL){
2386 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2389 ioc->alloc_total -= sz;
2392 mpt_free_fw_memory(ioc);
2394 kfree(ioc->spi_data.nvram);
2395 mpt_inactive_raid_list_free(ioc);
2396 kfree(ioc->raid_data.pIocPg2);
2397 kfree(ioc->raid_data.pIocPg3);
2398 ioc->spi_data.nvram = NULL;
2399 ioc->raid_data.pIocPg3 = NULL;
2401 if (ioc->spi_data.pIocPg4 != NULL) {
2402 sz = ioc->spi_data.IocPg4Sz;
2403 pci_free_consistent(ioc->pcidev, sz,
2404 ioc->spi_data.pIocPg4,
2405 ioc->spi_data.IocPg4_dma);
2406 ioc->spi_data.pIocPg4 = NULL;
2407 ioc->alloc_total -= sz;
2410 if (ioc->ReqToChain != NULL) {
2411 kfree(ioc->ReqToChain);
2412 kfree(ioc->RequestNB);
2413 ioc->ReqToChain = NULL;
2416 kfree(ioc->ChainToChain);
2417 ioc->ChainToChain = NULL;
2419 if (ioc->HostPageBuffer != NULL) {
2420 if((ret = mpt_host_page_access_control(ioc,
2421 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2422 printk(MYIOC_s_ERR_FMT
2423 "host page buffers free failed (%d)!\n",
2426 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "HostPageBuffer free @ %p, sz=%d bytes\n",
2427 ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
2428 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2429 ioc->HostPageBuffer, ioc->HostPageBuffer_dma);
2430 ioc->HostPageBuffer = NULL;
2431 ioc->HostPageBuffer_sz = 0;
2432 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2436 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2438 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2439 * @ioc: Pointer to MPT adapter structure
2441 * This routine unregisters h/w resources and frees all alloc'd memory
2442 * associated with a MPT adapter structure.
2445 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2447 int sz_first, sz_last;
2452 sz_first = ioc->alloc_total;
2454 mpt_adapter_disable(ioc);
2456 if (ioc->pci_irq != -1) {
2457 free_irq(ioc->pci_irq, ioc);
2458 if (ioc->msi_enable)
2459 pci_disable_msi(ioc->pcidev);
2463 if (ioc->memmap != NULL) {
2464 iounmap(ioc->memmap);
2468 pci_disable_device(ioc->pcidev);
2469 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2471 #if defined(CONFIG_MTRR) && 0
2472 if (ioc->mtrr_reg > 0) {
2473 mtrr_del(ioc->mtrr_reg, 0, 0);
2474 dprintk(ioc, printk(MYIOC_s_INFO_FMT "MTRR region de-registered\n", ioc->name));
2478 /* Zap the adapter lookup ptr! */
2479 list_del(&ioc->list);
2481 sz_last = ioc->alloc_total;
2482 dprintk(ioc, printk(MYIOC_s_INFO_FMT "free'd %d of %d bytes\n",
2483 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2486 ioc->alt_ioc->alt_ioc = NULL;
2491 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2493 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2494 * @ioc: Pointer to MPT adapter structure
2497 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2501 printk(KERN_INFO "%s: ", ioc->name);
2503 printk("%s: ", ioc->prod_name);
2504 printk("Capabilities={");
2506 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2507 printk("Initiator");
2511 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2512 printk("%sTarget", i ? "," : "");
2516 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2517 printk("%sLAN", i ? "," : "");
2523 * This would probably evoke more questions than it's worth
2525 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2526 printk("%sLogBusAddr", i ? "," : "");
2534 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2536 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2537 * @ioc: Pointer to MPT_ADAPTER structure
2538 * @force: Force hard KickStart of IOC
2539 * @sleepFlag: Specifies whether the process can sleep
2542 * 1 - DIAG reset and READY
2543 * 0 - READY initially OR soft reset and READY
2544 * -1 - Any failure on KickStart
2545 * -2 - Msg Unit Reset Failed
2546 * -3 - IO Unit Reset Failed
2547 * -4 - IOC owned by a PEER
2550 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2555 int hard_reset_done = 0;
2560 /* Get current [raw] IOC state */
2561 ioc_state = mpt_GetIocState(ioc, 0);
2562 dhsprintk(ioc, printk(MYIOC_s_INFO_FMT "MakeIocReady [raw] state=%08x\n", ioc->name, ioc_state));
2565 * Check to see if IOC got left/stuck in doorbell handshake
2566 * grip of death. If so, hard reset the IOC.
2568 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2570 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2574 /* Is it already READY? */
2575 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
2579 * Check to see if IOC is in FAULT state.
2581 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2583 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2585 printk(MYIOC_s_WARN_FMT " FAULT code = %04xh\n",
2586 ioc->name, ioc_state & MPI_DOORBELL_DATA_MASK);
2590 * Hmmm... Did it get left operational?
2592 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2593 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC operational unexpected\n",
2597 * If PCI Peer, exit.
2598 * Else, if no fault conditions are present, issue a MessageUnitReset
2599 * Else, fall through to KickStart case
2601 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2602 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2603 "whoinit 0x%x statefault %d force %d\n",
2604 ioc->name, whoinit, statefault, force));
2605 if (whoinit == MPI_WHOINIT_PCI_PEER)
2608 if ((statefault == 0 ) && (force == 0)) {
2609 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2616 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2617 if (hard_reset_done < 0)
2621 * Loop here waiting for IOC to come READY.
2624 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2626 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2627 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2629 * BIOS or previous driver load left IOC in OP state.
2630 * Reset messaging FIFOs.
2632 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2633 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2636 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2638 * Something is wrong. Try to get IOC back
2641 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2642 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2649 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2650 ioc->name, (int)((ii+5)/HZ));
2654 if (sleepFlag == CAN_SLEEP) {
2657 mdelay (1); /* 1 msec delay */
2662 if (statefault < 3) {
2663 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2665 statefault==1 ? "stuck handshake" : "IOC FAULT");
2668 return hard_reset_done;
2671 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2673 * mpt_GetIocState - Get the current state of a MPT adapter.
2674 * @ioc: Pointer to MPT_ADAPTER structure
2675 * @cooked: Request raw or cooked IOC state
2677 * Returns all IOC Doorbell register bits if cooked==0, else just the
2678 * Doorbell bits in MPI_IOC_STATE_MASK.
2681 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2686 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2687 sc = s & MPI_IOC_STATE_MASK;
2690 ioc->last_state = sc;
2692 return cooked ? sc : s;
2695 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2697 * GetIocFacts - Send IOCFacts request to MPT adapter.
2698 * @ioc: Pointer to MPT_ADAPTER structure
2699 * @sleepFlag: Specifies whether the process can sleep
2700 * @reason: If recovery, only update facts.
2702 * Returns 0 for success, non-zero for failure.
2705 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2707 IOCFacts_t get_facts;
2708 IOCFactsReply_t *facts;
2716 /* IOC *must* NOT be in RESET state! */
2717 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2718 printk(MYIOC_s_ERR_FMT "Can't get IOCFacts NOT READY! (%08x)\n",
2719 ioc->name, ioc->last_state );
2723 facts = &ioc->facts;
2725 /* Destination (reply area)... */
2726 reply_sz = sizeof(*facts);
2727 memset(facts, 0, reply_sz);
2729 /* Request area (get_facts on the stack right now!) */
2730 req_sz = sizeof(get_facts);
2731 memset(&get_facts, 0, req_sz);
2733 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2734 /* Assert: All other get_facts fields are zero! */
2736 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2737 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2738 ioc->name, req_sz, reply_sz));
2740 /* No non-zero fields in the get_facts request are greater than
2741 * 1 byte in size, so we can just fire it off as is.
2743 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2744 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2749 * Now byte swap (GRRR) the necessary fields before any further
2750 * inspection of reply contents.
2752 * But need to do some sanity checks on MsgLength (byte) field
2753 * to make sure we don't zero IOC's req_sz!
2755 /* Did we get a valid reply? */
2756 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2757 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2759 * If not been here, done that, save off first WhoInit value
2761 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2762 ioc->FirstWhoInit = facts->WhoInit;
2765 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2766 facts->MsgContext = le32_to_cpu(facts->MsgContext);
2767 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2768 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2769 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2770 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
2771 /* CHECKME! IOCStatus, IOCLogInfo */
2773 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2774 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2777 * FC f/w version changed between 1.1 and 1.2
2778 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2779 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2781 if (facts->MsgVersion < 0x0102) {
2783 * Handle old FC f/w style, convert to new...
2785 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2786 facts->FWVersion.Word =
2787 ((oldv<<12) & 0xFF000000) |
2788 ((oldv<<8) & 0x000FFF00);
2790 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2792 facts->ProductID = le16_to_cpu(facts->ProductID);
2793 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
2794 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
2795 ioc->ir_firmware = 1;
2796 facts->CurrentHostMfaHighAddr =
2797 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2798 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2799 facts->CurrentSenseBufferHighAddr =
2800 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2801 facts->CurReplyFrameSize =
2802 le16_to_cpu(facts->CurReplyFrameSize);
2803 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
2806 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2807 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2808 * to 14 in MPI-1.01.0x.
2810 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2811 facts->MsgVersion > 0x0100) {
2812 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2815 sz = facts->FWImageSize;
2820 facts->FWImageSize = sz;
2822 if (!facts->RequestFrameSize) {
2823 /* Something is wrong! */
2824 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2829 r = sz = facts->BlockSize;
2830 vv = ((63 / (sz * 4)) + 1) & 0x03;
2831 ioc->NB_for_64_byte_frame = vv;
2837 ioc->NBShiftFactor = shiftFactor;
2838 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2839 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2840 ioc->name, vv, shiftFactor, r));
2842 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2844 * Set values for this IOC's request & reply frame sizes,
2845 * and request & reply queue depths...
2847 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2848 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2849 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2850 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2852 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "reply_sz=%3d, reply_depth=%4d\n",
2853 ioc->name, ioc->reply_sz, ioc->reply_depth));
2854 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "req_sz =%3d, req_depth =%4d\n",
2855 ioc->name, ioc->req_sz, ioc->req_depth));
2857 /* Get port facts! */
2858 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2862 printk(MYIOC_s_ERR_FMT
2863 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2864 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2865 RequestFrameSize)/sizeof(u32)));
2872 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2874 * GetPortFacts - Send PortFacts request to MPT adapter.
2875 * @ioc: Pointer to MPT_ADAPTER structure
2876 * @portnum: Port number
2877 * @sleepFlag: Specifies whether the process can sleep
2879 * Returns 0 for success, non-zero for failure.
2882 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2884 PortFacts_t get_pfacts;
2885 PortFactsReply_t *pfacts;
2891 /* IOC *must* NOT be in RESET state! */
2892 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2893 printk(MYIOC_s_ERR_FMT "Can't get PortFacts NOT READY! (%08x)\n",
2894 ioc->name, ioc->last_state );
2898 pfacts = &ioc->pfacts[portnum];
2900 /* Destination (reply area)... */
2901 reply_sz = sizeof(*pfacts);
2902 memset(pfacts, 0, reply_sz);
2904 /* Request area (get_pfacts on the stack right now!) */
2905 req_sz = sizeof(get_pfacts);
2906 memset(&get_pfacts, 0, req_sz);
2908 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2909 get_pfacts.PortNumber = portnum;
2910 /* Assert: All other get_pfacts fields are zero! */
2912 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending get PortFacts(%d) request\n",
2913 ioc->name, portnum));
2915 /* No non-zero fields in the get_pfacts request are greater than
2916 * 1 byte in size, so we can just fire it off as is.
2918 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2919 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2923 /* Did we get a valid reply? */
2925 /* Now byte swap the necessary fields in the response. */
2926 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2927 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2928 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2929 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2930 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2931 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2932 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2933 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2934 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2936 max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
2938 ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
2939 ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
2942 * Place all the devices on channels
2946 if (mpt_channel_mapping) {
2947 ioc->devices_per_bus = 1;
2948 ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
2954 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2956 * SendIocInit - Send IOCInit request to MPT adapter.
2957 * @ioc: Pointer to MPT_ADAPTER structure
2958 * @sleepFlag: Specifies whether the process can sleep
2960 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2962 * Returns 0 for success, non-zero for failure.
2965 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2968 MPIDefaultReply_t init_reply;
2974 memset(&ioc_init, 0, sizeof(ioc_init));
2975 memset(&init_reply, 0, sizeof(init_reply));
2977 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2978 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2980 /* If we are in a recovery mode and we uploaded the FW image,
2981 * then this pointer is not NULL. Skip the upload a second time.
2982 * Set this flag if cached_fw set for either IOC.
2984 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
2988 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "upload_fw %d facts.Flags=%x\n",
2989 ioc->name, ioc->upload_fw, ioc->facts.Flags));
2991 ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
2992 ioc_init.MaxBuses = (U8)ioc->number_of_buses;
2993 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n",
2994 ioc->name, ioc->facts.MsgVersion));
2995 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
2996 // set MsgVersion and HeaderVersion host driver was built with
2997 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
2998 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
3000 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
3001 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
3002 } else if(mpt_host_page_alloc(ioc, &ioc_init))
3005 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
3007 if (sizeof(dma_addr_t) == sizeof(u64)) {
3008 /* Save the upper 32-bits of the request
3009 * (reply) and sense buffers.
3011 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
3012 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
3014 /* Force 32-bit addressing */
3015 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
3016 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
3019 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
3020 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
3021 ioc->facts.MaxDevices = ioc_init.MaxDevices;
3022 ioc->facts.MaxBuses = ioc_init.MaxBuses;
3024 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOCInit (req @ %p)\n",
3025 ioc->name, &ioc_init));
3027 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
3028 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
3030 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
3034 /* No need to byte swap the multibyte fields in the reply
3035 * since we don't even look at its contents.
3038 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending PortEnable (req @ %p)\n",
3039 ioc->name, &ioc_init));
3041 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
3042 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
3046 /* YIKES! SUPER IMPORTANT!!!
3047 * Poll IocState until _OPERATIONAL while IOC is doing
3048 * LoopInit and TargetDiscovery!
3051 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
3052 state = mpt_GetIocState(ioc, 1);
3053 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
3054 if (sleepFlag == CAN_SLEEP) {
3061 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
3062 ioc->name, (int)((count+5)/HZ));
3066 state = mpt_GetIocState(ioc, 1);
3069 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wait IOC_OPERATIONAL state (cnt=%d)\n",
3072 ioc->aen_event_read_flag=0;
3076 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3078 * SendPortEnable - Send PortEnable request to MPT adapter port.
3079 * @ioc: Pointer to MPT_ADAPTER structure
3080 * @portnum: Port number to enable
3081 * @sleepFlag: Specifies whether the process can sleep
3083 * Send PortEnable to bring IOC to OPERATIONAL state.
3085 * Returns 0 for success, non-zero for failure.
3088 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3090 PortEnable_t port_enable;
3091 MPIDefaultReply_t reply_buf;
3096 /* Destination... */
3097 reply_sz = sizeof(MPIDefaultReply_t);
3098 memset(&reply_buf, 0, reply_sz);
3100 req_sz = sizeof(PortEnable_t);
3101 memset(&port_enable, 0, req_sz);
3103 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
3104 port_enable.PortNumber = portnum;
3105 /* port_enable.ChainOffset = 0; */
3106 /* port_enable.MsgFlags = 0; */
3107 /* port_enable.MsgContext = 0; */
3109 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Port(%d)Enable (req @ %p)\n",
3110 ioc->name, portnum, &port_enable));
3112 /* RAID FW may take a long time to enable
3114 if (ioc->ir_firmware || ioc->bus_type == SAS) {
3115 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3116 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3117 300 /*seconds*/, sleepFlag);
3119 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3120 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3121 30 /*seconds*/, sleepFlag);
3127 * mpt_alloc_fw_memory - allocate firmware memory
3128 * @ioc: Pointer to MPT_ADAPTER structure
3129 * @size: total FW bytes
3131 * If memory has already been allocated, the same (cached) value
3134 * Return 0 if successfull, or non-zero for failure
3137 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
3141 if (ioc->cached_fw) {
3142 rc = 0; /* use already allocated memory */
3145 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
3146 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
3147 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
3151 ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma);
3152 if (!ioc->cached_fw) {
3153 printk(MYIOC_s_ERR_FMT "Unable to allocate memory for the cached firmware image!\n",
3157 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Image @ %p[%p], sz=%d[%x] bytes\n",
3158 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, size, size));
3159 ioc->alloc_total += size;
3167 * mpt_free_fw_memory - free firmware memory
3168 * @ioc: Pointer to MPT_ADAPTER structure
3170 * If alt_img is NULL, delete from ioc structure.
3171 * Else, delete a secondary image in same format.
3174 mpt_free_fw_memory(MPT_ADAPTER *ioc)
3178 if (!ioc->cached_fw)
3181 sz = ioc->facts.FWImageSize;
3182 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3183 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3184 pci_free_consistent(ioc->pcidev, sz, ioc->cached_fw, ioc->cached_fw_dma);
3185 ioc->alloc_total -= sz;
3186 ioc->cached_fw = NULL;
3189 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3191 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3192 * @ioc: Pointer to MPT_ADAPTER structure
3193 * @sleepFlag: Specifies whether the process can sleep
3195 * Returns 0 for success, >0 for handshake failure
3196 * <0 for fw upload failure.
3198 * Remark: If bound IOC and a successful FWUpload was performed
3199 * on the bound IOC, the second image is discarded
3200 * and memory is free'd. Both channels must upload to prevent
3201 * IOC from running in degraded mode.
3204 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3206 u8 reply[sizeof(FWUploadReply_t)];
3207 FWUpload_t *prequest;
3208 FWUploadReply_t *preply;
3209 FWUploadTCSGE_t *ptcsge;
3212 int ii, sz, reply_sz;
3215 /* If the image size is 0, we are done.
3217 if ((sz = ioc->facts.FWImageSize) == 0)
3220 if (mpt_alloc_fw_memory(ioc, ioc->facts.FWImageSize) != 0)
3223 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3224 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3226 prequest = (sleepFlag == NO_SLEEP) ? kzalloc(ioc->req_sz, GFP_ATOMIC) :
3227 kzalloc(ioc->req_sz, GFP_KERNEL);
3229 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed "
3230 "while allocating memory \n", ioc->name));
3231 mpt_free_fw_memory(ioc);
3235 preply = (FWUploadReply_t *)&reply;
3237 reply_sz = sizeof(reply);
3238 memset(preply, 0, reply_sz);
3240 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
3241 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
3243 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
3244 ptcsge->DetailsLength = 12;
3245 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
3246 ptcsge->ImageSize = cpu_to_le32(sz);
3249 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
3251 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3252 mpt_add_sge((char *)ptcsge, flagsLength, ioc->cached_fw_dma);
3254 sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
3255 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": Sending FW Upload (req @ %p) sgeoffset=%d \n",
3256 ioc->name, prequest, sgeoffset));
3257 DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest);
3259 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
3260 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
3262 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Upload completed rc=%x \n", ioc->name, ii));
3264 cmdStatus = -EFAULT;
3266 /* Handshake transfer was complete and successful.
3267 * Check the Reply Frame.
3269 int status, transfer_sz;
3270 status = le16_to_cpu(preply->IOCStatus);
3271 if (status == MPI_IOCSTATUS_SUCCESS) {
3272 transfer_sz = le32_to_cpu(preply->ActualImageSize);
3273 if (transfer_sz == sz)
3277 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n",
3278 ioc->name, cmdStatus));
3283 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": fw upload failed, freeing image \n",
3285 mpt_free_fw_memory(ioc);
3292 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3294 * mpt_downloadboot - DownloadBoot code
3295 * @ioc: Pointer to MPT_ADAPTER structure
3296 * @pFwHeader: Pointer to firmware header info
3297 * @sleepFlag: Specifies whether the process can sleep
3299 * FwDownloadBoot requires Programmed IO access.
3301 * Returns 0 for success
3302 * -1 FW Image size is 0
3303 * -2 No valid cached_fw Pointer
3304 * <0 for fw upload failure.
3307 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3309 MpiExtImageHeader_t *pExtImage;
3319 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3320 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
3322 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3323 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3324 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3325 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3326 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3327 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3329 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
3332 if (sleepFlag == CAN_SLEEP) {
3338 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3339 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3341 for (count = 0; count < 30; count ++) {
3342 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3343 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3344 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESET_ADAPTER cleared, count=%d\n",
3349 if (sleepFlag == CAN_SLEEP) {
3356 if ( count == 30 ) {
3357 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot failed! "
3358 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3359 ioc->name, diag0val));
3363 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3364 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3365 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3366 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3367 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3368 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3370 /* Set the DiagRwEn and Disable ARM bits */
3371 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3373 fwSize = (pFwHeader->ImageSize + 3)/4;
3374 ptrFw = (u32 *) pFwHeader;
3376 /* Write the LoadStartAddress to the DiagRw Address Register
3377 * using Programmed IO
3379 if (ioc->errata_flag_1064)
3380 pci_enable_io_access(ioc->pcidev);
3382 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3383 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "LoadStart addr written 0x%x \n",
3384 ioc->name, pFwHeader->LoadStartAddress));
3386 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write FW Image: 0x%x bytes @ %p\n",
3387 ioc->name, fwSize*4, ptrFw));
3389 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3392 nextImage = pFwHeader->NextImageHeaderOffset;
3394 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3396 load_addr = pExtImage->LoadStartAddress;
3398 fwSize = (pExtImage->ImageSize + 3) >> 2;
3399 ptrFw = (u32 *)pExtImage;
3401 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3402 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3403 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3406 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3408 nextImage = pExtImage->NextImageHeaderOffset;
3411 /* Write the IopResetVectorRegAddr */
3412 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
3413 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3415 /* Write the IopResetVectorValue */
3416 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3417 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3419 /* Clear the internal flash bad bit - autoincrementing register,
3420 * so must do two writes.
3422 if (ioc->bus_type == SPI) {
3424 * 1030 and 1035 H/W errata, workaround to access
3425 * the ClearFlashBadSignatureBit
3427 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3428 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3429 diagRwData |= 0x40000000;
3430 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3431 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3433 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3434 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3435 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3436 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3439 if (sleepFlag == CAN_SLEEP) {
3446 if (ioc->errata_flag_1064)
3447 pci_disable_io_access(ioc->pcidev);
3449 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3450 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot diag0val=%x, "
3451 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3452 ioc->name, diag0val));
3453 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3454 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot now diag0val=%x\n",
3455 ioc->name, diag0val));
3456 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3458 /* Write 0xFF to reset the sequencer */
3459 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3461 if (ioc->bus_type == SAS) {
3462 ioc_state = mpt_GetIocState(ioc, 0);
3463 if ( (GetIocFacts(ioc, sleepFlag,
3464 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3465 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "GetIocFacts failed: IocState=%x\n",
3466 ioc->name, ioc_state));
3471 for (count=0; count<HZ*20; count++) {
3472 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3473 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3474 "downloadboot successful! (count=%d) IocState=%x\n",
3475 ioc->name, count, ioc_state));
3476 if (ioc->bus_type == SAS) {
3479 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3480 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3481 "downloadboot: SendIocInit failed\n",
3485 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3486 "downloadboot: SendIocInit successful\n",
3490 if (sleepFlag == CAN_SLEEP) {
3496 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3497 "downloadboot failed! IocState=%x\n",ioc->name, ioc_state));
3501 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3503 * KickStart - Perform hard reset of MPT adapter.
3504 * @ioc: Pointer to MPT_ADAPTER structure
3505 * @force: Force hard reset
3506 * @sleepFlag: Specifies whether the process can sleep
3508 * This routine places MPT adapter in diagnostic mode via the
3509 * WriteSequence register, and then performs a hard reset of adapter
3510 * via the Diagnostic register.
3512 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3513 * or NO_SLEEP (interrupt thread, use mdelay)
3514 * force - 1 if doorbell active, board fault state
3515 * board operational, IOC_RECOVERY or
3516 * IOC_BRINGUP and there is an alt_ioc.
3520 * 1 - hard reset, READY
3521 * 0 - no reset due to History bit, READY
3522 * -1 - no reset due to History bit but not READY
3523 * OR reset but failed to come READY
3524 * -2 - no reset, could not enter DIAG mode
3525 * -3 - reset but bad FW bit
3528 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3530 int hard_reset_done = 0;
3534 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStarting!\n", ioc->name));
3535 if (ioc->bus_type == SPI) {
3536 /* Always issue a Msg Unit Reset first. This will clear some
3537 * SCSI bus hang conditions.
3539 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3541 if (sleepFlag == CAN_SLEEP) {
3548 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3549 if (hard_reset_done < 0)
3550 return hard_reset_done;
3552 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n",
3555 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3556 for (cnt=0; cnt<cntdn; cnt++) {
3557 ioc_state = mpt_GetIocState(ioc, 1);
3558 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3559 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStart successful! (cnt=%d)\n",
3561 return hard_reset_done;
3563 if (sleepFlag == CAN_SLEEP) {
3570 dinitprintk(ioc, printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3571 ioc->name, mpt_GetIocState(ioc, 0)));
3575 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3577 * mpt_diag_reset - Perform hard reset of the adapter.
3578 * @ioc: Pointer to MPT_ADAPTER structure
3579 * @ignore: Set if to honor and clear to ignore
3580 * the reset history bit
3581 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3582 * else set to NO_SLEEP (use mdelay instead)
3584 * This routine places the adapter in diagnostic mode via the
3585 * WriteSequence register and then performs a hard reset of adapter
3586 * via the Diagnostic register. Adapter should be in ready state
3587 * upon successful completion.
3589 * Returns: 1 hard reset successful
3590 * 0 no reset performed because reset history bit set
3591 * -2 enabling diagnostic mode failed
3592 * -3 diagnostic reset failed
3595 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3599 int hard_reset_done = 0;
3602 MpiFwHeader_t *cached_fw; /* Pointer to FW */
3604 /* Clear any existing interrupts */
3605 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3607 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3608 drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3609 "address=%p\n", ioc->name, __FUNCTION__,
3610 &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3611 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3612 if (sleepFlag == CAN_SLEEP)
3617 for (count = 0; count < 60; count ++) {
3618 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3619 doorbell &= MPI_IOC_STATE_MASK;
3621 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3622 "looking for READY STATE: doorbell=%x"
3624 ioc->name, doorbell, count));
3625 if (doorbell == MPI_IOC_STATE_READY) {
3630 if (sleepFlag == CAN_SLEEP)
3638 /* Use "Diagnostic reset" method! (only thing available!) */
3639 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3641 if (ioc->debug_level & MPT_DEBUG) {
3643 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3644 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3645 ioc->name, diag0val, diag1val));
3648 /* Do the reset if we are told to ignore the reset history
3649 * or if the reset history is 0
3651 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3652 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3653 /* Write magic sequence to WriteSequence register
3654 * Loop until in diagnostic mode
3656 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3657 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3658 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3659 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3660 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3661 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3664 if (sleepFlag == CAN_SLEEP) {
3672 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3673 ioc->name, diag0val);
3678 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3680 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3681 ioc->name, diag0val));
3684 if (ioc->debug_level & MPT_DEBUG) {
3686 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3687 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3688 ioc->name, diag0val, diag1val));
3691 * Disable the ARM (Bug fix)
3694 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3698 * Now hit the reset bit in the Diagnostic register
3699 * (THE BIG HAMMER!) (Clears DRWE bit).
3701 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3702 hard_reset_done = 1;
3703 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset performed\n",
3707 * Call each currently registered protocol IOC reset handler
3708 * with pre-reset indication.
3709 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3710 * MptResetHandlers[] registered yet.
3716 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
3717 if (MptResetHandlers[cb_idx]) {
3718 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3719 "Calling IOC pre_reset handler #%d\n",
3720 ioc->name, cb_idx));
3721 r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET);
3723 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3724 "Calling alt-%s pre_reset handler #%d\n",
3725 ioc->name, ioc->alt_ioc->name, cb_idx));
3726 r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_PRE_RESET);
3730 /* FIXME? Examine results here? */
3734 cached_fw = (MpiFwHeader_t *)ioc->cached_fw;
3735 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
3736 cached_fw = (MpiFwHeader_t *)ioc->alt_ioc->cached_fw;
3740 /* If the DownloadBoot operation fails, the
3741 * IOC will be left unusable. This is a fatal error
3742 * case. _diag_reset will return < 0
3744 for (count = 0; count < 30; count ++) {
3745 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3746 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3750 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n",
3751 ioc->name, diag0val, count));
3753 if (sleepFlag == CAN_SLEEP) {
3759 if ((count = mpt_downloadboot(ioc, cached_fw, sleepFlag)) < 0) {
3760 printk(MYIOC_s_WARN_FMT
3761 "firmware downloadboot failure (%d)!\n", ioc->name, count);
3765 /* Wait for FW to reload and for board
3766 * to go to the READY state.
3767 * Maximum wait is 60 seconds.
3768 * If fail, no error will check again
3769 * with calling program.
3771 for (count = 0; count < 60; count ++) {
3772 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3773 doorbell &= MPI_IOC_STATE_MASK;
3775 if (doorbell == MPI_IOC_STATE_READY) {
3780 if (sleepFlag == CAN_SLEEP) {
3789 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3790 if (ioc->debug_level & MPT_DEBUG) {
3792 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3793 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3794 ioc->name, diag0val, diag1val));
3797 /* Clear RESET_HISTORY bit! Place board in the
3798 * diagnostic mode to update the diag register.
3800 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3802 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3803 /* Write magic sequence to WriteSequence register
3804 * Loop until in diagnostic mode
3806 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3807 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3808 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3809 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3810 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3811 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3814 if (sleepFlag == CAN_SLEEP) {
3822 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3823 ioc->name, diag0val);
3826 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3828 diag0val &= ~MPI_DIAG_RESET_HISTORY;
3829 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3830 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3831 if (diag0val & MPI_DIAG_RESET_HISTORY) {
3832 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3836 /* Disable Diagnostic Mode
3838 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3840 /* Check FW reload status flags.
3842 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3843 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3844 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3845 ioc->name, diag0val);
3849 if (ioc->debug_level & MPT_DEBUG) {
3851 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3852 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3853 ioc->name, diag0val, diag1val));
3857 * Reset flag that says we've enabled event notification
3859 ioc->facts.EventState = 0;
3862 ioc->alt_ioc->facts.EventState = 0;
3864 return hard_reset_done;
3867 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3869 * SendIocReset - Send IOCReset request to MPT adapter.
3870 * @ioc: Pointer to MPT_ADAPTER structure
3871 * @reset_type: reset type, expected values are
3872 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3873 * @sleepFlag: Specifies whether the process can sleep
3875 * Send IOCReset request to the MPT adapter.
3877 * Returns 0 for success, non-zero for failure.
3880 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3886 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOC reset(0x%02x)!\n",
3887 ioc->name, reset_type));
3888 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3889 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3892 /* FW ACK'd request, wait for READY state
3895 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
3897 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3901 if (sleepFlag != CAN_SLEEP)
3904 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
3905 ioc->name, (int)((count+5)/HZ));
3909 if (sleepFlag == CAN_SLEEP) {
3912 mdelay (1); /* 1 msec delay */
3917 * Cleanup all event stuff for this IOC; re-issue EventNotification
3918 * request if needed.
3920 if (ioc->facts.Function)
3921 ioc->facts.EventState = 0;
3926 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3928 * initChainBuffers - Allocate memory for and initialize chain buffers
3929 * @ioc: Pointer to MPT_ADAPTER structure
3931 * Allocates memory for and initializes chain buffers,
3932 * chain buffer control arrays and spinlock.
3935 initChainBuffers(MPT_ADAPTER *ioc)
3938 int sz, ii, num_chain;
3939 int scale, num_sge, numSGE;
3941 /* ReqToChain size must equal the req_depth
3944 if (ioc->ReqToChain == NULL) {
3945 sz = ioc->req_depth * sizeof(int);
3946 mem = kmalloc(sz, GFP_ATOMIC);
3950 ioc->ReqToChain = (int *) mem;
3951 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReqToChain alloc @ %p, sz=%d bytes\n",
3952 ioc->name, mem, sz));
3953 mem = kmalloc(sz, GFP_ATOMIC);
3957 ioc->RequestNB = (int *) mem;
3958 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestNB alloc @ %p, sz=%d bytes\n",
3959 ioc->name, mem, sz));
3961 for (ii = 0; ii < ioc->req_depth; ii++) {
3962 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
3965 /* ChainToChain size must equal the total number
3966 * of chain buffers to be allocated.
3969 * Calculate the number of chain buffers needed(plus 1) per I/O
3970 * then multiply the maximum number of simultaneous cmds
3972 * num_sge = num sge in request frame + last chain buffer
3973 * scale = num sge per chain buffer if no chain element
3975 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3976 if (sizeof(dma_addr_t) == sizeof(u64))
3977 num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3979 num_sge = 1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3981 if (sizeof(dma_addr_t) == sizeof(u64)) {
3982 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3983 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3985 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3986 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3988 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n",
3989 ioc->name, num_sge, numSGE));
3991 if ( numSGE > MPT_SCSI_SG_DEPTH )
3992 numSGE = MPT_SCSI_SG_DEPTH;
3995 while (numSGE - num_sge > 0) {
3997 num_sge += (scale - 1);
4001 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Now numSGE=%d num_sge=%d num_chain=%d\n",
4002 ioc->name, numSGE, num_sge, num_chain));
4004 if (ioc->bus_type == SPI)
4005 num_chain *= MPT_SCSI_CAN_QUEUE;
4007 num_chain *= MPT_FC_CAN_QUEUE;
4009 ioc->num_chain = num_chain;
4011 sz = num_chain * sizeof(int);
4012 if (ioc->ChainToChain == NULL) {
4013 mem = kmalloc(sz, GFP_ATOMIC);
4017 ioc->ChainToChain = (int *) mem;
4018 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainToChain alloc @ %p, sz=%d bytes\n",
4019 ioc->name, mem, sz));
4021 mem = (u8 *) ioc->ChainToChain;
4023 memset(mem, 0xFF, sz);
4027 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4029 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
4030 * @ioc: Pointer to MPT_ADAPTER structure
4032 * This routine allocates memory for the MPT reply and request frame
4033 * pools (if necessary), and primes the IOC reply FIFO with
4036 * Returns 0 for success, non-zero for failure.
4039 PrimeIocFifos(MPT_ADAPTER *ioc)
4042 unsigned long flags;
4043 dma_addr_t alloc_dma;
4045 int i, reply_sz, sz, total_size, num_chain;
4047 /* Prime reply FIFO... */
4049 if (ioc->reply_frames == NULL) {
4050 if ( (num_chain = initChainBuffers(ioc)) < 0)
4053 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
4054 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
4055 ioc->name, ioc->reply_sz, ioc->reply_depth));
4056 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d[%x] bytes\n",
4057 ioc->name, reply_sz, reply_sz));
4059 sz = (ioc->req_sz * ioc->req_depth);
4060 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d bytes, RequestDepth=%d\n",
4061 ioc->name, ioc->req_sz, ioc->req_depth));
4062 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d[%x] bytes\n",
4063 ioc->name, sz, sz));
4066 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
4067 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d bytes, ChainDepth=%d\n",
4068 ioc->name, ioc->req_sz, num_chain));
4069 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
4070 ioc->name, sz, sz, num_chain));
4073 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
4075 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
4080 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Total alloc @ %p[%p], sz=%d[%x] bytes\n",
4081 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
4083 memset(mem, 0, total_size);
4084 ioc->alloc_total += total_size;
4086 ioc->alloc_dma = alloc_dma;
4087 ioc->alloc_sz = total_size;
4088 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
4089 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4091 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4092 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4094 alloc_dma += reply_sz;
4097 /* Request FIFO - WE manage this! */
4099 ioc->req_frames = (MPT_FRAME_HDR *) mem;
4100 ioc->req_frames_dma = alloc_dma;
4102 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffers @ %p[%p]\n",
4103 ioc->name, mem, (void *)(ulong)alloc_dma));
4105 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4107 #if defined(CONFIG_MTRR) && 0
4109 * Enable Write Combining MTRR for IOC's memory region.
4110 * (at least as much as we can; "size and base must be
4111 * multiples of 4 kiB"
4113 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
4115 MTRR_TYPE_WRCOMB, 1);
4116 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MTRR region registered (base:size=%08x:%x)\n",
4117 ioc->name, ioc->req_frames_dma, sz));
4120 for (i = 0; i < ioc->req_depth; i++) {
4121 alloc_dma += ioc->req_sz;
4125 ioc->ChainBuffer = mem;
4126 ioc->ChainBufferDMA = alloc_dma;
4128 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffers @ %p(%p)\n",
4129 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
4131 /* Initialize the free chain Q.
4134 INIT_LIST_HEAD(&ioc->FreeChainQ);
4136 /* Post the chain buffers to the FreeChainQ.
4138 mem = (u8 *)ioc->ChainBuffer;
4139 for (i=0; i < num_chain; i++) {
4140 mf = (MPT_FRAME_HDR *) mem;
4141 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
4145 /* Initialize Request frames linked list
4147 alloc_dma = ioc->req_frames_dma;
4148 mem = (u8 *) ioc->req_frames;
4150 spin_lock_irqsave(&ioc->FreeQlock, flags);
4151 INIT_LIST_HEAD(&ioc->FreeQ);
4152 for (i = 0; i < ioc->req_depth; i++) {
4153 mf = (MPT_FRAME_HDR *) mem;
4155 /* Queue REQUESTs *internally*! */
4156 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
4160 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4162 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4163 ioc->sense_buf_pool =
4164 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
4165 if (ioc->sense_buf_pool == NULL) {
4166 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
4171 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
4172 ioc->alloc_total += sz;
4173 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SenseBuffers @ %p[%p]\n",
4174 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
4178 /* Post Reply frames to FIFO
4180 alloc_dma = ioc->alloc_dma;
4181 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4182 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4184 for (i = 0; i < ioc->reply_depth; i++) {
4185 /* Write each address to the IOC! */
4186 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
4187 alloc_dma += ioc->reply_sz;
4193 if (ioc->alloc != NULL) {
4195 pci_free_consistent(ioc->pcidev,
4197 ioc->alloc, ioc->alloc_dma);
4198 ioc->reply_frames = NULL;
4199 ioc->req_frames = NULL;
4200 ioc->alloc_total -= sz;
4202 if (ioc->sense_buf_pool != NULL) {
4203 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4204 pci_free_consistent(ioc->pcidev,
4206 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
4207 ioc->sense_buf_pool = NULL;
4212 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4214 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4215 * from IOC via doorbell handshake method.
4216 * @ioc: Pointer to MPT_ADAPTER structure
4217 * @reqBytes: Size of the request in bytes
4218 * @req: Pointer to MPT request frame
4219 * @replyBytes: Expected size of the reply in bytes
4220 * @u16reply: Pointer to area where reply should be written
4221 * @maxwait: Max wait time for a reply (in seconds)
4222 * @sleepFlag: Specifies whether the process can sleep
4224 * NOTES: It is the callers responsibility to byte-swap fields in the
4225 * request which are greater than 1 byte in size. It is also the
4226 * callers responsibility to byte-swap response fields which are
4227 * greater than 1 byte in size.
4229 * Returns 0 for success, non-zero for failure.
4232 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
4233 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
4235 MPIDefaultReply_t *mptReply;
4240 * Get ready to cache a handshake reply
4242 ioc->hs_reply_idx = 0;
4243 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4244 mptReply->MsgLength = 0;
4247 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4248 * then tell IOC that we want to handshake a request of N words.
4249 * (WRITE u32val to Doorbell reg).
4251 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4252 CHIPREG_WRITE32(&ioc->chip->Doorbell,
4253 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
4254 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
4257 * Wait for IOC's doorbell handshake int
4259 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4262 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4263 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4265 /* Read doorbell and check for active bit */
4266 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
4270 * Clear doorbell int (WRITE 0 to IntStatus reg),
4271 * then wait for IOC to ACKnowledge that it's ready for
4272 * our handshake request.
4274 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4275 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4280 u8 *req_as_bytes = (u8 *) req;
4283 * Stuff request words via doorbell handshake,
4284 * with ACK from IOC for each.
4286 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
4287 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
4288 (req_as_bytes[(ii*4) + 1] << 8) |
4289 (req_as_bytes[(ii*4) + 2] << 16) |
4290 (req_as_bytes[(ii*4) + 3] << 24));
4292 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
4293 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4297 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req));
4298 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req);
4300 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n",
4301 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
4304 * Wait for completion of doorbell handshake reply from the IOC
4306 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
4309 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake reply count=%d%s\n",
4310 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
4313 * Copy out the cached reply...
4315 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
4316 u16reply[ii] = ioc->hs_reply[ii];
4324 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4326 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4327 * @ioc: Pointer to MPT_ADAPTER structure
4328 * @howlong: How long to wait (in seconds)
4329 * @sleepFlag: Specifies whether the process can sleep
4331 * This routine waits (up to ~2 seconds max) for IOC doorbell
4332 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4333 * bit in its IntStatus register being clear.
4335 * Returns a negative value on failure, else wait loop count.
4338 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4344 cntdn = 1000 * howlong;
4346 if (sleepFlag == CAN_SLEEP) {
4349 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4350 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4357 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4358 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4365 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell ACK (count=%d)\n",
4370 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4371 ioc->name, count, intstat);
4375 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4377 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4378 * @ioc: Pointer to MPT_ADAPTER structure
4379 * @howlong: How long to wait (in seconds)
4380 * @sleepFlag: Specifies whether the process can sleep
4382 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4383 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4385 * Returns a negative value on failure, else wait loop count.
4388 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4394 cntdn = 1000 * howlong;
4395 if (sleepFlag == CAN_SLEEP) {
4397 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4398 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4405 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4406 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4414 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4415 ioc->name, count, howlong));
4419 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4420 ioc->name, count, intstat);
4424 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4426 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4427 * @ioc: Pointer to MPT_ADAPTER structure
4428 * @howlong: How long to wait (in seconds)
4429 * @sleepFlag: Specifies whether the process can sleep
4431 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4432 * Reply is cached to IOC private area large enough to hold a maximum
4433 * of 128 bytes of reply data.
4435 * Returns a negative value on failure, else size of reply in WORDS.
4438 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4443 u16 *hs_reply = ioc->hs_reply;
4444 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4447 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4450 * Get first two u16's so we can look at IOC's intended reply MsgLength
4453 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4456 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4457 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4458 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4461 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4462 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4466 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4467 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4468 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4471 * If no error (and IOC said MsgLength is > 0), piece together
4472 * reply 16 bits at a time.
4474 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4475 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4477 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4478 /* don't overflow our IOC hs_reply[] buffer! */
4479 if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
4480 hs_reply[u16cnt] = hword;
4481 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4484 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4486 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4489 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4494 else if (u16cnt != (2 * mptReply->MsgLength)) {
4497 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4502 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name));
4503 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply);
4505 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4506 ioc->name, t, u16cnt/2));
4510 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4512 * GetLanConfigPages - Fetch LANConfig pages.
4513 * @ioc: Pointer to MPT_ADAPTER structure
4515 * Return: 0 for success
4516 * -ENOMEM if no memory available
4517 * -EPERM if not allowed due to ISR context
4518 * -EAGAIN if no msg frames currently available
4519 * -EFAULT for non-successful reply or no reply (timeout)
4522 GetLanConfigPages(MPT_ADAPTER *ioc)
4524 ConfigPageHeader_t hdr;
4526 LANPage0_t *ppage0_alloc;
4527 dma_addr_t page0_dma;
4528 LANPage1_t *ppage1_alloc;
4529 dma_addr_t page1_dma;
4534 /* Get LAN Page 0 header */
4535 hdr.PageVersion = 0;
4538 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4539 cfg.cfghdr.hdr = &hdr;
4541 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4546 if ((rc = mpt_config(ioc, &cfg)) != 0)
4549 if (hdr.PageLength > 0) {
4550 data_sz = hdr.PageLength * 4;
4551 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4554 memset((u8 *)ppage0_alloc, 0, data_sz);
4555 cfg.physAddr = page0_dma;
4556 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4558 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4560 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4561 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4565 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4568 * Normalize endianness of structure data,
4569 * by byte-swapping all > 1 byte fields!
4578 /* Get LAN Page 1 header */
4579 hdr.PageVersion = 0;
4582 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4583 cfg.cfghdr.hdr = &hdr;
4585 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4589 if ((rc = mpt_config(ioc, &cfg)) != 0)
4592 if (hdr.PageLength == 0)
4595 data_sz = hdr.PageLength * 4;
4597 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4599 memset((u8 *)ppage1_alloc, 0, data_sz);
4600 cfg.physAddr = page1_dma;
4601 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4603 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4605 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4606 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4609 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4612 * Normalize endianness of structure data,
4613 * by byte-swapping all > 1 byte fields!
4621 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4623 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
4624 * @ioc: Pointer to MPT_ADAPTER structure
4625 * @persist_opcode: see below
4627 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4628 * devices not currently present.
4629 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4631 * NOTE: Don't use not this function during interrupt time.
4633 * Returns 0 for success, non-zero error
4636 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4638 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4640 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
4641 SasIoUnitControlReply_t *sasIoUnitCntrReply;
4642 MPT_FRAME_HDR *mf = NULL;
4643 MPIHeader_t *mpi_hdr;
4646 /* insure garbage is not sent to fw */
4647 switch(persist_opcode) {
4649 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
4650 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
4658 printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode);
4660 /* Get a MF for this command.
4662 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4663 printk("%s: no msg frames!\n",__FUNCTION__);
4667 mpi_hdr = (MPIHeader_t *) mf;
4668 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
4669 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
4670 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
4671 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
4672 sasIoUnitCntrReq->Operation = persist_opcode;
4674 init_timer(&ioc->persist_timer);
4675 ioc->persist_timer.data = (unsigned long) ioc;
4676 ioc->persist_timer.function = mpt_timer_expired;
4677 ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
4678 ioc->persist_wait_done=0;
4679 add_timer(&ioc->persist_timer);
4680 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4681 wait_event(mpt_waitq, ioc->persist_wait_done);
4683 sasIoUnitCntrReply =
4684 (SasIoUnitControlReply_t *)ioc->persist_reply_frame;
4685 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
4686 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4688 sasIoUnitCntrReply->IOCStatus,
4689 sasIoUnitCntrReply->IOCLogInfo);
4693 printk("%s: success\n",__FUNCTION__);
4697 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4700 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
4701 MpiEventDataRaid_t * pRaidEventData)
4710 volume = pRaidEventData->VolumeID;
4711 reason = pRaidEventData->ReasonCode;
4712 disk = pRaidEventData->PhysDiskNum;
4713 status = le32_to_cpu(pRaidEventData->SettingsStatus);
4714 flags = (status >> 0) & 0xff;
4715 state = (status >> 8) & 0xff;
4717 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
4721 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
4722 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
4723 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
4724 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
4725 ioc->name, disk, volume);
4727 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
4732 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4733 printk(MYIOC_s_INFO_FMT " volume has been created\n",
4737 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4739 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
4743 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
4744 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
4748 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4749 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
4751 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
4753 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
4755 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
4758 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
4760 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
4761 ? ", quiesced" : "",
4762 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
4763 ? ", resync in progress" : "" );
4766 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
4767 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
4771 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4772 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
4776 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4777 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
4781 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
4782 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
4786 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4787 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
4789 state == MPI_PHYSDISK0_STATUS_ONLINE
4791 : state == MPI_PHYSDISK0_STATUS_MISSING
4793 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
4795 : state == MPI_PHYSDISK0_STATUS_FAILED
4797 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
4799 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
4800 ? "offline requested"
4801 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
4802 ? "failed requested"
4803 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
4806 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
4807 ? ", out of sync" : "",
4808 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
4809 ? ", quiesced" : "" );
4812 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
4813 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
4817 case MPI_EVENT_RAID_RC_SMART_DATA:
4818 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
4819 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
4822 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
4823 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
4829 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4831 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4832 * @ioc: Pointer to MPT_ADAPTER structure
4834 * Returns: 0 for success
4835 * -ENOMEM if no memory available
4836 * -EPERM if not allowed due to ISR context
4837 * -EAGAIN if no msg frames currently available
4838 * -EFAULT for non-successful reply or no reply (timeout)
4841 GetIoUnitPage2(MPT_ADAPTER *ioc)
4843 ConfigPageHeader_t hdr;
4845 IOUnitPage2_t *ppage_alloc;
4846 dma_addr_t page_dma;
4850 /* Get the page header */
4851 hdr.PageVersion = 0;
4854 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4855 cfg.cfghdr.hdr = &hdr;
4857 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4862 if ((rc = mpt_config(ioc, &cfg)) != 0)
4865 if (hdr.PageLength == 0)
4868 /* Read the config page */
4869 data_sz = hdr.PageLength * 4;
4871 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4873 memset((u8 *)ppage_alloc, 0, data_sz);
4874 cfg.physAddr = page_dma;
4875 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4877 /* If Good, save data */
4878 if ((rc = mpt_config(ioc, &cfg)) == 0)
4879 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4881 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4887 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4889 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4890 * @ioc: Pointer to a Adapter Strucutre
4891 * @portnum: IOC port number
4893 * Return: -EFAULT if read of config page header fails
4895 * If read of SCSI Port Page 0 fails,
4896 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4897 * Adapter settings: async, narrow
4899 * If read of SCSI Port Page 2 fails,
4900 * Adapter settings valid
4901 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4906 * CHECK - what type of locking mechanisms should be used????
4909 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4914 ConfigPageHeader_t header;
4920 if (!ioc->spi_data.nvram) {
4923 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4924 mem = kmalloc(sz, GFP_ATOMIC);
4928 ioc->spi_data.nvram = (int *) mem;
4930 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4931 ioc->name, ioc->spi_data.nvram, sz));
4934 /* Invalidate NVRAM information
4936 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4937 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4940 /* Read SPP0 header, allocate memory, then read page.
4942 header.PageVersion = 0;
4943 header.PageLength = 0;
4944 header.PageNumber = 0;
4945 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4946 cfg.cfghdr.hdr = &header;
4948 cfg.pageAddr = portnum;
4949 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4951 cfg.timeout = 0; /* use default */
4952 if (mpt_config(ioc, &cfg) != 0)
4955 if (header.PageLength > 0) {
4956 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4958 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4959 cfg.physAddr = buf_dma;
4960 if (mpt_config(ioc, &cfg) != 0) {
4961 ioc->spi_data.maxBusWidth = MPT_NARROW;
4962 ioc->spi_data.maxSyncOffset = 0;
4963 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4964 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4966 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4967 "Unable to read PortPage0 minSyncFactor=%x\n",
4968 ioc->name, ioc->spi_data.minSyncFactor));
4970 /* Save the Port Page 0 data
4972 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
4973 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4974 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4976 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
4977 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4978 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4979 "noQas due to Capabilities=%x\n",
4980 ioc->name, pPP0->Capabilities));
4982 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4983 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4985 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4986 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4987 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4988 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4989 "PortPage0 minSyncFactor=%x\n",
4990 ioc->name, ioc->spi_data.minSyncFactor));
4992 ioc->spi_data.maxSyncOffset = 0;
4993 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4996 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4998 /* Update the minSyncFactor based on bus type.
5000 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
5001 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
5003 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
5004 ioc->spi_data.minSyncFactor = MPT_ULTRA;
5005 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5006 "HVD or SE detected, minSyncFactor=%x\n",
5007 ioc->name, ioc->spi_data.minSyncFactor));
5012 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5017 /* SCSI Port Page 2 - Read the header then the page.
5019 header.PageVersion = 0;
5020 header.PageLength = 0;
5021 header.PageNumber = 2;
5022 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5023 cfg.cfghdr.hdr = &header;
5025 cfg.pageAddr = portnum;
5026 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5028 if (mpt_config(ioc, &cfg) != 0)
5031 if (header.PageLength > 0) {
5032 /* Allocate memory and read SCSI Port Page 2
5034 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5036 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
5037 cfg.physAddr = buf_dma;
5038 if (mpt_config(ioc, &cfg) != 0) {
5039 /* Nvram data is left with INVALID mark
5042 } else if (ioc->pcidev->vendor == PCI_VENDOR_ID_ATTO) {
5044 /* This is an ATTO adapter, read Page2 accordingly
5046 ATTO_SCSIPortPage2_t *pPP2 = (ATTO_SCSIPortPage2_t *) pbuf;
5047 ATTODeviceInfo_t *pdevice = NULL;
5050 /* Save the Port Page 2 data
5051 * (reformat into a 32bit quantity)
5053 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5054 pdevice = &pPP2->DeviceSettings[ii];
5055 ATTOFlags = le16_to_cpu(pdevice->ATTOFlags);
5058 /* Translate ATTO device flags to LSI format
5060 if (ATTOFlags & ATTOFLAG_DISC)
5061 data |= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE);
5062 if (ATTOFlags & ATTOFLAG_ID_ENB)
5063 data |= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE);
5064 if (ATTOFlags & ATTOFLAG_LUN_ENB)
5065 data |= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE);
5066 if (ATTOFlags & ATTOFLAG_TAGGED)
5067 data |= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE);
5068 if (!(ATTOFlags & ATTOFLAG_WIDE_ENB))
5069 data |= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE);
5071 data = (data << 16) | (pdevice->Period << 8) | 10;
5072 ioc->spi_data.nvram[ii] = data;
5075 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
5076 MpiDeviceInfo_t *pdevice = NULL;
5079 * Save "Set to Avoid SCSI Bus Resets" flag
5081 ioc->spi_data.bus_reset =
5082 (le32_to_cpu(pPP2->PortFlags) &
5083 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
5086 /* Save the Port Page 2 data
5087 * (reformat into a 32bit quantity)
5089 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
5090 ioc->spi_data.PortFlags = data;
5091 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5092 pdevice = &pPP2->DeviceSettings[ii];
5093 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
5094 (pdevice->SyncFactor << 8) | pdevice->Timeout;
5095 ioc->spi_data.nvram[ii] = data;
5099 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5103 /* Update Adapter limits with those from NVRAM
5104 * Comment: Don't need to do this. Target performance
5105 * parameters will never exceed the adapters limits.
5111 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5113 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
5114 * @ioc: Pointer to a Adapter Strucutre
5115 * @portnum: IOC port number
5117 * Return: -EFAULT if read of config page header fails
5121 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
5124 ConfigPageHeader_t header;
5126 /* Read the SCSI Device Page 1 header
5128 header.PageVersion = 0;
5129 header.PageLength = 0;
5130 header.PageNumber = 1;
5131 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5132 cfg.cfghdr.hdr = &header;
5134 cfg.pageAddr = portnum;
5135 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5138 if (mpt_config(ioc, &cfg) != 0)
5141 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
5142 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
5144 header.PageVersion = 0;
5145 header.PageLength = 0;
5146 header.PageNumber = 0;
5147 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5148 if (mpt_config(ioc, &cfg) != 0)
5151 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
5152 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
5154 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 0: version %d length %d\n",
5155 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
5157 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 1: version %d length %d\n",
5158 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
5163 * mpt_inactive_raid_list_free - This clears this link list.
5164 * @ioc : pointer to per adapter structure
5167 mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
5169 struct inactive_raid_component_info *component_info, *pNext;
5171 if (list_empty(&ioc->raid_data.inactive_list))
5174 mutex_lock(&ioc->raid_data.inactive_list_mutex);
5175 list_for_each_entry_safe(component_info, pNext,
5176 &ioc->raid_data.inactive_list, list) {
5177 list_del(&component_info->list);
5178 kfree(component_info);
5180 mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5184 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5186 * @ioc : pointer to per adapter structure
5187 * @channel : volume channel
5188 * @id : volume target id
5191 mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
5194 ConfigPageHeader_t hdr;
5195 dma_addr_t dma_handle;
5196 pRaidVolumePage0_t buffer = NULL;
5198 RaidPhysDiskPage0_t phys_disk;
5199 struct inactive_raid_component_info *component_info;
5200 int handle_inactive_volumes;
5202 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5203 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5204 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
5205 cfg.pageAddr = (channel << 8) + id;
5206 cfg.cfghdr.hdr = &hdr;
5207 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5209 if (mpt_config(ioc, &cfg) != 0)
5212 if (!hdr.PageLength)
5215 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5221 cfg.physAddr = dma_handle;
5222 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5224 if (mpt_config(ioc, &cfg) != 0)
5227 if (!buffer->NumPhysDisks)
5230 handle_inactive_volumes =
5231 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
5232 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
5233 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
5234 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
5236 if (!handle_inactive_volumes)
5239 mutex_lock(&ioc->raid_data.inactive_list_mutex);
5240 for (i = 0; i < buffer->NumPhysDisks; i++) {
5241 if(mpt_raid_phys_disk_pg0(ioc,
5242 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
5245 if ((component_info = kmalloc(sizeof (*component_info),
5246 GFP_KERNEL)) == NULL)
5249 component_info->volumeID = id;
5250 component_info->volumeBus = channel;
5251 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
5252 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
5253 component_info->d.PhysDiskID = phys_disk.PhysDiskID;
5254 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
5256 list_add_tail(&component_info->list,
5257 &ioc->raid_data.inactive_list);
5259 mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5263 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5268 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5269 * @ioc: Pointer to a Adapter Structure
5270 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5271 * @phys_disk: requested payload data returned
5275 * -EFAULT if read of config page header fails or data pointer not NULL
5276 * -ENOMEM if pci_alloc failed
5279 mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk)
5282 ConfigPageHeader_t hdr;
5283 dma_addr_t dma_handle;
5284 pRaidPhysDiskPage0_t buffer = NULL;
5287 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5288 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5290 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5291 cfg.cfghdr.hdr = &hdr;
5293 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5295 if (mpt_config(ioc, &cfg) != 0) {
5300 if (!hdr.PageLength) {
5305 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5313 cfg.physAddr = dma_handle;
5314 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5315 cfg.pageAddr = phys_disk_num;
5317 if (mpt_config(ioc, &cfg) != 0) {
5323 memcpy(phys_disk, buffer, sizeof(*buffer));
5324 phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
5329 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5336 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5337 * @ioc: Pointer to a Adapter Strucutre
5338 * @portnum: IOC port number
5342 * -EFAULT if read of config page header fails or data pointer not NULL
5343 * -ENOMEM if pci_alloc failed
5346 mpt_findImVolumes(MPT_ADAPTER *ioc)
5350 dma_addr_t ioc2_dma;
5352 ConfigPageHeader_t header;
5357 if (!ioc->ir_firmware)
5360 /* Free the old page
5362 kfree(ioc->raid_data.pIocPg2);
5363 ioc->raid_data.pIocPg2 = NULL;
5364 mpt_inactive_raid_list_free(ioc);
5366 /* Read IOCP2 header then the page.
5368 header.PageVersion = 0;
5369 header.PageLength = 0;
5370 header.PageNumber = 2;
5371 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5372 cfg.cfghdr.hdr = &header;
5375 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5378 if (mpt_config(ioc, &cfg) != 0)
5381 if (header.PageLength == 0)
5384 iocpage2sz = header.PageLength * 4;
5385 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
5389 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5390 cfg.physAddr = ioc2_dma;
5391 if (mpt_config(ioc, &cfg) != 0)
5394 mem = kmalloc(iocpage2sz, GFP_KERNEL);
5398 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
5399 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
5401 mpt_read_ioc_pg_3(ioc);
5403 for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
5404 mpt_inactive_raid_volumes(ioc,
5405 pIoc2->RaidVolume[i].VolumeBus,
5406 pIoc2->RaidVolume[i].VolumeID);
5409 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
5415 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
5420 ConfigPageHeader_t header;
5421 dma_addr_t ioc3_dma;
5424 /* Free the old page
5426 kfree(ioc->raid_data.pIocPg3);
5427 ioc->raid_data.pIocPg3 = NULL;
5429 /* There is at least one physical disk.
5430 * Read and save IOC Page 3
5432 header.PageVersion = 0;
5433 header.PageLength = 0;
5434 header.PageNumber = 3;
5435 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5436 cfg.cfghdr.hdr = &header;
5439 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5442 if (mpt_config(ioc, &cfg) != 0)
5445 if (header.PageLength == 0)
5448 /* Read Header good, alloc memory
5450 iocpage3sz = header.PageLength * 4;
5451 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
5455 /* Read the Page and save the data
5456 * into malloc'd memory.
5458 cfg.physAddr = ioc3_dma;
5459 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5460 if (mpt_config(ioc, &cfg) == 0) {
5461 mem = kmalloc(iocpage3sz, GFP_KERNEL);
5463 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
5464 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
5468 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
5474 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
5478 ConfigPageHeader_t header;
5479 dma_addr_t ioc4_dma;
5482 /* Read and save IOC Page 4
5484 header.PageVersion = 0;
5485 header.PageLength = 0;
5486 header.PageNumber = 4;
5487 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5488 cfg.cfghdr.hdr = &header;
5491 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5494 if (mpt_config(ioc, &cfg) != 0)
5497 if (header.PageLength == 0)
5500 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
5501 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
5502 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
5505 ioc->alloc_total += iocpage4sz;
5507 ioc4_dma = ioc->spi_data.IocPg4_dma;
5508 iocpage4sz = ioc->spi_data.IocPg4Sz;
5511 /* Read the Page into dma memory.
5513 cfg.physAddr = ioc4_dma;
5514 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5515 if (mpt_config(ioc, &cfg) == 0) {
5516 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
5517 ioc->spi_data.IocPg4_dma = ioc4_dma;
5518 ioc->spi_data.IocPg4Sz = iocpage4sz;
5520 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
5521 ioc->spi_data.pIocPg4 = NULL;
5522 ioc->alloc_total -= iocpage4sz;
5527 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
5531 ConfigPageHeader_t header;
5532 dma_addr_t ioc1_dma;
5536 /* Check the Coalescing Timeout in IOC Page 1
5538 header.PageVersion = 0;
5539 header.PageLength = 0;
5540 header.PageNumber = 1;
5541 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5542 cfg.cfghdr.hdr = &header;
5545 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5548 if (mpt_config(ioc, &cfg) != 0)
5551 if (header.PageLength == 0)
5554 /* Read Header good, alloc memory
5556 iocpage1sz = header.PageLength * 4;
5557 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
5561 /* Read the Page and check coalescing timeout
5563 cfg.physAddr = ioc1_dma;
5564 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5565 if (mpt_config(ioc, &cfg) == 0) {
5567 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
5568 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
5569 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
5571 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Coalescing Enabled Timeout = %d\n",
5574 if (tmp > MPT_COALESCING_TIMEOUT) {
5575 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
5577 /* Write NVRAM and current
5580 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5581 if (mpt_config(ioc, &cfg) == 0) {
5582 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Reset Current Coalescing Timeout to = %d\n",
5583 ioc->name, MPT_COALESCING_TIMEOUT));
5585 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
5586 if (mpt_config(ioc, &cfg) == 0) {
5587 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5588 "Reset NVRAM Coalescing Timeout to = %d\n",
5589 ioc->name, MPT_COALESCING_TIMEOUT));
5591 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5592 "Reset NVRAM Coalescing Timeout Failed\n",
5597 dprintk(ioc, printk(MYIOC_s_WARN_FMT
5598 "Reset of Current Coalescing Timeout Failed!\n",
5604 dprintk(ioc, printk(MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
5608 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
5614 mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
5617 ConfigPageHeader_t hdr;
5619 ManufacturingPage0_t *pbuf = NULL;
5621 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5622 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5624 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
5625 cfg.cfghdr.hdr = &hdr;
5627 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5630 if (mpt_config(ioc, &cfg) != 0)
5633 if (!cfg.cfghdr.hdr->PageLength)
5636 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5637 pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
5641 cfg.physAddr = buf_dma;
5643 if (mpt_config(ioc, &cfg) != 0)
5646 memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name));
5647 memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
5648 memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
5653 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
5656 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5658 * SendEventNotification - Send EventNotification (on or off) request to adapter
5659 * @ioc: Pointer to MPT_ADAPTER structure
5660 * @EvSwitch: Event switch flags
5663 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
5665 EventNotification_t *evnp;
5667 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
5669 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
5673 memset(evnp, 0, sizeof(*evnp));
5675 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
5677 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
5678 evnp->ChainOffset = 0;
5680 evnp->Switch = EvSwitch;
5682 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
5687 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5689 * SendEventAck - Send EventAck request to MPT adapter.
5690 * @ioc: Pointer to MPT_ADAPTER structure
5691 * @evnp: Pointer to original EventNotification request
5694 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
5698 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5699 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
5700 ioc->name,__FUNCTION__));
5704 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventAck\n", ioc->name));
5706 pAck->Function = MPI_FUNCTION_EVENT_ACK;
5707 pAck->ChainOffset = 0;
5708 pAck->Reserved[0] = pAck->Reserved[1] = 0;
5710 pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
5711 pAck->Event = evnp->Event;
5712 pAck->EventContext = evnp->EventContext;
5714 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
5719 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5721 * mpt_config - Generic function to issue config message
5722 * @ioc: Pointer to an adapter structure
5723 * @pCfg: Pointer to a configuration structure. Struct contains
5724 * action, page address, direction, physical address
5725 * and pointer to a configuration page header
5726 * Page header is updated.
5728 * Returns 0 for success
5729 * -EPERM if not allowed due to ISR context
5730 * -EAGAIN if no msg frames currently available
5731 * -EFAULT for non-successful reply or no reply (timeout)
5734 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5737 ConfigExtendedPageHeader_t *pExtHdr = NULL;
5739 unsigned long flags;
5744 /* Prevent calling wait_event() (below), if caller happens
5745 * to be in ISR context, because that is fatal!
5747 in_isr = in_interrupt();
5749 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
5754 /* Get and Populate a free Frame
5756 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5757 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
5761 pReq = (Config_t *)mf;
5762 pReq->Action = pCfg->action;
5764 pReq->ChainOffset = 0;
5765 pReq->Function = MPI_FUNCTION_CONFIG;
5767 /* Assume page type is not extended and clear "reserved" fields. */
5768 pReq->ExtPageLength = 0;
5769 pReq->ExtPageType = 0;
5772 for (ii=0; ii < 8; ii++)
5773 pReq->Reserved2[ii] = 0;
5775 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
5776 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
5777 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
5778 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
5780 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5781 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
5782 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
5783 pReq->ExtPageType = pExtHdr->ExtPageType;
5784 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
5786 /* Page Length must be treated as a reserved field for the extended header. */
5787 pReq->Header.PageLength = 0;
5790 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
5792 /* Add a SGE to the config request.
5795 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
5797 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
5799 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5800 flagsLength |= pExtHdr->ExtPageLength * 4;
5802 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n",
5803 ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action));
5806 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
5808 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n",
5809 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
5812 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
5814 /* Append pCfg pointer to end of mf
5816 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5818 /* Initalize the timer
5820 init_timer(&pCfg->timer);
5821 pCfg->timer.data = (unsigned long) ioc;
5822 pCfg->timer.function = mpt_timer_expired;
5823 pCfg->wait_done = 0;
5825 /* Set the timer; ensure 10 second minimum */
5826 if (pCfg->timeout < 10)
5827 pCfg->timer.expires = jiffies + HZ*10;
5829 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5831 /* Add to end of Q, set timer and then issue this command */
5832 spin_lock_irqsave(&ioc->FreeQlock, flags);
5833 list_add_tail(&pCfg->linkage, &ioc->configQ);
5834 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5836 add_timer(&pCfg->timer);
5837 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5838 wait_event(mpt_waitq, pCfg->wait_done);
5840 /* mf has been freed - do not access */
5847 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5849 * mpt_timer_expired - Callback for timer process.
5850 * Used only internal config functionality.
5851 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5854 mpt_timer_expired(unsigned long data)
5856 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
5858 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired! \n", ioc->name));
5860 /* Perform a FW reload */
5861 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
5862 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
5864 /* No more processing.
5865 * Hard reset clean-up will wake up
5866 * process and free all resources.
5868 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired complete!\n", ioc->name));
5873 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5875 * mpt_ioc_reset - Base cleanup for hard reset
5876 * @ioc: Pointer to the adapter structure
5877 * @reset_phase: Indicates pre- or post-reset functionality
5879 * Remark: Frees resources with internally generated commands.
5882 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
5885 unsigned long flags;
5887 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5888 ": IOC %s_reset routed to MPT base driver!\n",
5889 ioc->name, reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
5890 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
5892 if (reset_phase == MPT_IOC_SETUP_RESET) {
5894 } else if (reset_phase == MPT_IOC_PRE_RESET) {
5895 /* If the internal config Q is not empty -
5896 * delete timer. MF resources will be freed when
5897 * the FIFO's are primed.
5899 spin_lock_irqsave(&ioc->FreeQlock, flags);
5900 list_for_each_entry(pCfg, &ioc->configQ, linkage)
5901 del_timer(&pCfg->timer);
5902 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5907 /* Search the configQ for internal commands.
5908 * Flush the Q, and wake up all suspended threads.
5910 spin_lock_irqsave(&ioc->FreeQlock, flags);
5911 list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
5912 list_del(&pCfg->linkage);
5914 pCfg->status = MPT_CONFIG_ERROR;
5915 pCfg->wait_done = 1;
5916 wake_up(&mpt_waitq);
5918 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5921 return 1; /* currently means nothing really */
5925 #ifdef CONFIG_PROC_FS /* { */
5926 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5928 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5930 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5932 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5934 * Returns 0 for success, non-zero for failure.
5937 procmpt_create(void)
5939 struct proc_dir_entry *ent;
5941 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
5942 if (mpt_proc_root_dir == NULL)
5945 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5947 ent->read_proc = procmpt_summary_read;
5949 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5951 ent->read_proc = procmpt_version_read;
5956 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5958 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5960 * Returns 0 for success, non-zero for failure.
5963 procmpt_destroy(void)
5965 remove_proc_entry("version", mpt_proc_root_dir);
5966 remove_proc_entry("summary", mpt_proc_root_dir);
5967 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
5970 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5972 * procmpt_summary_read - Handle read request of a summary file
5973 * @buf: Pointer to area to write information
5974 * @start: Pointer to start pointer
5975 * @offset: Offset to start writing
5976 * @request: Amount of read data requested
5977 * @eof: Pointer to EOF integer
5980 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
5981 * Returns number of characters written to process performing the read.
5984 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5994 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5998 list_for_each_entry(ioc, &ioc_list, list) {
6001 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
6004 if ((out-buf) >= request)
6011 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6014 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6016 * procmpt_version_read - Handle read request from /proc/mpt/version.
6017 * @buf: Pointer to area to write information
6018 * @start: Pointer to start pointer
6019 * @offset: Offset to start writing
6020 * @request: Amount of read data requested
6021 * @eof: Pointer to EOF integer
6024 * Returns number of characters written to process performing the read.
6027 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6030 int scsi, fc, sas, lan, ctl, targ, dmp;
6034 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
6035 len += sprintf(buf+len, " Fusion MPT base driver\n");
6037 scsi = fc = sas = lan = ctl = targ = dmp = 0;
6038 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6040 if (MptCallbacks[cb_idx]) {
6041 switch (MptDriverClass[cb_idx]) {
6043 if (!scsi++) drvname = "SPI host";
6046 if (!fc++) drvname = "FC host";
6049 if (!sas++) drvname = "SAS host";
6052 if (!lan++) drvname = "LAN";
6055 if (!targ++) drvname = "SCSI target";
6058 if (!ctl++) drvname = "ioctl";
6063 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
6067 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6070 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6072 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
6073 * @buf: Pointer to area to write information
6074 * @start: Pointer to start pointer
6075 * @offset: Offset to start writing
6076 * @request: Amount of read data requested
6077 * @eof: Pointer to EOF integer
6080 * Returns number of characters written to process performing the read.
6083 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6085 MPT_ADAPTER *ioc = data;
6091 mpt_get_fw_exp_ver(expVer, ioc);
6093 len = sprintf(buf, "%s:", ioc->name);
6094 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
6095 len += sprintf(buf+len, " (f/w download boot flag set)");
6096 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6097 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
6099 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
6100 ioc->facts.ProductID,
6102 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
6103 if (ioc->facts.FWImageSize)
6104 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
6105 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
6106 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
6107 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
6109 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
6110 ioc->facts.CurrentHostMfaHighAddr);
6111 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
6112 ioc->facts.CurrentSenseBufferHighAddr);
6114 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
6115 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
6117 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6118 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
6120 * Rounding UP to nearest 4-kB boundary here...
6122 sz = (ioc->req_sz * ioc->req_depth) + 128;
6123 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
6124 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6125 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
6126 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
6127 4*ioc->facts.RequestFrameSize,
6128 ioc->facts.GlobalCredits);
6130 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
6131 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
6132 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
6133 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6134 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
6135 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
6136 ioc->facts.CurReplyFrameSize,
6137 ioc->facts.ReplyQueueDepth);
6139 len += sprintf(buf+len, " MaxDevices = %d\n",
6140 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
6141 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
6144 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
6145 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
6147 ioc->facts.NumberOfPorts);
6148 if (ioc->bus_type == FC) {
6149 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
6150 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6151 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6152 a[5], a[4], a[3], a[2], a[1], a[0]);
6154 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
6155 ioc->fc_port_page0[p].WWNN.High,
6156 ioc->fc_port_page0[p].WWNN.Low,
6157 ioc->fc_port_page0[p].WWPN.High,
6158 ioc->fc_port_page0[p].WWPN.Low);
6162 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6165 #endif /* CONFIG_PROC_FS } */
6167 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6169 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
6172 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
6173 sprintf(buf, " (Exp %02d%02d)",
6174 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
6175 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
6178 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
6179 strcat(buf, " [MDBG]");
6183 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6185 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6186 * @ioc: Pointer to MPT_ADAPTER structure
6187 * @buffer: Pointer to buffer where IOC summary info should be written
6188 * @size: Pointer to number of bytes we wrote (set by this routine)
6189 * @len: Offset at which to start writing in buffer
6190 * @showlan: Display LAN stuff?
6192 * This routine writes (english readable) ASCII text, which represents
6193 * a summary of IOC information, to a buffer.
6196 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
6201 mpt_get_fw_exp_ver(expVer, ioc);
6204 * Shorter summary of attached ioc's...
6206 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6209 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
6210 ioc->facts.FWVersion.Word,
6212 ioc->facts.NumberOfPorts,
6215 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6216 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6217 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6218 a[5], a[4], a[3], a[2], a[1], a[0]);
6221 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
6224 y += sprintf(buffer+len+y, " (disabled)");
6226 y += sprintf(buffer+len+y, "\n");
6231 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6235 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6237 * mpt_HardResetHandler - Generic reset handler
6238 * @ioc: Pointer to MPT_ADAPTER structure
6239 * @sleepFlag: Indicates if sleep or schedule must be called.
6241 * Issues SCSI Task Management call based on input arg values.
6242 * If TaskMgmt fails, returns associated SCSI request.
6244 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
6245 * or a non-interrupt thread. In the former, must not call schedule().
6247 * Note: A return of -1 is a FATAL error case, as it means a
6248 * FW reload/initialization failed.
6250 * Returns 0 for SUCCESS or -1 if FAILED.
6253 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6256 unsigned long flags;
6258 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name));
6260 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
6261 printk("MF count 0x%x !\n", ioc->mfcnt);
6264 /* Reset the adapter. Prevent more than 1 call to
6265 * mpt_do_ioc_recovery at any instant in time.
6267 spin_lock_irqsave(&ioc->diagLock, flags);
6268 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
6269 spin_unlock_irqrestore(&ioc->diagLock, flags);
6272 ioc->diagPending = 1;
6274 spin_unlock_irqrestore(&ioc->diagLock, flags);
6276 /* FIXME: If do_ioc_recovery fails, repeat....
6279 /* The SCSI driver needs to adjust timeouts on all current
6280 * commands prior to the diagnostic reset being issued.
6281 * Prevents timeouts occurring during a diagnostic reset...very bad.
6282 * For all other protocol drivers, this is a no-op.
6288 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6289 if (MptResetHandlers[cb_idx]) {
6290 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling IOC reset_setup handler #%d\n",
6291 ioc->name, cb_idx));
6292 r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
6294 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling alt-%s setup reset handler #%d\n",
6295 ioc->name, ioc->alt_ioc->name, cb_idx));
6296 r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_SETUP_RESET);
6302 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
6303 printk(MYIOC_s_WARN_FMT "Cannot recover rc = %d!\n", ioc->name, rc);
6307 ioc->alt_ioc->reload_fw = 0;
6309 spin_lock_irqsave(&ioc->diagLock, flags);
6310 ioc->diagPending = 0;
6312 ioc->alt_ioc->diagPending = 0;
6313 spin_unlock_irqrestore(&ioc->diagLock, flags);
6315 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
6320 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6322 EventDescriptionStr(u8 event, u32 evData0, char *evStr)
6327 case MPI_EVENT_NONE:
6330 case MPI_EVENT_LOG_DATA:
6333 case MPI_EVENT_STATE_CHANGE:
6334 ds = "State Change";
6336 case MPI_EVENT_UNIT_ATTENTION:
6337 ds = "Unit Attention";
6339 case MPI_EVENT_IOC_BUS_RESET:
6340 ds = "IOC Bus Reset";
6342 case MPI_EVENT_EXT_BUS_RESET:
6343 ds = "External Bus Reset";
6345 case MPI_EVENT_RESCAN:
6346 ds = "Bus Rescan Event";
6348 case MPI_EVENT_LINK_STATUS_CHANGE:
6349 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
6350 ds = "Link Status(FAILURE) Change";
6352 ds = "Link Status(ACTIVE) Change";
6354 case MPI_EVENT_LOOP_STATE_CHANGE:
6355 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
6356 ds = "Loop State(LIP) Change";
6357 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
6358 ds = "Loop State(LPE) Change"; /* ??? */
6360 ds = "Loop State(LPB) Change"; /* ??? */
6362 case MPI_EVENT_LOGOUT:
6365 case MPI_EVENT_EVENT_CHANGE:
6371 case MPI_EVENT_INTEGRATED_RAID:
6373 u8 ReasonCode = (u8)(evData0 >> 16);
6374 switch (ReasonCode) {
6375 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
6376 ds = "Integrated Raid: Volume Created";
6378 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
6379 ds = "Integrated Raid: Volume Deleted";
6381 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
6382 ds = "Integrated Raid: Volume Settings Changed";
6384 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
6385 ds = "Integrated Raid: Volume Status Changed";
6387 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
6388 ds = "Integrated Raid: Volume Physdisk Changed";
6390 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
6391 ds = "Integrated Raid: Physdisk Created";
6393 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
6394 ds = "Integrated Raid: Physdisk Deleted";
6396 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
6397 ds = "Integrated Raid: Physdisk Settings Changed";
6399 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
6400 ds = "Integrated Raid: Physdisk Status Changed";
6402 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
6403 ds = "Integrated Raid: Domain Validation Needed";
6405 case MPI_EVENT_RAID_RC_SMART_DATA :
6406 ds = "Integrated Raid; Smart Data";
6408 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
6409 ds = "Integrated Raid: Replace Action Started";
6412 ds = "Integrated Raid";
6417 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
6418 ds = "SCSI Device Status Change";
6420 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
6422 u8 id = (u8)(evData0);
6423 u8 channel = (u8)(evData0 >> 8);
6424 u8 ReasonCode = (u8)(evData0 >> 16);
6425 switch (ReasonCode) {
6426 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
6427 snprintf(evStr, EVENT_DESCR_STR_SZ,
6428 "SAS Device Status Change: Added: "
6429 "id=%d channel=%d", id, channel);
6431 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
6432 snprintf(evStr, EVENT_DESCR_STR_SZ,
6433 "SAS Device Status Change: Deleted: "
6434 "id=%d channel=%d", id, channel);
6436 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
6437 snprintf(evStr, EVENT_DESCR_STR_SZ,
6438 "SAS Device Status Change: SMART Data: "
6439 "id=%d channel=%d", id, channel);
6441 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
6442 snprintf(evStr, EVENT_DESCR_STR_SZ,
6443 "SAS Device Status Change: No Persistancy: "
6444 "id=%d channel=%d", id, channel);
6446 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
6447 snprintf(evStr, EVENT_DESCR_STR_SZ,
6448 "SAS Device Status Change: Unsupported Device "
6449 "Discovered : id=%d channel=%d", id, channel);
6451 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
6452 snprintf(evStr, EVENT_DESCR_STR_SZ,
6453 "SAS Device Status Change: Internal Device "
6454 "Reset : id=%d channel=%d", id, channel);
6456 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
6457 snprintf(evStr, EVENT_DESCR_STR_SZ,
6458 "SAS Device Status Change: Internal Task "
6459 "Abort : id=%d channel=%d", id, channel);
6461 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
6462 snprintf(evStr, EVENT_DESCR_STR_SZ,
6463 "SAS Device Status Change: Internal Abort "
6464 "Task Set : id=%d channel=%d", id, channel);
6466 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
6467 snprintf(evStr, EVENT_DESCR_STR_SZ,
6468 "SAS Device Status Change: Internal Clear "
6469 "Task Set : id=%d channel=%d", id, channel);
6471 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
6472 snprintf(evStr, EVENT_DESCR_STR_SZ,
6473 "SAS Device Status Change: Internal Query "
6474 "Task : id=%d channel=%d", id, channel);
6477 snprintf(evStr, EVENT_DESCR_STR_SZ,
6478 "SAS Device Status Change: Unknown: "
6479 "id=%d channel=%d", id, channel);
6484 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
6485 ds = "Bus Timer Expired";
6487 case MPI_EVENT_QUEUE_FULL:
6489 u16 curr_depth = (u16)(evData0 >> 16);
6490 u8 channel = (u8)(evData0 >> 8);
6491 u8 id = (u8)(evData0);
6493 snprintf(evStr, EVENT_DESCR_STR_SZ,
6494 "Queue Full: channel=%d id=%d depth=%d",
6495 channel, id, curr_depth);
6498 case MPI_EVENT_SAS_SES:
6499 ds = "SAS SES Event";
6501 case MPI_EVENT_PERSISTENT_TABLE_FULL:
6502 ds = "Persistent Table Full";
6504 case MPI_EVENT_SAS_PHY_LINK_STATUS:
6506 u8 LinkRates = (u8)(evData0 >> 8);
6507 u8 PhyNumber = (u8)(evData0);
6508 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
6509 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
6510 switch (LinkRates) {
6511 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
6512 snprintf(evStr, EVENT_DESCR_STR_SZ,
6513 "SAS PHY Link Status: Phy=%d:"
6514 " Rate Unknown",PhyNumber);
6516 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
6517 snprintf(evStr, EVENT_DESCR_STR_SZ,
6518 "SAS PHY Link Status: Phy=%d:"
6519 " Phy Disabled",PhyNumber);
6521 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
6522 snprintf(evStr, EVENT_DESCR_STR_SZ,
6523 "SAS PHY Link Status: Phy=%d:"
6524 " Failed Speed Nego",PhyNumber);
6526 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
6527 snprintf(evStr, EVENT_DESCR_STR_SZ,
6528 "SAS PHY Link Status: Phy=%d:"
6529 " Sata OOB Completed",PhyNumber);
6531 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
6532 snprintf(evStr, EVENT_DESCR_STR_SZ,
6533 "SAS PHY Link Status: Phy=%d:"
6534 " Rate 1.5 Gbps",PhyNumber);
6536 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
6537 snprintf(evStr, EVENT_DESCR_STR_SZ,
6538 "SAS PHY Link Status: Phy=%d:"
6539 " Rate 3.0 Gpbs",PhyNumber);
6542 snprintf(evStr, EVENT_DESCR_STR_SZ,
6543 "SAS PHY Link Status: Phy=%d", PhyNumber);
6548 case MPI_EVENT_SAS_DISCOVERY_ERROR:
6549 ds = "SAS Discovery Error";
6551 case MPI_EVENT_IR_RESYNC_UPDATE:
6553 u8 resync_complete = (u8)(evData0 >> 16);
6554 snprintf(evStr, EVENT_DESCR_STR_SZ,
6555 "IR Resync Update: Complete = %d:",resync_complete);
6560 u8 ReasonCode = (u8)(evData0 >> 16);
6561 switch (ReasonCode) {
6562 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
6563 ds = "IR2: LD State Changed";
6565 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
6566 ds = "IR2: PD State Changed";
6568 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
6569 ds = "IR2: Bad Block Table Full";
6571 case MPI_EVENT_IR2_RC_PD_INSERTED:
6572 ds = "IR2: PD Inserted";
6574 case MPI_EVENT_IR2_RC_PD_REMOVED:
6575 ds = "IR2: PD Removed";
6577 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
6578 ds = "IR2: Foreign CFG Detected";
6580 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
6581 ds = "IR2: Rebuild Medium Error";
6589 case MPI_EVENT_SAS_DISCOVERY:
6592 ds = "SAS Discovery: Start";
6594 ds = "SAS Discovery: Stop";
6597 case MPI_EVENT_LOG_ENTRY_ADDED:
6598 ds = "SAS Log Entry Added";
6601 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
6603 u8 phy_num = (u8)(evData0);
6604 u8 port_num = (u8)(evData0 >> 8);
6605 u8 port_width = (u8)(evData0 >> 16);
6606 u8 primative = (u8)(evData0 >> 24);
6607 snprintf(evStr, EVENT_DESCR_STR_SZ,
6608 "SAS Broadcase Primative: phy=%d port=%d "
6609 "width=%d primative=0x%02x",
6610 phy_num, port_num, port_width, primative);
6614 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
6616 u8 reason = (u8)(evData0);
6617 u8 port_num = (u8)(evData0 >> 8);
6618 u16 handle = le16_to_cpu(evData0 >> 16);
6620 snprintf(evStr, EVENT_DESCR_STR_SZ,
6621 "SAS Initiator Device Status Change: reason=0x%02x "
6622 "port=%d handle=0x%04x",
6623 reason, port_num, handle);
6627 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
6629 u8 max_init = (u8)(evData0);
6630 u8 current_init = (u8)(evData0 >> 8);
6632 snprintf(evStr, EVENT_DESCR_STR_SZ,
6633 "SAS Initiator Device Table Overflow: max initiators=%02d "
6634 "current initators=%02d",
6635 max_init, current_init);
6638 case MPI_EVENT_SAS_SMP_ERROR:
6640 u8 status = (u8)(evData0);
6641 u8 port_num = (u8)(evData0 >> 8);
6642 u8 result = (u8)(evData0 >> 16);
6644 if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
6645 snprintf(evStr, EVENT_DESCR_STR_SZ,
6646 "SAS SMP Error: port=%d result=0x%02x",
6648 else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
6649 snprintf(evStr, EVENT_DESCR_STR_SZ,
6650 "SAS SMP Error: port=%d : CRC Error",
6652 else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
6653 snprintf(evStr, EVENT_DESCR_STR_SZ,
6654 "SAS SMP Error: port=%d : Timeout",
6656 else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
6657 snprintf(evStr, EVENT_DESCR_STR_SZ,
6658 "SAS SMP Error: port=%d : No Destination",
6660 else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
6661 snprintf(evStr, EVENT_DESCR_STR_SZ,
6662 "SAS SMP Error: port=%d : Bad Destination",
6665 snprintf(evStr, EVENT_DESCR_STR_SZ,
6666 "SAS SMP Error: port=%d : status=0x%02x",
6672 * MPT base "custom" events may be added here...
6679 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
6682 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6684 * ProcessEventNotification - Route EventNotificationReply to all event handlers
6685 * @ioc: Pointer to MPT_ADAPTER structure
6686 * @pEventReply: Pointer to EventNotification reply frame
6687 * @evHandlers: Pointer to integer, number of event handlers
6689 * Routes a received EventNotificationReply to all currently registered
6691 * Returns sum of event handlers return values.
6694 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
6703 char evStr[EVENT_DESCR_STR_SZ];
6707 * Do platform normalization of values
6709 event = le32_to_cpu(pEventReply->Event) & 0xFF;
6710 // evCtx = le32_to_cpu(pEventReply->EventContext);
6711 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
6713 evData0 = le32_to_cpu(pEventReply->Data[0]);
6716 EventDescriptionStr(event, evData0, evStr);
6717 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event:(%02Xh) : %s\n",
6722 #ifdef CONFIG_FUSION_LOGGING
6723 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6724 ": Event data:\n", ioc->name));
6725 for (ii = 0; ii < evDataLen; ii++)
6726 devtverboseprintk(ioc, printk(" %08x",
6727 le32_to_cpu(pEventReply->Data[ii])));
6728 devtverboseprintk(ioc, printk("\n"));
6732 * Do general / base driver event processing
6735 case MPI_EVENT_EVENT_CHANGE: /* 0A */
6737 u8 evState = evData0 & 0xFF;
6739 /* CHECKME! What if evState unexpectedly says OFF (0)? */
6741 /* Update EventState field in cached IocFacts */
6742 if (ioc->facts.Function) {
6743 ioc->facts.EventState = evState;
6747 case MPI_EVENT_INTEGRATED_RAID:
6748 mptbase_raid_process_event_data(ioc,
6749 (MpiEventDataRaid_t *)pEventReply->Data);
6756 * Should this event be logged? Events are written sequentially.
6757 * When buffer is full, start again at the top.
6759 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
6762 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
6764 ioc->events[idx].event = event;
6765 ioc->events[idx].eventContext = ioc->eventContext;
6767 for (ii = 0; ii < 2; ii++) {
6769 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
6771 ioc->events[idx].data[ii] = 0;
6774 ioc->eventContext++;
6779 * Call each currently registered protocol event handler.
6781 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6782 if (MptEvHandlers[cb_idx]) {
6783 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Routing Event to event handler #%d\n",
6784 ioc->name, cb_idx));
6785 r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply);
6789 /* FIXME? Examine results here? */
6792 * If needed, send (a single) EventAck.
6794 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
6795 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6796 "EventAck required\n",ioc->name));
6797 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
6798 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SendEventAck returned %d\n",
6803 *evHandlers = handlers;
6807 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6809 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
6810 * @ioc: Pointer to MPT_ADAPTER structure
6811 * @log_info: U32 LogInfo reply word from the IOC
6813 * Refer to lsi/mpi_log_fc.h.
6816 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
6818 char *desc = "unknown";
6820 switch (log_info & 0xFF000000) {
6821 case MPI_IOCLOGINFO_FC_INIT_BASE:
6822 desc = "FCP Initiator";
6824 case MPI_IOCLOGINFO_FC_TARGET_BASE:
6825 desc = "FCP Target";
6827 case MPI_IOCLOGINFO_FC_LAN_BASE:
6830 case MPI_IOCLOGINFO_FC_MSG_BASE:
6831 desc = "MPI Message Layer";
6833 case MPI_IOCLOGINFO_FC_LINK_BASE:
6836 case MPI_IOCLOGINFO_FC_CTX_BASE:
6837 desc = "Context Manager";
6839 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
6840 desc = "Invalid Field Offset";
6842 case MPI_IOCLOGINFO_FC_STATE_CHANGE:
6843 desc = "State Change Info";
6847 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
6848 ioc->name, log_info, desc, (log_info & 0xFFFFFF));
6851 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6853 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
6854 * @ioc: Pointer to MPT_ADAPTER structure
6855 * @mr: Pointer to MPT reply frame
6856 * @log_info: U32 LogInfo word from the IOC
6858 * Refer to lsi/sp_log.h.
6861 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
6863 u32 info = log_info & 0x00FF0000;
6864 char *desc = "unknown";
6868 desc = "bug! MID not found";
6869 if (ioc->reload_fw == 0)
6874 desc = "Parity Error";
6878 desc = "ASYNC Outbound Overrun";
6882 desc = "SYNC Offset Error";
6890 desc = "Msg In Overflow";
6898 desc = "Outbound DMA Overrun";
6902 desc = "Task Management";
6906 desc = "Device Problem";
6910 desc = "Invalid Phase Change";
6914 desc = "Untagged Table Size";
6919 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
6922 /* strings for sas loginfo */
6923 static char *originator_str[] = {
6928 static char *iop_code_str[] = {
6930 "Invalid SAS Address", /* 01h */
6932 "Invalid Page", /* 03h */
6933 "Diag Message Error", /* 04h */
6934 "Task Terminated", /* 05h */
6935 "Enclosure Management", /* 06h */
6936 "Target Mode" /* 07h */
6938 static char *pl_code_str[] = {
6940 "Open Failure", /* 01h */
6941 "Invalid Scatter Gather List", /* 02h */
6942 "Wrong Relative Offset or Frame Length", /* 03h */
6943 "Frame Transfer Error", /* 04h */
6944 "Transmit Frame Connected Low", /* 05h */
6945 "SATA Non-NCQ RW Error Bit Set", /* 06h */
6946 "SATA Read Log Receive Data Error", /* 07h */
6947 "SATA NCQ Fail All Commands After Error", /* 08h */
6948 "SATA Error in Receive Set Device Bit FIS", /* 09h */
6949 "Receive Frame Invalid Message", /* 0Ah */
6950 "Receive Context Message Valid Error", /* 0Bh */
6951 "Receive Frame Current Frame Error", /* 0Ch */
6952 "SATA Link Down", /* 0Dh */
6953 "Discovery SATA Init W IOS", /* 0Eh */
6954 "Config Invalid Page", /* 0Fh */
6955 "Discovery SATA Init Timeout", /* 10h */
6958 "IO Not Yet Executed", /* 13h */
6959 "IO Executed", /* 14h */
6960 "Persistent Reservation Out Not Affiliation "
6962 "Open Transmit DMA Abort", /* 16h */
6963 "IO Device Missing Delay Retry", /* 17h */
6964 "IO Cancelled Due to Recieve Error", /* 18h */
6972 "Enclosure Management" /* 20h */
6974 static char *ir_code_str[] = {
6975 "Raid Action Error", /* 00h */
6985 static char *raid_sub_code_str[] = {
6987 "Volume Creation Failed: Data Passed too "
6989 "Volume Creation Failed: Duplicate Volumes "
6990 "Attempted", /* 02h */
6991 "Volume Creation Failed: Max Number "
6992 "Supported Volumes Exceeded", /* 03h */
6993 "Volume Creation Failed: DMA Error", /* 04h */
6994 "Volume Creation Failed: Invalid Volume Type", /* 05h */
6995 "Volume Creation Failed: Error Reading "
6996 "MFG Page 4", /* 06h */
6997 "Volume Creation Failed: Creating Internal "
6998 "Structures", /* 07h */
7007 "Activation failed: Already Active Volume", /* 10h */
7008 "Activation failed: Unsupported Volume Type", /* 11h */
7009 "Activation failed: Too Many Active Volumes", /* 12h */
7010 "Activation failed: Volume ID in Use", /* 13h */
7011 "Activation failed: Reported Failure", /* 14h */
7012 "Activation failed: Importing a Volume", /* 15h */
7023 "Phys Disk failed: Too Many Phys Disks", /* 20h */
7024 "Phys Disk failed: Data Passed too Large", /* 21h */
7025 "Phys Disk failed: DMA Error", /* 22h */
7026 "Phys Disk failed: Invalid <channel:id>", /* 23h */
7027 "Phys Disk failed: Creating Phys Disk Config "
7040 "Compatibility Error: IR Disabled", /* 30h */
7041 "Compatibility Error: Inquiry Comand Failed", /* 31h */
7042 "Compatibility Error: Device not Direct Access "
7043 "Device ", /* 32h */
7044 "Compatibility Error: Removable Device Found", /* 33h */
7045 "Compatibility Error: Device SCSI Version not "
7046 "2 or Higher", /* 34h */
7047 "Compatibility Error: SATA Device, 48 BIT LBA "
7048 "not Supported", /* 35h */
7049 "Compatibility Error: Device doesn't have "
7050 "512 Byte Block Sizes", /* 36h */
7051 "Compatibility Error: Volume Type Check Failed", /* 37h */
7052 "Compatibility Error: Volume Type is "
7053 "Unsupported by FW", /* 38h */
7054 "Compatibility Error: Disk Drive too Small for "
7055 "use in Volume", /* 39h */
7056 "Compatibility Error: Phys Disk for Create "
7057 "Volume not Found", /* 3Ah */
7058 "Compatibility Error: Too Many or too Few "
7059 "Disks for Volume Type", /* 3Bh */
7060 "Compatibility Error: Disk stripe Sizes "
7061 "Must be 64KB", /* 3Ch */
7062 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
7065 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7067 * mpt_sas_log_info - Log information returned from SAS IOC.
7068 * @ioc: Pointer to MPT_ADAPTER structure
7069 * @log_info: U32 LogInfo reply word from the IOC
7071 * Refer to lsi/mpi_log_sas.h.
7074 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
7076 union loginfo_type {
7085 union loginfo_type sas_loginfo;
7086 char *originator_desc = NULL;
7087 char *code_desc = NULL;
7088 char *sub_code_desc = NULL;
7090 sas_loginfo.loginfo = log_info;
7091 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
7092 (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
7095 originator_desc = originator_str[sas_loginfo.dw.originator];
7097 switch (sas_loginfo.dw.originator) {
7100 if (sas_loginfo.dw.code <
7101 sizeof(iop_code_str)/sizeof(char*))
7102 code_desc = iop_code_str[sas_loginfo.dw.code];
7105 if (sas_loginfo.dw.code <
7106 sizeof(pl_code_str)/sizeof(char*))
7107 code_desc = pl_code_str[sas_loginfo.dw.code];
7110 if (sas_loginfo.dw.code >=
7111 sizeof(ir_code_str)/sizeof(char*))
7113 code_desc = ir_code_str[sas_loginfo.dw.code];
7114 if (sas_loginfo.dw.subcode >=
7115 sizeof(raid_sub_code_str)/sizeof(char*))
7117 if (sas_loginfo.dw.code == 0)
7119 raid_sub_code_str[sas_loginfo.dw.subcode];
7125 if (sub_code_desc != NULL)
7126 printk(MYIOC_s_INFO_FMT
7127 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7129 ioc->name, log_info, originator_desc, code_desc,
7131 else if (code_desc != NULL)
7132 printk(MYIOC_s_INFO_FMT
7133 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7134 " SubCode(0x%04x)\n",
7135 ioc->name, log_info, originator_desc, code_desc,
7136 sas_loginfo.dw.subcode);
7138 printk(MYIOC_s_INFO_FMT
7139 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
7140 " SubCode(0x%04x)\n",
7141 ioc->name, log_info, originator_desc,
7142 sas_loginfo.dw.code, sas_loginfo.dw.subcode);
7145 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7147 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
7148 * @ioc: Pointer to MPT_ADAPTER structure
7149 * @ioc_status: U32 IOCStatus word from IOC
7150 * @mf: Pointer to MPT request frame
7152 * Refer to lsi/mpi.h.
7155 mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7157 Config_t *pReq = (Config_t *)mf;
7158 char extend_desc[EVENT_DESCR_STR_SZ];
7163 if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
7164 page_type = pReq->ExtPageType;
7166 page_type = pReq->Header.PageType;
7169 * ignore invalid page messages for GET_NEXT_HANDLE
7171 form = le32_to_cpu(pReq->PageAddress);
7172 if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
7173 if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
7174 page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
7175 page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
7176 if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
7177 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
7180 if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
7181 if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
7182 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
7186 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
7187 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
7188 page_type, pReq->Header.PageNumber, pReq->Action, form);
7190 switch (ioc_status) {
7192 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7193 desc = "Config Page Invalid Action";
7196 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7197 desc = "Config Page Invalid Type";
7200 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7201 desc = "Config Page Invalid Page";
7204 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7205 desc = "Config Page Invalid Data";
7208 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7209 desc = "Config Page No Defaults";
7212 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7213 desc = "Config Page Can't Commit";
7220 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s: %s\n",
7221 ioc->name, ioc_status, desc, extend_desc));
7225 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
7226 * @ioc: Pointer to MPT_ADAPTER structure
7227 * @ioc_status: U32 IOCStatus word from IOC
7228 * @mf: Pointer to MPT request frame
7230 * Refer to lsi/mpi.h.
7233 mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7235 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
7240 /****************************************************************************/
7241 /* Common IOCStatus values for all replies */
7242 /****************************************************************************/
7244 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
7245 desc = "Invalid Function";
7248 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
7252 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
7253 desc = "Invalid SGL";
7256 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
7257 desc = "Internal Error";
7260 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
7264 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
7265 desc = "Insufficient Resources";
7268 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
7269 desc = "Invalid Field";
7272 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
7273 desc = "Invalid State";
7276 /****************************************************************************/
7277 /* Config IOCStatus values */
7278 /****************************************************************************/
7280 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7281 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7282 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7283 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7284 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7285 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7286 mpt_iocstatus_info_config(ioc, status, mf);
7289 /****************************************************************************/
7290 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
7292 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
7294 /****************************************************************************/
7296 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
7297 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
7298 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
7299 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
7300 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
7301 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
7302 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
7303 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
7304 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
7305 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
7306 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
7307 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
7308 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
7311 /****************************************************************************/
7312 /* SCSI Target values */
7313 /****************************************************************************/
7315 case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
7316 desc = "Target: Priority IO";
7319 case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
7320 desc = "Target: Invalid Port";
7323 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
7324 desc = "Target Invalid IO Index:";
7327 case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
7328 desc = "Target: Aborted";
7331 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
7332 desc = "Target: No Conn Retryable";
7335 case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
7336 desc = "Target: No Connection";
7339 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
7340 desc = "Target: Transfer Count Mismatch";
7343 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
7344 desc = "Target: STS Data not Sent";
7347 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
7348 desc = "Target: Data Offset Error";
7351 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
7352 desc = "Target: Too Much Write Data";
7355 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
7356 desc = "Target: IU Too Short";
7359 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
7360 desc = "Target: ACK NAK Timeout";
7363 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
7364 desc = "Target: Nak Received";
7367 /****************************************************************************/
7368 /* Fibre Channel Direct Access values */
7369 /****************************************************************************/
7371 case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
7372 desc = "FC: Aborted";
7375 case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
7376 desc = "FC: RX ID Invalid";
7379 case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
7380 desc = "FC: DID Invalid";
7383 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
7384 desc = "FC: Node Logged Out";
7387 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
7388 desc = "FC: Exchange Canceled";
7391 /****************************************************************************/
7393 /****************************************************************************/
7395 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
7396 desc = "LAN: Device not Found";
7399 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
7400 desc = "LAN: Device Failure";
7403 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
7404 desc = "LAN: Transmit Error";
7407 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
7408 desc = "LAN: Transmit Aborted";
7411 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
7412 desc = "LAN: Receive Error";
7415 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
7416 desc = "LAN: Receive Aborted";
7419 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
7420 desc = "LAN: Partial Packet";
7423 case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
7424 desc = "LAN: Canceled";
7427 /****************************************************************************/
7428 /* Serial Attached SCSI values */
7429 /****************************************************************************/
7431 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
7432 desc = "SAS: SMP Request Failed";
7435 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
7436 desc = "SAS: SMP Data Overrun";
7447 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s\n",
7448 ioc->name, status, desc));
7451 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7452 EXPORT_SYMBOL(mpt_attach);
7453 EXPORT_SYMBOL(mpt_detach);
7455 EXPORT_SYMBOL(mpt_resume);
7456 EXPORT_SYMBOL(mpt_suspend);
7458 EXPORT_SYMBOL(ioc_list);
7459 EXPORT_SYMBOL(mpt_proc_root_dir);
7460 EXPORT_SYMBOL(mpt_register);
7461 EXPORT_SYMBOL(mpt_deregister);
7462 EXPORT_SYMBOL(mpt_event_register);
7463 EXPORT_SYMBOL(mpt_event_deregister);
7464 EXPORT_SYMBOL(mpt_reset_register);
7465 EXPORT_SYMBOL(mpt_reset_deregister);
7466 EXPORT_SYMBOL(mpt_device_driver_register);
7467 EXPORT_SYMBOL(mpt_device_driver_deregister);
7468 EXPORT_SYMBOL(mpt_get_msg_frame);
7469 EXPORT_SYMBOL(mpt_put_msg_frame);
7470 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri);
7471 EXPORT_SYMBOL(mpt_free_msg_frame);
7472 EXPORT_SYMBOL(mpt_add_sge);
7473 EXPORT_SYMBOL(mpt_send_handshake_request);
7474 EXPORT_SYMBOL(mpt_verify_adapter);
7475 EXPORT_SYMBOL(mpt_GetIocState);
7476 EXPORT_SYMBOL(mpt_print_ioc_summary);
7477 EXPORT_SYMBOL(mpt_HardResetHandler);
7478 EXPORT_SYMBOL(mpt_config);
7479 EXPORT_SYMBOL(mpt_findImVolumes);
7480 EXPORT_SYMBOL(mpt_alloc_fw_memory);
7481 EXPORT_SYMBOL(mpt_free_fw_memory);
7482 EXPORT_SYMBOL(mptbase_sas_persist_operation);
7483 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
7485 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7487 * fusion_init - Fusion MPT base driver initialization routine.
7489 * Returns 0 for success, non-zero for failure.
7496 show_mptmod_ver(my_NAME, my_VERSION);
7497 printk(KERN_INFO COPYRIGHT "\n");
7499 for (cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
7500 MptCallbacks[cb_idx] = NULL;
7501 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
7502 MptEvHandlers[cb_idx] = NULL;
7503 MptResetHandlers[cb_idx] = NULL;
7506 /* Register ourselves (mptbase) in order to facilitate
7507 * EventNotification handling.
7509 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
7511 /* Register for hard reset handling callbacks.
7513 mpt_reset_register(mpt_base_index, mpt_ioc_reset);
7515 #ifdef CONFIG_PROC_FS
7516 (void) procmpt_create();
7521 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7523 * fusion_exit - Perform driver unload cleanup.
7525 * This routine frees all resources associated with each MPT adapter
7526 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
7532 mpt_reset_deregister(mpt_base_index);
7534 #ifdef CONFIG_PROC_FS
7539 module_init(fusion_init);
7540 module_exit(fusion_exit);