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;
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
637 * @cb_idx: previously registered (via mpt_register) callback handle
638 * @ev_cbfunc: callback function
640 * This routine can be called by one or more protocol-specific drivers
641 * if/when they choose to be notified of MPT events.
643 * Returns 0 for success.
646 mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc)
648 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
651 MptEvHandlers[cb_idx] = ev_cbfunc;
655 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
657 * mpt_event_deregister - Deregister protocol-specific event callback
659 * @cb_idx: previously registered callback handle
661 * Each protocol-specific driver should call this routine
662 * when it does not (or can no longer) handle events,
663 * or when its module is unloaded.
666 mpt_event_deregister(u8 cb_idx)
668 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
671 MptEvHandlers[cb_idx] = NULL;
674 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
676 * mpt_reset_register - Register protocol-specific IOC reset handler.
677 * @cb_idx: previously registered (via mpt_register) callback handle
678 * @reset_func: reset function
680 * This routine can be called by one or more protocol-specific drivers
681 * if/when they choose to be notified of IOC resets.
683 * Returns 0 for success.
686 mpt_reset_register(u8 cb_idx, MPT_RESETHANDLER reset_func)
688 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
691 MptResetHandlers[cb_idx] = reset_func;
695 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
697 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
698 * @cb_idx: previously registered callback handle
700 * Each protocol-specific driver should call this routine
701 * when it does not (or can no longer) handle IOC reset handling,
702 * or when its module is unloaded.
705 mpt_reset_deregister(u8 cb_idx)
707 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
710 MptResetHandlers[cb_idx] = NULL;
713 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
715 * mpt_device_driver_register - Register device driver hooks
716 * @dd_cbfunc: driver callbacks struct
717 * @cb_idx: MPT protocol driver index
720 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, u8 cb_idx)
723 const struct pci_device_id *id;
725 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
728 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
730 /* call per pci device probe entry point */
731 list_for_each_entry(ioc, &ioc_list, list) {
732 id = ioc->pcidev->driver ?
733 ioc->pcidev->driver->id_table : NULL;
734 if (dd_cbfunc->probe)
735 dd_cbfunc->probe(ioc->pcidev, id);
741 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
743 * mpt_device_driver_deregister - DeRegister device driver hooks
744 * @cb_idx: MPT protocol driver index
747 mpt_device_driver_deregister(u8 cb_idx)
749 struct mpt_pci_driver *dd_cbfunc;
752 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
755 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
757 list_for_each_entry(ioc, &ioc_list, list) {
758 if (dd_cbfunc->remove)
759 dd_cbfunc->remove(ioc->pcidev);
762 MptDeviceDriverHandlers[cb_idx] = NULL;
766 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
768 * mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024)
769 * allocated per MPT adapter.
770 * @cb_idx: Handle of registered MPT protocol driver
771 * @ioc: Pointer to MPT adapter structure
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
839 * @cb_idx: Handle of registered MPT protocol driver
840 * @ioc: Pointer to MPT adapter structure
841 * @mf: Pointer to MPT request frame
843 * This routine posts a MPT request frame to the request post FIFO of a
844 * specific MPT adapter.
847 mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
851 u16 req_idx; /* Request index */
853 /* ensure values are reset properly! */
854 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
855 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
857 req_idx = req_offset / ioc->req_sz;
858 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
859 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
861 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
863 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
864 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d "
865 "RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx,
866 ioc->RequestNB[req_idx]));
867 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
871 * mpt_put_msg_frame_hi_pri - Send a protocol specific MPT request frame
872 * to a IOC using hi priority request queue.
873 * @cb_idx: Handle of registered MPT protocol driver
874 * @ioc: Pointer to MPT adapter structure
875 * @mf: Pointer to MPT request frame
877 * This routine posts a MPT request frame to the request post FIFO of a
878 * specific MPT adapter.
881 mpt_put_msg_frame_hi_pri(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
885 u16 req_idx; /* Request index */
887 /* ensure values are reset properly! */
888 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
889 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
890 req_idx = req_offset / ioc->req_sz;
891 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
892 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
894 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
896 mf_dma_addr = (ioc->req_frames_low_dma + req_offset);
897 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d\n",
898 ioc->name, mf_dma_addr, req_idx));
899 CHIPREG_WRITE32(&ioc->chip->RequestHiPriFifo, mf_dma_addr);
902 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
904 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
905 * @handle: Handle of registered MPT protocol driver
906 * @ioc: Pointer to MPT adapter structure
907 * @mf: Pointer to MPT request frame
909 * This routine places a MPT request frame back on the MPT adapter's
913 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
917 /* Put Request back on FreeQ! */
918 spin_lock_irqsave(&ioc->FreeQlock, flags);
919 mf->u.frame.linkage.arg1 = 0xdeadbeaf; /* signature to know if this mf is freed */
920 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
924 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
927 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
929 * mpt_add_sge - Place a simple SGE at address pAddr.
930 * @pAddr: virtual address for SGE
931 * @flagslength: SGE flags and data transfer length
932 * @dma_addr: Physical address
934 * This routine places a MPT request frame back on the MPT adapter's
938 mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
940 if (sizeof(dma_addr_t) == sizeof(u64)) {
941 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
942 u32 tmp = dma_addr & 0xFFFFFFFF;
944 pSge->FlagsLength = cpu_to_le32(flagslength);
945 pSge->Address.Low = cpu_to_le32(tmp);
946 tmp = (u32) ((u64)dma_addr >> 32);
947 pSge->Address.High = cpu_to_le32(tmp);
950 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
951 pSge->FlagsLength = cpu_to_le32(flagslength);
952 pSge->Address = cpu_to_le32(dma_addr);
956 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
958 * mpt_send_handshake_request - Send MPT request via doorbell handshake method.
959 * @cb_idx: Handle of registered MPT protocol driver
960 * @ioc: Pointer to MPT adapter structure
961 * @reqBytes: Size of the request in bytes
962 * @req: Pointer to MPT request frame
963 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
965 * This routine is used exclusively to send MptScsiTaskMgmt
966 * requests since they are required to be sent via doorbell handshake.
968 * NOTE: It is the callers responsibility to byte-swap fields in the
969 * request which are greater than 1 byte in size.
971 * Returns 0 for success, non-zero for failure.
974 mpt_send_handshake_request(u8 cb_idx, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
980 /* State is known to be good upon entering
981 * this function so issue the bus reset
986 * Emulate what mpt_put_msg_frame() does /wrt to sanity
987 * setting cb_idx/req_idx. But ONLY if this request
988 * is in proper (pre-alloc'd) request buffer range...
990 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
991 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
992 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
993 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
994 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
997 /* Make sure there are no doorbells */
998 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1000 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1001 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
1002 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
1004 /* Wait for IOC doorbell int */
1005 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
1009 /* Read doorbell and check for active bit */
1010 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
1013 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_send_handshake_request start, WaitCnt=%d\n",
1016 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1018 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1022 /* Send request via doorbell handshake */
1023 req_as_bytes = (u8 *) req;
1024 for (ii = 0; ii < reqBytes/4; ii++) {
1027 word = ((req_as_bytes[(ii*4) + 0] << 0) |
1028 (req_as_bytes[(ii*4) + 1] << 8) |
1029 (req_as_bytes[(ii*4) + 2] << 16) |
1030 (req_as_bytes[(ii*4) + 3] << 24));
1031 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
1032 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1038 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
1043 /* Make sure there are no doorbells */
1044 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1049 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1051 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
1052 * @ioc: Pointer to MPT adapter structure
1053 * @access_control_value: define bits below
1054 * @sleepFlag: Specifies whether the process can sleep
1056 * Provides mechanism for the host driver to control the IOC's
1057 * Host Page Buffer access.
1059 * Access Control Value - bits[15:12]
1061 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1062 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1063 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1065 * Returns 0 for success, non-zero for failure.
1069 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1073 /* return if in use */
1074 if (CHIPREG_READ32(&ioc->chip->Doorbell)
1075 & MPI_DOORBELL_ACTIVE)
1078 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1080 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1081 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1082 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1083 (access_control_value<<12)));
1085 /* Wait for IOC to clear Doorbell Status bit */
1086 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1092 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1094 * mpt_host_page_alloc - allocate system memory for the fw
1095 * @ioc: Pointer to pointer to IOC adapter
1096 * @ioc_init: Pointer to ioc init config page
1098 * If we already allocated memory in past, then resend the same pointer.
1099 * Returns 0 for success, non-zero for failure.
1102 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1106 u32 host_page_buffer_sz=0;
1108 if(!ioc->HostPageBuffer) {
1110 host_page_buffer_sz =
1111 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1113 if(!host_page_buffer_sz)
1114 return 0; /* fw doesn't need any host buffers */
1116 /* spin till we get enough memory */
1117 while(host_page_buffer_sz > 0) {
1119 if((ioc->HostPageBuffer = pci_alloc_consistent(
1121 host_page_buffer_sz,
1122 &ioc->HostPageBuffer_dma)) != NULL) {
1124 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1125 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1126 ioc->name, ioc->HostPageBuffer,
1127 (u32)ioc->HostPageBuffer_dma,
1128 host_page_buffer_sz));
1129 ioc->alloc_total += host_page_buffer_sz;
1130 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1134 host_page_buffer_sz -= (4*1024);
1138 if(!ioc->HostPageBuffer) {
1139 printk(MYIOC_s_ERR_FMT
1140 "Failed to alloc memory for host_page_buffer!\n",
1145 psge = (char *)&ioc_init->HostPageBufferSGE;
1146 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1147 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1148 MPI_SGE_FLAGS_32_BIT_ADDRESSING |
1149 MPI_SGE_FLAGS_HOST_TO_IOC |
1150 MPI_SGE_FLAGS_END_OF_BUFFER;
1151 if (sizeof(dma_addr_t) == sizeof(u64)) {
1152 flags_length |= MPI_SGE_FLAGS_64_BIT_ADDRESSING;
1154 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1155 flags_length |= ioc->HostPageBuffer_sz;
1156 mpt_add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1157 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1162 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1164 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1165 * @iocid: IOC unique identifier (integer)
1166 * @iocpp: Pointer to pointer to IOC adapter
1168 * Given a unique IOC identifier, set pointer to the associated MPT
1169 * adapter structure.
1171 * Returns iocid and sets iocpp if iocid is found.
1172 * Returns -1 if iocid is not found.
1175 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1179 list_for_each_entry(ioc,&ioc_list,list) {
1180 if (ioc->id == iocid) {
1191 * mpt_get_product_name - returns product string
1192 * @vendor: pci vendor id
1193 * @device: pci device id
1194 * @revision: pci revision id
1195 * @prod_name: string returned
1197 * Returns product string displayed when driver loads,
1198 * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1202 mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name)
1204 char *product_str = NULL;
1206 if (vendor == PCI_VENDOR_ID_BROCADE) {
1209 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1213 product_str = "BRE040 A0";
1216 product_str = "BRE040 A1";
1219 product_str = "BRE040";
1229 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1230 product_str = "LSIFC909 B1";
1232 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1233 product_str = "LSIFC919 B0";
1235 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1236 product_str = "LSIFC929 B0";
1238 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1239 if (revision < 0x80)
1240 product_str = "LSIFC919X A0";
1242 product_str = "LSIFC919XL A1";
1244 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1245 if (revision < 0x80)
1246 product_str = "LSIFC929X A0";
1248 product_str = "LSIFC929XL A1";
1250 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1251 product_str = "LSIFC939X A1";
1253 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1254 product_str = "LSIFC949X A1";
1256 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1260 product_str = "LSIFC949E A0";
1263 product_str = "LSIFC949E A1";
1266 product_str = "LSIFC949E";
1270 case MPI_MANUFACTPAGE_DEVID_53C1030:
1274 product_str = "LSI53C1030 A0";
1277 product_str = "LSI53C1030 B0";
1280 product_str = "LSI53C1030 B1";
1283 product_str = "LSI53C1030 B2";
1286 product_str = "LSI53C1030 C0";
1289 product_str = "LSI53C1030T A0";
1292 product_str = "LSI53C1030T A2";
1295 product_str = "LSI53C1030T A3";
1298 product_str = "LSI53C1020A A1";
1301 product_str = "LSI53C1030";
1305 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1309 product_str = "LSI53C1035 A2";
1312 product_str = "LSI53C1035 B0";
1315 product_str = "LSI53C1035";
1319 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1323 product_str = "LSISAS1064 A1";
1326 product_str = "LSISAS1064 A2";
1329 product_str = "LSISAS1064 A3";
1332 product_str = "LSISAS1064 A4";
1335 product_str = "LSISAS1064";
1339 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1343 product_str = "LSISAS1064E A0";
1346 product_str = "LSISAS1064E B0";
1349 product_str = "LSISAS1064E B1";
1352 product_str = "LSISAS1064E B2";
1355 product_str = "LSISAS1064E B3";
1358 product_str = "LSISAS1064E";
1362 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1366 product_str = "LSISAS1068 A0";
1369 product_str = "LSISAS1068 B0";
1372 product_str = "LSISAS1068 B1";
1375 product_str = "LSISAS1068";
1379 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1383 product_str = "LSISAS1068E A0";
1386 product_str = "LSISAS1068E B0";
1389 product_str = "LSISAS1068E B1";
1392 product_str = "LSISAS1068E B2";
1395 product_str = "LSISAS1068E B3";
1398 product_str = "LSISAS1068E";
1402 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1406 product_str = "LSISAS1078 A0";
1409 product_str = "LSISAS1078 B0";
1412 product_str = "LSISAS1078 C0";
1415 product_str = "LSISAS1078 C1";
1418 product_str = "LSISAS1078 C2";
1421 product_str = "LSISAS1078";
1429 sprintf(prod_name, "%s", product_str);
1432 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1434 * mpt_attach - Install a PCI intelligent MPT adapter.
1435 * @pdev: Pointer to pci_dev structure
1436 * @id: PCI device ID information
1438 * This routine performs all the steps necessary to bring the IOC of
1439 * a MPT adapter to a OPERATIONAL state. This includes registering
1440 * memory regions, registering the interrupt, and allocating request
1441 * and reply memory pools.
1443 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1446 * Returns 0 for success, non-zero for failure.
1448 * TODO: Add support for polled controllers
1451 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1456 unsigned long mem_phys;
1465 static int mpt_ids = 0;
1466 #ifdef CONFIG_PROC_FS
1467 struct proc_dir_entry *dent, *ent;
1470 if (mpt_debug_level)
1471 printk(KERN_INFO MYNAM ": mpt_debug_level=%xh\n", mpt_debug_level);
1473 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1475 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1478 ioc->debug_level = mpt_debug_level;
1479 ioc->id = mpt_ids++;
1480 sprintf(ioc->name, "ioc%d", ioc->id);
1482 ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
1483 if (pci_enable_device_mem(pdev)) {
1485 printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() "
1486 "failed\n", ioc->name);
1489 if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) {
1491 printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with "
1492 "MEM failed\n", ioc->name);
1496 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name));
1498 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
1499 dprintk(ioc, printk(MYIOC_s_INFO_FMT
1500 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n", ioc->name));
1501 } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
1502 printk(MYIOC_s_WARN_FMT ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n",
1508 if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
1509 dprintk(ioc, printk(MYIOC_s_INFO_FMT
1510 ": Using 64 bit consistent mask\n", ioc->name));
1512 dprintk(ioc, printk(MYIOC_s_INFO_FMT
1513 ": Not using 64 bit consistent mask\n", ioc->name));
1516 ioc->alloc_total = sizeof(MPT_ADAPTER);
1517 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1518 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1521 ioc->diagPending = 0;
1522 spin_lock_init(&ioc->diagLock);
1523 spin_lock_init(&ioc->initializing_hba_lock);
1525 /* Initialize the event logging.
1527 ioc->eventTypes = 0; /* None */
1528 ioc->eventContext = 0;
1529 ioc->eventLogSize = 0;
1536 ioc->cached_fw = NULL;
1538 /* Initilize SCSI Config Data structure
1540 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1542 /* Initialize the running configQ head.
1544 INIT_LIST_HEAD(&ioc->configQ);
1546 /* Initialize the fc rport list head.
1548 INIT_LIST_HEAD(&ioc->fc_rports);
1550 /* Find lookup slot. */
1551 INIT_LIST_HEAD(&ioc->list);
1553 mem_phys = msize = 0;
1555 for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1556 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1559 /* Get I/O space! */
1560 port = pci_resource_start(pdev, ii);
1561 psize = pci_resource_len(pdev,ii);
1566 mem_phys = pci_resource_start(pdev, ii);
1567 msize = pci_resource_len(pdev,ii);
1570 ioc->mem_size = msize;
1573 /* Get logical ptr for PciMem0 space */
1574 /*mem = ioremap(mem_phys, msize);*/
1575 mem = ioremap(mem_phys, msize);
1577 printk(MYIOC_s_ERR_FMT "Unable to map adapter memory!\n", ioc->name);
1582 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %lx\n", ioc->name, mem, mem_phys));
1584 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",
1585 ioc->name, &ioc->facts, &ioc->pfacts[0]));
1587 ioc->mem_phys = mem_phys;
1588 ioc->chip = (SYSIF_REGS __iomem *)mem;
1590 /* Save Port IO values in case we need to do downloadboot */
1591 ioc->pio_mem_phys = port;
1592 pmem = (u8 __iomem *)port;
1593 ioc->pio_chip = (SYSIF_REGS __iomem *)pmem;
1595 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1596 mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name);
1598 switch (pdev->device)
1600 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1601 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1602 ioc->errata_flag_1064 = 1;
1603 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1604 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1605 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1606 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1610 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1611 if (revision < XL_929) {
1612 /* 929X Chip Fix. Set Split transactions level
1613 * for PCIX. Set MOST bits to zero.
1615 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1617 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1619 /* 929XL Chip Fix. Set MMRBC to 0x08.
1621 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1623 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1628 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1629 /* 919X Chip Fix. Set Split transactions level
1630 * for PCIX. Set MOST bits to zero.
1632 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1634 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1638 case MPI_MANUFACTPAGE_DEVID_53C1030:
1639 /* 1030 Chip Fix. Disable Split transactions
1640 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1642 if (revision < C0_1030) {
1643 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1645 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1648 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1649 ioc->bus_type = SPI;
1652 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1653 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1654 ioc->errata_flag_1064 = 1;
1656 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1657 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1658 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1659 ioc->bus_type = SAS;
1662 if (ioc->errata_flag_1064)
1663 pci_disable_io_access(pdev);
1665 spin_lock_init(&ioc->FreeQlock);
1668 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1670 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1672 /* Set IOC ptr in the pcidev's driver data. */
1673 pci_set_drvdata(ioc->pcidev, ioc);
1675 /* Set lookup ptr. */
1676 list_add_tail(&ioc->list, &ioc_list);
1678 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1680 mpt_detect_bound_ports(ioc, pdev);
1682 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1684 printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",
1687 list_del(&ioc->list);
1689 ioc->alt_ioc->alt_ioc = NULL;
1692 pci_set_drvdata(pdev, NULL);
1696 /* call per device driver probe entry point */
1697 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
1698 if(MptDeviceDriverHandlers[cb_idx] &&
1699 MptDeviceDriverHandlers[cb_idx]->probe) {
1700 MptDeviceDriverHandlers[cb_idx]->probe(pdev,id);
1704 #ifdef CONFIG_PROC_FS
1706 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1708 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1710 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1712 ent->read_proc = procmpt_iocinfo_read;
1715 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1717 ent->read_proc = procmpt_summary_read;
1726 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1728 * mpt_detach - Remove a PCI intelligent MPT adapter.
1729 * @pdev: Pointer to pci_dev structure
1733 mpt_detach(struct pci_dev *pdev)
1735 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1739 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
1740 remove_proc_entry(pname, NULL);
1741 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
1742 remove_proc_entry(pname, NULL);
1743 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
1744 remove_proc_entry(pname, NULL);
1746 /* call per device driver remove entry point */
1747 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
1748 if(MptDeviceDriverHandlers[cb_idx] &&
1749 MptDeviceDriverHandlers[cb_idx]->remove) {
1750 MptDeviceDriverHandlers[cb_idx]->remove(pdev);
1754 /* Disable interrupts! */
1755 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1758 synchronize_irq(pdev->irq);
1760 /* Clear any lingering interrupt */
1761 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1763 CHIPREG_READ32(&ioc->chip->IntStatus);
1765 mpt_adapter_dispose(ioc);
1767 pci_set_drvdata(pdev, NULL);
1770 /**************************************************************************
1774 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1776 * mpt_suspend - Fusion MPT base driver suspend routine.
1777 * @pdev: Pointer to pci_dev structure
1778 * @state: new state to enter
1781 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
1784 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1786 device_state=pci_choose_state(pdev, state);
1788 printk(MYIOC_s_INFO_FMT
1789 "pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
1790 ioc->name, pdev, pci_name(pdev), device_state);
1792 pci_save_state(pdev);
1794 /* put ioc into READY_STATE */
1795 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
1796 printk(MYIOC_s_ERR_FMT
1797 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
1800 /* disable interrupts */
1801 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1804 /* Clear any lingering interrupt */
1805 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1807 pci_disable_device(pdev);
1808 pci_release_selected_regions(pdev, ioc->bars);
1809 pci_set_power_state(pdev, device_state);
1814 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1816 * mpt_resume - Fusion MPT base driver resume routine.
1817 * @pdev: Pointer to pci_dev structure
1820 mpt_resume(struct pci_dev *pdev)
1822 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1823 u32 device_state = pdev->current_state;
1826 printk(MYIOC_s_INFO_FMT
1827 "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
1828 ioc->name, pdev, pci_name(pdev), device_state);
1830 pci_set_power_state(pdev, 0);
1831 pci_restore_state(pdev);
1832 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT) {
1833 ioc->bars = pci_select_bars(ioc->pcidev, IORESOURCE_MEM |
1835 if (pci_enable_device(pdev))
1838 ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
1839 if (pci_enable_device_mem(pdev))
1842 if (pci_request_selected_regions(pdev, ioc->bars, "mpt"))
1845 /* enable interrupts */
1846 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
1849 printk(MYIOC_s_INFO_FMT
1850 "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1852 (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1853 CHIPREG_READ32(&ioc->chip->Doorbell));
1855 /* bring ioc to operational state */
1856 if ((recovery_state = mpt_do_ioc_recovery(ioc,
1857 MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {
1858 printk(MYIOC_s_INFO_FMT
1859 "pci-resume: Cannot recover, error:[%x]\n",
1860 ioc->name, recovery_state);
1862 printk(MYIOC_s_INFO_FMT
1863 "pci-resume: success\n", ioc->name);
1871 mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase)
1873 if ((MptDriverClass[index] == MPTSPI_DRIVER &&
1874 ioc->bus_type != SPI) ||
1875 (MptDriverClass[index] == MPTFC_DRIVER &&
1876 ioc->bus_type != FC) ||
1877 (MptDriverClass[index] == MPTSAS_DRIVER &&
1878 ioc->bus_type != SAS))
1879 /* make sure we only call the relevant reset handler
1882 return (MptResetHandlers[index])(ioc, reset_phase);
1885 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1887 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1888 * @ioc: Pointer to MPT adapter structure
1889 * @reason: Event word / reason
1890 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1892 * This routine performs all the steps necessary to bring the IOC
1893 * to a OPERATIONAL state.
1895 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1900 * -1 if failed to get board READY
1901 * -2 if READY but IOCFacts Failed
1902 * -3 if READY but PrimeIOCFifos Failed
1903 * -4 if READY but IOCInit Failed
1904 * -5 if failed to enable_device and/or request_selected_regions
1907 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1909 int hard_reset_done = 0;
1910 int alt_ioc_ready = 0;
1917 int reset_alt_ioc_active = 0;
1918 int irq_allocated = 0;
1921 printk(MYIOC_s_INFO_FMT "Initiating %s\n", ioc->name,
1922 reason == MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
1924 /* Disable reply interrupts (also blocks FreeQ) */
1925 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1929 if (ioc->alt_ioc->active)
1930 reset_alt_ioc_active = 1;
1932 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1933 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
1934 ioc->alt_ioc->active = 0;
1938 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
1941 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
1942 if (hard_reset_done == -4) {
1943 printk(MYIOC_s_WARN_FMT "Owned by PEER..skipping!\n",
1946 if (reset_alt_ioc_active && ioc->alt_ioc) {
1947 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1948 dprintk(ioc, printk(MYIOC_s_INFO_FMT
1949 "alt_ioc reply irq re-enabled\n", ioc->alt_ioc->name));
1950 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
1951 ioc->alt_ioc->active = 1;
1955 printk(MYIOC_s_WARN_FMT "NOT READY!\n", ioc->name);
1960 /* hard_reset_done = 0 if a soft reset was performed
1961 * and 1 if a hard reset was performed.
1963 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
1964 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
1967 printk(MYIOC_s_WARN_FMT "alt_ioc not ready!\n", ioc->alt_ioc->name);
1970 for (ii=0; ii<5; ii++) {
1971 /* Get IOC facts! Allow 5 retries */
1972 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
1978 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1979 "Retry IocFacts failed rc=%x\n", ioc->name, rc));
1981 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1982 MptDisplayIocCapabilities(ioc);
1985 if (alt_ioc_ready) {
1986 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
1987 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1988 "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
1989 /* Retry - alt IOC was initialized once
1991 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
1994 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1995 "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
1997 reset_alt_ioc_active = 0;
1998 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1999 MptDisplayIocCapabilities(ioc->alt_ioc);
2003 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP) &&
2004 (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)) {
2005 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2006 ioc->bars = pci_select_bars(ioc->pcidev, IORESOURCE_MEM |
2008 if (pci_enable_device(ioc->pcidev))
2010 if (pci_request_selected_regions(ioc->pcidev, ioc->bars,
2016 * Device is reset now. It must have de-asserted the interrupt line
2017 * (if it was asserted) and it should be safe to register for the
2020 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2022 if (ioc->pcidev->irq) {
2023 if (mpt_msi_enable && !pci_enable_msi(ioc->pcidev))
2024 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
2026 rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
2027 IRQF_SHARED, ioc->name, ioc);
2029 printk(MYIOC_s_ERR_FMT "Unable to allocate "
2030 "interrupt %d!\n", ioc->name, ioc->pcidev->irq);
2032 pci_disable_msi(ioc->pcidev);
2036 ioc->pci_irq = ioc->pcidev->irq;
2037 pci_set_master(ioc->pcidev); /* ?? */
2038 dprintk(ioc, printk(MYIOC_s_INFO_FMT "installed at interrupt "
2039 "%d\n", ioc->name, ioc->pcidev->irq));
2043 /* Prime reply & request queues!
2044 * (mucho alloc's) Must be done prior to
2045 * init as upper addresses are needed for init.
2046 * If fails, continue with alt-ioc processing
2048 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
2051 /* May need to check/upload firmware & data here!
2052 * If fails, continue with alt-ioc processing
2054 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
2057 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
2058 printk(MYIOC_s_WARN_FMT ": alt_ioc (%d) FIFO mgmt alloc!\n",
2059 ioc->alt_ioc->name, rc);
2061 reset_alt_ioc_active = 0;
2064 if (alt_ioc_ready) {
2065 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
2067 reset_alt_ioc_active = 0;
2068 printk(MYIOC_s_WARN_FMT "alt_ioc (%d) init failure!\n",
2069 ioc->alt_ioc->name, rc);
2073 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
2074 if (ioc->upload_fw) {
2075 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2076 "firmware upload required!\n", ioc->name));
2078 /* Controller is not operational, cannot do upload
2081 rc = mpt_do_upload(ioc, sleepFlag);
2083 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2085 * Maintain only one pointer to FW memory
2086 * so there will not be two attempt to
2087 * downloadboot onboard dual function
2088 * chips (mpt_adapter_disable,
2091 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2092 "mpt_upload: alt_%s has cached_fw=%p \n",
2093 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
2094 ioc->cached_fw = NULL;
2097 printk(MYIOC_s_WARN_FMT
2098 "firmware upload failure!\n", ioc->name);
2106 /* Enable! (reply interrupt) */
2107 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
2111 if (reset_alt_ioc_active && ioc->alt_ioc) {
2112 /* (re)Enable alt-IOC! (reply interrupt) */
2113 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "alt_ioc reply irq re-enabled\n",
2114 ioc->alt_ioc->name));
2115 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2116 ioc->alt_ioc->active = 1;
2119 /* Enable MPT base driver management of EventNotification
2120 * and EventAck handling.
2122 if ((ret == 0) && (!ioc->facts.EventState))
2123 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
2125 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2126 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
2128 /* Add additional "reason" check before call to GetLanConfigPages
2129 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2130 * recursive scenario; GetLanConfigPages times out, timer expired
2131 * routine calls HardResetHandler, which calls into here again,
2132 * and we try GetLanConfigPages again...
2134 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2137 * Initalize link list for inactive raid volumes.
2139 init_MUTEX(&ioc->raid_data.inactive_list_mutex);
2140 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2142 if (ioc->bus_type == SAS) {
2144 /* clear persistency table */
2145 if(ioc->facts.IOCExceptions &
2146 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
2147 ret = mptbase_sas_persist_operation(ioc,
2148 MPI_SAS_OP_CLEAR_NOT_PRESENT);
2155 mpt_findImVolumes(ioc);
2157 } else if (ioc->bus_type == FC) {
2158 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
2159 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2161 * Pre-fetch the ports LAN MAC address!
2162 * (LANPage1_t stuff)
2164 (void) GetLanConfigPages(ioc);
2165 a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2166 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2167 "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
2168 ioc->name, a[5], a[4], a[3], a[2], a[1], a[0]));
2172 /* Get NVRAM and adapter maximums from SPP 0 and 2
2174 mpt_GetScsiPortSettings(ioc, 0);
2176 /* Get version and length of SDP 1
2178 mpt_readScsiDevicePageHeaders(ioc, 0);
2182 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
2183 mpt_findImVolumes(ioc);
2185 /* Check, and possibly reset, the coalescing value
2187 mpt_read_ioc_pg_1(ioc);
2189 mpt_read_ioc_pg_4(ioc);
2192 GetIoUnitPage2(ioc);
2193 mpt_get_manufacturing_pg_0(ioc);
2197 * Call each currently registered protocol IOC reset handler
2198 * with post-reset indication.
2199 * NOTE: If we're doing _IOC_BRINGUP, there can be no
2200 * MptResetHandlers[] registered yet.
2202 if (hard_reset_done) {
2204 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
2205 if ((ret == 0) && MptResetHandlers[cb_idx]) {
2206 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2207 "Calling IOC post_reset handler #%d\n",
2208 ioc->name, cb_idx));
2209 rc += mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET);
2213 if (alt_ioc_ready && MptResetHandlers[cb_idx]) {
2214 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2215 "Calling IOC post_reset handler #%d\n",
2216 ioc->alt_ioc->name, cb_idx));
2217 rc += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_POST_RESET);
2221 /* FIXME? Examine results here? */
2225 if ((ret != 0) && irq_allocated) {
2226 free_irq(ioc->pci_irq, ioc);
2228 pci_disable_msi(ioc->pcidev);
2233 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2235 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2236 * @ioc: Pointer to MPT adapter structure
2237 * @pdev: Pointer to (struct pci_dev) structure
2239 * Search for PCI bus/dev_function which matches
2240 * PCI bus/dev_function (+/-1) for newly discovered 929,
2241 * 929X, 1030 or 1035.
2243 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2244 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2247 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
2249 struct pci_dev *peer=NULL;
2250 unsigned int slot = PCI_SLOT(pdev->devfn);
2251 unsigned int func = PCI_FUNC(pdev->devfn);
2252 MPT_ADAPTER *ioc_srch;
2254 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PCI device %s devfn=%x/%x,"
2255 " searching for devfn match on %x or %x\n",
2256 ioc->name, pci_name(pdev), pdev->bus->number,
2257 pdev->devfn, func-1, func+1));
2259 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
2261 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
2266 list_for_each_entry(ioc_srch, &ioc_list, list) {
2267 struct pci_dev *_pcidev = ioc_srch->pcidev;
2268 if (_pcidev == peer) {
2269 /* Paranoia checks */
2270 if (ioc->alt_ioc != NULL) {
2271 printk(MYIOC_s_WARN_FMT "Oops, already bound to %s!\n",
2272 ioc->name, ioc->alt_ioc->name);
2274 } else if (ioc_srch->alt_ioc != NULL) {
2275 printk(MYIOC_s_WARN_FMT "Oops, already bound to %s!\n",
2276 ioc_srch->name, ioc_srch->alt_ioc->name);
2279 dprintk(ioc, printk(MYIOC_s_INFO_FMT "FOUND! binding to %s\n",
2280 ioc->name, ioc_srch->name));
2281 ioc_srch->alt_ioc = ioc;
2282 ioc->alt_ioc = ioc_srch;
2288 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2290 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2291 * @ioc: Pointer to MPT adapter structure
2294 mpt_adapter_disable(MPT_ADAPTER *ioc)
2299 if (ioc->cached_fw != NULL) {
2300 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: Pushing FW onto "
2301 "adapter\n", __FUNCTION__, ioc->name));
2302 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)
2303 ioc->cached_fw, CAN_SLEEP)) < 0) {
2304 printk(MYIOC_s_WARN_FMT
2305 ": firmware downloadboot failure (%d)!\n",
2310 /* Disable adapter interrupts! */
2311 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2313 /* Clear any lingering interrupt */
2314 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2316 if (ioc->alloc != NULL) {
2318 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "free @ %p, sz=%d bytes\n",
2319 ioc->name, ioc->alloc, ioc->alloc_sz));
2320 pci_free_consistent(ioc->pcidev, sz,
2321 ioc->alloc, ioc->alloc_dma);
2322 ioc->reply_frames = NULL;
2323 ioc->req_frames = NULL;
2325 ioc->alloc_total -= sz;
2328 if (ioc->sense_buf_pool != NULL) {
2329 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2330 pci_free_consistent(ioc->pcidev, sz,
2331 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2332 ioc->sense_buf_pool = NULL;
2333 ioc->alloc_total -= sz;
2336 if (ioc->events != NULL){
2337 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2340 ioc->alloc_total -= sz;
2343 mpt_free_fw_memory(ioc);
2345 kfree(ioc->spi_data.nvram);
2346 mpt_inactive_raid_list_free(ioc);
2347 kfree(ioc->raid_data.pIocPg2);
2348 kfree(ioc->raid_data.pIocPg3);
2349 ioc->spi_data.nvram = NULL;
2350 ioc->raid_data.pIocPg3 = NULL;
2352 if (ioc->spi_data.pIocPg4 != NULL) {
2353 sz = ioc->spi_data.IocPg4Sz;
2354 pci_free_consistent(ioc->pcidev, sz,
2355 ioc->spi_data.pIocPg4,
2356 ioc->spi_data.IocPg4_dma);
2357 ioc->spi_data.pIocPg4 = NULL;
2358 ioc->alloc_total -= sz;
2361 if (ioc->ReqToChain != NULL) {
2362 kfree(ioc->ReqToChain);
2363 kfree(ioc->RequestNB);
2364 ioc->ReqToChain = NULL;
2367 kfree(ioc->ChainToChain);
2368 ioc->ChainToChain = NULL;
2370 if (ioc->HostPageBuffer != NULL) {
2371 if((ret = mpt_host_page_access_control(ioc,
2372 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2373 printk(MYIOC_s_ERR_FMT
2374 "host page buffers free failed (%d)!\n",
2377 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "HostPageBuffer free @ %p, sz=%d bytes\n",
2378 ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
2379 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2380 ioc->HostPageBuffer, ioc->HostPageBuffer_dma);
2381 ioc->HostPageBuffer = NULL;
2382 ioc->HostPageBuffer_sz = 0;
2383 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2387 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2389 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2390 * @ioc: Pointer to MPT adapter structure
2392 * This routine unregisters h/w resources and frees all alloc'd memory
2393 * associated with a MPT adapter structure.
2396 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2398 int sz_first, sz_last;
2403 sz_first = ioc->alloc_total;
2405 mpt_adapter_disable(ioc);
2407 if (ioc->pci_irq != -1) {
2408 free_irq(ioc->pci_irq, ioc);
2410 pci_disable_msi(ioc->pcidev);
2414 if (ioc->memmap != NULL) {
2415 iounmap(ioc->memmap);
2419 pci_disable_device(ioc->pcidev);
2420 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2422 #if defined(CONFIG_MTRR) && 0
2423 if (ioc->mtrr_reg > 0) {
2424 mtrr_del(ioc->mtrr_reg, 0, 0);
2425 dprintk(ioc, printk(MYIOC_s_INFO_FMT "MTRR region de-registered\n", ioc->name));
2429 /* Zap the adapter lookup ptr! */
2430 list_del(&ioc->list);
2432 sz_last = ioc->alloc_total;
2433 dprintk(ioc, printk(MYIOC_s_INFO_FMT "free'd %d of %d bytes\n",
2434 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2437 ioc->alt_ioc->alt_ioc = NULL;
2442 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2444 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2445 * @ioc: Pointer to MPT adapter structure
2448 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2452 printk(KERN_INFO "%s: ", ioc->name);
2454 printk("%s: ", ioc->prod_name);
2455 printk("Capabilities={");
2457 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2458 printk("Initiator");
2462 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2463 printk("%sTarget", i ? "," : "");
2467 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2468 printk("%sLAN", i ? "," : "");
2474 * This would probably evoke more questions than it's worth
2476 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2477 printk("%sLogBusAddr", i ? "," : "");
2485 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2487 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2488 * @ioc: Pointer to MPT_ADAPTER structure
2489 * @force: Force hard KickStart of IOC
2490 * @sleepFlag: Specifies whether the process can sleep
2493 * 1 - DIAG reset and READY
2494 * 0 - READY initially OR soft reset and READY
2495 * -1 - Any failure on KickStart
2496 * -2 - Msg Unit Reset Failed
2497 * -3 - IO Unit Reset Failed
2498 * -4 - IOC owned by a PEER
2501 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2506 int hard_reset_done = 0;
2511 /* Get current [raw] IOC state */
2512 ioc_state = mpt_GetIocState(ioc, 0);
2513 dhsprintk(ioc, printk(MYIOC_s_INFO_FMT "MakeIocReady [raw] state=%08x\n", ioc->name, ioc_state));
2516 * Check to see if IOC got left/stuck in doorbell handshake
2517 * grip of death. If so, hard reset the IOC.
2519 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2521 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2525 /* Is it already READY? */
2526 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
2530 * Check to see if IOC is in FAULT state.
2532 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2534 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2536 printk(MYIOC_s_WARN_FMT " FAULT code = %04xh\n",
2537 ioc->name, ioc_state & MPI_DOORBELL_DATA_MASK);
2541 * Hmmm... Did it get left operational?
2543 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2544 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC operational unexpected\n",
2548 * If PCI Peer, exit.
2549 * Else, if no fault conditions are present, issue a MessageUnitReset
2550 * Else, fall through to KickStart case
2552 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2553 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2554 "whoinit 0x%x statefault %d force %d\n",
2555 ioc->name, whoinit, statefault, force));
2556 if (whoinit == MPI_WHOINIT_PCI_PEER)
2559 if ((statefault == 0 ) && (force == 0)) {
2560 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2567 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2568 if (hard_reset_done < 0)
2572 * Loop here waiting for IOC to come READY.
2575 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2577 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2578 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2580 * BIOS or previous driver load left IOC in OP state.
2581 * Reset messaging FIFOs.
2583 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2584 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2587 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2589 * Something is wrong. Try to get IOC back
2592 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2593 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2600 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2601 ioc->name, (int)((ii+5)/HZ));
2605 if (sleepFlag == CAN_SLEEP) {
2608 mdelay (1); /* 1 msec delay */
2613 if (statefault < 3) {
2614 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2616 statefault==1 ? "stuck handshake" : "IOC FAULT");
2619 return hard_reset_done;
2622 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2624 * mpt_GetIocState - Get the current state of a MPT adapter.
2625 * @ioc: Pointer to MPT_ADAPTER structure
2626 * @cooked: Request raw or cooked IOC state
2628 * Returns all IOC Doorbell register bits if cooked==0, else just the
2629 * Doorbell bits in MPI_IOC_STATE_MASK.
2632 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2637 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2638 sc = s & MPI_IOC_STATE_MASK;
2641 ioc->last_state = sc;
2643 return cooked ? sc : s;
2646 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2648 * GetIocFacts - Send IOCFacts request to MPT adapter.
2649 * @ioc: Pointer to MPT_ADAPTER structure
2650 * @sleepFlag: Specifies whether the process can sleep
2651 * @reason: If recovery, only update facts.
2653 * Returns 0 for success, non-zero for failure.
2656 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2658 IOCFacts_t get_facts;
2659 IOCFactsReply_t *facts;
2667 /* IOC *must* NOT be in RESET state! */
2668 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2669 printk(MYIOC_s_ERR_FMT "Can't get IOCFacts NOT READY! (%08x)\n",
2670 ioc->name, ioc->last_state );
2674 facts = &ioc->facts;
2676 /* Destination (reply area)... */
2677 reply_sz = sizeof(*facts);
2678 memset(facts, 0, reply_sz);
2680 /* Request area (get_facts on the stack right now!) */
2681 req_sz = sizeof(get_facts);
2682 memset(&get_facts, 0, req_sz);
2684 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2685 /* Assert: All other get_facts fields are zero! */
2687 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2688 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2689 ioc->name, req_sz, reply_sz));
2691 /* No non-zero fields in the get_facts request are greater than
2692 * 1 byte in size, so we can just fire it off as is.
2694 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2695 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2700 * Now byte swap (GRRR) the necessary fields before any further
2701 * inspection of reply contents.
2703 * But need to do some sanity checks on MsgLength (byte) field
2704 * to make sure we don't zero IOC's req_sz!
2706 /* Did we get a valid reply? */
2707 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2708 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2710 * If not been here, done that, save off first WhoInit value
2712 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2713 ioc->FirstWhoInit = facts->WhoInit;
2716 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2717 facts->MsgContext = le32_to_cpu(facts->MsgContext);
2718 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2719 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2720 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2721 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
2722 /* CHECKME! IOCStatus, IOCLogInfo */
2724 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2725 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2728 * FC f/w version changed between 1.1 and 1.2
2729 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2730 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2732 if (facts->MsgVersion < 0x0102) {
2734 * Handle old FC f/w style, convert to new...
2736 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2737 facts->FWVersion.Word =
2738 ((oldv<<12) & 0xFF000000) |
2739 ((oldv<<8) & 0x000FFF00);
2741 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2743 facts->ProductID = le16_to_cpu(facts->ProductID);
2744 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
2745 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
2746 ioc->ir_firmware = 1;
2747 facts->CurrentHostMfaHighAddr =
2748 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2749 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2750 facts->CurrentSenseBufferHighAddr =
2751 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2752 facts->CurReplyFrameSize =
2753 le16_to_cpu(facts->CurReplyFrameSize);
2754 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
2757 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2758 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2759 * to 14 in MPI-1.01.0x.
2761 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2762 facts->MsgVersion > 0x0100) {
2763 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2766 sz = facts->FWImageSize;
2771 facts->FWImageSize = sz;
2773 if (!facts->RequestFrameSize) {
2774 /* Something is wrong! */
2775 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2780 r = sz = facts->BlockSize;
2781 vv = ((63 / (sz * 4)) + 1) & 0x03;
2782 ioc->NB_for_64_byte_frame = vv;
2788 ioc->NBShiftFactor = shiftFactor;
2789 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2790 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2791 ioc->name, vv, shiftFactor, r));
2793 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2795 * Set values for this IOC's request & reply frame sizes,
2796 * and request & reply queue depths...
2798 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2799 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2800 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2801 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2803 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "reply_sz=%3d, reply_depth=%4d\n",
2804 ioc->name, ioc->reply_sz, ioc->reply_depth));
2805 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "req_sz =%3d, req_depth =%4d\n",
2806 ioc->name, ioc->req_sz, ioc->req_depth));
2808 /* Get port facts! */
2809 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2813 printk(MYIOC_s_ERR_FMT
2814 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2815 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2816 RequestFrameSize)/sizeof(u32)));
2823 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2825 * GetPortFacts - Send PortFacts request to MPT adapter.
2826 * @ioc: Pointer to MPT_ADAPTER structure
2827 * @portnum: Port number
2828 * @sleepFlag: Specifies whether the process can sleep
2830 * Returns 0 for success, non-zero for failure.
2833 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2835 PortFacts_t get_pfacts;
2836 PortFactsReply_t *pfacts;
2842 /* IOC *must* NOT be in RESET state! */
2843 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2844 printk(MYIOC_s_ERR_FMT "Can't get PortFacts NOT READY! (%08x)\n",
2845 ioc->name, ioc->last_state );
2849 pfacts = &ioc->pfacts[portnum];
2851 /* Destination (reply area)... */
2852 reply_sz = sizeof(*pfacts);
2853 memset(pfacts, 0, reply_sz);
2855 /* Request area (get_pfacts on the stack right now!) */
2856 req_sz = sizeof(get_pfacts);
2857 memset(&get_pfacts, 0, req_sz);
2859 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2860 get_pfacts.PortNumber = portnum;
2861 /* Assert: All other get_pfacts fields are zero! */
2863 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending get PortFacts(%d) request\n",
2864 ioc->name, portnum));
2866 /* No non-zero fields in the get_pfacts request are greater than
2867 * 1 byte in size, so we can just fire it off as is.
2869 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2870 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2874 /* Did we get a valid reply? */
2876 /* Now byte swap the necessary fields in the response. */
2877 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2878 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2879 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2880 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2881 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2882 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2883 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2884 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2885 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2887 max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
2889 ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
2890 ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
2893 * Place all the devices on channels
2897 if (mpt_channel_mapping) {
2898 ioc->devices_per_bus = 1;
2899 ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
2905 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2907 * SendIocInit - Send IOCInit request to MPT adapter.
2908 * @ioc: Pointer to MPT_ADAPTER structure
2909 * @sleepFlag: Specifies whether the process can sleep
2911 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2913 * Returns 0 for success, non-zero for failure.
2916 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2919 MPIDefaultReply_t init_reply;
2925 memset(&ioc_init, 0, sizeof(ioc_init));
2926 memset(&init_reply, 0, sizeof(init_reply));
2928 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2929 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2931 /* If we are in a recovery mode and we uploaded the FW image,
2932 * then this pointer is not NULL. Skip the upload a second time.
2933 * Set this flag if cached_fw set for either IOC.
2935 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
2939 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "upload_fw %d facts.Flags=%x\n",
2940 ioc->name, ioc->upload_fw, ioc->facts.Flags));
2942 ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
2943 ioc_init.MaxBuses = (U8)ioc->number_of_buses;
2944 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n",
2945 ioc->name, ioc->facts.MsgVersion));
2946 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
2947 // set MsgVersion and HeaderVersion host driver was built with
2948 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
2949 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
2951 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
2952 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
2953 } else if(mpt_host_page_alloc(ioc, &ioc_init))
2956 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
2958 if (sizeof(dma_addr_t) == sizeof(u64)) {
2959 /* Save the upper 32-bits of the request
2960 * (reply) and sense buffers.
2962 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
2963 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2965 /* Force 32-bit addressing */
2966 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
2967 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
2970 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
2971 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
2972 ioc->facts.MaxDevices = ioc_init.MaxDevices;
2973 ioc->facts.MaxBuses = ioc_init.MaxBuses;
2975 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOCInit (req @ %p)\n",
2976 ioc->name, &ioc_init));
2978 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
2979 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
2981 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
2985 /* No need to byte swap the multibyte fields in the reply
2986 * since we don't even look at its contents.
2989 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending PortEnable (req @ %p)\n",
2990 ioc->name, &ioc_init));
2992 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
2993 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
2997 /* YIKES! SUPER IMPORTANT!!!
2998 * Poll IocState until _OPERATIONAL while IOC is doing
2999 * LoopInit and TargetDiscovery!
3002 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
3003 state = mpt_GetIocState(ioc, 1);
3004 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
3005 if (sleepFlag == CAN_SLEEP) {
3012 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
3013 ioc->name, (int)((count+5)/HZ));
3017 state = mpt_GetIocState(ioc, 1);
3020 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wait IOC_OPERATIONAL state (cnt=%d)\n",
3023 ioc->aen_event_read_flag=0;
3027 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3029 * SendPortEnable - Send PortEnable request to MPT adapter port.
3030 * @ioc: Pointer to MPT_ADAPTER structure
3031 * @portnum: Port number to enable
3032 * @sleepFlag: Specifies whether the process can sleep
3034 * Send PortEnable to bring IOC to OPERATIONAL state.
3036 * Returns 0 for success, non-zero for failure.
3039 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3041 PortEnable_t port_enable;
3042 MPIDefaultReply_t reply_buf;
3047 /* Destination... */
3048 reply_sz = sizeof(MPIDefaultReply_t);
3049 memset(&reply_buf, 0, reply_sz);
3051 req_sz = sizeof(PortEnable_t);
3052 memset(&port_enable, 0, req_sz);
3054 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
3055 port_enable.PortNumber = portnum;
3056 /* port_enable.ChainOffset = 0; */
3057 /* port_enable.MsgFlags = 0; */
3058 /* port_enable.MsgContext = 0; */
3060 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Port(%d)Enable (req @ %p)\n",
3061 ioc->name, portnum, &port_enable));
3063 /* RAID FW may take a long time to enable
3065 if (ioc->ir_firmware || ioc->bus_type == SAS) {
3066 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3067 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3068 300 /*seconds*/, sleepFlag);
3070 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3071 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3072 30 /*seconds*/, sleepFlag);
3078 * mpt_alloc_fw_memory - allocate firmware memory
3079 * @ioc: Pointer to MPT_ADAPTER structure
3080 * @size: total FW bytes
3082 * If memory has already been allocated, the same (cached) value
3085 * Return 0 if successfull, or non-zero for failure
3088 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
3092 if (ioc->cached_fw) {
3093 rc = 0; /* use already allocated memory */
3096 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
3097 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
3098 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
3102 ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma);
3103 if (!ioc->cached_fw) {
3104 printk(MYIOC_s_ERR_FMT "Unable to allocate memory for the cached firmware image!\n",
3108 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Image @ %p[%p], sz=%d[%x] bytes\n",
3109 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, size, size));
3110 ioc->alloc_total += size;
3118 * mpt_free_fw_memory - free firmware memory
3119 * @ioc: Pointer to MPT_ADAPTER structure
3121 * If alt_img is NULL, delete from ioc structure.
3122 * Else, delete a secondary image in same format.
3125 mpt_free_fw_memory(MPT_ADAPTER *ioc)
3129 if (!ioc->cached_fw)
3132 sz = ioc->facts.FWImageSize;
3133 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3134 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3135 pci_free_consistent(ioc->pcidev, sz, ioc->cached_fw, ioc->cached_fw_dma);
3136 ioc->alloc_total -= sz;
3137 ioc->cached_fw = NULL;
3140 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3142 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3143 * @ioc: Pointer to MPT_ADAPTER structure
3144 * @sleepFlag: Specifies whether the process can sleep
3146 * Returns 0 for success, >0 for handshake failure
3147 * <0 for fw upload failure.
3149 * Remark: If bound IOC and a successful FWUpload was performed
3150 * on the bound IOC, the second image is discarded
3151 * and memory is free'd. Both channels must upload to prevent
3152 * IOC from running in degraded mode.
3155 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3157 u8 reply[sizeof(FWUploadReply_t)];
3158 FWUpload_t *prequest;
3159 FWUploadReply_t *preply;
3160 FWUploadTCSGE_t *ptcsge;
3163 int ii, sz, reply_sz;
3166 /* If the image size is 0, we are done.
3168 if ((sz = ioc->facts.FWImageSize) == 0)
3171 if (mpt_alloc_fw_memory(ioc, ioc->facts.FWImageSize) != 0)
3174 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3175 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3177 prequest = (sleepFlag == NO_SLEEP) ? kzalloc(ioc->req_sz, GFP_ATOMIC) :
3178 kzalloc(ioc->req_sz, GFP_KERNEL);
3180 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed "
3181 "while allocating memory \n", ioc->name));
3182 mpt_free_fw_memory(ioc);
3186 preply = (FWUploadReply_t *)&reply;
3188 reply_sz = sizeof(reply);
3189 memset(preply, 0, reply_sz);
3191 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
3192 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
3194 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
3195 ptcsge->DetailsLength = 12;
3196 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
3197 ptcsge->ImageSize = cpu_to_le32(sz);
3200 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
3202 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3203 mpt_add_sge((char *)ptcsge, flagsLength, ioc->cached_fw_dma);
3205 sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
3206 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": Sending FW Upload (req @ %p) sgeoffset=%d \n",
3207 ioc->name, prequest, sgeoffset));
3208 DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest);
3210 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
3211 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
3213 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Upload completed rc=%x \n", ioc->name, ii));
3215 cmdStatus = -EFAULT;
3217 /* Handshake transfer was complete and successful.
3218 * Check the Reply Frame.
3220 int status, transfer_sz;
3221 status = le16_to_cpu(preply->IOCStatus);
3222 if (status == MPI_IOCSTATUS_SUCCESS) {
3223 transfer_sz = le32_to_cpu(preply->ActualImageSize);
3224 if (transfer_sz == sz)
3228 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n",
3229 ioc->name, cmdStatus));
3234 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": fw upload failed, freeing image \n",
3236 mpt_free_fw_memory(ioc);
3243 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3245 * mpt_downloadboot - DownloadBoot code
3246 * @ioc: Pointer to MPT_ADAPTER structure
3247 * @pFwHeader: Pointer to firmware header info
3248 * @sleepFlag: Specifies whether the process can sleep
3250 * FwDownloadBoot requires Programmed IO access.
3252 * Returns 0 for success
3253 * -1 FW Image size is 0
3254 * -2 No valid cached_fw Pointer
3255 * <0 for fw upload failure.
3258 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3260 MpiExtImageHeader_t *pExtImage;
3270 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3271 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
3273 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3274 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3275 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3276 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3277 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3278 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3280 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
3283 if (sleepFlag == CAN_SLEEP) {
3289 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3290 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3292 for (count = 0; count < 30; count ++) {
3293 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3294 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3295 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESET_ADAPTER cleared, count=%d\n",
3300 if (sleepFlag == CAN_SLEEP) {
3307 if ( count == 30 ) {
3308 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot failed! "
3309 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3310 ioc->name, diag0val));
3314 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3315 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3316 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3317 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3318 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3319 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3321 /* Set the DiagRwEn and Disable ARM bits */
3322 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3324 fwSize = (pFwHeader->ImageSize + 3)/4;
3325 ptrFw = (u32 *) pFwHeader;
3327 /* Write the LoadStartAddress to the DiagRw Address Register
3328 * using Programmed IO
3330 if (ioc->errata_flag_1064)
3331 pci_enable_io_access(ioc->pcidev);
3333 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3334 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "LoadStart addr written 0x%x \n",
3335 ioc->name, pFwHeader->LoadStartAddress));
3337 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write FW Image: 0x%x bytes @ %p\n",
3338 ioc->name, fwSize*4, ptrFw));
3340 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3343 nextImage = pFwHeader->NextImageHeaderOffset;
3345 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3347 load_addr = pExtImage->LoadStartAddress;
3349 fwSize = (pExtImage->ImageSize + 3) >> 2;
3350 ptrFw = (u32 *)pExtImage;
3352 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3353 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3354 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3357 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3359 nextImage = pExtImage->NextImageHeaderOffset;
3362 /* Write the IopResetVectorRegAddr */
3363 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
3364 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3366 /* Write the IopResetVectorValue */
3367 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3368 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3370 /* Clear the internal flash bad bit - autoincrementing register,
3371 * so must do two writes.
3373 if (ioc->bus_type == SPI) {
3375 * 1030 and 1035 H/W errata, workaround to access
3376 * the ClearFlashBadSignatureBit
3378 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3379 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3380 diagRwData |= 0x40000000;
3381 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3382 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3384 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3385 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3386 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3387 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3390 if (sleepFlag == CAN_SLEEP) {
3397 if (ioc->errata_flag_1064)
3398 pci_disable_io_access(ioc->pcidev);
3400 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3401 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot diag0val=%x, "
3402 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3403 ioc->name, diag0val));
3404 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3405 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot now diag0val=%x\n",
3406 ioc->name, diag0val));
3407 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3409 /* Write 0xFF to reset the sequencer */
3410 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3412 if (ioc->bus_type == SAS) {
3413 ioc_state = mpt_GetIocState(ioc, 0);
3414 if ( (GetIocFacts(ioc, sleepFlag,
3415 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3416 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "GetIocFacts failed: IocState=%x\n",
3417 ioc->name, ioc_state));
3422 for (count=0; count<HZ*20; count++) {
3423 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3424 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3425 "downloadboot successful! (count=%d) IocState=%x\n",
3426 ioc->name, count, ioc_state));
3427 if (ioc->bus_type == SAS) {
3430 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3431 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3432 "downloadboot: SendIocInit failed\n",
3436 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3437 "downloadboot: SendIocInit successful\n",
3441 if (sleepFlag == CAN_SLEEP) {
3447 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3448 "downloadboot failed! IocState=%x\n",ioc->name, ioc_state));
3452 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3454 * KickStart - Perform hard reset of MPT adapter.
3455 * @ioc: Pointer to MPT_ADAPTER structure
3456 * @force: Force hard reset
3457 * @sleepFlag: Specifies whether the process can sleep
3459 * This routine places MPT adapter in diagnostic mode via the
3460 * WriteSequence register, and then performs a hard reset of adapter
3461 * via the Diagnostic register.
3463 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3464 * or NO_SLEEP (interrupt thread, use mdelay)
3465 * force - 1 if doorbell active, board fault state
3466 * board operational, IOC_RECOVERY or
3467 * IOC_BRINGUP and there is an alt_ioc.
3471 * 1 - hard reset, READY
3472 * 0 - no reset due to History bit, READY
3473 * -1 - no reset due to History bit but not READY
3474 * OR reset but failed to come READY
3475 * -2 - no reset, could not enter DIAG mode
3476 * -3 - reset but bad FW bit
3479 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3481 int hard_reset_done = 0;
3485 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStarting!\n", ioc->name));
3486 if (ioc->bus_type == SPI) {
3487 /* Always issue a Msg Unit Reset first. This will clear some
3488 * SCSI bus hang conditions.
3490 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3492 if (sleepFlag == CAN_SLEEP) {
3499 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3500 if (hard_reset_done < 0)
3501 return hard_reset_done;
3503 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n",
3506 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3507 for (cnt=0; cnt<cntdn; cnt++) {
3508 ioc_state = mpt_GetIocState(ioc, 1);
3509 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3510 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStart successful! (cnt=%d)\n",
3512 return hard_reset_done;
3514 if (sleepFlag == CAN_SLEEP) {
3521 dinitprintk(ioc, printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3522 ioc->name, mpt_GetIocState(ioc, 0)));
3526 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3528 * mpt_diag_reset - Perform hard reset of the adapter.
3529 * @ioc: Pointer to MPT_ADAPTER structure
3530 * @ignore: Set if to honor and clear to ignore
3531 * the reset history bit
3532 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3533 * else set to NO_SLEEP (use mdelay instead)
3535 * This routine places the adapter in diagnostic mode via the
3536 * WriteSequence register and then performs a hard reset of adapter
3537 * via the Diagnostic register. Adapter should be in ready state
3538 * upon successful completion.
3540 * Returns: 1 hard reset successful
3541 * 0 no reset performed because reset history bit set
3542 * -2 enabling diagnostic mode failed
3543 * -3 diagnostic reset failed
3546 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3550 int hard_reset_done = 0;
3553 MpiFwHeader_t *cached_fw; /* Pointer to FW */
3555 /* Clear any existing interrupts */
3556 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3558 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3559 drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3560 "address=%p\n", ioc->name, __FUNCTION__,
3561 &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3562 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3563 if (sleepFlag == CAN_SLEEP)
3568 for (count = 0; count < 60; count ++) {
3569 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3570 doorbell &= MPI_IOC_STATE_MASK;
3572 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3573 "looking for READY STATE: doorbell=%x"
3575 ioc->name, doorbell, count));
3576 if (doorbell == MPI_IOC_STATE_READY) {
3581 if (sleepFlag == CAN_SLEEP)
3589 /* Use "Diagnostic reset" method! (only thing available!) */
3590 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3592 if (ioc->debug_level & MPT_DEBUG) {
3594 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3595 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3596 ioc->name, diag0val, diag1val));
3599 /* Do the reset if we are told to ignore the reset history
3600 * or if the reset history is 0
3602 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3603 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3604 /* Write magic sequence to WriteSequence register
3605 * Loop until in diagnostic mode
3607 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3608 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3609 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3610 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3611 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3612 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3615 if (sleepFlag == CAN_SLEEP) {
3623 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3624 ioc->name, diag0val);
3629 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3631 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3632 ioc->name, diag0val));
3635 if (ioc->debug_level & MPT_DEBUG) {
3637 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3638 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3639 ioc->name, diag0val, diag1val));
3642 * Disable the ARM (Bug fix)
3645 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3649 * Now hit the reset bit in the Diagnostic register
3650 * (THE BIG HAMMER!) (Clears DRWE bit).
3652 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3653 hard_reset_done = 1;
3654 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset performed\n",
3658 * Call each currently registered protocol IOC reset handler
3659 * with pre-reset indication.
3660 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3661 * MptResetHandlers[] registered yet.
3667 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
3668 if (MptResetHandlers[cb_idx]) {
3669 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3670 "Calling IOC pre_reset handler #%d\n",
3671 ioc->name, cb_idx));
3672 r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET);
3674 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3675 "Calling alt-%s pre_reset handler #%d\n",
3676 ioc->name, ioc->alt_ioc->name, cb_idx));
3677 r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_PRE_RESET);
3681 /* FIXME? Examine results here? */
3685 cached_fw = (MpiFwHeader_t *)ioc->cached_fw;
3686 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
3687 cached_fw = (MpiFwHeader_t *)ioc->alt_ioc->cached_fw;
3691 /* If the DownloadBoot operation fails, the
3692 * IOC will be left unusable. This is a fatal error
3693 * case. _diag_reset will return < 0
3695 for (count = 0; count < 30; count ++) {
3696 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3697 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3701 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n",
3702 ioc->name, diag0val, count));
3704 if (sleepFlag == CAN_SLEEP) {
3710 if ((count = mpt_downloadboot(ioc, cached_fw, sleepFlag)) < 0) {
3711 printk(MYIOC_s_WARN_FMT
3712 "firmware downloadboot failure (%d)!\n", ioc->name, count);
3716 /* Wait for FW to reload and for board
3717 * to go to the READY state.
3718 * Maximum wait is 60 seconds.
3719 * If fail, no error will check again
3720 * with calling program.
3722 for (count = 0; count < 60; count ++) {
3723 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3724 doorbell &= MPI_IOC_STATE_MASK;
3726 if (doorbell == MPI_IOC_STATE_READY) {
3731 if (sleepFlag == CAN_SLEEP) {
3740 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3741 if (ioc->debug_level & MPT_DEBUG) {
3743 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3744 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3745 ioc->name, diag0val, diag1val));
3748 /* Clear RESET_HISTORY bit! Place board in the
3749 * diagnostic mode to update the diag register.
3751 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3753 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3754 /* Write magic sequence to WriteSequence register
3755 * Loop until in diagnostic mode
3757 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3758 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3759 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3760 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3761 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3762 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3765 if (sleepFlag == CAN_SLEEP) {
3773 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3774 ioc->name, diag0val);
3777 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3779 diag0val &= ~MPI_DIAG_RESET_HISTORY;
3780 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3781 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3782 if (diag0val & MPI_DIAG_RESET_HISTORY) {
3783 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3787 /* Disable Diagnostic Mode
3789 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3791 /* Check FW reload status flags.
3793 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3794 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3795 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3796 ioc->name, diag0val);
3800 if (ioc->debug_level & MPT_DEBUG) {
3802 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3803 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3804 ioc->name, diag0val, diag1val));
3808 * Reset flag that says we've enabled event notification
3810 ioc->facts.EventState = 0;
3813 ioc->alt_ioc->facts.EventState = 0;
3815 return hard_reset_done;
3818 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3820 * SendIocReset - Send IOCReset request to MPT adapter.
3821 * @ioc: Pointer to MPT_ADAPTER structure
3822 * @reset_type: reset type, expected values are
3823 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3824 * @sleepFlag: Specifies whether the process can sleep
3826 * Send IOCReset request to the MPT adapter.
3828 * Returns 0 for success, non-zero for failure.
3831 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3837 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOC reset(0x%02x)!\n",
3838 ioc->name, reset_type));
3839 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3840 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3843 /* FW ACK'd request, wait for READY state
3846 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
3848 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3852 if (sleepFlag != CAN_SLEEP)
3855 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
3856 ioc->name, (int)((count+5)/HZ));
3860 if (sleepFlag == CAN_SLEEP) {
3863 mdelay (1); /* 1 msec delay */
3868 * Cleanup all event stuff for this IOC; re-issue EventNotification
3869 * request if needed.
3871 if (ioc->facts.Function)
3872 ioc->facts.EventState = 0;
3877 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3879 * initChainBuffers - Allocate memory for and initialize chain buffers
3880 * @ioc: Pointer to MPT_ADAPTER structure
3882 * Allocates memory for and initializes chain buffers,
3883 * chain buffer control arrays and spinlock.
3886 initChainBuffers(MPT_ADAPTER *ioc)
3889 int sz, ii, num_chain;
3890 int scale, num_sge, numSGE;
3892 /* ReqToChain size must equal the req_depth
3895 if (ioc->ReqToChain == NULL) {
3896 sz = ioc->req_depth * sizeof(int);
3897 mem = kmalloc(sz, GFP_ATOMIC);
3901 ioc->ReqToChain = (int *) mem;
3902 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReqToChain alloc @ %p, sz=%d bytes\n",
3903 ioc->name, mem, sz));
3904 mem = kmalloc(sz, GFP_ATOMIC);
3908 ioc->RequestNB = (int *) mem;
3909 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestNB alloc @ %p, sz=%d bytes\n",
3910 ioc->name, mem, sz));
3912 for (ii = 0; ii < ioc->req_depth; ii++) {
3913 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
3916 /* ChainToChain size must equal the total number
3917 * of chain buffers to be allocated.
3920 * Calculate the number of chain buffers needed(plus 1) per I/O
3921 * then multiply the maximum number of simultaneous cmds
3923 * num_sge = num sge in request frame + last chain buffer
3924 * scale = num sge per chain buffer if no chain element
3926 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3927 if (sizeof(dma_addr_t) == sizeof(u64))
3928 num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3930 num_sge = 1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3932 if (sizeof(dma_addr_t) == sizeof(u64)) {
3933 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3934 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3936 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3937 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3939 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n",
3940 ioc->name, num_sge, numSGE));
3942 if ( numSGE > MPT_SCSI_SG_DEPTH )
3943 numSGE = MPT_SCSI_SG_DEPTH;
3946 while (numSGE - num_sge > 0) {
3948 num_sge += (scale - 1);
3952 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Now numSGE=%d num_sge=%d num_chain=%d\n",
3953 ioc->name, numSGE, num_sge, num_chain));
3955 if (ioc->bus_type == SPI)
3956 num_chain *= MPT_SCSI_CAN_QUEUE;
3958 num_chain *= MPT_FC_CAN_QUEUE;
3960 ioc->num_chain = num_chain;
3962 sz = num_chain * sizeof(int);
3963 if (ioc->ChainToChain == NULL) {
3964 mem = kmalloc(sz, GFP_ATOMIC);
3968 ioc->ChainToChain = (int *) mem;
3969 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainToChain alloc @ %p, sz=%d bytes\n",
3970 ioc->name, mem, sz));
3972 mem = (u8 *) ioc->ChainToChain;
3974 memset(mem, 0xFF, sz);
3978 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3980 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
3981 * @ioc: Pointer to MPT_ADAPTER structure
3983 * This routine allocates memory for the MPT reply and request frame
3984 * pools (if necessary), and primes the IOC reply FIFO with
3987 * Returns 0 for success, non-zero for failure.
3990 PrimeIocFifos(MPT_ADAPTER *ioc)
3993 unsigned long flags;
3994 dma_addr_t alloc_dma;
3996 int i, reply_sz, sz, total_size, num_chain;
3998 /* Prime reply FIFO... */
4000 if (ioc->reply_frames == NULL) {
4001 if ( (num_chain = initChainBuffers(ioc)) < 0)
4004 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
4005 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
4006 ioc->name, ioc->reply_sz, ioc->reply_depth));
4007 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d[%x] bytes\n",
4008 ioc->name, reply_sz, reply_sz));
4010 sz = (ioc->req_sz * ioc->req_depth);
4011 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d bytes, RequestDepth=%d\n",
4012 ioc->name, ioc->req_sz, ioc->req_depth));
4013 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d[%x] bytes\n",
4014 ioc->name, sz, sz));
4017 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
4018 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d bytes, ChainDepth=%d\n",
4019 ioc->name, ioc->req_sz, num_chain));
4020 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
4021 ioc->name, sz, sz, num_chain));
4024 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
4026 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
4031 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Total alloc @ %p[%p], sz=%d[%x] bytes\n",
4032 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
4034 memset(mem, 0, total_size);
4035 ioc->alloc_total += total_size;
4037 ioc->alloc_dma = alloc_dma;
4038 ioc->alloc_sz = total_size;
4039 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
4040 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4042 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4043 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4045 alloc_dma += reply_sz;
4048 /* Request FIFO - WE manage this! */
4050 ioc->req_frames = (MPT_FRAME_HDR *) mem;
4051 ioc->req_frames_dma = alloc_dma;
4053 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffers @ %p[%p]\n",
4054 ioc->name, mem, (void *)(ulong)alloc_dma));
4056 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4058 #if defined(CONFIG_MTRR) && 0
4060 * Enable Write Combining MTRR for IOC's memory region.
4061 * (at least as much as we can; "size and base must be
4062 * multiples of 4 kiB"
4064 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
4066 MTRR_TYPE_WRCOMB, 1);
4067 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MTRR region registered (base:size=%08x:%x)\n",
4068 ioc->name, ioc->req_frames_dma, sz));
4071 for (i = 0; i < ioc->req_depth; i++) {
4072 alloc_dma += ioc->req_sz;
4076 ioc->ChainBuffer = mem;
4077 ioc->ChainBufferDMA = alloc_dma;
4079 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffers @ %p(%p)\n",
4080 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
4082 /* Initialize the free chain Q.
4085 INIT_LIST_HEAD(&ioc->FreeChainQ);
4087 /* Post the chain buffers to the FreeChainQ.
4089 mem = (u8 *)ioc->ChainBuffer;
4090 for (i=0; i < num_chain; i++) {
4091 mf = (MPT_FRAME_HDR *) mem;
4092 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
4096 /* Initialize Request frames linked list
4098 alloc_dma = ioc->req_frames_dma;
4099 mem = (u8 *) ioc->req_frames;
4101 spin_lock_irqsave(&ioc->FreeQlock, flags);
4102 INIT_LIST_HEAD(&ioc->FreeQ);
4103 for (i = 0; i < ioc->req_depth; i++) {
4104 mf = (MPT_FRAME_HDR *) mem;
4106 /* Queue REQUESTs *internally*! */
4107 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
4111 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4113 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4114 ioc->sense_buf_pool =
4115 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
4116 if (ioc->sense_buf_pool == NULL) {
4117 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
4122 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
4123 ioc->alloc_total += sz;
4124 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SenseBuffers @ %p[%p]\n",
4125 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
4129 /* Post Reply frames to FIFO
4131 alloc_dma = ioc->alloc_dma;
4132 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4133 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4135 for (i = 0; i < ioc->reply_depth; i++) {
4136 /* Write each address to the IOC! */
4137 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
4138 alloc_dma += ioc->reply_sz;
4144 if (ioc->alloc != NULL) {
4146 pci_free_consistent(ioc->pcidev,
4148 ioc->alloc, ioc->alloc_dma);
4149 ioc->reply_frames = NULL;
4150 ioc->req_frames = NULL;
4151 ioc->alloc_total -= sz;
4153 if (ioc->sense_buf_pool != NULL) {
4154 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4155 pci_free_consistent(ioc->pcidev,
4157 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
4158 ioc->sense_buf_pool = NULL;
4163 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4165 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4166 * from IOC via doorbell handshake method.
4167 * @ioc: Pointer to MPT_ADAPTER structure
4168 * @reqBytes: Size of the request in bytes
4169 * @req: Pointer to MPT request frame
4170 * @replyBytes: Expected size of the reply in bytes
4171 * @u16reply: Pointer to area where reply should be written
4172 * @maxwait: Max wait time for a reply (in seconds)
4173 * @sleepFlag: Specifies whether the process can sleep
4175 * NOTES: It is the callers responsibility to byte-swap fields in the
4176 * request which are greater than 1 byte in size. It is also the
4177 * callers responsibility to byte-swap response fields which are
4178 * greater than 1 byte in size.
4180 * Returns 0 for success, non-zero for failure.
4183 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
4184 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
4186 MPIDefaultReply_t *mptReply;
4191 * Get ready to cache a handshake reply
4193 ioc->hs_reply_idx = 0;
4194 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4195 mptReply->MsgLength = 0;
4198 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4199 * then tell IOC that we want to handshake a request of N words.
4200 * (WRITE u32val to Doorbell reg).
4202 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4203 CHIPREG_WRITE32(&ioc->chip->Doorbell,
4204 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
4205 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
4208 * Wait for IOC's doorbell handshake int
4210 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4213 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4214 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4216 /* Read doorbell and check for active bit */
4217 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
4221 * Clear doorbell int (WRITE 0 to IntStatus reg),
4222 * then wait for IOC to ACKnowledge that it's ready for
4223 * our handshake request.
4225 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4226 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4231 u8 *req_as_bytes = (u8 *) req;
4234 * Stuff request words via doorbell handshake,
4235 * with ACK from IOC for each.
4237 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
4238 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
4239 (req_as_bytes[(ii*4) + 1] << 8) |
4240 (req_as_bytes[(ii*4) + 2] << 16) |
4241 (req_as_bytes[(ii*4) + 3] << 24));
4243 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
4244 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4248 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req));
4249 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req);
4251 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n",
4252 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
4255 * Wait for completion of doorbell handshake reply from the IOC
4257 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
4260 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake reply count=%d%s\n",
4261 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
4264 * Copy out the cached reply...
4266 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
4267 u16reply[ii] = ioc->hs_reply[ii];
4275 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4277 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4278 * @ioc: Pointer to MPT_ADAPTER structure
4279 * @howlong: How long to wait (in seconds)
4280 * @sleepFlag: Specifies whether the process can sleep
4282 * This routine waits (up to ~2 seconds max) for IOC doorbell
4283 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4284 * bit in its IntStatus register being clear.
4286 * Returns a negative value on failure, else wait loop count.
4289 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4295 cntdn = 1000 * howlong;
4297 if (sleepFlag == CAN_SLEEP) {
4300 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4301 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4308 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4309 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4316 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell ACK (count=%d)\n",
4321 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4322 ioc->name, count, intstat);
4326 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4328 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4329 * @ioc: Pointer to MPT_ADAPTER structure
4330 * @howlong: How long to wait (in seconds)
4331 * @sleepFlag: Specifies whether the process can sleep
4333 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4334 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4336 * Returns a negative value on failure, else wait loop count.
4339 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4345 cntdn = 1000 * howlong;
4346 if (sleepFlag == CAN_SLEEP) {
4348 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4349 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4356 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4357 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4365 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4366 ioc->name, count, howlong));
4370 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4371 ioc->name, count, intstat);
4375 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4377 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
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 polls the IOC for a handshake reply, 16 bits at a time.
4383 * Reply is cached to IOC private area large enough to hold a maximum
4384 * of 128 bytes of reply data.
4386 * Returns a negative value on failure, else size of reply in WORDS.
4389 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4394 u16 *hs_reply = ioc->hs_reply;
4395 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4398 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4401 * Get first two u16's so we can look at IOC's intended reply MsgLength
4404 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4407 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4408 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4409 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4412 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4413 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4417 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4418 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4419 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4422 * If no error (and IOC said MsgLength is > 0), piece together
4423 * reply 16 bits at a time.
4425 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4426 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4428 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4429 /* don't overflow our IOC hs_reply[] buffer! */
4430 if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
4431 hs_reply[u16cnt] = hword;
4432 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4435 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4437 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4440 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4445 else if (u16cnt != (2 * mptReply->MsgLength)) {
4448 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4453 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name));
4454 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply);
4456 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4457 ioc->name, t, u16cnt/2));
4461 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4463 * GetLanConfigPages - Fetch LANConfig pages.
4464 * @ioc: Pointer to MPT_ADAPTER structure
4466 * Return: 0 for success
4467 * -ENOMEM if no memory available
4468 * -EPERM if not allowed due to ISR context
4469 * -EAGAIN if no msg frames currently available
4470 * -EFAULT for non-successful reply or no reply (timeout)
4473 GetLanConfigPages(MPT_ADAPTER *ioc)
4475 ConfigPageHeader_t hdr;
4477 LANPage0_t *ppage0_alloc;
4478 dma_addr_t page0_dma;
4479 LANPage1_t *ppage1_alloc;
4480 dma_addr_t page1_dma;
4485 /* Get LAN Page 0 header */
4486 hdr.PageVersion = 0;
4489 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4490 cfg.cfghdr.hdr = &hdr;
4492 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4497 if ((rc = mpt_config(ioc, &cfg)) != 0)
4500 if (hdr.PageLength > 0) {
4501 data_sz = hdr.PageLength * 4;
4502 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4505 memset((u8 *)ppage0_alloc, 0, data_sz);
4506 cfg.physAddr = page0_dma;
4507 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4509 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4511 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4512 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4516 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4519 * Normalize endianness of structure data,
4520 * by byte-swapping all > 1 byte fields!
4529 /* Get LAN Page 1 header */
4530 hdr.PageVersion = 0;
4533 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4534 cfg.cfghdr.hdr = &hdr;
4536 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4540 if ((rc = mpt_config(ioc, &cfg)) != 0)
4543 if (hdr.PageLength == 0)
4546 data_sz = hdr.PageLength * 4;
4548 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4550 memset((u8 *)ppage1_alloc, 0, data_sz);
4551 cfg.physAddr = page1_dma;
4552 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4554 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4556 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4557 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4560 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4563 * Normalize endianness of structure data,
4564 * by byte-swapping all > 1 byte fields!
4572 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4574 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
4575 * @ioc: Pointer to MPT_ADAPTER structure
4576 * @persist_opcode: see below
4578 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4579 * devices not currently present.
4580 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4582 * NOTE: Don't use not this function during interrupt time.
4584 * Returns 0 for success, non-zero error
4587 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4589 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4591 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
4592 SasIoUnitControlReply_t *sasIoUnitCntrReply;
4593 MPT_FRAME_HDR *mf = NULL;
4594 MPIHeader_t *mpi_hdr;
4597 /* insure garbage is not sent to fw */
4598 switch(persist_opcode) {
4600 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
4601 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
4609 printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode);
4611 /* Get a MF for this command.
4613 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4614 printk("%s: no msg frames!\n",__FUNCTION__);
4618 mpi_hdr = (MPIHeader_t *) mf;
4619 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
4620 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
4621 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
4622 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
4623 sasIoUnitCntrReq->Operation = persist_opcode;
4625 init_timer(&ioc->persist_timer);
4626 ioc->persist_timer.data = (unsigned long) ioc;
4627 ioc->persist_timer.function = mpt_timer_expired;
4628 ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
4629 ioc->persist_wait_done=0;
4630 add_timer(&ioc->persist_timer);
4631 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4632 wait_event(mpt_waitq, ioc->persist_wait_done);
4634 sasIoUnitCntrReply =
4635 (SasIoUnitControlReply_t *)ioc->persist_reply_frame;
4636 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
4637 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4639 sasIoUnitCntrReply->IOCStatus,
4640 sasIoUnitCntrReply->IOCLogInfo);
4644 printk("%s: success\n",__FUNCTION__);
4648 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4651 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
4652 MpiEventDataRaid_t * pRaidEventData)
4661 volume = pRaidEventData->VolumeID;
4662 reason = pRaidEventData->ReasonCode;
4663 disk = pRaidEventData->PhysDiskNum;
4664 status = le32_to_cpu(pRaidEventData->SettingsStatus);
4665 flags = (status >> 0) & 0xff;
4666 state = (status >> 8) & 0xff;
4668 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
4672 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
4673 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
4674 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
4675 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
4676 ioc->name, disk, volume);
4678 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
4683 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4684 printk(MYIOC_s_INFO_FMT " volume has been created\n",
4688 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4690 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
4694 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
4695 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
4699 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4700 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
4702 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
4704 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
4706 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
4709 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
4711 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
4712 ? ", quiesced" : "",
4713 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
4714 ? ", resync in progress" : "" );
4717 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
4718 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
4722 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4723 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
4727 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4728 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
4732 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
4733 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
4737 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4738 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
4740 state == MPI_PHYSDISK0_STATUS_ONLINE
4742 : state == MPI_PHYSDISK0_STATUS_MISSING
4744 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
4746 : state == MPI_PHYSDISK0_STATUS_FAILED
4748 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
4750 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
4751 ? "offline requested"
4752 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
4753 ? "failed requested"
4754 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
4757 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
4758 ? ", out of sync" : "",
4759 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
4760 ? ", quiesced" : "" );
4763 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
4764 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
4768 case MPI_EVENT_RAID_RC_SMART_DATA:
4769 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
4770 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
4773 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
4774 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
4780 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4782 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4783 * @ioc: Pointer to MPT_ADAPTER structure
4785 * Returns: 0 for success
4786 * -ENOMEM if no memory available
4787 * -EPERM if not allowed due to ISR context
4788 * -EAGAIN if no msg frames currently available
4789 * -EFAULT for non-successful reply or no reply (timeout)
4792 GetIoUnitPage2(MPT_ADAPTER *ioc)
4794 ConfigPageHeader_t hdr;
4796 IOUnitPage2_t *ppage_alloc;
4797 dma_addr_t page_dma;
4801 /* Get the page header */
4802 hdr.PageVersion = 0;
4805 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4806 cfg.cfghdr.hdr = &hdr;
4808 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4813 if ((rc = mpt_config(ioc, &cfg)) != 0)
4816 if (hdr.PageLength == 0)
4819 /* Read the config page */
4820 data_sz = hdr.PageLength * 4;
4822 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4824 memset((u8 *)ppage_alloc, 0, data_sz);
4825 cfg.physAddr = page_dma;
4826 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4828 /* If Good, save data */
4829 if ((rc = mpt_config(ioc, &cfg)) == 0)
4830 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4832 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4838 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4840 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4841 * @ioc: Pointer to a Adapter Strucutre
4842 * @portnum: IOC port number
4844 * Return: -EFAULT if read of config page header fails
4846 * If read of SCSI Port Page 0 fails,
4847 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4848 * Adapter settings: async, narrow
4850 * If read of SCSI Port Page 2 fails,
4851 * Adapter settings valid
4852 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4857 * CHECK - what type of locking mechanisms should be used????
4860 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4865 ConfigPageHeader_t header;
4871 if (!ioc->spi_data.nvram) {
4874 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4875 mem = kmalloc(sz, GFP_ATOMIC);
4879 ioc->spi_data.nvram = (int *) mem;
4881 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4882 ioc->name, ioc->spi_data.nvram, sz));
4885 /* Invalidate NVRAM information
4887 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4888 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4891 /* Read SPP0 header, allocate memory, then read page.
4893 header.PageVersion = 0;
4894 header.PageLength = 0;
4895 header.PageNumber = 0;
4896 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4897 cfg.cfghdr.hdr = &header;
4899 cfg.pageAddr = portnum;
4900 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4902 cfg.timeout = 0; /* use default */
4903 if (mpt_config(ioc, &cfg) != 0)
4906 if (header.PageLength > 0) {
4907 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4909 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4910 cfg.physAddr = buf_dma;
4911 if (mpt_config(ioc, &cfg) != 0) {
4912 ioc->spi_data.maxBusWidth = MPT_NARROW;
4913 ioc->spi_data.maxSyncOffset = 0;
4914 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4915 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4917 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4918 "Unable to read PortPage0 minSyncFactor=%x\n",
4919 ioc->name, ioc->spi_data.minSyncFactor));
4921 /* Save the Port Page 0 data
4923 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
4924 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4925 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4927 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
4928 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4929 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4930 "noQas due to Capabilities=%x\n",
4931 ioc->name, pPP0->Capabilities));
4933 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4934 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4936 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4937 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4938 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4939 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4940 "PortPage0 minSyncFactor=%x\n",
4941 ioc->name, ioc->spi_data.minSyncFactor));
4943 ioc->spi_data.maxSyncOffset = 0;
4944 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4947 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4949 /* Update the minSyncFactor based on bus type.
4951 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4952 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
4954 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
4955 ioc->spi_data.minSyncFactor = MPT_ULTRA;
4956 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4957 "HVD or SE detected, minSyncFactor=%x\n",
4958 ioc->name, ioc->spi_data.minSyncFactor));
4963 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4968 /* SCSI Port Page 2 - Read the header then the page.
4970 header.PageVersion = 0;
4971 header.PageLength = 0;
4972 header.PageNumber = 2;
4973 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4974 cfg.cfghdr.hdr = &header;
4976 cfg.pageAddr = portnum;
4977 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4979 if (mpt_config(ioc, &cfg) != 0)
4982 if (header.PageLength > 0) {
4983 /* Allocate memory and read SCSI Port Page 2
4985 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4987 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
4988 cfg.physAddr = buf_dma;
4989 if (mpt_config(ioc, &cfg) != 0) {
4990 /* Nvram data is left with INVALID mark
4993 } else if (ioc->pcidev->vendor == PCI_VENDOR_ID_ATTO) {
4995 /* This is an ATTO adapter, read Page2 accordingly
4997 ATTO_SCSIPortPage2_t *pPP2 = (ATTO_SCSIPortPage2_t *) pbuf;
4998 ATTODeviceInfo_t *pdevice = NULL;
5001 /* Save the Port Page 2 data
5002 * (reformat into a 32bit quantity)
5004 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5005 pdevice = &pPP2->DeviceSettings[ii];
5006 ATTOFlags = le16_to_cpu(pdevice->ATTOFlags);
5009 /* Translate ATTO device flags to LSI format
5011 if (ATTOFlags & ATTOFLAG_DISC)
5012 data |= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE);
5013 if (ATTOFlags & ATTOFLAG_ID_ENB)
5014 data |= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE);
5015 if (ATTOFlags & ATTOFLAG_LUN_ENB)
5016 data |= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE);
5017 if (ATTOFlags & ATTOFLAG_TAGGED)
5018 data |= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE);
5019 if (!(ATTOFlags & ATTOFLAG_WIDE_ENB))
5020 data |= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE);
5022 data = (data << 16) | (pdevice->Period << 8) | 10;
5023 ioc->spi_data.nvram[ii] = data;
5026 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
5027 MpiDeviceInfo_t *pdevice = NULL;
5030 * Save "Set to Avoid SCSI Bus Resets" flag
5032 ioc->spi_data.bus_reset =
5033 (le32_to_cpu(pPP2->PortFlags) &
5034 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
5037 /* Save the Port Page 2 data
5038 * (reformat into a 32bit quantity)
5040 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
5041 ioc->spi_data.PortFlags = data;
5042 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5043 pdevice = &pPP2->DeviceSettings[ii];
5044 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
5045 (pdevice->SyncFactor << 8) | pdevice->Timeout;
5046 ioc->spi_data.nvram[ii] = data;
5050 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5054 /* Update Adapter limits with those from NVRAM
5055 * Comment: Don't need to do this. Target performance
5056 * parameters will never exceed the adapters limits.
5062 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5064 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
5065 * @ioc: Pointer to a Adapter Strucutre
5066 * @portnum: IOC port number
5068 * Return: -EFAULT if read of config page header fails
5072 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
5075 ConfigPageHeader_t header;
5077 /* Read the SCSI Device Page 1 header
5079 header.PageVersion = 0;
5080 header.PageLength = 0;
5081 header.PageNumber = 1;
5082 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5083 cfg.cfghdr.hdr = &header;
5085 cfg.pageAddr = portnum;
5086 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5089 if (mpt_config(ioc, &cfg) != 0)
5092 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
5093 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
5095 header.PageVersion = 0;
5096 header.PageLength = 0;
5097 header.PageNumber = 0;
5098 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5099 if (mpt_config(ioc, &cfg) != 0)
5102 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
5103 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
5105 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 0: version %d length %d\n",
5106 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
5108 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 1: version %d length %d\n",
5109 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
5114 * mpt_inactive_raid_list_free - This clears this link list.
5115 * @ioc : pointer to per adapter structure
5118 mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
5120 struct inactive_raid_component_info *component_info, *pNext;
5122 if (list_empty(&ioc->raid_data.inactive_list))
5125 down(&ioc->raid_data.inactive_list_mutex);
5126 list_for_each_entry_safe(component_info, pNext,
5127 &ioc->raid_data.inactive_list, list) {
5128 list_del(&component_info->list);
5129 kfree(component_info);
5131 up(&ioc->raid_data.inactive_list_mutex);
5135 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5137 * @ioc : pointer to per adapter structure
5138 * @channel : volume channel
5139 * @id : volume target id
5142 mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
5145 ConfigPageHeader_t hdr;
5146 dma_addr_t dma_handle;
5147 pRaidVolumePage0_t buffer = NULL;
5149 RaidPhysDiskPage0_t phys_disk;
5150 struct inactive_raid_component_info *component_info;
5151 int handle_inactive_volumes;
5153 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5154 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5155 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
5156 cfg.pageAddr = (channel << 8) + id;
5157 cfg.cfghdr.hdr = &hdr;
5158 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5160 if (mpt_config(ioc, &cfg) != 0)
5163 if (!hdr.PageLength)
5166 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5172 cfg.physAddr = dma_handle;
5173 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5175 if (mpt_config(ioc, &cfg) != 0)
5178 if (!buffer->NumPhysDisks)
5181 handle_inactive_volumes =
5182 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
5183 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
5184 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
5185 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
5187 if (!handle_inactive_volumes)
5190 down(&ioc->raid_data.inactive_list_mutex);
5191 for (i = 0; i < buffer->NumPhysDisks; i++) {
5192 if(mpt_raid_phys_disk_pg0(ioc,
5193 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
5196 if ((component_info = kmalloc(sizeof (*component_info),
5197 GFP_KERNEL)) == NULL)
5200 component_info->volumeID = id;
5201 component_info->volumeBus = channel;
5202 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
5203 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
5204 component_info->d.PhysDiskID = phys_disk.PhysDiskID;
5205 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
5207 list_add_tail(&component_info->list,
5208 &ioc->raid_data.inactive_list);
5210 up(&ioc->raid_data.inactive_list_mutex);
5214 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5219 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5220 * @ioc: Pointer to a Adapter Structure
5221 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5222 * @phys_disk: requested payload data returned
5226 * -EFAULT if read of config page header fails or data pointer not NULL
5227 * -ENOMEM if pci_alloc failed
5230 mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk)
5233 ConfigPageHeader_t hdr;
5234 dma_addr_t dma_handle;
5235 pRaidPhysDiskPage0_t buffer = NULL;
5238 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5239 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5241 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5242 cfg.cfghdr.hdr = &hdr;
5244 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5246 if (mpt_config(ioc, &cfg) != 0) {
5251 if (!hdr.PageLength) {
5256 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5264 cfg.physAddr = dma_handle;
5265 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5266 cfg.pageAddr = phys_disk_num;
5268 if (mpt_config(ioc, &cfg) != 0) {
5274 memcpy(phys_disk, buffer, sizeof(*buffer));
5275 phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
5280 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5287 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5288 * @ioc: Pointer to a Adapter Strucutre
5289 * @portnum: IOC port number
5293 * -EFAULT if read of config page header fails or data pointer not NULL
5294 * -ENOMEM if pci_alloc failed
5297 mpt_findImVolumes(MPT_ADAPTER *ioc)
5301 dma_addr_t ioc2_dma;
5303 ConfigPageHeader_t header;
5308 if (!ioc->ir_firmware)
5311 /* Free the old page
5313 kfree(ioc->raid_data.pIocPg2);
5314 ioc->raid_data.pIocPg2 = NULL;
5315 mpt_inactive_raid_list_free(ioc);
5317 /* Read IOCP2 header then the page.
5319 header.PageVersion = 0;
5320 header.PageLength = 0;
5321 header.PageNumber = 2;
5322 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5323 cfg.cfghdr.hdr = &header;
5326 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5329 if (mpt_config(ioc, &cfg) != 0)
5332 if (header.PageLength == 0)
5335 iocpage2sz = header.PageLength * 4;
5336 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
5340 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5341 cfg.physAddr = ioc2_dma;
5342 if (mpt_config(ioc, &cfg) != 0)
5345 mem = kmalloc(iocpage2sz, GFP_KERNEL);
5349 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
5350 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
5352 mpt_read_ioc_pg_3(ioc);
5354 for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
5355 mpt_inactive_raid_volumes(ioc,
5356 pIoc2->RaidVolume[i].VolumeBus,
5357 pIoc2->RaidVolume[i].VolumeID);
5360 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
5366 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
5371 ConfigPageHeader_t header;
5372 dma_addr_t ioc3_dma;
5375 /* Free the old page
5377 kfree(ioc->raid_data.pIocPg3);
5378 ioc->raid_data.pIocPg3 = NULL;
5380 /* There is at least one physical disk.
5381 * Read and save IOC Page 3
5383 header.PageVersion = 0;
5384 header.PageLength = 0;
5385 header.PageNumber = 3;
5386 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5387 cfg.cfghdr.hdr = &header;
5390 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5393 if (mpt_config(ioc, &cfg) != 0)
5396 if (header.PageLength == 0)
5399 /* Read Header good, alloc memory
5401 iocpage3sz = header.PageLength * 4;
5402 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
5406 /* Read the Page and save the data
5407 * into malloc'd memory.
5409 cfg.physAddr = ioc3_dma;
5410 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5411 if (mpt_config(ioc, &cfg) == 0) {
5412 mem = kmalloc(iocpage3sz, GFP_KERNEL);
5414 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
5415 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
5419 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
5425 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
5429 ConfigPageHeader_t header;
5430 dma_addr_t ioc4_dma;
5433 /* Read and save IOC Page 4
5435 header.PageVersion = 0;
5436 header.PageLength = 0;
5437 header.PageNumber = 4;
5438 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5439 cfg.cfghdr.hdr = &header;
5442 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5445 if (mpt_config(ioc, &cfg) != 0)
5448 if (header.PageLength == 0)
5451 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
5452 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
5453 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
5456 ioc->alloc_total += iocpage4sz;
5458 ioc4_dma = ioc->spi_data.IocPg4_dma;
5459 iocpage4sz = ioc->spi_data.IocPg4Sz;
5462 /* Read the Page into dma memory.
5464 cfg.physAddr = ioc4_dma;
5465 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5466 if (mpt_config(ioc, &cfg) == 0) {
5467 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
5468 ioc->spi_data.IocPg4_dma = ioc4_dma;
5469 ioc->spi_data.IocPg4Sz = iocpage4sz;
5471 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
5472 ioc->spi_data.pIocPg4 = NULL;
5473 ioc->alloc_total -= iocpage4sz;
5478 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
5482 ConfigPageHeader_t header;
5483 dma_addr_t ioc1_dma;
5487 /* Check the Coalescing Timeout in IOC Page 1
5489 header.PageVersion = 0;
5490 header.PageLength = 0;
5491 header.PageNumber = 1;
5492 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5493 cfg.cfghdr.hdr = &header;
5496 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5499 if (mpt_config(ioc, &cfg) != 0)
5502 if (header.PageLength == 0)
5505 /* Read Header good, alloc memory
5507 iocpage1sz = header.PageLength * 4;
5508 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
5512 /* Read the Page and check coalescing timeout
5514 cfg.physAddr = ioc1_dma;
5515 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5516 if (mpt_config(ioc, &cfg) == 0) {
5518 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
5519 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
5520 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
5522 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Coalescing Enabled Timeout = %d\n",
5525 if (tmp > MPT_COALESCING_TIMEOUT) {
5526 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
5528 /* Write NVRAM and current
5531 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5532 if (mpt_config(ioc, &cfg) == 0) {
5533 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Reset Current Coalescing Timeout to = %d\n",
5534 ioc->name, MPT_COALESCING_TIMEOUT));
5536 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
5537 if (mpt_config(ioc, &cfg) == 0) {
5538 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5539 "Reset NVRAM Coalescing Timeout to = %d\n",
5540 ioc->name, MPT_COALESCING_TIMEOUT));
5542 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5543 "Reset NVRAM Coalescing Timeout Failed\n",
5548 dprintk(ioc, printk(MYIOC_s_WARN_FMT
5549 "Reset of Current Coalescing Timeout Failed!\n",
5555 dprintk(ioc, printk(MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
5559 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
5565 mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
5568 ConfigPageHeader_t hdr;
5570 ManufacturingPage0_t *pbuf = NULL;
5572 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5573 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5575 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
5576 cfg.cfghdr.hdr = &hdr;
5578 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5581 if (mpt_config(ioc, &cfg) != 0)
5584 if (!cfg.cfghdr.hdr->PageLength)
5587 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5588 pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
5592 cfg.physAddr = buf_dma;
5594 if (mpt_config(ioc, &cfg) != 0)
5597 memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name));
5598 memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
5599 memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
5604 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
5607 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5609 * SendEventNotification - Send EventNotification (on or off) request to adapter
5610 * @ioc: Pointer to MPT_ADAPTER structure
5611 * @EvSwitch: Event switch flags
5614 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
5616 EventNotification_t *evnp;
5618 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
5620 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
5624 memset(evnp, 0, sizeof(*evnp));
5626 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
5628 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
5629 evnp->ChainOffset = 0;
5631 evnp->Switch = EvSwitch;
5633 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
5638 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5640 * SendEventAck - Send EventAck request to MPT adapter.
5641 * @ioc: Pointer to MPT_ADAPTER structure
5642 * @evnp: Pointer to original EventNotification request
5645 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
5649 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5650 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
5651 ioc->name,__FUNCTION__));
5655 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventAck\n", ioc->name));
5657 pAck->Function = MPI_FUNCTION_EVENT_ACK;
5658 pAck->ChainOffset = 0;
5659 pAck->Reserved[0] = pAck->Reserved[1] = 0;
5661 pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
5662 pAck->Event = evnp->Event;
5663 pAck->EventContext = evnp->EventContext;
5665 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
5670 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5672 * mpt_config - Generic function to issue config message
5673 * @ioc: Pointer to an adapter structure
5674 * @pCfg: Pointer to a configuration structure. Struct contains
5675 * action, page address, direction, physical address
5676 * and pointer to a configuration page header
5677 * Page header is updated.
5679 * Returns 0 for success
5680 * -EPERM if not allowed due to ISR context
5681 * -EAGAIN if no msg frames currently available
5682 * -EFAULT for non-successful reply or no reply (timeout)
5685 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5688 ConfigExtendedPageHeader_t *pExtHdr = NULL;
5690 unsigned long flags;
5695 /* Prevent calling wait_event() (below), if caller happens
5696 * to be in ISR context, because that is fatal!
5698 in_isr = in_interrupt();
5700 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
5705 /* Get and Populate a free Frame
5707 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5708 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
5712 pReq = (Config_t *)mf;
5713 pReq->Action = pCfg->action;
5715 pReq->ChainOffset = 0;
5716 pReq->Function = MPI_FUNCTION_CONFIG;
5718 /* Assume page type is not extended and clear "reserved" fields. */
5719 pReq->ExtPageLength = 0;
5720 pReq->ExtPageType = 0;
5723 for (ii=0; ii < 8; ii++)
5724 pReq->Reserved2[ii] = 0;
5726 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
5727 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
5728 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
5729 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
5731 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5732 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
5733 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
5734 pReq->ExtPageType = pExtHdr->ExtPageType;
5735 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
5737 /* Page Length must be treated as a reserved field for the extended header. */
5738 pReq->Header.PageLength = 0;
5741 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
5743 /* Add a SGE to the config request.
5746 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
5748 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
5750 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5751 flagsLength |= pExtHdr->ExtPageLength * 4;
5753 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n",
5754 ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action));
5757 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
5759 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n",
5760 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
5763 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
5765 /* Append pCfg pointer to end of mf
5767 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5769 /* Initalize the timer
5771 init_timer(&pCfg->timer);
5772 pCfg->timer.data = (unsigned long) ioc;
5773 pCfg->timer.function = mpt_timer_expired;
5774 pCfg->wait_done = 0;
5776 /* Set the timer; ensure 10 second minimum */
5777 if (pCfg->timeout < 10)
5778 pCfg->timer.expires = jiffies + HZ*10;
5780 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5782 /* Add to end of Q, set timer and then issue this command */
5783 spin_lock_irqsave(&ioc->FreeQlock, flags);
5784 list_add_tail(&pCfg->linkage, &ioc->configQ);
5785 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5787 add_timer(&pCfg->timer);
5788 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5789 wait_event(mpt_waitq, pCfg->wait_done);
5791 /* mf has been freed - do not access */
5798 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5800 * mpt_timer_expired - Callback for timer process.
5801 * Used only internal config functionality.
5802 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5805 mpt_timer_expired(unsigned long data)
5807 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
5809 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired! \n", ioc->name));
5811 /* Perform a FW reload */
5812 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
5813 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
5815 /* No more processing.
5816 * Hard reset clean-up will wake up
5817 * process and free all resources.
5819 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired complete!\n", ioc->name));
5824 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5826 * mpt_ioc_reset - Base cleanup for hard reset
5827 * @ioc: Pointer to the adapter structure
5828 * @reset_phase: Indicates pre- or post-reset functionality
5830 * Remark: Frees resources with internally generated commands.
5833 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
5836 unsigned long flags;
5838 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5839 ": IOC %s_reset routed to MPT base driver!\n",
5840 ioc->name, reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
5841 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
5843 if (reset_phase == MPT_IOC_SETUP_RESET) {
5845 } else if (reset_phase == MPT_IOC_PRE_RESET) {
5846 /* If the internal config Q is not empty -
5847 * delete timer. MF resources will be freed when
5848 * the FIFO's are primed.
5850 spin_lock_irqsave(&ioc->FreeQlock, flags);
5851 list_for_each_entry(pCfg, &ioc->configQ, linkage)
5852 del_timer(&pCfg->timer);
5853 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5858 /* Search the configQ for internal commands.
5859 * Flush the Q, and wake up all suspended threads.
5861 spin_lock_irqsave(&ioc->FreeQlock, flags);
5862 list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
5863 list_del(&pCfg->linkage);
5865 pCfg->status = MPT_CONFIG_ERROR;
5866 pCfg->wait_done = 1;
5867 wake_up(&mpt_waitq);
5869 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5872 return 1; /* currently means nothing really */
5876 #ifdef CONFIG_PROC_FS /* { */
5877 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5879 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5881 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5883 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5885 * Returns 0 for success, non-zero for failure.
5888 procmpt_create(void)
5890 struct proc_dir_entry *ent;
5892 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
5893 if (mpt_proc_root_dir == NULL)
5896 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5898 ent->read_proc = procmpt_summary_read;
5900 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5902 ent->read_proc = procmpt_version_read;
5907 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5909 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5911 * Returns 0 for success, non-zero for failure.
5914 procmpt_destroy(void)
5916 remove_proc_entry("version", mpt_proc_root_dir);
5917 remove_proc_entry("summary", mpt_proc_root_dir);
5918 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
5921 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5923 * procmpt_summary_read - Handle read request of a summary file
5924 * @buf: Pointer to area to write information
5925 * @start: Pointer to start pointer
5926 * @offset: Offset to start writing
5927 * @request: Amount of read data requested
5928 * @eof: Pointer to EOF integer
5931 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
5932 * Returns number of characters written to process performing the read.
5935 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5945 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5949 list_for_each_entry(ioc, &ioc_list, list) {
5952 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5955 if ((out-buf) >= request)
5962 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5965 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5967 * procmpt_version_read - Handle read request from /proc/mpt/version.
5968 * @buf: Pointer to area to write information
5969 * @start: Pointer to start pointer
5970 * @offset: Offset to start writing
5971 * @request: Amount of read data requested
5972 * @eof: Pointer to EOF integer
5975 * Returns number of characters written to process performing the read.
5978 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5981 int scsi, fc, sas, lan, ctl, targ, dmp;
5985 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
5986 len += sprintf(buf+len, " Fusion MPT base driver\n");
5988 scsi = fc = sas = lan = ctl = targ = dmp = 0;
5989 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
5991 if (MptCallbacks[cb_idx]) {
5992 switch (MptDriverClass[cb_idx]) {
5994 if (!scsi++) drvname = "SPI host";
5997 if (!fc++) drvname = "FC host";
6000 if (!sas++) drvname = "SAS host";
6003 if (!lan++) drvname = "LAN";
6006 if (!targ++) drvname = "SCSI target";
6009 if (!ctl++) drvname = "ioctl";
6014 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
6018 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6021 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6023 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
6024 * @buf: Pointer to area to write information
6025 * @start: Pointer to start pointer
6026 * @offset: Offset to start writing
6027 * @request: Amount of read data requested
6028 * @eof: Pointer to EOF integer
6031 * Returns number of characters written to process performing the read.
6034 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6036 MPT_ADAPTER *ioc = data;
6042 mpt_get_fw_exp_ver(expVer, ioc);
6044 len = sprintf(buf, "%s:", ioc->name);
6045 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
6046 len += sprintf(buf+len, " (f/w download boot flag set)");
6047 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6048 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
6050 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
6051 ioc->facts.ProductID,
6053 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
6054 if (ioc->facts.FWImageSize)
6055 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
6056 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
6057 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
6058 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
6060 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
6061 ioc->facts.CurrentHostMfaHighAddr);
6062 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
6063 ioc->facts.CurrentSenseBufferHighAddr);
6065 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
6066 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
6068 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6069 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
6071 * Rounding UP to nearest 4-kB boundary here...
6073 sz = (ioc->req_sz * ioc->req_depth) + 128;
6074 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
6075 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6076 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
6077 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
6078 4*ioc->facts.RequestFrameSize,
6079 ioc->facts.GlobalCredits);
6081 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
6082 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
6083 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
6084 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6085 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
6086 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
6087 ioc->facts.CurReplyFrameSize,
6088 ioc->facts.ReplyQueueDepth);
6090 len += sprintf(buf+len, " MaxDevices = %d\n",
6091 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
6092 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
6095 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
6096 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
6098 ioc->facts.NumberOfPorts);
6099 if (ioc->bus_type == FC) {
6100 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
6101 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6102 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6103 a[5], a[4], a[3], a[2], a[1], a[0]);
6105 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
6106 ioc->fc_port_page0[p].WWNN.High,
6107 ioc->fc_port_page0[p].WWNN.Low,
6108 ioc->fc_port_page0[p].WWPN.High,
6109 ioc->fc_port_page0[p].WWPN.Low);
6113 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6116 #endif /* CONFIG_PROC_FS } */
6118 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6120 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
6123 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
6124 sprintf(buf, " (Exp %02d%02d)",
6125 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
6126 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
6129 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
6130 strcat(buf, " [MDBG]");
6134 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6136 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6137 * @ioc: Pointer to MPT_ADAPTER structure
6138 * @buffer: Pointer to buffer where IOC summary info should be written
6139 * @size: Pointer to number of bytes we wrote (set by this routine)
6140 * @len: Offset at which to start writing in buffer
6141 * @showlan: Display LAN stuff?
6143 * This routine writes (english readable) ASCII text, which represents
6144 * a summary of IOC information, to a buffer.
6147 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
6152 mpt_get_fw_exp_ver(expVer, ioc);
6155 * Shorter summary of attached ioc's...
6157 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6160 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
6161 ioc->facts.FWVersion.Word,
6163 ioc->facts.NumberOfPorts,
6166 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6167 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6168 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6169 a[5], a[4], a[3], a[2], a[1], a[0]);
6172 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
6175 y += sprintf(buffer+len+y, " (disabled)");
6177 y += sprintf(buffer+len+y, "\n");
6182 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6186 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6188 * mpt_HardResetHandler - Generic reset handler
6189 * @ioc: Pointer to MPT_ADAPTER structure
6190 * @sleepFlag: Indicates if sleep or schedule must be called.
6192 * Issues SCSI Task Management call based on input arg values.
6193 * If TaskMgmt fails, returns associated SCSI request.
6195 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
6196 * or a non-interrupt thread. In the former, must not call schedule().
6198 * Note: A return of -1 is a FATAL error case, as it means a
6199 * FW reload/initialization failed.
6201 * Returns 0 for SUCCESS or -1 if FAILED.
6204 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6207 unsigned long flags;
6209 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name));
6211 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
6212 printk("MF count 0x%x !\n", ioc->mfcnt);
6215 /* Reset the adapter. Prevent more than 1 call to
6216 * mpt_do_ioc_recovery at any instant in time.
6218 spin_lock_irqsave(&ioc->diagLock, flags);
6219 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
6220 spin_unlock_irqrestore(&ioc->diagLock, flags);
6223 ioc->diagPending = 1;
6225 spin_unlock_irqrestore(&ioc->diagLock, flags);
6227 /* FIXME: If do_ioc_recovery fails, repeat....
6230 /* The SCSI driver needs to adjust timeouts on all current
6231 * commands prior to the diagnostic reset being issued.
6232 * Prevents timeouts occurring during a diagnostic reset...very bad.
6233 * For all other protocol drivers, this is a no-op.
6239 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6240 if (MptResetHandlers[cb_idx]) {
6241 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling IOC reset_setup handler #%d\n",
6242 ioc->name, cb_idx));
6243 r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
6245 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling alt-%s setup reset handler #%d\n",
6246 ioc->name, ioc->alt_ioc->name, cb_idx));
6247 r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_SETUP_RESET);
6253 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
6254 printk(MYIOC_s_WARN_FMT "Cannot recover rc = %d!\n", ioc->name, rc);
6258 ioc->alt_ioc->reload_fw = 0;
6260 spin_lock_irqsave(&ioc->diagLock, flags);
6261 ioc->diagPending = 0;
6263 ioc->alt_ioc->diagPending = 0;
6264 spin_unlock_irqrestore(&ioc->diagLock, flags);
6266 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
6271 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6273 EventDescriptionStr(u8 event, u32 evData0, char *evStr)
6278 case MPI_EVENT_NONE:
6281 case MPI_EVENT_LOG_DATA:
6284 case MPI_EVENT_STATE_CHANGE:
6285 ds = "State Change";
6287 case MPI_EVENT_UNIT_ATTENTION:
6288 ds = "Unit Attention";
6290 case MPI_EVENT_IOC_BUS_RESET:
6291 ds = "IOC Bus Reset";
6293 case MPI_EVENT_EXT_BUS_RESET:
6294 ds = "External Bus Reset";
6296 case MPI_EVENT_RESCAN:
6297 ds = "Bus Rescan Event";
6299 case MPI_EVENT_LINK_STATUS_CHANGE:
6300 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
6301 ds = "Link Status(FAILURE) Change";
6303 ds = "Link Status(ACTIVE) Change";
6305 case MPI_EVENT_LOOP_STATE_CHANGE:
6306 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
6307 ds = "Loop State(LIP) Change";
6308 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
6309 ds = "Loop State(LPE) Change"; /* ??? */
6311 ds = "Loop State(LPB) Change"; /* ??? */
6313 case MPI_EVENT_LOGOUT:
6316 case MPI_EVENT_EVENT_CHANGE:
6322 case MPI_EVENT_INTEGRATED_RAID:
6324 u8 ReasonCode = (u8)(evData0 >> 16);
6325 switch (ReasonCode) {
6326 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
6327 ds = "Integrated Raid: Volume Created";
6329 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
6330 ds = "Integrated Raid: Volume Deleted";
6332 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
6333 ds = "Integrated Raid: Volume Settings Changed";
6335 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
6336 ds = "Integrated Raid: Volume Status Changed";
6338 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
6339 ds = "Integrated Raid: Volume Physdisk Changed";
6341 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
6342 ds = "Integrated Raid: Physdisk Created";
6344 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
6345 ds = "Integrated Raid: Physdisk Deleted";
6347 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
6348 ds = "Integrated Raid: Physdisk Settings Changed";
6350 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
6351 ds = "Integrated Raid: Physdisk Status Changed";
6353 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
6354 ds = "Integrated Raid: Domain Validation Needed";
6356 case MPI_EVENT_RAID_RC_SMART_DATA :
6357 ds = "Integrated Raid; Smart Data";
6359 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
6360 ds = "Integrated Raid: Replace Action Started";
6363 ds = "Integrated Raid";
6368 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
6369 ds = "SCSI Device Status Change";
6371 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
6373 u8 id = (u8)(evData0);
6374 u8 channel = (u8)(evData0 >> 8);
6375 u8 ReasonCode = (u8)(evData0 >> 16);
6376 switch (ReasonCode) {
6377 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
6378 snprintf(evStr, EVENT_DESCR_STR_SZ,
6379 "SAS Device Status Change: Added: "
6380 "id=%d channel=%d", id, channel);
6382 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
6383 snprintf(evStr, EVENT_DESCR_STR_SZ,
6384 "SAS Device Status Change: Deleted: "
6385 "id=%d channel=%d", id, channel);
6387 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
6388 snprintf(evStr, EVENT_DESCR_STR_SZ,
6389 "SAS Device Status Change: SMART Data: "
6390 "id=%d channel=%d", id, channel);
6392 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
6393 snprintf(evStr, EVENT_DESCR_STR_SZ,
6394 "SAS Device Status Change: No Persistancy: "
6395 "id=%d channel=%d", id, channel);
6397 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
6398 snprintf(evStr, EVENT_DESCR_STR_SZ,
6399 "SAS Device Status Change: Unsupported Device "
6400 "Discovered : id=%d channel=%d", id, channel);
6402 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
6403 snprintf(evStr, EVENT_DESCR_STR_SZ,
6404 "SAS Device Status Change: Internal Device "
6405 "Reset : id=%d channel=%d", id, channel);
6407 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
6408 snprintf(evStr, EVENT_DESCR_STR_SZ,
6409 "SAS Device Status Change: Internal Task "
6410 "Abort : id=%d channel=%d", id, channel);
6412 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
6413 snprintf(evStr, EVENT_DESCR_STR_SZ,
6414 "SAS Device Status Change: Internal Abort "
6415 "Task Set : id=%d channel=%d", id, channel);
6417 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
6418 snprintf(evStr, EVENT_DESCR_STR_SZ,
6419 "SAS Device Status Change: Internal Clear "
6420 "Task Set : id=%d channel=%d", id, channel);
6422 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
6423 snprintf(evStr, EVENT_DESCR_STR_SZ,
6424 "SAS Device Status Change: Internal Query "
6425 "Task : id=%d channel=%d", id, channel);
6428 snprintf(evStr, EVENT_DESCR_STR_SZ,
6429 "SAS Device Status Change: Unknown: "
6430 "id=%d channel=%d", id, channel);
6435 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
6436 ds = "Bus Timer Expired";
6438 case MPI_EVENT_QUEUE_FULL:
6440 u16 curr_depth = (u16)(evData0 >> 16);
6441 u8 channel = (u8)(evData0 >> 8);
6442 u8 id = (u8)(evData0);
6444 snprintf(evStr, EVENT_DESCR_STR_SZ,
6445 "Queue Full: channel=%d id=%d depth=%d",
6446 channel, id, curr_depth);
6449 case MPI_EVENT_SAS_SES:
6450 ds = "SAS SES Event";
6452 case MPI_EVENT_PERSISTENT_TABLE_FULL:
6453 ds = "Persistent Table Full";
6455 case MPI_EVENT_SAS_PHY_LINK_STATUS:
6457 u8 LinkRates = (u8)(evData0 >> 8);
6458 u8 PhyNumber = (u8)(evData0);
6459 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
6460 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
6461 switch (LinkRates) {
6462 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
6463 snprintf(evStr, EVENT_DESCR_STR_SZ,
6464 "SAS PHY Link Status: Phy=%d:"
6465 " Rate Unknown",PhyNumber);
6467 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
6468 snprintf(evStr, EVENT_DESCR_STR_SZ,
6469 "SAS PHY Link Status: Phy=%d:"
6470 " Phy Disabled",PhyNumber);
6472 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
6473 snprintf(evStr, EVENT_DESCR_STR_SZ,
6474 "SAS PHY Link Status: Phy=%d:"
6475 " Failed Speed Nego",PhyNumber);
6477 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
6478 snprintf(evStr, EVENT_DESCR_STR_SZ,
6479 "SAS PHY Link Status: Phy=%d:"
6480 " Sata OOB Completed",PhyNumber);
6482 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
6483 snprintf(evStr, EVENT_DESCR_STR_SZ,
6484 "SAS PHY Link Status: Phy=%d:"
6485 " Rate 1.5 Gbps",PhyNumber);
6487 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
6488 snprintf(evStr, EVENT_DESCR_STR_SZ,
6489 "SAS PHY Link Status: Phy=%d:"
6490 " Rate 3.0 Gpbs",PhyNumber);
6493 snprintf(evStr, EVENT_DESCR_STR_SZ,
6494 "SAS PHY Link Status: Phy=%d", PhyNumber);
6499 case MPI_EVENT_SAS_DISCOVERY_ERROR:
6500 ds = "SAS Discovery Error";
6502 case MPI_EVENT_IR_RESYNC_UPDATE:
6504 u8 resync_complete = (u8)(evData0 >> 16);
6505 snprintf(evStr, EVENT_DESCR_STR_SZ,
6506 "IR Resync Update: Complete = %d:",resync_complete);
6511 u8 ReasonCode = (u8)(evData0 >> 16);
6512 switch (ReasonCode) {
6513 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
6514 ds = "IR2: LD State Changed";
6516 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
6517 ds = "IR2: PD State Changed";
6519 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
6520 ds = "IR2: Bad Block Table Full";
6522 case MPI_EVENT_IR2_RC_PD_INSERTED:
6523 ds = "IR2: PD Inserted";
6525 case MPI_EVENT_IR2_RC_PD_REMOVED:
6526 ds = "IR2: PD Removed";
6528 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
6529 ds = "IR2: Foreign CFG Detected";
6531 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
6532 ds = "IR2: Rebuild Medium Error";
6540 case MPI_EVENT_SAS_DISCOVERY:
6543 ds = "SAS Discovery: Start";
6545 ds = "SAS Discovery: Stop";
6548 case MPI_EVENT_LOG_ENTRY_ADDED:
6549 ds = "SAS Log Entry Added";
6552 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
6554 u8 phy_num = (u8)(evData0);
6555 u8 port_num = (u8)(evData0 >> 8);
6556 u8 port_width = (u8)(evData0 >> 16);
6557 u8 primative = (u8)(evData0 >> 24);
6558 snprintf(evStr, EVENT_DESCR_STR_SZ,
6559 "SAS Broadcase Primative: phy=%d port=%d "
6560 "width=%d primative=0x%02x",
6561 phy_num, port_num, port_width, primative);
6565 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
6567 u8 reason = (u8)(evData0);
6568 u8 port_num = (u8)(evData0 >> 8);
6569 u16 handle = le16_to_cpu(evData0 >> 16);
6571 snprintf(evStr, EVENT_DESCR_STR_SZ,
6572 "SAS Initiator Device Status Change: reason=0x%02x "
6573 "port=%d handle=0x%04x",
6574 reason, port_num, handle);
6578 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
6580 u8 max_init = (u8)(evData0);
6581 u8 current_init = (u8)(evData0 >> 8);
6583 snprintf(evStr, EVENT_DESCR_STR_SZ,
6584 "SAS Initiator Device Table Overflow: max initiators=%02d "
6585 "current initators=%02d",
6586 max_init, current_init);
6589 case MPI_EVENT_SAS_SMP_ERROR:
6591 u8 status = (u8)(evData0);
6592 u8 port_num = (u8)(evData0 >> 8);
6593 u8 result = (u8)(evData0 >> 16);
6595 if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
6596 snprintf(evStr, EVENT_DESCR_STR_SZ,
6597 "SAS SMP Error: port=%d result=0x%02x",
6599 else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
6600 snprintf(evStr, EVENT_DESCR_STR_SZ,
6601 "SAS SMP Error: port=%d : CRC Error",
6603 else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
6604 snprintf(evStr, EVENT_DESCR_STR_SZ,
6605 "SAS SMP Error: port=%d : Timeout",
6607 else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
6608 snprintf(evStr, EVENT_DESCR_STR_SZ,
6609 "SAS SMP Error: port=%d : No Destination",
6611 else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
6612 snprintf(evStr, EVENT_DESCR_STR_SZ,
6613 "SAS SMP Error: port=%d : Bad Destination",
6616 snprintf(evStr, EVENT_DESCR_STR_SZ,
6617 "SAS SMP Error: port=%d : status=0x%02x",
6623 * MPT base "custom" events may be added here...
6630 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
6633 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6635 * ProcessEventNotification - Route EventNotificationReply to all event handlers
6636 * @ioc: Pointer to MPT_ADAPTER structure
6637 * @pEventReply: Pointer to EventNotification reply frame
6638 * @evHandlers: Pointer to integer, number of event handlers
6640 * Routes a received EventNotificationReply to all currently registered
6642 * Returns sum of event handlers return values.
6645 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
6654 char evStr[EVENT_DESCR_STR_SZ];
6658 * Do platform normalization of values
6660 event = le32_to_cpu(pEventReply->Event) & 0xFF;
6661 // evCtx = le32_to_cpu(pEventReply->EventContext);
6662 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
6664 evData0 = le32_to_cpu(pEventReply->Data[0]);
6667 EventDescriptionStr(event, evData0, evStr);
6668 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event:(%02Xh) : %s\n",
6673 #ifdef CONFIG_FUSION_LOGGING
6674 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6675 ": Event data:\n", ioc->name));
6676 for (ii = 0; ii < evDataLen; ii++)
6677 devtverboseprintk(ioc, printk(" %08x",
6678 le32_to_cpu(pEventReply->Data[ii])));
6679 devtverboseprintk(ioc, printk("\n"));
6683 * Do general / base driver event processing
6686 case MPI_EVENT_EVENT_CHANGE: /* 0A */
6688 u8 evState = evData0 & 0xFF;
6690 /* CHECKME! What if evState unexpectedly says OFF (0)? */
6692 /* Update EventState field in cached IocFacts */
6693 if (ioc->facts.Function) {
6694 ioc->facts.EventState = evState;
6698 case MPI_EVENT_INTEGRATED_RAID:
6699 mptbase_raid_process_event_data(ioc,
6700 (MpiEventDataRaid_t *)pEventReply->Data);
6707 * Should this event be logged? Events are written sequentially.
6708 * When buffer is full, start again at the top.
6710 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
6713 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
6715 ioc->events[idx].event = event;
6716 ioc->events[idx].eventContext = ioc->eventContext;
6718 for (ii = 0; ii < 2; ii++) {
6720 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
6722 ioc->events[idx].data[ii] = 0;
6725 ioc->eventContext++;
6730 * Call each currently registered protocol event handler.
6732 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6733 if (MptEvHandlers[cb_idx]) {
6734 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Routing Event to event handler #%d\n",
6735 ioc->name, cb_idx));
6736 r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply);
6740 /* FIXME? Examine results here? */
6743 * If needed, send (a single) EventAck.
6745 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
6746 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6747 "EventAck required\n",ioc->name));
6748 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
6749 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SendEventAck returned %d\n",
6754 *evHandlers = handlers;
6758 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6760 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
6761 * @ioc: Pointer to MPT_ADAPTER structure
6762 * @log_info: U32 LogInfo reply word from the IOC
6764 * Refer to lsi/mpi_log_fc.h.
6767 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
6769 char *desc = "unknown";
6771 switch (log_info & 0xFF000000) {
6772 case MPI_IOCLOGINFO_FC_INIT_BASE:
6773 desc = "FCP Initiator";
6775 case MPI_IOCLOGINFO_FC_TARGET_BASE:
6776 desc = "FCP Target";
6778 case MPI_IOCLOGINFO_FC_LAN_BASE:
6781 case MPI_IOCLOGINFO_FC_MSG_BASE:
6782 desc = "MPI Message Layer";
6784 case MPI_IOCLOGINFO_FC_LINK_BASE:
6787 case MPI_IOCLOGINFO_FC_CTX_BASE:
6788 desc = "Context Manager";
6790 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
6791 desc = "Invalid Field Offset";
6793 case MPI_IOCLOGINFO_FC_STATE_CHANGE:
6794 desc = "State Change Info";
6798 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
6799 ioc->name, log_info, desc, (log_info & 0xFFFFFF));
6802 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6804 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
6805 * @ioc: Pointer to MPT_ADAPTER structure
6806 * @mr: Pointer to MPT reply frame
6807 * @log_info: U32 LogInfo word from the IOC
6809 * Refer to lsi/sp_log.h.
6812 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
6814 u32 info = log_info & 0x00FF0000;
6815 char *desc = "unknown";
6819 desc = "bug! MID not found";
6820 if (ioc->reload_fw == 0)
6825 desc = "Parity Error";
6829 desc = "ASYNC Outbound Overrun";
6833 desc = "SYNC Offset Error";
6841 desc = "Msg In Overflow";
6849 desc = "Outbound DMA Overrun";
6853 desc = "Task Management";
6857 desc = "Device Problem";
6861 desc = "Invalid Phase Change";
6865 desc = "Untagged Table Size";
6870 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
6873 /* strings for sas loginfo */
6874 static char *originator_str[] = {
6879 static char *iop_code_str[] = {
6881 "Invalid SAS Address", /* 01h */
6883 "Invalid Page", /* 03h */
6884 "Diag Message Error", /* 04h */
6885 "Task Terminated", /* 05h */
6886 "Enclosure Management", /* 06h */
6887 "Target Mode" /* 07h */
6889 static char *pl_code_str[] = {
6891 "Open Failure", /* 01h */
6892 "Invalid Scatter Gather List", /* 02h */
6893 "Wrong Relative Offset or Frame Length", /* 03h */
6894 "Frame Transfer Error", /* 04h */
6895 "Transmit Frame Connected Low", /* 05h */
6896 "SATA Non-NCQ RW Error Bit Set", /* 06h */
6897 "SATA Read Log Receive Data Error", /* 07h */
6898 "SATA NCQ Fail All Commands After Error", /* 08h */
6899 "SATA Error in Receive Set Device Bit FIS", /* 09h */
6900 "Receive Frame Invalid Message", /* 0Ah */
6901 "Receive Context Message Valid Error", /* 0Bh */
6902 "Receive Frame Current Frame Error", /* 0Ch */
6903 "SATA Link Down", /* 0Dh */
6904 "Discovery SATA Init W IOS", /* 0Eh */
6905 "Config Invalid Page", /* 0Fh */
6906 "Discovery SATA Init Timeout", /* 10h */
6909 "IO Not Yet Executed", /* 13h */
6910 "IO Executed", /* 14h */
6911 "Persistent Reservation Out Not Affiliation "
6913 "Open Transmit DMA Abort", /* 16h */
6914 "IO Device Missing Delay Retry", /* 17h */
6915 "IO Cancelled Due to Recieve Error", /* 18h */
6923 "Enclosure Management" /* 20h */
6925 static char *ir_code_str[] = {
6926 "Raid Action Error", /* 00h */
6936 static char *raid_sub_code_str[] = {
6938 "Volume Creation Failed: Data Passed too "
6940 "Volume Creation Failed: Duplicate Volumes "
6941 "Attempted", /* 02h */
6942 "Volume Creation Failed: Max Number "
6943 "Supported Volumes Exceeded", /* 03h */
6944 "Volume Creation Failed: DMA Error", /* 04h */
6945 "Volume Creation Failed: Invalid Volume Type", /* 05h */
6946 "Volume Creation Failed: Error Reading "
6947 "MFG Page 4", /* 06h */
6948 "Volume Creation Failed: Creating Internal "
6949 "Structures", /* 07h */
6958 "Activation failed: Already Active Volume", /* 10h */
6959 "Activation failed: Unsupported Volume Type", /* 11h */
6960 "Activation failed: Too Many Active Volumes", /* 12h */
6961 "Activation failed: Volume ID in Use", /* 13h */
6962 "Activation failed: Reported Failure", /* 14h */
6963 "Activation failed: Importing a Volume", /* 15h */
6974 "Phys Disk failed: Too Many Phys Disks", /* 20h */
6975 "Phys Disk failed: Data Passed too Large", /* 21h */
6976 "Phys Disk failed: DMA Error", /* 22h */
6977 "Phys Disk failed: Invalid <channel:id>", /* 23h */
6978 "Phys Disk failed: Creating Phys Disk Config "
6991 "Compatibility Error: IR Disabled", /* 30h */
6992 "Compatibility Error: Inquiry Comand Failed", /* 31h */
6993 "Compatibility Error: Device not Direct Access "
6994 "Device ", /* 32h */
6995 "Compatibility Error: Removable Device Found", /* 33h */
6996 "Compatibility Error: Device SCSI Version not "
6997 "2 or Higher", /* 34h */
6998 "Compatibility Error: SATA Device, 48 BIT LBA "
6999 "not Supported", /* 35h */
7000 "Compatibility Error: Device doesn't have "
7001 "512 Byte Block Sizes", /* 36h */
7002 "Compatibility Error: Volume Type Check Failed", /* 37h */
7003 "Compatibility Error: Volume Type is "
7004 "Unsupported by FW", /* 38h */
7005 "Compatibility Error: Disk Drive too Small for "
7006 "use in Volume", /* 39h */
7007 "Compatibility Error: Phys Disk for Create "
7008 "Volume not Found", /* 3Ah */
7009 "Compatibility Error: Too Many or too Few "
7010 "Disks for Volume Type", /* 3Bh */
7011 "Compatibility Error: Disk stripe Sizes "
7012 "Must be 64KB", /* 3Ch */
7013 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
7016 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7018 * mpt_sas_log_info - Log information returned from SAS IOC.
7019 * @ioc: Pointer to MPT_ADAPTER structure
7020 * @log_info: U32 LogInfo reply word from the IOC
7022 * Refer to lsi/mpi_log_sas.h.
7025 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
7027 union loginfo_type {
7036 union loginfo_type sas_loginfo;
7037 char *originator_desc = NULL;
7038 char *code_desc = NULL;
7039 char *sub_code_desc = NULL;
7041 sas_loginfo.loginfo = log_info;
7042 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
7043 (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
7046 originator_desc = originator_str[sas_loginfo.dw.originator];
7048 switch (sas_loginfo.dw.originator) {
7051 if (sas_loginfo.dw.code <
7052 sizeof(iop_code_str)/sizeof(char*))
7053 code_desc = iop_code_str[sas_loginfo.dw.code];
7056 if (sas_loginfo.dw.code <
7057 sizeof(pl_code_str)/sizeof(char*))
7058 code_desc = pl_code_str[sas_loginfo.dw.code];
7061 if (sas_loginfo.dw.code >=
7062 sizeof(ir_code_str)/sizeof(char*))
7064 code_desc = ir_code_str[sas_loginfo.dw.code];
7065 if (sas_loginfo.dw.subcode >=
7066 sizeof(raid_sub_code_str)/sizeof(char*))
7068 if (sas_loginfo.dw.code == 0)
7070 raid_sub_code_str[sas_loginfo.dw.subcode];
7076 if (sub_code_desc != NULL)
7077 printk(MYIOC_s_INFO_FMT
7078 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7080 ioc->name, log_info, originator_desc, code_desc,
7082 else if (code_desc != NULL)
7083 printk(MYIOC_s_INFO_FMT
7084 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7085 " SubCode(0x%04x)\n",
7086 ioc->name, log_info, originator_desc, code_desc,
7087 sas_loginfo.dw.subcode);
7089 printk(MYIOC_s_INFO_FMT
7090 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
7091 " SubCode(0x%04x)\n",
7092 ioc->name, log_info, originator_desc,
7093 sas_loginfo.dw.code, sas_loginfo.dw.subcode);
7096 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7098 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
7099 * @ioc: Pointer to MPT_ADAPTER structure
7100 * @ioc_status: U32 IOCStatus word from IOC
7101 * @mf: Pointer to MPT request frame
7103 * Refer to lsi/mpi.h.
7106 mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7108 Config_t *pReq = (Config_t *)mf;
7109 char extend_desc[EVENT_DESCR_STR_SZ];
7114 if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
7115 page_type = pReq->ExtPageType;
7117 page_type = pReq->Header.PageType;
7120 * ignore invalid page messages for GET_NEXT_HANDLE
7122 form = le32_to_cpu(pReq->PageAddress);
7123 if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
7124 if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
7125 page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
7126 page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
7127 if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
7128 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
7131 if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
7132 if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
7133 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
7137 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
7138 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
7139 page_type, pReq->Header.PageNumber, pReq->Action, form);
7141 switch (ioc_status) {
7143 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7144 desc = "Config Page Invalid Action";
7147 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7148 desc = "Config Page Invalid Type";
7151 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7152 desc = "Config Page Invalid Page";
7155 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7156 desc = "Config Page Invalid Data";
7159 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7160 desc = "Config Page No Defaults";
7163 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7164 desc = "Config Page Can't Commit";
7171 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s: %s\n",
7172 ioc->name, ioc_status, desc, extend_desc));
7176 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
7177 * @ioc: Pointer to MPT_ADAPTER structure
7178 * @ioc_status: U32 IOCStatus word from IOC
7179 * @mf: Pointer to MPT request frame
7181 * Refer to lsi/mpi.h.
7184 mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7186 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
7191 /****************************************************************************/
7192 /* Common IOCStatus values for all replies */
7193 /****************************************************************************/
7195 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
7196 desc = "Invalid Function";
7199 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
7203 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
7204 desc = "Invalid SGL";
7207 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
7208 desc = "Internal Error";
7211 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
7215 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
7216 desc = "Insufficient Resources";
7219 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
7220 desc = "Invalid Field";
7223 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
7224 desc = "Invalid State";
7227 /****************************************************************************/
7228 /* Config IOCStatus values */
7229 /****************************************************************************/
7231 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7232 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7233 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7234 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7235 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7236 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7237 mpt_iocstatus_info_config(ioc, status, mf);
7240 /****************************************************************************/
7241 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
7243 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
7245 /****************************************************************************/
7247 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
7248 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
7249 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
7250 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
7251 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
7252 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
7253 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
7254 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
7255 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
7256 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
7257 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
7258 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
7259 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
7262 /****************************************************************************/
7263 /* SCSI Target values */
7264 /****************************************************************************/
7266 case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
7267 desc = "Target: Priority IO";
7270 case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
7271 desc = "Target: Invalid Port";
7274 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
7275 desc = "Target Invalid IO Index:";
7278 case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
7279 desc = "Target: Aborted";
7282 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
7283 desc = "Target: No Conn Retryable";
7286 case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
7287 desc = "Target: No Connection";
7290 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
7291 desc = "Target: Transfer Count Mismatch";
7294 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
7295 desc = "Target: STS Data not Sent";
7298 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
7299 desc = "Target: Data Offset Error";
7302 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
7303 desc = "Target: Too Much Write Data";
7306 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
7307 desc = "Target: IU Too Short";
7310 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
7311 desc = "Target: ACK NAK Timeout";
7314 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
7315 desc = "Target: Nak Received";
7318 /****************************************************************************/
7319 /* Fibre Channel Direct Access values */
7320 /****************************************************************************/
7322 case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
7323 desc = "FC: Aborted";
7326 case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
7327 desc = "FC: RX ID Invalid";
7330 case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
7331 desc = "FC: DID Invalid";
7334 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
7335 desc = "FC: Node Logged Out";
7338 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
7339 desc = "FC: Exchange Canceled";
7342 /****************************************************************************/
7344 /****************************************************************************/
7346 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
7347 desc = "LAN: Device not Found";
7350 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
7351 desc = "LAN: Device Failure";
7354 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
7355 desc = "LAN: Transmit Error";
7358 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
7359 desc = "LAN: Transmit Aborted";
7362 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
7363 desc = "LAN: Receive Error";
7366 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
7367 desc = "LAN: Receive Aborted";
7370 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
7371 desc = "LAN: Partial Packet";
7374 case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
7375 desc = "LAN: Canceled";
7378 /****************************************************************************/
7379 /* Serial Attached SCSI values */
7380 /****************************************************************************/
7382 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
7383 desc = "SAS: SMP Request Failed";
7386 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
7387 desc = "SAS: SMP Data Overrun";
7398 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s\n",
7399 ioc->name, status, desc));
7402 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7403 EXPORT_SYMBOL(mpt_attach);
7404 EXPORT_SYMBOL(mpt_detach);
7406 EXPORT_SYMBOL(mpt_resume);
7407 EXPORT_SYMBOL(mpt_suspend);
7409 EXPORT_SYMBOL(ioc_list);
7410 EXPORT_SYMBOL(mpt_proc_root_dir);
7411 EXPORT_SYMBOL(mpt_register);
7412 EXPORT_SYMBOL(mpt_deregister);
7413 EXPORT_SYMBOL(mpt_event_register);
7414 EXPORT_SYMBOL(mpt_event_deregister);
7415 EXPORT_SYMBOL(mpt_reset_register);
7416 EXPORT_SYMBOL(mpt_reset_deregister);
7417 EXPORT_SYMBOL(mpt_device_driver_register);
7418 EXPORT_SYMBOL(mpt_device_driver_deregister);
7419 EXPORT_SYMBOL(mpt_get_msg_frame);
7420 EXPORT_SYMBOL(mpt_put_msg_frame);
7421 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri);
7422 EXPORT_SYMBOL(mpt_free_msg_frame);
7423 EXPORT_SYMBOL(mpt_add_sge);
7424 EXPORT_SYMBOL(mpt_send_handshake_request);
7425 EXPORT_SYMBOL(mpt_verify_adapter);
7426 EXPORT_SYMBOL(mpt_GetIocState);
7427 EXPORT_SYMBOL(mpt_print_ioc_summary);
7428 EXPORT_SYMBOL(mpt_HardResetHandler);
7429 EXPORT_SYMBOL(mpt_config);
7430 EXPORT_SYMBOL(mpt_findImVolumes);
7431 EXPORT_SYMBOL(mpt_alloc_fw_memory);
7432 EXPORT_SYMBOL(mpt_free_fw_memory);
7433 EXPORT_SYMBOL(mptbase_sas_persist_operation);
7434 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
7436 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7438 * fusion_init - Fusion MPT base driver initialization routine.
7440 * Returns 0 for success, non-zero for failure.
7447 show_mptmod_ver(my_NAME, my_VERSION);
7448 printk(KERN_INFO COPYRIGHT "\n");
7450 for (cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
7451 MptCallbacks[cb_idx] = NULL;
7452 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
7453 MptEvHandlers[cb_idx] = NULL;
7454 MptResetHandlers[cb_idx] = NULL;
7457 /* Register ourselves (mptbase) in order to facilitate
7458 * EventNotification handling.
7460 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
7462 /* Register for hard reset handling callbacks.
7464 mpt_reset_register(mpt_base_index, mpt_ioc_reset);
7466 #ifdef CONFIG_PROC_FS
7467 (void) procmpt_create();
7472 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7474 * fusion_exit - Perform driver unload cleanup.
7476 * This routine frees all resources associated with each MPT adapter
7477 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
7483 mpt_reset_deregister(mpt_base_index);
7485 #ifdef CONFIG_PROC_FS
7490 module_init(fusion_init);
7491 module_exit(fusion_exit);