2 * linux/drivers/message/fusion/mptbase.c
3 * This is the Fusion MPT base driver which supports multiple
4 * (SCSI + LAN) specialized protocol drivers.
5 * For use with LSI PCI chip/adapter(s)
6 * running LSI Fusion MPT (Message Passing Technology) firmware.
8 * Copyright (c) 1999-2007 LSI Corporation
9 * (mailto:DL-MPTFusionLinux@lsi.com)
12 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; version 2 of the License.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
24 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
25 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
26 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
27 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
28 solely responsible for determining the appropriateness of using and
29 distributing the Program and assumes all risks associated with its
30 exercise of rights under this Agreement, including but not limited to
31 the risks and costs of program errors, damage to or loss of data,
32 programs or equipment, and unavailability or interruption of operations.
34 DISCLAIMER OF LIABILITY
35 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
36 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
38 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
39 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
40 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
41 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
43 You should have received a copy of the GNU General Public License
44 along with this program; if not, write to the Free Software
45 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
47 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
49 #include <linux/kernel.h>
50 #include <linux/module.h>
51 #include <linux/errno.h>
52 #include <linux/init.h>
53 #include <linux/slab.h>
54 #include <linux/types.h>
55 #include <linux/pci.h>
56 #include <linux/kdev_t.h>
57 #include <linux/blkdev.h>
58 #include <linux/delay.h>
59 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
60 #include <linux/dma-mapping.h>
67 #include "lsi/mpi_log_fc.h"
69 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
70 #define my_NAME "Fusion MPT base driver"
71 #define my_VERSION MPT_LINUX_VERSION_COMMON
72 #define MYNAM "mptbase"
74 MODULE_AUTHOR(MODULEAUTHOR);
75 MODULE_DESCRIPTION(my_NAME);
76 MODULE_LICENSE("GPL");
77 MODULE_VERSION(my_VERSION);
82 static int mpt_msi_enable;
83 module_param(mpt_msi_enable, int, 0);
84 MODULE_PARM_DESC(mpt_msi_enable, " MSI Support Enable (default=0)");
86 static int mpt_channel_mapping;
87 module_param(mpt_channel_mapping, int, 0);
88 MODULE_PARM_DESC(mpt_channel_mapping, " Mapping id's to channels (default=0)");
90 static int mpt_debug_level;
91 static int mpt_set_debug_level(const char *val, struct kernel_param *kp);
92 module_param_call(mpt_debug_level, mpt_set_debug_level, param_get_int,
93 &mpt_debug_level, 0600);
94 MODULE_PARM_DESC(mpt_debug_level, " debug level - refer to mptdebug.h - (default=0)");
97 static int mfcounter = 0;
98 #define PRINT_MF_COUNT 20000
101 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
106 struct proc_dir_entry *mpt_proc_root_dir;
108 #define WHOINIT_UNKNOWN 0xAA
110 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
114 /* Adapter link list */
116 /* Callback lookup table */
117 static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
118 /* Protocol driver class lookup table */
119 static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
120 /* Event handler lookup table */
121 static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
122 /* Reset handler lookup table */
123 static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
124 static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
126 static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq);
129 * Driver Callback Index's
131 static u8 mpt_base_index = MPT_MAX_PROTOCOL_DRIVERS;
132 static u8 last_drv_idx;
134 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
138 static irqreturn_t mpt_interrupt(int irq, void *bus_id);
139 static int mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
140 static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
141 u32 *req, int replyBytes, u16 *u16reply, int maxwait,
143 static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
144 static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
145 static void mpt_adapter_disable(MPT_ADAPTER *ioc);
146 static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
148 static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
149 static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
150 static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
151 static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
152 static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
153 static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
154 static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
155 static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
156 static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
157 static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
158 static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
159 static int PrimeIocFifos(MPT_ADAPTER *ioc);
160 static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
161 static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
162 static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
163 static int GetLanConfigPages(MPT_ADAPTER *ioc);
164 static int GetIoUnitPage2(MPT_ADAPTER *ioc);
165 int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
166 static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
167 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
168 static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
169 static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
170 static void mpt_timer_expired(unsigned long data);
171 static void mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc);
172 static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
173 static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
174 static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
175 static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
177 #ifdef CONFIG_PROC_FS
178 static int procmpt_summary_read(char *buf, char **start, off_t offset,
179 int request, int *eof, void *data);
180 static int procmpt_version_read(char *buf, char **start, off_t offset,
181 int request, int *eof, void *data);
182 static int procmpt_iocinfo_read(char *buf, char **start, off_t offset,
183 int request, int *eof, void *data);
185 static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
187 //int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
188 static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers);
189 static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
190 static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
191 static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
192 static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
193 static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
194 static void mpt_inactive_raid_list_free(MPT_ADAPTER *ioc);
196 /* module entry point */
197 static int __init fusion_init (void);
198 static void __exit fusion_exit (void);
200 #define CHIPREG_READ32(addr) readl_relaxed(addr)
201 #define CHIPREG_READ32_dmasync(addr) readl(addr)
202 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
203 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
204 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
207 pci_disable_io_access(struct pci_dev *pdev)
211 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
213 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
217 pci_enable_io_access(struct pci_dev *pdev)
221 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
223 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
226 static int mpt_set_debug_level(const char *val, struct kernel_param *kp)
228 int ret = param_set_int(val, kp);
234 list_for_each_entry(ioc, &ioc_list, list)
235 ioc->debug_level = mpt_debug_level;
240 * mpt_get_cb_idx - obtain cb_idx for registered driver
241 * @dclass: class driver enum
243 * Returns cb_idx, or zero means it wasn't found
246 mpt_get_cb_idx(MPT_DRIVER_CLASS dclass)
250 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--)
251 if (MptDriverClass[cb_idx] == dclass)
257 * Process turbo (context) reply...
260 mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
262 MPT_FRAME_HDR *mf = NULL;
263 MPT_FRAME_HDR *mr = NULL;
267 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got TURBO reply req_idx=%08x\n",
270 switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
271 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
272 req_idx = pa & 0x0000FFFF;
273 cb_idx = (pa & 0x00FF0000) >> 16;
274 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
276 case MPI_CONTEXT_REPLY_TYPE_LAN:
277 cb_idx = mpt_get_cb_idx(MPTLAN_DRIVER);
279 * Blind set of mf to NULL here was fatal
280 * after lan_reply says "freeme"
281 * Fix sort of combined with an optimization here;
282 * added explicit check for case where lan_reply
283 * was just returning 1 and doing nothing else.
284 * For this case skip the callback, but set up
285 * proper mf value first here:-)
287 if ((pa & 0x58000000) == 0x58000000) {
288 req_idx = pa & 0x0000FFFF;
289 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
290 mpt_free_msg_frame(ioc, mf);
295 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
297 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
298 cb_idx = mpt_get_cb_idx(MPTSTM_DRIVER);
299 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
306 /* Check for (valid) IO callback! */
307 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
308 MptCallbacks[cb_idx] == NULL) {
309 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
310 __FUNCTION__, ioc->name, cb_idx);
314 if (MptCallbacks[cb_idx](ioc, mf, mr))
315 mpt_free_msg_frame(ioc, mf);
321 mpt_reply(MPT_ADAPTER *ioc, u32 pa)
332 /* non-TURBO reply! Hmmm, something may be up...
333 * Newest turbo reply mechanism; get address
334 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
337 /* Map DMA address of reply header to cpu address.
338 * pa is 32 bits - but the dma address may be 32 or 64 bits
339 * get offset based only only the low addresses
342 reply_dma_low = (pa <<= 1);
343 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
344 (reply_dma_low - ioc->reply_frames_low_dma));
346 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
347 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
348 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
350 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
351 ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
352 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mr);
354 /* Check/log IOC log info
356 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
357 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
358 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
359 if (ioc->bus_type == FC)
360 mpt_fc_log_info(ioc, log_info);
361 else if (ioc->bus_type == SPI)
362 mpt_spi_log_info(ioc, log_info);
363 else if (ioc->bus_type == SAS)
364 mpt_sas_log_info(ioc, log_info);
367 if (ioc_stat & MPI_IOCSTATUS_MASK)
368 mpt_iocstatus_info(ioc, (u32)ioc_stat, mf);
370 /* Check for (valid) IO callback! */
371 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
372 MptCallbacks[cb_idx] == NULL) {
373 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
374 __FUNCTION__, ioc->name, cb_idx);
379 freeme = MptCallbacks[cb_idx](ioc, mf, mr);
382 /* Flush (non-TURBO) reply with a WRITE! */
383 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
386 mpt_free_msg_frame(ioc, mf);
390 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
392 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
393 * @irq: irq number (not used)
394 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
396 * This routine is registered via the request_irq() kernel API call,
397 * and handles all interrupts generated from a specific MPT adapter
398 * (also referred to as a IO Controller or IOC).
399 * This routine must clear the interrupt from the adapter and does
400 * so by reading the reply FIFO. Multiple replies may be processed
401 * per single call to this routine.
403 * This routine handles register-level access of the adapter but
404 * dispatches (calls) a protocol-specific callback routine to handle
405 * the protocol-specific details of the MPT request completion.
408 mpt_interrupt(int irq, void *bus_id)
410 MPT_ADAPTER *ioc = bus_id;
411 u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
413 if (pa == 0xFFFFFFFF)
417 * Drain the reply FIFO!
420 if (pa & MPI_ADDRESS_REPLY_A_BIT)
423 mpt_turbo_reply(ioc, pa);
424 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
425 } while (pa != 0xFFFFFFFF);
430 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
432 * mpt_base_reply - MPT base driver's callback routine
433 * @ioc: Pointer to MPT_ADAPTER structure
434 * @mf: Pointer to original MPT request frame
435 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
437 * MPT base driver's callback routine; all base driver
438 * "internal" request/reply processing is routed here.
439 * Currently used for EventNotification and EventAck handling.
441 * Returns 1 indicating original alloc'd request frame ptr
442 * should be freed, or 0 if it shouldn't.
445 mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
450 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply() called\n", ioc->name));
451 #ifdef CONFIG_FUSION_LOGGING
452 if ((ioc->debug_level & MPT_DEBUG_MSG_FRAME) &&
453 !(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) {
454 dmfprintk(ioc, printk(MYIOC_s_INFO_FMT ": Original request frame (@%p) header\n",
456 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)mf);
460 func = reply->u.hdr.Function;
461 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply, Function=%02Xh\n",
464 if (func == MPI_FUNCTION_EVENT_NOTIFICATION) {
465 EventNotificationReply_t *pEvReply = (EventNotificationReply_t *) reply;
469 results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
470 if (results != evHandlers) {
471 /* CHECKME! Any special handling needed here? */
472 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
473 ioc->name, evHandlers, results));
477 * Hmmm... It seems that EventNotificationReply is an exception
478 * to the rule of one reply per request.
480 if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) {
483 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
484 ioc->name, pEvReply));
487 #ifdef CONFIG_PROC_FS
488 // LogEvent(ioc, pEvReply);
491 } else if (func == MPI_FUNCTION_EVENT_ACK) {
492 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply, EventAck reply received\n",
494 } else if (func == MPI_FUNCTION_CONFIG) {
498 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "config_complete (mf=%p,mr=%p)\n",
499 ioc->name, mf, reply));
501 pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *)));
504 /* disable timer and remove from linked list */
505 del_timer(&pCfg->timer);
507 spin_lock_irqsave(&ioc->FreeQlock, flags);
508 list_del(&pCfg->linkage);
509 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
512 * If IOC Status is SUCCESS, save the header
513 * and set the status code to GOOD.
515 pCfg->status = MPT_CONFIG_ERROR;
517 ConfigReply_t *pReply = (ConfigReply_t *)reply;
520 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
521 dcprintk(ioc, printk(MYIOC_s_NOTE_FMT " IOCStatus=%04xh, IOCLogInfo=%08xh\n",
522 ioc->name, status, le32_to_cpu(pReply->IOCLogInfo)));
524 pCfg->status = status;
525 if (status == MPI_IOCSTATUS_SUCCESS) {
526 if ((pReply->Header.PageType &
527 MPI_CONFIG_PAGETYPE_MASK) ==
528 MPI_CONFIG_PAGETYPE_EXTENDED) {
529 pCfg->cfghdr.ehdr->ExtPageLength =
530 le16_to_cpu(pReply->ExtPageLength);
531 pCfg->cfghdr.ehdr->ExtPageType =
534 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
536 /* If this is a regular header, save PageLength. */
537 /* LMP Do this better so not using a reserved field! */
538 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
539 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
540 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
545 * Wake up the original calling thread
550 } else if (func == MPI_FUNCTION_SAS_IO_UNIT_CONTROL) {
551 /* we should be always getting a reply frame */
552 memcpy(ioc->persist_reply_frame, reply,
553 min(MPT_DEFAULT_FRAME_SIZE,
554 4*reply->u.reply.MsgLength));
555 del_timer(&ioc->persist_timer);
556 ioc->persist_wait_done = 1;
559 printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
564 * Conditionally tell caller to free the original
565 * EventNotification/EventAck/unexpected request frame!
570 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
572 * mpt_register - Register protocol-specific main callback handler.
573 * @cbfunc: callback function pointer
574 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
576 * This routine is called by a protocol-specific driver (SCSI host,
577 * LAN, SCSI target) to register its reply callback routine. Each
578 * protocol-specific driver must do this before it will be able to
579 * use any IOC resources, such as obtaining request frames.
581 * NOTES: The SCSI protocol driver currently calls this routine thrice
582 * in order to register separate callbacks; one for "normal" SCSI IO;
583 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
585 * Returns u8 valued "handle" in the range (and S.O.D. order)
586 * {N,...,7,6,5,...,1} if successful.
587 * A return value of MPT_MAX_PROTOCOL_DRIVERS (including zero!) should be
588 * considered an error by the caller.
591 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
594 last_drv_idx = MPT_MAX_PROTOCOL_DRIVERS;
597 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
598 * (slot/handle 0 is reserved!)
600 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
601 if (MptCallbacks[cb_idx] == NULL) {
602 MptCallbacks[cb_idx] = cbfunc;
603 MptDriverClass[cb_idx] = dclass;
604 MptEvHandlers[cb_idx] = NULL;
605 last_drv_idx = cb_idx;
613 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
615 * mpt_deregister - Deregister a protocol drivers resources.
616 * @cb_idx: previously registered callback handle
618 * Each protocol-specific driver should call this routine when its
619 * module is unloaded.
622 mpt_deregister(u8 cb_idx)
624 if (cb_idx && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
625 MptCallbacks[cb_idx] = NULL;
626 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
627 MptEvHandlers[cb_idx] = NULL;
633 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
635 * mpt_event_register - Register protocol-specific event callback
637 * @cb_idx: previously registered (via mpt_register) callback handle
638 * @ev_cbfunc: callback function
640 * This routine can be called by one or more protocol-specific drivers
641 * if/when they choose to be notified of MPT events.
643 * Returns 0 for success.
646 mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc)
648 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
651 MptEvHandlers[cb_idx] = ev_cbfunc;
655 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
657 * mpt_event_deregister - Deregister protocol-specific event callback
659 * @cb_idx: previously registered callback handle
661 * Each protocol-specific driver should call this routine
662 * when it does not (or can no longer) handle events,
663 * or when its module is unloaded.
666 mpt_event_deregister(u8 cb_idx)
668 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
671 MptEvHandlers[cb_idx] = NULL;
674 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
676 * mpt_reset_register - Register protocol-specific IOC reset handler.
677 * @cb_idx: previously registered (via mpt_register) callback handle
678 * @reset_func: reset function
680 * This routine can be called by one or more protocol-specific drivers
681 * if/when they choose to be notified of IOC resets.
683 * Returns 0 for success.
686 mpt_reset_register(u8 cb_idx, MPT_RESETHANDLER reset_func)
688 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
691 MptResetHandlers[cb_idx] = reset_func;
695 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
697 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
698 * @cb_idx: previously registered callback handle
700 * Each protocol-specific driver should call this routine
701 * when it does not (or can no longer) handle IOC reset handling,
702 * or when its module is unloaded.
705 mpt_reset_deregister(u8 cb_idx)
707 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
710 MptResetHandlers[cb_idx] = NULL;
713 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
715 * mpt_device_driver_register - Register device driver hooks
716 * @dd_cbfunc: driver callbacks struct
717 * @cb_idx: MPT protocol driver index
720 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, u8 cb_idx)
723 const struct pci_device_id *id;
725 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
728 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
730 /* call per pci device probe entry point */
731 list_for_each_entry(ioc, &ioc_list, list) {
732 id = ioc->pcidev->driver ?
733 ioc->pcidev->driver->id_table : NULL;
734 if (dd_cbfunc->probe)
735 dd_cbfunc->probe(ioc->pcidev, id);
741 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
743 * mpt_device_driver_deregister - DeRegister device driver hooks
744 * @cb_idx: MPT protocol driver index
747 mpt_device_driver_deregister(u8 cb_idx)
749 struct mpt_pci_driver *dd_cbfunc;
752 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
755 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
757 list_for_each_entry(ioc, &ioc_list, list) {
758 if (dd_cbfunc->remove)
759 dd_cbfunc->remove(ioc->pcidev);
762 MptDeviceDriverHandlers[cb_idx] = NULL;
766 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
768 * mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024)
769 * allocated per MPT adapter.
770 * @cb_idx: Handle of registered MPT protocol driver
771 * @ioc: Pointer to MPT adapter structure
773 * Returns pointer to a MPT request frame or %NULL if none are available
774 * or IOC is not active.
777 mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc)
781 u16 req_idx; /* Request index */
783 /* validate handle and ioc identifier */
787 printk(MYIOC_s_WARN_FMT "IOC Not Active! mpt_get_msg_frame "
788 "returning NULL!\n", ioc->name);
791 /* If interrupts are not attached, do not return a request frame */
795 spin_lock_irqsave(&ioc->FreeQlock, flags);
796 if (!list_empty(&ioc->FreeQ)) {
799 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
800 u.frame.linkage.list);
801 list_del(&mf->u.frame.linkage.list);
802 mf->u.frame.linkage.arg1 = 0;
803 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
804 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
806 req_idx = req_offset / ioc->req_sz;
807 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
808 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
809 /* Default, will be changed if necessary in SG generation */
810 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame;
817 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
821 printk(MYIOC_s_WARN_FMT "IOC Active. No free Msg Frames! "
822 "Count 0x%x Max 0x%x\n", ioc->name, ioc->mfcnt,
825 if (mfcounter == PRINT_MF_COUNT)
826 printk(MYIOC_s_INFO_FMT "MF Count 0x%x Max 0x%x \n", ioc->name,
827 ioc->mfcnt, ioc->req_depth);
830 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_get_msg_frame(%d,%d), got mf=%p\n",
831 ioc->name, cb_idx, ioc->id, mf));
835 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
837 * mpt_put_msg_frame - Send a protocol specific MPT request frame
839 * @cb_idx: Handle of registered MPT protocol driver
840 * @ioc: Pointer to MPT adapter structure
841 * @mf: Pointer to MPT request frame
843 * This routine posts a MPT request frame to the request post FIFO of a
844 * specific MPT adapter.
847 mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
851 u16 req_idx; /* Request index */
853 /* ensure values are reset properly! */
854 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
855 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
857 req_idx = req_offset / ioc->req_sz;
858 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
859 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
861 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
863 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
864 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d "
865 "RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx,
866 ioc->RequestNB[req_idx]));
867 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
871 * mpt_put_msg_frame_hi_pri - Send a protocol specific MPT request frame
872 * to a IOC using hi priority request queue.
873 * @cb_idx: Handle of registered MPT protocol driver
874 * @ioc: Pointer to MPT adapter structure
875 * @mf: Pointer to MPT request frame
877 * This routine posts a MPT request frame to the request post FIFO of a
878 * specific MPT adapter.
881 mpt_put_msg_frame_hi_pri(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
885 u16 req_idx; /* Request index */
887 /* ensure values are reset properly! */
888 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
889 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
890 req_idx = req_offset / ioc->req_sz;
891 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
892 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
894 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
896 mf_dma_addr = (ioc->req_frames_low_dma + req_offset);
897 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d\n",
898 ioc->name, mf_dma_addr, req_idx));
899 CHIPREG_WRITE32(&ioc->chip->RequestHiPriFifo, mf_dma_addr);
902 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
904 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
905 * @handle: Handle of registered MPT protocol driver
906 * @ioc: Pointer to MPT adapter structure
907 * @mf: Pointer to MPT request frame
909 * This routine places a MPT request frame back on the MPT adapter's
913 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
917 /* Put Request back on FreeQ! */
918 spin_lock_irqsave(&ioc->FreeQlock, flags);
919 mf->u.frame.linkage.arg1 = 0xdeadbeaf; /* signature to know if this mf is freed */
920 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
924 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
927 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
929 * mpt_add_sge - Place a simple SGE at address pAddr.
930 * @pAddr: virtual address for SGE
931 * @flagslength: SGE flags and data transfer length
932 * @dma_addr: Physical address
934 * This routine places a MPT request frame back on the MPT adapter's
938 mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
940 if (sizeof(dma_addr_t) == sizeof(u64)) {
941 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
942 u32 tmp = dma_addr & 0xFFFFFFFF;
944 pSge->FlagsLength = cpu_to_le32(flagslength);
945 pSge->Address.Low = cpu_to_le32(tmp);
946 tmp = (u32) ((u64)dma_addr >> 32);
947 pSge->Address.High = cpu_to_le32(tmp);
950 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
951 pSge->FlagsLength = cpu_to_le32(flagslength);
952 pSge->Address = cpu_to_le32(dma_addr);
956 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
958 * mpt_send_handshake_request - Send MPT request via doorbell handshake method.
959 * @cb_idx: Handle of registered MPT protocol driver
960 * @ioc: Pointer to MPT adapter structure
961 * @reqBytes: Size of the request in bytes
962 * @req: Pointer to MPT request frame
963 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
965 * This routine is used exclusively to send MptScsiTaskMgmt
966 * requests since they are required to be sent via doorbell handshake.
968 * NOTE: It is the callers responsibility to byte-swap fields in the
969 * request which are greater than 1 byte in size.
971 * Returns 0 for success, non-zero for failure.
974 mpt_send_handshake_request(u8 cb_idx, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
980 /* State is known to be good upon entering
981 * this function so issue the bus reset
986 * Emulate what mpt_put_msg_frame() does /wrt to sanity
987 * setting cb_idx/req_idx. But ONLY if this request
988 * is in proper (pre-alloc'd) request buffer range...
990 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
991 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
992 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
993 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
994 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
997 /* Make sure there are no doorbells */
998 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1000 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1001 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
1002 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
1004 /* Wait for IOC doorbell int */
1005 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
1009 /* Read doorbell and check for active bit */
1010 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
1013 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_send_handshake_request start, WaitCnt=%d\n",
1016 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1018 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1022 /* Send request via doorbell handshake */
1023 req_as_bytes = (u8 *) req;
1024 for (ii = 0; ii < reqBytes/4; ii++) {
1027 word = ((req_as_bytes[(ii*4) + 0] << 0) |
1028 (req_as_bytes[(ii*4) + 1] << 8) |
1029 (req_as_bytes[(ii*4) + 2] << 16) |
1030 (req_as_bytes[(ii*4) + 3] << 24));
1031 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
1032 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1038 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
1043 /* Make sure there are no doorbells */
1044 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1049 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1051 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
1052 * @ioc: Pointer to MPT adapter structure
1053 * @access_control_value: define bits below
1054 * @sleepFlag: Specifies whether the process can sleep
1056 * Provides mechanism for the host driver to control the IOC's
1057 * Host Page Buffer access.
1059 * Access Control Value - bits[15:12]
1061 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1062 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1063 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1065 * Returns 0 for success, non-zero for failure.
1069 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1073 /* return if in use */
1074 if (CHIPREG_READ32(&ioc->chip->Doorbell)
1075 & MPI_DOORBELL_ACTIVE)
1078 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1080 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1081 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1082 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1083 (access_control_value<<12)));
1085 /* Wait for IOC to clear Doorbell Status bit */
1086 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1092 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1094 * mpt_host_page_alloc - allocate system memory for the fw
1095 * @ioc: Pointer to pointer to IOC adapter
1096 * @ioc_init: Pointer to ioc init config page
1098 * If we already allocated memory in past, then resend the same pointer.
1099 * Returns 0 for success, non-zero for failure.
1102 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1106 u32 host_page_buffer_sz=0;
1108 if(!ioc->HostPageBuffer) {
1110 host_page_buffer_sz =
1111 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1113 if(!host_page_buffer_sz)
1114 return 0; /* fw doesn't need any host buffers */
1116 /* spin till we get enough memory */
1117 while(host_page_buffer_sz > 0) {
1119 if((ioc->HostPageBuffer = pci_alloc_consistent(
1121 host_page_buffer_sz,
1122 &ioc->HostPageBuffer_dma)) != NULL) {
1124 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1125 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1126 ioc->name, ioc->HostPageBuffer,
1127 (u32)ioc->HostPageBuffer_dma,
1128 host_page_buffer_sz));
1129 ioc->alloc_total += host_page_buffer_sz;
1130 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1134 host_page_buffer_sz -= (4*1024);
1138 if(!ioc->HostPageBuffer) {
1139 printk(MYIOC_s_ERR_FMT
1140 "Failed to alloc memory for host_page_buffer!\n",
1145 psge = (char *)&ioc_init->HostPageBufferSGE;
1146 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1147 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1148 MPI_SGE_FLAGS_32_BIT_ADDRESSING |
1149 MPI_SGE_FLAGS_HOST_TO_IOC |
1150 MPI_SGE_FLAGS_END_OF_BUFFER;
1151 if (sizeof(dma_addr_t) == sizeof(u64)) {
1152 flags_length |= MPI_SGE_FLAGS_64_BIT_ADDRESSING;
1154 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1155 flags_length |= ioc->HostPageBuffer_sz;
1156 mpt_add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1157 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1162 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1164 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1165 * @iocid: IOC unique identifier (integer)
1166 * @iocpp: Pointer to pointer to IOC adapter
1168 * Given a unique IOC identifier, set pointer to the associated MPT
1169 * adapter structure.
1171 * Returns iocid and sets iocpp if iocid is found.
1172 * Returns -1 if iocid is not found.
1175 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1179 list_for_each_entry(ioc,&ioc_list,list) {
1180 if (ioc->id == iocid) {
1191 * mpt_get_product_name - returns product string
1192 * @vendor: pci vendor id
1193 * @device: pci device id
1194 * @revision: pci revision id
1195 * @prod_name: string returned
1197 * Returns product string displayed when driver loads,
1198 * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1202 mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name)
1204 char *product_str = NULL;
1206 if (vendor == PCI_VENDOR_ID_BROCADE) {
1209 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1213 product_str = "BRE040 A0";
1216 product_str = "BRE040 A1";
1219 product_str = "BRE040";
1229 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1230 product_str = "LSIFC909 B1";
1232 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1233 product_str = "LSIFC919 B0";
1235 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1236 product_str = "LSIFC929 B0";
1238 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1239 if (revision < 0x80)
1240 product_str = "LSIFC919X A0";
1242 product_str = "LSIFC919XL A1";
1244 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1245 if (revision < 0x80)
1246 product_str = "LSIFC929X A0";
1248 product_str = "LSIFC929XL A1";
1250 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1251 product_str = "LSIFC939X A1";
1253 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1254 product_str = "LSIFC949X A1";
1256 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1260 product_str = "LSIFC949E A0";
1263 product_str = "LSIFC949E A1";
1266 product_str = "LSIFC949E";
1270 case MPI_MANUFACTPAGE_DEVID_53C1030:
1274 product_str = "LSI53C1030 A0";
1277 product_str = "LSI53C1030 B0";
1280 product_str = "LSI53C1030 B1";
1283 product_str = "LSI53C1030 B2";
1286 product_str = "LSI53C1030 C0";
1289 product_str = "LSI53C1030T A0";
1292 product_str = "LSI53C1030T A2";
1295 product_str = "LSI53C1030T A3";
1298 product_str = "LSI53C1020A A1";
1301 product_str = "LSI53C1030";
1305 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1309 product_str = "LSI53C1035 A2";
1312 product_str = "LSI53C1035 B0";
1315 product_str = "LSI53C1035";
1319 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1323 product_str = "LSISAS1064 A1";
1326 product_str = "LSISAS1064 A2";
1329 product_str = "LSISAS1064 A3";
1332 product_str = "LSISAS1064 A4";
1335 product_str = "LSISAS1064";
1339 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1343 product_str = "LSISAS1064E A0";
1346 product_str = "LSISAS1064E B0";
1349 product_str = "LSISAS1064E B1";
1352 product_str = "LSISAS1064E B2";
1355 product_str = "LSISAS1064E B3";
1358 product_str = "LSISAS1064E";
1362 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1366 product_str = "LSISAS1068 A0";
1369 product_str = "LSISAS1068 B0";
1372 product_str = "LSISAS1068 B1";
1375 product_str = "LSISAS1068";
1379 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1383 product_str = "LSISAS1068E A0";
1386 product_str = "LSISAS1068E B0";
1389 product_str = "LSISAS1068E B1";
1392 product_str = "LSISAS1068E B2";
1395 product_str = "LSISAS1068E B3";
1398 product_str = "LSISAS1068E";
1402 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1406 product_str = "LSISAS1078 A0";
1409 product_str = "LSISAS1078 B0";
1412 product_str = "LSISAS1078 C0";
1415 product_str = "LSISAS1078 C1";
1418 product_str = "LSISAS1078 C2";
1421 product_str = "LSISAS1078";
1429 sprintf(prod_name, "%s", product_str);
1432 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1434 * mpt_attach - Install a PCI intelligent MPT adapter.
1435 * @pdev: Pointer to pci_dev structure
1436 * @id: PCI device ID information
1438 * This routine performs all the steps necessary to bring the IOC of
1439 * a MPT adapter to a OPERATIONAL state. This includes registering
1440 * memory regions, registering the interrupt, and allocating request
1441 * and reply memory pools.
1443 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1446 * Returns 0 for success, non-zero for failure.
1448 * TODO: Add support for polled controllers
1451 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1455 unsigned long mem_phys;
1464 static int mpt_ids = 0;
1465 #ifdef CONFIG_PROC_FS
1466 struct proc_dir_entry *dent, *ent;
1469 if (mpt_debug_level)
1470 printk(KERN_INFO MYNAM ": mpt_debug_level=%xh\n", mpt_debug_level);
1472 if (pci_enable_device(pdev))
1475 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1477 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1480 ioc->debug_level = mpt_debug_level;
1481 ioc->id = mpt_ids++;
1482 sprintf(ioc->name, "ioc%d", ioc->id);
1484 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name));
1486 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
1487 dprintk(ioc, printk(MYIOC_s_INFO_FMT
1488 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n", ioc->name));
1489 } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
1490 printk(MYIOC_s_WARN_FMT ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n",
1496 if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
1497 dprintk(ioc, printk(MYIOC_s_INFO_FMT
1498 ": Using 64 bit consistent mask\n", ioc->name));
1500 dprintk(ioc, printk(MYIOC_s_INFO_FMT
1501 ": Not using 64 bit consistent mask\n", ioc->name));
1504 ioc->alloc_total = sizeof(MPT_ADAPTER);
1505 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1506 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1509 ioc->diagPending = 0;
1510 spin_lock_init(&ioc->diagLock);
1511 spin_lock_init(&ioc->initializing_hba_lock);
1513 /* Initialize the event logging.
1515 ioc->eventTypes = 0; /* None */
1516 ioc->eventContext = 0;
1517 ioc->eventLogSize = 0;
1524 ioc->cached_fw = NULL;
1526 /* Initilize SCSI Config Data structure
1528 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1530 /* Initialize the running configQ head.
1532 INIT_LIST_HEAD(&ioc->configQ);
1534 /* Initialize the fc rport list head.
1536 INIT_LIST_HEAD(&ioc->fc_rports);
1538 /* Find lookup slot. */
1539 INIT_LIST_HEAD(&ioc->list);
1541 mem_phys = msize = 0;
1543 for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1544 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1547 /* Get I/O space! */
1548 port = pci_resource_start(pdev, ii);
1549 psize = pci_resource_len(pdev,ii);
1554 mem_phys = pci_resource_start(pdev, ii);
1555 msize = pci_resource_len(pdev,ii);
1558 ioc->mem_size = msize;
1561 /* Get logical ptr for PciMem0 space */
1562 /*mem = ioremap(mem_phys, msize);*/
1563 mem = ioremap(mem_phys, msize);
1565 printk(MYIOC_s_ERR_FMT "Unable to map adapter memory!\n", ioc->name);
1570 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %lx\n", ioc->name, mem, mem_phys));
1572 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",
1573 ioc->name, &ioc->facts, &ioc->pfacts[0]));
1575 ioc->mem_phys = mem_phys;
1576 ioc->chip = (SYSIF_REGS __iomem *)mem;
1578 /* Save Port IO values in case we need to do downloadboot */
1580 u8 *pmem = (u8*)port;
1581 ioc->pio_mem_phys = port;
1582 ioc->pio_chip = (SYSIF_REGS __iomem *)pmem;
1585 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1586 mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name);
1588 switch (pdev->device)
1590 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1591 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1592 ioc->errata_flag_1064 = 1;
1593 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1594 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1595 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1596 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1600 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1601 if (revision < XL_929) {
1602 /* 929X Chip Fix. Set Split transactions level
1603 * for PCIX. Set MOST bits to zero.
1605 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1607 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1609 /* 929XL Chip Fix. Set MMRBC to 0x08.
1611 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1613 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1618 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1619 /* 919X Chip Fix. Set Split transactions level
1620 * for PCIX. Set MOST bits to zero.
1622 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1624 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1628 case MPI_MANUFACTPAGE_DEVID_53C1030:
1629 /* 1030 Chip Fix. Disable Split transactions
1630 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1632 if (revision < C0_1030) {
1633 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1635 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1638 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1639 ioc->bus_type = SPI;
1642 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1643 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1644 ioc->errata_flag_1064 = 1;
1646 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1647 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1648 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1649 ioc->bus_type = SAS;
1652 if (ioc->errata_flag_1064)
1653 pci_disable_io_access(pdev);
1655 spin_lock_init(&ioc->FreeQlock);
1658 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1660 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1662 /* Set lookup ptr. */
1663 list_add_tail(&ioc->list, &ioc_list);
1665 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1667 mpt_detect_bound_ports(ioc, pdev);
1669 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1671 printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",
1674 list_del(&ioc->list);
1676 ioc->alt_ioc->alt_ioc = NULL;
1679 pci_set_drvdata(pdev, NULL);
1683 /* call per device driver probe entry point */
1684 for(cb_idx=0; cb_idx<MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
1685 if(MptDeviceDriverHandlers[cb_idx] &&
1686 MptDeviceDriverHandlers[cb_idx]->probe) {
1687 MptDeviceDriverHandlers[cb_idx]->probe(pdev,id);
1691 #ifdef CONFIG_PROC_FS
1693 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1695 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1697 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1699 ent->read_proc = procmpt_iocinfo_read;
1702 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1704 ent->read_proc = procmpt_summary_read;
1713 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1715 * mpt_detach - Remove a PCI intelligent MPT adapter.
1716 * @pdev: Pointer to pci_dev structure
1720 mpt_detach(struct pci_dev *pdev)
1722 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1726 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
1727 remove_proc_entry(pname, NULL);
1728 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
1729 remove_proc_entry(pname, NULL);
1730 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
1731 remove_proc_entry(pname, NULL);
1733 /* call per device driver remove entry point */
1734 for(cb_idx=0; cb_idx<MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
1735 if(MptDeviceDriverHandlers[cb_idx] &&
1736 MptDeviceDriverHandlers[cb_idx]->remove) {
1737 MptDeviceDriverHandlers[cb_idx]->remove(pdev);
1741 /* Disable interrupts! */
1742 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1745 synchronize_irq(pdev->irq);
1747 /* Clear any lingering interrupt */
1748 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1750 CHIPREG_READ32(&ioc->chip->IntStatus);
1752 mpt_adapter_dispose(ioc);
1754 pci_set_drvdata(pdev, NULL);
1757 /**************************************************************************
1761 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1763 * mpt_suspend - Fusion MPT base driver suspend routine.
1764 * @pdev: Pointer to pci_dev structure
1765 * @state: new state to enter
1768 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
1771 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1773 device_state=pci_choose_state(pdev, state);
1775 printk(MYIOC_s_INFO_FMT
1776 "pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
1777 ioc->name, pdev, pci_name(pdev), device_state);
1779 pci_save_state(pdev);
1781 /* put ioc into READY_STATE */
1782 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
1783 printk(MYIOC_s_ERR_FMT
1784 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
1787 /* disable interrupts */
1788 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1791 /* Clear any lingering interrupt */
1792 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1794 pci_disable_device(pdev);
1795 pci_set_power_state(pdev, device_state);
1800 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1802 * mpt_resume - Fusion MPT base driver resume routine.
1803 * @pdev: Pointer to pci_dev structure
1806 mpt_resume(struct pci_dev *pdev)
1808 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1809 u32 device_state = pdev->current_state;
1813 printk(MYIOC_s_INFO_FMT
1814 "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
1815 ioc->name, pdev, pci_name(pdev), device_state);
1817 pci_set_power_state(pdev, 0);
1818 pci_restore_state(pdev);
1819 err = pci_enable_device(pdev);
1823 /* enable interrupts */
1824 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
1827 printk(MYIOC_s_INFO_FMT
1828 "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1830 (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1831 CHIPREG_READ32(&ioc->chip->Doorbell));
1833 /* bring ioc to operational state */
1834 if ((recovery_state = mpt_do_ioc_recovery(ioc,
1835 MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {
1836 printk(MYIOC_s_INFO_FMT
1837 "pci-resume: Cannot recover, error:[%x]\n",
1838 ioc->name, recovery_state);
1840 printk(MYIOC_s_INFO_FMT
1841 "pci-resume: success\n", ioc->name);
1849 mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase)
1851 if ((MptDriverClass[index] == MPTSPI_DRIVER &&
1852 ioc->bus_type != SPI) ||
1853 (MptDriverClass[index] == MPTFC_DRIVER &&
1854 ioc->bus_type != FC) ||
1855 (MptDriverClass[index] == MPTSAS_DRIVER &&
1856 ioc->bus_type != SAS))
1857 /* make sure we only call the relevant reset handler
1860 return (MptResetHandlers[index])(ioc, reset_phase);
1863 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1865 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1866 * @ioc: Pointer to MPT adapter structure
1867 * @reason: Event word / reason
1868 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1870 * This routine performs all the steps necessary to bring the IOC
1871 * to a OPERATIONAL state.
1873 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1878 * -1 if failed to get board READY
1879 * -2 if READY but IOCFacts Failed
1880 * -3 if READY but PrimeIOCFifos Failed
1881 * -4 if READY but IOCInit Failed
1884 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1886 int hard_reset_done = 0;
1887 int alt_ioc_ready = 0;
1894 int reset_alt_ioc_active = 0;
1895 int irq_allocated = 0;
1898 printk(MYIOC_s_INFO_FMT "Initiating %s\n", ioc->name,
1899 reason == MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
1901 /* Disable reply interrupts (also blocks FreeQ) */
1902 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1906 if (ioc->alt_ioc->active)
1907 reset_alt_ioc_active = 1;
1909 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1910 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
1911 ioc->alt_ioc->active = 0;
1915 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
1918 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
1919 if (hard_reset_done == -4) {
1920 printk(MYIOC_s_WARN_FMT "Owned by PEER..skipping!\n",
1923 if (reset_alt_ioc_active && ioc->alt_ioc) {
1924 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1925 dprintk(ioc, printk(MYIOC_s_INFO_FMT
1926 "alt_ioc reply irq re-enabled\n", ioc->alt_ioc->name));
1927 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
1928 ioc->alt_ioc->active = 1;
1932 printk(MYIOC_s_WARN_FMT "NOT READY!\n", ioc->name);
1937 /* hard_reset_done = 0 if a soft reset was performed
1938 * and 1 if a hard reset was performed.
1940 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
1941 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
1944 printk(MYIOC_s_WARN_FMT "alt_ioc not ready!\n", ioc->alt_ioc->name);
1947 for (ii=0; ii<5; ii++) {
1948 /* Get IOC facts! Allow 5 retries */
1949 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
1955 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1956 "Retry IocFacts failed rc=%x\n", ioc->name, rc));
1958 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1959 MptDisplayIocCapabilities(ioc);
1962 if (alt_ioc_ready) {
1963 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
1964 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1965 "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
1966 /* Retry - alt IOC was initialized once
1968 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
1971 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1972 "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
1974 reset_alt_ioc_active = 0;
1975 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1976 MptDisplayIocCapabilities(ioc->alt_ioc);
1981 * Device is reset now. It must have de-asserted the interrupt line
1982 * (if it was asserted) and it should be safe to register for the
1985 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1987 if (ioc->pcidev->irq) {
1988 if (mpt_msi_enable && !pci_enable_msi(ioc->pcidev))
1989 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
1991 rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
1992 IRQF_SHARED, ioc->name, ioc);
1994 printk(MYIOC_s_ERR_FMT "Unable to allocate "
1995 "interrupt %d!\n", ioc->name, ioc->pcidev->irq);
1997 pci_disable_msi(ioc->pcidev);
2001 ioc->pci_irq = ioc->pcidev->irq;
2002 pci_set_master(ioc->pcidev); /* ?? */
2003 pci_set_drvdata(ioc->pcidev, ioc);
2004 dprintk(ioc, printk(MYIOC_s_INFO_FMT "installed at interrupt "
2005 "%d\n", ioc->name, ioc->pcidev->irq));
2009 /* Prime reply & request queues!
2010 * (mucho alloc's) Must be done prior to
2011 * init as upper addresses are needed for init.
2012 * If fails, continue with alt-ioc processing
2014 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
2017 /* May need to check/upload firmware & data here!
2018 * If fails, continue with alt-ioc processing
2020 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
2023 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
2024 printk(MYIOC_s_WARN_FMT ": alt_ioc (%d) FIFO mgmt alloc!\n",
2025 ioc->alt_ioc->name, rc);
2027 reset_alt_ioc_active = 0;
2030 if (alt_ioc_ready) {
2031 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
2033 reset_alt_ioc_active = 0;
2034 printk(MYIOC_s_WARN_FMT "alt_ioc (%d) init failure!\n",
2035 ioc->alt_ioc->name, rc);
2039 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
2040 if (ioc->upload_fw) {
2041 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2042 "firmware upload required!\n", ioc->name));
2044 /* Controller is not operational, cannot do upload
2047 rc = mpt_do_upload(ioc, sleepFlag);
2049 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2051 * Maintain only one pointer to FW memory
2052 * so there will not be two attempt to
2053 * downloadboot onboard dual function
2054 * chips (mpt_adapter_disable,
2057 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2058 "mpt_upload: alt_%s has cached_fw=%p \n",
2059 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
2060 ioc->alt_ioc->cached_fw = NULL;
2063 printk(MYIOC_s_WARN_FMT
2064 "firmware upload failure!\n", ioc->name);
2072 /* Enable! (reply interrupt) */
2073 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
2077 if (reset_alt_ioc_active && ioc->alt_ioc) {
2078 /* (re)Enable alt-IOC! (reply interrupt) */
2079 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "alt_ioc reply irq re-enabled\n",
2080 ioc->alt_ioc->name));
2081 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2082 ioc->alt_ioc->active = 1;
2085 /* Enable MPT base driver management of EventNotification
2086 * and EventAck handling.
2088 if ((ret == 0) && (!ioc->facts.EventState))
2089 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
2091 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2092 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
2094 /* Add additional "reason" check before call to GetLanConfigPages
2095 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2096 * recursive scenario; GetLanConfigPages times out, timer expired
2097 * routine calls HardResetHandler, which calls into here again,
2098 * and we try GetLanConfigPages again...
2100 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2103 * Initalize link list for inactive raid volumes.
2105 init_MUTEX(&ioc->raid_data.inactive_list_mutex);
2106 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2108 if (ioc->bus_type == SAS) {
2110 /* clear persistency table */
2111 if(ioc->facts.IOCExceptions &
2112 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
2113 ret = mptbase_sas_persist_operation(ioc,
2114 MPI_SAS_OP_CLEAR_NOT_PRESENT);
2121 mpt_findImVolumes(ioc);
2123 } else if (ioc->bus_type == FC) {
2124 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
2125 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2127 * Pre-fetch the ports LAN MAC address!
2128 * (LANPage1_t stuff)
2130 (void) GetLanConfigPages(ioc);
2131 a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2132 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2133 "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
2134 ioc->name, a[5], a[4], a[3], a[2], a[1], a[0]));
2138 /* Get NVRAM and adapter maximums from SPP 0 and 2
2140 mpt_GetScsiPortSettings(ioc, 0);
2142 /* Get version and length of SDP 1
2144 mpt_readScsiDevicePageHeaders(ioc, 0);
2148 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
2149 mpt_findImVolumes(ioc);
2151 /* Check, and possibly reset, the coalescing value
2153 mpt_read_ioc_pg_1(ioc);
2155 mpt_read_ioc_pg_4(ioc);
2158 GetIoUnitPage2(ioc);
2159 mpt_get_manufacturing_pg_0(ioc);
2163 * Call each currently registered protocol IOC reset handler
2164 * with post-reset indication.
2165 * NOTE: If we're doing _IOC_BRINGUP, there can be no
2166 * MptResetHandlers[] registered yet.
2168 if (hard_reset_done) {
2170 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
2171 if ((ret == 0) && MptResetHandlers[cb_idx]) {
2172 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2173 "Calling IOC post_reset handler #%d\n",
2174 ioc->name, cb_idx));
2175 rc += mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET);
2179 if (alt_ioc_ready && MptResetHandlers[cb_idx]) {
2180 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2181 "Calling IOC post_reset handler #%d\n",
2182 ioc->alt_ioc->name, cb_idx));
2183 rc += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_POST_RESET);
2187 /* FIXME? Examine results here? */
2191 if ((ret != 0) && irq_allocated) {
2192 free_irq(ioc->pci_irq, ioc);
2194 pci_disable_msi(ioc->pcidev);
2199 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2201 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2202 * @ioc: Pointer to MPT adapter structure
2203 * @pdev: Pointer to (struct pci_dev) structure
2205 * Search for PCI bus/dev_function which matches
2206 * PCI bus/dev_function (+/-1) for newly discovered 929,
2207 * 929X, 1030 or 1035.
2209 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2210 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2213 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
2215 struct pci_dev *peer=NULL;
2216 unsigned int slot = PCI_SLOT(pdev->devfn);
2217 unsigned int func = PCI_FUNC(pdev->devfn);
2218 MPT_ADAPTER *ioc_srch;
2220 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PCI device %s devfn=%x/%x,"
2221 " searching for devfn match on %x or %x\n",
2222 ioc->name, pci_name(pdev), pdev->bus->number,
2223 pdev->devfn, func-1, func+1));
2225 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
2227 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
2232 list_for_each_entry(ioc_srch, &ioc_list, list) {
2233 struct pci_dev *_pcidev = ioc_srch->pcidev;
2234 if (_pcidev == peer) {
2235 /* Paranoia checks */
2236 if (ioc->alt_ioc != NULL) {
2237 printk(MYIOC_s_WARN_FMT "Oops, already bound to %s!\n",
2238 ioc->name, ioc->alt_ioc->name);
2240 } else if (ioc_srch->alt_ioc != NULL) {
2241 printk(MYIOC_s_WARN_FMT "Oops, already bound to %s!\n",
2242 ioc_srch->name, ioc_srch->alt_ioc->name);
2245 dprintk(ioc, printk(MYIOC_s_INFO_FMT "FOUND! binding to %s\n",
2246 ioc->name, ioc_srch->name));
2247 ioc_srch->alt_ioc = ioc;
2248 ioc->alt_ioc = ioc_srch;
2254 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2256 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2257 * @ioc: Pointer to MPT adapter structure
2260 mpt_adapter_disable(MPT_ADAPTER *ioc)
2265 if (ioc->cached_fw != NULL) {
2266 ddlprintk(ioc, printk(MYIOC_s_INFO_FMT
2267 "mpt_adapter_disable: Pushing FW onto adapter\n", ioc->name));
2268 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)ioc->cached_fw, NO_SLEEP)) < 0) {
2269 printk(MYIOC_s_WARN_FMT "firmware downloadboot failure (%d)!\n",
2274 /* Disable adapter interrupts! */
2275 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2277 /* Clear any lingering interrupt */
2278 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2280 if (ioc->alloc != NULL) {
2282 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "free @ %p, sz=%d bytes\n",
2283 ioc->name, ioc->alloc, ioc->alloc_sz));
2284 pci_free_consistent(ioc->pcidev, sz,
2285 ioc->alloc, ioc->alloc_dma);
2286 ioc->reply_frames = NULL;
2287 ioc->req_frames = NULL;
2289 ioc->alloc_total -= sz;
2292 if (ioc->sense_buf_pool != NULL) {
2293 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2294 pci_free_consistent(ioc->pcidev, sz,
2295 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2296 ioc->sense_buf_pool = NULL;
2297 ioc->alloc_total -= sz;
2300 if (ioc->events != NULL){
2301 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2304 ioc->alloc_total -= sz;
2307 if (ioc->cached_fw != NULL) {
2308 sz = ioc->facts.FWImageSize;
2309 pci_free_consistent(ioc->pcidev, sz,
2310 ioc->cached_fw, ioc->cached_fw_dma);
2311 ioc->cached_fw = NULL;
2312 ioc->alloc_total -= sz;
2315 kfree(ioc->spi_data.nvram);
2316 mpt_inactive_raid_list_free(ioc);
2317 kfree(ioc->raid_data.pIocPg2);
2318 kfree(ioc->raid_data.pIocPg3);
2319 ioc->spi_data.nvram = NULL;
2320 ioc->raid_data.pIocPg3 = NULL;
2322 if (ioc->spi_data.pIocPg4 != NULL) {
2323 sz = ioc->spi_data.IocPg4Sz;
2324 pci_free_consistent(ioc->pcidev, sz,
2325 ioc->spi_data.pIocPg4,
2326 ioc->spi_data.IocPg4_dma);
2327 ioc->spi_data.pIocPg4 = NULL;
2328 ioc->alloc_total -= sz;
2331 if (ioc->ReqToChain != NULL) {
2332 kfree(ioc->ReqToChain);
2333 kfree(ioc->RequestNB);
2334 ioc->ReqToChain = NULL;
2337 kfree(ioc->ChainToChain);
2338 ioc->ChainToChain = NULL;
2340 if (ioc->HostPageBuffer != NULL) {
2341 if((ret = mpt_host_page_access_control(ioc,
2342 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2343 printk(MYIOC_s_ERR_FMT
2344 "host page buffers free failed (%d)!\n",
2347 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "HostPageBuffer free @ %p, sz=%d bytes\n",
2348 ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
2349 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2350 ioc->HostPageBuffer, ioc->HostPageBuffer_dma);
2351 ioc->HostPageBuffer = NULL;
2352 ioc->HostPageBuffer_sz = 0;
2353 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2357 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2359 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2360 * @ioc: Pointer to MPT adapter structure
2362 * This routine unregisters h/w resources and frees all alloc'd memory
2363 * associated with a MPT adapter structure.
2366 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2368 int sz_first, sz_last;
2373 sz_first = ioc->alloc_total;
2375 mpt_adapter_disable(ioc);
2377 if (ioc->pci_irq != -1) {
2378 free_irq(ioc->pci_irq, ioc);
2380 pci_disable_msi(ioc->pcidev);
2384 if (ioc->memmap != NULL) {
2385 iounmap(ioc->memmap);
2389 #if defined(CONFIG_MTRR) && 0
2390 if (ioc->mtrr_reg > 0) {
2391 mtrr_del(ioc->mtrr_reg, 0, 0);
2392 dprintk(ioc, printk(MYIOC_s_INFO_FMT "MTRR region de-registered\n", ioc->name));
2396 /* Zap the adapter lookup ptr! */
2397 list_del(&ioc->list);
2399 sz_last = ioc->alloc_total;
2400 dprintk(ioc, printk(MYIOC_s_INFO_FMT "free'd %d of %d bytes\n",
2401 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2404 ioc->alt_ioc->alt_ioc = NULL;
2409 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2411 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2412 * @ioc: Pointer to MPT adapter structure
2415 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2419 printk(KERN_INFO "%s: ", ioc->name);
2421 printk("%s: ", ioc->prod_name);
2422 printk("Capabilities={");
2424 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2425 printk("Initiator");
2429 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2430 printk("%sTarget", i ? "," : "");
2434 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2435 printk("%sLAN", i ? "," : "");
2441 * This would probably evoke more questions than it's worth
2443 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2444 printk("%sLogBusAddr", i ? "," : "");
2452 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2454 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2455 * @ioc: Pointer to MPT_ADAPTER structure
2456 * @force: Force hard KickStart of IOC
2457 * @sleepFlag: Specifies whether the process can sleep
2460 * 1 - DIAG reset and READY
2461 * 0 - READY initially OR soft reset and READY
2462 * -1 - Any failure on KickStart
2463 * -2 - Msg Unit Reset Failed
2464 * -3 - IO Unit Reset Failed
2465 * -4 - IOC owned by a PEER
2468 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2473 int hard_reset_done = 0;
2478 /* Get current [raw] IOC state */
2479 ioc_state = mpt_GetIocState(ioc, 0);
2480 dhsprintk(ioc, printk(MYIOC_s_INFO_FMT "MakeIocReady [raw] state=%08x\n", ioc->name, ioc_state));
2483 * Check to see if IOC got left/stuck in doorbell handshake
2484 * grip of death. If so, hard reset the IOC.
2486 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2488 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2492 /* Is it already READY? */
2493 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
2497 * Check to see if IOC is in FAULT state.
2499 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2501 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2503 printk(MYIOC_s_WARN_FMT " FAULT code = %04xh\n",
2504 ioc->name, ioc_state & MPI_DOORBELL_DATA_MASK);
2508 * Hmmm... Did it get left operational?
2510 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2511 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC operational unexpected\n",
2515 * If PCI Peer, exit.
2516 * Else, if no fault conditions are present, issue a MessageUnitReset
2517 * Else, fall through to KickStart case
2519 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2520 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2521 "whoinit 0x%x statefault %d force %d\n",
2522 ioc->name, whoinit, statefault, force));
2523 if (whoinit == MPI_WHOINIT_PCI_PEER)
2526 if ((statefault == 0 ) && (force == 0)) {
2527 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2534 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2535 if (hard_reset_done < 0)
2539 * Loop here waiting for IOC to come READY.
2542 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2544 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2545 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2547 * BIOS or previous driver load left IOC in OP state.
2548 * Reset messaging FIFOs.
2550 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2551 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2554 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2556 * Something is wrong. Try to get IOC back
2559 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2560 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2567 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2568 ioc->name, (int)((ii+5)/HZ));
2572 if (sleepFlag == CAN_SLEEP) {
2575 mdelay (1); /* 1 msec delay */
2580 if (statefault < 3) {
2581 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2583 statefault==1 ? "stuck handshake" : "IOC FAULT");
2586 return hard_reset_done;
2589 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2591 * mpt_GetIocState - Get the current state of a MPT adapter.
2592 * @ioc: Pointer to MPT_ADAPTER structure
2593 * @cooked: Request raw or cooked IOC state
2595 * Returns all IOC Doorbell register bits if cooked==0, else just the
2596 * Doorbell bits in MPI_IOC_STATE_MASK.
2599 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2604 s = CHIPREG_READ32(&ioc->chip->Doorbell);
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(MYIOC_s_ERR_FMT "Can't get IOCFacts NOT READY! (%08x)\n",
2637 ioc->name, ioc->last_state );
2641 facts = &ioc->facts;
2643 /* Destination (reply area)... */
2644 reply_sz = sizeof(*facts);
2645 memset(facts, 0, reply_sz);
2647 /* Request area (get_facts on the stack right now!) */
2648 req_sz = sizeof(get_facts);
2649 memset(&get_facts, 0, req_sz);
2651 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2652 /* Assert: All other get_facts fields are zero! */
2654 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2655 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2656 ioc->name, req_sz, reply_sz));
2658 /* No non-zero fields in the get_facts request are greater than
2659 * 1 byte in size, so we can just fire it off as is.
2661 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2662 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2667 * Now byte swap (GRRR) the necessary fields before any further
2668 * inspection of reply contents.
2670 * But need to do some sanity checks on MsgLength (byte) field
2671 * to make sure we don't zero IOC's req_sz!
2673 /* Did we get a valid reply? */
2674 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2675 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2677 * If not been here, done that, save off first WhoInit value
2679 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2680 ioc->FirstWhoInit = facts->WhoInit;
2683 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2684 facts->MsgContext = le32_to_cpu(facts->MsgContext);
2685 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2686 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2687 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2688 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
2689 /* CHECKME! IOCStatus, IOCLogInfo */
2691 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2692 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2695 * FC f/w version changed between 1.1 and 1.2
2696 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2697 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2699 if (facts->MsgVersion < 0x0102) {
2701 * Handle old FC f/w style, convert to new...
2703 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2704 facts->FWVersion.Word =
2705 ((oldv<<12) & 0xFF000000) |
2706 ((oldv<<8) & 0x000FFF00);
2708 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2710 facts->ProductID = le16_to_cpu(facts->ProductID);
2711 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
2712 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
2713 ioc->ir_firmware = 1;
2714 facts->CurrentHostMfaHighAddr =
2715 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2716 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2717 facts->CurrentSenseBufferHighAddr =
2718 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2719 facts->CurReplyFrameSize =
2720 le16_to_cpu(facts->CurReplyFrameSize);
2721 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
2724 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2725 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2726 * to 14 in MPI-1.01.0x.
2728 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2729 facts->MsgVersion > 0x0100) {
2730 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2733 sz = facts->FWImageSize;
2738 facts->FWImageSize = sz;
2740 if (!facts->RequestFrameSize) {
2741 /* Something is wrong! */
2742 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2747 r = sz = facts->BlockSize;
2748 vv = ((63 / (sz * 4)) + 1) & 0x03;
2749 ioc->NB_for_64_byte_frame = vv;
2755 ioc->NBShiftFactor = shiftFactor;
2756 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2757 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2758 ioc->name, vv, shiftFactor, r));
2760 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2762 * Set values for this IOC's request & reply frame sizes,
2763 * and request & reply queue depths...
2765 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2766 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2767 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2768 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2770 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "reply_sz=%3d, reply_depth=%4d\n",
2771 ioc->name, ioc->reply_sz, ioc->reply_depth));
2772 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "req_sz =%3d, req_depth =%4d\n",
2773 ioc->name, ioc->req_sz, ioc->req_depth));
2775 /* Get port facts! */
2776 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2780 printk(MYIOC_s_ERR_FMT
2781 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2782 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2783 RequestFrameSize)/sizeof(u32)));
2790 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2792 * GetPortFacts - Send PortFacts request to MPT adapter.
2793 * @ioc: Pointer to MPT_ADAPTER structure
2794 * @portnum: Port number
2795 * @sleepFlag: Specifies whether the process can sleep
2797 * Returns 0 for success, non-zero for failure.
2800 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2802 PortFacts_t get_pfacts;
2803 PortFactsReply_t *pfacts;
2809 /* IOC *must* NOT be in RESET state! */
2810 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2811 printk(MYIOC_s_ERR_FMT "Can't get PortFacts NOT READY! (%08x)\n",
2812 ioc->name, ioc->last_state );
2816 pfacts = &ioc->pfacts[portnum];
2818 /* Destination (reply area)... */
2819 reply_sz = sizeof(*pfacts);
2820 memset(pfacts, 0, reply_sz);
2822 /* Request area (get_pfacts on the stack right now!) */
2823 req_sz = sizeof(get_pfacts);
2824 memset(&get_pfacts, 0, req_sz);
2826 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2827 get_pfacts.PortNumber = portnum;
2828 /* Assert: All other get_pfacts fields are zero! */
2830 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending get PortFacts(%d) request\n",
2831 ioc->name, portnum));
2833 /* No non-zero fields in the get_pfacts request are greater than
2834 * 1 byte in size, so we can just fire it off as is.
2836 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2837 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2841 /* Did we get a valid reply? */
2843 /* Now byte swap the necessary fields in the response. */
2844 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2845 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2846 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2847 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2848 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2849 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2850 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2851 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2852 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2854 max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
2856 ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
2857 ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
2860 * Place all the devices on channels
2864 if (mpt_channel_mapping) {
2865 ioc->devices_per_bus = 1;
2866 ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
2872 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2874 * SendIocInit - Send IOCInit request to MPT adapter.
2875 * @ioc: Pointer to MPT_ADAPTER structure
2876 * @sleepFlag: Specifies whether the process can sleep
2878 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2880 * Returns 0 for success, non-zero for failure.
2883 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2886 MPIDefaultReply_t init_reply;
2892 memset(&ioc_init, 0, sizeof(ioc_init));
2893 memset(&init_reply, 0, sizeof(init_reply));
2895 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2896 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2898 /* If we are in a recovery mode and we uploaded the FW image,
2899 * then this pointer is not NULL. Skip the upload a second time.
2900 * Set this flag if cached_fw set for either IOC.
2902 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
2906 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "upload_fw %d facts.Flags=%x\n",
2907 ioc->name, ioc->upload_fw, ioc->facts.Flags));
2909 ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
2910 ioc_init.MaxBuses = (U8)ioc->number_of_buses;
2911 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n",
2912 ioc->name, ioc->facts.MsgVersion));
2913 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
2914 // set MsgVersion and HeaderVersion host driver was built with
2915 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
2916 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
2918 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
2919 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
2920 } else if(mpt_host_page_alloc(ioc, &ioc_init))
2923 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
2925 if (sizeof(dma_addr_t) == sizeof(u64)) {
2926 /* Save the upper 32-bits of the request
2927 * (reply) and sense buffers.
2929 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
2930 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2932 /* Force 32-bit addressing */
2933 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
2934 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
2937 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
2938 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
2939 ioc->facts.MaxDevices = ioc_init.MaxDevices;
2940 ioc->facts.MaxBuses = ioc_init.MaxBuses;
2942 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOCInit (req @ %p)\n",
2943 ioc->name, &ioc_init));
2945 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
2946 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
2948 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
2952 /* No need to byte swap the multibyte fields in the reply
2953 * since we don't even look at its contents.
2956 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending PortEnable (req @ %p)\n",
2957 ioc->name, &ioc_init));
2959 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
2960 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
2964 /* YIKES! SUPER IMPORTANT!!!
2965 * Poll IocState until _OPERATIONAL while IOC is doing
2966 * LoopInit and TargetDiscovery!
2969 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
2970 state = mpt_GetIocState(ioc, 1);
2971 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
2972 if (sleepFlag == CAN_SLEEP) {
2979 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
2980 ioc->name, (int)((count+5)/HZ));
2984 state = mpt_GetIocState(ioc, 1);
2987 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wait IOC_OPERATIONAL state (cnt=%d)\n",
2990 ioc->aen_event_read_flag=0;
2994 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2996 * SendPortEnable - Send PortEnable request to MPT adapter port.
2997 * @ioc: Pointer to MPT_ADAPTER structure
2998 * @portnum: Port number to enable
2999 * @sleepFlag: Specifies whether the process can sleep
3001 * Send PortEnable to bring IOC to OPERATIONAL state.
3003 * Returns 0 for success, non-zero for failure.
3006 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3008 PortEnable_t port_enable;
3009 MPIDefaultReply_t reply_buf;
3014 /* Destination... */
3015 reply_sz = sizeof(MPIDefaultReply_t);
3016 memset(&reply_buf, 0, reply_sz);
3018 req_sz = sizeof(PortEnable_t);
3019 memset(&port_enable, 0, req_sz);
3021 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
3022 port_enable.PortNumber = portnum;
3023 /* port_enable.ChainOffset = 0; */
3024 /* port_enable.MsgFlags = 0; */
3025 /* port_enable.MsgContext = 0; */
3027 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Port(%d)Enable (req @ %p)\n",
3028 ioc->name, portnum, &port_enable));
3030 /* RAID FW may take a long time to enable
3032 if (ioc->ir_firmware || ioc->bus_type == SAS) {
3033 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3034 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3035 300 /*seconds*/, sleepFlag);
3037 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3038 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3039 30 /*seconds*/, sleepFlag);
3045 * mpt_alloc_fw_memory - allocate firmware memory
3046 * @ioc: Pointer to MPT_ADAPTER structure
3047 * @size: total FW bytes
3049 * If memory has already been allocated, the same (cached) value
3053 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
3056 return; /* use already allocated memory */
3057 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
3058 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
3059 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
3060 ioc->alloc_total += size;
3061 ioc->alt_ioc->alloc_total -= size;
3063 if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
3064 ioc->alloc_total += size;
3068 * mpt_free_fw_memory - free firmware memory
3069 * @ioc: Pointer to MPT_ADAPTER structure
3071 * If alt_img is NULL, delete from ioc structure.
3072 * Else, delete a secondary image in same format.
3075 mpt_free_fw_memory(MPT_ADAPTER *ioc)
3079 sz = ioc->facts.FWImageSize;
3080 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3081 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3082 pci_free_consistent(ioc->pcidev, sz, ioc->cached_fw, ioc->cached_fw_dma);
3083 ioc->cached_fw = NULL;
3089 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3091 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3092 * @ioc: Pointer to MPT_ADAPTER structure
3093 * @sleepFlag: Specifies whether the process can sleep
3095 * Returns 0 for success, >0 for handshake failure
3096 * <0 for fw upload failure.
3098 * Remark: If bound IOC and a successful FWUpload was performed
3099 * on the bound IOC, the second image is discarded
3100 * and memory is free'd. Both channels must upload to prevent
3101 * IOC from running in degraded mode.
3104 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3106 u8 request[ioc->req_sz];
3107 u8 reply[sizeof(FWUploadReply_t)];
3108 FWUpload_t *prequest;
3109 FWUploadReply_t *preply;
3110 FWUploadTCSGE_t *ptcsge;
3113 int ii, sz, reply_sz;
3116 /* If the image size is 0, we are done.
3118 if ((sz = ioc->facts.FWImageSize) == 0)
3121 mpt_alloc_fw_memory(ioc, sz);
3123 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3124 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3126 if (ioc->cached_fw == NULL) {
3132 prequest = (FWUpload_t *)&request;
3133 preply = (FWUploadReply_t *)&reply;
3135 /* Destination... */
3136 memset(prequest, 0, ioc->req_sz);
3138 reply_sz = sizeof(reply);
3139 memset(preply, 0, reply_sz);
3141 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
3142 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
3144 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
3145 ptcsge->DetailsLength = 12;
3146 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
3147 ptcsge->ImageSize = cpu_to_le32(sz);
3149 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
3151 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3152 mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma);
3154 sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
3155 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": Sending FW Upload (req @ %p) sgeoffset=%d \n",
3156 ioc->name, prequest, sgeoffset));
3157 DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest);
3159 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
3160 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
3162 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Upload completed rc=%x \n", ioc->name, ii));
3164 cmdStatus = -EFAULT;
3166 /* Handshake transfer was complete and successful.
3167 * Check the Reply Frame.
3169 int status, transfer_sz;
3170 status = le16_to_cpu(preply->IOCStatus);
3171 if (status == MPI_IOCSTATUS_SUCCESS) {
3172 transfer_sz = le32_to_cpu(preply->ActualImageSize);
3173 if (transfer_sz == sz)
3177 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n",
3178 ioc->name, cmdStatus));
3183 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": fw upload failed, freeing image \n",
3185 mpt_free_fw_memory(ioc);
3191 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3193 * mpt_downloadboot - DownloadBoot code
3194 * @ioc: Pointer to MPT_ADAPTER structure
3195 * @pFwHeader: Pointer to firmware header info
3196 * @sleepFlag: Specifies whether the process can sleep
3198 * FwDownloadBoot requires Programmed IO access.
3200 * Returns 0 for success
3201 * -1 FW Image size is 0
3202 * -2 No valid cached_fw Pointer
3203 * <0 for fw upload failure.
3206 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3208 MpiExtImageHeader_t *pExtImage;
3218 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3219 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
3221 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3222 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3223 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3224 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3225 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3226 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3228 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
3231 if (sleepFlag == CAN_SLEEP) {
3237 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3238 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3240 for (count = 0; count < 30; count ++) {
3241 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3242 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3243 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESET_ADAPTER cleared, count=%d\n",
3248 if (sleepFlag == CAN_SLEEP) {
3255 if ( count == 30 ) {
3256 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot failed! "
3257 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3258 ioc->name, diag0val));
3262 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3263 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3264 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3265 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3266 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3267 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3269 /* Set the DiagRwEn and Disable ARM bits */
3270 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3272 fwSize = (pFwHeader->ImageSize + 3)/4;
3273 ptrFw = (u32 *) pFwHeader;
3275 /* Write the LoadStartAddress to the DiagRw Address Register
3276 * using Programmed IO
3278 if (ioc->errata_flag_1064)
3279 pci_enable_io_access(ioc->pcidev);
3281 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3282 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "LoadStart addr written 0x%x \n",
3283 ioc->name, pFwHeader->LoadStartAddress));
3285 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write FW Image: 0x%x bytes @ %p\n",
3286 ioc->name, fwSize*4, ptrFw));
3288 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3291 nextImage = pFwHeader->NextImageHeaderOffset;
3293 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3295 load_addr = pExtImage->LoadStartAddress;
3297 fwSize = (pExtImage->ImageSize + 3) >> 2;
3298 ptrFw = (u32 *)pExtImage;
3300 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3301 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3302 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3305 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3307 nextImage = pExtImage->NextImageHeaderOffset;
3310 /* Write the IopResetVectorRegAddr */
3311 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
3312 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3314 /* Write the IopResetVectorValue */
3315 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3316 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3318 /* Clear the internal flash bad bit - autoincrementing register,
3319 * so must do two writes.
3321 if (ioc->bus_type == SPI) {
3323 * 1030 and 1035 H/W errata, workaround to access
3324 * the ClearFlashBadSignatureBit
3326 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3327 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3328 diagRwData |= 0x40000000;
3329 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3330 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3332 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3333 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3334 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3335 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3338 if (sleepFlag == CAN_SLEEP) {
3345 if (ioc->errata_flag_1064)
3346 pci_disable_io_access(ioc->pcidev);
3348 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3349 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot diag0val=%x, "
3350 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3351 ioc->name, diag0val));
3352 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3353 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot now diag0val=%x\n",
3354 ioc->name, diag0val));
3355 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3357 /* Write 0xFF to reset the sequencer */
3358 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3360 if (ioc->bus_type == SAS) {
3361 ioc_state = mpt_GetIocState(ioc, 0);
3362 if ( (GetIocFacts(ioc, sleepFlag,
3363 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3364 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "GetIocFacts failed: IocState=%x\n",
3365 ioc->name, ioc_state));
3370 for (count=0; count<HZ*20; count++) {
3371 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3372 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3373 "downloadboot successful! (count=%d) IocState=%x\n",
3374 ioc->name, count, ioc_state));
3375 if (ioc->bus_type == SAS) {
3378 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3379 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3380 "downloadboot: SendIocInit failed\n",
3384 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3385 "downloadboot: SendIocInit successful\n",
3389 if (sleepFlag == CAN_SLEEP) {
3395 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3396 "downloadboot failed! IocState=%x\n",ioc->name, ioc_state));
3400 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3402 * KickStart - Perform hard reset of MPT adapter.
3403 * @ioc: Pointer to MPT_ADAPTER structure
3404 * @force: Force hard reset
3405 * @sleepFlag: Specifies whether the process can sleep
3407 * This routine places MPT adapter in diagnostic mode via the
3408 * WriteSequence register, and then performs a hard reset of adapter
3409 * via the Diagnostic register.
3411 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3412 * or NO_SLEEP (interrupt thread, use mdelay)
3413 * force - 1 if doorbell active, board fault state
3414 * board operational, IOC_RECOVERY or
3415 * IOC_BRINGUP and there is an alt_ioc.
3419 * 1 - hard reset, READY
3420 * 0 - no reset due to History bit, READY
3421 * -1 - no reset due to History bit but not READY
3422 * OR reset but failed to come READY
3423 * -2 - no reset, could not enter DIAG mode
3424 * -3 - reset but bad FW bit
3427 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3429 int hard_reset_done = 0;
3433 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStarting!\n", ioc->name));
3434 if (ioc->bus_type == SPI) {
3435 /* Always issue a Msg Unit Reset first. This will clear some
3436 * SCSI bus hang conditions.
3438 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3440 if (sleepFlag == CAN_SLEEP) {
3447 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3448 if (hard_reset_done < 0)
3449 return hard_reset_done;
3451 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n",
3454 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3455 for (cnt=0; cnt<cntdn; cnt++) {
3456 ioc_state = mpt_GetIocState(ioc, 1);
3457 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3458 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStart successful! (cnt=%d)\n",
3460 return hard_reset_done;
3462 if (sleepFlag == CAN_SLEEP) {
3469 dinitprintk(ioc, printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3470 ioc->name, mpt_GetIocState(ioc, 0)));
3474 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3476 * mpt_diag_reset - Perform hard reset of the adapter.
3477 * @ioc: Pointer to MPT_ADAPTER structure
3478 * @ignore: Set if to honor and clear to ignore
3479 * the reset history bit
3480 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3481 * else set to NO_SLEEP (use mdelay instead)
3483 * This routine places the adapter in diagnostic mode via the
3484 * WriteSequence register and then performs a hard reset of adapter
3485 * via the Diagnostic register. Adapter should be in ready state
3486 * upon successful completion.
3488 * Returns: 1 hard reset successful
3489 * 0 no reset performed because reset history bit set
3490 * -2 enabling diagnostic mode failed
3491 * -3 diagnostic reset failed
3494 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3496 MPT_ADAPTER *iocp=NULL;
3499 int hard_reset_done = 0;
3503 /* Clear any existing interrupts */
3504 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3506 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3507 drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3508 "address=%p\n", ioc->name, __FUNCTION__,
3509 &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3510 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3511 if (sleepFlag == CAN_SLEEP)
3516 for (count = 0; count < 60; count ++) {
3517 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3518 doorbell &= MPI_IOC_STATE_MASK;
3520 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3521 "looking for READY STATE: doorbell=%x"
3523 ioc->name, doorbell, count));
3524 if (doorbell == MPI_IOC_STATE_READY) {
3529 if (sleepFlag == CAN_SLEEP)
3537 /* Use "Diagnostic reset" method! (only thing available!) */
3538 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3540 if (ioc->debug_level & MPT_DEBUG) {
3542 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3543 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3544 ioc->name, diag0val, diag1val));
3547 /* Do the reset if we are told to ignore the reset history
3548 * or if the reset history is 0
3550 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3551 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3552 /* Write magic sequence to WriteSequence register
3553 * Loop until in diagnostic mode
3555 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3556 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3557 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3558 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3559 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3560 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3563 if (sleepFlag == CAN_SLEEP) {
3571 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3572 ioc->name, diag0val);
3577 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3579 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3580 ioc->name, diag0val));
3583 if (ioc->debug_level & MPT_DEBUG) {
3585 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3586 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3587 ioc->name, diag0val, diag1val));
3590 * Disable the ARM (Bug fix)
3593 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3597 * Now hit the reset bit in the Diagnostic register
3598 * (THE BIG HAMMER!) (Clears DRWE bit).
3600 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3601 hard_reset_done = 1;
3602 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset performed\n",
3606 * Call each currently registered protocol IOC reset handler
3607 * with pre-reset indication.
3608 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3609 * MptResetHandlers[] registered yet.
3615 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
3616 if (MptResetHandlers[cb_idx]) {
3617 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3618 "Calling IOC pre_reset handler #%d\n",
3619 ioc->name, cb_idx));
3620 r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET);
3622 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3623 "Calling alt-%s pre_reset handler #%d\n",
3624 ioc->name, ioc->alt_ioc->name, cb_idx));
3625 r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_PRE_RESET);
3629 /* FIXME? Examine results here? */
3634 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
3635 iocp = ioc->alt_ioc;
3637 /* If the DownloadBoot operation fails, the
3638 * IOC will be left unusable. This is a fatal error
3639 * case. _diag_reset will return < 0
3641 for (count = 0; count < 30; count ++) {
3642 diag0val = CHIPREG_READ32(&iocp->chip->Diagnostic);
3643 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3647 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n",
3648 iocp->name, diag0val, count));
3650 if (sleepFlag == CAN_SLEEP) {
3656 if ((count = mpt_downloadboot(ioc,
3657 (MpiFwHeader_t *)iocp->cached_fw, sleepFlag)) < 0) {
3658 printk(MYIOC_s_WARN_FMT
3659 "firmware downloadboot failure (%d)!\n", ioc->name, count);
3663 /* Wait for FW to reload and for board
3664 * to go to the READY state.
3665 * Maximum wait is 60 seconds.
3666 * If fail, no error will check again
3667 * with calling program.
3669 for (count = 0; count < 60; count ++) {
3670 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3671 doorbell &= MPI_IOC_STATE_MASK;
3673 if (doorbell == MPI_IOC_STATE_READY) {
3678 if (sleepFlag == CAN_SLEEP) {
3687 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3688 if (ioc->debug_level & MPT_DEBUG) {
3690 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3691 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3692 ioc->name, diag0val, diag1val));
3695 /* Clear RESET_HISTORY bit! Place board in the
3696 * diagnostic mode to update the diag register.
3698 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3700 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3701 /* Write magic sequence to WriteSequence register
3702 * Loop until in diagnostic mode
3704 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3705 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3706 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3707 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3708 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3709 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3712 if (sleepFlag == CAN_SLEEP) {
3720 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3721 ioc->name, diag0val);
3724 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3726 diag0val &= ~MPI_DIAG_RESET_HISTORY;
3727 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3728 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3729 if (diag0val & MPI_DIAG_RESET_HISTORY) {
3730 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3734 /* Disable Diagnostic Mode
3736 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3738 /* Check FW reload status flags.
3740 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3741 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3742 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3743 ioc->name, diag0val);
3747 if (ioc->debug_level & MPT_DEBUG) {
3749 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3750 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3751 ioc->name, diag0val, diag1val));
3755 * Reset flag that says we've enabled event notification
3757 ioc->facts.EventState = 0;
3760 ioc->alt_ioc->facts.EventState = 0;
3762 return hard_reset_done;
3765 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3767 * SendIocReset - Send IOCReset request to MPT adapter.
3768 * @ioc: Pointer to MPT_ADAPTER structure
3769 * @reset_type: reset type, expected values are
3770 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3771 * @sleepFlag: Specifies whether the process can sleep
3773 * Send IOCReset request to the MPT adapter.
3775 * Returns 0 for success, non-zero for failure.
3778 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3784 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOC reset(0x%02x)!\n",
3785 ioc->name, reset_type));
3786 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3787 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3790 /* FW ACK'd request, wait for READY state
3793 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
3795 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3799 if (sleepFlag != CAN_SLEEP)
3802 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
3803 ioc->name, (int)((count+5)/HZ));
3807 if (sleepFlag == CAN_SLEEP) {
3810 mdelay (1); /* 1 msec delay */
3815 * Cleanup all event stuff for this IOC; re-issue EventNotification
3816 * request if needed.
3818 if (ioc->facts.Function)
3819 ioc->facts.EventState = 0;
3824 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3826 * initChainBuffers - Allocate memory for and initialize chain buffers
3827 * @ioc: Pointer to MPT_ADAPTER structure
3829 * Allocates memory for and initializes chain buffers,
3830 * chain buffer control arrays and spinlock.
3833 initChainBuffers(MPT_ADAPTER *ioc)
3836 int sz, ii, num_chain;
3837 int scale, num_sge, numSGE;
3839 /* ReqToChain size must equal the req_depth
3842 if (ioc->ReqToChain == NULL) {
3843 sz = ioc->req_depth * sizeof(int);
3844 mem = kmalloc(sz, GFP_ATOMIC);
3848 ioc->ReqToChain = (int *) mem;
3849 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReqToChain alloc @ %p, sz=%d bytes\n",
3850 ioc->name, mem, sz));
3851 mem = kmalloc(sz, GFP_ATOMIC);
3855 ioc->RequestNB = (int *) mem;
3856 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestNB alloc @ %p, sz=%d bytes\n",
3857 ioc->name, mem, sz));
3859 for (ii = 0; ii < ioc->req_depth; ii++) {
3860 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
3863 /* ChainToChain size must equal the total number
3864 * of chain buffers to be allocated.
3867 * Calculate the number of chain buffers needed(plus 1) per I/O
3868 * then multiply the maximum number of simultaneous cmds
3870 * num_sge = num sge in request frame + last chain buffer
3871 * scale = num sge per chain buffer if no chain element
3873 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3874 if (sizeof(dma_addr_t) == sizeof(u64))
3875 num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3877 num_sge = 1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3879 if (sizeof(dma_addr_t) == sizeof(u64)) {
3880 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3881 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3883 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3884 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3886 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n",
3887 ioc->name, num_sge, numSGE));
3889 if ( numSGE > MPT_SCSI_SG_DEPTH )
3890 numSGE = MPT_SCSI_SG_DEPTH;
3893 while (numSGE - num_sge > 0) {
3895 num_sge += (scale - 1);
3899 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Now numSGE=%d num_sge=%d num_chain=%d\n",
3900 ioc->name, numSGE, num_sge, num_chain));
3902 if (ioc->bus_type == SPI)
3903 num_chain *= MPT_SCSI_CAN_QUEUE;
3905 num_chain *= MPT_FC_CAN_QUEUE;
3907 ioc->num_chain = num_chain;
3909 sz = num_chain * sizeof(int);
3910 if (ioc->ChainToChain == NULL) {
3911 mem = kmalloc(sz, GFP_ATOMIC);
3915 ioc->ChainToChain = (int *) mem;
3916 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainToChain alloc @ %p, sz=%d bytes\n",
3917 ioc->name, mem, sz));
3919 mem = (u8 *) ioc->ChainToChain;
3921 memset(mem, 0xFF, sz);
3925 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3927 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
3928 * @ioc: Pointer to MPT_ADAPTER structure
3930 * This routine allocates memory for the MPT reply and request frame
3931 * pools (if necessary), and primes the IOC reply FIFO with
3934 * Returns 0 for success, non-zero for failure.
3937 PrimeIocFifos(MPT_ADAPTER *ioc)
3940 unsigned long flags;
3941 dma_addr_t alloc_dma;
3943 int i, reply_sz, sz, total_size, num_chain;
3945 /* Prime reply FIFO... */
3947 if (ioc->reply_frames == NULL) {
3948 if ( (num_chain = initChainBuffers(ioc)) < 0)
3951 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
3952 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
3953 ioc->name, ioc->reply_sz, ioc->reply_depth));
3954 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d[%x] bytes\n",
3955 ioc->name, reply_sz, reply_sz));
3957 sz = (ioc->req_sz * ioc->req_depth);
3958 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d bytes, RequestDepth=%d\n",
3959 ioc->name, ioc->req_sz, ioc->req_depth));
3960 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d[%x] bytes\n",
3961 ioc->name, sz, sz));
3964 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
3965 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d bytes, ChainDepth=%d\n",
3966 ioc->name, ioc->req_sz, num_chain));
3967 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
3968 ioc->name, sz, sz, num_chain));
3971 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
3973 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
3978 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Total alloc @ %p[%p], sz=%d[%x] bytes\n",
3979 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
3981 memset(mem, 0, total_size);
3982 ioc->alloc_total += total_size;
3984 ioc->alloc_dma = alloc_dma;
3985 ioc->alloc_sz = total_size;
3986 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
3987 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3989 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
3990 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3992 alloc_dma += reply_sz;
3995 /* Request FIFO - WE manage this! */
3997 ioc->req_frames = (MPT_FRAME_HDR *) mem;
3998 ioc->req_frames_dma = alloc_dma;
4000 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffers @ %p[%p]\n",
4001 ioc->name, mem, (void *)(ulong)alloc_dma));
4003 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4005 #if defined(CONFIG_MTRR) && 0
4007 * Enable Write Combining MTRR for IOC's memory region.
4008 * (at least as much as we can; "size and base must be
4009 * multiples of 4 kiB"
4011 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
4013 MTRR_TYPE_WRCOMB, 1);
4014 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MTRR region registered (base:size=%08x:%x)\n",
4015 ioc->name, ioc->req_frames_dma, sz));
4018 for (i = 0; i < ioc->req_depth; i++) {
4019 alloc_dma += ioc->req_sz;
4023 ioc->ChainBuffer = mem;
4024 ioc->ChainBufferDMA = alloc_dma;
4026 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffers @ %p(%p)\n",
4027 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
4029 /* Initialize the free chain Q.
4032 INIT_LIST_HEAD(&ioc->FreeChainQ);
4034 /* Post the chain buffers to the FreeChainQ.
4036 mem = (u8 *)ioc->ChainBuffer;
4037 for (i=0; i < num_chain; i++) {
4038 mf = (MPT_FRAME_HDR *) mem;
4039 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
4043 /* Initialize Request frames linked list
4045 alloc_dma = ioc->req_frames_dma;
4046 mem = (u8 *) ioc->req_frames;
4048 spin_lock_irqsave(&ioc->FreeQlock, flags);
4049 INIT_LIST_HEAD(&ioc->FreeQ);
4050 for (i = 0; i < ioc->req_depth; i++) {
4051 mf = (MPT_FRAME_HDR *) mem;
4053 /* Queue REQUESTs *internally*! */
4054 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
4058 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4060 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4061 ioc->sense_buf_pool =
4062 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
4063 if (ioc->sense_buf_pool == NULL) {
4064 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
4069 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
4070 ioc->alloc_total += sz;
4071 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SenseBuffers @ %p[%p]\n",
4072 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
4076 /* Post Reply frames to FIFO
4078 alloc_dma = ioc->alloc_dma;
4079 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4080 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4082 for (i = 0; i < ioc->reply_depth; i++) {
4083 /* Write each address to the IOC! */
4084 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
4085 alloc_dma += ioc->reply_sz;
4091 if (ioc->alloc != NULL) {
4093 pci_free_consistent(ioc->pcidev,
4095 ioc->alloc, ioc->alloc_dma);
4096 ioc->reply_frames = NULL;
4097 ioc->req_frames = NULL;
4098 ioc->alloc_total -= sz;
4100 if (ioc->sense_buf_pool != NULL) {
4101 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4102 pci_free_consistent(ioc->pcidev,
4104 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
4105 ioc->sense_buf_pool = NULL;
4110 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4112 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4113 * from IOC via doorbell handshake method.
4114 * @ioc: Pointer to MPT_ADAPTER structure
4115 * @reqBytes: Size of the request in bytes
4116 * @req: Pointer to MPT request frame
4117 * @replyBytes: Expected size of the reply in bytes
4118 * @u16reply: Pointer to area where reply should be written
4119 * @maxwait: Max wait time for a reply (in seconds)
4120 * @sleepFlag: Specifies whether the process can sleep
4122 * NOTES: It is the callers responsibility to byte-swap fields in the
4123 * request which are greater than 1 byte in size. It is also the
4124 * callers responsibility to byte-swap response fields which are
4125 * greater than 1 byte in size.
4127 * Returns 0 for success, non-zero for failure.
4130 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
4131 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
4133 MPIDefaultReply_t *mptReply;
4138 * Get ready to cache a handshake reply
4140 ioc->hs_reply_idx = 0;
4141 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4142 mptReply->MsgLength = 0;
4145 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4146 * then tell IOC that we want to handshake a request of N words.
4147 * (WRITE u32val to Doorbell reg).
4149 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4150 CHIPREG_WRITE32(&ioc->chip->Doorbell,
4151 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
4152 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
4155 * Wait for IOC's doorbell handshake int
4157 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4160 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4161 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4163 /* Read doorbell and check for active bit */
4164 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
4168 * Clear doorbell int (WRITE 0 to IntStatus reg),
4169 * then wait for IOC to ACKnowledge that it's ready for
4170 * our handshake request.
4172 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4173 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4178 u8 *req_as_bytes = (u8 *) req;
4181 * Stuff request words via doorbell handshake,
4182 * with ACK from IOC for each.
4184 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
4185 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
4186 (req_as_bytes[(ii*4) + 1] << 8) |
4187 (req_as_bytes[(ii*4) + 2] << 16) |
4188 (req_as_bytes[(ii*4) + 3] << 24));
4190 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
4191 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4195 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req));
4196 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req);
4198 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n",
4199 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
4202 * Wait for completion of doorbell handshake reply from the IOC
4204 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
4207 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake reply count=%d%s\n",
4208 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
4211 * Copy out the cached reply...
4213 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
4214 u16reply[ii] = ioc->hs_reply[ii];
4222 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4224 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4225 * @ioc: Pointer to MPT_ADAPTER structure
4226 * @howlong: How long to wait (in seconds)
4227 * @sleepFlag: Specifies whether the process can sleep
4229 * This routine waits (up to ~2 seconds max) for IOC doorbell
4230 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4231 * bit in its IntStatus register being clear.
4233 * Returns a negative value on failure, else wait loop count.
4236 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4242 cntdn = 1000 * howlong;
4244 if (sleepFlag == CAN_SLEEP) {
4247 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4248 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4255 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4256 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4263 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell ACK (count=%d)\n",
4268 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4269 ioc->name, count, intstat);
4273 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4275 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4276 * @ioc: Pointer to MPT_ADAPTER structure
4277 * @howlong: How long to wait (in seconds)
4278 * @sleepFlag: Specifies whether the process can sleep
4280 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4281 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4283 * Returns a negative value on failure, else wait loop count.
4286 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4292 cntdn = 1000 * howlong;
4293 if (sleepFlag == CAN_SLEEP) {
4295 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4296 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4303 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4304 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4312 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4313 ioc->name, count, howlong));
4317 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4318 ioc->name, count, intstat);
4322 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4324 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4325 * @ioc: Pointer to MPT_ADAPTER structure
4326 * @howlong: How long to wait (in seconds)
4327 * @sleepFlag: Specifies whether the process can sleep
4329 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4330 * Reply is cached to IOC private area large enough to hold a maximum
4331 * of 128 bytes of reply data.
4333 * Returns a negative value on failure, else size of reply in WORDS.
4336 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4341 u16 *hs_reply = ioc->hs_reply;
4342 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4345 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4348 * Get first two u16's so we can look at IOC's intended reply MsgLength
4351 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4354 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4355 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4356 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4359 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4360 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4364 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4365 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4366 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4369 * If no error (and IOC said MsgLength is > 0), piece together
4370 * reply 16 bits at a time.
4372 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4373 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4375 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4376 /* don't overflow our IOC hs_reply[] buffer! */
4377 if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
4378 hs_reply[u16cnt] = hword;
4379 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4382 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4384 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4387 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4392 else if (u16cnt != (2 * mptReply->MsgLength)) {
4395 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4400 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name));
4401 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply);
4403 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4404 ioc->name, t, u16cnt/2));
4408 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4410 * GetLanConfigPages - Fetch LANConfig pages.
4411 * @ioc: Pointer to MPT_ADAPTER structure
4413 * Return: 0 for success
4414 * -ENOMEM if no memory available
4415 * -EPERM if not allowed due to ISR context
4416 * -EAGAIN if no msg frames currently available
4417 * -EFAULT for non-successful reply or no reply (timeout)
4420 GetLanConfigPages(MPT_ADAPTER *ioc)
4422 ConfigPageHeader_t hdr;
4424 LANPage0_t *ppage0_alloc;
4425 dma_addr_t page0_dma;
4426 LANPage1_t *ppage1_alloc;
4427 dma_addr_t page1_dma;
4432 /* Get LAN Page 0 header */
4433 hdr.PageVersion = 0;
4436 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4437 cfg.cfghdr.hdr = &hdr;
4439 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4444 if ((rc = mpt_config(ioc, &cfg)) != 0)
4447 if (hdr.PageLength > 0) {
4448 data_sz = hdr.PageLength * 4;
4449 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4452 memset((u8 *)ppage0_alloc, 0, data_sz);
4453 cfg.physAddr = page0_dma;
4454 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4456 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4458 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4459 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4463 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4466 * Normalize endianness of structure data,
4467 * by byte-swapping all > 1 byte fields!
4476 /* Get LAN Page 1 header */
4477 hdr.PageVersion = 0;
4480 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4481 cfg.cfghdr.hdr = &hdr;
4483 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4487 if ((rc = mpt_config(ioc, &cfg)) != 0)
4490 if (hdr.PageLength == 0)
4493 data_sz = hdr.PageLength * 4;
4495 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4497 memset((u8 *)ppage1_alloc, 0, data_sz);
4498 cfg.physAddr = page1_dma;
4499 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4501 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4503 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4504 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4507 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4510 * Normalize endianness of structure data,
4511 * by byte-swapping all > 1 byte fields!
4519 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4521 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
4522 * @ioc: Pointer to MPT_ADAPTER structure
4523 * @persist_opcode: see below
4525 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4526 * devices not currently present.
4527 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4529 * NOTE: Don't use not this function during interrupt time.
4531 * Returns 0 for success, non-zero error
4534 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4536 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4538 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
4539 SasIoUnitControlReply_t *sasIoUnitCntrReply;
4540 MPT_FRAME_HDR *mf = NULL;
4541 MPIHeader_t *mpi_hdr;
4544 /* insure garbage is not sent to fw */
4545 switch(persist_opcode) {
4547 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
4548 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
4556 printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode);
4558 /* Get a MF for this command.
4560 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4561 printk("%s: no msg frames!\n",__FUNCTION__);
4565 mpi_hdr = (MPIHeader_t *) mf;
4566 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
4567 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
4568 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
4569 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
4570 sasIoUnitCntrReq->Operation = persist_opcode;
4572 init_timer(&ioc->persist_timer);
4573 ioc->persist_timer.data = (unsigned long) ioc;
4574 ioc->persist_timer.function = mpt_timer_expired;
4575 ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
4576 ioc->persist_wait_done=0;
4577 add_timer(&ioc->persist_timer);
4578 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4579 wait_event(mpt_waitq, ioc->persist_wait_done);
4581 sasIoUnitCntrReply =
4582 (SasIoUnitControlReply_t *)ioc->persist_reply_frame;
4583 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
4584 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4586 sasIoUnitCntrReply->IOCStatus,
4587 sasIoUnitCntrReply->IOCLogInfo);
4591 printk("%s: success\n",__FUNCTION__);
4595 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4598 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
4599 MpiEventDataRaid_t * pRaidEventData)
4608 volume = pRaidEventData->VolumeID;
4609 reason = pRaidEventData->ReasonCode;
4610 disk = pRaidEventData->PhysDiskNum;
4611 status = le32_to_cpu(pRaidEventData->SettingsStatus);
4612 flags = (status >> 0) & 0xff;
4613 state = (status >> 8) & 0xff;
4615 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
4619 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
4620 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
4621 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
4622 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
4623 ioc->name, disk, volume);
4625 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
4630 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4631 printk(MYIOC_s_INFO_FMT " volume has been created\n",
4635 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4637 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
4641 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
4642 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
4646 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4647 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
4649 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
4651 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
4653 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
4656 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
4658 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
4659 ? ", quiesced" : "",
4660 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
4661 ? ", resync in progress" : "" );
4664 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
4665 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
4669 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4670 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
4674 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4675 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
4679 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
4680 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
4684 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4685 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
4687 state == MPI_PHYSDISK0_STATUS_ONLINE
4689 : state == MPI_PHYSDISK0_STATUS_MISSING
4691 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
4693 : state == MPI_PHYSDISK0_STATUS_FAILED
4695 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
4697 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
4698 ? "offline requested"
4699 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
4700 ? "failed requested"
4701 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
4704 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
4705 ? ", out of sync" : "",
4706 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
4707 ? ", quiesced" : "" );
4710 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
4711 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
4715 case MPI_EVENT_RAID_RC_SMART_DATA:
4716 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
4717 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
4720 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
4721 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
4727 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4729 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4730 * @ioc: Pointer to MPT_ADAPTER structure
4732 * Returns: 0 for success
4733 * -ENOMEM if no memory available
4734 * -EPERM if not allowed due to ISR context
4735 * -EAGAIN if no msg frames currently available
4736 * -EFAULT for non-successful reply or no reply (timeout)
4739 GetIoUnitPage2(MPT_ADAPTER *ioc)
4741 ConfigPageHeader_t hdr;
4743 IOUnitPage2_t *ppage_alloc;
4744 dma_addr_t page_dma;
4748 /* Get the page header */
4749 hdr.PageVersion = 0;
4752 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4753 cfg.cfghdr.hdr = &hdr;
4755 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4760 if ((rc = mpt_config(ioc, &cfg)) != 0)
4763 if (hdr.PageLength == 0)
4766 /* Read the config page */
4767 data_sz = hdr.PageLength * 4;
4769 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4771 memset((u8 *)ppage_alloc, 0, data_sz);
4772 cfg.physAddr = page_dma;
4773 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4775 /* If Good, save data */
4776 if ((rc = mpt_config(ioc, &cfg)) == 0)
4777 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4779 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4785 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4787 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4788 * @ioc: Pointer to a Adapter Strucutre
4789 * @portnum: IOC port number
4791 * Return: -EFAULT if read of config page header fails
4793 * If read of SCSI Port Page 0 fails,
4794 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4795 * Adapter settings: async, narrow
4797 * If read of SCSI Port Page 2 fails,
4798 * Adapter settings valid
4799 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4804 * CHECK - what type of locking mechanisms should be used????
4807 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4812 ConfigPageHeader_t header;
4818 if (!ioc->spi_data.nvram) {
4821 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4822 mem = kmalloc(sz, GFP_ATOMIC);
4826 ioc->spi_data.nvram = (int *) mem;
4828 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4829 ioc->name, ioc->spi_data.nvram, sz));
4832 /* Invalidate NVRAM information
4834 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4835 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4838 /* Read SPP0 header, allocate memory, then read page.
4840 header.PageVersion = 0;
4841 header.PageLength = 0;
4842 header.PageNumber = 0;
4843 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4844 cfg.cfghdr.hdr = &header;
4846 cfg.pageAddr = portnum;
4847 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4849 cfg.timeout = 0; /* use default */
4850 if (mpt_config(ioc, &cfg) != 0)
4853 if (header.PageLength > 0) {
4854 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4856 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4857 cfg.physAddr = buf_dma;
4858 if (mpt_config(ioc, &cfg) != 0) {
4859 ioc->spi_data.maxBusWidth = MPT_NARROW;
4860 ioc->spi_data.maxSyncOffset = 0;
4861 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4862 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4864 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4865 "Unable to read PortPage0 minSyncFactor=%x\n",
4866 ioc->name, ioc->spi_data.minSyncFactor));
4868 /* Save the Port Page 0 data
4870 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
4871 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4872 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4874 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
4875 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4876 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4877 "noQas due to Capabilities=%x\n",
4878 ioc->name, pPP0->Capabilities));
4880 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4881 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4883 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4884 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4885 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4886 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4887 "PortPage0 minSyncFactor=%x\n",
4888 ioc->name, ioc->spi_data.minSyncFactor));
4890 ioc->spi_data.maxSyncOffset = 0;
4891 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4894 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4896 /* Update the minSyncFactor based on bus type.
4898 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4899 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
4901 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
4902 ioc->spi_data.minSyncFactor = MPT_ULTRA;
4903 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4904 "HVD or SE detected, minSyncFactor=%x\n",
4905 ioc->name, ioc->spi_data.minSyncFactor));
4910 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4915 /* SCSI Port Page 2 - Read the header then the page.
4917 header.PageVersion = 0;
4918 header.PageLength = 0;
4919 header.PageNumber = 2;
4920 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4921 cfg.cfghdr.hdr = &header;
4923 cfg.pageAddr = portnum;
4924 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4926 if (mpt_config(ioc, &cfg) != 0)
4929 if (header.PageLength > 0) {
4930 /* Allocate memory and read SCSI Port Page 2
4932 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4934 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
4935 cfg.physAddr = buf_dma;
4936 if (mpt_config(ioc, &cfg) != 0) {
4937 /* Nvram data is left with INVALID mark
4940 } else if (ioc->pcidev->vendor == PCI_VENDOR_ID_ATTO) {
4942 /* This is an ATTO adapter, read Page2 accordingly
4944 ATTO_SCSIPortPage2_t *pPP2 = (ATTO_SCSIPortPage2_t *) pbuf;
4945 ATTODeviceInfo_t *pdevice = NULL;
4948 /* Save the Port Page 2 data
4949 * (reformat into a 32bit quantity)
4951 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4952 pdevice = &pPP2->DeviceSettings[ii];
4953 ATTOFlags = le16_to_cpu(pdevice->ATTOFlags);
4956 /* Translate ATTO device flags to LSI format
4958 if (ATTOFlags & ATTOFLAG_DISC)
4959 data |= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE);
4960 if (ATTOFlags & ATTOFLAG_ID_ENB)
4961 data |= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE);
4962 if (ATTOFlags & ATTOFLAG_LUN_ENB)
4963 data |= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE);
4964 if (ATTOFlags & ATTOFLAG_TAGGED)
4965 data |= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE);
4966 if (!(ATTOFlags & ATTOFLAG_WIDE_ENB))
4967 data |= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE);
4969 data = (data << 16) | (pdevice->Period << 8) | 10;
4970 ioc->spi_data.nvram[ii] = data;
4973 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
4974 MpiDeviceInfo_t *pdevice = NULL;
4977 * Save "Set to Avoid SCSI Bus Resets" flag
4979 ioc->spi_data.bus_reset =
4980 (le32_to_cpu(pPP2->PortFlags) &
4981 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
4984 /* Save the Port Page 2 data
4985 * (reformat into a 32bit quantity)
4987 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
4988 ioc->spi_data.PortFlags = data;
4989 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4990 pdevice = &pPP2->DeviceSettings[ii];
4991 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
4992 (pdevice->SyncFactor << 8) | pdevice->Timeout;
4993 ioc->spi_data.nvram[ii] = data;
4997 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5001 /* Update Adapter limits with those from NVRAM
5002 * Comment: Don't need to do this. Target performance
5003 * parameters will never exceed the adapters limits.
5009 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5011 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
5012 * @ioc: Pointer to a Adapter Strucutre
5013 * @portnum: IOC port number
5015 * Return: -EFAULT if read of config page header fails
5019 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
5022 ConfigPageHeader_t header;
5024 /* Read the SCSI Device Page 1 header
5026 header.PageVersion = 0;
5027 header.PageLength = 0;
5028 header.PageNumber = 1;
5029 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5030 cfg.cfghdr.hdr = &header;
5032 cfg.pageAddr = portnum;
5033 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5036 if (mpt_config(ioc, &cfg) != 0)
5039 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
5040 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
5042 header.PageVersion = 0;
5043 header.PageLength = 0;
5044 header.PageNumber = 0;
5045 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5046 if (mpt_config(ioc, &cfg) != 0)
5049 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
5050 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
5052 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 0: version %d length %d\n",
5053 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
5055 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 1: version %d length %d\n",
5056 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
5061 * mpt_inactive_raid_list_free - This clears this link list.
5062 * @ioc : pointer to per adapter structure
5065 mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
5067 struct inactive_raid_component_info *component_info, *pNext;
5069 if (list_empty(&ioc->raid_data.inactive_list))
5072 down(&ioc->raid_data.inactive_list_mutex);
5073 list_for_each_entry_safe(component_info, pNext,
5074 &ioc->raid_data.inactive_list, list) {
5075 list_del(&component_info->list);
5076 kfree(component_info);
5078 up(&ioc->raid_data.inactive_list_mutex);
5082 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5084 * @ioc : pointer to per adapter structure
5085 * @channel : volume channel
5086 * @id : volume target id
5089 mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
5092 ConfigPageHeader_t hdr;
5093 dma_addr_t dma_handle;
5094 pRaidVolumePage0_t buffer = NULL;
5096 RaidPhysDiskPage0_t phys_disk;
5097 struct inactive_raid_component_info *component_info;
5098 int handle_inactive_volumes;
5100 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5101 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5102 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
5103 cfg.pageAddr = (channel << 8) + id;
5104 cfg.cfghdr.hdr = &hdr;
5105 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5107 if (mpt_config(ioc, &cfg) != 0)
5110 if (!hdr.PageLength)
5113 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5119 cfg.physAddr = dma_handle;
5120 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5122 if (mpt_config(ioc, &cfg) != 0)
5125 if (!buffer->NumPhysDisks)
5128 handle_inactive_volumes =
5129 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
5130 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
5131 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
5132 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
5134 if (!handle_inactive_volumes)
5137 down(&ioc->raid_data.inactive_list_mutex);
5138 for (i = 0; i < buffer->NumPhysDisks; i++) {
5139 if(mpt_raid_phys_disk_pg0(ioc,
5140 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
5143 if ((component_info = kmalloc(sizeof (*component_info),
5144 GFP_KERNEL)) == NULL)
5147 component_info->volumeID = id;
5148 component_info->volumeBus = channel;
5149 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
5150 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
5151 component_info->d.PhysDiskID = phys_disk.PhysDiskID;
5152 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
5154 list_add_tail(&component_info->list,
5155 &ioc->raid_data.inactive_list);
5157 up(&ioc->raid_data.inactive_list_mutex);
5161 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5166 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5167 * @ioc: Pointer to a Adapter Structure
5168 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5169 * @phys_disk: requested payload data returned
5173 * -EFAULT if read of config page header fails or data pointer not NULL
5174 * -ENOMEM if pci_alloc failed
5177 mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk)
5180 ConfigPageHeader_t hdr;
5181 dma_addr_t dma_handle;
5182 pRaidPhysDiskPage0_t buffer = NULL;
5185 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5186 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5188 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5189 cfg.cfghdr.hdr = &hdr;
5191 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5193 if (mpt_config(ioc, &cfg) != 0) {
5198 if (!hdr.PageLength) {
5203 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5211 cfg.physAddr = dma_handle;
5212 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5213 cfg.pageAddr = phys_disk_num;
5215 if (mpt_config(ioc, &cfg) != 0) {
5221 memcpy(phys_disk, buffer, sizeof(*buffer));
5222 phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
5227 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5234 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5235 * @ioc: Pointer to a Adapter Strucutre
5236 * @portnum: IOC port number
5240 * -EFAULT if read of config page header fails or data pointer not NULL
5241 * -ENOMEM if pci_alloc failed
5244 mpt_findImVolumes(MPT_ADAPTER *ioc)
5248 dma_addr_t ioc2_dma;
5250 ConfigPageHeader_t header;
5255 if (!ioc->ir_firmware)
5258 /* Free the old page
5260 kfree(ioc->raid_data.pIocPg2);
5261 ioc->raid_data.pIocPg2 = NULL;
5262 mpt_inactive_raid_list_free(ioc);
5264 /* Read IOCP2 header then the page.
5266 header.PageVersion = 0;
5267 header.PageLength = 0;
5268 header.PageNumber = 2;
5269 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5270 cfg.cfghdr.hdr = &header;
5273 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5276 if (mpt_config(ioc, &cfg) != 0)
5279 if (header.PageLength == 0)
5282 iocpage2sz = header.PageLength * 4;
5283 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
5287 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5288 cfg.physAddr = ioc2_dma;
5289 if (mpt_config(ioc, &cfg) != 0)
5292 mem = kmalloc(iocpage2sz, GFP_KERNEL);
5296 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
5297 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
5299 mpt_read_ioc_pg_3(ioc);
5301 for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
5302 mpt_inactive_raid_volumes(ioc,
5303 pIoc2->RaidVolume[i].VolumeBus,
5304 pIoc2->RaidVolume[i].VolumeID);
5307 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
5313 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
5318 ConfigPageHeader_t header;
5319 dma_addr_t ioc3_dma;
5322 /* Free the old page
5324 kfree(ioc->raid_data.pIocPg3);
5325 ioc->raid_data.pIocPg3 = NULL;
5327 /* There is at least one physical disk.
5328 * Read and save IOC Page 3
5330 header.PageVersion = 0;
5331 header.PageLength = 0;
5332 header.PageNumber = 3;
5333 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5334 cfg.cfghdr.hdr = &header;
5337 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5340 if (mpt_config(ioc, &cfg) != 0)
5343 if (header.PageLength == 0)
5346 /* Read Header good, alloc memory
5348 iocpage3sz = header.PageLength * 4;
5349 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
5353 /* Read the Page and save the data
5354 * into malloc'd memory.
5356 cfg.physAddr = ioc3_dma;
5357 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5358 if (mpt_config(ioc, &cfg) == 0) {
5359 mem = kmalloc(iocpage3sz, GFP_KERNEL);
5361 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
5362 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
5366 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
5372 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
5376 ConfigPageHeader_t header;
5377 dma_addr_t ioc4_dma;
5380 /* Read and save IOC Page 4
5382 header.PageVersion = 0;
5383 header.PageLength = 0;
5384 header.PageNumber = 4;
5385 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5386 cfg.cfghdr.hdr = &header;
5389 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5392 if (mpt_config(ioc, &cfg) != 0)
5395 if (header.PageLength == 0)
5398 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
5399 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
5400 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
5403 ioc->alloc_total += iocpage4sz;
5405 ioc4_dma = ioc->spi_data.IocPg4_dma;
5406 iocpage4sz = ioc->spi_data.IocPg4Sz;
5409 /* Read the Page into dma memory.
5411 cfg.physAddr = ioc4_dma;
5412 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5413 if (mpt_config(ioc, &cfg) == 0) {
5414 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
5415 ioc->spi_data.IocPg4_dma = ioc4_dma;
5416 ioc->spi_data.IocPg4Sz = iocpage4sz;
5418 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
5419 ioc->spi_data.pIocPg4 = NULL;
5420 ioc->alloc_total -= iocpage4sz;
5425 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
5429 ConfigPageHeader_t header;
5430 dma_addr_t ioc1_dma;
5434 /* Check the Coalescing Timeout in IOC Page 1
5436 header.PageVersion = 0;
5437 header.PageLength = 0;
5438 header.PageNumber = 1;
5439 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5440 cfg.cfghdr.hdr = &header;
5443 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5446 if (mpt_config(ioc, &cfg) != 0)
5449 if (header.PageLength == 0)
5452 /* Read Header good, alloc memory
5454 iocpage1sz = header.PageLength * 4;
5455 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
5459 /* Read the Page and check coalescing timeout
5461 cfg.physAddr = ioc1_dma;
5462 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5463 if (mpt_config(ioc, &cfg) == 0) {
5465 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
5466 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
5467 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
5469 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Coalescing Enabled Timeout = %d\n",
5472 if (tmp > MPT_COALESCING_TIMEOUT) {
5473 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
5475 /* Write NVRAM and current
5478 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5479 if (mpt_config(ioc, &cfg) == 0) {
5480 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Reset Current Coalescing Timeout to = %d\n",
5481 ioc->name, MPT_COALESCING_TIMEOUT));
5483 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
5484 if (mpt_config(ioc, &cfg) == 0) {
5485 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5486 "Reset NVRAM Coalescing Timeout to = %d\n",
5487 ioc->name, MPT_COALESCING_TIMEOUT));
5489 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5490 "Reset NVRAM Coalescing Timeout Failed\n",
5495 dprintk(ioc, printk(MYIOC_s_WARN_FMT
5496 "Reset of Current Coalescing Timeout Failed!\n",
5502 dprintk(ioc, printk(MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
5506 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
5512 mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
5515 ConfigPageHeader_t hdr;
5517 ManufacturingPage0_t *pbuf = NULL;
5519 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5520 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5522 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
5523 cfg.cfghdr.hdr = &hdr;
5525 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5528 if (mpt_config(ioc, &cfg) != 0)
5531 if (!cfg.cfghdr.hdr->PageLength)
5534 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5535 pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
5539 cfg.physAddr = buf_dma;
5541 if (mpt_config(ioc, &cfg) != 0)
5544 memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name));
5545 memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
5546 memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
5551 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
5554 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5556 * SendEventNotification - Send EventNotification (on or off) request to adapter
5557 * @ioc: Pointer to MPT_ADAPTER structure
5558 * @EvSwitch: Event switch flags
5561 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
5563 EventNotification_t *evnp;
5565 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
5567 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
5571 memset(evnp, 0, sizeof(*evnp));
5573 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
5575 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
5576 evnp->ChainOffset = 0;
5578 evnp->Switch = EvSwitch;
5580 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
5585 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5587 * SendEventAck - Send EventAck request to MPT adapter.
5588 * @ioc: Pointer to MPT_ADAPTER structure
5589 * @evnp: Pointer to original EventNotification request
5592 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
5596 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5597 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
5598 ioc->name,__FUNCTION__));
5602 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventAck\n", ioc->name));
5604 pAck->Function = MPI_FUNCTION_EVENT_ACK;
5605 pAck->ChainOffset = 0;
5606 pAck->Reserved[0] = pAck->Reserved[1] = 0;
5608 pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
5609 pAck->Event = evnp->Event;
5610 pAck->EventContext = evnp->EventContext;
5612 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
5617 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5619 * mpt_config - Generic function to issue config message
5620 * @ioc: Pointer to an adapter structure
5621 * @pCfg: Pointer to a configuration structure. Struct contains
5622 * action, page address, direction, physical address
5623 * and pointer to a configuration page header
5624 * Page header is updated.
5626 * Returns 0 for success
5627 * -EPERM if not allowed due to ISR context
5628 * -EAGAIN if no msg frames currently available
5629 * -EFAULT for non-successful reply or no reply (timeout)
5632 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5635 ConfigExtendedPageHeader_t *pExtHdr = NULL;
5637 unsigned long flags;
5642 /* Prevent calling wait_event() (below), if caller happens
5643 * to be in ISR context, because that is fatal!
5645 in_isr = in_interrupt();
5647 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
5652 /* Get and Populate a free Frame
5654 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5655 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
5659 pReq = (Config_t *)mf;
5660 pReq->Action = pCfg->action;
5662 pReq->ChainOffset = 0;
5663 pReq->Function = MPI_FUNCTION_CONFIG;
5665 /* Assume page type is not extended and clear "reserved" fields. */
5666 pReq->ExtPageLength = 0;
5667 pReq->ExtPageType = 0;
5670 for (ii=0; ii < 8; ii++)
5671 pReq->Reserved2[ii] = 0;
5673 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
5674 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
5675 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
5676 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
5678 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5679 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
5680 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
5681 pReq->ExtPageType = pExtHdr->ExtPageType;
5682 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
5684 /* Page Length must be treated as a reserved field for the extended header. */
5685 pReq->Header.PageLength = 0;
5688 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
5690 /* Add a SGE to the config request.
5693 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
5695 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
5697 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5698 flagsLength |= pExtHdr->ExtPageLength * 4;
5700 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n",
5701 ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action));
5704 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
5706 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n",
5707 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
5710 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
5712 /* Append pCfg pointer to end of mf
5714 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5716 /* Initalize the timer
5718 init_timer(&pCfg->timer);
5719 pCfg->timer.data = (unsigned long) ioc;
5720 pCfg->timer.function = mpt_timer_expired;
5721 pCfg->wait_done = 0;
5723 /* Set the timer; ensure 10 second minimum */
5724 if (pCfg->timeout < 10)
5725 pCfg->timer.expires = jiffies + HZ*10;
5727 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5729 /* Add to end of Q, set timer and then issue this command */
5730 spin_lock_irqsave(&ioc->FreeQlock, flags);
5731 list_add_tail(&pCfg->linkage, &ioc->configQ);
5732 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5734 add_timer(&pCfg->timer);
5735 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5736 wait_event(mpt_waitq, pCfg->wait_done);
5738 /* mf has been freed - do not access */
5745 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5747 * mpt_timer_expired - Callback for timer process.
5748 * Used only internal config functionality.
5749 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5752 mpt_timer_expired(unsigned long data)
5754 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
5756 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired! \n", ioc->name));
5758 /* Perform a FW reload */
5759 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
5760 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
5762 /* No more processing.
5763 * Hard reset clean-up will wake up
5764 * process and free all resources.
5766 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired complete!\n", ioc->name));
5771 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5773 * mpt_ioc_reset - Base cleanup for hard reset
5774 * @ioc: Pointer to the adapter structure
5775 * @reset_phase: Indicates pre- or post-reset functionality
5777 * Remark: Frees resources with internally generated commands.
5780 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
5783 unsigned long flags;
5785 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5786 ": IOC %s_reset routed to MPT base driver!\n",
5787 ioc->name, reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
5788 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
5790 if (reset_phase == MPT_IOC_SETUP_RESET) {
5792 } else if (reset_phase == MPT_IOC_PRE_RESET) {
5793 /* If the internal config Q is not empty -
5794 * delete timer. MF resources will be freed when
5795 * the FIFO's are primed.
5797 spin_lock_irqsave(&ioc->FreeQlock, flags);
5798 list_for_each_entry(pCfg, &ioc->configQ, linkage)
5799 del_timer(&pCfg->timer);
5800 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5805 /* Search the configQ for internal commands.
5806 * Flush the Q, and wake up all suspended threads.
5808 spin_lock_irqsave(&ioc->FreeQlock, flags);
5809 list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
5810 list_del(&pCfg->linkage);
5812 pCfg->status = MPT_CONFIG_ERROR;
5813 pCfg->wait_done = 1;
5814 wake_up(&mpt_waitq);
5816 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5819 return 1; /* currently means nothing really */
5823 #ifdef CONFIG_PROC_FS /* { */
5824 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5826 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5828 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5830 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5832 * Returns 0 for success, non-zero for failure.
5835 procmpt_create(void)
5837 struct proc_dir_entry *ent;
5839 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
5840 if (mpt_proc_root_dir == NULL)
5843 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5845 ent->read_proc = procmpt_summary_read;
5847 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5849 ent->read_proc = procmpt_version_read;
5854 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5856 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5858 * Returns 0 for success, non-zero for failure.
5861 procmpt_destroy(void)
5863 remove_proc_entry("version", mpt_proc_root_dir);
5864 remove_proc_entry("summary", mpt_proc_root_dir);
5865 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
5868 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5870 * procmpt_summary_read - Handle read request of a summary file
5871 * @buf: Pointer to area to write information
5872 * @start: Pointer to start pointer
5873 * @offset: Offset to start writing
5874 * @request: Amount of read data requested
5875 * @eof: Pointer to EOF integer
5878 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
5879 * Returns number of characters written to process performing the read.
5882 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5892 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5896 list_for_each_entry(ioc, &ioc_list, list) {
5899 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5902 if ((out-buf) >= request)
5909 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5912 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5914 * procmpt_version_read - Handle read request from /proc/mpt/version.
5915 * @buf: Pointer to area to write information
5916 * @start: Pointer to start pointer
5917 * @offset: Offset to start writing
5918 * @request: Amount of read data requested
5919 * @eof: Pointer to EOF integer
5922 * Returns number of characters written to process performing the read.
5925 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5928 int scsi, fc, sas, lan, ctl, targ, dmp;
5932 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
5933 len += sprintf(buf+len, " Fusion MPT base driver\n");
5935 scsi = fc = sas = lan = ctl = targ = dmp = 0;
5936 for (cb_idx=MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
5938 if (MptCallbacks[cb_idx]) {
5939 switch (MptDriverClass[cb_idx]) {
5941 if (!scsi++) drvname = "SPI host";
5944 if (!fc++) drvname = "FC host";
5947 if (!sas++) drvname = "SAS host";
5950 if (!lan++) drvname = "LAN";
5953 if (!targ++) drvname = "SCSI target";
5956 if (!ctl++) drvname = "ioctl";
5961 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
5965 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5968 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5970 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
5971 * @buf: Pointer to area to write information
5972 * @start: Pointer to start pointer
5973 * @offset: Offset to start writing
5974 * @request: Amount of read data requested
5975 * @eof: Pointer to EOF integer
5978 * Returns number of characters written to process performing the read.
5981 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5983 MPT_ADAPTER *ioc = data;
5989 mpt_get_fw_exp_ver(expVer, ioc);
5991 len = sprintf(buf, "%s:", ioc->name);
5992 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
5993 len += sprintf(buf+len, " (f/w download boot flag set)");
5994 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
5995 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
5997 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
5998 ioc->facts.ProductID,
6000 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
6001 if (ioc->facts.FWImageSize)
6002 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
6003 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
6004 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
6005 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
6007 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
6008 ioc->facts.CurrentHostMfaHighAddr);
6009 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
6010 ioc->facts.CurrentSenseBufferHighAddr);
6012 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
6013 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
6015 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6016 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
6018 * Rounding UP to nearest 4-kB boundary here...
6020 sz = (ioc->req_sz * ioc->req_depth) + 128;
6021 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
6022 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6023 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
6024 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
6025 4*ioc->facts.RequestFrameSize,
6026 ioc->facts.GlobalCredits);
6028 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
6029 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
6030 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
6031 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6032 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
6033 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
6034 ioc->facts.CurReplyFrameSize,
6035 ioc->facts.ReplyQueueDepth);
6037 len += sprintf(buf+len, " MaxDevices = %d\n",
6038 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
6039 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
6042 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
6043 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
6045 ioc->facts.NumberOfPorts);
6046 if (ioc->bus_type == FC) {
6047 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
6048 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6049 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6050 a[5], a[4], a[3], a[2], a[1], a[0]);
6052 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
6053 ioc->fc_port_page0[p].WWNN.High,
6054 ioc->fc_port_page0[p].WWNN.Low,
6055 ioc->fc_port_page0[p].WWPN.High,
6056 ioc->fc_port_page0[p].WWPN.Low);
6060 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6063 #endif /* CONFIG_PROC_FS } */
6065 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6067 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
6070 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
6071 sprintf(buf, " (Exp %02d%02d)",
6072 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
6073 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
6076 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
6077 strcat(buf, " [MDBG]");
6081 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6083 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6084 * @ioc: Pointer to MPT_ADAPTER structure
6085 * @buffer: Pointer to buffer where IOC summary info should be written
6086 * @size: Pointer to number of bytes we wrote (set by this routine)
6087 * @len: Offset at which to start writing in buffer
6088 * @showlan: Display LAN stuff?
6090 * This routine writes (english readable) ASCII text, which represents
6091 * a summary of IOC information, to a buffer.
6094 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
6099 mpt_get_fw_exp_ver(expVer, ioc);
6102 * Shorter summary of attached ioc's...
6104 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6107 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
6108 ioc->facts.FWVersion.Word,
6110 ioc->facts.NumberOfPorts,
6113 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6114 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6115 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6116 a[5], a[4], a[3], a[2], a[1], a[0]);
6119 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
6122 y += sprintf(buffer+len+y, " (disabled)");
6124 y += sprintf(buffer+len+y, "\n");
6129 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6133 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6135 * mpt_HardResetHandler - Generic reset handler
6136 * @ioc: Pointer to MPT_ADAPTER structure
6137 * @sleepFlag: Indicates if sleep or schedule must be called.
6139 * Issues SCSI Task Management call based on input arg values.
6140 * If TaskMgmt fails, returns associated SCSI request.
6142 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
6143 * or a non-interrupt thread. In the former, must not call schedule().
6145 * Note: A return of -1 is a FATAL error case, as it means a
6146 * FW reload/initialization failed.
6148 * Returns 0 for SUCCESS or -1 if FAILED.
6151 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6154 unsigned long flags;
6156 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name));
6158 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
6159 printk("MF count 0x%x !\n", ioc->mfcnt);
6162 /* Reset the adapter. Prevent more than 1 call to
6163 * mpt_do_ioc_recovery at any instant in time.
6165 spin_lock_irqsave(&ioc->diagLock, flags);
6166 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
6167 spin_unlock_irqrestore(&ioc->diagLock, flags);
6170 ioc->diagPending = 1;
6172 spin_unlock_irqrestore(&ioc->diagLock, flags);
6174 /* FIXME: If do_ioc_recovery fails, repeat....
6177 /* The SCSI driver needs to adjust timeouts on all current
6178 * commands prior to the diagnostic reset being issued.
6179 * Prevents timeouts occurring during a diagnostic reset...very bad.
6180 * For all other protocol drivers, this is a no-op.
6186 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6187 if (MptResetHandlers[cb_idx]) {
6188 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling IOC reset_setup handler #%d\n",
6189 ioc->name, cb_idx));
6190 r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
6192 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling alt-%s setup reset handler #%d\n",
6193 ioc->name, ioc->alt_ioc->name, cb_idx));
6194 r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_SETUP_RESET);
6200 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
6201 printk(MYIOC_s_WARN_FMT "Cannot recover rc = %d!\n", ioc->name, rc);
6205 ioc->alt_ioc->reload_fw = 0;
6207 spin_lock_irqsave(&ioc->diagLock, flags);
6208 ioc->diagPending = 0;
6210 ioc->alt_ioc->diagPending = 0;
6211 spin_unlock_irqrestore(&ioc->diagLock, flags);
6213 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
6218 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6220 EventDescriptionStr(u8 event, u32 evData0, char *evStr)
6225 case MPI_EVENT_NONE:
6228 case MPI_EVENT_LOG_DATA:
6231 case MPI_EVENT_STATE_CHANGE:
6232 ds = "State Change";
6234 case MPI_EVENT_UNIT_ATTENTION:
6235 ds = "Unit Attention";
6237 case MPI_EVENT_IOC_BUS_RESET:
6238 ds = "IOC Bus Reset";
6240 case MPI_EVENT_EXT_BUS_RESET:
6241 ds = "External Bus Reset";
6243 case MPI_EVENT_RESCAN:
6244 ds = "Bus Rescan Event";
6246 case MPI_EVENT_LINK_STATUS_CHANGE:
6247 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
6248 ds = "Link Status(FAILURE) Change";
6250 ds = "Link Status(ACTIVE) Change";
6252 case MPI_EVENT_LOOP_STATE_CHANGE:
6253 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
6254 ds = "Loop State(LIP) Change";
6255 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
6256 ds = "Loop State(LPE) Change"; /* ??? */
6258 ds = "Loop State(LPB) Change"; /* ??? */
6260 case MPI_EVENT_LOGOUT:
6263 case MPI_EVENT_EVENT_CHANGE:
6269 case MPI_EVENT_INTEGRATED_RAID:
6271 u8 ReasonCode = (u8)(evData0 >> 16);
6272 switch (ReasonCode) {
6273 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
6274 ds = "Integrated Raid: Volume Created";
6276 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
6277 ds = "Integrated Raid: Volume Deleted";
6279 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
6280 ds = "Integrated Raid: Volume Settings Changed";
6282 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
6283 ds = "Integrated Raid: Volume Status Changed";
6285 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
6286 ds = "Integrated Raid: Volume Physdisk Changed";
6288 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
6289 ds = "Integrated Raid: Physdisk Created";
6291 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
6292 ds = "Integrated Raid: Physdisk Deleted";
6294 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
6295 ds = "Integrated Raid: Physdisk Settings Changed";
6297 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
6298 ds = "Integrated Raid: Physdisk Status Changed";
6300 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
6301 ds = "Integrated Raid: Domain Validation Needed";
6303 case MPI_EVENT_RAID_RC_SMART_DATA :
6304 ds = "Integrated Raid; Smart Data";
6306 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
6307 ds = "Integrated Raid: Replace Action Started";
6310 ds = "Integrated Raid";
6315 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
6316 ds = "SCSI Device Status Change";
6318 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
6320 u8 id = (u8)(evData0);
6321 u8 channel = (u8)(evData0 >> 8);
6322 u8 ReasonCode = (u8)(evData0 >> 16);
6323 switch (ReasonCode) {
6324 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
6325 snprintf(evStr, EVENT_DESCR_STR_SZ,
6326 "SAS Device Status Change: Added: "
6327 "id=%d channel=%d", id, channel);
6329 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
6330 snprintf(evStr, EVENT_DESCR_STR_SZ,
6331 "SAS Device Status Change: Deleted: "
6332 "id=%d channel=%d", id, channel);
6334 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
6335 snprintf(evStr, EVENT_DESCR_STR_SZ,
6336 "SAS Device Status Change: SMART Data: "
6337 "id=%d channel=%d", id, channel);
6339 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
6340 snprintf(evStr, EVENT_DESCR_STR_SZ,
6341 "SAS Device Status Change: No Persistancy: "
6342 "id=%d channel=%d", id, channel);
6344 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
6345 snprintf(evStr, EVENT_DESCR_STR_SZ,
6346 "SAS Device Status Change: Unsupported Device "
6347 "Discovered : id=%d channel=%d", id, channel);
6349 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
6350 snprintf(evStr, EVENT_DESCR_STR_SZ,
6351 "SAS Device Status Change: Internal Device "
6352 "Reset : id=%d channel=%d", id, channel);
6354 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
6355 snprintf(evStr, EVENT_DESCR_STR_SZ,
6356 "SAS Device Status Change: Internal Task "
6357 "Abort : id=%d channel=%d", id, channel);
6359 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
6360 snprintf(evStr, EVENT_DESCR_STR_SZ,
6361 "SAS Device Status Change: Internal Abort "
6362 "Task Set : id=%d channel=%d", id, channel);
6364 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
6365 snprintf(evStr, EVENT_DESCR_STR_SZ,
6366 "SAS Device Status Change: Internal Clear "
6367 "Task Set : id=%d channel=%d", id, channel);
6369 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
6370 snprintf(evStr, EVENT_DESCR_STR_SZ,
6371 "SAS Device Status Change: Internal Query "
6372 "Task : id=%d channel=%d", id, channel);
6375 snprintf(evStr, EVENT_DESCR_STR_SZ,
6376 "SAS Device Status Change: Unknown: "
6377 "id=%d channel=%d", id, channel);
6382 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
6383 ds = "Bus Timer Expired";
6385 case MPI_EVENT_QUEUE_FULL:
6387 u16 curr_depth = (u16)(evData0 >> 16);
6388 u8 channel = (u8)(evData0 >> 8);
6389 u8 id = (u8)(evData0);
6391 snprintf(evStr, EVENT_DESCR_STR_SZ,
6392 "Queue Full: channel=%d id=%d depth=%d",
6393 channel, id, curr_depth);
6396 case MPI_EVENT_SAS_SES:
6397 ds = "SAS SES Event";
6399 case MPI_EVENT_PERSISTENT_TABLE_FULL:
6400 ds = "Persistent Table Full";
6402 case MPI_EVENT_SAS_PHY_LINK_STATUS:
6404 u8 LinkRates = (u8)(evData0 >> 8);
6405 u8 PhyNumber = (u8)(evData0);
6406 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
6407 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
6408 switch (LinkRates) {
6409 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
6410 snprintf(evStr, EVENT_DESCR_STR_SZ,
6411 "SAS PHY Link Status: Phy=%d:"
6412 " Rate Unknown",PhyNumber);
6414 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
6415 snprintf(evStr, EVENT_DESCR_STR_SZ,
6416 "SAS PHY Link Status: Phy=%d:"
6417 " Phy Disabled",PhyNumber);
6419 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
6420 snprintf(evStr, EVENT_DESCR_STR_SZ,
6421 "SAS PHY Link Status: Phy=%d:"
6422 " Failed Speed Nego",PhyNumber);
6424 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
6425 snprintf(evStr, EVENT_DESCR_STR_SZ,
6426 "SAS PHY Link Status: Phy=%d:"
6427 " Sata OOB Completed",PhyNumber);
6429 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
6430 snprintf(evStr, EVENT_DESCR_STR_SZ,
6431 "SAS PHY Link Status: Phy=%d:"
6432 " Rate 1.5 Gbps",PhyNumber);
6434 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
6435 snprintf(evStr, EVENT_DESCR_STR_SZ,
6436 "SAS PHY Link Status: Phy=%d:"
6437 " Rate 3.0 Gpbs",PhyNumber);
6440 snprintf(evStr, EVENT_DESCR_STR_SZ,
6441 "SAS PHY Link Status: Phy=%d", PhyNumber);
6446 case MPI_EVENT_SAS_DISCOVERY_ERROR:
6447 ds = "SAS Discovery Error";
6449 case MPI_EVENT_IR_RESYNC_UPDATE:
6451 u8 resync_complete = (u8)(evData0 >> 16);
6452 snprintf(evStr, EVENT_DESCR_STR_SZ,
6453 "IR Resync Update: Complete = %d:",resync_complete);
6458 u8 ReasonCode = (u8)(evData0 >> 16);
6459 switch (ReasonCode) {
6460 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
6461 ds = "IR2: LD State Changed";
6463 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
6464 ds = "IR2: PD State Changed";
6466 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
6467 ds = "IR2: Bad Block Table Full";
6469 case MPI_EVENT_IR2_RC_PD_INSERTED:
6470 ds = "IR2: PD Inserted";
6472 case MPI_EVENT_IR2_RC_PD_REMOVED:
6473 ds = "IR2: PD Removed";
6475 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
6476 ds = "IR2: Foreign CFG Detected";
6478 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
6479 ds = "IR2: Rebuild Medium Error";
6487 case MPI_EVENT_SAS_DISCOVERY:
6490 ds = "SAS Discovery: Start";
6492 ds = "SAS Discovery: Stop";
6495 case MPI_EVENT_LOG_ENTRY_ADDED:
6496 ds = "SAS Log Entry Added";
6499 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
6501 u8 phy_num = (u8)(evData0);
6502 u8 port_num = (u8)(evData0 >> 8);
6503 u8 port_width = (u8)(evData0 >> 16);
6504 u8 primative = (u8)(evData0 >> 24);
6505 snprintf(evStr, EVENT_DESCR_STR_SZ,
6506 "SAS Broadcase Primative: phy=%d port=%d "
6507 "width=%d primative=0x%02x",
6508 phy_num, port_num, port_width, primative);
6512 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
6514 u8 reason = (u8)(evData0);
6515 u8 port_num = (u8)(evData0 >> 8);
6516 u16 handle = le16_to_cpu(evData0 >> 16);
6518 snprintf(evStr, EVENT_DESCR_STR_SZ,
6519 "SAS Initiator Device Status Change: reason=0x%02x "
6520 "port=%d handle=0x%04x",
6521 reason, port_num, handle);
6525 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
6527 u8 max_init = (u8)(evData0);
6528 u8 current_init = (u8)(evData0 >> 8);
6530 snprintf(evStr, EVENT_DESCR_STR_SZ,
6531 "SAS Initiator Device Table Overflow: max initiators=%02d "
6532 "current initators=%02d",
6533 max_init, current_init);
6536 case MPI_EVENT_SAS_SMP_ERROR:
6538 u8 status = (u8)(evData0);
6539 u8 port_num = (u8)(evData0 >> 8);
6540 u8 result = (u8)(evData0 >> 16);
6542 if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
6543 snprintf(evStr, EVENT_DESCR_STR_SZ,
6544 "SAS SMP Error: port=%d result=0x%02x",
6546 else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
6547 snprintf(evStr, EVENT_DESCR_STR_SZ,
6548 "SAS SMP Error: port=%d : CRC Error",
6550 else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
6551 snprintf(evStr, EVENT_DESCR_STR_SZ,
6552 "SAS SMP Error: port=%d : Timeout",
6554 else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
6555 snprintf(evStr, EVENT_DESCR_STR_SZ,
6556 "SAS SMP Error: port=%d : No Destination",
6558 else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
6559 snprintf(evStr, EVENT_DESCR_STR_SZ,
6560 "SAS SMP Error: port=%d : Bad Destination",
6563 snprintf(evStr, EVENT_DESCR_STR_SZ,
6564 "SAS SMP Error: port=%d : status=0x%02x",
6570 * MPT base "custom" events may be added here...
6577 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
6580 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6582 * ProcessEventNotification - Route EventNotificationReply to all event handlers
6583 * @ioc: Pointer to MPT_ADAPTER structure
6584 * @pEventReply: Pointer to EventNotification reply frame
6585 * @evHandlers: Pointer to integer, number of event handlers
6587 * Routes a received EventNotificationReply to all currently registered
6589 * Returns sum of event handlers return values.
6592 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
6601 char evStr[EVENT_DESCR_STR_SZ];
6605 * Do platform normalization of values
6607 event = le32_to_cpu(pEventReply->Event) & 0xFF;
6608 // evCtx = le32_to_cpu(pEventReply->EventContext);
6609 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
6611 evData0 = le32_to_cpu(pEventReply->Data[0]);
6614 EventDescriptionStr(event, evData0, evStr);
6615 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event:(%02Xh) : %s\n",
6620 #ifdef CONFIG_FUSION_LOGGING
6621 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6622 ": Event data:\n", ioc->name));
6623 for (ii = 0; ii < evDataLen; ii++)
6624 devtverboseprintk(ioc, printk(" %08x",
6625 le32_to_cpu(pEventReply->Data[ii])));
6626 devtverboseprintk(ioc, printk("\n"));
6630 * Do general / base driver event processing
6633 case MPI_EVENT_EVENT_CHANGE: /* 0A */
6635 u8 evState = evData0 & 0xFF;
6637 /* CHECKME! What if evState unexpectedly says OFF (0)? */
6639 /* Update EventState field in cached IocFacts */
6640 if (ioc->facts.Function) {
6641 ioc->facts.EventState = evState;
6645 case MPI_EVENT_INTEGRATED_RAID:
6646 mptbase_raid_process_event_data(ioc,
6647 (MpiEventDataRaid_t *)pEventReply->Data);
6654 * Should this event be logged? Events are written sequentially.
6655 * When buffer is full, start again at the top.
6657 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
6660 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
6662 ioc->events[idx].event = event;
6663 ioc->events[idx].eventContext = ioc->eventContext;
6665 for (ii = 0; ii < 2; ii++) {
6667 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
6669 ioc->events[idx].data[ii] = 0;
6672 ioc->eventContext++;
6677 * Call each currently registered protocol event handler.
6679 for (cb_idx=MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6680 if (MptEvHandlers[cb_idx]) {
6681 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Routing Event to event handler #%d\n",
6682 ioc->name, cb_idx));
6683 r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply);
6687 /* FIXME? Examine results here? */
6690 * If needed, send (a single) EventAck.
6692 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
6693 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6694 "EventAck required\n",ioc->name));
6695 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
6696 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SendEventAck returned %d\n",
6701 *evHandlers = handlers;
6705 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6707 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
6708 * @ioc: Pointer to MPT_ADAPTER structure
6709 * @log_info: U32 LogInfo reply word from the IOC
6711 * Refer to lsi/mpi_log_fc.h.
6714 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
6716 char *desc = "unknown";
6718 switch (log_info & 0xFF000000) {
6719 case MPI_IOCLOGINFO_FC_INIT_BASE:
6720 desc = "FCP Initiator";
6722 case MPI_IOCLOGINFO_FC_TARGET_BASE:
6723 desc = "FCP Target";
6725 case MPI_IOCLOGINFO_FC_LAN_BASE:
6728 case MPI_IOCLOGINFO_FC_MSG_BASE:
6729 desc = "MPI Message Layer";
6731 case MPI_IOCLOGINFO_FC_LINK_BASE:
6734 case MPI_IOCLOGINFO_FC_CTX_BASE:
6735 desc = "Context Manager";
6737 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
6738 desc = "Invalid Field Offset";
6740 case MPI_IOCLOGINFO_FC_STATE_CHANGE:
6741 desc = "State Change Info";
6745 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
6746 ioc->name, log_info, desc, (log_info & 0xFFFFFF));
6749 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6751 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
6752 * @ioc: Pointer to MPT_ADAPTER structure
6753 * @mr: Pointer to MPT reply frame
6754 * @log_info: U32 LogInfo word from the IOC
6756 * Refer to lsi/sp_log.h.
6759 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
6761 u32 info = log_info & 0x00FF0000;
6762 char *desc = "unknown";
6766 desc = "bug! MID not found";
6767 if (ioc->reload_fw == 0)
6772 desc = "Parity Error";
6776 desc = "ASYNC Outbound Overrun";
6780 desc = "SYNC Offset Error";
6788 desc = "Msg In Overflow";
6796 desc = "Outbound DMA Overrun";
6800 desc = "Task Management";
6804 desc = "Device Problem";
6808 desc = "Invalid Phase Change";
6812 desc = "Untagged Table Size";
6817 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
6820 /* strings for sas loginfo */
6821 static char *originator_str[] = {
6826 static char *iop_code_str[] = {
6828 "Invalid SAS Address", /* 01h */
6830 "Invalid Page", /* 03h */
6831 "Diag Message Error", /* 04h */
6832 "Task Terminated", /* 05h */
6833 "Enclosure Management", /* 06h */
6834 "Target Mode" /* 07h */
6836 static char *pl_code_str[] = {
6838 "Open Failure", /* 01h */
6839 "Invalid Scatter Gather List", /* 02h */
6840 "Wrong Relative Offset or Frame Length", /* 03h */
6841 "Frame Transfer Error", /* 04h */
6842 "Transmit Frame Connected Low", /* 05h */
6843 "SATA Non-NCQ RW Error Bit Set", /* 06h */
6844 "SATA Read Log Receive Data Error", /* 07h */
6845 "SATA NCQ Fail All Commands After Error", /* 08h */
6846 "SATA Error in Receive Set Device Bit FIS", /* 09h */
6847 "Receive Frame Invalid Message", /* 0Ah */
6848 "Receive Context Message Valid Error", /* 0Bh */
6849 "Receive Frame Current Frame Error", /* 0Ch */
6850 "SATA Link Down", /* 0Dh */
6851 "Discovery SATA Init W IOS", /* 0Eh */
6852 "Config Invalid Page", /* 0Fh */
6853 "Discovery SATA Init Timeout", /* 10h */
6856 "IO Not Yet Executed", /* 13h */
6857 "IO Executed", /* 14h */
6858 "Persistent Reservation Out Not Affiliation "
6860 "Open Transmit DMA Abort", /* 16h */
6861 "IO Device Missing Delay Retry", /* 17h */
6862 "IO Cancelled Due to Recieve Error", /* 18h */
6870 "Enclosure Management" /* 20h */
6872 static char *ir_code_str[] = {
6873 "Raid Action Error", /* 00h */
6883 static char *raid_sub_code_str[] = {
6885 "Volume Creation Failed: Data Passed too "
6887 "Volume Creation Failed: Duplicate Volumes "
6888 "Attempted", /* 02h */
6889 "Volume Creation Failed: Max Number "
6890 "Supported Volumes Exceeded", /* 03h */
6891 "Volume Creation Failed: DMA Error", /* 04h */
6892 "Volume Creation Failed: Invalid Volume Type", /* 05h */
6893 "Volume Creation Failed: Error Reading "
6894 "MFG Page 4", /* 06h */
6895 "Volume Creation Failed: Creating Internal "
6896 "Structures", /* 07h */
6905 "Activation failed: Already Active Volume", /* 10h */
6906 "Activation failed: Unsupported Volume Type", /* 11h */
6907 "Activation failed: Too Many Active Volumes", /* 12h */
6908 "Activation failed: Volume ID in Use", /* 13h */
6909 "Activation failed: Reported Failure", /* 14h */
6910 "Activation failed: Importing a Volume", /* 15h */
6921 "Phys Disk failed: Too Many Phys Disks", /* 20h */
6922 "Phys Disk failed: Data Passed too Large", /* 21h */
6923 "Phys Disk failed: DMA Error", /* 22h */
6924 "Phys Disk failed: Invalid <channel:id>", /* 23h */
6925 "Phys Disk failed: Creating Phys Disk Config "
6938 "Compatibility Error: IR Disabled", /* 30h */
6939 "Compatibility Error: Inquiry Comand Failed", /* 31h */
6940 "Compatibility Error: Device not Direct Access "
6941 "Device ", /* 32h */
6942 "Compatibility Error: Removable Device Found", /* 33h */
6943 "Compatibility Error: Device SCSI Version not "
6944 "2 or Higher", /* 34h */
6945 "Compatibility Error: SATA Device, 48 BIT LBA "
6946 "not Supported", /* 35h */
6947 "Compatibility Error: Device doesn't have "
6948 "512 Byte Block Sizes", /* 36h */
6949 "Compatibility Error: Volume Type Check Failed", /* 37h */
6950 "Compatibility Error: Volume Type is "
6951 "Unsupported by FW", /* 38h */
6952 "Compatibility Error: Disk Drive too Small for "
6953 "use in Volume", /* 39h */
6954 "Compatibility Error: Phys Disk for Create "
6955 "Volume not Found", /* 3Ah */
6956 "Compatibility Error: Too Many or too Few "
6957 "Disks for Volume Type", /* 3Bh */
6958 "Compatibility Error: Disk stripe Sizes "
6959 "Must be 64KB", /* 3Ch */
6960 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
6963 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6965 * mpt_sas_log_info - Log information returned from SAS IOC.
6966 * @ioc: Pointer to MPT_ADAPTER structure
6967 * @log_info: U32 LogInfo reply word from the IOC
6969 * Refer to lsi/mpi_log_sas.h.
6972 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
6974 union loginfo_type {
6983 union loginfo_type sas_loginfo;
6984 char *originator_desc = NULL;
6985 char *code_desc = NULL;
6986 char *sub_code_desc = NULL;
6988 sas_loginfo.loginfo = log_info;
6989 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
6990 (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
6993 originator_desc = originator_str[sas_loginfo.dw.originator];
6995 switch (sas_loginfo.dw.originator) {
6998 if (sas_loginfo.dw.code <
6999 sizeof(iop_code_str)/sizeof(char*))
7000 code_desc = iop_code_str[sas_loginfo.dw.code];
7003 if (sas_loginfo.dw.code <
7004 sizeof(pl_code_str)/sizeof(char*))
7005 code_desc = pl_code_str[sas_loginfo.dw.code];
7008 if (sas_loginfo.dw.code >=
7009 sizeof(ir_code_str)/sizeof(char*))
7011 code_desc = ir_code_str[sas_loginfo.dw.code];
7012 if (sas_loginfo.dw.subcode >=
7013 sizeof(raid_sub_code_str)/sizeof(char*))
7015 if (sas_loginfo.dw.code == 0)
7017 raid_sub_code_str[sas_loginfo.dw.subcode];
7023 if (sub_code_desc != NULL)
7024 printk(MYIOC_s_INFO_FMT
7025 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7027 ioc->name, log_info, originator_desc, code_desc,
7029 else if (code_desc != NULL)
7030 printk(MYIOC_s_INFO_FMT
7031 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7032 " SubCode(0x%04x)\n",
7033 ioc->name, log_info, originator_desc, code_desc,
7034 sas_loginfo.dw.subcode);
7036 printk(MYIOC_s_INFO_FMT
7037 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
7038 " SubCode(0x%04x)\n",
7039 ioc->name, log_info, originator_desc,
7040 sas_loginfo.dw.code, sas_loginfo.dw.subcode);
7043 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7045 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
7046 * @ioc: Pointer to MPT_ADAPTER structure
7047 * @ioc_status: U32 IOCStatus word from IOC
7048 * @mf: Pointer to MPT request frame
7050 * Refer to lsi/mpi.h.
7053 mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7055 Config_t *pReq = (Config_t *)mf;
7056 char extend_desc[EVENT_DESCR_STR_SZ];
7061 if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
7062 page_type = pReq->ExtPageType;
7064 page_type = pReq->Header.PageType;
7067 * ignore invalid page messages for GET_NEXT_HANDLE
7069 form = le32_to_cpu(pReq->PageAddress);
7070 if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
7071 if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
7072 page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
7073 page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
7074 if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
7075 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
7078 if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
7079 if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
7080 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
7084 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
7085 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
7086 page_type, pReq->Header.PageNumber, pReq->Action, form);
7088 switch (ioc_status) {
7090 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7091 desc = "Config Page Invalid Action";
7094 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7095 desc = "Config Page Invalid Type";
7098 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7099 desc = "Config Page Invalid Page";
7102 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7103 desc = "Config Page Invalid Data";
7106 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7107 desc = "Config Page No Defaults";
7110 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7111 desc = "Config Page Can't Commit";
7118 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s: %s\n",
7119 ioc->name, ioc_status, desc, extend_desc));
7123 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
7124 * @ioc: Pointer to MPT_ADAPTER structure
7125 * @ioc_status: U32 IOCStatus word from IOC
7126 * @mf: Pointer to MPT request frame
7128 * Refer to lsi/mpi.h.
7131 mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7133 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
7138 /****************************************************************************/
7139 /* Common IOCStatus values for all replies */
7140 /****************************************************************************/
7142 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
7143 desc = "Invalid Function";
7146 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
7150 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
7151 desc = "Invalid SGL";
7154 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
7155 desc = "Internal Error";
7158 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
7162 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
7163 desc = "Insufficient Resources";
7166 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
7167 desc = "Invalid Field";
7170 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
7171 desc = "Invalid State";
7174 /****************************************************************************/
7175 /* Config IOCStatus values */
7176 /****************************************************************************/
7178 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7179 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7180 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7181 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7182 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7183 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7184 mpt_iocstatus_info_config(ioc, status, mf);
7187 /****************************************************************************/
7188 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
7190 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
7192 /****************************************************************************/
7194 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
7195 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
7196 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
7197 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
7198 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
7199 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
7200 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
7201 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
7202 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
7203 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
7204 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
7205 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
7206 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
7209 /****************************************************************************/
7210 /* SCSI Target values */
7211 /****************************************************************************/
7213 case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
7214 desc = "Target: Priority IO";
7217 case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
7218 desc = "Target: Invalid Port";
7221 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
7222 desc = "Target Invalid IO Index:";
7225 case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
7226 desc = "Target: Aborted";
7229 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
7230 desc = "Target: No Conn Retryable";
7233 case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
7234 desc = "Target: No Connection";
7237 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
7238 desc = "Target: Transfer Count Mismatch";
7241 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
7242 desc = "Target: STS Data not Sent";
7245 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
7246 desc = "Target: Data Offset Error";
7249 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
7250 desc = "Target: Too Much Write Data";
7253 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
7254 desc = "Target: IU Too Short";
7257 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
7258 desc = "Target: ACK NAK Timeout";
7261 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
7262 desc = "Target: Nak Received";
7265 /****************************************************************************/
7266 /* Fibre Channel Direct Access values */
7267 /****************************************************************************/
7269 case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
7270 desc = "FC: Aborted";
7273 case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
7274 desc = "FC: RX ID Invalid";
7277 case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
7278 desc = "FC: DID Invalid";
7281 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
7282 desc = "FC: Node Logged Out";
7285 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
7286 desc = "FC: Exchange Canceled";
7289 /****************************************************************************/
7291 /****************************************************************************/
7293 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
7294 desc = "LAN: Device not Found";
7297 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
7298 desc = "LAN: Device Failure";
7301 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
7302 desc = "LAN: Transmit Error";
7305 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
7306 desc = "LAN: Transmit Aborted";
7309 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
7310 desc = "LAN: Receive Error";
7313 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
7314 desc = "LAN: Receive Aborted";
7317 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
7318 desc = "LAN: Partial Packet";
7321 case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
7322 desc = "LAN: Canceled";
7325 /****************************************************************************/
7326 /* Serial Attached SCSI values */
7327 /****************************************************************************/
7329 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
7330 desc = "SAS: SMP Request Failed";
7333 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
7334 desc = "SAS: SMP Data Overrun";
7345 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s\n",
7346 ioc->name, status, desc));
7349 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7350 EXPORT_SYMBOL(mpt_attach);
7351 EXPORT_SYMBOL(mpt_detach);
7353 EXPORT_SYMBOL(mpt_resume);
7354 EXPORT_SYMBOL(mpt_suspend);
7356 EXPORT_SYMBOL(ioc_list);
7357 EXPORT_SYMBOL(mpt_proc_root_dir);
7358 EXPORT_SYMBOL(mpt_register);
7359 EXPORT_SYMBOL(mpt_deregister);
7360 EXPORT_SYMBOL(mpt_event_register);
7361 EXPORT_SYMBOL(mpt_event_deregister);
7362 EXPORT_SYMBOL(mpt_reset_register);
7363 EXPORT_SYMBOL(mpt_reset_deregister);
7364 EXPORT_SYMBOL(mpt_device_driver_register);
7365 EXPORT_SYMBOL(mpt_device_driver_deregister);
7366 EXPORT_SYMBOL(mpt_get_msg_frame);
7367 EXPORT_SYMBOL(mpt_put_msg_frame);
7368 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri);
7369 EXPORT_SYMBOL(mpt_free_msg_frame);
7370 EXPORT_SYMBOL(mpt_add_sge);
7371 EXPORT_SYMBOL(mpt_send_handshake_request);
7372 EXPORT_SYMBOL(mpt_verify_adapter);
7373 EXPORT_SYMBOL(mpt_GetIocState);
7374 EXPORT_SYMBOL(mpt_print_ioc_summary);
7375 EXPORT_SYMBOL(mpt_HardResetHandler);
7376 EXPORT_SYMBOL(mpt_config);
7377 EXPORT_SYMBOL(mpt_findImVolumes);
7378 EXPORT_SYMBOL(mpt_alloc_fw_memory);
7379 EXPORT_SYMBOL(mpt_free_fw_memory);
7380 EXPORT_SYMBOL(mptbase_sas_persist_operation);
7381 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
7383 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7385 * fusion_init - Fusion MPT base driver initialization routine.
7387 * Returns 0 for success, non-zero for failure.
7394 show_mptmod_ver(my_NAME, my_VERSION);
7395 printk(KERN_INFO COPYRIGHT "\n");
7397 for (cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
7398 MptCallbacks[cb_idx] = NULL;
7399 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
7400 MptEvHandlers[cb_idx] = NULL;
7401 MptResetHandlers[cb_idx] = NULL;
7404 /* Register ourselves (mptbase) in order to facilitate
7405 * EventNotification handling.
7407 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
7409 /* Register for hard reset handling callbacks.
7411 mpt_reset_register(mpt_base_index, mpt_ioc_reset);
7413 #ifdef CONFIG_PROC_FS
7414 (void) procmpt_create();
7419 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7421 * fusion_exit - Perform driver unload cleanup.
7423 * This routine frees all resources associated with each MPT adapter
7424 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
7430 mpt_reset_deregister(mpt_base_index);
7432 #ifdef CONFIG_PROC_FS
7437 module_init(fusion_init);
7438 module_exit(fusion_exit);