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(KERN_INFO MYNAM ": Original request frame (@%p) header\n", mf));
455 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)mf)
459 func = reply->u.hdr.Function;
460 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply, Function=%02Xh\n",
463 if (func == MPI_FUNCTION_EVENT_NOTIFICATION) {
464 EventNotificationReply_t *pEvReply = (EventNotificationReply_t *) reply;
468 results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
469 if (results != evHandlers) {
470 /* CHECKME! Any special handling needed here? */
471 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
472 ioc->name, evHandlers, results));
476 * Hmmm... It seems that EventNotificationReply is an exception
477 * to the rule of one reply per request.
479 if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) {
482 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
483 ioc->name, pEvReply));
486 #ifdef CONFIG_PROC_FS
487 // LogEvent(ioc, pEvReply);
490 } else if (func == MPI_FUNCTION_EVENT_ACK) {
491 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply, EventAck reply received\n",
493 } else if (func == MPI_FUNCTION_CONFIG) {
497 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "config_complete (mf=%p,mr=%p)\n",
498 ioc->name, mf, reply));
500 pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *)));
503 /* disable timer and remove from linked list */
504 del_timer(&pCfg->timer);
506 spin_lock_irqsave(&ioc->FreeQlock, flags);
507 list_del(&pCfg->linkage);
508 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
511 * If IOC Status is SUCCESS, save the header
512 * and set the status code to GOOD.
514 pCfg->status = MPT_CONFIG_ERROR;
516 ConfigReply_t *pReply = (ConfigReply_t *)reply;
519 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
520 dcprintk(ioc, printk(KERN_NOTICE " IOCStatus=%04xh, IOCLogInfo=%08xh\n",
521 status, le32_to_cpu(pReply->IOCLogInfo)));
523 pCfg->status = status;
524 if (status == MPI_IOCSTATUS_SUCCESS) {
525 if ((pReply->Header.PageType &
526 MPI_CONFIG_PAGETYPE_MASK) ==
527 MPI_CONFIG_PAGETYPE_EXTENDED) {
528 pCfg->cfghdr.ehdr->ExtPageLength =
529 le16_to_cpu(pReply->ExtPageLength);
530 pCfg->cfghdr.ehdr->ExtPageType =
533 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
535 /* If this is a regular header, save PageLength. */
536 /* LMP Do this better so not using a reserved field! */
537 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
538 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
539 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
544 * Wake up the original calling thread
549 } else if (func == MPI_FUNCTION_SAS_IO_UNIT_CONTROL) {
550 /* we should be always getting a reply frame */
551 memcpy(ioc->persist_reply_frame, reply,
552 min(MPT_DEFAULT_FRAME_SIZE,
553 4*reply->u.reply.MsgLength));
554 del_timer(&ioc->persist_timer);
555 ioc->persist_wait_done = 1;
558 printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
563 * Conditionally tell caller to free the original
564 * EventNotification/EventAck/unexpected request frame!
569 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
571 * mpt_register - Register protocol-specific main callback handler.
572 * @cbfunc: callback function pointer
573 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
575 * This routine is called by a protocol-specific driver (SCSI host,
576 * LAN, SCSI target) to register its reply callback routine. Each
577 * protocol-specific driver must do this before it will be able to
578 * use any IOC resources, such as obtaining request frames.
580 * NOTES: The SCSI protocol driver currently calls this routine thrice
581 * in order to register separate callbacks; one for "normal" SCSI IO;
582 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
584 * Returns u8 valued "handle" in the range (and S.O.D. order)
585 * {N,...,7,6,5,...,1} if successful.
586 * A return value of MPT_MAX_PROTOCOL_DRIVERS (including zero!) should be
587 * considered an error by the caller.
590 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
593 last_drv_idx = MPT_MAX_PROTOCOL_DRIVERS;
596 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
597 * (slot/handle 0 is reserved!)
599 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
600 if (MptCallbacks[cb_idx] == NULL) {
601 MptCallbacks[cb_idx] = cbfunc;
602 MptDriverClass[cb_idx] = dclass;
603 MptEvHandlers[cb_idx] = NULL;
604 last_drv_idx = cb_idx;
612 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
614 * mpt_deregister - Deregister a protocol drivers resources.
615 * @cb_idx: previously registered callback handle
617 * Each protocol-specific driver should call this routine when its
618 * module is unloaded.
621 mpt_deregister(u8 cb_idx)
623 if (cb_idx && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
624 MptCallbacks[cb_idx] = NULL;
625 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
626 MptEvHandlers[cb_idx] = NULL;
632 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
634 * mpt_event_register - Register protocol-specific event callback
636 * @cb_idx: previously registered (via mpt_register) callback handle
637 * @ev_cbfunc: callback function
639 * This routine can be called by one or more protocol-specific drivers
640 * if/when they choose to be notified of MPT events.
642 * Returns 0 for success.
645 mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc)
647 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
650 MptEvHandlers[cb_idx] = ev_cbfunc;
654 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
656 * mpt_event_deregister - Deregister protocol-specific event callback
658 * @cb_idx: previously registered callback handle
660 * Each protocol-specific driver should call this routine
661 * when it does not (or can no longer) handle events,
662 * or when its module is unloaded.
665 mpt_event_deregister(u8 cb_idx)
667 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
670 MptEvHandlers[cb_idx] = NULL;
673 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
675 * mpt_reset_register - Register protocol-specific IOC reset handler.
676 * @cb_idx: previously registered (via mpt_register) callback handle
677 * @reset_func: reset function
679 * This routine can be called by one or more protocol-specific drivers
680 * if/when they choose to be notified of IOC resets.
682 * Returns 0 for success.
685 mpt_reset_register(u8 cb_idx, MPT_RESETHANDLER reset_func)
687 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
690 MptResetHandlers[cb_idx] = reset_func;
694 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
696 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
697 * @cb_idx: previously registered callback handle
699 * Each protocol-specific driver should call this routine
700 * when it does not (or can no longer) handle IOC reset handling,
701 * or when its module is unloaded.
704 mpt_reset_deregister(u8 cb_idx)
706 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
709 MptResetHandlers[cb_idx] = NULL;
712 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
714 * mpt_device_driver_register - Register device driver hooks
715 * @dd_cbfunc: driver callbacks struct
716 * @cb_idx: MPT protocol driver index
719 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, u8 cb_idx)
722 const struct pci_device_id *id;
724 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
727 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
729 /* call per pci device probe entry point */
730 list_for_each_entry(ioc, &ioc_list, list) {
731 id = ioc->pcidev->driver ?
732 ioc->pcidev->driver->id_table : NULL;
733 if (dd_cbfunc->probe)
734 dd_cbfunc->probe(ioc->pcidev, id);
740 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
742 * mpt_device_driver_deregister - DeRegister device driver hooks
743 * @cb_idx: MPT protocol driver index
746 mpt_device_driver_deregister(u8 cb_idx)
748 struct mpt_pci_driver *dd_cbfunc;
751 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
754 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
756 list_for_each_entry(ioc, &ioc_list, list) {
757 if (dd_cbfunc->remove)
758 dd_cbfunc->remove(ioc->pcidev);
761 MptDeviceDriverHandlers[cb_idx] = NULL;
765 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
767 * mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024)
768 * allocated per MPT adapter.
769 * @cb_idx: Handle of registered MPT protocol driver
770 * @ioc: Pointer to MPT adapter structure
772 * Returns pointer to a MPT request frame or %NULL if none are available
773 * or IOC is not active.
776 mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc)
780 u16 req_idx; /* Request index */
782 /* validate handle and ioc identifier */
786 printk(KERN_WARNING "IOC Not Active! mpt_get_msg_frame returning NULL!\n");
789 /* If interrupts are not attached, do not return a request frame */
793 spin_lock_irqsave(&ioc->FreeQlock, flags);
794 if (!list_empty(&ioc->FreeQ)) {
797 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
798 u.frame.linkage.list);
799 list_del(&mf->u.frame.linkage.list);
800 mf->u.frame.linkage.arg1 = 0;
801 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
802 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
804 req_idx = req_offset / ioc->req_sz;
805 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
806 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
807 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame; /* Default, will be changed if necessary in SG generation */
814 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
818 printk(KERN_WARNING "IOC Active. No free Msg Frames! Count 0x%x Max 0x%x\n", ioc->mfcnt, ioc->req_depth);
820 if (mfcounter == PRINT_MF_COUNT)
821 printk(KERN_INFO "MF Count 0x%x Max 0x%x \n", ioc->mfcnt, ioc->req_depth);
824 dmfprintk(ioc, printk(KERN_INFO MYNAM ": %s: mpt_get_msg_frame(%d,%d), got mf=%p\n",
825 ioc->name, cb_idx, ioc->id, mf));
829 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
831 * mpt_put_msg_frame - Send a protocol specific MPT request frame
833 * @cb_idx: Handle of registered MPT protocol driver
834 * @ioc: Pointer to MPT adapter structure
835 * @mf: Pointer to MPT request frame
837 * This routine posts a MPT request frame to the request post FIFO of a
838 * specific MPT adapter.
841 mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
845 u16 req_idx; /* Request index */
847 /* ensure values are reset properly! */
848 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
849 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
851 req_idx = req_offset / ioc->req_sz;
852 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
853 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
855 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
857 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
858 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx, ioc->RequestNB[req_idx]));
859 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
863 * mpt_put_msg_frame_hi_pri - Send a protocol specific MPT request frame
864 * to a IOC using hi priority request queue.
865 * @cb_idx: Handle of registered MPT protocol driver
866 * @ioc: Pointer to MPT adapter structure
867 * @mf: Pointer to MPT request frame
869 * This routine posts a MPT request frame to the request post FIFO of a
870 * specific MPT adapter.
873 mpt_put_msg_frame_hi_pri(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
877 u16 req_idx; /* Request index */
879 /* ensure values are reset properly! */
880 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
881 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
882 req_idx = req_offset / ioc->req_sz;
883 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
884 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
886 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
888 mf_dma_addr = (ioc->req_frames_low_dma + req_offset);
889 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d\n",
890 ioc->name, mf_dma_addr, req_idx));
891 CHIPREG_WRITE32(&ioc->chip->RequestHiPriFifo, mf_dma_addr);
894 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
896 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
897 * @handle: Handle of registered MPT protocol driver
898 * @ioc: Pointer to MPT adapter structure
899 * @mf: Pointer to MPT request frame
901 * This routine places a MPT request frame back on the MPT adapter's
905 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
909 /* Put Request back on FreeQ! */
910 spin_lock_irqsave(&ioc->FreeQlock, flags);
911 mf->u.frame.linkage.arg1 = 0xdeadbeaf; /* signature to know if this mf is freed */
912 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
916 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
919 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
921 * mpt_add_sge - Place a simple SGE at address pAddr.
922 * @pAddr: virtual address for SGE
923 * @flagslength: SGE flags and data transfer length
924 * @dma_addr: Physical address
926 * This routine places a MPT request frame back on the MPT adapter's
930 mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
932 if (sizeof(dma_addr_t) == sizeof(u64)) {
933 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
934 u32 tmp = dma_addr & 0xFFFFFFFF;
936 pSge->FlagsLength = cpu_to_le32(flagslength);
937 pSge->Address.Low = cpu_to_le32(tmp);
938 tmp = (u32) ((u64)dma_addr >> 32);
939 pSge->Address.High = cpu_to_le32(tmp);
942 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
943 pSge->FlagsLength = cpu_to_le32(flagslength);
944 pSge->Address = cpu_to_le32(dma_addr);
948 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
950 * mpt_send_handshake_request - Send MPT request via doorbell handshake method.
951 * @cb_idx: Handle of registered MPT protocol driver
952 * @ioc: Pointer to MPT adapter structure
953 * @reqBytes: Size of the request in bytes
954 * @req: Pointer to MPT request frame
955 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
957 * This routine is used exclusively to send MptScsiTaskMgmt
958 * requests since they are required to be sent via doorbell handshake.
960 * NOTE: It is the callers responsibility to byte-swap fields in the
961 * request which are greater than 1 byte in size.
963 * Returns 0 for success, non-zero for failure.
966 mpt_send_handshake_request(u8 cb_idx, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
972 /* State is known to be good upon entering
973 * this function so issue the bus reset
978 * Emulate what mpt_put_msg_frame() does /wrt to sanity
979 * setting cb_idx/req_idx. But ONLY if this request
980 * is in proper (pre-alloc'd) request buffer range...
982 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
983 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
984 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
985 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
986 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
989 /* Make sure there are no doorbells */
990 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
992 CHIPREG_WRITE32(&ioc->chip->Doorbell,
993 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
994 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
996 /* Wait for IOC doorbell int */
997 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
1001 /* Read doorbell and check for active bit */
1002 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
1005 dhsprintk(ioc, printk(KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
1008 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1010 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1014 /* Send request via doorbell handshake */
1015 req_as_bytes = (u8 *) req;
1016 for (ii = 0; ii < reqBytes/4; ii++) {
1019 word = ((req_as_bytes[(ii*4) + 0] << 0) |
1020 (req_as_bytes[(ii*4) + 1] << 8) |
1021 (req_as_bytes[(ii*4) + 2] << 16) |
1022 (req_as_bytes[(ii*4) + 3] << 24));
1023 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
1024 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1030 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
1035 /* Make sure there are no doorbells */
1036 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1041 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1043 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
1044 * @ioc: Pointer to MPT adapter structure
1045 * @access_control_value: define bits below
1046 * @sleepFlag: Specifies whether the process can sleep
1048 * Provides mechanism for the host driver to control the IOC's
1049 * Host Page Buffer access.
1051 * Access Control Value - bits[15:12]
1053 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1054 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1055 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1057 * Returns 0 for success, non-zero for failure.
1061 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1065 /* return if in use */
1066 if (CHIPREG_READ32(&ioc->chip->Doorbell)
1067 & MPI_DOORBELL_ACTIVE)
1070 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1072 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1073 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1074 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1075 (access_control_value<<12)));
1077 /* Wait for IOC to clear Doorbell Status bit */
1078 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1084 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1086 * mpt_host_page_alloc - allocate system memory for the fw
1087 * @ioc: Pointer to pointer to IOC adapter
1088 * @ioc_init: Pointer to ioc init config page
1090 * If we already allocated memory in past, then resend the same pointer.
1091 * Returns 0 for success, non-zero for failure.
1094 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1098 u32 host_page_buffer_sz=0;
1100 if(!ioc->HostPageBuffer) {
1102 host_page_buffer_sz =
1103 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1105 if(!host_page_buffer_sz)
1106 return 0; /* fw doesn't need any host buffers */
1108 /* spin till we get enough memory */
1109 while(host_page_buffer_sz > 0) {
1111 if((ioc->HostPageBuffer = pci_alloc_consistent(
1113 host_page_buffer_sz,
1114 &ioc->HostPageBuffer_dma)) != NULL) {
1116 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1117 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1118 ioc->name, ioc->HostPageBuffer,
1119 (u32)ioc->HostPageBuffer_dma,
1120 host_page_buffer_sz));
1121 ioc->alloc_total += host_page_buffer_sz;
1122 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1126 host_page_buffer_sz -= (4*1024);
1130 if(!ioc->HostPageBuffer) {
1131 printk(MYIOC_s_ERR_FMT
1132 "Failed to alloc memory for host_page_buffer!\n",
1137 psge = (char *)&ioc_init->HostPageBufferSGE;
1138 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1139 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1140 MPI_SGE_FLAGS_32_BIT_ADDRESSING |
1141 MPI_SGE_FLAGS_HOST_TO_IOC |
1142 MPI_SGE_FLAGS_END_OF_BUFFER;
1143 if (sizeof(dma_addr_t) == sizeof(u64)) {
1144 flags_length |= MPI_SGE_FLAGS_64_BIT_ADDRESSING;
1146 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1147 flags_length |= ioc->HostPageBuffer_sz;
1148 mpt_add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1149 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1154 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1156 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1157 * @iocid: IOC unique identifier (integer)
1158 * @iocpp: Pointer to pointer to IOC adapter
1160 * Given a unique IOC identifier, set pointer to the associated MPT
1161 * adapter structure.
1163 * Returns iocid and sets iocpp if iocid is found.
1164 * Returns -1 if iocid is not found.
1167 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1171 list_for_each_entry(ioc,&ioc_list,list) {
1172 if (ioc->id == iocid) {
1183 * mpt_get_product_name - returns product string
1184 * @vendor: pci vendor id
1185 * @device: pci device id
1186 * @revision: pci revision id
1187 * @prod_name: string returned
1189 * Returns product string displayed when driver loads,
1190 * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1194 mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name)
1196 char *product_str = NULL;
1198 if (vendor == PCI_VENDOR_ID_BROCADE) {
1201 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1205 product_str = "BRE040 A0";
1208 product_str = "BRE040 A1";
1211 product_str = "BRE040";
1221 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1222 product_str = "LSIFC909 B1";
1224 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1225 product_str = "LSIFC919 B0";
1227 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1228 product_str = "LSIFC929 B0";
1230 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1231 if (revision < 0x80)
1232 product_str = "LSIFC919X A0";
1234 product_str = "LSIFC919XL A1";
1236 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1237 if (revision < 0x80)
1238 product_str = "LSIFC929X A0";
1240 product_str = "LSIFC929XL A1";
1242 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1243 product_str = "LSIFC939X A1";
1245 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1246 product_str = "LSIFC949X A1";
1248 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1252 product_str = "LSIFC949E A0";
1255 product_str = "LSIFC949E A1";
1258 product_str = "LSIFC949E";
1262 case MPI_MANUFACTPAGE_DEVID_53C1030:
1266 product_str = "LSI53C1030 A0";
1269 product_str = "LSI53C1030 B0";
1272 product_str = "LSI53C1030 B1";
1275 product_str = "LSI53C1030 B2";
1278 product_str = "LSI53C1030 C0";
1281 product_str = "LSI53C1030T A0";
1284 product_str = "LSI53C1030T A2";
1287 product_str = "LSI53C1030T A3";
1290 product_str = "LSI53C1020A A1";
1293 product_str = "LSI53C1030";
1297 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1301 product_str = "LSI53C1035 A2";
1304 product_str = "LSI53C1035 B0";
1307 product_str = "LSI53C1035";
1311 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1315 product_str = "LSISAS1064 A1";
1318 product_str = "LSISAS1064 A2";
1321 product_str = "LSISAS1064 A3";
1324 product_str = "LSISAS1064 A4";
1327 product_str = "LSISAS1064";
1331 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1335 product_str = "LSISAS1064E A0";
1338 product_str = "LSISAS1064E B0";
1341 product_str = "LSISAS1064E B1";
1344 product_str = "LSISAS1064E B2";
1347 product_str = "LSISAS1064E B3";
1350 product_str = "LSISAS1064E";
1354 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1358 product_str = "LSISAS1068 A0";
1361 product_str = "LSISAS1068 B0";
1364 product_str = "LSISAS1068 B1";
1367 product_str = "LSISAS1068";
1371 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1375 product_str = "LSISAS1068E A0";
1378 product_str = "LSISAS1068E B0";
1381 product_str = "LSISAS1068E B1";
1384 product_str = "LSISAS1068E B2";
1387 product_str = "LSISAS1068E B3";
1390 product_str = "LSISAS1068E";
1394 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1398 product_str = "LSISAS1078 A0";
1401 product_str = "LSISAS1078 B0";
1404 product_str = "LSISAS1078 C0";
1407 product_str = "LSISAS1078 C1";
1410 product_str = "LSISAS1078 C2";
1413 product_str = "LSISAS1078";
1421 sprintf(prod_name, "%s", product_str);
1424 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1426 * mpt_attach - Install a PCI intelligent MPT adapter.
1427 * @pdev: Pointer to pci_dev structure
1428 * @id: PCI device ID information
1430 * This routine performs all the steps necessary to bring the IOC of
1431 * a MPT adapter to a OPERATIONAL state. This includes registering
1432 * memory regions, registering the interrupt, and allocating request
1433 * and reply memory pools.
1435 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1438 * Returns 0 for success, non-zero for failure.
1440 * TODO: Add support for polled controllers
1443 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1447 unsigned long mem_phys;
1456 static int mpt_ids = 0;
1457 #ifdef CONFIG_PROC_FS
1458 struct proc_dir_entry *dent, *ent;
1461 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1463 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1467 ioc->debug_level = mpt_debug_level;
1468 if (mpt_debug_level)
1469 printk(KERN_INFO MYNAM ": mpt_debug_level=%xh\n", mpt_debug_level);
1471 if (pci_enable_device(pdev))
1474 dinitprintk(ioc, printk(KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1476 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
1477 dprintk(ioc, printk(KERN_INFO MYNAM
1478 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n"));
1479 } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
1480 printk(KERN_WARNING MYNAM ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");
1484 if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
1485 dprintk(ioc, printk(KERN_INFO MYNAM
1486 ": Using 64 bit consistent mask\n"));
1488 dprintk(ioc, printk(KERN_INFO MYNAM
1489 ": Not using 64 bit consistent mask\n"));
1492 ioc->alloc_total = sizeof(MPT_ADAPTER);
1493 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1494 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1497 ioc->diagPending = 0;
1498 spin_lock_init(&ioc->diagLock);
1499 spin_lock_init(&ioc->initializing_hba_lock);
1501 /* Initialize the event logging.
1503 ioc->eventTypes = 0; /* None */
1504 ioc->eventContext = 0;
1505 ioc->eventLogSize = 0;
1512 ioc->cached_fw = NULL;
1514 /* Initilize SCSI Config Data structure
1516 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1518 /* Initialize the running configQ head.
1520 INIT_LIST_HEAD(&ioc->configQ);
1522 /* Initialize the fc rport list head.
1524 INIT_LIST_HEAD(&ioc->fc_rports);
1526 /* Find lookup slot. */
1527 INIT_LIST_HEAD(&ioc->list);
1528 ioc->id = mpt_ids++;
1530 mem_phys = msize = 0;
1532 for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1533 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1536 /* Get I/O space! */
1537 port = pci_resource_start(pdev, ii);
1538 psize = pci_resource_len(pdev,ii);
1543 mem_phys = pci_resource_start(pdev, ii);
1544 msize = pci_resource_len(pdev,ii);
1547 ioc->mem_size = msize;
1550 /* Get logical ptr for PciMem0 space */
1551 /*mem = ioremap(mem_phys, msize);*/
1552 mem = ioremap(mem_phys, msize);
1554 printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n");
1559 dinitprintk(ioc, printk(KERN_INFO MYNAM ": mem = %p, mem_phys = %lx\n", mem, mem_phys));
1561 dinitprintk(ioc, printk(KERN_INFO MYNAM ": facts @ %p, pfacts[0] @ %p\n",
1562 &ioc->facts, &ioc->pfacts[0]));
1564 ioc->mem_phys = mem_phys;
1565 ioc->chip = (SYSIF_REGS __iomem *)mem;
1567 /* Save Port IO values in case we need to do downloadboot */
1569 u8 *pmem = (u8*)port;
1570 ioc->pio_mem_phys = port;
1571 ioc->pio_chip = (SYSIF_REGS __iomem *)pmem;
1574 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1575 mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name);
1577 switch (pdev->device)
1579 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1580 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1581 ioc->errata_flag_1064 = 1;
1582 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1583 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1584 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1585 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1589 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1590 if (revision < XL_929) {
1591 /* 929X Chip Fix. Set Split transactions level
1592 * for PCIX. Set MOST bits to zero.
1594 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1596 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1598 /* 929XL Chip Fix. Set MMRBC to 0x08.
1600 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1602 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1607 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1608 /* 919X Chip Fix. Set Split transactions level
1609 * for PCIX. Set MOST bits to zero.
1611 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1613 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1617 case MPI_MANUFACTPAGE_DEVID_53C1030:
1618 /* 1030 Chip Fix. Disable Split transactions
1619 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1621 if (revision < C0_1030) {
1622 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1624 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1627 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1628 ioc->bus_type = SPI;
1631 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1632 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1633 ioc->errata_flag_1064 = 1;
1635 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1636 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1637 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1638 ioc->bus_type = SAS;
1641 if (ioc->errata_flag_1064)
1642 pci_disable_io_access(pdev);
1644 sprintf(ioc->name, "ioc%d", ioc->id);
1646 spin_lock_init(&ioc->FreeQlock);
1649 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1651 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1653 /* Set lookup ptr. */
1654 list_add_tail(&ioc->list, &ioc_list);
1656 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1658 mpt_detect_bound_ports(ioc, pdev);
1660 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1662 printk(KERN_WARNING MYNAM
1663 ": WARNING - %s did not initialize properly! (%d)\n",
1666 list_del(&ioc->list);
1668 ioc->alt_ioc->alt_ioc = NULL;
1671 pci_set_drvdata(pdev, NULL);
1675 /* call per device driver probe entry point */
1676 for(cb_idx=0; cb_idx<MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
1677 if(MptDeviceDriverHandlers[cb_idx] &&
1678 MptDeviceDriverHandlers[cb_idx]->probe) {
1679 MptDeviceDriverHandlers[cb_idx]->probe(pdev,id);
1683 #ifdef CONFIG_PROC_FS
1685 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1687 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1689 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1691 ent->read_proc = procmpt_iocinfo_read;
1694 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1696 ent->read_proc = procmpt_summary_read;
1705 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1707 * mpt_detach - Remove a PCI intelligent MPT adapter.
1708 * @pdev: Pointer to pci_dev structure
1712 mpt_detach(struct pci_dev *pdev)
1714 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1718 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
1719 remove_proc_entry(pname, NULL);
1720 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
1721 remove_proc_entry(pname, NULL);
1722 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
1723 remove_proc_entry(pname, NULL);
1725 /* call per device driver remove entry point */
1726 for(cb_idx=0; cb_idx<MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
1727 if(MptDeviceDriverHandlers[cb_idx] &&
1728 MptDeviceDriverHandlers[cb_idx]->remove) {
1729 MptDeviceDriverHandlers[cb_idx]->remove(pdev);
1733 /* Disable interrupts! */
1734 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1737 synchronize_irq(pdev->irq);
1739 /* Clear any lingering interrupt */
1740 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1742 CHIPREG_READ32(&ioc->chip->IntStatus);
1744 mpt_adapter_dispose(ioc);
1746 pci_set_drvdata(pdev, NULL);
1749 /**************************************************************************
1753 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1755 * mpt_suspend - Fusion MPT base driver suspend routine.
1756 * @pdev: Pointer to pci_dev structure
1757 * @state: new state to enter
1760 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
1763 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1765 device_state=pci_choose_state(pdev, state);
1767 printk(MYIOC_s_INFO_FMT
1768 "pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
1769 ioc->name, pdev, pci_name(pdev), device_state);
1771 pci_save_state(pdev);
1773 /* put ioc into READY_STATE */
1774 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
1775 printk(MYIOC_s_ERR_FMT
1776 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
1779 /* disable interrupts */
1780 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1783 /* Clear any lingering interrupt */
1784 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1786 pci_disable_device(pdev);
1787 pci_set_power_state(pdev, device_state);
1792 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1794 * mpt_resume - Fusion MPT base driver resume routine.
1795 * @pdev: Pointer to pci_dev structure
1798 mpt_resume(struct pci_dev *pdev)
1800 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1801 u32 device_state = pdev->current_state;
1805 printk(MYIOC_s_INFO_FMT
1806 "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
1807 ioc->name, pdev, pci_name(pdev), device_state);
1809 pci_set_power_state(pdev, 0);
1810 pci_restore_state(pdev);
1811 err = pci_enable_device(pdev);
1815 /* enable interrupts */
1816 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
1819 printk(MYIOC_s_INFO_FMT
1820 "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1822 (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1823 CHIPREG_READ32(&ioc->chip->Doorbell));
1825 /* bring ioc to operational state */
1826 if ((recovery_state = mpt_do_ioc_recovery(ioc,
1827 MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {
1828 printk(MYIOC_s_INFO_FMT
1829 "pci-resume: Cannot recover, error:[%x]\n",
1830 ioc->name, recovery_state);
1832 printk(MYIOC_s_INFO_FMT
1833 "pci-resume: success\n", ioc->name);
1841 mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase)
1843 if ((MptDriverClass[index] == MPTSPI_DRIVER &&
1844 ioc->bus_type != SPI) ||
1845 (MptDriverClass[index] == MPTFC_DRIVER &&
1846 ioc->bus_type != FC) ||
1847 (MptDriverClass[index] == MPTSAS_DRIVER &&
1848 ioc->bus_type != SAS))
1849 /* make sure we only call the relevant reset handler
1852 return (MptResetHandlers[index])(ioc, reset_phase);
1855 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1857 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1858 * @ioc: Pointer to MPT adapter structure
1859 * @reason: Event word / reason
1860 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1862 * This routine performs all the steps necessary to bring the IOC
1863 * to a OPERATIONAL state.
1865 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1870 * -1 if failed to get board READY
1871 * -2 if READY but IOCFacts Failed
1872 * -3 if READY but PrimeIOCFifos Failed
1873 * -4 if READY but IOCInit Failed
1876 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1878 int hard_reset_done = 0;
1879 int alt_ioc_ready = 0;
1886 int reset_alt_ioc_active = 0;
1887 int irq_allocated = 0;
1890 printk(KERN_INFO MYNAM ": Initiating %s %s\n",
1891 ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
1893 /* Disable reply interrupts (also blocks FreeQ) */
1894 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1898 if (ioc->alt_ioc->active)
1899 reset_alt_ioc_active = 1;
1901 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1902 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
1903 ioc->alt_ioc->active = 0;
1907 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
1910 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
1911 if (hard_reset_done == -4) {
1912 printk(KERN_WARNING MYNAM ": %s Owned by PEER..skipping!\n",
1915 if (reset_alt_ioc_active && ioc->alt_ioc) {
1916 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1917 dprintk(ioc, printk(KERN_INFO MYNAM
1918 ": alt-%s reply irq re-enabled\n",
1919 ioc->alt_ioc->name));
1920 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
1921 ioc->alt_ioc->active = 1;
1925 printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",
1931 /* hard_reset_done = 0 if a soft reset was performed
1932 * and 1 if a hard reset was performed.
1934 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
1935 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
1938 printk(KERN_WARNING MYNAM
1939 ": alt-%s: Not ready WARNING!\n",
1940 ioc->alt_ioc->name);
1943 for (ii=0; ii<5; ii++) {
1944 /* Get IOC facts! Allow 5 retries */
1945 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
1951 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Retry IocFacts failed rc=%x\n", ioc->name, rc));
1953 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1954 MptDisplayIocCapabilities(ioc);
1957 if (alt_ioc_ready) {
1958 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
1959 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1960 "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
1961 /* Retry - alt IOC was initialized once
1963 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
1966 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1967 "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
1969 reset_alt_ioc_active = 0;
1970 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1971 MptDisplayIocCapabilities(ioc->alt_ioc);
1976 * Device is reset now. It must have de-asserted the interrupt line
1977 * (if it was asserted) and it should be safe to register for the
1980 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1982 if (ioc->pcidev->irq) {
1983 if (mpt_msi_enable && !pci_enable_msi(ioc->pcidev))
1984 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
1986 rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
1987 IRQF_SHARED, ioc->name, ioc);
1989 printk(MYIOC_s_ERR_FMT "Unable to allocate "
1990 "interrupt %d!\n", ioc->name,
1993 pci_disable_msi(ioc->pcidev);
1997 ioc->pci_irq = ioc->pcidev->irq;
1998 pci_set_master(ioc->pcidev); /* ?? */
1999 pci_set_drvdata(ioc->pcidev, ioc);
2000 dprintk(ioc, printk(KERN_INFO MYNAM ": %s installed at interrupt "
2001 "%d\n", ioc->name, ioc->pcidev->irq));
2005 /* Prime reply & request queues!
2006 * (mucho alloc's) Must be done prior to
2007 * init as upper addresses are needed for init.
2008 * If fails, continue with alt-ioc processing
2010 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
2013 /* May need to check/upload firmware & data here!
2014 * If fails, continue with alt-ioc processing
2016 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
2019 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
2020 printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
2021 ioc->alt_ioc->name, rc);
2023 reset_alt_ioc_active = 0;
2026 if (alt_ioc_ready) {
2027 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
2029 reset_alt_ioc_active = 0;
2030 printk(KERN_WARNING MYNAM
2031 ": alt-%s: (%d) init failure WARNING!\n",
2032 ioc->alt_ioc->name, rc);
2036 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
2037 if (ioc->upload_fw) {
2038 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2039 "firmware upload required!\n", ioc->name));
2041 /* Controller is not operational, cannot do upload
2044 rc = mpt_do_upload(ioc, sleepFlag);
2046 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2048 * Maintain only one pointer to FW memory
2049 * so there will not be two attempt to
2050 * downloadboot onboard dual function
2051 * chips (mpt_adapter_disable,
2054 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2055 ": mpt_upload: alt_%s has cached_fw=%p \n",
2056 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
2057 ioc->alt_ioc->cached_fw = NULL;
2060 printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
2068 /* Enable! (reply interrupt) */
2069 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
2073 if (reset_alt_ioc_active && ioc->alt_ioc) {
2074 /* (re)Enable alt-IOC! (reply interrupt) */
2075 dinitprintk(ioc, printk(KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
2076 ioc->alt_ioc->name));
2077 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2078 ioc->alt_ioc->active = 1;
2081 /* Enable MPT base driver management of EventNotification
2082 * and EventAck handling.
2084 if ((ret == 0) && (!ioc->facts.EventState))
2085 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
2087 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2088 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
2090 /* Add additional "reason" check before call to GetLanConfigPages
2091 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2092 * recursive scenario; GetLanConfigPages times out, timer expired
2093 * routine calls HardResetHandler, which calls into here again,
2094 * and we try GetLanConfigPages again...
2096 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2099 * Initalize link list for inactive raid volumes.
2101 init_MUTEX(&ioc->raid_data.inactive_list_mutex);
2102 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2104 if (ioc->bus_type == SAS) {
2106 /* clear persistency table */
2107 if(ioc->facts.IOCExceptions &
2108 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
2109 ret = mptbase_sas_persist_operation(ioc,
2110 MPI_SAS_OP_CLEAR_NOT_PRESENT);
2117 mpt_findImVolumes(ioc);
2119 } else if (ioc->bus_type == FC) {
2120 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
2121 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2123 * Pre-fetch the ports LAN MAC address!
2124 * (LANPage1_t stuff)
2126 (void) GetLanConfigPages(ioc);
2127 a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2128 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2129 "LanAddr = %02X:%02X:%02X:"
2131 ioc->name, a[5], a[4],
2132 a[3], a[2], a[1], a[0] ));
2136 /* Get NVRAM and adapter maximums from SPP 0 and 2
2138 mpt_GetScsiPortSettings(ioc, 0);
2140 /* Get version and length of SDP 1
2142 mpt_readScsiDevicePageHeaders(ioc, 0);
2146 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
2147 mpt_findImVolumes(ioc);
2149 /* Check, and possibly reset, the coalescing value
2151 mpt_read_ioc_pg_1(ioc);
2153 mpt_read_ioc_pg_4(ioc);
2156 GetIoUnitPage2(ioc);
2157 mpt_get_manufacturing_pg_0(ioc);
2161 * Call each currently registered protocol IOC reset handler
2162 * with post-reset indication.
2163 * NOTE: If we're doing _IOC_BRINGUP, there can be no
2164 * MptResetHandlers[] registered yet.
2166 if (hard_reset_done) {
2168 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
2169 if ((ret == 0) && MptResetHandlers[cb_idx]) {
2170 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2171 "Calling IOC post_reset handler #%d\n",
2172 ioc->name, cb_idx));
2173 rc += mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET);
2177 if (alt_ioc_ready && MptResetHandlers[cb_idx]) {
2178 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2179 "Calling alt-%s post_reset handler #%d\n",
2180 ioc->name, ioc->alt_ioc->name, cb_idx));
2181 rc += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_POST_RESET);
2185 /* FIXME? Examine results here? */
2189 if ((ret != 0) && irq_allocated) {
2190 free_irq(ioc->pci_irq, ioc);
2192 pci_disable_msi(ioc->pcidev);
2197 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2199 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2200 * @ioc: Pointer to MPT adapter structure
2201 * @pdev: Pointer to (struct pci_dev) structure
2203 * Search for PCI bus/dev_function which matches
2204 * PCI bus/dev_function (+/-1) for newly discovered 929,
2205 * 929X, 1030 or 1035.
2207 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2208 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2211 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
2213 struct pci_dev *peer=NULL;
2214 unsigned int slot = PCI_SLOT(pdev->devfn);
2215 unsigned int func = PCI_FUNC(pdev->devfn);
2216 MPT_ADAPTER *ioc_srch;
2218 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PCI device %s devfn=%x/%x,"
2219 " searching for devfn match on %x or %x\n",
2220 ioc->name, pci_name(pdev), pdev->bus->number,
2221 pdev->devfn, func-1, func+1));
2223 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
2225 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
2230 list_for_each_entry(ioc_srch, &ioc_list, list) {
2231 struct pci_dev *_pcidev = ioc_srch->pcidev;
2232 if (_pcidev == peer) {
2233 /* Paranoia checks */
2234 if (ioc->alt_ioc != NULL) {
2235 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
2236 ioc->name, ioc->alt_ioc->name);
2238 } else if (ioc_srch->alt_ioc != NULL) {
2239 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
2240 ioc_srch->name, ioc_srch->alt_ioc->name);
2243 dprintk(ioc, printk(KERN_INFO MYNAM ": FOUND! binding %s <==> %s\n",
2244 ioc->name, ioc_srch->name));
2245 ioc_srch->alt_ioc = ioc;
2246 ioc->alt_ioc = ioc_srch;
2252 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2254 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2255 * @ioc: Pointer to MPT adapter structure
2258 mpt_adapter_disable(MPT_ADAPTER *ioc)
2263 if (ioc->cached_fw != NULL) {
2264 ddlprintk(ioc, printk(KERN_INFO MYNAM ": mpt_adapter_disable: Pushing FW onto adapter\n"));
2265 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)ioc->cached_fw, NO_SLEEP)) < 0) {
2266 printk(KERN_WARNING MYNAM
2267 ": firmware downloadboot failure (%d)!\n", ret);
2271 /* Disable adapter interrupts! */
2272 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2274 /* Clear any lingering interrupt */
2275 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2277 if (ioc->alloc != NULL) {
2279 dexitprintk(ioc, printk(KERN_INFO MYNAM ": %s.free @ %p, sz=%d bytes\n",
2280 ioc->name, ioc->alloc, ioc->alloc_sz));
2281 pci_free_consistent(ioc->pcidev, sz,
2282 ioc->alloc, ioc->alloc_dma);
2283 ioc->reply_frames = NULL;
2284 ioc->req_frames = NULL;
2286 ioc->alloc_total -= sz;
2289 if (ioc->sense_buf_pool != NULL) {
2290 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2291 pci_free_consistent(ioc->pcidev, sz,
2292 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2293 ioc->sense_buf_pool = NULL;
2294 ioc->alloc_total -= sz;
2297 if (ioc->events != NULL){
2298 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2301 ioc->alloc_total -= sz;
2304 if (ioc->cached_fw != NULL) {
2305 sz = ioc->facts.FWImageSize;
2306 pci_free_consistent(ioc->pcidev, sz,
2307 ioc->cached_fw, ioc->cached_fw_dma);
2308 ioc->cached_fw = NULL;
2309 ioc->alloc_total -= sz;
2312 kfree(ioc->spi_data.nvram);
2313 mpt_inactive_raid_list_free(ioc);
2314 kfree(ioc->raid_data.pIocPg2);
2315 kfree(ioc->raid_data.pIocPg3);
2316 ioc->spi_data.nvram = NULL;
2317 ioc->raid_data.pIocPg3 = NULL;
2319 if (ioc->spi_data.pIocPg4 != NULL) {
2320 sz = ioc->spi_data.IocPg4Sz;
2321 pci_free_consistent(ioc->pcidev, sz,
2322 ioc->spi_data.pIocPg4,
2323 ioc->spi_data.IocPg4_dma);
2324 ioc->spi_data.pIocPg4 = NULL;
2325 ioc->alloc_total -= sz;
2328 if (ioc->ReqToChain != NULL) {
2329 kfree(ioc->ReqToChain);
2330 kfree(ioc->RequestNB);
2331 ioc->ReqToChain = NULL;
2334 kfree(ioc->ChainToChain);
2335 ioc->ChainToChain = NULL;
2337 if (ioc->HostPageBuffer != NULL) {
2338 if((ret = mpt_host_page_access_control(ioc,
2339 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2340 printk(KERN_ERR MYNAM
2341 ": %s: host page buffers free failed (%d)!\n",
2344 dexitprintk(ioc, printk(KERN_INFO MYNAM ": %s HostPageBuffer free @ %p, sz=%d bytes\n",
2345 ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
2346 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2347 ioc->HostPageBuffer,
2348 ioc->HostPageBuffer_dma);
2349 ioc->HostPageBuffer = NULL;
2350 ioc->HostPageBuffer_sz = 0;
2351 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2355 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2357 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2358 * @ioc: Pointer to MPT adapter structure
2360 * This routine unregisters h/w resources and frees all alloc'd memory
2361 * associated with a MPT adapter structure.
2364 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2366 int sz_first, sz_last;
2371 sz_first = ioc->alloc_total;
2373 mpt_adapter_disable(ioc);
2375 if (ioc->pci_irq != -1) {
2376 free_irq(ioc->pci_irq, ioc);
2378 pci_disable_msi(ioc->pcidev);
2382 if (ioc->memmap != NULL) {
2383 iounmap(ioc->memmap);
2387 #if defined(CONFIG_MTRR) && 0
2388 if (ioc->mtrr_reg > 0) {
2389 mtrr_del(ioc->mtrr_reg, 0, 0);
2390 dprintk(ioc, printk(KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name));
2394 /* Zap the adapter lookup ptr! */
2395 list_del(&ioc->list);
2397 sz_last = ioc->alloc_total;
2398 dprintk(ioc, printk(KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
2399 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2402 ioc->alt_ioc->alt_ioc = NULL;
2407 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2409 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2410 * @ioc: Pointer to MPT adapter structure
2413 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2417 printk(KERN_INFO "%s: ", ioc->name);
2419 printk("%s: ", ioc->prod_name);
2420 printk("Capabilities={");
2422 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2423 printk("Initiator");
2427 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2428 printk("%sTarget", i ? "," : "");
2432 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2433 printk("%sLAN", i ? "," : "");
2439 * This would probably evoke more questions than it's worth
2441 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2442 printk("%sLogBusAddr", i ? "," : "");
2450 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2452 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2453 * @ioc: Pointer to MPT_ADAPTER structure
2454 * @force: Force hard KickStart of IOC
2455 * @sleepFlag: Specifies whether the process can sleep
2458 * 1 - DIAG reset and READY
2459 * 0 - READY initially OR soft reset and READY
2460 * -1 - Any failure on KickStart
2461 * -2 - Msg Unit Reset Failed
2462 * -3 - IO Unit Reset Failed
2463 * -4 - IOC owned by a PEER
2466 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2471 int hard_reset_done = 0;
2476 /* Get current [raw] IOC state */
2477 ioc_state = mpt_GetIocState(ioc, 0);
2478 dhsprintk(ioc, printk(KERN_INFO MYNAM "::MakeIocReady, %s [raw] state=%08x\n", ioc->name, ioc_state));
2481 * Check to see if IOC got left/stuck in doorbell handshake
2482 * grip of death. If so, hard reset the IOC.
2484 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2486 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2490 /* Is it already READY? */
2491 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
2495 * Check to see if IOC is in FAULT state.
2497 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2499 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2501 printk(KERN_WARNING " FAULT code = %04xh\n",
2502 ioc_state & MPI_DOORBELL_DATA_MASK);
2506 * Hmmm... Did it get left operational?
2508 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2509 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC operational unexpected\n",
2513 * If PCI Peer, exit.
2514 * Else, if no fault conditions are present, issue a MessageUnitReset
2515 * Else, fall through to KickStart case
2517 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2518 dinitprintk(ioc, printk(KERN_INFO MYNAM
2519 ": whoinit 0x%x statefault %d force %d\n",
2520 whoinit, statefault, force));
2521 if (whoinit == MPI_WHOINIT_PCI_PEER)
2524 if ((statefault == 0 ) && (force == 0)) {
2525 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2532 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2533 if (hard_reset_done < 0)
2537 * Loop here waiting for IOC to come READY.
2540 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2542 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2543 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2545 * BIOS or previous driver load left IOC in OP state.
2546 * Reset messaging FIFOs.
2548 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2549 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2552 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2554 * Something is wrong. Try to get IOC back
2557 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2558 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2565 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2566 ioc->name, (int)((ii+5)/HZ));
2570 if (sleepFlag == CAN_SLEEP) {
2573 mdelay (1); /* 1 msec delay */
2578 if (statefault < 3) {
2579 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2581 statefault==1 ? "stuck handshake" : "IOC FAULT");
2584 return hard_reset_done;
2587 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2589 * mpt_GetIocState - Get the current state of a MPT adapter.
2590 * @ioc: Pointer to MPT_ADAPTER structure
2591 * @cooked: Request raw or cooked IOC state
2593 * Returns all IOC Doorbell register bits if cooked==0, else just the
2594 * Doorbell bits in MPI_IOC_STATE_MASK.
2597 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2602 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2603 // dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
2604 sc = s & MPI_IOC_STATE_MASK;
2607 ioc->last_state = sc;
2609 return cooked ? sc : s;
2612 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2614 * GetIocFacts - Send IOCFacts request to MPT adapter.
2615 * @ioc: Pointer to MPT_ADAPTER structure
2616 * @sleepFlag: Specifies whether the process can sleep
2617 * @reason: If recovery, only update facts.
2619 * Returns 0 for success, non-zero for failure.
2622 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2624 IOCFacts_t get_facts;
2625 IOCFactsReply_t *facts;
2633 /* IOC *must* NOT be in RESET state! */
2634 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2635 printk(KERN_ERR MYNAM ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
2641 facts = &ioc->facts;
2643 /* Destination (reply area)... */
2644 reply_sz = sizeof(*facts);
2645 memset(facts, 0, reply_sz);
2647 /* Request area (get_facts on the stack right now!) */
2648 req_sz = sizeof(get_facts);
2649 memset(&get_facts, 0, req_sz);
2651 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2652 /* Assert: All other get_facts fields are zero! */
2654 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2655 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2656 ioc->name, req_sz, reply_sz));
2658 /* No non-zero fields in the get_facts request are greater than
2659 * 1 byte in size, so we can just fire it off as is.
2661 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2662 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2667 * Now byte swap (GRRR) the necessary fields before any further
2668 * inspection of reply contents.
2670 * But need to do some sanity checks on MsgLength (byte) field
2671 * to make sure we don't zero IOC's req_sz!
2673 /* Did we get a valid reply? */
2674 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2675 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2677 * If not been here, done that, save off first WhoInit value
2679 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2680 ioc->FirstWhoInit = facts->WhoInit;
2683 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2684 facts->MsgContext = le32_to_cpu(facts->MsgContext);
2685 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2686 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2687 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2688 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
2689 /* CHECKME! IOCStatus, IOCLogInfo */
2691 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2692 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2695 * FC f/w version changed between 1.1 and 1.2
2696 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2697 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2699 if (facts->MsgVersion < 0x0102) {
2701 * Handle old FC f/w style, convert to new...
2703 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2704 facts->FWVersion.Word =
2705 ((oldv<<12) & 0xFF000000) |
2706 ((oldv<<8) & 0x000FFF00);
2708 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2710 facts->ProductID = le16_to_cpu(facts->ProductID);
2711 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
2712 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
2713 ioc->ir_firmware = 1;
2714 facts->CurrentHostMfaHighAddr =
2715 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2716 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2717 facts->CurrentSenseBufferHighAddr =
2718 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2719 facts->CurReplyFrameSize =
2720 le16_to_cpu(facts->CurReplyFrameSize);
2721 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
2724 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2725 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2726 * to 14 in MPI-1.01.0x.
2728 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2729 facts->MsgVersion > 0x0100) {
2730 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2733 sz = facts->FWImageSize;
2738 facts->FWImageSize = sz;
2740 if (!facts->RequestFrameSize) {
2741 /* Something is wrong! */
2742 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2747 r = sz = facts->BlockSize;
2748 vv = ((63 / (sz * 4)) + 1) & 0x03;
2749 ioc->NB_for_64_byte_frame = vv;
2755 ioc->NBShiftFactor = shiftFactor;
2756 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2757 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2758 ioc->name, vv, shiftFactor, r));
2760 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2762 * Set values for this IOC's request & reply frame sizes,
2763 * and request & reply queue depths...
2765 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2766 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2767 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2768 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2770 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "reply_sz=%3d, reply_depth=%4d\n",
2771 ioc->name, ioc->reply_sz, ioc->reply_depth));
2772 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "req_sz =%3d, req_depth =%4d\n",
2773 ioc->name, ioc->req_sz, ioc->req_depth));
2775 /* Get port facts! */
2776 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2780 printk(MYIOC_s_ERR_FMT
2781 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2782 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2783 RequestFrameSize)/sizeof(u32)));
2790 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2792 * GetPortFacts - Send PortFacts request to MPT adapter.
2793 * @ioc: Pointer to MPT_ADAPTER structure
2794 * @portnum: Port number
2795 * @sleepFlag: Specifies whether the process can sleep
2797 * Returns 0 for success, non-zero for failure.
2800 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2802 PortFacts_t get_pfacts;
2803 PortFactsReply_t *pfacts;
2809 /* IOC *must* NOT be in RESET state! */
2810 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2811 printk(KERN_ERR MYNAM ": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n",
2817 pfacts = &ioc->pfacts[portnum];
2819 /* Destination (reply area)... */
2820 reply_sz = sizeof(*pfacts);
2821 memset(pfacts, 0, reply_sz);
2823 /* Request area (get_pfacts on the stack right now!) */
2824 req_sz = sizeof(get_pfacts);
2825 memset(&get_pfacts, 0, req_sz);
2827 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2828 get_pfacts.PortNumber = portnum;
2829 /* Assert: All other get_pfacts fields are zero! */
2831 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending get PortFacts(%d) request\n",
2832 ioc->name, portnum));
2834 /* No non-zero fields in the get_pfacts request are greater than
2835 * 1 byte in size, so we can just fire it off as is.
2837 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2838 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2842 /* Did we get a valid reply? */
2844 /* Now byte swap the necessary fields in the response. */
2845 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2846 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2847 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2848 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2849 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2850 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2851 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2852 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2853 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2855 max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
2857 ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
2858 ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
2861 * Place all the devices on channels
2865 if (mpt_channel_mapping) {
2866 ioc->devices_per_bus = 1;
2867 ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
2873 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2875 * SendIocInit - Send IOCInit request to MPT adapter.
2876 * @ioc: Pointer to MPT_ADAPTER structure
2877 * @sleepFlag: Specifies whether the process can sleep
2879 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2881 * Returns 0 for success, non-zero for failure.
2884 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2887 MPIDefaultReply_t init_reply;
2893 memset(&ioc_init, 0, sizeof(ioc_init));
2894 memset(&init_reply, 0, sizeof(init_reply));
2896 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2897 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2899 /* If we are in a recovery mode and we uploaded the FW image,
2900 * then this pointer is not NULL. Skip the upload a second time.
2901 * Set this flag if cached_fw set for either IOC.
2903 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
2907 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "upload_fw %d facts.Flags=%x\n",
2908 ioc->name, ioc->upload_fw, ioc->facts.Flags));
2910 ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
2911 ioc_init.MaxBuses = (U8)ioc->number_of_buses;
2912 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n",
2913 ioc->name, ioc->facts.MsgVersion));
2914 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
2915 // set MsgVersion and HeaderVersion host driver was built with
2916 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
2917 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
2919 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
2920 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
2921 } else if(mpt_host_page_alloc(ioc, &ioc_init))
2924 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
2926 if (sizeof(dma_addr_t) == sizeof(u64)) {
2927 /* Save the upper 32-bits of the request
2928 * (reply) and sense buffers.
2930 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
2931 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2933 /* Force 32-bit addressing */
2934 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
2935 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
2938 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
2939 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
2940 ioc->facts.MaxDevices = ioc_init.MaxDevices;
2941 ioc->facts.MaxBuses = ioc_init.MaxBuses;
2943 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOCInit (req @ %p)\n",
2944 ioc->name, &ioc_init));
2946 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
2947 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
2949 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
2953 /* No need to byte swap the multibyte fields in the reply
2954 * since we don't even look at its contents.
2957 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending PortEnable (req @ %p)\n",
2958 ioc->name, &ioc_init));
2960 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
2961 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
2965 /* YIKES! SUPER IMPORTANT!!!
2966 * Poll IocState until _OPERATIONAL while IOC is doing
2967 * LoopInit and TargetDiscovery!
2970 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
2971 state = mpt_GetIocState(ioc, 1);
2972 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
2973 if (sleepFlag == CAN_SLEEP) {
2980 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
2981 ioc->name, (int)((count+5)/HZ));
2985 state = mpt_GetIocState(ioc, 1);
2988 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
2991 ioc->aen_event_read_flag=0;
2995 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2997 * SendPortEnable - Send PortEnable request to MPT adapter port.
2998 * @ioc: Pointer to MPT_ADAPTER structure
2999 * @portnum: Port number to enable
3000 * @sleepFlag: Specifies whether the process can sleep
3002 * Send PortEnable to bring IOC to OPERATIONAL state.
3004 * Returns 0 for success, non-zero for failure.
3007 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3009 PortEnable_t port_enable;
3010 MPIDefaultReply_t reply_buf;
3015 /* Destination... */
3016 reply_sz = sizeof(MPIDefaultReply_t);
3017 memset(&reply_buf, 0, reply_sz);
3019 req_sz = sizeof(PortEnable_t);
3020 memset(&port_enable, 0, req_sz);
3022 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
3023 port_enable.PortNumber = portnum;
3024 /* port_enable.ChainOffset = 0; */
3025 /* port_enable.MsgFlags = 0; */
3026 /* port_enable.MsgContext = 0; */
3028 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Port(%d)Enable (req @ %p)\n",
3029 ioc->name, portnum, &port_enable));
3031 /* RAID FW may take a long time to enable
3033 if (ioc->ir_firmware || ioc->bus_type == SAS) {
3034 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3035 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3036 300 /*seconds*/, sleepFlag);
3038 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3039 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3040 30 /*seconds*/, sleepFlag);
3046 * mpt_alloc_fw_memory - allocate firmware memory
3047 * @ioc: Pointer to MPT_ADAPTER structure
3048 * @size: total FW bytes
3050 * If memory has already been allocated, the same (cached) value
3054 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
3057 return; /* use already allocated memory */
3058 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
3059 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
3060 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
3061 ioc->alloc_total += size;
3062 ioc->alt_ioc->alloc_total -= size;
3064 if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
3065 ioc->alloc_total += size;
3069 * mpt_free_fw_memory - free firmware memory
3070 * @ioc: Pointer to MPT_ADAPTER structure
3072 * If alt_img is NULL, delete from ioc structure.
3073 * Else, delete a secondary image in same format.
3076 mpt_free_fw_memory(MPT_ADAPTER *ioc)
3080 sz = ioc->facts.FWImageSize;
3081 dinitprintk(ioc, printk(KERN_INFO MYNAM "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3082 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3083 pci_free_consistent(ioc->pcidev, sz,
3084 ioc->cached_fw, ioc->cached_fw_dma);
3085 ioc->cached_fw = NULL;
3091 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3093 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3094 * @ioc: Pointer to MPT_ADAPTER structure
3095 * @sleepFlag: Specifies whether the process can sleep
3097 * Returns 0 for success, >0 for handshake failure
3098 * <0 for fw upload failure.
3100 * Remark: If bound IOC and a successful FWUpload was performed
3101 * on the bound IOC, the second image is discarded
3102 * and memory is free'd. Both channels must upload to prevent
3103 * IOC from running in degraded mode.
3106 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3108 u8 request[ioc->req_sz];
3109 u8 reply[sizeof(FWUploadReply_t)];
3110 FWUpload_t *prequest;
3111 FWUploadReply_t *preply;
3112 FWUploadTCSGE_t *ptcsge;
3115 int ii, sz, reply_sz;
3118 /* If the image size is 0, we are done.
3120 if ((sz = ioc->facts.FWImageSize) == 0)
3123 mpt_alloc_fw_memory(ioc, sz);
3125 dinitprintk(ioc, printk(KERN_INFO MYNAM ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3126 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3128 if (ioc->cached_fw == NULL) {
3134 prequest = (FWUpload_t *)&request;
3135 preply = (FWUploadReply_t *)&reply;
3137 /* Destination... */
3138 memset(prequest, 0, ioc->req_sz);
3140 reply_sz = sizeof(reply);
3141 memset(preply, 0, reply_sz);
3143 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
3144 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
3146 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
3147 ptcsge->DetailsLength = 12;
3148 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
3149 ptcsge->ImageSize = cpu_to_le32(sz);
3151 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
3153 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3154 mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma);
3156 sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
3157 dinitprintk(ioc, printk(KERN_INFO MYNAM ": Sending FW Upload (req @ %p) sgeoffset=%d \n",
3158 prequest, sgeoffset));
3159 DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest)
3161 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
3162 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
3164 dinitprintk(ioc, printk(KERN_INFO MYNAM ": FW Upload completed rc=%x \n", ii));
3166 cmdStatus = -EFAULT;
3168 /* Handshake transfer was complete and successful.
3169 * Check the Reply Frame.
3171 int status, transfer_sz;
3172 status = le16_to_cpu(preply->IOCStatus);
3173 if (status == MPI_IOCSTATUS_SUCCESS) {
3174 transfer_sz = le32_to_cpu(preply->ActualImageSize);
3175 if (transfer_sz == sz)
3179 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n",
3180 ioc->name, cmdStatus));
3185 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": fw upload failed, freeing image \n",
3187 mpt_free_fw_memory(ioc);
3193 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3195 * mpt_downloadboot - DownloadBoot code
3196 * @ioc: Pointer to MPT_ADAPTER structure
3197 * @pFwHeader: Pointer to firmware header info
3198 * @sleepFlag: Specifies whether the process can sleep
3200 * FwDownloadBoot requires Programmed IO access.
3202 * Returns 0 for success
3203 * -1 FW Image size is 0
3204 * -2 No valid cached_fw Pointer
3205 * <0 for fw upload failure.
3208 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3210 MpiExtImageHeader_t *pExtImage;
3220 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3221 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
3223 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3224 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3225 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3226 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3227 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3228 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3230 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
3233 if (sleepFlag == CAN_SLEEP) {
3239 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3240 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3242 for (count = 0; count < 30; count ++) {
3243 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3244 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3245 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESET_ADAPTER cleared, count=%d\n",
3250 if (sleepFlag == CAN_SLEEP) {
3257 if ( count == 30 ) {
3258 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot failed! "
3259 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3260 ioc->name, diag0val));
3264 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3265 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3266 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3267 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3268 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3269 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3271 /* Set the DiagRwEn and Disable ARM bits */
3272 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3274 fwSize = (pFwHeader->ImageSize + 3)/4;
3275 ptrFw = (u32 *) pFwHeader;
3277 /* Write the LoadStartAddress to the DiagRw Address Register
3278 * using Programmed IO
3280 if (ioc->errata_flag_1064)
3281 pci_enable_io_access(ioc->pcidev);
3283 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3284 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "LoadStart addr written 0x%x \n",
3285 ioc->name, pFwHeader->LoadStartAddress));
3287 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write FW Image: 0x%x bytes @ %p\n",
3288 ioc->name, fwSize*4, ptrFw));
3290 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3293 nextImage = pFwHeader->NextImageHeaderOffset;
3295 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3297 load_addr = pExtImage->LoadStartAddress;
3299 fwSize = (pExtImage->ImageSize + 3) >> 2;
3300 ptrFw = (u32 *)pExtImage;
3302 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3303 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3304 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3307 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3309 nextImage = pExtImage->NextImageHeaderOffset;
3312 /* Write the IopResetVectorRegAddr */
3313 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
3314 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3316 /* Write the IopResetVectorValue */
3317 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3318 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3320 /* Clear the internal flash bad bit - autoincrementing register,
3321 * so must do two writes.
3323 if (ioc->bus_type == SPI) {
3325 * 1030 and 1035 H/W errata, workaround to access
3326 * the ClearFlashBadSignatureBit
3328 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3329 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3330 diagRwData |= 0x40000000;
3331 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3332 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3334 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3335 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3336 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3337 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3340 if (sleepFlag == CAN_SLEEP) {
3347 if (ioc->errata_flag_1064)
3348 pci_disable_io_access(ioc->pcidev);
3350 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3351 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot diag0val=%x, "
3352 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3353 ioc->name, diag0val));
3354 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3355 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot now diag0val=%x\n",
3356 ioc->name, diag0val));
3357 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3359 /* Write 0xFF to reset the sequencer */
3360 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3362 if (ioc->bus_type == SAS) {
3363 ioc_state = mpt_GetIocState(ioc, 0);
3364 if ( (GetIocFacts(ioc, sleepFlag,
3365 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3366 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "GetIocFacts failed: IocState=%x\n",
3367 ioc->name, ioc_state));
3372 for (count=0; count<HZ*20; count++) {
3373 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3374 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3375 "downloadboot successful! (count=%d) IocState=%x\n",
3376 ioc->name, count, ioc_state));
3377 if (ioc->bus_type == SAS) {
3380 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3381 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3382 "downloadboot: SendIocInit failed\n",
3386 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3387 "downloadboot: SendIocInit successful\n",
3391 if (sleepFlag == CAN_SLEEP) {
3397 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3398 "downloadboot failed! IocState=%x\n",ioc->name, ioc_state));
3402 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3404 * KickStart - Perform hard reset of MPT adapter.
3405 * @ioc: Pointer to MPT_ADAPTER structure
3406 * @force: Force hard reset
3407 * @sleepFlag: Specifies whether the process can sleep
3409 * This routine places MPT adapter in diagnostic mode via the
3410 * WriteSequence register, and then performs a hard reset of adapter
3411 * via the Diagnostic register.
3413 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3414 * or NO_SLEEP (interrupt thread, use mdelay)
3415 * force - 1 if doorbell active, board fault state
3416 * board operational, IOC_RECOVERY or
3417 * IOC_BRINGUP and there is an alt_ioc.
3421 * 1 - hard reset, READY
3422 * 0 - no reset due to History bit, READY
3423 * -1 - no reset due to History bit but not READY
3424 * OR reset but failed to come READY
3425 * -2 - no reset, could not enter DIAG mode
3426 * -3 - reset but bad FW bit
3429 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3431 int hard_reset_done = 0;
3435 dinitprintk(ioc, printk(KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
3436 if (ioc->bus_type == SPI) {
3437 /* Always issue a Msg Unit Reset first. This will clear some
3438 * SCSI bus hang conditions.
3440 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3442 if (sleepFlag == CAN_SLEEP) {
3449 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3450 if (hard_reset_done < 0)
3451 return hard_reset_done;
3453 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n",
3456 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3457 for (cnt=0; cnt<cntdn; cnt++) {
3458 ioc_state = mpt_GetIocState(ioc, 1);
3459 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3460 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStart successful! (cnt=%d)\n",
3462 return hard_reset_done;
3464 if (sleepFlag == CAN_SLEEP) {
3471 printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3472 ioc->name, ioc_state);
3476 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3478 * mpt_diag_reset - Perform hard reset of the adapter.
3479 * @ioc: Pointer to MPT_ADAPTER structure
3480 * @ignore: Set if to honor and clear to ignore
3481 * the reset history bit
3482 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3483 * else set to NO_SLEEP (use mdelay instead)
3485 * This routine places the adapter in diagnostic mode via the
3486 * WriteSequence register and then performs a hard reset of adapter
3487 * via the Diagnostic register. Adapter should be in ready state
3488 * upon successful completion.
3490 * Returns: 1 hard reset successful
3491 * 0 no reset performed because reset history bit set
3492 * -2 enabling diagnostic mode failed
3493 * -3 diagnostic reset failed
3496 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3498 MPT_ADAPTER *iocp=NULL;
3501 int hard_reset_done = 0;
3505 /* Clear any existing interrupts */
3506 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3508 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3509 drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3510 "address=%p\n", ioc->name, __FUNCTION__,
3511 &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3512 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3513 if (sleepFlag == CAN_SLEEP)
3518 for (count = 0; count < 60; count ++) {
3519 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3520 doorbell &= MPI_IOC_STATE_MASK;
3522 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3523 "looking for READY STATE: doorbell=%x"
3525 ioc->name, doorbell, count));
3526 if (doorbell == MPI_IOC_STATE_READY) {
3531 if (sleepFlag == CAN_SLEEP)
3539 /* Use "Diagnostic reset" method! (only thing available!) */
3540 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3542 if (ioc->debug_level & MPT_DEBUG) {
3544 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3545 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3546 ioc->name, diag0val, diag1val));
3549 /* Do the reset if we are told to ignore the reset history
3550 * or if the reset history is 0
3552 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3553 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3554 /* Write magic sequence to WriteSequence register
3555 * Loop until in diagnostic mode
3557 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3558 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3559 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3560 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3561 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3562 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3565 if (sleepFlag == CAN_SLEEP) {
3573 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3574 ioc->name, diag0val);
3579 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3581 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3582 ioc->name, diag0val));
3585 if (ioc->debug_level & MPT_DEBUG) {
3587 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3588 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3589 ioc->name, diag0val, diag1val));
3592 * Disable the ARM (Bug fix)
3595 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3599 * Now hit the reset bit in the Diagnostic register
3600 * (THE BIG HAMMER!) (Clears DRWE bit).
3602 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3603 hard_reset_done = 1;
3604 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset performed\n",
3608 * Call each currently registered protocol IOC reset handler
3609 * with pre-reset indication.
3610 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3611 * MptResetHandlers[] registered yet.
3617 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
3618 if (MptResetHandlers[cb_idx]) {
3619 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3620 "Calling IOC pre_reset handler #%d\n",
3621 ioc->name, cb_idx));
3622 r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET);
3624 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3625 "Calling alt-%s pre_reset handler #%d\n",
3626 ioc->name, ioc->alt_ioc->name, cb_idx));
3627 r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_PRE_RESET);
3631 /* FIXME? Examine results here? */
3636 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
3637 iocp = ioc->alt_ioc;
3639 /* If the DownloadBoot operation fails, the
3640 * IOC will be left unusable. This is a fatal error
3641 * case. _diag_reset will return < 0
3643 for (count = 0; count < 30; count ++) {
3644 diag0val = CHIPREG_READ32(&iocp->chip->Diagnostic);
3645 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3649 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n",
3650 iocp->name, diag0val, count));
3652 if (sleepFlag == CAN_SLEEP) {
3658 if ((count = mpt_downloadboot(ioc,
3659 (MpiFwHeader_t *)iocp->cached_fw, sleepFlag)) < 0) {
3660 printk(KERN_WARNING MYNAM
3661 ": firmware downloadboot failure (%d)!\n", count);
3665 /* Wait for FW to reload and for board
3666 * to go to the READY state.
3667 * Maximum wait is 60 seconds.
3668 * If fail, no error will check again
3669 * with calling program.
3671 for (count = 0; count < 60; count ++) {
3672 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3673 doorbell &= MPI_IOC_STATE_MASK;
3675 if (doorbell == MPI_IOC_STATE_READY) {
3680 if (sleepFlag == CAN_SLEEP) {
3689 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3690 if (ioc->debug_level & MPT_DEBUG) {
3692 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3693 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3694 ioc->name, diag0val, diag1val));
3697 /* Clear RESET_HISTORY bit! Place board in the
3698 * diagnostic mode to update the diag register.
3700 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3702 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3703 /* Write magic sequence to WriteSequence register
3704 * Loop until in diagnostic mode
3706 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3707 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3708 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3709 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3710 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3711 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3714 if (sleepFlag == CAN_SLEEP) {
3722 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3723 ioc->name, diag0val);
3726 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3728 diag0val &= ~MPI_DIAG_RESET_HISTORY;
3729 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3730 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3731 if (diag0val & MPI_DIAG_RESET_HISTORY) {
3732 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3736 /* Disable Diagnostic Mode
3738 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3740 /* Check FW reload status flags.
3742 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3743 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3744 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3745 ioc->name, diag0val);
3749 if (ioc->debug_level & MPT_DEBUG) {
3751 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3752 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3753 ioc->name, diag0val, diag1val));
3757 * Reset flag that says we've enabled event notification
3759 ioc->facts.EventState = 0;
3762 ioc->alt_ioc->facts.EventState = 0;
3764 return hard_reset_done;
3767 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3769 * SendIocReset - Send IOCReset request to MPT adapter.
3770 * @ioc: Pointer to MPT_ADAPTER structure
3771 * @reset_type: reset type, expected values are
3772 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3773 * @sleepFlag: Specifies whether the process can sleep
3775 * Send IOCReset request to the MPT adapter.
3777 * Returns 0 for success, non-zero for failure.
3780 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3786 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOC reset(0x%02x)!\n",
3787 ioc->name, reset_type));
3788 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3789 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3792 /* FW ACK'd request, wait for READY state
3795 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
3797 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3801 if (sleepFlag != CAN_SLEEP)
3804 printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
3805 ioc->name, (int)((count+5)/HZ));
3809 if (sleepFlag == CAN_SLEEP) {
3812 mdelay (1); /* 1 msec delay */
3817 * Cleanup all event stuff for this IOC; re-issue EventNotification
3818 * request if needed.
3820 if (ioc->facts.Function)
3821 ioc->facts.EventState = 0;
3826 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3828 * initChainBuffers - Allocate memory for and initialize chain buffers
3829 * @ioc: Pointer to MPT_ADAPTER structure
3831 * Allocates memory for and initializes chain buffers,
3832 * chain buffer control arrays and spinlock.
3835 initChainBuffers(MPT_ADAPTER *ioc)
3838 int sz, ii, num_chain;
3839 int scale, num_sge, numSGE;
3841 /* ReqToChain size must equal the req_depth
3844 if (ioc->ReqToChain == NULL) {
3845 sz = ioc->req_depth * sizeof(int);
3846 mem = kmalloc(sz, GFP_ATOMIC);
3850 ioc->ReqToChain = (int *) mem;
3851 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReqToChain alloc @ %p, sz=%d bytes\n",
3852 ioc->name, mem, sz));
3853 mem = kmalloc(sz, GFP_ATOMIC);
3857 ioc->RequestNB = (int *) mem;
3858 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestNB alloc @ %p, sz=%d bytes\n",
3859 ioc->name, mem, sz));
3861 for (ii = 0; ii < ioc->req_depth; ii++) {
3862 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
3865 /* ChainToChain size must equal the total number
3866 * of chain buffers to be allocated.
3869 * Calculate the number of chain buffers needed(plus 1) per I/O
3870 * then multiply the maximum number of simultaneous cmds
3872 * num_sge = num sge in request frame + last chain buffer
3873 * scale = num sge per chain buffer if no chain element
3875 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3876 if (sizeof(dma_addr_t) == sizeof(u64))
3877 num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3879 num_sge = 1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3881 if (sizeof(dma_addr_t) == sizeof(u64)) {
3882 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3883 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3885 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3886 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3888 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n",
3889 ioc->name, num_sge, numSGE));
3891 if ( numSGE > MPT_SCSI_SG_DEPTH )
3892 numSGE = MPT_SCSI_SG_DEPTH;
3895 while (numSGE - num_sge > 0) {
3897 num_sge += (scale - 1);
3901 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Now numSGE=%d num_sge=%d num_chain=%d\n",
3902 ioc->name, numSGE, num_sge, num_chain));
3904 if (ioc->bus_type == SPI)
3905 num_chain *= MPT_SCSI_CAN_QUEUE;
3907 num_chain *= MPT_FC_CAN_QUEUE;
3909 ioc->num_chain = num_chain;
3911 sz = num_chain * sizeof(int);
3912 if (ioc->ChainToChain == NULL) {
3913 mem = kmalloc(sz, GFP_ATOMIC);
3917 ioc->ChainToChain = (int *) mem;
3918 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainToChain alloc @ %p, sz=%d bytes\n",
3919 ioc->name, mem, sz));
3921 mem = (u8 *) ioc->ChainToChain;
3923 memset(mem, 0xFF, sz);
3927 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3929 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
3930 * @ioc: Pointer to MPT_ADAPTER structure
3932 * This routine allocates memory for the MPT reply and request frame
3933 * pools (if necessary), and primes the IOC reply FIFO with
3936 * Returns 0 for success, non-zero for failure.
3939 PrimeIocFifos(MPT_ADAPTER *ioc)
3942 unsigned long flags;
3943 dma_addr_t alloc_dma;
3945 int i, reply_sz, sz, total_size, num_chain;
3947 /* Prime reply FIFO... */
3949 if (ioc->reply_frames == NULL) {
3950 if ( (num_chain = initChainBuffers(ioc)) < 0)
3953 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
3954 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
3955 ioc->name, ioc->reply_sz, ioc->reply_depth));
3956 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d[%x] bytes\n",
3957 ioc->name, reply_sz, reply_sz));
3959 sz = (ioc->req_sz * ioc->req_depth);
3960 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d bytes, RequestDepth=%d\n",
3961 ioc->name, ioc->req_sz, ioc->req_depth));
3962 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d[%x] bytes\n",
3963 ioc->name, sz, sz));
3966 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
3967 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d bytes, ChainDepth=%d\n",
3968 ioc->name, ioc->req_sz, num_chain));
3969 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
3970 ioc->name, sz, sz, num_chain));
3973 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
3975 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
3980 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Total alloc @ %p[%p], sz=%d[%x] bytes\n",
3981 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
3983 memset(mem, 0, total_size);
3984 ioc->alloc_total += total_size;
3986 ioc->alloc_dma = alloc_dma;
3987 ioc->alloc_sz = total_size;
3988 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
3989 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3991 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
3992 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3994 alloc_dma += reply_sz;
3997 /* Request FIFO - WE manage this! */
3999 ioc->req_frames = (MPT_FRAME_HDR *) mem;
4000 ioc->req_frames_dma = alloc_dma;
4002 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffers @ %p[%p]\n",
4003 ioc->name, mem, (void *)(ulong)alloc_dma));
4005 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4007 #if defined(CONFIG_MTRR) && 0
4009 * Enable Write Combining MTRR for IOC's memory region.
4010 * (at least as much as we can; "size and base must be
4011 * multiples of 4 kiB"
4013 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
4015 MTRR_TYPE_WRCOMB, 1);
4016 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MTRR region registered (base:size=%08x:%x)\n",
4017 ioc->name, ioc->req_frames_dma, sz));
4020 for (i = 0; i < ioc->req_depth; i++) {
4021 alloc_dma += ioc->req_sz;
4025 ioc->ChainBuffer = mem;
4026 ioc->ChainBufferDMA = alloc_dma;
4028 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffers @ %p(%p)\n",
4029 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
4031 /* Initialize the free chain Q.
4034 INIT_LIST_HEAD(&ioc->FreeChainQ);
4036 /* Post the chain buffers to the FreeChainQ.
4038 mem = (u8 *)ioc->ChainBuffer;
4039 for (i=0; i < num_chain; i++) {
4040 mf = (MPT_FRAME_HDR *) mem;
4041 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
4045 /* Initialize Request frames linked list
4047 alloc_dma = ioc->req_frames_dma;
4048 mem = (u8 *) ioc->req_frames;
4050 spin_lock_irqsave(&ioc->FreeQlock, flags);
4051 INIT_LIST_HEAD(&ioc->FreeQ);
4052 for (i = 0; i < ioc->req_depth; i++) {
4053 mf = (MPT_FRAME_HDR *) mem;
4055 /* Queue REQUESTs *internally*! */
4056 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
4060 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4062 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4063 ioc->sense_buf_pool =
4064 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
4065 if (ioc->sense_buf_pool == NULL) {
4066 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
4071 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
4072 ioc->alloc_total += sz;
4073 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SenseBuffers @ %p[%p]\n",
4074 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
4078 /* Post Reply frames to FIFO
4080 alloc_dma = ioc->alloc_dma;
4081 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4082 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4084 for (i = 0; i < ioc->reply_depth; i++) {
4085 /* Write each address to the IOC! */
4086 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
4087 alloc_dma += ioc->reply_sz;
4093 if (ioc->alloc != NULL) {
4095 pci_free_consistent(ioc->pcidev,
4097 ioc->alloc, ioc->alloc_dma);
4098 ioc->reply_frames = NULL;
4099 ioc->req_frames = NULL;
4100 ioc->alloc_total -= sz;
4102 if (ioc->sense_buf_pool != NULL) {
4103 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4104 pci_free_consistent(ioc->pcidev,
4106 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
4107 ioc->sense_buf_pool = NULL;
4112 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4114 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4115 * from IOC via doorbell handshake method.
4116 * @ioc: Pointer to MPT_ADAPTER structure
4117 * @reqBytes: Size of the request in bytes
4118 * @req: Pointer to MPT request frame
4119 * @replyBytes: Expected size of the reply in bytes
4120 * @u16reply: Pointer to area where reply should be written
4121 * @maxwait: Max wait time for a reply (in seconds)
4122 * @sleepFlag: Specifies whether the process can sleep
4124 * NOTES: It is the callers responsibility to byte-swap fields in the
4125 * request which are greater than 1 byte in size. It is also the
4126 * callers responsibility to byte-swap response fields which are
4127 * greater than 1 byte in size.
4129 * Returns 0 for success, non-zero for failure.
4132 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
4133 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
4135 MPIDefaultReply_t *mptReply;
4140 * Get ready to cache a handshake reply
4142 ioc->hs_reply_idx = 0;
4143 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4144 mptReply->MsgLength = 0;
4147 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4148 * then tell IOC that we want to handshake a request of N words.
4149 * (WRITE u32val to Doorbell reg).
4151 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4152 CHIPREG_WRITE32(&ioc->chip->Doorbell,
4153 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
4154 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
4157 * Wait for IOC's doorbell handshake int
4159 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4162 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4163 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4165 /* Read doorbell and check for active bit */
4166 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
4170 * Clear doorbell int (WRITE 0 to IntStatus reg),
4171 * then wait for IOC to ACKnowledge that it's ready for
4172 * our handshake request.
4174 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4175 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4180 u8 *req_as_bytes = (u8 *) req;
4183 * Stuff request words via doorbell handshake,
4184 * with ACK from IOC for each.
4186 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
4187 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
4188 (req_as_bytes[(ii*4) + 1] << 8) |
4189 (req_as_bytes[(ii*4) + 2] << 16) |
4190 (req_as_bytes[(ii*4) + 3] << 24));
4192 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
4193 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4197 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req));
4198 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req)
4200 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n",
4201 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
4204 * Wait for completion of doorbell handshake reply from the IOC
4206 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
4209 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake reply count=%d%s\n",
4210 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
4213 * Copy out the cached reply...
4215 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
4216 u16reply[ii] = ioc->hs_reply[ii];
4224 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4226 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4227 * @ioc: Pointer to MPT_ADAPTER structure
4228 * @howlong: How long to wait (in seconds)
4229 * @sleepFlag: Specifies whether the process can sleep
4231 * This routine waits (up to ~2 seconds max) for IOC doorbell
4232 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4233 * bit in its IntStatus register being clear.
4235 * Returns a negative value on failure, else wait loop count.
4238 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4244 cntdn = 1000 * howlong;
4246 if (sleepFlag == CAN_SLEEP) {
4249 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4250 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4257 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4258 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4265 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell ACK (count=%d)\n",
4270 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4271 ioc->name, count, intstat);
4275 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4277 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
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 interrupt
4283 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4285 * Returns a negative value on failure, else wait loop count.
4288 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4294 cntdn = 1000 * howlong;
4295 if (sleepFlag == CAN_SLEEP) {
4297 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4298 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4305 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4306 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4314 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4315 ioc->name, count, howlong));
4319 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4320 ioc->name, count, intstat);
4324 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4326 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4327 * @ioc: Pointer to MPT_ADAPTER structure
4328 * @howlong: How long to wait (in seconds)
4329 * @sleepFlag: Specifies whether the process can sleep
4331 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4332 * Reply is cached to IOC private area large enough to hold a maximum
4333 * of 128 bytes of reply data.
4335 * Returns a negative value on failure, else size of reply in WORDS.
4338 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4343 u16 *hs_reply = ioc->hs_reply;
4344 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4347 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4350 * Get first two u16's so we can look at IOC's intended reply MsgLength
4353 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4356 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4357 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4358 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4361 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4362 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4366 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4367 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4368 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4371 * If no error (and IOC said MsgLength is > 0), piece together
4372 * reply 16 bits at a time.
4374 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4375 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4377 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4378 /* don't overflow our IOC hs_reply[] buffer! */
4379 if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
4380 hs_reply[u16cnt] = hword;
4381 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4384 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4386 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4389 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4394 else if (u16cnt != (2 * mptReply->MsgLength)) {
4397 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4402 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name));
4403 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply)
4405 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4406 ioc->name, t, u16cnt/2));
4410 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4412 * GetLanConfigPages - Fetch LANConfig pages.
4413 * @ioc: Pointer to MPT_ADAPTER structure
4415 * Return: 0 for success
4416 * -ENOMEM if no memory available
4417 * -EPERM if not allowed due to ISR context
4418 * -EAGAIN if no msg frames currently available
4419 * -EFAULT for non-successful reply or no reply (timeout)
4422 GetLanConfigPages(MPT_ADAPTER *ioc)
4424 ConfigPageHeader_t hdr;
4426 LANPage0_t *ppage0_alloc;
4427 dma_addr_t page0_dma;
4428 LANPage1_t *ppage1_alloc;
4429 dma_addr_t page1_dma;
4434 /* Get LAN Page 0 header */
4435 hdr.PageVersion = 0;
4438 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4439 cfg.cfghdr.hdr = &hdr;
4441 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4446 if ((rc = mpt_config(ioc, &cfg)) != 0)
4449 if (hdr.PageLength > 0) {
4450 data_sz = hdr.PageLength * 4;
4451 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4454 memset((u8 *)ppage0_alloc, 0, data_sz);
4455 cfg.physAddr = page0_dma;
4456 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4458 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4460 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4461 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4465 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4468 * Normalize endianness of structure data,
4469 * by byte-swapping all > 1 byte fields!
4478 /* Get LAN Page 1 header */
4479 hdr.PageVersion = 0;
4482 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4483 cfg.cfghdr.hdr = &hdr;
4485 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4489 if ((rc = mpt_config(ioc, &cfg)) != 0)
4492 if (hdr.PageLength == 0)
4495 data_sz = hdr.PageLength * 4;
4497 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4499 memset((u8 *)ppage1_alloc, 0, data_sz);
4500 cfg.physAddr = page1_dma;
4501 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4503 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4505 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4506 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4509 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4512 * Normalize endianness of structure data,
4513 * by byte-swapping all > 1 byte fields!
4521 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4523 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
4524 * @ioc: Pointer to MPT_ADAPTER structure
4525 * @persist_opcode: see below
4527 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4528 * devices not currently present.
4529 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4531 * NOTE: Don't use not this function during interrupt time.
4533 * Returns 0 for success, non-zero error
4536 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4538 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4540 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
4541 SasIoUnitControlReply_t *sasIoUnitCntrReply;
4542 MPT_FRAME_HDR *mf = NULL;
4543 MPIHeader_t *mpi_hdr;
4546 /* insure garbage is not sent to fw */
4547 switch(persist_opcode) {
4549 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
4550 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
4558 printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode);
4560 /* Get a MF for this command.
4562 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4563 printk("%s: no msg frames!\n",__FUNCTION__);
4567 mpi_hdr = (MPIHeader_t *) mf;
4568 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
4569 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
4570 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
4571 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
4572 sasIoUnitCntrReq->Operation = persist_opcode;
4574 init_timer(&ioc->persist_timer);
4575 ioc->persist_timer.data = (unsigned long) ioc;
4576 ioc->persist_timer.function = mpt_timer_expired;
4577 ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
4578 ioc->persist_wait_done=0;
4579 add_timer(&ioc->persist_timer);
4580 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4581 wait_event(mpt_waitq, ioc->persist_wait_done);
4583 sasIoUnitCntrReply =
4584 (SasIoUnitControlReply_t *)ioc->persist_reply_frame;
4585 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
4586 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4588 sasIoUnitCntrReply->IOCStatus,
4589 sasIoUnitCntrReply->IOCLogInfo);
4593 printk("%s: success\n",__FUNCTION__);
4597 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4600 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
4601 MpiEventDataRaid_t * pRaidEventData)
4610 volume = pRaidEventData->VolumeID;
4611 reason = pRaidEventData->ReasonCode;
4612 disk = pRaidEventData->PhysDiskNum;
4613 status = le32_to_cpu(pRaidEventData->SettingsStatus);
4614 flags = (status >> 0) & 0xff;
4615 state = (status >> 8) & 0xff;
4617 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
4621 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
4622 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
4623 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
4624 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
4625 ioc->name, disk, volume);
4627 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
4632 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4633 printk(MYIOC_s_INFO_FMT " volume has been created\n",
4637 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4639 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
4643 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
4644 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
4648 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4649 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
4651 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
4653 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
4655 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
4658 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
4660 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
4661 ? ", quiesced" : "",
4662 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
4663 ? ", resync in progress" : "" );
4666 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
4667 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
4671 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4672 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
4676 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4677 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
4681 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
4682 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
4686 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4687 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
4689 state == MPI_PHYSDISK0_STATUS_ONLINE
4691 : state == MPI_PHYSDISK0_STATUS_MISSING
4693 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
4695 : state == MPI_PHYSDISK0_STATUS_FAILED
4697 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
4699 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
4700 ? "offline requested"
4701 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
4702 ? "failed requested"
4703 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
4706 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
4707 ? ", out of sync" : "",
4708 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
4709 ? ", quiesced" : "" );
4712 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
4713 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
4717 case MPI_EVENT_RAID_RC_SMART_DATA:
4718 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
4719 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
4722 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
4723 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
4729 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4731 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4732 * @ioc: Pointer to MPT_ADAPTER structure
4734 * Returns: 0 for success
4735 * -ENOMEM if no memory available
4736 * -EPERM if not allowed due to ISR context
4737 * -EAGAIN if no msg frames currently available
4738 * -EFAULT for non-successful reply or no reply (timeout)
4741 GetIoUnitPage2(MPT_ADAPTER *ioc)
4743 ConfigPageHeader_t hdr;
4745 IOUnitPage2_t *ppage_alloc;
4746 dma_addr_t page_dma;
4750 /* Get the page header */
4751 hdr.PageVersion = 0;
4754 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4755 cfg.cfghdr.hdr = &hdr;
4757 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4762 if ((rc = mpt_config(ioc, &cfg)) != 0)
4765 if (hdr.PageLength == 0)
4768 /* Read the config page */
4769 data_sz = hdr.PageLength * 4;
4771 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4773 memset((u8 *)ppage_alloc, 0, data_sz);
4774 cfg.physAddr = page_dma;
4775 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4777 /* If Good, save data */
4778 if ((rc = mpt_config(ioc, &cfg)) == 0)
4779 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4781 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4787 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4789 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4790 * @ioc: Pointer to a Adapter Strucutre
4791 * @portnum: IOC port number
4793 * Return: -EFAULT if read of config page header fails
4795 * If read of SCSI Port Page 0 fails,
4796 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4797 * Adapter settings: async, narrow
4799 * If read of SCSI Port Page 2 fails,
4800 * Adapter settings valid
4801 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4806 * CHECK - what type of locking mechanisms should be used????
4809 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4814 ConfigPageHeader_t header;
4820 if (!ioc->spi_data.nvram) {
4823 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4824 mem = kmalloc(sz, GFP_ATOMIC);
4828 ioc->spi_data.nvram = (int *) mem;
4830 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4831 ioc->name, ioc->spi_data.nvram, sz));
4834 /* Invalidate NVRAM information
4836 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4837 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4840 /* Read SPP0 header, allocate memory, then read page.
4842 header.PageVersion = 0;
4843 header.PageLength = 0;
4844 header.PageNumber = 0;
4845 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4846 cfg.cfghdr.hdr = &header;
4848 cfg.pageAddr = portnum;
4849 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4851 cfg.timeout = 0; /* use default */
4852 if (mpt_config(ioc, &cfg) != 0)
4855 if (header.PageLength > 0) {
4856 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4858 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4859 cfg.physAddr = buf_dma;
4860 if (mpt_config(ioc, &cfg) != 0) {
4861 ioc->spi_data.maxBusWidth = MPT_NARROW;
4862 ioc->spi_data.maxSyncOffset = 0;
4863 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4864 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4866 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4867 "Unable to read PortPage0 minSyncFactor=%x\n",
4868 ioc->name, ioc->spi_data.minSyncFactor));
4870 /* Save the Port Page 0 data
4872 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
4873 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4874 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4876 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
4877 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4878 ddvprintk(ioc, printk(KERN_INFO MYNAM
4879 " :%s noQas due to Capabilities=%x\n",
4880 ioc->name, pPP0->Capabilities));
4882 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4883 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4885 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4886 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4887 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4888 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4889 "PortPage0 minSyncFactor=%x\n",
4890 ioc->name, ioc->spi_data.minSyncFactor));
4892 ioc->spi_data.maxSyncOffset = 0;
4893 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4896 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4898 /* Update the minSyncFactor based on bus type.
4900 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4901 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
4903 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
4904 ioc->spi_data.minSyncFactor = MPT_ULTRA;
4905 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4906 "HVD or SE detected, minSyncFactor=%x\n",
4907 ioc->name, ioc->spi_data.minSyncFactor));
4912 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4917 /* SCSI Port Page 2 - Read the header then the page.
4919 header.PageVersion = 0;
4920 header.PageLength = 0;
4921 header.PageNumber = 2;
4922 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4923 cfg.cfghdr.hdr = &header;
4925 cfg.pageAddr = portnum;
4926 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4928 if (mpt_config(ioc, &cfg) != 0)
4931 if (header.PageLength > 0) {
4932 /* Allocate memory and read SCSI Port Page 2
4934 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4936 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
4937 cfg.physAddr = buf_dma;
4938 if (mpt_config(ioc, &cfg) != 0) {
4939 /* Nvram data is left with INVALID mark
4942 } else if (ioc->pcidev->vendor == PCI_VENDOR_ID_ATTO) {
4944 /* This is an ATTO adapter, read Page2 accordingly
4946 ATTO_SCSIPortPage2_t *pPP2 = (ATTO_SCSIPortPage2_t *) pbuf;
4947 ATTODeviceInfo_t *pdevice = NULL;
4950 /* Save the Port Page 2 data
4951 * (reformat into a 32bit quantity)
4953 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4954 pdevice = &pPP2->DeviceSettings[ii];
4955 ATTOFlags = le16_to_cpu(pdevice->ATTOFlags);
4958 /* Translate ATTO device flags to LSI format
4960 if (ATTOFlags & ATTOFLAG_DISC)
4961 data |= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE);
4962 if (ATTOFlags & ATTOFLAG_ID_ENB)
4963 data |= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE);
4964 if (ATTOFlags & ATTOFLAG_LUN_ENB)
4965 data |= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE);
4966 if (ATTOFlags & ATTOFLAG_TAGGED)
4967 data |= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE);
4968 if (!(ATTOFlags & ATTOFLAG_WIDE_ENB))
4969 data |= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE);
4971 data = (data << 16) | (pdevice->Period << 8) | 10;
4972 ioc->spi_data.nvram[ii] = data;
4975 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
4976 MpiDeviceInfo_t *pdevice = NULL;
4979 * Save "Set to Avoid SCSI Bus Resets" flag
4981 ioc->spi_data.bus_reset =
4982 (le32_to_cpu(pPP2->PortFlags) &
4983 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
4986 /* Save the Port Page 2 data
4987 * (reformat into a 32bit quantity)
4989 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
4990 ioc->spi_data.PortFlags = data;
4991 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4992 pdevice = &pPP2->DeviceSettings[ii];
4993 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
4994 (pdevice->SyncFactor << 8) | pdevice->Timeout;
4995 ioc->spi_data.nvram[ii] = data;
4999 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5003 /* Update Adapter limits with those from NVRAM
5004 * Comment: Don't need to do this. Target performance
5005 * parameters will never exceed the adapters limits.
5011 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5013 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
5014 * @ioc: Pointer to a Adapter Strucutre
5015 * @portnum: IOC port number
5017 * Return: -EFAULT if read of config page header fails
5021 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
5024 ConfigPageHeader_t header;
5026 /* Read the SCSI Device Page 1 header
5028 header.PageVersion = 0;
5029 header.PageLength = 0;
5030 header.PageNumber = 1;
5031 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5032 cfg.cfghdr.hdr = &header;
5034 cfg.pageAddr = portnum;
5035 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5038 if (mpt_config(ioc, &cfg) != 0)
5041 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
5042 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
5044 header.PageVersion = 0;
5045 header.PageLength = 0;
5046 header.PageNumber = 0;
5047 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5048 if (mpt_config(ioc, &cfg) != 0)
5051 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
5052 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
5054 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 0: version %d length %d\n",
5055 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
5057 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 1: version %d length %d\n",
5058 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
5063 * mpt_inactive_raid_list_free - This clears this link list.
5064 * @ioc : pointer to per adapter structure
5067 mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
5069 struct inactive_raid_component_info *component_info, *pNext;
5071 if (list_empty(&ioc->raid_data.inactive_list))
5074 down(&ioc->raid_data.inactive_list_mutex);
5075 list_for_each_entry_safe(component_info, pNext,
5076 &ioc->raid_data.inactive_list, list) {
5077 list_del(&component_info->list);
5078 kfree(component_info);
5080 up(&ioc->raid_data.inactive_list_mutex);
5084 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5086 * @ioc : pointer to per adapter structure
5087 * @channel : volume channel
5088 * @id : volume target id
5091 mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
5094 ConfigPageHeader_t hdr;
5095 dma_addr_t dma_handle;
5096 pRaidVolumePage0_t buffer = NULL;
5098 RaidPhysDiskPage0_t phys_disk;
5099 struct inactive_raid_component_info *component_info;
5100 int handle_inactive_volumes;
5102 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5103 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5104 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
5105 cfg.pageAddr = (channel << 8) + id;
5106 cfg.cfghdr.hdr = &hdr;
5107 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5109 if (mpt_config(ioc, &cfg) != 0)
5112 if (!hdr.PageLength)
5115 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5121 cfg.physAddr = dma_handle;
5122 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5124 if (mpt_config(ioc, &cfg) != 0)
5127 if (!buffer->NumPhysDisks)
5130 handle_inactive_volumes =
5131 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
5132 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
5133 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
5134 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
5136 if (!handle_inactive_volumes)
5139 down(&ioc->raid_data.inactive_list_mutex);
5140 for (i = 0; i < buffer->NumPhysDisks; i++) {
5141 if(mpt_raid_phys_disk_pg0(ioc,
5142 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
5145 if ((component_info = kmalloc(sizeof (*component_info),
5146 GFP_KERNEL)) == NULL)
5149 component_info->volumeID = id;
5150 component_info->volumeBus = channel;
5151 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
5152 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
5153 component_info->d.PhysDiskID = phys_disk.PhysDiskID;
5154 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
5156 list_add_tail(&component_info->list,
5157 &ioc->raid_data.inactive_list);
5159 up(&ioc->raid_data.inactive_list_mutex);
5163 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5168 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5169 * @ioc: Pointer to a Adapter Structure
5170 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5171 * @phys_disk: requested payload data returned
5175 * -EFAULT if read of config page header fails or data pointer not NULL
5176 * -ENOMEM if pci_alloc failed
5179 mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk)
5182 ConfigPageHeader_t hdr;
5183 dma_addr_t dma_handle;
5184 pRaidPhysDiskPage0_t buffer = NULL;
5187 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5188 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5190 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5191 cfg.cfghdr.hdr = &hdr;
5193 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5195 if (mpt_config(ioc, &cfg) != 0) {
5200 if (!hdr.PageLength) {
5205 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5213 cfg.physAddr = dma_handle;
5214 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5215 cfg.pageAddr = phys_disk_num;
5217 if (mpt_config(ioc, &cfg) != 0) {
5223 memcpy(phys_disk, buffer, sizeof(*buffer));
5224 phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
5229 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5236 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5237 * @ioc: Pointer to a Adapter Strucutre
5238 * @portnum: IOC port number
5242 * -EFAULT if read of config page header fails or data pointer not NULL
5243 * -ENOMEM if pci_alloc failed
5246 mpt_findImVolumes(MPT_ADAPTER *ioc)
5250 dma_addr_t ioc2_dma;
5252 ConfigPageHeader_t header;
5257 if (!ioc->ir_firmware)
5260 /* Free the old page
5262 kfree(ioc->raid_data.pIocPg2);
5263 ioc->raid_data.pIocPg2 = NULL;
5264 mpt_inactive_raid_list_free(ioc);
5266 /* Read IOCP2 header then the page.
5268 header.PageVersion = 0;
5269 header.PageLength = 0;
5270 header.PageNumber = 2;
5271 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5272 cfg.cfghdr.hdr = &header;
5275 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5278 if (mpt_config(ioc, &cfg) != 0)
5281 if (header.PageLength == 0)
5284 iocpage2sz = header.PageLength * 4;
5285 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
5289 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5290 cfg.physAddr = ioc2_dma;
5291 if (mpt_config(ioc, &cfg) != 0)
5294 mem = kmalloc(iocpage2sz, GFP_KERNEL);
5298 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
5299 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
5301 mpt_read_ioc_pg_3(ioc);
5303 for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
5304 mpt_inactive_raid_volumes(ioc,
5305 pIoc2->RaidVolume[i].VolumeBus,
5306 pIoc2->RaidVolume[i].VolumeID);
5309 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
5315 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
5320 ConfigPageHeader_t header;
5321 dma_addr_t ioc3_dma;
5324 /* Free the old page
5326 kfree(ioc->raid_data.pIocPg3);
5327 ioc->raid_data.pIocPg3 = NULL;
5329 /* There is at least one physical disk.
5330 * Read and save IOC Page 3
5332 header.PageVersion = 0;
5333 header.PageLength = 0;
5334 header.PageNumber = 3;
5335 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5336 cfg.cfghdr.hdr = &header;
5339 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5342 if (mpt_config(ioc, &cfg) != 0)
5345 if (header.PageLength == 0)
5348 /* Read Header good, alloc memory
5350 iocpage3sz = header.PageLength * 4;
5351 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
5355 /* Read the Page and save the data
5356 * into malloc'd memory.
5358 cfg.physAddr = ioc3_dma;
5359 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5360 if (mpt_config(ioc, &cfg) == 0) {
5361 mem = kmalloc(iocpage3sz, GFP_KERNEL);
5363 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
5364 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
5368 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
5374 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
5378 ConfigPageHeader_t header;
5379 dma_addr_t ioc4_dma;
5382 /* Read and save IOC Page 4
5384 header.PageVersion = 0;
5385 header.PageLength = 0;
5386 header.PageNumber = 4;
5387 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5388 cfg.cfghdr.hdr = &header;
5391 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5394 if (mpt_config(ioc, &cfg) != 0)
5397 if (header.PageLength == 0)
5400 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
5401 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
5402 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
5405 ioc->alloc_total += iocpage4sz;
5407 ioc4_dma = ioc->spi_data.IocPg4_dma;
5408 iocpage4sz = ioc->spi_data.IocPg4Sz;
5411 /* Read the Page into dma memory.
5413 cfg.physAddr = ioc4_dma;
5414 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5415 if (mpt_config(ioc, &cfg) == 0) {
5416 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
5417 ioc->spi_data.IocPg4_dma = ioc4_dma;
5418 ioc->spi_data.IocPg4Sz = iocpage4sz;
5420 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
5421 ioc->spi_data.pIocPg4 = NULL;
5422 ioc->alloc_total -= iocpage4sz;
5427 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
5431 ConfigPageHeader_t header;
5432 dma_addr_t ioc1_dma;
5436 /* Check the Coalescing Timeout in IOC Page 1
5438 header.PageVersion = 0;
5439 header.PageLength = 0;
5440 header.PageNumber = 1;
5441 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5442 cfg.cfghdr.hdr = &header;
5445 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5448 if (mpt_config(ioc, &cfg) != 0)
5451 if (header.PageLength == 0)
5454 /* Read Header good, alloc memory
5456 iocpage1sz = header.PageLength * 4;
5457 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
5461 /* Read the Page and check coalescing timeout
5463 cfg.physAddr = ioc1_dma;
5464 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5465 if (mpt_config(ioc, &cfg) == 0) {
5467 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
5468 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
5469 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
5471 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Coalescing Enabled Timeout = %d\n",
5474 if (tmp > MPT_COALESCING_TIMEOUT) {
5475 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
5477 /* Write NVRAM and current
5480 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5481 if (mpt_config(ioc, &cfg) == 0) {
5482 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Reset Current Coalescing Timeout to = %d\n",
5483 ioc->name, MPT_COALESCING_TIMEOUT));
5485 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
5486 if (mpt_config(ioc, &cfg) == 0) {
5487 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5488 "Reset NVRAM Coalescing Timeout to = %d\n",
5489 ioc->name, MPT_COALESCING_TIMEOUT));
5491 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5492 "Reset NVRAM Coalescing Timeout Failed\n",
5497 dprintk(ioc, printk(MYIOC_s_WARN_FMT
5498 "Reset of Current Coalescing Timeout Failed!\n",
5504 dprintk(ioc, printk(MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
5508 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
5514 mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
5517 ConfigPageHeader_t hdr;
5519 ManufacturingPage0_t *pbuf = NULL;
5521 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5522 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5524 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
5525 cfg.cfghdr.hdr = &hdr;
5527 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5530 if (mpt_config(ioc, &cfg) != 0)
5533 if (!cfg.cfghdr.hdr->PageLength)
5536 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5537 pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
5541 cfg.physAddr = buf_dma;
5543 if (mpt_config(ioc, &cfg) != 0)
5546 memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name));
5547 memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
5548 memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
5553 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
5556 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5558 * SendEventNotification - Send EventNotification (on or off) request to adapter
5559 * @ioc: Pointer to MPT_ADAPTER structure
5560 * @EvSwitch: Event switch flags
5563 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
5565 EventNotification_t *evnp;
5567 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
5569 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
5573 memset(evnp, 0, sizeof(*evnp));
5575 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
5577 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
5578 evnp->ChainOffset = 0;
5580 evnp->Switch = EvSwitch;
5582 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
5587 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5589 * SendEventAck - Send EventAck request to MPT adapter.
5590 * @ioc: Pointer to MPT_ADAPTER structure
5591 * @evnp: Pointer to original EventNotification request
5594 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
5598 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5599 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
5600 ioc->name,__FUNCTION__));
5604 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventAck\n", ioc->name));
5606 pAck->Function = MPI_FUNCTION_EVENT_ACK;
5607 pAck->ChainOffset = 0;
5608 pAck->Reserved[0] = pAck->Reserved[1] = 0;
5610 pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
5611 pAck->Event = evnp->Event;
5612 pAck->EventContext = evnp->EventContext;
5614 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
5619 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5621 * mpt_config - Generic function to issue config message
5622 * @ioc: Pointer to an adapter structure
5623 * @pCfg: Pointer to a configuration structure. Struct contains
5624 * action, page address, direction, physical address
5625 * and pointer to a configuration page header
5626 * Page header is updated.
5628 * Returns 0 for success
5629 * -EPERM if not allowed due to ISR context
5630 * -EAGAIN if no msg frames currently available
5631 * -EFAULT for non-successful reply or no reply (timeout)
5634 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5637 ConfigExtendedPageHeader_t *pExtHdr = NULL;
5639 unsigned long flags;
5644 /* Prevent calling wait_event() (below), if caller happens
5645 * to be in ISR context, because that is fatal!
5647 in_isr = in_interrupt();
5649 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
5654 /* Get and Populate a free Frame
5656 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5657 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
5661 pReq = (Config_t *)mf;
5662 pReq->Action = pCfg->action;
5664 pReq->ChainOffset = 0;
5665 pReq->Function = MPI_FUNCTION_CONFIG;
5667 /* Assume page type is not extended and clear "reserved" fields. */
5668 pReq->ExtPageLength = 0;
5669 pReq->ExtPageType = 0;
5672 for (ii=0; ii < 8; ii++)
5673 pReq->Reserved2[ii] = 0;
5675 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
5676 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
5677 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
5678 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
5680 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5681 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
5682 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
5683 pReq->ExtPageType = pExtHdr->ExtPageType;
5684 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
5686 /* Page Length must be treated as a reserved field for the extended header. */
5687 pReq->Header.PageLength = 0;
5690 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
5692 /* Add a SGE to the config request.
5695 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
5697 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
5699 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5700 flagsLength |= pExtHdr->ExtPageLength * 4;
5702 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n",
5703 ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action));
5706 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
5708 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n",
5709 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
5712 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
5714 /* Append pCfg pointer to end of mf
5716 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5718 /* Initalize the timer
5720 init_timer(&pCfg->timer);
5721 pCfg->timer.data = (unsigned long) ioc;
5722 pCfg->timer.function = mpt_timer_expired;
5723 pCfg->wait_done = 0;
5725 /* Set the timer; ensure 10 second minimum */
5726 if (pCfg->timeout < 10)
5727 pCfg->timer.expires = jiffies + HZ*10;
5729 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5731 /* Add to end of Q, set timer and then issue this command */
5732 spin_lock_irqsave(&ioc->FreeQlock, flags);
5733 list_add_tail(&pCfg->linkage, &ioc->configQ);
5734 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5736 add_timer(&pCfg->timer);
5737 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5738 wait_event(mpt_waitq, pCfg->wait_done);
5740 /* mf has been freed - do not access */
5747 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5749 * mpt_timer_expired - Callback for timer process.
5750 * Used only internal config functionality.
5751 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5754 mpt_timer_expired(unsigned long data)
5756 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
5758 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired! \n", ioc->name));
5760 /* Perform a FW reload */
5761 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
5762 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
5764 /* No more processing.
5765 * Hard reset clean-up will wake up
5766 * process and free all resources.
5768 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired complete!\n", ioc->name));
5773 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5775 * mpt_ioc_reset - Base cleanup for hard reset
5776 * @ioc: Pointer to the adapter structure
5777 * @reset_phase: Indicates pre- or post-reset functionality
5779 * Remark: Frees resources with internally generated commands.
5782 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
5785 unsigned long flags;
5787 dprintk(ioc, printk(KERN_DEBUG MYNAM
5788 ": IOC %s_reset routed to MPT base driver!\n",
5789 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
5790 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
5792 if (reset_phase == MPT_IOC_SETUP_RESET) {
5794 } else if (reset_phase == MPT_IOC_PRE_RESET) {
5795 /* If the internal config Q is not empty -
5796 * delete timer. MF resources will be freed when
5797 * the FIFO's are primed.
5799 spin_lock_irqsave(&ioc->FreeQlock, flags);
5800 list_for_each_entry(pCfg, &ioc->configQ, linkage)
5801 del_timer(&pCfg->timer);
5802 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5807 /* Search the configQ for internal commands.
5808 * Flush the Q, and wake up all suspended threads.
5810 spin_lock_irqsave(&ioc->FreeQlock, flags);
5811 list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
5812 list_del(&pCfg->linkage);
5814 pCfg->status = MPT_CONFIG_ERROR;
5815 pCfg->wait_done = 1;
5816 wake_up(&mpt_waitq);
5818 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5821 return 1; /* currently means nothing really */
5825 #ifdef CONFIG_PROC_FS /* { */
5826 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5828 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5830 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5832 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5834 * Returns 0 for success, non-zero for failure.
5837 procmpt_create(void)
5839 struct proc_dir_entry *ent;
5841 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
5842 if (mpt_proc_root_dir == NULL)
5845 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5847 ent->read_proc = procmpt_summary_read;
5849 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5851 ent->read_proc = procmpt_version_read;
5856 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5858 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5860 * Returns 0 for success, non-zero for failure.
5863 procmpt_destroy(void)
5865 remove_proc_entry("version", mpt_proc_root_dir);
5866 remove_proc_entry("summary", mpt_proc_root_dir);
5867 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
5870 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5872 * procmpt_summary_read - Handle read request of a summary file
5873 * @buf: Pointer to area to write information
5874 * @start: Pointer to start pointer
5875 * @offset: Offset to start writing
5876 * @request: Amount of read data requested
5877 * @eof: Pointer to EOF integer
5880 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
5881 * Returns number of characters written to process performing the read.
5884 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5894 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5898 list_for_each_entry(ioc, &ioc_list, list) {
5901 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5904 if ((out-buf) >= request)
5911 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5914 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5916 * procmpt_version_read - Handle read request from /proc/mpt/version.
5917 * @buf: Pointer to area to write information
5918 * @start: Pointer to start pointer
5919 * @offset: Offset to start writing
5920 * @request: Amount of read data requested
5921 * @eof: Pointer to EOF integer
5924 * Returns number of characters written to process performing the read.
5927 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5930 int scsi, fc, sas, lan, ctl, targ, dmp;
5934 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
5935 len += sprintf(buf+len, " Fusion MPT base driver\n");
5937 scsi = fc = sas = lan = ctl = targ = dmp = 0;
5938 for (cb_idx=MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
5940 if (MptCallbacks[cb_idx]) {
5941 switch (MptDriverClass[cb_idx]) {
5943 if (!scsi++) drvname = "SPI host";
5946 if (!fc++) drvname = "FC host";
5949 if (!sas++) drvname = "SAS host";
5952 if (!lan++) drvname = "LAN";
5955 if (!targ++) drvname = "SCSI target";
5958 if (!ctl++) drvname = "ioctl";
5963 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
5967 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5970 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5972 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
5973 * @buf: Pointer to area to write information
5974 * @start: Pointer to start pointer
5975 * @offset: Offset to start writing
5976 * @request: Amount of read data requested
5977 * @eof: Pointer to EOF integer
5980 * Returns number of characters written to process performing the read.
5983 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5985 MPT_ADAPTER *ioc = data;
5991 mpt_get_fw_exp_ver(expVer, ioc);
5993 len = sprintf(buf, "%s:", ioc->name);
5994 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
5995 len += sprintf(buf+len, " (f/w download boot flag set)");
5996 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
5997 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
5999 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
6000 ioc->facts.ProductID,
6002 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
6003 if (ioc->facts.FWImageSize)
6004 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
6005 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
6006 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
6007 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
6009 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
6010 ioc->facts.CurrentHostMfaHighAddr);
6011 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
6012 ioc->facts.CurrentSenseBufferHighAddr);
6014 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
6015 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
6017 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6018 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
6020 * Rounding UP to nearest 4-kB boundary here...
6022 sz = (ioc->req_sz * ioc->req_depth) + 128;
6023 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
6024 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6025 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
6026 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
6027 4*ioc->facts.RequestFrameSize,
6028 ioc->facts.GlobalCredits);
6030 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
6031 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
6032 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
6033 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6034 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
6035 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
6036 ioc->facts.CurReplyFrameSize,
6037 ioc->facts.ReplyQueueDepth);
6039 len += sprintf(buf+len, " MaxDevices = %d\n",
6040 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
6041 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
6044 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
6045 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
6047 ioc->facts.NumberOfPorts);
6048 if (ioc->bus_type == FC) {
6049 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
6050 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6051 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6052 a[5], a[4], a[3], a[2], a[1], a[0]);
6054 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
6055 ioc->fc_port_page0[p].WWNN.High,
6056 ioc->fc_port_page0[p].WWNN.Low,
6057 ioc->fc_port_page0[p].WWPN.High,
6058 ioc->fc_port_page0[p].WWPN.Low);
6062 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6065 #endif /* CONFIG_PROC_FS } */
6067 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6069 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
6072 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
6073 sprintf(buf, " (Exp %02d%02d)",
6074 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
6075 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
6078 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
6079 strcat(buf, " [MDBG]");
6083 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6085 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6086 * @ioc: Pointer to MPT_ADAPTER structure
6087 * @buffer: Pointer to buffer where IOC summary info should be written
6088 * @size: Pointer to number of bytes we wrote (set by this routine)
6089 * @len: Offset at which to start writing in buffer
6090 * @showlan: Display LAN stuff?
6092 * This routine writes (english readable) ASCII text, which represents
6093 * a summary of IOC information, to a buffer.
6096 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
6101 mpt_get_fw_exp_ver(expVer, ioc);
6104 * Shorter summary of attached ioc's...
6106 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6109 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
6110 ioc->facts.FWVersion.Word,
6112 ioc->facts.NumberOfPorts,
6115 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6116 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6117 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6118 a[5], a[4], a[3], a[2], a[1], a[0]);
6121 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
6124 y += sprintf(buffer+len+y, " (disabled)");
6126 y += sprintf(buffer+len+y, "\n");
6131 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6135 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6137 * mpt_HardResetHandler - Generic reset handler
6138 * @ioc: Pointer to MPT_ADAPTER structure
6139 * @sleepFlag: Indicates if sleep or schedule must be called.
6141 * Issues SCSI Task Management call based on input arg values.
6142 * If TaskMgmt fails, returns associated SCSI request.
6144 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
6145 * or a non-interrupt thread. In the former, must not call schedule().
6147 * Note: A return of -1 is a FATAL error case, as it means a
6148 * FW reload/initialization failed.
6150 * Returns 0 for SUCCESS or -1 if FAILED.
6153 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6156 unsigned long flags;
6158 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name));
6160 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
6161 printk("MF count 0x%x !\n", ioc->mfcnt);
6164 /* Reset the adapter. Prevent more than 1 call to
6165 * mpt_do_ioc_recovery at any instant in time.
6167 spin_lock_irqsave(&ioc->diagLock, flags);
6168 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
6169 spin_unlock_irqrestore(&ioc->diagLock, flags);
6172 ioc->diagPending = 1;
6174 spin_unlock_irqrestore(&ioc->diagLock, flags);
6176 /* FIXME: If do_ioc_recovery fails, repeat....
6179 /* The SCSI driver needs to adjust timeouts on all current
6180 * commands prior to the diagnostic reset being issued.
6181 * Prevents timeouts occurring during a diagnostic reset...very bad.
6182 * For all other protocol drivers, this is a no-op.
6188 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6189 if (MptResetHandlers[cb_idx]) {
6190 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling IOC reset_setup handler #%d\n",
6191 ioc->name, cb_idx));
6192 r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
6194 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling alt-%s setup reset handler #%d\n",
6195 ioc->name, ioc->alt_ioc->name, cb_idx));
6196 r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_SETUP_RESET);
6202 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
6203 printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
6208 ioc->alt_ioc->reload_fw = 0;
6210 spin_lock_irqsave(&ioc->diagLock, flags);
6211 ioc->diagPending = 0;
6213 ioc->alt_ioc->diagPending = 0;
6214 spin_unlock_irqrestore(&ioc->diagLock, flags);
6216 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
6221 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6223 EventDescriptionStr(u8 event, u32 evData0, char *evStr)
6228 case MPI_EVENT_NONE:
6231 case MPI_EVENT_LOG_DATA:
6234 case MPI_EVENT_STATE_CHANGE:
6235 ds = "State Change";
6237 case MPI_EVENT_UNIT_ATTENTION:
6238 ds = "Unit Attention";
6240 case MPI_EVENT_IOC_BUS_RESET:
6241 ds = "IOC Bus Reset";
6243 case MPI_EVENT_EXT_BUS_RESET:
6244 ds = "External Bus Reset";
6246 case MPI_EVENT_RESCAN:
6247 ds = "Bus Rescan Event";
6249 case MPI_EVENT_LINK_STATUS_CHANGE:
6250 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
6251 ds = "Link Status(FAILURE) Change";
6253 ds = "Link Status(ACTIVE) Change";
6255 case MPI_EVENT_LOOP_STATE_CHANGE:
6256 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
6257 ds = "Loop State(LIP) Change";
6258 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
6259 ds = "Loop State(LPE) Change"; /* ??? */
6261 ds = "Loop State(LPB) Change"; /* ??? */
6263 case MPI_EVENT_LOGOUT:
6266 case MPI_EVENT_EVENT_CHANGE:
6272 case MPI_EVENT_INTEGRATED_RAID:
6274 u8 ReasonCode = (u8)(evData0 >> 16);
6275 switch (ReasonCode) {
6276 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
6277 ds = "Integrated Raid: Volume Created";
6279 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
6280 ds = "Integrated Raid: Volume Deleted";
6282 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
6283 ds = "Integrated Raid: Volume Settings Changed";
6285 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
6286 ds = "Integrated Raid: Volume Status Changed";
6288 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
6289 ds = "Integrated Raid: Volume Physdisk Changed";
6291 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
6292 ds = "Integrated Raid: Physdisk Created";
6294 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
6295 ds = "Integrated Raid: Physdisk Deleted";
6297 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
6298 ds = "Integrated Raid: Physdisk Settings Changed";
6300 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
6301 ds = "Integrated Raid: Physdisk Status Changed";
6303 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
6304 ds = "Integrated Raid: Domain Validation Needed";
6306 case MPI_EVENT_RAID_RC_SMART_DATA :
6307 ds = "Integrated Raid; Smart Data";
6309 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
6310 ds = "Integrated Raid: Replace Action Started";
6313 ds = "Integrated Raid";
6318 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
6319 ds = "SCSI Device Status Change";
6321 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
6323 u8 id = (u8)(evData0);
6324 u8 channel = (u8)(evData0 >> 8);
6325 u8 ReasonCode = (u8)(evData0 >> 16);
6326 switch (ReasonCode) {
6327 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
6328 snprintf(evStr, EVENT_DESCR_STR_SZ,
6329 "SAS Device Status Change: Added: "
6330 "id=%d channel=%d", id, channel);
6332 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
6333 snprintf(evStr, EVENT_DESCR_STR_SZ,
6334 "SAS Device Status Change: Deleted: "
6335 "id=%d channel=%d", id, channel);
6337 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
6338 snprintf(evStr, EVENT_DESCR_STR_SZ,
6339 "SAS Device Status Change: SMART Data: "
6340 "id=%d channel=%d", id, channel);
6342 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
6343 snprintf(evStr, EVENT_DESCR_STR_SZ,
6344 "SAS Device Status Change: No Persistancy: "
6345 "id=%d channel=%d", id, channel);
6347 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
6348 snprintf(evStr, EVENT_DESCR_STR_SZ,
6349 "SAS Device Status Change: Unsupported Device "
6350 "Discovered : id=%d channel=%d", id, channel);
6352 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
6353 snprintf(evStr, EVENT_DESCR_STR_SZ,
6354 "SAS Device Status Change: Internal Device "
6355 "Reset : id=%d channel=%d", id, channel);
6357 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
6358 snprintf(evStr, EVENT_DESCR_STR_SZ,
6359 "SAS Device Status Change: Internal Task "
6360 "Abort : id=%d channel=%d", id, channel);
6362 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
6363 snprintf(evStr, EVENT_DESCR_STR_SZ,
6364 "SAS Device Status Change: Internal Abort "
6365 "Task Set : id=%d channel=%d", id, channel);
6367 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
6368 snprintf(evStr, EVENT_DESCR_STR_SZ,
6369 "SAS Device Status Change: Internal Clear "
6370 "Task Set : id=%d channel=%d", id, channel);
6372 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
6373 snprintf(evStr, EVENT_DESCR_STR_SZ,
6374 "SAS Device Status Change: Internal Query "
6375 "Task : id=%d channel=%d", id, channel);
6378 snprintf(evStr, EVENT_DESCR_STR_SZ,
6379 "SAS Device Status Change: Unknown: "
6380 "id=%d channel=%d", id, channel);
6385 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
6386 ds = "Bus Timer Expired";
6388 case MPI_EVENT_QUEUE_FULL:
6390 u16 curr_depth = (u16)(evData0 >> 16);
6391 u8 channel = (u8)(evData0 >> 8);
6392 u8 id = (u8)(evData0);
6394 snprintf(evStr, EVENT_DESCR_STR_SZ,
6395 "Queue Full: channel=%d id=%d depth=%d",
6396 channel, id, curr_depth);
6399 case MPI_EVENT_SAS_SES:
6400 ds = "SAS SES Event";
6402 case MPI_EVENT_PERSISTENT_TABLE_FULL:
6403 ds = "Persistent Table Full";
6405 case MPI_EVENT_SAS_PHY_LINK_STATUS:
6407 u8 LinkRates = (u8)(evData0 >> 8);
6408 u8 PhyNumber = (u8)(evData0);
6409 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
6410 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
6411 switch (LinkRates) {
6412 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
6413 snprintf(evStr, EVENT_DESCR_STR_SZ,
6414 "SAS PHY Link Status: Phy=%d:"
6415 " Rate Unknown",PhyNumber);
6417 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
6418 snprintf(evStr, EVENT_DESCR_STR_SZ,
6419 "SAS PHY Link Status: Phy=%d:"
6420 " Phy Disabled",PhyNumber);
6422 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
6423 snprintf(evStr, EVENT_DESCR_STR_SZ,
6424 "SAS PHY Link Status: Phy=%d:"
6425 " Failed Speed Nego",PhyNumber);
6427 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
6428 snprintf(evStr, EVENT_DESCR_STR_SZ,
6429 "SAS PHY Link Status: Phy=%d:"
6430 " Sata OOB Completed",PhyNumber);
6432 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
6433 snprintf(evStr, EVENT_DESCR_STR_SZ,
6434 "SAS PHY Link Status: Phy=%d:"
6435 " Rate 1.5 Gbps",PhyNumber);
6437 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
6438 snprintf(evStr, EVENT_DESCR_STR_SZ,
6439 "SAS PHY Link Status: Phy=%d:"
6440 " Rate 3.0 Gpbs",PhyNumber);
6443 snprintf(evStr, EVENT_DESCR_STR_SZ,
6444 "SAS PHY Link Status: Phy=%d", PhyNumber);
6449 case MPI_EVENT_SAS_DISCOVERY_ERROR:
6450 ds = "SAS Discovery Error";
6452 case MPI_EVENT_IR_RESYNC_UPDATE:
6454 u8 resync_complete = (u8)(evData0 >> 16);
6455 snprintf(evStr, EVENT_DESCR_STR_SZ,
6456 "IR Resync Update: Complete = %d:",resync_complete);
6461 u8 ReasonCode = (u8)(evData0 >> 16);
6462 switch (ReasonCode) {
6463 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
6464 ds = "IR2: LD State Changed";
6466 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
6467 ds = "IR2: PD State Changed";
6469 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
6470 ds = "IR2: Bad Block Table Full";
6472 case MPI_EVENT_IR2_RC_PD_INSERTED:
6473 ds = "IR2: PD Inserted";
6475 case MPI_EVENT_IR2_RC_PD_REMOVED:
6476 ds = "IR2: PD Removed";
6478 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
6479 ds = "IR2: Foreign CFG Detected";
6481 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
6482 ds = "IR2: Rebuild Medium Error";
6490 case MPI_EVENT_SAS_DISCOVERY:
6493 ds = "SAS Discovery: Start";
6495 ds = "SAS Discovery: Stop";
6498 case MPI_EVENT_LOG_ENTRY_ADDED:
6499 ds = "SAS Log Entry Added";
6502 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
6504 u8 phy_num = (u8)(evData0);
6505 u8 port_num = (u8)(evData0 >> 8);
6506 u8 port_width = (u8)(evData0 >> 16);
6507 u8 primative = (u8)(evData0 >> 24);
6508 snprintf(evStr, EVENT_DESCR_STR_SZ,
6509 "SAS Broadcase Primative: phy=%d port=%d "
6510 "width=%d primative=0x%02x",
6511 phy_num, port_num, port_width, primative);
6515 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
6517 u8 reason = (u8)(evData0);
6518 u8 port_num = (u8)(evData0 >> 8);
6519 u16 handle = le16_to_cpu(evData0 >> 16);
6521 snprintf(evStr, EVENT_DESCR_STR_SZ,
6522 "SAS Initiator Device Status Change: reason=0x%02x "
6523 "port=%d handle=0x%04x",
6524 reason, port_num, handle);
6528 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
6530 u8 max_init = (u8)(evData0);
6531 u8 current_init = (u8)(evData0 >> 8);
6533 snprintf(evStr, EVENT_DESCR_STR_SZ,
6534 "SAS Initiator Device Table Overflow: max initiators=%02d "
6535 "current initators=%02d",
6536 max_init, current_init);
6539 case MPI_EVENT_SAS_SMP_ERROR:
6541 u8 status = (u8)(evData0);
6542 u8 port_num = (u8)(evData0 >> 8);
6543 u8 result = (u8)(evData0 >> 16);
6545 if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
6546 snprintf(evStr, EVENT_DESCR_STR_SZ,
6547 "SAS SMP Error: port=%d result=0x%02x",
6549 else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
6550 snprintf(evStr, EVENT_DESCR_STR_SZ,
6551 "SAS SMP Error: port=%d : CRC Error",
6553 else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
6554 snprintf(evStr, EVENT_DESCR_STR_SZ,
6555 "SAS SMP Error: port=%d : Timeout",
6557 else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
6558 snprintf(evStr, EVENT_DESCR_STR_SZ,
6559 "SAS SMP Error: port=%d : No Destination",
6561 else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
6562 snprintf(evStr, EVENT_DESCR_STR_SZ,
6563 "SAS SMP Error: port=%d : Bad Destination",
6566 snprintf(evStr, EVENT_DESCR_STR_SZ,
6567 "SAS SMP Error: port=%d : status=0x%02x",
6573 * MPT base "custom" events may be added here...
6580 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
6583 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6585 * ProcessEventNotification - Route EventNotificationReply to all event handlers
6586 * @ioc: Pointer to MPT_ADAPTER structure
6587 * @pEventReply: Pointer to EventNotification reply frame
6588 * @evHandlers: Pointer to integer, number of event handlers
6590 * Routes a received EventNotificationReply to all currently registered
6592 * Returns sum of event handlers return values.
6595 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
6604 char evStr[EVENT_DESCR_STR_SZ];
6608 * Do platform normalization of values
6610 event = le32_to_cpu(pEventReply->Event) & 0xFF;
6611 // evCtx = le32_to_cpu(pEventReply->EventContext);
6612 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
6614 evData0 = le32_to_cpu(pEventReply->Data[0]);
6617 EventDescriptionStr(event, evData0, evStr);
6618 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event:(%02Xh) : %s\n",
6623 #ifdef CONFIG_FUSION_LOGGING
6624 devtverboseprintk(ioc, printk(KERN_DEBUG MYNAM
6625 ": Event data:\n"));
6626 for (ii = 0; ii < evDataLen; ii++)
6627 devtverboseprintk(ioc, printk(" %08x",
6628 le32_to_cpu(pEventReply->Data[ii])));
6629 devtverboseprintk(ioc, printk(KERN_DEBUG "\n"));
6633 * Do general / base driver event processing
6636 case MPI_EVENT_EVENT_CHANGE: /* 0A */
6638 u8 evState = evData0 & 0xFF;
6640 /* CHECKME! What if evState unexpectedly says OFF (0)? */
6642 /* Update EventState field in cached IocFacts */
6643 if (ioc->facts.Function) {
6644 ioc->facts.EventState = evState;
6648 case MPI_EVENT_INTEGRATED_RAID:
6649 mptbase_raid_process_event_data(ioc,
6650 (MpiEventDataRaid_t *)pEventReply->Data);
6657 * Should this event be logged? Events are written sequentially.
6658 * When buffer is full, start again at the top.
6660 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
6663 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
6665 ioc->events[idx].event = event;
6666 ioc->events[idx].eventContext = ioc->eventContext;
6668 for (ii = 0; ii < 2; ii++) {
6670 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
6672 ioc->events[idx].data[ii] = 0;
6675 ioc->eventContext++;
6680 * Call each currently registered protocol event handler.
6682 for (cb_idx=MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6683 if (MptEvHandlers[cb_idx]) {
6684 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Routing Event to event handler #%d\n",
6685 ioc->name, cb_idx));
6686 r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply);
6690 /* FIXME? Examine results here? */
6693 * If needed, send (a single) EventAck.
6695 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
6696 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6697 "EventAck required\n",ioc->name));
6698 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
6699 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SendEventAck returned %d\n",
6704 *evHandlers = handlers;
6708 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6710 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
6711 * @ioc: Pointer to MPT_ADAPTER structure
6712 * @log_info: U32 LogInfo reply word from the IOC
6714 * Refer to lsi/mpi_log_fc.h.
6717 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
6719 char *desc = "unknown";
6721 switch (log_info & 0xFF000000) {
6722 case MPI_IOCLOGINFO_FC_INIT_BASE:
6723 desc = "FCP Initiator";
6725 case MPI_IOCLOGINFO_FC_TARGET_BASE:
6726 desc = "FCP Target";
6728 case MPI_IOCLOGINFO_FC_LAN_BASE:
6731 case MPI_IOCLOGINFO_FC_MSG_BASE:
6732 desc = "MPI Message Layer";
6734 case MPI_IOCLOGINFO_FC_LINK_BASE:
6737 case MPI_IOCLOGINFO_FC_CTX_BASE:
6738 desc = "Context Manager";
6740 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
6741 desc = "Invalid Field Offset";
6743 case MPI_IOCLOGINFO_FC_STATE_CHANGE:
6744 desc = "State Change Info";
6748 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
6749 ioc->name, log_info, desc, (log_info & 0xFFFFFF));
6752 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6754 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
6755 * @ioc: Pointer to MPT_ADAPTER structure
6756 * @mr: Pointer to MPT reply frame
6757 * @log_info: U32 LogInfo word from the IOC
6759 * Refer to lsi/sp_log.h.
6762 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
6764 u32 info = log_info & 0x00FF0000;
6765 char *desc = "unknown";
6769 desc = "bug! MID not found";
6770 if (ioc->reload_fw == 0)
6775 desc = "Parity Error";
6779 desc = "ASYNC Outbound Overrun";
6783 desc = "SYNC Offset Error";
6791 desc = "Msg In Overflow";
6799 desc = "Outbound DMA Overrun";
6803 desc = "Task Management";
6807 desc = "Device Problem";
6811 desc = "Invalid Phase Change";
6815 desc = "Untagged Table Size";
6820 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
6823 /* strings for sas loginfo */
6824 static char *originator_str[] = {
6829 static char *iop_code_str[] = {
6831 "Invalid SAS Address", /* 01h */
6833 "Invalid Page", /* 03h */
6834 "Diag Message Error", /* 04h */
6835 "Task Terminated", /* 05h */
6836 "Enclosure Management", /* 06h */
6837 "Target Mode" /* 07h */
6839 static char *pl_code_str[] = {
6841 "Open Failure", /* 01h */
6842 "Invalid Scatter Gather List", /* 02h */
6843 "Wrong Relative Offset or Frame Length", /* 03h */
6844 "Frame Transfer Error", /* 04h */
6845 "Transmit Frame Connected Low", /* 05h */
6846 "SATA Non-NCQ RW Error Bit Set", /* 06h */
6847 "SATA Read Log Receive Data Error", /* 07h */
6848 "SATA NCQ Fail All Commands After Error", /* 08h */
6849 "SATA Error in Receive Set Device Bit FIS", /* 09h */
6850 "Receive Frame Invalid Message", /* 0Ah */
6851 "Receive Context Message Valid Error", /* 0Bh */
6852 "Receive Frame Current Frame Error", /* 0Ch */
6853 "SATA Link Down", /* 0Dh */
6854 "Discovery SATA Init W IOS", /* 0Eh */
6855 "Config Invalid Page", /* 0Fh */
6856 "Discovery SATA Init Timeout", /* 10h */
6859 "IO Not Yet Executed", /* 13h */
6860 "IO Executed", /* 14h */
6861 "Persistent Reservation Out Not Affiliation "
6863 "Open Transmit DMA Abort", /* 16h */
6864 "IO Device Missing Delay Retry", /* 17h */
6865 "IO Cancelled Due to Recieve Error", /* 18h */
6873 "Enclosure Management" /* 20h */
6875 static char *ir_code_str[] = {
6876 "Raid Action Error", /* 00h */
6886 static char *raid_sub_code_str[] = {
6888 "Volume Creation Failed: Data Passed too "
6890 "Volume Creation Failed: Duplicate Volumes "
6891 "Attempted", /* 02h */
6892 "Volume Creation Failed: Max Number "
6893 "Supported Volumes Exceeded", /* 03h */
6894 "Volume Creation Failed: DMA Error", /* 04h */
6895 "Volume Creation Failed: Invalid Volume Type", /* 05h */
6896 "Volume Creation Failed: Error Reading "
6897 "MFG Page 4", /* 06h */
6898 "Volume Creation Failed: Creating Internal "
6899 "Structures", /* 07h */
6908 "Activation failed: Already Active Volume", /* 10h */
6909 "Activation failed: Unsupported Volume Type", /* 11h */
6910 "Activation failed: Too Many Active Volumes", /* 12h */
6911 "Activation failed: Volume ID in Use", /* 13h */
6912 "Activation failed: Reported Failure", /* 14h */
6913 "Activation failed: Importing a Volume", /* 15h */
6924 "Phys Disk failed: Too Many Phys Disks", /* 20h */
6925 "Phys Disk failed: Data Passed too Large", /* 21h */
6926 "Phys Disk failed: DMA Error", /* 22h */
6927 "Phys Disk failed: Invalid <channel:id>", /* 23h */
6928 "Phys Disk failed: Creating Phys Disk Config "
6941 "Compatibility Error: IR Disabled", /* 30h */
6942 "Compatibility Error: Inquiry Comand Failed", /* 31h */
6943 "Compatibility Error: Device not Direct Access "
6944 "Device ", /* 32h */
6945 "Compatibility Error: Removable Device Found", /* 33h */
6946 "Compatibility Error: Device SCSI Version not "
6947 "2 or Higher", /* 34h */
6948 "Compatibility Error: SATA Device, 48 BIT LBA "
6949 "not Supported", /* 35h */
6950 "Compatibility Error: Device doesn't have "
6951 "512 Byte Block Sizes", /* 36h */
6952 "Compatibility Error: Volume Type Check Failed", /* 37h */
6953 "Compatibility Error: Volume Type is "
6954 "Unsupported by FW", /* 38h */
6955 "Compatibility Error: Disk Drive too Small for "
6956 "use in Volume", /* 39h */
6957 "Compatibility Error: Phys Disk for Create "
6958 "Volume not Found", /* 3Ah */
6959 "Compatibility Error: Too Many or too Few "
6960 "Disks for Volume Type", /* 3Bh */
6961 "Compatibility Error: Disk stripe Sizes "
6962 "Must be 64KB", /* 3Ch */
6963 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
6966 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6968 * mpt_sas_log_info - Log information returned from SAS IOC.
6969 * @ioc: Pointer to MPT_ADAPTER structure
6970 * @log_info: U32 LogInfo reply word from the IOC
6972 * Refer to lsi/mpi_log_sas.h.
6975 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
6977 union loginfo_type {
6986 union loginfo_type sas_loginfo;
6987 char *originator_desc = NULL;
6988 char *code_desc = NULL;
6989 char *sub_code_desc = NULL;
6991 sas_loginfo.loginfo = log_info;
6992 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
6993 (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
6996 originator_desc = originator_str[sas_loginfo.dw.originator];
6998 switch (sas_loginfo.dw.originator) {
7001 if (sas_loginfo.dw.code <
7002 sizeof(iop_code_str)/sizeof(char*))
7003 code_desc = iop_code_str[sas_loginfo.dw.code];
7006 if (sas_loginfo.dw.code <
7007 sizeof(pl_code_str)/sizeof(char*))
7008 code_desc = pl_code_str[sas_loginfo.dw.code];
7011 if (sas_loginfo.dw.code >=
7012 sizeof(ir_code_str)/sizeof(char*))
7014 code_desc = ir_code_str[sas_loginfo.dw.code];
7015 if (sas_loginfo.dw.subcode >=
7016 sizeof(raid_sub_code_str)/sizeof(char*))
7018 if (sas_loginfo.dw.code == 0)
7020 raid_sub_code_str[sas_loginfo.dw.subcode];
7026 if (sub_code_desc != NULL)
7027 printk(MYIOC_s_INFO_FMT
7028 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7030 ioc->name, log_info, originator_desc, code_desc,
7032 else if (code_desc != NULL)
7033 printk(MYIOC_s_INFO_FMT
7034 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7035 " SubCode(0x%04x)\n",
7036 ioc->name, log_info, originator_desc, code_desc,
7037 sas_loginfo.dw.subcode);
7039 printk(MYIOC_s_INFO_FMT
7040 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
7041 " SubCode(0x%04x)\n",
7042 ioc->name, log_info, originator_desc,
7043 sas_loginfo.dw.code, sas_loginfo.dw.subcode);
7046 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7048 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
7049 * @ioc: Pointer to MPT_ADAPTER structure
7050 * @ioc_status: U32 IOCStatus word from IOC
7051 * @mf: Pointer to MPT request frame
7053 * Refer to lsi/mpi.h.
7056 mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7058 Config_t *pReq = (Config_t *)mf;
7059 char extend_desc[EVENT_DESCR_STR_SZ];
7064 if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
7065 page_type = pReq->ExtPageType;
7067 page_type = pReq->Header.PageType;
7070 * ignore invalid page messages for GET_NEXT_HANDLE
7072 form = le32_to_cpu(pReq->PageAddress);
7073 if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
7074 if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
7075 page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
7076 page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
7077 if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
7078 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
7081 if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
7082 if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
7083 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
7087 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
7088 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
7089 page_type, pReq->Header.PageNumber, pReq->Action, form);
7091 switch (ioc_status) {
7093 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7094 desc = "Config Page Invalid Action";
7097 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7098 desc = "Config Page Invalid Type";
7101 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7102 desc = "Config Page Invalid Page";
7105 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7106 desc = "Config Page Invalid Data";
7109 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7110 desc = "Config Page No Defaults";
7113 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7114 desc = "Config Page Can't Commit";
7121 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s: %s\n",
7122 ioc->name, ioc_status, desc, extend_desc);
7126 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
7127 * @ioc: Pointer to MPT_ADAPTER structure
7128 * @ioc_status: U32 IOCStatus word from IOC
7129 * @mf: Pointer to MPT request frame
7131 * Refer to lsi/mpi.h.
7134 mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7136 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
7141 /****************************************************************************/
7142 /* Common IOCStatus values for all replies */
7143 /****************************************************************************/
7145 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
7146 desc = "Invalid Function";
7149 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
7153 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
7154 desc = "Invalid SGL";
7157 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
7158 desc = "Internal Error";
7161 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
7165 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
7166 desc = "Insufficient Resources";
7169 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
7170 desc = "Invalid Field";
7173 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
7174 desc = "Invalid State";
7177 /****************************************************************************/
7178 /* Config IOCStatus values */
7179 /****************************************************************************/
7181 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7182 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7183 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7184 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7185 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7186 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7187 mpt_iocstatus_info_config(ioc, status, mf);
7190 /****************************************************************************/
7191 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
7193 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
7195 /****************************************************************************/
7197 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
7198 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
7199 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
7200 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
7201 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
7202 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
7203 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
7204 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
7205 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
7206 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
7207 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
7208 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
7209 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
7212 /****************************************************************************/
7213 /* SCSI Target values */
7214 /****************************************************************************/
7216 case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
7217 desc = "Target: Priority IO";
7220 case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
7221 desc = "Target: Invalid Port";
7224 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
7225 desc = "Target Invalid IO Index:";
7228 case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
7229 desc = "Target: Aborted";
7232 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
7233 desc = "Target: No Conn Retryable";
7236 case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
7237 desc = "Target: No Connection";
7240 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
7241 desc = "Target: Transfer Count Mismatch";
7244 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
7245 desc = "Target: STS Data not Sent";
7248 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
7249 desc = "Target: Data Offset Error";
7252 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
7253 desc = "Target: Too Much Write Data";
7256 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
7257 desc = "Target: IU Too Short";
7260 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
7261 desc = "Target: ACK NAK Timeout";
7264 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
7265 desc = "Target: Nak Received";
7268 /****************************************************************************/
7269 /* Fibre Channel Direct Access values */
7270 /****************************************************************************/
7272 case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
7273 desc = "FC: Aborted";
7276 case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
7277 desc = "FC: RX ID Invalid";
7280 case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
7281 desc = "FC: DID Invalid";
7284 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
7285 desc = "FC: Node Logged Out";
7288 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
7289 desc = "FC: Exchange Canceled";
7292 /****************************************************************************/
7294 /****************************************************************************/
7296 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
7297 desc = "LAN: Device not Found";
7300 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
7301 desc = "LAN: Device Failure";
7304 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
7305 desc = "LAN: Transmit Error";
7308 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
7309 desc = "LAN: Transmit Aborted";
7312 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
7313 desc = "LAN: Receive Error";
7316 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
7317 desc = "LAN: Receive Aborted";
7320 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
7321 desc = "LAN: Partial Packet";
7324 case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
7325 desc = "LAN: Canceled";
7328 /****************************************************************************/
7329 /* Serial Attached SCSI values */
7330 /****************************************************************************/
7332 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
7333 desc = "SAS: SMP Request Failed";
7336 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
7337 desc = "SAS: SMP Data Overrun";
7348 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s\n", ioc->name, status, desc);
7351 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7352 EXPORT_SYMBOL(mpt_attach);
7353 EXPORT_SYMBOL(mpt_detach);
7355 EXPORT_SYMBOL(mpt_resume);
7356 EXPORT_SYMBOL(mpt_suspend);
7358 EXPORT_SYMBOL(ioc_list);
7359 EXPORT_SYMBOL(mpt_proc_root_dir);
7360 EXPORT_SYMBOL(mpt_register);
7361 EXPORT_SYMBOL(mpt_deregister);
7362 EXPORT_SYMBOL(mpt_event_register);
7363 EXPORT_SYMBOL(mpt_event_deregister);
7364 EXPORT_SYMBOL(mpt_reset_register);
7365 EXPORT_SYMBOL(mpt_reset_deregister);
7366 EXPORT_SYMBOL(mpt_device_driver_register);
7367 EXPORT_SYMBOL(mpt_device_driver_deregister);
7368 EXPORT_SYMBOL(mpt_get_msg_frame);
7369 EXPORT_SYMBOL(mpt_put_msg_frame);
7370 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri);
7371 EXPORT_SYMBOL(mpt_free_msg_frame);
7372 EXPORT_SYMBOL(mpt_add_sge);
7373 EXPORT_SYMBOL(mpt_send_handshake_request);
7374 EXPORT_SYMBOL(mpt_verify_adapter);
7375 EXPORT_SYMBOL(mpt_GetIocState);
7376 EXPORT_SYMBOL(mpt_print_ioc_summary);
7377 EXPORT_SYMBOL(mpt_HardResetHandler);
7378 EXPORT_SYMBOL(mpt_config);
7379 EXPORT_SYMBOL(mpt_findImVolumes);
7380 EXPORT_SYMBOL(mpt_alloc_fw_memory);
7381 EXPORT_SYMBOL(mpt_free_fw_memory);
7382 EXPORT_SYMBOL(mptbase_sas_persist_operation);
7383 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
7385 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7387 * fusion_init - Fusion MPT base driver initialization routine.
7389 * Returns 0 for success, non-zero for failure.
7396 show_mptmod_ver(my_NAME, my_VERSION);
7397 printk(KERN_INFO COPYRIGHT "\n");
7399 for (cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
7400 MptCallbacks[cb_idx] = NULL;
7401 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
7402 MptEvHandlers[cb_idx] = NULL;
7403 MptResetHandlers[cb_idx] = NULL;
7406 /* Register ourselves (mptbase) in order to facilitate
7407 * EventNotification handling.
7409 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
7411 /* Register for hard reset handling callbacks.
7413 mpt_reset_register(mpt_base_index, mpt_ioc_reset);
7415 #ifdef CONFIG_PROC_FS
7416 (void) procmpt_create();
7421 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7423 * fusion_exit - Perform driver unload cleanup.
7425 * This routine frees all resources associated with each MPT adapter
7426 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
7432 mpt_reset_deregister(mpt_base_index);
7434 #ifdef CONFIG_PROC_FS
7439 module_init(fusion_init);
7440 module_exit(fusion_exit);