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 if (mpt_debug_level)
1462 printk(KERN_INFO MYNAM ": mpt_debug_level=%xh\n", mpt_debug_level);
1464 if (pci_enable_device(pdev))
1467 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1469 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1472 ioc->debug_level = mpt_debug_level;
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");
1485 if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
1486 dprintk(ioc, printk(KERN_INFO MYNAM
1487 ": Using 64 bit consistent mask\n"));
1489 dprintk(ioc, printk(KERN_INFO MYNAM
1490 ": Not using 64 bit consistent mask\n"));
1493 ioc->alloc_total = sizeof(MPT_ADAPTER);
1494 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1495 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1498 ioc->diagPending = 0;
1499 spin_lock_init(&ioc->diagLock);
1500 spin_lock_init(&ioc->initializing_hba_lock);
1502 /* Initialize the event logging.
1504 ioc->eventTypes = 0; /* None */
1505 ioc->eventContext = 0;
1506 ioc->eventLogSize = 0;
1513 ioc->cached_fw = NULL;
1515 /* Initilize SCSI Config Data structure
1517 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1519 /* Initialize the running configQ head.
1521 INIT_LIST_HEAD(&ioc->configQ);
1523 /* Initialize the fc rport list head.
1525 INIT_LIST_HEAD(&ioc->fc_rports);
1527 /* Find lookup slot. */
1528 INIT_LIST_HEAD(&ioc->list);
1529 ioc->id = mpt_ids++;
1531 mem_phys = msize = 0;
1533 for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1534 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1537 /* Get I/O space! */
1538 port = pci_resource_start(pdev, ii);
1539 psize = pci_resource_len(pdev,ii);
1544 mem_phys = pci_resource_start(pdev, ii);
1545 msize = pci_resource_len(pdev,ii);
1548 ioc->mem_size = msize;
1551 /* Get logical ptr for PciMem0 space */
1552 /*mem = ioremap(mem_phys, msize);*/
1553 mem = ioremap(mem_phys, msize);
1555 printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n");
1560 dinitprintk(ioc, printk(KERN_INFO MYNAM ": mem = %p, mem_phys = %lx\n", mem, mem_phys));
1562 dinitprintk(ioc, printk(KERN_INFO MYNAM ": facts @ %p, pfacts[0] @ %p\n",
1563 &ioc->facts, &ioc->pfacts[0]));
1565 ioc->mem_phys = mem_phys;
1566 ioc->chip = (SYSIF_REGS __iomem *)mem;
1568 /* Save Port IO values in case we need to do downloadboot */
1570 u8 *pmem = (u8*)port;
1571 ioc->pio_mem_phys = port;
1572 ioc->pio_chip = (SYSIF_REGS __iomem *)pmem;
1575 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1576 mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name);
1578 switch (pdev->device)
1580 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1581 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1582 ioc->errata_flag_1064 = 1;
1583 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1584 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1585 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1586 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1590 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1591 if (revision < XL_929) {
1592 /* 929X Chip Fix. Set Split transactions level
1593 * for PCIX. Set MOST bits to zero.
1595 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1597 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1599 /* 929XL Chip Fix. Set MMRBC to 0x08.
1601 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1603 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1608 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1609 /* 919X Chip Fix. Set Split transactions level
1610 * for PCIX. Set MOST bits to zero.
1612 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1614 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1618 case MPI_MANUFACTPAGE_DEVID_53C1030:
1619 /* 1030 Chip Fix. Disable Split transactions
1620 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1622 if (revision < C0_1030) {
1623 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1625 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1628 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1629 ioc->bus_type = SPI;
1632 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1633 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1634 ioc->errata_flag_1064 = 1;
1636 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1637 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1638 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1639 ioc->bus_type = SAS;
1642 if (ioc->errata_flag_1064)
1643 pci_disable_io_access(pdev);
1645 sprintf(ioc->name, "ioc%d", ioc->id);
1647 spin_lock_init(&ioc->FreeQlock);
1650 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1652 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1654 /* Set lookup ptr. */
1655 list_add_tail(&ioc->list, &ioc_list);
1657 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1659 mpt_detect_bound_ports(ioc, pdev);
1661 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1663 printk(KERN_WARNING MYNAM
1664 ": WARNING - %s did not initialize properly! (%d)\n",
1667 list_del(&ioc->list);
1669 ioc->alt_ioc->alt_ioc = NULL;
1672 pci_set_drvdata(pdev, NULL);
1676 /* call per device driver probe entry point */
1677 for(cb_idx=0; cb_idx<MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
1678 if(MptDeviceDriverHandlers[cb_idx] &&
1679 MptDeviceDriverHandlers[cb_idx]->probe) {
1680 MptDeviceDriverHandlers[cb_idx]->probe(pdev,id);
1684 #ifdef CONFIG_PROC_FS
1686 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1688 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1690 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1692 ent->read_proc = procmpt_iocinfo_read;
1695 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1697 ent->read_proc = procmpt_summary_read;
1706 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1708 * mpt_detach - Remove a PCI intelligent MPT adapter.
1709 * @pdev: Pointer to pci_dev structure
1713 mpt_detach(struct pci_dev *pdev)
1715 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1719 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
1720 remove_proc_entry(pname, NULL);
1721 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
1722 remove_proc_entry(pname, NULL);
1723 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
1724 remove_proc_entry(pname, NULL);
1726 /* call per device driver remove entry point */
1727 for(cb_idx=0; cb_idx<MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
1728 if(MptDeviceDriverHandlers[cb_idx] &&
1729 MptDeviceDriverHandlers[cb_idx]->remove) {
1730 MptDeviceDriverHandlers[cb_idx]->remove(pdev);
1734 /* Disable interrupts! */
1735 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1738 synchronize_irq(pdev->irq);
1740 /* Clear any lingering interrupt */
1741 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1743 CHIPREG_READ32(&ioc->chip->IntStatus);
1745 mpt_adapter_dispose(ioc);
1747 pci_set_drvdata(pdev, NULL);
1750 /**************************************************************************
1754 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1756 * mpt_suspend - Fusion MPT base driver suspend routine.
1757 * @pdev: Pointer to pci_dev structure
1758 * @state: new state to enter
1761 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
1764 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1766 device_state=pci_choose_state(pdev, state);
1768 printk(MYIOC_s_INFO_FMT
1769 "pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
1770 ioc->name, pdev, pci_name(pdev), device_state);
1772 pci_save_state(pdev);
1774 /* put ioc into READY_STATE */
1775 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
1776 printk(MYIOC_s_ERR_FMT
1777 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
1780 /* disable interrupts */
1781 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1784 /* Clear any lingering interrupt */
1785 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1787 pci_disable_device(pdev);
1788 pci_set_power_state(pdev, device_state);
1793 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1795 * mpt_resume - Fusion MPT base driver resume routine.
1796 * @pdev: Pointer to pci_dev structure
1799 mpt_resume(struct pci_dev *pdev)
1801 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1802 u32 device_state = pdev->current_state;
1806 printk(MYIOC_s_INFO_FMT
1807 "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
1808 ioc->name, pdev, pci_name(pdev), device_state);
1810 pci_set_power_state(pdev, 0);
1811 pci_restore_state(pdev);
1812 err = pci_enable_device(pdev);
1816 /* enable interrupts */
1817 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
1820 printk(MYIOC_s_INFO_FMT
1821 "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1823 (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1824 CHIPREG_READ32(&ioc->chip->Doorbell));
1826 /* bring ioc to operational state */
1827 if ((recovery_state = mpt_do_ioc_recovery(ioc,
1828 MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {
1829 printk(MYIOC_s_INFO_FMT
1830 "pci-resume: Cannot recover, error:[%x]\n",
1831 ioc->name, recovery_state);
1833 printk(MYIOC_s_INFO_FMT
1834 "pci-resume: success\n", ioc->name);
1842 mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase)
1844 if ((MptDriverClass[index] == MPTSPI_DRIVER &&
1845 ioc->bus_type != SPI) ||
1846 (MptDriverClass[index] == MPTFC_DRIVER &&
1847 ioc->bus_type != FC) ||
1848 (MptDriverClass[index] == MPTSAS_DRIVER &&
1849 ioc->bus_type != SAS))
1850 /* make sure we only call the relevant reset handler
1853 return (MptResetHandlers[index])(ioc, reset_phase);
1856 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1858 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1859 * @ioc: Pointer to MPT adapter structure
1860 * @reason: Event word / reason
1861 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1863 * This routine performs all the steps necessary to bring the IOC
1864 * to a OPERATIONAL state.
1866 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1871 * -1 if failed to get board READY
1872 * -2 if READY but IOCFacts Failed
1873 * -3 if READY but PrimeIOCFifos Failed
1874 * -4 if READY but IOCInit Failed
1877 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1879 int hard_reset_done = 0;
1880 int alt_ioc_ready = 0;
1887 int reset_alt_ioc_active = 0;
1888 int irq_allocated = 0;
1891 printk(KERN_INFO MYNAM ": Initiating %s %s\n",
1892 ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
1894 /* Disable reply interrupts (also blocks FreeQ) */
1895 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1899 if (ioc->alt_ioc->active)
1900 reset_alt_ioc_active = 1;
1902 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1903 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
1904 ioc->alt_ioc->active = 0;
1908 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
1911 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
1912 if (hard_reset_done == -4) {
1913 printk(KERN_WARNING MYNAM ": %s Owned by PEER..skipping!\n",
1916 if (reset_alt_ioc_active && ioc->alt_ioc) {
1917 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1918 dprintk(ioc, printk(KERN_INFO MYNAM
1919 ": alt-%s reply irq re-enabled\n",
1920 ioc->alt_ioc->name));
1921 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
1922 ioc->alt_ioc->active = 1;
1926 printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",
1932 /* hard_reset_done = 0 if a soft reset was performed
1933 * and 1 if a hard reset was performed.
1935 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
1936 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
1939 printk(KERN_WARNING MYNAM
1940 ": alt-%s: Not ready WARNING!\n",
1941 ioc->alt_ioc->name);
1944 for (ii=0; ii<5; ii++) {
1945 /* Get IOC facts! Allow 5 retries */
1946 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
1952 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Retry IocFacts failed rc=%x\n", ioc->name, rc));
1954 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1955 MptDisplayIocCapabilities(ioc);
1958 if (alt_ioc_ready) {
1959 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
1960 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1961 "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
1962 /* Retry - alt IOC was initialized once
1964 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
1967 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1968 "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
1970 reset_alt_ioc_active = 0;
1971 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1972 MptDisplayIocCapabilities(ioc->alt_ioc);
1977 * Device is reset now. It must have de-asserted the interrupt line
1978 * (if it was asserted) and it should be safe to register for the
1981 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1983 if (ioc->pcidev->irq) {
1984 if (mpt_msi_enable && !pci_enable_msi(ioc->pcidev))
1985 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
1987 rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
1988 IRQF_SHARED, ioc->name, ioc);
1990 printk(MYIOC_s_ERR_FMT "Unable to allocate "
1991 "interrupt %d!\n", ioc->name,
1994 pci_disable_msi(ioc->pcidev);
1998 ioc->pci_irq = ioc->pcidev->irq;
1999 pci_set_master(ioc->pcidev); /* ?? */
2000 pci_set_drvdata(ioc->pcidev, ioc);
2001 dprintk(ioc, printk(KERN_INFO MYNAM ": %s installed at interrupt "
2002 "%d\n", ioc->name, ioc->pcidev->irq));
2006 /* Prime reply & request queues!
2007 * (mucho alloc's) Must be done prior to
2008 * init as upper addresses are needed for init.
2009 * If fails, continue with alt-ioc processing
2011 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
2014 /* May need to check/upload firmware & data here!
2015 * If fails, continue with alt-ioc processing
2017 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
2020 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
2021 printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
2022 ioc->alt_ioc->name, rc);
2024 reset_alt_ioc_active = 0;
2027 if (alt_ioc_ready) {
2028 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
2030 reset_alt_ioc_active = 0;
2031 printk(KERN_WARNING MYNAM
2032 ": alt-%s: (%d) init failure WARNING!\n",
2033 ioc->alt_ioc->name, rc);
2037 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
2038 if (ioc->upload_fw) {
2039 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2040 "firmware upload required!\n", ioc->name));
2042 /* Controller is not operational, cannot do upload
2045 rc = mpt_do_upload(ioc, sleepFlag);
2047 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2049 * Maintain only one pointer to FW memory
2050 * so there will not be two attempt to
2051 * downloadboot onboard dual function
2052 * chips (mpt_adapter_disable,
2055 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2056 ": mpt_upload: alt_%s has cached_fw=%p \n",
2057 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
2058 ioc->alt_ioc->cached_fw = NULL;
2061 printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
2069 /* Enable! (reply interrupt) */
2070 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
2074 if (reset_alt_ioc_active && ioc->alt_ioc) {
2075 /* (re)Enable alt-IOC! (reply interrupt) */
2076 dinitprintk(ioc, printk(KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
2077 ioc->alt_ioc->name));
2078 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2079 ioc->alt_ioc->active = 1;
2082 /* Enable MPT base driver management of EventNotification
2083 * and EventAck handling.
2085 if ((ret == 0) && (!ioc->facts.EventState))
2086 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
2088 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2089 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
2091 /* Add additional "reason" check before call to GetLanConfigPages
2092 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2093 * recursive scenario; GetLanConfigPages times out, timer expired
2094 * routine calls HardResetHandler, which calls into here again,
2095 * and we try GetLanConfigPages again...
2097 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2100 * Initalize link list for inactive raid volumes.
2102 init_MUTEX(&ioc->raid_data.inactive_list_mutex);
2103 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2105 if (ioc->bus_type == SAS) {
2107 /* clear persistency table */
2108 if(ioc->facts.IOCExceptions &
2109 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
2110 ret = mptbase_sas_persist_operation(ioc,
2111 MPI_SAS_OP_CLEAR_NOT_PRESENT);
2118 mpt_findImVolumes(ioc);
2120 } else if (ioc->bus_type == FC) {
2121 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
2122 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2124 * Pre-fetch the ports LAN MAC address!
2125 * (LANPage1_t stuff)
2127 (void) GetLanConfigPages(ioc);
2128 a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2129 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2130 "LanAddr = %02X:%02X:%02X:"
2132 ioc->name, a[5], a[4],
2133 a[3], a[2], a[1], a[0] ));
2137 /* Get NVRAM and adapter maximums from SPP 0 and 2
2139 mpt_GetScsiPortSettings(ioc, 0);
2141 /* Get version and length of SDP 1
2143 mpt_readScsiDevicePageHeaders(ioc, 0);
2147 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
2148 mpt_findImVolumes(ioc);
2150 /* Check, and possibly reset, the coalescing value
2152 mpt_read_ioc_pg_1(ioc);
2154 mpt_read_ioc_pg_4(ioc);
2157 GetIoUnitPage2(ioc);
2158 mpt_get_manufacturing_pg_0(ioc);
2162 * Call each currently registered protocol IOC reset handler
2163 * with post-reset indication.
2164 * NOTE: If we're doing _IOC_BRINGUP, there can be no
2165 * MptResetHandlers[] registered yet.
2167 if (hard_reset_done) {
2169 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
2170 if ((ret == 0) && MptResetHandlers[cb_idx]) {
2171 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2172 "Calling IOC post_reset handler #%d\n",
2173 ioc->name, cb_idx));
2174 rc += mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET);
2178 if (alt_ioc_ready && MptResetHandlers[cb_idx]) {
2179 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2180 "Calling alt-%s post_reset handler #%d\n",
2181 ioc->name, ioc->alt_ioc->name, cb_idx));
2182 rc += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_POST_RESET);
2186 /* FIXME? Examine results here? */
2190 if ((ret != 0) && irq_allocated) {
2191 free_irq(ioc->pci_irq, ioc);
2193 pci_disable_msi(ioc->pcidev);
2198 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2200 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2201 * @ioc: Pointer to MPT adapter structure
2202 * @pdev: Pointer to (struct pci_dev) structure
2204 * Search for PCI bus/dev_function which matches
2205 * PCI bus/dev_function (+/-1) for newly discovered 929,
2206 * 929X, 1030 or 1035.
2208 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2209 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2212 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
2214 struct pci_dev *peer=NULL;
2215 unsigned int slot = PCI_SLOT(pdev->devfn);
2216 unsigned int func = PCI_FUNC(pdev->devfn);
2217 MPT_ADAPTER *ioc_srch;
2219 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PCI device %s devfn=%x/%x,"
2220 " searching for devfn match on %x or %x\n",
2221 ioc->name, pci_name(pdev), pdev->bus->number,
2222 pdev->devfn, func-1, func+1));
2224 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
2226 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
2231 list_for_each_entry(ioc_srch, &ioc_list, list) {
2232 struct pci_dev *_pcidev = ioc_srch->pcidev;
2233 if (_pcidev == peer) {
2234 /* Paranoia checks */
2235 if (ioc->alt_ioc != NULL) {
2236 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
2237 ioc->name, ioc->alt_ioc->name);
2239 } else if (ioc_srch->alt_ioc != NULL) {
2240 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
2241 ioc_srch->name, ioc_srch->alt_ioc->name);
2244 dprintk(ioc, printk(KERN_INFO MYNAM ": FOUND! binding %s <==> %s\n",
2245 ioc->name, ioc_srch->name));
2246 ioc_srch->alt_ioc = ioc;
2247 ioc->alt_ioc = ioc_srch;
2253 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2255 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2256 * @ioc: Pointer to MPT adapter structure
2259 mpt_adapter_disable(MPT_ADAPTER *ioc)
2264 if (ioc->cached_fw != NULL) {
2265 ddlprintk(ioc, printk(KERN_INFO MYNAM ": mpt_adapter_disable: Pushing FW onto adapter\n"));
2266 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)ioc->cached_fw, NO_SLEEP)) < 0) {
2267 printk(KERN_WARNING MYNAM
2268 ": firmware downloadboot failure (%d)!\n", ret);
2272 /* Disable adapter interrupts! */
2273 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2275 /* Clear any lingering interrupt */
2276 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2278 if (ioc->alloc != NULL) {
2280 dexitprintk(ioc, printk(KERN_INFO MYNAM ": %s.free @ %p, sz=%d bytes\n",
2281 ioc->name, ioc->alloc, ioc->alloc_sz));
2282 pci_free_consistent(ioc->pcidev, sz,
2283 ioc->alloc, ioc->alloc_dma);
2284 ioc->reply_frames = NULL;
2285 ioc->req_frames = NULL;
2287 ioc->alloc_total -= sz;
2290 if (ioc->sense_buf_pool != NULL) {
2291 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2292 pci_free_consistent(ioc->pcidev, sz,
2293 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2294 ioc->sense_buf_pool = NULL;
2295 ioc->alloc_total -= sz;
2298 if (ioc->events != NULL){
2299 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2302 ioc->alloc_total -= sz;
2305 if (ioc->cached_fw != NULL) {
2306 sz = ioc->facts.FWImageSize;
2307 pci_free_consistent(ioc->pcidev, sz,
2308 ioc->cached_fw, ioc->cached_fw_dma);
2309 ioc->cached_fw = NULL;
2310 ioc->alloc_total -= sz;
2313 kfree(ioc->spi_data.nvram);
2314 mpt_inactive_raid_list_free(ioc);
2315 kfree(ioc->raid_data.pIocPg2);
2316 kfree(ioc->raid_data.pIocPg3);
2317 ioc->spi_data.nvram = NULL;
2318 ioc->raid_data.pIocPg3 = NULL;
2320 if (ioc->spi_data.pIocPg4 != NULL) {
2321 sz = ioc->spi_data.IocPg4Sz;
2322 pci_free_consistent(ioc->pcidev, sz,
2323 ioc->spi_data.pIocPg4,
2324 ioc->spi_data.IocPg4_dma);
2325 ioc->spi_data.pIocPg4 = NULL;
2326 ioc->alloc_total -= sz;
2329 if (ioc->ReqToChain != NULL) {
2330 kfree(ioc->ReqToChain);
2331 kfree(ioc->RequestNB);
2332 ioc->ReqToChain = NULL;
2335 kfree(ioc->ChainToChain);
2336 ioc->ChainToChain = NULL;
2338 if (ioc->HostPageBuffer != NULL) {
2339 if((ret = mpt_host_page_access_control(ioc,
2340 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2341 printk(KERN_ERR MYNAM
2342 ": %s: host page buffers free failed (%d)!\n",
2345 dexitprintk(ioc, printk(KERN_INFO MYNAM ": %s HostPageBuffer free @ %p, sz=%d bytes\n",
2346 ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
2347 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2348 ioc->HostPageBuffer,
2349 ioc->HostPageBuffer_dma);
2350 ioc->HostPageBuffer = NULL;
2351 ioc->HostPageBuffer_sz = 0;
2352 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2356 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2358 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2359 * @ioc: Pointer to MPT adapter structure
2361 * This routine unregisters h/w resources and frees all alloc'd memory
2362 * associated with a MPT adapter structure.
2365 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2367 int sz_first, sz_last;
2372 sz_first = ioc->alloc_total;
2374 mpt_adapter_disable(ioc);
2376 if (ioc->pci_irq != -1) {
2377 free_irq(ioc->pci_irq, ioc);
2379 pci_disable_msi(ioc->pcidev);
2383 if (ioc->memmap != NULL) {
2384 iounmap(ioc->memmap);
2388 #if defined(CONFIG_MTRR) && 0
2389 if (ioc->mtrr_reg > 0) {
2390 mtrr_del(ioc->mtrr_reg, 0, 0);
2391 dprintk(ioc, printk(KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name));
2395 /* Zap the adapter lookup ptr! */
2396 list_del(&ioc->list);
2398 sz_last = ioc->alloc_total;
2399 dprintk(ioc, printk(KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
2400 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2403 ioc->alt_ioc->alt_ioc = NULL;
2408 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2410 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2411 * @ioc: Pointer to MPT adapter structure
2414 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2418 printk(KERN_INFO "%s: ", ioc->name);
2420 printk("%s: ", ioc->prod_name);
2421 printk("Capabilities={");
2423 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2424 printk("Initiator");
2428 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2429 printk("%sTarget", i ? "," : "");
2433 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2434 printk("%sLAN", i ? "," : "");
2440 * This would probably evoke more questions than it's worth
2442 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2443 printk("%sLogBusAddr", i ? "," : "");
2451 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2453 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2454 * @ioc: Pointer to MPT_ADAPTER structure
2455 * @force: Force hard KickStart of IOC
2456 * @sleepFlag: Specifies whether the process can sleep
2459 * 1 - DIAG reset and READY
2460 * 0 - READY initially OR soft reset and READY
2461 * -1 - Any failure on KickStart
2462 * -2 - Msg Unit Reset Failed
2463 * -3 - IO Unit Reset Failed
2464 * -4 - IOC owned by a PEER
2467 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2472 int hard_reset_done = 0;
2477 /* Get current [raw] IOC state */
2478 ioc_state = mpt_GetIocState(ioc, 0);
2479 dhsprintk(ioc, printk(KERN_INFO MYNAM "::MakeIocReady, %s [raw] state=%08x\n", ioc->name, ioc_state));
2482 * Check to see if IOC got left/stuck in doorbell handshake
2483 * grip of death. If so, hard reset the IOC.
2485 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2487 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2491 /* Is it already READY? */
2492 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
2496 * Check to see if IOC is in FAULT state.
2498 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2500 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2502 printk(KERN_WARNING " FAULT code = %04xh\n",
2503 ioc_state & MPI_DOORBELL_DATA_MASK);
2507 * Hmmm... Did it get left operational?
2509 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2510 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC operational unexpected\n",
2514 * If PCI Peer, exit.
2515 * Else, if no fault conditions are present, issue a MessageUnitReset
2516 * Else, fall through to KickStart case
2518 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2519 dinitprintk(ioc, printk(KERN_INFO MYNAM
2520 ": whoinit 0x%x statefault %d force %d\n",
2521 whoinit, statefault, force));
2522 if (whoinit == MPI_WHOINIT_PCI_PEER)
2525 if ((statefault == 0 ) && (force == 0)) {
2526 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2533 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2534 if (hard_reset_done < 0)
2538 * Loop here waiting for IOC to come READY.
2541 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2543 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2544 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2546 * BIOS or previous driver load left IOC in OP state.
2547 * Reset messaging FIFOs.
2549 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2550 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2553 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2555 * Something is wrong. Try to get IOC back
2558 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2559 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2566 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2567 ioc->name, (int)((ii+5)/HZ));
2571 if (sleepFlag == CAN_SLEEP) {
2574 mdelay (1); /* 1 msec delay */
2579 if (statefault < 3) {
2580 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2582 statefault==1 ? "stuck handshake" : "IOC FAULT");
2585 return hard_reset_done;
2588 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2590 * mpt_GetIocState - Get the current state of a MPT adapter.
2591 * @ioc: Pointer to MPT_ADAPTER structure
2592 * @cooked: Request raw or cooked IOC state
2594 * Returns all IOC Doorbell register bits if cooked==0, else just the
2595 * Doorbell bits in MPI_IOC_STATE_MASK.
2598 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2603 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2604 // dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
2605 sc = s & MPI_IOC_STATE_MASK;
2608 ioc->last_state = sc;
2610 return cooked ? sc : s;
2613 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2615 * GetIocFacts - Send IOCFacts request to MPT adapter.
2616 * @ioc: Pointer to MPT_ADAPTER structure
2617 * @sleepFlag: Specifies whether the process can sleep
2618 * @reason: If recovery, only update facts.
2620 * Returns 0 for success, non-zero for failure.
2623 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2625 IOCFacts_t get_facts;
2626 IOCFactsReply_t *facts;
2634 /* IOC *must* NOT be in RESET state! */
2635 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2636 printk(KERN_ERR MYNAM ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
2642 facts = &ioc->facts;
2644 /* Destination (reply area)... */
2645 reply_sz = sizeof(*facts);
2646 memset(facts, 0, reply_sz);
2648 /* Request area (get_facts on the stack right now!) */
2649 req_sz = sizeof(get_facts);
2650 memset(&get_facts, 0, req_sz);
2652 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2653 /* Assert: All other get_facts fields are zero! */
2655 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2656 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2657 ioc->name, req_sz, reply_sz));
2659 /* No non-zero fields in the get_facts request are greater than
2660 * 1 byte in size, so we can just fire it off as is.
2662 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2663 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2668 * Now byte swap (GRRR) the necessary fields before any further
2669 * inspection of reply contents.
2671 * But need to do some sanity checks on MsgLength (byte) field
2672 * to make sure we don't zero IOC's req_sz!
2674 /* Did we get a valid reply? */
2675 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2676 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2678 * If not been here, done that, save off first WhoInit value
2680 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2681 ioc->FirstWhoInit = facts->WhoInit;
2684 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2685 facts->MsgContext = le32_to_cpu(facts->MsgContext);
2686 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2687 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2688 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2689 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
2690 /* CHECKME! IOCStatus, IOCLogInfo */
2692 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2693 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2696 * FC f/w version changed between 1.1 and 1.2
2697 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2698 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2700 if (facts->MsgVersion < 0x0102) {
2702 * Handle old FC f/w style, convert to new...
2704 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2705 facts->FWVersion.Word =
2706 ((oldv<<12) & 0xFF000000) |
2707 ((oldv<<8) & 0x000FFF00);
2709 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2711 facts->ProductID = le16_to_cpu(facts->ProductID);
2712 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
2713 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
2714 ioc->ir_firmware = 1;
2715 facts->CurrentHostMfaHighAddr =
2716 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2717 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2718 facts->CurrentSenseBufferHighAddr =
2719 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2720 facts->CurReplyFrameSize =
2721 le16_to_cpu(facts->CurReplyFrameSize);
2722 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
2725 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2726 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2727 * to 14 in MPI-1.01.0x.
2729 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2730 facts->MsgVersion > 0x0100) {
2731 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2734 sz = facts->FWImageSize;
2739 facts->FWImageSize = sz;
2741 if (!facts->RequestFrameSize) {
2742 /* Something is wrong! */
2743 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2748 r = sz = facts->BlockSize;
2749 vv = ((63 / (sz * 4)) + 1) & 0x03;
2750 ioc->NB_for_64_byte_frame = vv;
2756 ioc->NBShiftFactor = shiftFactor;
2757 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2758 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2759 ioc->name, vv, shiftFactor, r));
2761 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2763 * Set values for this IOC's request & reply frame sizes,
2764 * and request & reply queue depths...
2766 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2767 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2768 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2769 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2771 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "reply_sz=%3d, reply_depth=%4d\n",
2772 ioc->name, ioc->reply_sz, ioc->reply_depth));
2773 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "req_sz =%3d, req_depth =%4d\n",
2774 ioc->name, ioc->req_sz, ioc->req_depth));
2776 /* Get port facts! */
2777 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2781 printk(MYIOC_s_ERR_FMT
2782 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2783 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2784 RequestFrameSize)/sizeof(u32)));
2791 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2793 * GetPortFacts - Send PortFacts request to MPT adapter.
2794 * @ioc: Pointer to MPT_ADAPTER structure
2795 * @portnum: Port number
2796 * @sleepFlag: Specifies whether the process can sleep
2798 * Returns 0 for success, non-zero for failure.
2801 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2803 PortFacts_t get_pfacts;
2804 PortFactsReply_t *pfacts;
2810 /* IOC *must* NOT be in RESET state! */
2811 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2812 printk(KERN_ERR MYNAM ": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n",
2818 pfacts = &ioc->pfacts[portnum];
2820 /* Destination (reply area)... */
2821 reply_sz = sizeof(*pfacts);
2822 memset(pfacts, 0, reply_sz);
2824 /* Request area (get_pfacts on the stack right now!) */
2825 req_sz = sizeof(get_pfacts);
2826 memset(&get_pfacts, 0, req_sz);
2828 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2829 get_pfacts.PortNumber = portnum;
2830 /* Assert: All other get_pfacts fields are zero! */
2832 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending get PortFacts(%d) request\n",
2833 ioc->name, portnum));
2835 /* No non-zero fields in the get_pfacts request are greater than
2836 * 1 byte in size, so we can just fire it off as is.
2838 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2839 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2843 /* Did we get a valid reply? */
2845 /* Now byte swap the necessary fields in the response. */
2846 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2847 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2848 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2849 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2850 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2851 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2852 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2853 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2854 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2856 max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
2858 ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
2859 ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
2862 * Place all the devices on channels
2866 if (mpt_channel_mapping) {
2867 ioc->devices_per_bus = 1;
2868 ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
2874 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2876 * SendIocInit - Send IOCInit request to MPT adapter.
2877 * @ioc: Pointer to MPT_ADAPTER structure
2878 * @sleepFlag: Specifies whether the process can sleep
2880 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2882 * Returns 0 for success, non-zero for failure.
2885 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2888 MPIDefaultReply_t init_reply;
2894 memset(&ioc_init, 0, sizeof(ioc_init));
2895 memset(&init_reply, 0, sizeof(init_reply));
2897 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2898 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2900 /* If we are in a recovery mode and we uploaded the FW image,
2901 * then this pointer is not NULL. Skip the upload a second time.
2902 * Set this flag if cached_fw set for either IOC.
2904 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
2908 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "upload_fw %d facts.Flags=%x\n",
2909 ioc->name, ioc->upload_fw, ioc->facts.Flags));
2911 ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
2912 ioc_init.MaxBuses = (U8)ioc->number_of_buses;
2913 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n",
2914 ioc->name, ioc->facts.MsgVersion));
2915 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
2916 // set MsgVersion and HeaderVersion host driver was built with
2917 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
2918 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
2920 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
2921 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
2922 } else if(mpt_host_page_alloc(ioc, &ioc_init))
2925 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
2927 if (sizeof(dma_addr_t) == sizeof(u64)) {
2928 /* Save the upper 32-bits of the request
2929 * (reply) and sense buffers.
2931 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
2932 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2934 /* Force 32-bit addressing */
2935 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
2936 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
2939 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
2940 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
2941 ioc->facts.MaxDevices = ioc_init.MaxDevices;
2942 ioc->facts.MaxBuses = ioc_init.MaxBuses;
2944 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOCInit (req @ %p)\n",
2945 ioc->name, &ioc_init));
2947 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
2948 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
2950 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
2954 /* No need to byte swap the multibyte fields in the reply
2955 * since we don't even look at its contents.
2958 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending PortEnable (req @ %p)\n",
2959 ioc->name, &ioc_init));
2961 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
2962 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
2966 /* YIKES! SUPER IMPORTANT!!!
2967 * Poll IocState until _OPERATIONAL while IOC is doing
2968 * LoopInit and TargetDiscovery!
2971 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
2972 state = mpt_GetIocState(ioc, 1);
2973 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
2974 if (sleepFlag == CAN_SLEEP) {
2981 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
2982 ioc->name, (int)((count+5)/HZ));
2986 state = mpt_GetIocState(ioc, 1);
2989 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
2992 ioc->aen_event_read_flag=0;
2996 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2998 * SendPortEnable - Send PortEnable request to MPT adapter port.
2999 * @ioc: Pointer to MPT_ADAPTER structure
3000 * @portnum: Port number to enable
3001 * @sleepFlag: Specifies whether the process can sleep
3003 * Send PortEnable to bring IOC to OPERATIONAL state.
3005 * Returns 0 for success, non-zero for failure.
3008 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3010 PortEnable_t port_enable;
3011 MPIDefaultReply_t reply_buf;
3016 /* Destination... */
3017 reply_sz = sizeof(MPIDefaultReply_t);
3018 memset(&reply_buf, 0, reply_sz);
3020 req_sz = sizeof(PortEnable_t);
3021 memset(&port_enable, 0, req_sz);
3023 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
3024 port_enable.PortNumber = portnum;
3025 /* port_enable.ChainOffset = 0; */
3026 /* port_enable.MsgFlags = 0; */
3027 /* port_enable.MsgContext = 0; */
3029 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Port(%d)Enable (req @ %p)\n",
3030 ioc->name, portnum, &port_enable));
3032 /* RAID FW may take a long time to enable
3034 if (ioc->ir_firmware || ioc->bus_type == SAS) {
3035 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3036 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3037 300 /*seconds*/, sleepFlag);
3039 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3040 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3041 30 /*seconds*/, sleepFlag);
3047 * mpt_alloc_fw_memory - allocate firmware memory
3048 * @ioc: Pointer to MPT_ADAPTER structure
3049 * @size: total FW bytes
3051 * If memory has already been allocated, the same (cached) value
3055 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
3058 return; /* use already allocated memory */
3059 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
3060 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
3061 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
3062 ioc->alloc_total += size;
3063 ioc->alt_ioc->alloc_total -= size;
3065 if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
3066 ioc->alloc_total += size;
3070 * mpt_free_fw_memory - free firmware memory
3071 * @ioc: Pointer to MPT_ADAPTER structure
3073 * If alt_img is NULL, delete from ioc structure.
3074 * Else, delete a secondary image in same format.
3077 mpt_free_fw_memory(MPT_ADAPTER *ioc)
3081 sz = ioc->facts.FWImageSize;
3082 dinitprintk(ioc, printk(KERN_INFO MYNAM "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3083 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3084 pci_free_consistent(ioc->pcidev, sz,
3085 ioc->cached_fw, ioc->cached_fw_dma);
3086 ioc->cached_fw = NULL;
3092 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3094 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3095 * @ioc: Pointer to MPT_ADAPTER structure
3096 * @sleepFlag: Specifies whether the process can sleep
3098 * Returns 0 for success, >0 for handshake failure
3099 * <0 for fw upload failure.
3101 * Remark: If bound IOC and a successful FWUpload was performed
3102 * on the bound IOC, the second image is discarded
3103 * and memory is free'd. Both channels must upload to prevent
3104 * IOC from running in degraded mode.
3107 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3109 u8 request[ioc->req_sz];
3110 u8 reply[sizeof(FWUploadReply_t)];
3111 FWUpload_t *prequest;
3112 FWUploadReply_t *preply;
3113 FWUploadTCSGE_t *ptcsge;
3116 int ii, sz, reply_sz;
3119 /* If the image size is 0, we are done.
3121 if ((sz = ioc->facts.FWImageSize) == 0)
3124 mpt_alloc_fw_memory(ioc, sz);
3126 dinitprintk(ioc, printk(KERN_INFO MYNAM ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3127 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3129 if (ioc->cached_fw == NULL) {
3135 prequest = (FWUpload_t *)&request;
3136 preply = (FWUploadReply_t *)&reply;
3138 /* Destination... */
3139 memset(prequest, 0, ioc->req_sz);
3141 reply_sz = sizeof(reply);
3142 memset(preply, 0, reply_sz);
3144 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
3145 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
3147 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
3148 ptcsge->DetailsLength = 12;
3149 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
3150 ptcsge->ImageSize = cpu_to_le32(sz);
3152 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
3154 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3155 mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma);
3157 sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
3158 dinitprintk(ioc, printk(KERN_INFO MYNAM ": Sending FW Upload (req @ %p) sgeoffset=%d \n",
3159 prequest, sgeoffset));
3160 DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest)
3162 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
3163 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
3165 dinitprintk(ioc, printk(KERN_INFO MYNAM ": FW Upload completed rc=%x \n", ii));
3167 cmdStatus = -EFAULT;
3169 /* Handshake transfer was complete and successful.
3170 * Check the Reply Frame.
3172 int status, transfer_sz;
3173 status = le16_to_cpu(preply->IOCStatus);
3174 if (status == MPI_IOCSTATUS_SUCCESS) {
3175 transfer_sz = le32_to_cpu(preply->ActualImageSize);
3176 if (transfer_sz == sz)
3180 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n",
3181 ioc->name, cmdStatus));
3186 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": fw upload failed, freeing image \n",
3188 mpt_free_fw_memory(ioc);
3194 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3196 * mpt_downloadboot - DownloadBoot code
3197 * @ioc: Pointer to MPT_ADAPTER structure
3198 * @pFwHeader: Pointer to firmware header info
3199 * @sleepFlag: Specifies whether the process can sleep
3201 * FwDownloadBoot requires Programmed IO access.
3203 * Returns 0 for success
3204 * -1 FW Image size is 0
3205 * -2 No valid cached_fw Pointer
3206 * <0 for fw upload failure.
3209 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3211 MpiExtImageHeader_t *pExtImage;
3221 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3222 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
3224 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3225 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3226 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3227 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3228 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3229 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3231 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
3234 if (sleepFlag == CAN_SLEEP) {
3240 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3241 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3243 for (count = 0; count < 30; count ++) {
3244 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3245 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3246 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESET_ADAPTER cleared, count=%d\n",
3251 if (sleepFlag == CAN_SLEEP) {
3258 if ( count == 30 ) {
3259 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot failed! "
3260 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3261 ioc->name, diag0val));
3265 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3266 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3267 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3268 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3269 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3270 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3272 /* Set the DiagRwEn and Disable ARM bits */
3273 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3275 fwSize = (pFwHeader->ImageSize + 3)/4;
3276 ptrFw = (u32 *) pFwHeader;
3278 /* Write the LoadStartAddress to the DiagRw Address Register
3279 * using Programmed IO
3281 if (ioc->errata_flag_1064)
3282 pci_enable_io_access(ioc->pcidev);
3284 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3285 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "LoadStart addr written 0x%x \n",
3286 ioc->name, pFwHeader->LoadStartAddress));
3288 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write FW Image: 0x%x bytes @ %p\n",
3289 ioc->name, fwSize*4, ptrFw));
3291 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3294 nextImage = pFwHeader->NextImageHeaderOffset;
3296 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3298 load_addr = pExtImage->LoadStartAddress;
3300 fwSize = (pExtImage->ImageSize + 3) >> 2;
3301 ptrFw = (u32 *)pExtImage;
3303 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3304 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3305 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3308 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3310 nextImage = pExtImage->NextImageHeaderOffset;
3313 /* Write the IopResetVectorRegAddr */
3314 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
3315 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3317 /* Write the IopResetVectorValue */
3318 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3319 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3321 /* Clear the internal flash bad bit - autoincrementing register,
3322 * so must do two writes.
3324 if (ioc->bus_type == SPI) {
3326 * 1030 and 1035 H/W errata, workaround to access
3327 * the ClearFlashBadSignatureBit
3329 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3330 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3331 diagRwData |= 0x40000000;
3332 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3333 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3335 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3336 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3337 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3338 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3341 if (sleepFlag == CAN_SLEEP) {
3348 if (ioc->errata_flag_1064)
3349 pci_disable_io_access(ioc->pcidev);
3351 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3352 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot diag0val=%x, "
3353 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3354 ioc->name, diag0val));
3355 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3356 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot now diag0val=%x\n",
3357 ioc->name, diag0val));
3358 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3360 /* Write 0xFF to reset the sequencer */
3361 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3363 if (ioc->bus_type == SAS) {
3364 ioc_state = mpt_GetIocState(ioc, 0);
3365 if ( (GetIocFacts(ioc, sleepFlag,
3366 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3367 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "GetIocFacts failed: IocState=%x\n",
3368 ioc->name, ioc_state));
3373 for (count=0; count<HZ*20; count++) {
3374 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3375 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3376 "downloadboot successful! (count=%d) IocState=%x\n",
3377 ioc->name, count, ioc_state));
3378 if (ioc->bus_type == SAS) {
3381 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3382 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3383 "downloadboot: SendIocInit failed\n",
3387 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3388 "downloadboot: SendIocInit successful\n",
3392 if (sleepFlag == CAN_SLEEP) {
3398 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3399 "downloadboot failed! IocState=%x\n",ioc->name, ioc_state));
3403 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3405 * KickStart - Perform hard reset of MPT adapter.
3406 * @ioc: Pointer to MPT_ADAPTER structure
3407 * @force: Force hard reset
3408 * @sleepFlag: Specifies whether the process can sleep
3410 * This routine places MPT adapter in diagnostic mode via the
3411 * WriteSequence register, and then performs a hard reset of adapter
3412 * via the Diagnostic register.
3414 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3415 * or NO_SLEEP (interrupt thread, use mdelay)
3416 * force - 1 if doorbell active, board fault state
3417 * board operational, IOC_RECOVERY or
3418 * IOC_BRINGUP and there is an alt_ioc.
3422 * 1 - hard reset, READY
3423 * 0 - no reset due to History bit, READY
3424 * -1 - no reset due to History bit but not READY
3425 * OR reset but failed to come READY
3426 * -2 - no reset, could not enter DIAG mode
3427 * -3 - reset but bad FW bit
3430 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3432 int hard_reset_done = 0;
3436 dinitprintk(ioc, printk(KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
3437 if (ioc->bus_type == SPI) {
3438 /* Always issue a Msg Unit Reset first. This will clear some
3439 * SCSI bus hang conditions.
3441 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3443 if (sleepFlag == CAN_SLEEP) {
3450 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3451 if (hard_reset_done < 0)
3452 return hard_reset_done;
3454 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n",
3457 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3458 for (cnt=0; cnt<cntdn; cnt++) {
3459 ioc_state = mpt_GetIocState(ioc, 1);
3460 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3461 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStart successful! (cnt=%d)\n",
3463 return hard_reset_done;
3465 if (sleepFlag == CAN_SLEEP) {
3472 printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3473 ioc->name, ioc_state);
3477 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3479 * mpt_diag_reset - Perform hard reset of the adapter.
3480 * @ioc: Pointer to MPT_ADAPTER structure
3481 * @ignore: Set if to honor and clear to ignore
3482 * the reset history bit
3483 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3484 * else set to NO_SLEEP (use mdelay instead)
3486 * This routine places the adapter in diagnostic mode via the
3487 * WriteSequence register and then performs a hard reset of adapter
3488 * via the Diagnostic register. Adapter should be in ready state
3489 * upon successful completion.
3491 * Returns: 1 hard reset successful
3492 * 0 no reset performed because reset history bit set
3493 * -2 enabling diagnostic mode failed
3494 * -3 diagnostic reset failed
3497 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3499 MPT_ADAPTER *iocp=NULL;
3502 int hard_reset_done = 0;
3506 /* Clear any existing interrupts */
3507 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3509 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3510 drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3511 "address=%p\n", ioc->name, __FUNCTION__,
3512 &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3513 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3514 if (sleepFlag == CAN_SLEEP)
3519 for (count = 0; count < 60; count ++) {
3520 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3521 doorbell &= MPI_IOC_STATE_MASK;
3523 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3524 "looking for READY STATE: doorbell=%x"
3526 ioc->name, doorbell, count));
3527 if (doorbell == MPI_IOC_STATE_READY) {
3532 if (sleepFlag == CAN_SLEEP)
3540 /* Use "Diagnostic reset" method! (only thing available!) */
3541 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3543 if (ioc->debug_level & MPT_DEBUG) {
3545 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3546 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3547 ioc->name, diag0val, diag1val));
3550 /* Do the reset if we are told to ignore the reset history
3551 * or if the reset history is 0
3553 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3554 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3555 /* Write magic sequence to WriteSequence register
3556 * Loop until in diagnostic mode
3558 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3559 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3560 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3561 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3562 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3563 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3566 if (sleepFlag == CAN_SLEEP) {
3574 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3575 ioc->name, diag0val);
3580 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3582 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3583 ioc->name, diag0val));
3586 if (ioc->debug_level & MPT_DEBUG) {
3588 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3589 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3590 ioc->name, diag0val, diag1val));
3593 * Disable the ARM (Bug fix)
3596 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3600 * Now hit the reset bit in the Diagnostic register
3601 * (THE BIG HAMMER!) (Clears DRWE bit).
3603 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3604 hard_reset_done = 1;
3605 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset performed\n",
3609 * Call each currently registered protocol IOC reset handler
3610 * with pre-reset indication.
3611 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3612 * MptResetHandlers[] registered yet.
3618 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
3619 if (MptResetHandlers[cb_idx]) {
3620 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3621 "Calling IOC pre_reset handler #%d\n",
3622 ioc->name, cb_idx));
3623 r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET);
3625 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3626 "Calling alt-%s pre_reset handler #%d\n",
3627 ioc->name, ioc->alt_ioc->name, cb_idx));
3628 r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_PRE_RESET);
3632 /* FIXME? Examine results here? */
3637 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
3638 iocp = ioc->alt_ioc;
3640 /* If the DownloadBoot operation fails, the
3641 * IOC will be left unusable. This is a fatal error
3642 * case. _diag_reset will return < 0
3644 for (count = 0; count < 30; count ++) {
3645 diag0val = CHIPREG_READ32(&iocp->chip->Diagnostic);
3646 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3650 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n",
3651 iocp->name, diag0val, count));
3653 if (sleepFlag == CAN_SLEEP) {
3659 if ((count = mpt_downloadboot(ioc,
3660 (MpiFwHeader_t *)iocp->cached_fw, sleepFlag)) < 0) {
3661 printk(KERN_WARNING MYNAM
3662 ": firmware downloadboot failure (%d)!\n", count);
3666 /* Wait for FW to reload and for board
3667 * to go to the READY state.
3668 * Maximum wait is 60 seconds.
3669 * If fail, no error will check again
3670 * with calling program.
3672 for (count = 0; count < 60; count ++) {
3673 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3674 doorbell &= MPI_IOC_STATE_MASK;
3676 if (doorbell == MPI_IOC_STATE_READY) {
3681 if (sleepFlag == CAN_SLEEP) {
3690 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3691 if (ioc->debug_level & MPT_DEBUG) {
3693 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3694 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3695 ioc->name, diag0val, diag1val));
3698 /* Clear RESET_HISTORY bit! Place board in the
3699 * diagnostic mode to update the diag register.
3701 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3703 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3704 /* Write magic sequence to WriteSequence register
3705 * Loop until in diagnostic mode
3707 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3708 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3709 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3710 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3711 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3712 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3715 if (sleepFlag == CAN_SLEEP) {
3723 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3724 ioc->name, diag0val);
3727 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3729 diag0val &= ~MPI_DIAG_RESET_HISTORY;
3730 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3731 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3732 if (diag0val & MPI_DIAG_RESET_HISTORY) {
3733 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3737 /* Disable Diagnostic Mode
3739 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3741 /* Check FW reload status flags.
3743 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3744 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3745 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3746 ioc->name, diag0val);
3750 if (ioc->debug_level & MPT_DEBUG) {
3752 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3753 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3754 ioc->name, diag0val, diag1val));
3758 * Reset flag that says we've enabled event notification
3760 ioc->facts.EventState = 0;
3763 ioc->alt_ioc->facts.EventState = 0;
3765 return hard_reset_done;
3768 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3770 * SendIocReset - Send IOCReset request to MPT adapter.
3771 * @ioc: Pointer to MPT_ADAPTER structure
3772 * @reset_type: reset type, expected values are
3773 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3774 * @sleepFlag: Specifies whether the process can sleep
3776 * Send IOCReset request to the MPT adapter.
3778 * Returns 0 for success, non-zero for failure.
3781 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3787 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOC reset(0x%02x)!\n",
3788 ioc->name, reset_type));
3789 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3790 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3793 /* FW ACK'd request, wait for READY state
3796 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
3798 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3802 if (sleepFlag != CAN_SLEEP)
3805 printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
3806 ioc->name, (int)((count+5)/HZ));
3810 if (sleepFlag == CAN_SLEEP) {
3813 mdelay (1); /* 1 msec delay */
3818 * Cleanup all event stuff for this IOC; re-issue EventNotification
3819 * request if needed.
3821 if (ioc->facts.Function)
3822 ioc->facts.EventState = 0;
3827 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3829 * initChainBuffers - Allocate memory for and initialize chain buffers
3830 * @ioc: Pointer to MPT_ADAPTER structure
3832 * Allocates memory for and initializes chain buffers,
3833 * chain buffer control arrays and spinlock.
3836 initChainBuffers(MPT_ADAPTER *ioc)
3839 int sz, ii, num_chain;
3840 int scale, num_sge, numSGE;
3842 /* ReqToChain size must equal the req_depth
3845 if (ioc->ReqToChain == NULL) {
3846 sz = ioc->req_depth * sizeof(int);
3847 mem = kmalloc(sz, GFP_ATOMIC);
3851 ioc->ReqToChain = (int *) mem;
3852 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReqToChain alloc @ %p, sz=%d bytes\n",
3853 ioc->name, mem, sz));
3854 mem = kmalloc(sz, GFP_ATOMIC);
3858 ioc->RequestNB = (int *) mem;
3859 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestNB alloc @ %p, sz=%d bytes\n",
3860 ioc->name, mem, sz));
3862 for (ii = 0; ii < ioc->req_depth; ii++) {
3863 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
3866 /* ChainToChain size must equal the total number
3867 * of chain buffers to be allocated.
3870 * Calculate the number of chain buffers needed(plus 1) per I/O
3871 * then multiply the maximum number of simultaneous cmds
3873 * num_sge = num sge in request frame + last chain buffer
3874 * scale = num sge per chain buffer if no chain element
3876 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3877 if (sizeof(dma_addr_t) == sizeof(u64))
3878 num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3880 num_sge = 1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3882 if (sizeof(dma_addr_t) == sizeof(u64)) {
3883 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3884 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3886 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3887 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3889 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n",
3890 ioc->name, num_sge, numSGE));
3892 if ( numSGE > MPT_SCSI_SG_DEPTH )
3893 numSGE = MPT_SCSI_SG_DEPTH;
3896 while (numSGE - num_sge > 0) {
3898 num_sge += (scale - 1);
3902 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Now numSGE=%d num_sge=%d num_chain=%d\n",
3903 ioc->name, numSGE, num_sge, num_chain));
3905 if (ioc->bus_type == SPI)
3906 num_chain *= MPT_SCSI_CAN_QUEUE;
3908 num_chain *= MPT_FC_CAN_QUEUE;
3910 ioc->num_chain = num_chain;
3912 sz = num_chain * sizeof(int);
3913 if (ioc->ChainToChain == NULL) {
3914 mem = kmalloc(sz, GFP_ATOMIC);
3918 ioc->ChainToChain = (int *) mem;
3919 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainToChain alloc @ %p, sz=%d bytes\n",
3920 ioc->name, mem, sz));
3922 mem = (u8 *) ioc->ChainToChain;
3924 memset(mem, 0xFF, sz);
3928 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3930 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
3931 * @ioc: Pointer to MPT_ADAPTER structure
3933 * This routine allocates memory for the MPT reply and request frame
3934 * pools (if necessary), and primes the IOC reply FIFO with
3937 * Returns 0 for success, non-zero for failure.
3940 PrimeIocFifos(MPT_ADAPTER *ioc)
3943 unsigned long flags;
3944 dma_addr_t alloc_dma;
3946 int i, reply_sz, sz, total_size, num_chain;
3948 /* Prime reply FIFO... */
3950 if (ioc->reply_frames == NULL) {
3951 if ( (num_chain = initChainBuffers(ioc)) < 0)
3954 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
3955 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
3956 ioc->name, ioc->reply_sz, ioc->reply_depth));
3957 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d[%x] bytes\n",
3958 ioc->name, reply_sz, reply_sz));
3960 sz = (ioc->req_sz * ioc->req_depth);
3961 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d bytes, RequestDepth=%d\n",
3962 ioc->name, ioc->req_sz, ioc->req_depth));
3963 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d[%x] bytes\n",
3964 ioc->name, sz, sz));
3967 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
3968 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d bytes, ChainDepth=%d\n",
3969 ioc->name, ioc->req_sz, num_chain));
3970 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
3971 ioc->name, sz, sz, num_chain));
3974 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
3976 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
3981 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Total alloc @ %p[%p], sz=%d[%x] bytes\n",
3982 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
3984 memset(mem, 0, total_size);
3985 ioc->alloc_total += total_size;
3987 ioc->alloc_dma = alloc_dma;
3988 ioc->alloc_sz = total_size;
3989 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
3990 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3992 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
3993 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3995 alloc_dma += reply_sz;
3998 /* Request FIFO - WE manage this! */
4000 ioc->req_frames = (MPT_FRAME_HDR *) mem;
4001 ioc->req_frames_dma = alloc_dma;
4003 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffers @ %p[%p]\n",
4004 ioc->name, mem, (void *)(ulong)alloc_dma));
4006 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4008 #if defined(CONFIG_MTRR) && 0
4010 * Enable Write Combining MTRR for IOC's memory region.
4011 * (at least as much as we can; "size and base must be
4012 * multiples of 4 kiB"
4014 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
4016 MTRR_TYPE_WRCOMB, 1);
4017 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MTRR region registered (base:size=%08x:%x)\n",
4018 ioc->name, ioc->req_frames_dma, sz));
4021 for (i = 0; i < ioc->req_depth; i++) {
4022 alloc_dma += ioc->req_sz;
4026 ioc->ChainBuffer = mem;
4027 ioc->ChainBufferDMA = alloc_dma;
4029 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffers @ %p(%p)\n",
4030 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
4032 /* Initialize the free chain Q.
4035 INIT_LIST_HEAD(&ioc->FreeChainQ);
4037 /* Post the chain buffers to the FreeChainQ.
4039 mem = (u8 *)ioc->ChainBuffer;
4040 for (i=0; i < num_chain; i++) {
4041 mf = (MPT_FRAME_HDR *) mem;
4042 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
4046 /* Initialize Request frames linked list
4048 alloc_dma = ioc->req_frames_dma;
4049 mem = (u8 *) ioc->req_frames;
4051 spin_lock_irqsave(&ioc->FreeQlock, flags);
4052 INIT_LIST_HEAD(&ioc->FreeQ);
4053 for (i = 0; i < ioc->req_depth; i++) {
4054 mf = (MPT_FRAME_HDR *) mem;
4056 /* Queue REQUESTs *internally*! */
4057 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
4061 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4063 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4064 ioc->sense_buf_pool =
4065 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
4066 if (ioc->sense_buf_pool == NULL) {
4067 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
4072 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
4073 ioc->alloc_total += sz;
4074 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SenseBuffers @ %p[%p]\n",
4075 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
4079 /* Post Reply frames to FIFO
4081 alloc_dma = ioc->alloc_dma;
4082 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4083 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4085 for (i = 0; i < ioc->reply_depth; i++) {
4086 /* Write each address to the IOC! */
4087 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
4088 alloc_dma += ioc->reply_sz;
4094 if (ioc->alloc != NULL) {
4096 pci_free_consistent(ioc->pcidev,
4098 ioc->alloc, ioc->alloc_dma);
4099 ioc->reply_frames = NULL;
4100 ioc->req_frames = NULL;
4101 ioc->alloc_total -= sz;
4103 if (ioc->sense_buf_pool != NULL) {
4104 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4105 pci_free_consistent(ioc->pcidev,
4107 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
4108 ioc->sense_buf_pool = NULL;
4113 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4115 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4116 * from IOC via doorbell handshake method.
4117 * @ioc: Pointer to MPT_ADAPTER structure
4118 * @reqBytes: Size of the request in bytes
4119 * @req: Pointer to MPT request frame
4120 * @replyBytes: Expected size of the reply in bytes
4121 * @u16reply: Pointer to area where reply should be written
4122 * @maxwait: Max wait time for a reply (in seconds)
4123 * @sleepFlag: Specifies whether the process can sleep
4125 * NOTES: It is the callers responsibility to byte-swap fields in the
4126 * request which are greater than 1 byte in size. It is also the
4127 * callers responsibility to byte-swap response fields which are
4128 * greater than 1 byte in size.
4130 * Returns 0 for success, non-zero for failure.
4133 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
4134 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
4136 MPIDefaultReply_t *mptReply;
4141 * Get ready to cache a handshake reply
4143 ioc->hs_reply_idx = 0;
4144 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4145 mptReply->MsgLength = 0;
4148 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4149 * then tell IOC that we want to handshake a request of N words.
4150 * (WRITE u32val to Doorbell reg).
4152 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4153 CHIPREG_WRITE32(&ioc->chip->Doorbell,
4154 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
4155 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
4158 * Wait for IOC's doorbell handshake int
4160 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4163 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4164 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4166 /* Read doorbell and check for active bit */
4167 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
4171 * Clear doorbell int (WRITE 0 to IntStatus reg),
4172 * then wait for IOC to ACKnowledge that it's ready for
4173 * our handshake request.
4175 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4176 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4181 u8 *req_as_bytes = (u8 *) req;
4184 * Stuff request words via doorbell handshake,
4185 * with ACK from IOC for each.
4187 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
4188 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
4189 (req_as_bytes[(ii*4) + 1] << 8) |
4190 (req_as_bytes[(ii*4) + 2] << 16) |
4191 (req_as_bytes[(ii*4) + 3] << 24));
4193 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
4194 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4198 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req));
4199 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req)
4201 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n",
4202 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
4205 * Wait for completion of doorbell handshake reply from the IOC
4207 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
4210 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake reply count=%d%s\n",
4211 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
4214 * Copy out the cached reply...
4216 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
4217 u16reply[ii] = ioc->hs_reply[ii];
4225 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4227 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4228 * @ioc: Pointer to MPT_ADAPTER structure
4229 * @howlong: How long to wait (in seconds)
4230 * @sleepFlag: Specifies whether the process can sleep
4232 * This routine waits (up to ~2 seconds max) for IOC doorbell
4233 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4234 * bit in its IntStatus register being clear.
4236 * Returns a negative value on failure, else wait loop count.
4239 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4245 cntdn = 1000 * howlong;
4247 if (sleepFlag == CAN_SLEEP) {
4250 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4251 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4258 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4259 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4266 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell ACK (count=%d)\n",
4271 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4272 ioc->name, count, intstat);
4276 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4278 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4279 * @ioc: Pointer to MPT_ADAPTER structure
4280 * @howlong: How long to wait (in seconds)
4281 * @sleepFlag: Specifies whether the process can sleep
4283 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4284 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4286 * Returns a negative value on failure, else wait loop count.
4289 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4295 cntdn = 1000 * howlong;
4296 if (sleepFlag == CAN_SLEEP) {
4298 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4299 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4306 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4307 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4315 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4316 ioc->name, count, howlong));
4320 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4321 ioc->name, count, intstat);
4325 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4327 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4328 * @ioc: Pointer to MPT_ADAPTER structure
4329 * @howlong: How long to wait (in seconds)
4330 * @sleepFlag: Specifies whether the process can sleep
4332 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4333 * Reply is cached to IOC private area large enough to hold a maximum
4334 * of 128 bytes of reply data.
4336 * Returns a negative value on failure, else size of reply in WORDS.
4339 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4344 u16 *hs_reply = ioc->hs_reply;
4345 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4348 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4351 * Get first two u16's so we can look at IOC's intended reply MsgLength
4354 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4357 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4358 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4359 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4362 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4363 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4367 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4368 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4369 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4372 * If no error (and IOC said MsgLength is > 0), piece together
4373 * reply 16 bits at a time.
4375 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4376 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4378 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4379 /* don't overflow our IOC hs_reply[] buffer! */
4380 if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
4381 hs_reply[u16cnt] = hword;
4382 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4385 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4387 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4390 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4395 else if (u16cnt != (2 * mptReply->MsgLength)) {
4398 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4403 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name));
4404 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply)
4406 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4407 ioc->name, t, u16cnt/2));
4411 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4413 * GetLanConfigPages - Fetch LANConfig pages.
4414 * @ioc: Pointer to MPT_ADAPTER structure
4416 * Return: 0 for success
4417 * -ENOMEM if no memory available
4418 * -EPERM if not allowed due to ISR context
4419 * -EAGAIN if no msg frames currently available
4420 * -EFAULT for non-successful reply or no reply (timeout)
4423 GetLanConfigPages(MPT_ADAPTER *ioc)
4425 ConfigPageHeader_t hdr;
4427 LANPage0_t *ppage0_alloc;
4428 dma_addr_t page0_dma;
4429 LANPage1_t *ppage1_alloc;
4430 dma_addr_t page1_dma;
4435 /* Get LAN Page 0 header */
4436 hdr.PageVersion = 0;
4439 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4440 cfg.cfghdr.hdr = &hdr;
4442 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4447 if ((rc = mpt_config(ioc, &cfg)) != 0)
4450 if (hdr.PageLength > 0) {
4451 data_sz = hdr.PageLength * 4;
4452 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4455 memset((u8 *)ppage0_alloc, 0, data_sz);
4456 cfg.physAddr = page0_dma;
4457 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4459 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4461 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4462 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4466 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4469 * Normalize endianness of structure data,
4470 * by byte-swapping all > 1 byte fields!
4479 /* Get LAN Page 1 header */
4480 hdr.PageVersion = 0;
4483 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4484 cfg.cfghdr.hdr = &hdr;
4486 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4490 if ((rc = mpt_config(ioc, &cfg)) != 0)
4493 if (hdr.PageLength == 0)
4496 data_sz = hdr.PageLength * 4;
4498 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4500 memset((u8 *)ppage1_alloc, 0, data_sz);
4501 cfg.physAddr = page1_dma;
4502 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4504 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4506 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4507 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4510 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4513 * Normalize endianness of structure data,
4514 * by byte-swapping all > 1 byte fields!
4522 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4524 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
4525 * @ioc: Pointer to MPT_ADAPTER structure
4526 * @persist_opcode: see below
4528 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4529 * devices not currently present.
4530 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4532 * NOTE: Don't use not this function during interrupt time.
4534 * Returns 0 for success, non-zero error
4537 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4539 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4541 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
4542 SasIoUnitControlReply_t *sasIoUnitCntrReply;
4543 MPT_FRAME_HDR *mf = NULL;
4544 MPIHeader_t *mpi_hdr;
4547 /* insure garbage is not sent to fw */
4548 switch(persist_opcode) {
4550 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
4551 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
4559 printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode);
4561 /* Get a MF for this command.
4563 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4564 printk("%s: no msg frames!\n",__FUNCTION__);
4568 mpi_hdr = (MPIHeader_t *) mf;
4569 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
4570 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
4571 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
4572 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
4573 sasIoUnitCntrReq->Operation = persist_opcode;
4575 init_timer(&ioc->persist_timer);
4576 ioc->persist_timer.data = (unsigned long) ioc;
4577 ioc->persist_timer.function = mpt_timer_expired;
4578 ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
4579 ioc->persist_wait_done=0;
4580 add_timer(&ioc->persist_timer);
4581 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4582 wait_event(mpt_waitq, ioc->persist_wait_done);
4584 sasIoUnitCntrReply =
4585 (SasIoUnitControlReply_t *)ioc->persist_reply_frame;
4586 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
4587 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4589 sasIoUnitCntrReply->IOCStatus,
4590 sasIoUnitCntrReply->IOCLogInfo);
4594 printk("%s: success\n",__FUNCTION__);
4598 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4601 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
4602 MpiEventDataRaid_t * pRaidEventData)
4611 volume = pRaidEventData->VolumeID;
4612 reason = pRaidEventData->ReasonCode;
4613 disk = pRaidEventData->PhysDiskNum;
4614 status = le32_to_cpu(pRaidEventData->SettingsStatus);
4615 flags = (status >> 0) & 0xff;
4616 state = (status >> 8) & 0xff;
4618 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
4622 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
4623 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
4624 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
4625 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
4626 ioc->name, disk, volume);
4628 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
4633 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4634 printk(MYIOC_s_INFO_FMT " volume has been created\n",
4638 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4640 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
4644 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
4645 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
4649 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4650 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
4652 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
4654 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
4656 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
4659 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
4661 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
4662 ? ", quiesced" : "",
4663 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
4664 ? ", resync in progress" : "" );
4667 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
4668 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
4672 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4673 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
4677 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4678 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
4682 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
4683 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
4687 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4688 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
4690 state == MPI_PHYSDISK0_STATUS_ONLINE
4692 : state == MPI_PHYSDISK0_STATUS_MISSING
4694 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
4696 : state == MPI_PHYSDISK0_STATUS_FAILED
4698 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
4700 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
4701 ? "offline requested"
4702 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
4703 ? "failed requested"
4704 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
4707 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
4708 ? ", out of sync" : "",
4709 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
4710 ? ", quiesced" : "" );
4713 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
4714 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
4718 case MPI_EVENT_RAID_RC_SMART_DATA:
4719 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
4720 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
4723 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
4724 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
4730 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4732 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4733 * @ioc: Pointer to MPT_ADAPTER structure
4735 * Returns: 0 for success
4736 * -ENOMEM if no memory available
4737 * -EPERM if not allowed due to ISR context
4738 * -EAGAIN if no msg frames currently available
4739 * -EFAULT for non-successful reply or no reply (timeout)
4742 GetIoUnitPage2(MPT_ADAPTER *ioc)
4744 ConfigPageHeader_t hdr;
4746 IOUnitPage2_t *ppage_alloc;
4747 dma_addr_t page_dma;
4751 /* Get the page header */
4752 hdr.PageVersion = 0;
4755 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4756 cfg.cfghdr.hdr = &hdr;
4758 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4763 if ((rc = mpt_config(ioc, &cfg)) != 0)
4766 if (hdr.PageLength == 0)
4769 /* Read the config page */
4770 data_sz = hdr.PageLength * 4;
4772 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4774 memset((u8 *)ppage_alloc, 0, data_sz);
4775 cfg.physAddr = page_dma;
4776 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4778 /* If Good, save data */
4779 if ((rc = mpt_config(ioc, &cfg)) == 0)
4780 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4782 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4788 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4790 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4791 * @ioc: Pointer to a Adapter Strucutre
4792 * @portnum: IOC port number
4794 * Return: -EFAULT if read of config page header fails
4796 * If read of SCSI Port Page 0 fails,
4797 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4798 * Adapter settings: async, narrow
4800 * If read of SCSI Port Page 2 fails,
4801 * Adapter settings valid
4802 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4807 * CHECK - what type of locking mechanisms should be used????
4810 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4815 ConfigPageHeader_t header;
4821 if (!ioc->spi_data.nvram) {
4824 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4825 mem = kmalloc(sz, GFP_ATOMIC);
4829 ioc->spi_data.nvram = (int *) mem;
4831 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4832 ioc->name, ioc->spi_data.nvram, sz));
4835 /* Invalidate NVRAM information
4837 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4838 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4841 /* Read SPP0 header, allocate memory, then read page.
4843 header.PageVersion = 0;
4844 header.PageLength = 0;
4845 header.PageNumber = 0;
4846 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4847 cfg.cfghdr.hdr = &header;
4849 cfg.pageAddr = portnum;
4850 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4852 cfg.timeout = 0; /* use default */
4853 if (mpt_config(ioc, &cfg) != 0)
4856 if (header.PageLength > 0) {
4857 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4859 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4860 cfg.physAddr = buf_dma;
4861 if (mpt_config(ioc, &cfg) != 0) {
4862 ioc->spi_data.maxBusWidth = MPT_NARROW;
4863 ioc->spi_data.maxSyncOffset = 0;
4864 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4865 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4867 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4868 "Unable to read PortPage0 minSyncFactor=%x\n",
4869 ioc->name, ioc->spi_data.minSyncFactor));
4871 /* Save the Port Page 0 data
4873 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
4874 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4875 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4877 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
4878 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4879 ddvprintk(ioc, printk(KERN_INFO MYNAM
4880 " :%s noQas due to Capabilities=%x\n",
4881 ioc->name, pPP0->Capabilities));
4883 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4884 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4886 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4887 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4888 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4889 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4890 "PortPage0 minSyncFactor=%x\n",
4891 ioc->name, ioc->spi_data.minSyncFactor));
4893 ioc->spi_data.maxSyncOffset = 0;
4894 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4897 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4899 /* Update the minSyncFactor based on bus type.
4901 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4902 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
4904 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
4905 ioc->spi_data.minSyncFactor = MPT_ULTRA;
4906 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4907 "HVD or SE detected, minSyncFactor=%x\n",
4908 ioc->name, ioc->spi_data.minSyncFactor));
4913 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4918 /* SCSI Port Page 2 - Read the header then the page.
4920 header.PageVersion = 0;
4921 header.PageLength = 0;
4922 header.PageNumber = 2;
4923 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4924 cfg.cfghdr.hdr = &header;
4926 cfg.pageAddr = portnum;
4927 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4929 if (mpt_config(ioc, &cfg) != 0)
4932 if (header.PageLength > 0) {
4933 /* Allocate memory and read SCSI Port Page 2
4935 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4937 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
4938 cfg.physAddr = buf_dma;
4939 if (mpt_config(ioc, &cfg) != 0) {
4940 /* Nvram data is left with INVALID mark
4943 } else if (ioc->pcidev->vendor == PCI_VENDOR_ID_ATTO) {
4945 /* This is an ATTO adapter, read Page2 accordingly
4947 ATTO_SCSIPortPage2_t *pPP2 = (ATTO_SCSIPortPage2_t *) pbuf;
4948 ATTODeviceInfo_t *pdevice = NULL;
4951 /* Save the Port Page 2 data
4952 * (reformat into a 32bit quantity)
4954 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4955 pdevice = &pPP2->DeviceSettings[ii];
4956 ATTOFlags = le16_to_cpu(pdevice->ATTOFlags);
4959 /* Translate ATTO device flags to LSI format
4961 if (ATTOFlags & ATTOFLAG_DISC)
4962 data |= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE);
4963 if (ATTOFlags & ATTOFLAG_ID_ENB)
4964 data |= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE);
4965 if (ATTOFlags & ATTOFLAG_LUN_ENB)
4966 data |= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE);
4967 if (ATTOFlags & ATTOFLAG_TAGGED)
4968 data |= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE);
4969 if (!(ATTOFlags & ATTOFLAG_WIDE_ENB))
4970 data |= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE);
4972 data = (data << 16) | (pdevice->Period << 8) | 10;
4973 ioc->spi_data.nvram[ii] = data;
4976 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
4977 MpiDeviceInfo_t *pdevice = NULL;
4980 * Save "Set to Avoid SCSI Bus Resets" flag
4982 ioc->spi_data.bus_reset =
4983 (le32_to_cpu(pPP2->PortFlags) &
4984 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
4987 /* Save the Port Page 2 data
4988 * (reformat into a 32bit quantity)
4990 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
4991 ioc->spi_data.PortFlags = data;
4992 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4993 pdevice = &pPP2->DeviceSettings[ii];
4994 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
4995 (pdevice->SyncFactor << 8) | pdevice->Timeout;
4996 ioc->spi_data.nvram[ii] = data;
5000 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5004 /* Update Adapter limits with those from NVRAM
5005 * Comment: Don't need to do this. Target performance
5006 * parameters will never exceed the adapters limits.
5012 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5014 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
5015 * @ioc: Pointer to a Adapter Strucutre
5016 * @portnum: IOC port number
5018 * Return: -EFAULT if read of config page header fails
5022 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
5025 ConfigPageHeader_t header;
5027 /* Read the SCSI Device Page 1 header
5029 header.PageVersion = 0;
5030 header.PageLength = 0;
5031 header.PageNumber = 1;
5032 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5033 cfg.cfghdr.hdr = &header;
5035 cfg.pageAddr = portnum;
5036 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5039 if (mpt_config(ioc, &cfg) != 0)
5042 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
5043 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
5045 header.PageVersion = 0;
5046 header.PageLength = 0;
5047 header.PageNumber = 0;
5048 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5049 if (mpt_config(ioc, &cfg) != 0)
5052 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
5053 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
5055 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 0: version %d length %d\n",
5056 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
5058 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 1: version %d length %d\n",
5059 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
5064 * mpt_inactive_raid_list_free - This clears this link list.
5065 * @ioc : pointer to per adapter structure
5068 mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
5070 struct inactive_raid_component_info *component_info, *pNext;
5072 if (list_empty(&ioc->raid_data.inactive_list))
5075 down(&ioc->raid_data.inactive_list_mutex);
5076 list_for_each_entry_safe(component_info, pNext,
5077 &ioc->raid_data.inactive_list, list) {
5078 list_del(&component_info->list);
5079 kfree(component_info);
5081 up(&ioc->raid_data.inactive_list_mutex);
5085 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5087 * @ioc : pointer to per adapter structure
5088 * @channel : volume channel
5089 * @id : volume target id
5092 mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
5095 ConfigPageHeader_t hdr;
5096 dma_addr_t dma_handle;
5097 pRaidVolumePage0_t buffer = NULL;
5099 RaidPhysDiskPage0_t phys_disk;
5100 struct inactive_raid_component_info *component_info;
5101 int handle_inactive_volumes;
5103 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5104 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5105 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
5106 cfg.pageAddr = (channel << 8) + id;
5107 cfg.cfghdr.hdr = &hdr;
5108 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5110 if (mpt_config(ioc, &cfg) != 0)
5113 if (!hdr.PageLength)
5116 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5122 cfg.physAddr = dma_handle;
5123 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5125 if (mpt_config(ioc, &cfg) != 0)
5128 if (!buffer->NumPhysDisks)
5131 handle_inactive_volumes =
5132 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
5133 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
5134 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
5135 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
5137 if (!handle_inactive_volumes)
5140 down(&ioc->raid_data.inactive_list_mutex);
5141 for (i = 0; i < buffer->NumPhysDisks; i++) {
5142 if(mpt_raid_phys_disk_pg0(ioc,
5143 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
5146 if ((component_info = kmalloc(sizeof (*component_info),
5147 GFP_KERNEL)) == NULL)
5150 component_info->volumeID = id;
5151 component_info->volumeBus = channel;
5152 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
5153 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
5154 component_info->d.PhysDiskID = phys_disk.PhysDiskID;
5155 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
5157 list_add_tail(&component_info->list,
5158 &ioc->raid_data.inactive_list);
5160 up(&ioc->raid_data.inactive_list_mutex);
5164 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5169 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5170 * @ioc: Pointer to a Adapter Structure
5171 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5172 * @phys_disk: requested payload data returned
5176 * -EFAULT if read of config page header fails or data pointer not NULL
5177 * -ENOMEM if pci_alloc failed
5180 mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk)
5183 ConfigPageHeader_t hdr;
5184 dma_addr_t dma_handle;
5185 pRaidPhysDiskPage0_t buffer = NULL;
5188 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5189 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5191 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5192 cfg.cfghdr.hdr = &hdr;
5194 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5196 if (mpt_config(ioc, &cfg) != 0) {
5201 if (!hdr.PageLength) {
5206 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5214 cfg.physAddr = dma_handle;
5215 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5216 cfg.pageAddr = phys_disk_num;
5218 if (mpt_config(ioc, &cfg) != 0) {
5224 memcpy(phys_disk, buffer, sizeof(*buffer));
5225 phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
5230 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5237 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5238 * @ioc: Pointer to a Adapter Strucutre
5239 * @portnum: IOC port number
5243 * -EFAULT if read of config page header fails or data pointer not NULL
5244 * -ENOMEM if pci_alloc failed
5247 mpt_findImVolumes(MPT_ADAPTER *ioc)
5251 dma_addr_t ioc2_dma;
5253 ConfigPageHeader_t header;
5258 if (!ioc->ir_firmware)
5261 /* Free the old page
5263 kfree(ioc->raid_data.pIocPg2);
5264 ioc->raid_data.pIocPg2 = NULL;
5265 mpt_inactive_raid_list_free(ioc);
5267 /* Read IOCP2 header then the page.
5269 header.PageVersion = 0;
5270 header.PageLength = 0;
5271 header.PageNumber = 2;
5272 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5273 cfg.cfghdr.hdr = &header;
5276 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5279 if (mpt_config(ioc, &cfg) != 0)
5282 if (header.PageLength == 0)
5285 iocpage2sz = header.PageLength * 4;
5286 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
5290 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5291 cfg.physAddr = ioc2_dma;
5292 if (mpt_config(ioc, &cfg) != 0)
5295 mem = kmalloc(iocpage2sz, GFP_KERNEL);
5299 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
5300 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
5302 mpt_read_ioc_pg_3(ioc);
5304 for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
5305 mpt_inactive_raid_volumes(ioc,
5306 pIoc2->RaidVolume[i].VolumeBus,
5307 pIoc2->RaidVolume[i].VolumeID);
5310 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
5316 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
5321 ConfigPageHeader_t header;
5322 dma_addr_t ioc3_dma;
5325 /* Free the old page
5327 kfree(ioc->raid_data.pIocPg3);
5328 ioc->raid_data.pIocPg3 = NULL;
5330 /* There is at least one physical disk.
5331 * Read and save IOC Page 3
5333 header.PageVersion = 0;
5334 header.PageLength = 0;
5335 header.PageNumber = 3;
5336 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5337 cfg.cfghdr.hdr = &header;
5340 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5343 if (mpt_config(ioc, &cfg) != 0)
5346 if (header.PageLength == 0)
5349 /* Read Header good, alloc memory
5351 iocpage3sz = header.PageLength * 4;
5352 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
5356 /* Read the Page and save the data
5357 * into malloc'd memory.
5359 cfg.physAddr = ioc3_dma;
5360 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5361 if (mpt_config(ioc, &cfg) == 0) {
5362 mem = kmalloc(iocpage3sz, GFP_KERNEL);
5364 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
5365 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
5369 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
5375 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
5379 ConfigPageHeader_t header;
5380 dma_addr_t ioc4_dma;
5383 /* Read and save IOC Page 4
5385 header.PageVersion = 0;
5386 header.PageLength = 0;
5387 header.PageNumber = 4;
5388 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5389 cfg.cfghdr.hdr = &header;
5392 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5395 if (mpt_config(ioc, &cfg) != 0)
5398 if (header.PageLength == 0)
5401 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
5402 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
5403 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
5406 ioc->alloc_total += iocpage4sz;
5408 ioc4_dma = ioc->spi_data.IocPg4_dma;
5409 iocpage4sz = ioc->spi_data.IocPg4Sz;
5412 /* Read the Page into dma memory.
5414 cfg.physAddr = ioc4_dma;
5415 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5416 if (mpt_config(ioc, &cfg) == 0) {
5417 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
5418 ioc->spi_data.IocPg4_dma = ioc4_dma;
5419 ioc->spi_data.IocPg4Sz = iocpage4sz;
5421 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
5422 ioc->spi_data.pIocPg4 = NULL;
5423 ioc->alloc_total -= iocpage4sz;
5428 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
5432 ConfigPageHeader_t header;
5433 dma_addr_t ioc1_dma;
5437 /* Check the Coalescing Timeout in IOC Page 1
5439 header.PageVersion = 0;
5440 header.PageLength = 0;
5441 header.PageNumber = 1;
5442 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5443 cfg.cfghdr.hdr = &header;
5446 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5449 if (mpt_config(ioc, &cfg) != 0)
5452 if (header.PageLength == 0)
5455 /* Read Header good, alloc memory
5457 iocpage1sz = header.PageLength * 4;
5458 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
5462 /* Read the Page and check coalescing timeout
5464 cfg.physAddr = ioc1_dma;
5465 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5466 if (mpt_config(ioc, &cfg) == 0) {
5468 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
5469 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
5470 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
5472 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Coalescing Enabled Timeout = %d\n",
5475 if (tmp > MPT_COALESCING_TIMEOUT) {
5476 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
5478 /* Write NVRAM and current
5481 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5482 if (mpt_config(ioc, &cfg) == 0) {
5483 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Reset Current Coalescing Timeout to = %d\n",
5484 ioc->name, MPT_COALESCING_TIMEOUT));
5486 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
5487 if (mpt_config(ioc, &cfg) == 0) {
5488 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5489 "Reset NVRAM Coalescing Timeout to = %d\n",
5490 ioc->name, MPT_COALESCING_TIMEOUT));
5492 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5493 "Reset NVRAM Coalescing Timeout Failed\n",
5498 dprintk(ioc, printk(MYIOC_s_WARN_FMT
5499 "Reset of Current Coalescing Timeout Failed!\n",
5505 dprintk(ioc, printk(MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
5509 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
5515 mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
5518 ConfigPageHeader_t hdr;
5520 ManufacturingPage0_t *pbuf = NULL;
5522 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5523 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5525 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
5526 cfg.cfghdr.hdr = &hdr;
5528 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5531 if (mpt_config(ioc, &cfg) != 0)
5534 if (!cfg.cfghdr.hdr->PageLength)
5537 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5538 pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
5542 cfg.physAddr = buf_dma;
5544 if (mpt_config(ioc, &cfg) != 0)
5547 memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name));
5548 memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
5549 memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
5554 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
5557 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5559 * SendEventNotification - Send EventNotification (on or off) request to adapter
5560 * @ioc: Pointer to MPT_ADAPTER structure
5561 * @EvSwitch: Event switch flags
5564 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
5566 EventNotification_t *evnp;
5568 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
5570 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
5574 memset(evnp, 0, sizeof(*evnp));
5576 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
5578 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
5579 evnp->ChainOffset = 0;
5581 evnp->Switch = EvSwitch;
5583 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
5588 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5590 * SendEventAck - Send EventAck request to MPT adapter.
5591 * @ioc: Pointer to MPT_ADAPTER structure
5592 * @evnp: Pointer to original EventNotification request
5595 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
5599 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5600 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
5601 ioc->name,__FUNCTION__));
5605 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventAck\n", ioc->name));
5607 pAck->Function = MPI_FUNCTION_EVENT_ACK;
5608 pAck->ChainOffset = 0;
5609 pAck->Reserved[0] = pAck->Reserved[1] = 0;
5611 pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
5612 pAck->Event = evnp->Event;
5613 pAck->EventContext = evnp->EventContext;
5615 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
5620 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5622 * mpt_config - Generic function to issue config message
5623 * @ioc: Pointer to an adapter structure
5624 * @pCfg: Pointer to a configuration structure. Struct contains
5625 * action, page address, direction, physical address
5626 * and pointer to a configuration page header
5627 * Page header is updated.
5629 * Returns 0 for success
5630 * -EPERM if not allowed due to ISR context
5631 * -EAGAIN if no msg frames currently available
5632 * -EFAULT for non-successful reply or no reply (timeout)
5635 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5638 ConfigExtendedPageHeader_t *pExtHdr = NULL;
5640 unsigned long flags;
5645 /* Prevent calling wait_event() (below), if caller happens
5646 * to be in ISR context, because that is fatal!
5648 in_isr = in_interrupt();
5650 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
5655 /* Get and Populate a free Frame
5657 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5658 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
5662 pReq = (Config_t *)mf;
5663 pReq->Action = pCfg->action;
5665 pReq->ChainOffset = 0;
5666 pReq->Function = MPI_FUNCTION_CONFIG;
5668 /* Assume page type is not extended and clear "reserved" fields. */
5669 pReq->ExtPageLength = 0;
5670 pReq->ExtPageType = 0;
5673 for (ii=0; ii < 8; ii++)
5674 pReq->Reserved2[ii] = 0;
5676 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
5677 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
5678 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
5679 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
5681 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5682 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
5683 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
5684 pReq->ExtPageType = pExtHdr->ExtPageType;
5685 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
5687 /* Page Length must be treated as a reserved field for the extended header. */
5688 pReq->Header.PageLength = 0;
5691 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
5693 /* Add a SGE to the config request.
5696 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
5698 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
5700 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5701 flagsLength |= pExtHdr->ExtPageLength * 4;
5703 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n",
5704 ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action));
5707 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
5709 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n",
5710 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
5713 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
5715 /* Append pCfg pointer to end of mf
5717 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5719 /* Initalize the timer
5721 init_timer(&pCfg->timer);
5722 pCfg->timer.data = (unsigned long) ioc;
5723 pCfg->timer.function = mpt_timer_expired;
5724 pCfg->wait_done = 0;
5726 /* Set the timer; ensure 10 second minimum */
5727 if (pCfg->timeout < 10)
5728 pCfg->timer.expires = jiffies + HZ*10;
5730 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5732 /* Add to end of Q, set timer and then issue this command */
5733 spin_lock_irqsave(&ioc->FreeQlock, flags);
5734 list_add_tail(&pCfg->linkage, &ioc->configQ);
5735 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5737 add_timer(&pCfg->timer);
5738 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5739 wait_event(mpt_waitq, pCfg->wait_done);
5741 /* mf has been freed - do not access */
5748 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5750 * mpt_timer_expired - Callback for timer process.
5751 * Used only internal config functionality.
5752 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5755 mpt_timer_expired(unsigned long data)
5757 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
5759 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired! \n", ioc->name));
5761 /* Perform a FW reload */
5762 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
5763 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
5765 /* No more processing.
5766 * Hard reset clean-up will wake up
5767 * process and free all resources.
5769 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired complete!\n", ioc->name));
5774 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5776 * mpt_ioc_reset - Base cleanup for hard reset
5777 * @ioc: Pointer to the adapter structure
5778 * @reset_phase: Indicates pre- or post-reset functionality
5780 * Remark: Frees resources with internally generated commands.
5783 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
5786 unsigned long flags;
5788 dprintk(ioc, printk(KERN_DEBUG MYNAM
5789 ": IOC %s_reset routed to MPT base driver!\n",
5790 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
5791 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
5793 if (reset_phase == MPT_IOC_SETUP_RESET) {
5795 } else if (reset_phase == MPT_IOC_PRE_RESET) {
5796 /* If the internal config Q is not empty -
5797 * delete timer. MF resources will be freed when
5798 * the FIFO's are primed.
5800 spin_lock_irqsave(&ioc->FreeQlock, flags);
5801 list_for_each_entry(pCfg, &ioc->configQ, linkage)
5802 del_timer(&pCfg->timer);
5803 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5808 /* Search the configQ for internal commands.
5809 * Flush the Q, and wake up all suspended threads.
5811 spin_lock_irqsave(&ioc->FreeQlock, flags);
5812 list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
5813 list_del(&pCfg->linkage);
5815 pCfg->status = MPT_CONFIG_ERROR;
5816 pCfg->wait_done = 1;
5817 wake_up(&mpt_waitq);
5819 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5822 return 1; /* currently means nothing really */
5826 #ifdef CONFIG_PROC_FS /* { */
5827 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5829 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5831 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5833 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5835 * Returns 0 for success, non-zero for failure.
5838 procmpt_create(void)
5840 struct proc_dir_entry *ent;
5842 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
5843 if (mpt_proc_root_dir == NULL)
5846 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5848 ent->read_proc = procmpt_summary_read;
5850 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5852 ent->read_proc = procmpt_version_read;
5857 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5859 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5861 * Returns 0 for success, non-zero for failure.
5864 procmpt_destroy(void)
5866 remove_proc_entry("version", mpt_proc_root_dir);
5867 remove_proc_entry("summary", mpt_proc_root_dir);
5868 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
5871 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5873 * procmpt_summary_read - Handle read request of a summary file
5874 * @buf: Pointer to area to write information
5875 * @start: Pointer to start pointer
5876 * @offset: Offset to start writing
5877 * @request: Amount of read data requested
5878 * @eof: Pointer to EOF integer
5881 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
5882 * Returns number of characters written to process performing the read.
5885 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5895 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5899 list_for_each_entry(ioc, &ioc_list, list) {
5902 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5905 if ((out-buf) >= request)
5912 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5915 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5917 * procmpt_version_read - Handle read request from /proc/mpt/version.
5918 * @buf: Pointer to area to write information
5919 * @start: Pointer to start pointer
5920 * @offset: Offset to start writing
5921 * @request: Amount of read data requested
5922 * @eof: Pointer to EOF integer
5925 * Returns number of characters written to process performing the read.
5928 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5931 int scsi, fc, sas, lan, ctl, targ, dmp;
5935 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
5936 len += sprintf(buf+len, " Fusion MPT base driver\n");
5938 scsi = fc = sas = lan = ctl = targ = dmp = 0;
5939 for (cb_idx=MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
5941 if (MptCallbacks[cb_idx]) {
5942 switch (MptDriverClass[cb_idx]) {
5944 if (!scsi++) drvname = "SPI host";
5947 if (!fc++) drvname = "FC host";
5950 if (!sas++) drvname = "SAS host";
5953 if (!lan++) drvname = "LAN";
5956 if (!targ++) drvname = "SCSI target";
5959 if (!ctl++) drvname = "ioctl";
5964 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
5968 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5971 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5973 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
5974 * @buf: Pointer to area to write information
5975 * @start: Pointer to start pointer
5976 * @offset: Offset to start writing
5977 * @request: Amount of read data requested
5978 * @eof: Pointer to EOF integer
5981 * Returns number of characters written to process performing the read.
5984 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5986 MPT_ADAPTER *ioc = data;
5992 mpt_get_fw_exp_ver(expVer, ioc);
5994 len = sprintf(buf, "%s:", ioc->name);
5995 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
5996 len += sprintf(buf+len, " (f/w download boot flag set)");
5997 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
5998 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
6000 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
6001 ioc->facts.ProductID,
6003 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
6004 if (ioc->facts.FWImageSize)
6005 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
6006 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
6007 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
6008 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
6010 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
6011 ioc->facts.CurrentHostMfaHighAddr);
6012 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
6013 ioc->facts.CurrentSenseBufferHighAddr);
6015 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
6016 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
6018 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6019 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
6021 * Rounding UP to nearest 4-kB boundary here...
6023 sz = (ioc->req_sz * ioc->req_depth) + 128;
6024 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
6025 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6026 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
6027 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
6028 4*ioc->facts.RequestFrameSize,
6029 ioc->facts.GlobalCredits);
6031 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
6032 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
6033 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
6034 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6035 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
6036 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
6037 ioc->facts.CurReplyFrameSize,
6038 ioc->facts.ReplyQueueDepth);
6040 len += sprintf(buf+len, " MaxDevices = %d\n",
6041 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
6042 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
6045 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
6046 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
6048 ioc->facts.NumberOfPorts);
6049 if (ioc->bus_type == FC) {
6050 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
6051 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6052 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6053 a[5], a[4], a[3], a[2], a[1], a[0]);
6055 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
6056 ioc->fc_port_page0[p].WWNN.High,
6057 ioc->fc_port_page0[p].WWNN.Low,
6058 ioc->fc_port_page0[p].WWPN.High,
6059 ioc->fc_port_page0[p].WWPN.Low);
6063 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6066 #endif /* CONFIG_PROC_FS } */
6068 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6070 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
6073 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
6074 sprintf(buf, " (Exp %02d%02d)",
6075 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
6076 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
6079 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
6080 strcat(buf, " [MDBG]");
6084 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6086 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6087 * @ioc: Pointer to MPT_ADAPTER structure
6088 * @buffer: Pointer to buffer where IOC summary info should be written
6089 * @size: Pointer to number of bytes we wrote (set by this routine)
6090 * @len: Offset at which to start writing in buffer
6091 * @showlan: Display LAN stuff?
6093 * This routine writes (english readable) ASCII text, which represents
6094 * a summary of IOC information, to a buffer.
6097 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
6102 mpt_get_fw_exp_ver(expVer, ioc);
6105 * Shorter summary of attached ioc's...
6107 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6110 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
6111 ioc->facts.FWVersion.Word,
6113 ioc->facts.NumberOfPorts,
6116 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6117 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6118 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6119 a[5], a[4], a[3], a[2], a[1], a[0]);
6122 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
6125 y += sprintf(buffer+len+y, " (disabled)");
6127 y += sprintf(buffer+len+y, "\n");
6132 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6136 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6138 * mpt_HardResetHandler - Generic reset handler
6139 * @ioc: Pointer to MPT_ADAPTER structure
6140 * @sleepFlag: Indicates if sleep or schedule must be called.
6142 * Issues SCSI Task Management call based on input arg values.
6143 * If TaskMgmt fails, returns associated SCSI request.
6145 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
6146 * or a non-interrupt thread. In the former, must not call schedule().
6148 * Note: A return of -1 is a FATAL error case, as it means a
6149 * FW reload/initialization failed.
6151 * Returns 0 for SUCCESS or -1 if FAILED.
6154 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6157 unsigned long flags;
6159 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name));
6161 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
6162 printk("MF count 0x%x !\n", ioc->mfcnt);
6165 /* Reset the adapter. Prevent more than 1 call to
6166 * mpt_do_ioc_recovery at any instant in time.
6168 spin_lock_irqsave(&ioc->diagLock, flags);
6169 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
6170 spin_unlock_irqrestore(&ioc->diagLock, flags);
6173 ioc->diagPending = 1;
6175 spin_unlock_irqrestore(&ioc->diagLock, flags);
6177 /* FIXME: If do_ioc_recovery fails, repeat....
6180 /* The SCSI driver needs to adjust timeouts on all current
6181 * commands prior to the diagnostic reset being issued.
6182 * Prevents timeouts occurring during a diagnostic reset...very bad.
6183 * For all other protocol drivers, this is a no-op.
6189 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6190 if (MptResetHandlers[cb_idx]) {
6191 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling IOC reset_setup handler #%d\n",
6192 ioc->name, cb_idx));
6193 r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
6195 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling alt-%s setup reset handler #%d\n",
6196 ioc->name, ioc->alt_ioc->name, cb_idx));
6197 r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_SETUP_RESET);
6203 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
6204 printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
6209 ioc->alt_ioc->reload_fw = 0;
6211 spin_lock_irqsave(&ioc->diagLock, flags);
6212 ioc->diagPending = 0;
6214 ioc->alt_ioc->diagPending = 0;
6215 spin_unlock_irqrestore(&ioc->diagLock, flags);
6217 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
6222 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6224 EventDescriptionStr(u8 event, u32 evData0, char *evStr)
6229 case MPI_EVENT_NONE:
6232 case MPI_EVENT_LOG_DATA:
6235 case MPI_EVENT_STATE_CHANGE:
6236 ds = "State Change";
6238 case MPI_EVENT_UNIT_ATTENTION:
6239 ds = "Unit Attention";
6241 case MPI_EVENT_IOC_BUS_RESET:
6242 ds = "IOC Bus Reset";
6244 case MPI_EVENT_EXT_BUS_RESET:
6245 ds = "External Bus Reset";
6247 case MPI_EVENT_RESCAN:
6248 ds = "Bus Rescan Event";
6250 case MPI_EVENT_LINK_STATUS_CHANGE:
6251 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
6252 ds = "Link Status(FAILURE) Change";
6254 ds = "Link Status(ACTIVE) Change";
6256 case MPI_EVENT_LOOP_STATE_CHANGE:
6257 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
6258 ds = "Loop State(LIP) Change";
6259 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
6260 ds = "Loop State(LPE) Change"; /* ??? */
6262 ds = "Loop State(LPB) Change"; /* ??? */
6264 case MPI_EVENT_LOGOUT:
6267 case MPI_EVENT_EVENT_CHANGE:
6273 case MPI_EVENT_INTEGRATED_RAID:
6275 u8 ReasonCode = (u8)(evData0 >> 16);
6276 switch (ReasonCode) {
6277 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
6278 ds = "Integrated Raid: Volume Created";
6280 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
6281 ds = "Integrated Raid: Volume Deleted";
6283 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
6284 ds = "Integrated Raid: Volume Settings Changed";
6286 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
6287 ds = "Integrated Raid: Volume Status Changed";
6289 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
6290 ds = "Integrated Raid: Volume Physdisk Changed";
6292 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
6293 ds = "Integrated Raid: Physdisk Created";
6295 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
6296 ds = "Integrated Raid: Physdisk Deleted";
6298 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
6299 ds = "Integrated Raid: Physdisk Settings Changed";
6301 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
6302 ds = "Integrated Raid: Physdisk Status Changed";
6304 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
6305 ds = "Integrated Raid: Domain Validation Needed";
6307 case MPI_EVENT_RAID_RC_SMART_DATA :
6308 ds = "Integrated Raid; Smart Data";
6310 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
6311 ds = "Integrated Raid: Replace Action Started";
6314 ds = "Integrated Raid";
6319 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
6320 ds = "SCSI Device Status Change";
6322 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
6324 u8 id = (u8)(evData0);
6325 u8 channel = (u8)(evData0 >> 8);
6326 u8 ReasonCode = (u8)(evData0 >> 16);
6327 switch (ReasonCode) {
6328 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
6329 snprintf(evStr, EVENT_DESCR_STR_SZ,
6330 "SAS Device Status Change: Added: "
6331 "id=%d channel=%d", id, channel);
6333 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
6334 snprintf(evStr, EVENT_DESCR_STR_SZ,
6335 "SAS Device Status Change: Deleted: "
6336 "id=%d channel=%d", id, channel);
6338 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
6339 snprintf(evStr, EVENT_DESCR_STR_SZ,
6340 "SAS Device Status Change: SMART Data: "
6341 "id=%d channel=%d", id, channel);
6343 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
6344 snprintf(evStr, EVENT_DESCR_STR_SZ,
6345 "SAS Device Status Change: No Persistancy: "
6346 "id=%d channel=%d", id, channel);
6348 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
6349 snprintf(evStr, EVENT_DESCR_STR_SZ,
6350 "SAS Device Status Change: Unsupported Device "
6351 "Discovered : id=%d channel=%d", id, channel);
6353 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
6354 snprintf(evStr, EVENT_DESCR_STR_SZ,
6355 "SAS Device Status Change: Internal Device "
6356 "Reset : id=%d channel=%d", id, channel);
6358 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
6359 snprintf(evStr, EVENT_DESCR_STR_SZ,
6360 "SAS Device Status Change: Internal Task "
6361 "Abort : id=%d channel=%d", id, channel);
6363 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
6364 snprintf(evStr, EVENT_DESCR_STR_SZ,
6365 "SAS Device Status Change: Internal Abort "
6366 "Task Set : id=%d channel=%d", id, channel);
6368 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
6369 snprintf(evStr, EVENT_DESCR_STR_SZ,
6370 "SAS Device Status Change: Internal Clear "
6371 "Task Set : id=%d channel=%d", id, channel);
6373 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
6374 snprintf(evStr, EVENT_DESCR_STR_SZ,
6375 "SAS Device Status Change: Internal Query "
6376 "Task : id=%d channel=%d", id, channel);
6379 snprintf(evStr, EVENT_DESCR_STR_SZ,
6380 "SAS Device Status Change: Unknown: "
6381 "id=%d channel=%d", id, channel);
6386 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
6387 ds = "Bus Timer Expired";
6389 case MPI_EVENT_QUEUE_FULL:
6391 u16 curr_depth = (u16)(evData0 >> 16);
6392 u8 channel = (u8)(evData0 >> 8);
6393 u8 id = (u8)(evData0);
6395 snprintf(evStr, EVENT_DESCR_STR_SZ,
6396 "Queue Full: channel=%d id=%d depth=%d",
6397 channel, id, curr_depth);
6400 case MPI_EVENT_SAS_SES:
6401 ds = "SAS SES Event";
6403 case MPI_EVENT_PERSISTENT_TABLE_FULL:
6404 ds = "Persistent Table Full";
6406 case MPI_EVENT_SAS_PHY_LINK_STATUS:
6408 u8 LinkRates = (u8)(evData0 >> 8);
6409 u8 PhyNumber = (u8)(evData0);
6410 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
6411 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
6412 switch (LinkRates) {
6413 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
6414 snprintf(evStr, EVENT_DESCR_STR_SZ,
6415 "SAS PHY Link Status: Phy=%d:"
6416 " Rate Unknown",PhyNumber);
6418 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
6419 snprintf(evStr, EVENT_DESCR_STR_SZ,
6420 "SAS PHY Link Status: Phy=%d:"
6421 " Phy Disabled",PhyNumber);
6423 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
6424 snprintf(evStr, EVENT_DESCR_STR_SZ,
6425 "SAS PHY Link Status: Phy=%d:"
6426 " Failed Speed Nego",PhyNumber);
6428 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
6429 snprintf(evStr, EVENT_DESCR_STR_SZ,
6430 "SAS PHY Link Status: Phy=%d:"
6431 " Sata OOB Completed",PhyNumber);
6433 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
6434 snprintf(evStr, EVENT_DESCR_STR_SZ,
6435 "SAS PHY Link Status: Phy=%d:"
6436 " Rate 1.5 Gbps",PhyNumber);
6438 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
6439 snprintf(evStr, EVENT_DESCR_STR_SZ,
6440 "SAS PHY Link Status: Phy=%d:"
6441 " Rate 3.0 Gpbs",PhyNumber);
6444 snprintf(evStr, EVENT_DESCR_STR_SZ,
6445 "SAS PHY Link Status: Phy=%d", PhyNumber);
6450 case MPI_EVENT_SAS_DISCOVERY_ERROR:
6451 ds = "SAS Discovery Error";
6453 case MPI_EVENT_IR_RESYNC_UPDATE:
6455 u8 resync_complete = (u8)(evData0 >> 16);
6456 snprintf(evStr, EVENT_DESCR_STR_SZ,
6457 "IR Resync Update: Complete = %d:",resync_complete);
6462 u8 ReasonCode = (u8)(evData0 >> 16);
6463 switch (ReasonCode) {
6464 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
6465 ds = "IR2: LD State Changed";
6467 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
6468 ds = "IR2: PD State Changed";
6470 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
6471 ds = "IR2: Bad Block Table Full";
6473 case MPI_EVENT_IR2_RC_PD_INSERTED:
6474 ds = "IR2: PD Inserted";
6476 case MPI_EVENT_IR2_RC_PD_REMOVED:
6477 ds = "IR2: PD Removed";
6479 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
6480 ds = "IR2: Foreign CFG Detected";
6482 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
6483 ds = "IR2: Rebuild Medium Error";
6491 case MPI_EVENT_SAS_DISCOVERY:
6494 ds = "SAS Discovery: Start";
6496 ds = "SAS Discovery: Stop";
6499 case MPI_EVENT_LOG_ENTRY_ADDED:
6500 ds = "SAS Log Entry Added";
6503 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
6505 u8 phy_num = (u8)(evData0);
6506 u8 port_num = (u8)(evData0 >> 8);
6507 u8 port_width = (u8)(evData0 >> 16);
6508 u8 primative = (u8)(evData0 >> 24);
6509 snprintf(evStr, EVENT_DESCR_STR_SZ,
6510 "SAS Broadcase Primative: phy=%d port=%d "
6511 "width=%d primative=0x%02x",
6512 phy_num, port_num, port_width, primative);
6516 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
6518 u8 reason = (u8)(evData0);
6519 u8 port_num = (u8)(evData0 >> 8);
6520 u16 handle = le16_to_cpu(evData0 >> 16);
6522 snprintf(evStr, EVENT_DESCR_STR_SZ,
6523 "SAS Initiator Device Status Change: reason=0x%02x "
6524 "port=%d handle=0x%04x",
6525 reason, port_num, handle);
6529 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
6531 u8 max_init = (u8)(evData0);
6532 u8 current_init = (u8)(evData0 >> 8);
6534 snprintf(evStr, EVENT_DESCR_STR_SZ,
6535 "SAS Initiator Device Table Overflow: max initiators=%02d "
6536 "current initators=%02d",
6537 max_init, current_init);
6540 case MPI_EVENT_SAS_SMP_ERROR:
6542 u8 status = (u8)(evData0);
6543 u8 port_num = (u8)(evData0 >> 8);
6544 u8 result = (u8)(evData0 >> 16);
6546 if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
6547 snprintf(evStr, EVENT_DESCR_STR_SZ,
6548 "SAS SMP Error: port=%d result=0x%02x",
6550 else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
6551 snprintf(evStr, EVENT_DESCR_STR_SZ,
6552 "SAS SMP Error: port=%d : CRC Error",
6554 else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
6555 snprintf(evStr, EVENT_DESCR_STR_SZ,
6556 "SAS SMP Error: port=%d : Timeout",
6558 else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
6559 snprintf(evStr, EVENT_DESCR_STR_SZ,
6560 "SAS SMP Error: port=%d : No Destination",
6562 else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
6563 snprintf(evStr, EVENT_DESCR_STR_SZ,
6564 "SAS SMP Error: port=%d : Bad Destination",
6567 snprintf(evStr, EVENT_DESCR_STR_SZ,
6568 "SAS SMP Error: port=%d : status=0x%02x",
6574 * MPT base "custom" events may be added here...
6581 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
6584 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6586 * ProcessEventNotification - Route EventNotificationReply to all event handlers
6587 * @ioc: Pointer to MPT_ADAPTER structure
6588 * @pEventReply: Pointer to EventNotification reply frame
6589 * @evHandlers: Pointer to integer, number of event handlers
6591 * Routes a received EventNotificationReply to all currently registered
6593 * Returns sum of event handlers return values.
6596 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
6605 char evStr[EVENT_DESCR_STR_SZ];
6609 * Do platform normalization of values
6611 event = le32_to_cpu(pEventReply->Event) & 0xFF;
6612 // evCtx = le32_to_cpu(pEventReply->EventContext);
6613 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
6615 evData0 = le32_to_cpu(pEventReply->Data[0]);
6618 EventDescriptionStr(event, evData0, evStr);
6619 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event:(%02Xh) : %s\n",
6624 #ifdef CONFIG_FUSION_LOGGING
6625 devtverboseprintk(ioc, printk(KERN_DEBUG MYNAM
6626 ": Event data:\n"));
6627 for (ii = 0; ii < evDataLen; ii++)
6628 devtverboseprintk(ioc, printk(" %08x",
6629 le32_to_cpu(pEventReply->Data[ii])));
6630 devtverboseprintk(ioc, printk(KERN_DEBUG "\n"));
6634 * Do general / base driver event processing
6637 case MPI_EVENT_EVENT_CHANGE: /* 0A */
6639 u8 evState = evData0 & 0xFF;
6641 /* CHECKME! What if evState unexpectedly says OFF (0)? */
6643 /* Update EventState field in cached IocFacts */
6644 if (ioc->facts.Function) {
6645 ioc->facts.EventState = evState;
6649 case MPI_EVENT_INTEGRATED_RAID:
6650 mptbase_raid_process_event_data(ioc,
6651 (MpiEventDataRaid_t *)pEventReply->Data);
6658 * Should this event be logged? Events are written sequentially.
6659 * When buffer is full, start again at the top.
6661 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
6664 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
6666 ioc->events[idx].event = event;
6667 ioc->events[idx].eventContext = ioc->eventContext;
6669 for (ii = 0; ii < 2; ii++) {
6671 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
6673 ioc->events[idx].data[ii] = 0;
6676 ioc->eventContext++;
6681 * Call each currently registered protocol event handler.
6683 for (cb_idx=MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6684 if (MptEvHandlers[cb_idx]) {
6685 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Routing Event to event handler #%d\n",
6686 ioc->name, cb_idx));
6687 r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply);
6691 /* FIXME? Examine results here? */
6694 * If needed, send (a single) EventAck.
6696 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
6697 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6698 "EventAck required\n",ioc->name));
6699 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
6700 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SendEventAck returned %d\n",
6705 *evHandlers = handlers;
6709 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6711 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
6712 * @ioc: Pointer to MPT_ADAPTER structure
6713 * @log_info: U32 LogInfo reply word from the IOC
6715 * Refer to lsi/mpi_log_fc.h.
6718 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
6720 char *desc = "unknown";
6722 switch (log_info & 0xFF000000) {
6723 case MPI_IOCLOGINFO_FC_INIT_BASE:
6724 desc = "FCP Initiator";
6726 case MPI_IOCLOGINFO_FC_TARGET_BASE:
6727 desc = "FCP Target";
6729 case MPI_IOCLOGINFO_FC_LAN_BASE:
6732 case MPI_IOCLOGINFO_FC_MSG_BASE:
6733 desc = "MPI Message Layer";
6735 case MPI_IOCLOGINFO_FC_LINK_BASE:
6738 case MPI_IOCLOGINFO_FC_CTX_BASE:
6739 desc = "Context Manager";
6741 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
6742 desc = "Invalid Field Offset";
6744 case MPI_IOCLOGINFO_FC_STATE_CHANGE:
6745 desc = "State Change Info";
6749 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
6750 ioc->name, log_info, desc, (log_info & 0xFFFFFF));
6753 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6755 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
6756 * @ioc: Pointer to MPT_ADAPTER structure
6757 * @mr: Pointer to MPT reply frame
6758 * @log_info: U32 LogInfo word from the IOC
6760 * Refer to lsi/sp_log.h.
6763 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
6765 u32 info = log_info & 0x00FF0000;
6766 char *desc = "unknown";
6770 desc = "bug! MID not found";
6771 if (ioc->reload_fw == 0)
6776 desc = "Parity Error";
6780 desc = "ASYNC Outbound Overrun";
6784 desc = "SYNC Offset Error";
6792 desc = "Msg In Overflow";
6800 desc = "Outbound DMA Overrun";
6804 desc = "Task Management";
6808 desc = "Device Problem";
6812 desc = "Invalid Phase Change";
6816 desc = "Untagged Table Size";
6821 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
6824 /* strings for sas loginfo */
6825 static char *originator_str[] = {
6830 static char *iop_code_str[] = {
6832 "Invalid SAS Address", /* 01h */
6834 "Invalid Page", /* 03h */
6835 "Diag Message Error", /* 04h */
6836 "Task Terminated", /* 05h */
6837 "Enclosure Management", /* 06h */
6838 "Target Mode" /* 07h */
6840 static char *pl_code_str[] = {
6842 "Open Failure", /* 01h */
6843 "Invalid Scatter Gather List", /* 02h */
6844 "Wrong Relative Offset or Frame Length", /* 03h */
6845 "Frame Transfer Error", /* 04h */
6846 "Transmit Frame Connected Low", /* 05h */
6847 "SATA Non-NCQ RW Error Bit Set", /* 06h */
6848 "SATA Read Log Receive Data Error", /* 07h */
6849 "SATA NCQ Fail All Commands After Error", /* 08h */
6850 "SATA Error in Receive Set Device Bit FIS", /* 09h */
6851 "Receive Frame Invalid Message", /* 0Ah */
6852 "Receive Context Message Valid Error", /* 0Bh */
6853 "Receive Frame Current Frame Error", /* 0Ch */
6854 "SATA Link Down", /* 0Dh */
6855 "Discovery SATA Init W IOS", /* 0Eh */
6856 "Config Invalid Page", /* 0Fh */
6857 "Discovery SATA Init Timeout", /* 10h */
6860 "IO Not Yet Executed", /* 13h */
6861 "IO Executed", /* 14h */
6862 "Persistent Reservation Out Not Affiliation "
6864 "Open Transmit DMA Abort", /* 16h */
6865 "IO Device Missing Delay Retry", /* 17h */
6866 "IO Cancelled Due to Recieve Error", /* 18h */
6874 "Enclosure Management" /* 20h */
6876 static char *ir_code_str[] = {
6877 "Raid Action Error", /* 00h */
6887 static char *raid_sub_code_str[] = {
6889 "Volume Creation Failed: Data Passed too "
6891 "Volume Creation Failed: Duplicate Volumes "
6892 "Attempted", /* 02h */
6893 "Volume Creation Failed: Max Number "
6894 "Supported Volumes Exceeded", /* 03h */
6895 "Volume Creation Failed: DMA Error", /* 04h */
6896 "Volume Creation Failed: Invalid Volume Type", /* 05h */
6897 "Volume Creation Failed: Error Reading "
6898 "MFG Page 4", /* 06h */
6899 "Volume Creation Failed: Creating Internal "
6900 "Structures", /* 07h */
6909 "Activation failed: Already Active Volume", /* 10h */
6910 "Activation failed: Unsupported Volume Type", /* 11h */
6911 "Activation failed: Too Many Active Volumes", /* 12h */
6912 "Activation failed: Volume ID in Use", /* 13h */
6913 "Activation failed: Reported Failure", /* 14h */
6914 "Activation failed: Importing a Volume", /* 15h */
6925 "Phys Disk failed: Too Many Phys Disks", /* 20h */
6926 "Phys Disk failed: Data Passed too Large", /* 21h */
6927 "Phys Disk failed: DMA Error", /* 22h */
6928 "Phys Disk failed: Invalid <channel:id>", /* 23h */
6929 "Phys Disk failed: Creating Phys Disk Config "
6942 "Compatibility Error: IR Disabled", /* 30h */
6943 "Compatibility Error: Inquiry Comand Failed", /* 31h */
6944 "Compatibility Error: Device not Direct Access "
6945 "Device ", /* 32h */
6946 "Compatibility Error: Removable Device Found", /* 33h */
6947 "Compatibility Error: Device SCSI Version not "
6948 "2 or Higher", /* 34h */
6949 "Compatibility Error: SATA Device, 48 BIT LBA "
6950 "not Supported", /* 35h */
6951 "Compatibility Error: Device doesn't have "
6952 "512 Byte Block Sizes", /* 36h */
6953 "Compatibility Error: Volume Type Check Failed", /* 37h */
6954 "Compatibility Error: Volume Type is "
6955 "Unsupported by FW", /* 38h */
6956 "Compatibility Error: Disk Drive too Small for "
6957 "use in Volume", /* 39h */
6958 "Compatibility Error: Phys Disk for Create "
6959 "Volume not Found", /* 3Ah */
6960 "Compatibility Error: Too Many or too Few "
6961 "Disks for Volume Type", /* 3Bh */
6962 "Compatibility Error: Disk stripe Sizes "
6963 "Must be 64KB", /* 3Ch */
6964 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
6967 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6969 * mpt_sas_log_info - Log information returned from SAS IOC.
6970 * @ioc: Pointer to MPT_ADAPTER structure
6971 * @log_info: U32 LogInfo reply word from the IOC
6973 * Refer to lsi/mpi_log_sas.h.
6976 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
6978 union loginfo_type {
6987 union loginfo_type sas_loginfo;
6988 char *originator_desc = NULL;
6989 char *code_desc = NULL;
6990 char *sub_code_desc = NULL;
6992 sas_loginfo.loginfo = log_info;
6993 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
6994 (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
6997 originator_desc = originator_str[sas_loginfo.dw.originator];
6999 switch (sas_loginfo.dw.originator) {
7002 if (sas_loginfo.dw.code <
7003 sizeof(iop_code_str)/sizeof(char*))
7004 code_desc = iop_code_str[sas_loginfo.dw.code];
7007 if (sas_loginfo.dw.code <
7008 sizeof(pl_code_str)/sizeof(char*))
7009 code_desc = pl_code_str[sas_loginfo.dw.code];
7012 if (sas_loginfo.dw.code >=
7013 sizeof(ir_code_str)/sizeof(char*))
7015 code_desc = ir_code_str[sas_loginfo.dw.code];
7016 if (sas_loginfo.dw.subcode >=
7017 sizeof(raid_sub_code_str)/sizeof(char*))
7019 if (sas_loginfo.dw.code == 0)
7021 raid_sub_code_str[sas_loginfo.dw.subcode];
7027 if (sub_code_desc != NULL)
7028 printk(MYIOC_s_INFO_FMT
7029 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7031 ioc->name, log_info, originator_desc, code_desc,
7033 else if (code_desc != NULL)
7034 printk(MYIOC_s_INFO_FMT
7035 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7036 " SubCode(0x%04x)\n",
7037 ioc->name, log_info, originator_desc, code_desc,
7038 sas_loginfo.dw.subcode);
7040 printk(MYIOC_s_INFO_FMT
7041 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
7042 " SubCode(0x%04x)\n",
7043 ioc->name, log_info, originator_desc,
7044 sas_loginfo.dw.code, sas_loginfo.dw.subcode);
7047 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7049 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
7050 * @ioc: Pointer to MPT_ADAPTER structure
7051 * @ioc_status: U32 IOCStatus word from IOC
7052 * @mf: Pointer to MPT request frame
7054 * Refer to lsi/mpi.h.
7057 mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7059 Config_t *pReq = (Config_t *)mf;
7060 char extend_desc[EVENT_DESCR_STR_SZ];
7065 if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
7066 page_type = pReq->ExtPageType;
7068 page_type = pReq->Header.PageType;
7071 * ignore invalid page messages for GET_NEXT_HANDLE
7073 form = le32_to_cpu(pReq->PageAddress);
7074 if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
7075 if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
7076 page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
7077 page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
7078 if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
7079 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
7082 if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
7083 if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
7084 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
7088 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
7089 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
7090 page_type, pReq->Header.PageNumber, pReq->Action, form);
7092 switch (ioc_status) {
7094 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7095 desc = "Config Page Invalid Action";
7098 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7099 desc = "Config Page Invalid Type";
7102 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7103 desc = "Config Page Invalid Page";
7106 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7107 desc = "Config Page Invalid Data";
7110 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7111 desc = "Config Page No Defaults";
7114 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7115 desc = "Config Page Can't Commit";
7122 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s: %s\n",
7123 ioc->name, ioc_status, desc, extend_desc);
7127 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
7128 * @ioc: Pointer to MPT_ADAPTER structure
7129 * @ioc_status: U32 IOCStatus word from IOC
7130 * @mf: Pointer to MPT request frame
7132 * Refer to lsi/mpi.h.
7135 mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7137 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
7142 /****************************************************************************/
7143 /* Common IOCStatus values for all replies */
7144 /****************************************************************************/
7146 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
7147 desc = "Invalid Function";
7150 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
7154 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
7155 desc = "Invalid SGL";
7158 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
7159 desc = "Internal Error";
7162 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
7166 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
7167 desc = "Insufficient Resources";
7170 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
7171 desc = "Invalid Field";
7174 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
7175 desc = "Invalid State";
7178 /****************************************************************************/
7179 /* Config IOCStatus values */
7180 /****************************************************************************/
7182 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7183 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7184 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7185 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7186 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7187 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7188 mpt_iocstatus_info_config(ioc, status, mf);
7191 /****************************************************************************/
7192 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
7194 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
7196 /****************************************************************************/
7198 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
7199 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
7200 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
7201 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
7202 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
7203 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
7204 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
7205 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
7206 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
7207 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
7208 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
7209 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
7210 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
7213 /****************************************************************************/
7214 /* SCSI Target values */
7215 /****************************************************************************/
7217 case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
7218 desc = "Target: Priority IO";
7221 case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
7222 desc = "Target: Invalid Port";
7225 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
7226 desc = "Target Invalid IO Index:";
7229 case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
7230 desc = "Target: Aborted";
7233 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
7234 desc = "Target: No Conn Retryable";
7237 case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
7238 desc = "Target: No Connection";
7241 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
7242 desc = "Target: Transfer Count Mismatch";
7245 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
7246 desc = "Target: STS Data not Sent";
7249 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
7250 desc = "Target: Data Offset Error";
7253 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
7254 desc = "Target: Too Much Write Data";
7257 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
7258 desc = "Target: IU Too Short";
7261 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
7262 desc = "Target: ACK NAK Timeout";
7265 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
7266 desc = "Target: Nak Received";
7269 /****************************************************************************/
7270 /* Fibre Channel Direct Access values */
7271 /****************************************************************************/
7273 case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
7274 desc = "FC: Aborted";
7277 case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
7278 desc = "FC: RX ID Invalid";
7281 case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
7282 desc = "FC: DID Invalid";
7285 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
7286 desc = "FC: Node Logged Out";
7289 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
7290 desc = "FC: Exchange Canceled";
7293 /****************************************************************************/
7295 /****************************************************************************/
7297 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
7298 desc = "LAN: Device not Found";
7301 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
7302 desc = "LAN: Device Failure";
7305 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
7306 desc = "LAN: Transmit Error";
7309 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
7310 desc = "LAN: Transmit Aborted";
7313 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
7314 desc = "LAN: Receive Error";
7317 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
7318 desc = "LAN: Receive Aborted";
7321 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
7322 desc = "LAN: Partial Packet";
7325 case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
7326 desc = "LAN: Canceled";
7329 /****************************************************************************/
7330 /* Serial Attached SCSI values */
7331 /****************************************************************************/
7333 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
7334 desc = "SAS: SMP Request Failed";
7337 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
7338 desc = "SAS: SMP Data Overrun";
7349 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s\n", ioc->name, status, desc);
7352 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7353 EXPORT_SYMBOL(mpt_attach);
7354 EXPORT_SYMBOL(mpt_detach);
7356 EXPORT_SYMBOL(mpt_resume);
7357 EXPORT_SYMBOL(mpt_suspend);
7359 EXPORT_SYMBOL(ioc_list);
7360 EXPORT_SYMBOL(mpt_proc_root_dir);
7361 EXPORT_SYMBOL(mpt_register);
7362 EXPORT_SYMBOL(mpt_deregister);
7363 EXPORT_SYMBOL(mpt_event_register);
7364 EXPORT_SYMBOL(mpt_event_deregister);
7365 EXPORT_SYMBOL(mpt_reset_register);
7366 EXPORT_SYMBOL(mpt_reset_deregister);
7367 EXPORT_SYMBOL(mpt_device_driver_register);
7368 EXPORT_SYMBOL(mpt_device_driver_deregister);
7369 EXPORT_SYMBOL(mpt_get_msg_frame);
7370 EXPORT_SYMBOL(mpt_put_msg_frame);
7371 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri);
7372 EXPORT_SYMBOL(mpt_free_msg_frame);
7373 EXPORT_SYMBOL(mpt_add_sge);
7374 EXPORT_SYMBOL(mpt_send_handshake_request);
7375 EXPORT_SYMBOL(mpt_verify_adapter);
7376 EXPORT_SYMBOL(mpt_GetIocState);
7377 EXPORT_SYMBOL(mpt_print_ioc_summary);
7378 EXPORT_SYMBOL(mpt_HardResetHandler);
7379 EXPORT_SYMBOL(mpt_config);
7380 EXPORT_SYMBOL(mpt_findImVolumes);
7381 EXPORT_SYMBOL(mpt_alloc_fw_memory);
7382 EXPORT_SYMBOL(mpt_free_fw_memory);
7383 EXPORT_SYMBOL(mptbase_sas_persist_operation);
7384 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
7386 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7388 * fusion_init - Fusion MPT base driver initialization routine.
7390 * Returns 0 for success, non-zero for failure.
7397 show_mptmod_ver(my_NAME, my_VERSION);
7398 printk(KERN_INFO COPYRIGHT "\n");
7400 for (cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
7401 MptCallbacks[cb_idx] = NULL;
7402 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
7403 MptEvHandlers[cb_idx] = NULL;
7404 MptResetHandlers[cb_idx] = NULL;
7407 /* Register ourselves (mptbase) in order to facilitate
7408 * EventNotification handling.
7410 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
7412 /* Register for hard reset handling callbacks.
7414 mpt_reset_register(mpt_base_index, mpt_ioc_reset);
7416 #ifdef CONFIG_PROC_FS
7417 (void) procmpt_create();
7422 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7424 * fusion_exit - Perform driver unload cleanup.
7426 * This routine frees all resources associated with each MPT adapter
7427 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
7433 mpt_reset_deregister(mpt_base_index);
7435 #ifdef CONFIG_PROC_FS
7440 module_init(fusion_init);
7441 module_exit(fusion_exit);