2 * linux/drivers/message/fusion/mptbase.c
3 * This is the Fusion MPT base driver which supports multiple
4 * (SCSI + LAN) specialized protocol drivers.
5 * For use with LSI PCI chip/adapter(s)
6 * running LSI Fusion MPT (Message Passing Technology) firmware.
8 * Copyright (c) 1999-2007 LSI Corporation
9 * (mailto:DL-MPTFusionLinux@lsi.com)
12 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; version 2 of the License.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
24 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
25 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
26 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
27 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
28 solely responsible for determining the appropriateness of using and
29 distributing the Program and assumes all risks associated with its
30 exercise of rights under this Agreement, including but not limited to
31 the risks and costs of program errors, damage to or loss of data,
32 programs or equipment, and unavailability or interruption of operations.
34 DISCLAIMER OF LIABILITY
35 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
36 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
38 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
39 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
40 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
41 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
43 You should have received a copy of the GNU General Public License
44 along with this program; if not, write to the Free Software
45 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
47 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
49 #include <linux/kernel.h>
50 #include <linux/module.h>
51 #include <linux/errno.h>
52 #include <linux/init.h>
53 #include <linux/slab.h>
54 #include <linux/types.h>
55 #include <linux/pci.h>
56 #include <linux/kdev_t.h>
57 #include <linux/blkdev.h>
58 #include <linux/delay.h>
59 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
60 #include <linux/dma-mapping.h>
67 #include "lsi/mpi_log_fc.h"
69 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
70 #define my_NAME "Fusion MPT base driver"
71 #define my_VERSION MPT_LINUX_VERSION_COMMON
72 #define MYNAM "mptbase"
74 MODULE_AUTHOR(MODULEAUTHOR);
75 MODULE_DESCRIPTION(my_NAME);
76 MODULE_LICENSE("GPL");
77 MODULE_VERSION(my_VERSION);
82 static int mpt_msi_enable;
83 module_param(mpt_msi_enable, int, 0);
84 MODULE_PARM_DESC(mpt_msi_enable, " MSI Support Enable (default=0)");
86 static int mpt_channel_mapping;
87 module_param(mpt_channel_mapping, int, 0);
88 MODULE_PARM_DESC(mpt_channel_mapping, " Mapping id's to channels (default=0)");
90 static int mpt_debug_level;
91 static int mpt_set_debug_level(const char *val, struct kernel_param *kp);
92 module_param_call(mpt_debug_level, mpt_set_debug_level, param_get_int,
93 &mpt_debug_level, 0600);
94 MODULE_PARM_DESC(mpt_debug_level, " debug level - refer to mptdebug.h - (default=0)");
97 static int mfcounter = 0;
98 #define PRINT_MF_COUNT 20000
101 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
106 struct proc_dir_entry *mpt_proc_root_dir;
108 #define WHOINIT_UNKNOWN 0xAA
110 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
114 /* Adapter link list */
116 /* Callback lookup table */
117 static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
118 /* Protocol driver class lookup table */
119 static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
120 /* Event handler lookup table */
121 static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
122 /* Reset handler lookup table */
123 static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
124 static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
126 static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq);
129 * Driver Callback Index's
131 static u8 mpt_base_index = MPT_MAX_PROTOCOL_DRIVERS;
132 static u8 last_drv_idx;
134 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
138 static irqreturn_t mpt_interrupt(int irq, void *bus_id);
139 static int mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
140 static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
141 u32 *req, int replyBytes, u16 *u16reply, int maxwait,
143 static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
144 static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
145 static void mpt_adapter_disable(MPT_ADAPTER *ioc);
146 static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
148 static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
149 static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
150 static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
151 static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
152 static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
153 static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
154 static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
155 static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
156 static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
157 static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
158 static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
159 static int PrimeIocFifos(MPT_ADAPTER *ioc);
160 static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
161 static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
162 static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
163 static int GetLanConfigPages(MPT_ADAPTER *ioc);
164 static int GetIoUnitPage2(MPT_ADAPTER *ioc);
165 int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
166 static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
167 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
168 static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
169 static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
170 static void mpt_timer_expired(unsigned long data);
171 static void mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc);
172 static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
173 static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
174 static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
175 static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
177 #ifdef CONFIG_PROC_FS
178 static int procmpt_summary_read(char *buf, char **start, off_t offset,
179 int request, int *eof, void *data);
180 static int procmpt_version_read(char *buf, char **start, off_t offset,
181 int request, int *eof, void *data);
182 static int procmpt_iocinfo_read(char *buf, char **start, off_t offset,
183 int request, int *eof, void *data);
185 static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
187 //int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
188 static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers);
189 static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
190 static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
191 static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
192 static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
193 static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
194 static void mpt_inactive_raid_list_free(MPT_ADAPTER *ioc);
196 /* module entry point */
197 static int __init fusion_init (void);
198 static void __exit fusion_exit (void);
200 #define CHIPREG_READ32(addr) readl_relaxed(addr)
201 #define CHIPREG_READ32_dmasync(addr) readl(addr)
202 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
203 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
204 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
207 pci_disable_io_access(struct pci_dev *pdev)
211 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
213 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
217 pci_enable_io_access(struct pci_dev *pdev)
221 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
223 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
226 static int mpt_set_debug_level(const char *val, struct kernel_param *kp)
228 int ret = param_set_int(val, kp);
234 list_for_each_entry(ioc, &ioc_list, list)
235 ioc->debug_level = mpt_debug_level;
240 * mpt_get_cb_idx - obtain cb_idx for registered driver
241 * @dclass: class driver enum
243 * Returns cb_idx, or zero means it wasn't found
246 mpt_get_cb_idx(MPT_DRIVER_CLASS dclass)
250 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--)
251 if (MptDriverClass[cb_idx] == dclass)
257 * Process turbo (context) reply...
260 mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
262 MPT_FRAME_HDR *mf = NULL;
263 MPT_FRAME_HDR *mr = NULL;
267 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got TURBO reply req_idx=%08x\n",
270 switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
271 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
272 req_idx = pa & 0x0000FFFF;
273 cb_idx = (pa & 0x00FF0000) >> 16;
274 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
276 case MPI_CONTEXT_REPLY_TYPE_LAN:
277 cb_idx = mpt_get_cb_idx(MPTLAN_DRIVER);
279 * Blind set of mf to NULL here was fatal
280 * after lan_reply says "freeme"
281 * Fix sort of combined with an optimization here;
282 * added explicit check for case where lan_reply
283 * was just returning 1 and doing nothing else.
284 * For this case skip the callback, but set up
285 * proper mf value first here:-)
287 if ((pa & 0x58000000) == 0x58000000) {
288 req_idx = pa & 0x0000FFFF;
289 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
290 mpt_free_msg_frame(ioc, mf);
295 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
297 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
298 cb_idx = mpt_get_cb_idx(MPTSTM_DRIVER);
299 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
306 /* Check for (valid) IO callback! */
307 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
308 MptCallbacks[cb_idx] == NULL) {
309 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
310 __FUNCTION__, ioc->name, cb_idx);
314 if (MptCallbacks[cb_idx](ioc, mf, mr))
315 mpt_free_msg_frame(ioc, mf);
321 mpt_reply(MPT_ADAPTER *ioc, u32 pa)
332 /* non-TURBO reply! Hmmm, something may be up...
333 * Newest turbo reply mechanism; get address
334 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
337 /* Map DMA address of reply header to cpu address.
338 * pa is 32 bits - but the dma address may be 32 or 64 bits
339 * get offset based only only the low addresses
342 reply_dma_low = (pa <<= 1);
343 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
344 (reply_dma_low - ioc->reply_frames_low_dma));
346 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
347 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
348 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
350 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
351 ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
352 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mr);
354 /* Check/log IOC log info
356 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
357 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
358 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
359 if (ioc->bus_type == FC)
360 mpt_fc_log_info(ioc, log_info);
361 else if (ioc->bus_type == SPI)
362 mpt_spi_log_info(ioc, log_info);
363 else if (ioc->bus_type == SAS)
364 mpt_sas_log_info(ioc, log_info);
367 if (ioc_stat & MPI_IOCSTATUS_MASK)
368 mpt_iocstatus_info(ioc, (u32)ioc_stat, mf);
370 /* Check for (valid) IO callback! */
371 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
372 MptCallbacks[cb_idx] == NULL) {
373 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
374 __FUNCTION__, ioc->name, cb_idx);
379 freeme = MptCallbacks[cb_idx](ioc, mf, mr);
382 /* Flush (non-TURBO) reply with a WRITE! */
383 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
386 mpt_free_msg_frame(ioc, mf);
390 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
392 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
393 * @irq: irq number (not used)
394 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
396 * This routine is registered via the request_irq() kernel API call,
397 * and handles all interrupts generated from a specific MPT adapter
398 * (also referred to as a IO Controller or IOC).
399 * This routine must clear the interrupt from the adapter and does
400 * so by reading the reply FIFO. Multiple replies may be processed
401 * per single call to this routine.
403 * This routine handles register-level access of the adapter but
404 * dispatches (calls) a protocol-specific callback routine to handle
405 * the protocol-specific details of the MPT request completion.
408 mpt_interrupt(int irq, void *bus_id)
410 MPT_ADAPTER *ioc = bus_id;
411 u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
413 if (pa == 0xFFFFFFFF)
417 * Drain the reply FIFO!
420 if (pa & MPI_ADDRESS_REPLY_A_BIT)
423 mpt_turbo_reply(ioc, pa);
424 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
425 } while (pa != 0xFFFFFFFF);
430 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
432 * mpt_base_reply - MPT base driver's callback routine
433 * @ioc: Pointer to MPT_ADAPTER structure
434 * @mf: Pointer to original MPT request frame
435 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
437 * MPT base driver's callback routine; all base driver
438 * "internal" request/reply processing is routed here.
439 * Currently used for EventNotification and EventAck handling.
441 * Returns 1 indicating original alloc'd request frame ptr
442 * should be freed, or 0 if it shouldn't.
445 mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
450 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply() called\n", ioc->name));
451 #ifdef CONFIG_FUSION_LOGGING
452 if ((ioc->debug_level & MPT_DEBUG_MSG_FRAME) &&
453 !(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) {
454 dmfprintk(ioc, printk(MYIOC_s_INFO_FMT ": Original request frame (@%p) header\n",
456 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)mf);
460 func = reply->u.hdr.Function;
461 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply, Function=%02Xh\n",
464 if (func == MPI_FUNCTION_EVENT_NOTIFICATION) {
465 EventNotificationReply_t *pEvReply = (EventNotificationReply_t *) reply;
469 results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
470 if (results != evHandlers) {
471 /* CHECKME! Any special handling needed here? */
472 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
473 ioc->name, evHandlers, results));
477 * Hmmm... It seems that EventNotificationReply is an exception
478 * to the rule of one reply per request.
480 if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) {
483 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
484 ioc->name, pEvReply));
487 #ifdef CONFIG_PROC_FS
488 // LogEvent(ioc, pEvReply);
491 } else if (func == MPI_FUNCTION_EVENT_ACK) {
492 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply, EventAck reply received\n",
494 } else if (func == MPI_FUNCTION_CONFIG) {
498 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "config_complete (mf=%p,mr=%p)\n",
499 ioc->name, mf, reply));
501 pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *)));
504 /* disable timer and remove from linked list */
505 del_timer(&pCfg->timer);
507 spin_lock_irqsave(&ioc->FreeQlock, flags);
508 list_del(&pCfg->linkage);
509 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
512 * If IOC Status is SUCCESS, save the header
513 * and set the status code to GOOD.
515 pCfg->status = MPT_CONFIG_ERROR;
517 ConfigReply_t *pReply = (ConfigReply_t *)reply;
520 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
521 dcprintk(ioc, printk(MYIOC_s_NOTE_FMT " IOCStatus=%04xh, IOCLogInfo=%08xh\n",
522 ioc->name, status, le32_to_cpu(pReply->IOCLogInfo)));
524 pCfg->status = status;
525 if (status == MPI_IOCSTATUS_SUCCESS) {
526 if ((pReply->Header.PageType &
527 MPI_CONFIG_PAGETYPE_MASK) ==
528 MPI_CONFIG_PAGETYPE_EXTENDED) {
529 pCfg->cfghdr.ehdr->ExtPageLength =
530 le16_to_cpu(pReply->ExtPageLength);
531 pCfg->cfghdr.ehdr->ExtPageType =
534 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
536 /* If this is a regular header, save PageLength. */
537 /* LMP Do this better so not using a reserved field! */
538 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
539 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
540 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
545 * Wake up the original calling thread
550 } else if (func == MPI_FUNCTION_SAS_IO_UNIT_CONTROL) {
551 /* we should be always getting a reply frame */
552 memcpy(ioc->persist_reply_frame, reply,
553 min(MPT_DEFAULT_FRAME_SIZE,
554 4*reply->u.reply.MsgLength));
555 del_timer(&ioc->persist_timer);
556 ioc->persist_wait_done = 1;
559 printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
564 * Conditionally tell caller to free the original
565 * EventNotification/EventAck/unexpected request frame!
570 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
572 * mpt_register - Register protocol-specific main callback handler.
573 * @cbfunc: callback function pointer
574 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
576 * This routine is called by a protocol-specific driver (SCSI host,
577 * LAN, SCSI target) to register its reply callback routine. Each
578 * protocol-specific driver must do this before it will be able to
579 * use any IOC resources, such as obtaining request frames.
581 * NOTES: The SCSI protocol driver currently calls this routine thrice
582 * in order to register separate callbacks; one for "normal" SCSI IO;
583 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
585 * Returns u8 valued "handle" in the range (and S.O.D. order)
586 * {N,...,7,6,5,...,1} if successful.
587 * A return value of MPT_MAX_PROTOCOL_DRIVERS (including zero!) should be
588 * considered an error by the caller.
591 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
594 last_drv_idx = MPT_MAX_PROTOCOL_DRIVERS;
597 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
598 * (slot/handle 0 is reserved!)
600 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
601 if (MptCallbacks[cb_idx] == NULL) {
602 MptCallbacks[cb_idx] = cbfunc;
603 MptDriverClass[cb_idx] = dclass;
604 MptEvHandlers[cb_idx] = NULL;
605 last_drv_idx = cb_idx;
613 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
615 * mpt_deregister - Deregister a protocol drivers resources.
616 * @cb_idx: previously registered callback handle
618 * Each protocol-specific driver should call this routine when its
619 * module is unloaded.
622 mpt_deregister(u8 cb_idx)
624 if (cb_idx && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
625 MptCallbacks[cb_idx] = NULL;
626 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
627 MptEvHandlers[cb_idx] = NULL;
633 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
635 * mpt_event_register - Register protocol-specific event callback
637 * @cb_idx: previously registered (via mpt_register) callback handle
638 * @ev_cbfunc: callback function
640 * This routine can be called by one or more protocol-specific drivers
641 * if/when they choose to be notified of MPT events.
643 * Returns 0 for success.
646 mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc)
648 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
651 MptEvHandlers[cb_idx] = ev_cbfunc;
655 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
657 * mpt_event_deregister - Deregister protocol-specific event callback
659 * @cb_idx: previously registered callback handle
661 * Each protocol-specific driver should call this routine
662 * when it does not (or can no longer) handle events,
663 * or when its module is unloaded.
666 mpt_event_deregister(u8 cb_idx)
668 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
671 MptEvHandlers[cb_idx] = NULL;
674 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
676 * mpt_reset_register - Register protocol-specific IOC reset handler.
677 * @cb_idx: previously registered (via mpt_register) callback handle
678 * @reset_func: reset function
680 * This routine can be called by one or more protocol-specific drivers
681 * if/when they choose to be notified of IOC resets.
683 * Returns 0 for success.
686 mpt_reset_register(u8 cb_idx, MPT_RESETHANDLER reset_func)
688 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
691 MptResetHandlers[cb_idx] = reset_func;
695 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
697 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
698 * @cb_idx: previously registered callback handle
700 * Each protocol-specific driver should call this routine
701 * when it does not (or can no longer) handle IOC reset handling,
702 * or when its module is unloaded.
705 mpt_reset_deregister(u8 cb_idx)
707 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
710 MptResetHandlers[cb_idx] = NULL;
713 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
715 * mpt_device_driver_register - Register device driver hooks
716 * @dd_cbfunc: driver callbacks struct
717 * @cb_idx: MPT protocol driver index
720 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, u8 cb_idx)
723 const struct pci_device_id *id;
725 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
728 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
730 /* call per pci device probe entry point */
731 list_for_each_entry(ioc, &ioc_list, list) {
732 id = ioc->pcidev->driver ?
733 ioc->pcidev->driver->id_table : NULL;
734 if (dd_cbfunc->probe)
735 dd_cbfunc->probe(ioc->pcidev, id);
741 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
743 * mpt_device_driver_deregister - DeRegister device driver hooks
744 * @cb_idx: MPT protocol driver index
747 mpt_device_driver_deregister(u8 cb_idx)
749 struct mpt_pci_driver *dd_cbfunc;
752 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
755 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
757 list_for_each_entry(ioc, &ioc_list, list) {
758 if (dd_cbfunc->remove)
759 dd_cbfunc->remove(ioc->pcidev);
762 MptDeviceDriverHandlers[cb_idx] = NULL;
766 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
768 * mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024)
769 * allocated per MPT adapter.
770 * @cb_idx: Handle of registered MPT protocol driver
771 * @ioc: Pointer to MPT adapter structure
773 * Returns pointer to a MPT request frame or %NULL if none are available
774 * or IOC is not active.
777 mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc)
781 u16 req_idx; /* Request index */
783 /* validate handle and ioc identifier */
787 printk(MYIOC_s_WARN_FMT "IOC Not Active! mpt_get_msg_frame "
788 "returning NULL!\n", ioc->name);
791 /* If interrupts are not attached, do not return a request frame */
795 spin_lock_irqsave(&ioc->FreeQlock, flags);
796 if (!list_empty(&ioc->FreeQ)) {
799 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
800 u.frame.linkage.list);
801 list_del(&mf->u.frame.linkage.list);
802 mf->u.frame.linkage.arg1 = 0;
803 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
804 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
806 req_idx = req_offset / ioc->req_sz;
807 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
808 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
809 /* Default, will be changed if necessary in SG generation */
810 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame;
817 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
821 printk(MYIOC_s_WARN_FMT "IOC Active. No free Msg Frames! "
822 "Count 0x%x Max 0x%x\n", ioc->name, ioc->mfcnt,
825 if (mfcounter == PRINT_MF_COUNT)
826 printk(MYIOC_s_INFO_FMT "MF Count 0x%x Max 0x%x \n", ioc->name,
827 ioc->mfcnt, ioc->req_depth);
830 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_get_msg_frame(%d,%d), got mf=%p\n",
831 ioc->name, cb_idx, ioc->id, mf));
835 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
837 * mpt_put_msg_frame - Send a protocol specific MPT request frame
839 * @cb_idx: Handle of registered MPT protocol driver
840 * @ioc: Pointer to MPT adapter structure
841 * @mf: Pointer to MPT request frame
843 * This routine posts a MPT request frame to the request post FIFO of a
844 * specific MPT adapter.
847 mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
851 u16 req_idx; /* Request index */
853 /* ensure values are reset properly! */
854 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
855 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
857 req_idx = req_offset / ioc->req_sz;
858 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
859 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
861 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
863 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
864 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d "
865 "RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx,
866 ioc->RequestNB[req_idx]));
867 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
871 * mpt_put_msg_frame_hi_pri - Send a protocol specific MPT request frame
872 * to a IOC using hi priority request queue.
873 * @cb_idx: Handle of registered MPT protocol driver
874 * @ioc: Pointer to MPT adapter structure
875 * @mf: Pointer to MPT request frame
877 * This routine posts a MPT request frame to the request post FIFO of a
878 * specific MPT adapter.
881 mpt_put_msg_frame_hi_pri(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
885 u16 req_idx; /* Request index */
887 /* ensure values are reset properly! */
888 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
889 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
890 req_idx = req_offset / ioc->req_sz;
891 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
892 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
894 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
896 mf_dma_addr = (ioc->req_frames_low_dma + req_offset);
897 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d\n",
898 ioc->name, mf_dma_addr, req_idx));
899 CHIPREG_WRITE32(&ioc->chip->RequestHiPriFifo, mf_dma_addr);
902 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
904 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
905 * @handle: Handle of registered MPT protocol driver
906 * @ioc: Pointer to MPT adapter structure
907 * @mf: Pointer to MPT request frame
909 * This routine places a MPT request frame back on the MPT adapter's
913 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
917 /* Put Request back on FreeQ! */
918 spin_lock_irqsave(&ioc->FreeQlock, flags);
919 mf->u.frame.linkage.arg1 = 0xdeadbeaf; /* signature to know if this mf is freed */
920 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
924 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
927 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
929 * mpt_add_sge - Place a simple SGE at address pAddr.
930 * @pAddr: virtual address for SGE
931 * @flagslength: SGE flags and data transfer length
932 * @dma_addr: Physical address
934 * This routine places a MPT request frame back on the MPT adapter's
938 mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
940 if (sizeof(dma_addr_t) == sizeof(u64)) {
941 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
942 u32 tmp = dma_addr & 0xFFFFFFFF;
944 pSge->FlagsLength = cpu_to_le32(flagslength);
945 pSge->Address.Low = cpu_to_le32(tmp);
946 tmp = (u32) ((u64)dma_addr >> 32);
947 pSge->Address.High = cpu_to_le32(tmp);
950 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
951 pSge->FlagsLength = cpu_to_le32(flagslength);
952 pSge->Address = cpu_to_le32(dma_addr);
956 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
958 * mpt_send_handshake_request - Send MPT request via doorbell handshake method.
959 * @cb_idx: Handle of registered MPT protocol driver
960 * @ioc: Pointer to MPT adapter structure
961 * @reqBytes: Size of the request in bytes
962 * @req: Pointer to MPT request frame
963 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
965 * This routine is used exclusively to send MptScsiTaskMgmt
966 * requests since they are required to be sent via doorbell handshake.
968 * NOTE: It is the callers responsibility to byte-swap fields in the
969 * request which are greater than 1 byte in size.
971 * Returns 0 for success, non-zero for failure.
974 mpt_send_handshake_request(u8 cb_idx, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
980 /* State is known to be good upon entering
981 * this function so issue the bus reset
986 * Emulate what mpt_put_msg_frame() does /wrt to sanity
987 * setting cb_idx/req_idx. But ONLY if this request
988 * is in proper (pre-alloc'd) request buffer range...
990 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
991 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
992 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
993 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
994 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
997 /* Make sure there are no doorbells */
998 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1000 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1001 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
1002 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
1004 /* Wait for IOC doorbell int */
1005 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
1009 /* Read doorbell and check for active bit */
1010 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
1013 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_send_handshake_request start, WaitCnt=%d\n",
1016 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1018 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1022 /* Send request via doorbell handshake */
1023 req_as_bytes = (u8 *) req;
1024 for (ii = 0; ii < reqBytes/4; ii++) {
1027 word = ((req_as_bytes[(ii*4) + 0] << 0) |
1028 (req_as_bytes[(ii*4) + 1] << 8) |
1029 (req_as_bytes[(ii*4) + 2] << 16) |
1030 (req_as_bytes[(ii*4) + 3] << 24));
1031 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
1032 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1038 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
1043 /* Make sure there are no doorbells */
1044 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1049 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1051 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
1052 * @ioc: Pointer to MPT adapter structure
1053 * @access_control_value: define bits below
1054 * @sleepFlag: Specifies whether the process can sleep
1056 * Provides mechanism for the host driver to control the IOC's
1057 * Host Page Buffer access.
1059 * Access Control Value - bits[15:12]
1061 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1062 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1063 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1065 * Returns 0 for success, non-zero for failure.
1069 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1073 /* return if in use */
1074 if (CHIPREG_READ32(&ioc->chip->Doorbell)
1075 & MPI_DOORBELL_ACTIVE)
1078 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1080 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1081 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1082 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1083 (access_control_value<<12)));
1085 /* Wait for IOC to clear Doorbell Status bit */
1086 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1092 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1094 * mpt_host_page_alloc - allocate system memory for the fw
1095 * @ioc: Pointer to pointer to IOC adapter
1096 * @ioc_init: Pointer to ioc init config page
1098 * If we already allocated memory in past, then resend the same pointer.
1099 * Returns 0 for success, non-zero for failure.
1102 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1106 u32 host_page_buffer_sz=0;
1108 if(!ioc->HostPageBuffer) {
1110 host_page_buffer_sz =
1111 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1113 if(!host_page_buffer_sz)
1114 return 0; /* fw doesn't need any host buffers */
1116 /* spin till we get enough memory */
1117 while(host_page_buffer_sz > 0) {
1119 if((ioc->HostPageBuffer = pci_alloc_consistent(
1121 host_page_buffer_sz,
1122 &ioc->HostPageBuffer_dma)) != NULL) {
1124 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1125 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1126 ioc->name, ioc->HostPageBuffer,
1127 (u32)ioc->HostPageBuffer_dma,
1128 host_page_buffer_sz));
1129 ioc->alloc_total += host_page_buffer_sz;
1130 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1134 host_page_buffer_sz -= (4*1024);
1138 if(!ioc->HostPageBuffer) {
1139 printk(MYIOC_s_ERR_FMT
1140 "Failed to alloc memory for host_page_buffer!\n",
1145 psge = (char *)&ioc_init->HostPageBufferSGE;
1146 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1147 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1148 MPI_SGE_FLAGS_32_BIT_ADDRESSING |
1149 MPI_SGE_FLAGS_HOST_TO_IOC |
1150 MPI_SGE_FLAGS_END_OF_BUFFER;
1151 if (sizeof(dma_addr_t) == sizeof(u64)) {
1152 flags_length |= MPI_SGE_FLAGS_64_BIT_ADDRESSING;
1154 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1155 flags_length |= ioc->HostPageBuffer_sz;
1156 mpt_add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1157 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1162 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1164 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1165 * @iocid: IOC unique identifier (integer)
1166 * @iocpp: Pointer to pointer to IOC adapter
1168 * Given a unique IOC identifier, set pointer to the associated MPT
1169 * adapter structure.
1171 * Returns iocid and sets iocpp if iocid is found.
1172 * Returns -1 if iocid is not found.
1175 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1179 list_for_each_entry(ioc,&ioc_list,list) {
1180 if (ioc->id == iocid) {
1191 * mpt_get_product_name - returns product string
1192 * @vendor: pci vendor id
1193 * @device: pci device id
1194 * @revision: pci revision id
1195 * @prod_name: string returned
1197 * Returns product string displayed when driver loads,
1198 * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1202 mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name)
1204 char *product_str = NULL;
1206 if (vendor == PCI_VENDOR_ID_BROCADE) {
1209 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1213 product_str = "BRE040 A0";
1216 product_str = "BRE040 A1";
1219 product_str = "BRE040";
1229 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1230 product_str = "LSIFC909 B1";
1232 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1233 product_str = "LSIFC919 B0";
1235 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1236 product_str = "LSIFC929 B0";
1238 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1239 if (revision < 0x80)
1240 product_str = "LSIFC919X A0";
1242 product_str = "LSIFC919XL A1";
1244 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1245 if (revision < 0x80)
1246 product_str = "LSIFC929X A0";
1248 product_str = "LSIFC929XL A1";
1250 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1251 product_str = "LSIFC939X A1";
1253 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1254 product_str = "LSIFC949X A1";
1256 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1260 product_str = "LSIFC949E A0";
1263 product_str = "LSIFC949E A1";
1266 product_str = "LSIFC949E";
1270 case MPI_MANUFACTPAGE_DEVID_53C1030:
1274 product_str = "LSI53C1030 A0";
1277 product_str = "LSI53C1030 B0";
1280 product_str = "LSI53C1030 B1";
1283 product_str = "LSI53C1030 B2";
1286 product_str = "LSI53C1030 C0";
1289 product_str = "LSI53C1030T A0";
1292 product_str = "LSI53C1030T A2";
1295 product_str = "LSI53C1030T A3";
1298 product_str = "LSI53C1020A A1";
1301 product_str = "LSI53C1030";
1305 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1309 product_str = "LSI53C1035 A2";
1312 product_str = "LSI53C1035 B0";
1315 product_str = "LSI53C1035";
1319 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1323 product_str = "LSISAS1064 A1";
1326 product_str = "LSISAS1064 A2";
1329 product_str = "LSISAS1064 A3";
1332 product_str = "LSISAS1064 A4";
1335 product_str = "LSISAS1064";
1339 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1343 product_str = "LSISAS1064E A0";
1346 product_str = "LSISAS1064E B0";
1349 product_str = "LSISAS1064E B1";
1352 product_str = "LSISAS1064E B2";
1355 product_str = "LSISAS1064E B3";
1358 product_str = "LSISAS1064E";
1362 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1366 product_str = "LSISAS1068 A0";
1369 product_str = "LSISAS1068 B0";
1372 product_str = "LSISAS1068 B1";
1375 product_str = "LSISAS1068";
1379 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1383 product_str = "LSISAS1068E A0";
1386 product_str = "LSISAS1068E B0";
1389 product_str = "LSISAS1068E B1";
1392 product_str = "LSISAS1068E B2";
1395 product_str = "LSISAS1068E B3";
1398 product_str = "LSISAS1068E";
1402 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1406 product_str = "LSISAS1078 A0";
1409 product_str = "LSISAS1078 B0";
1412 product_str = "LSISAS1078 C0";
1415 product_str = "LSISAS1078 C1";
1418 product_str = "LSISAS1078 C2";
1421 product_str = "LSISAS1078";
1429 sprintf(prod_name, "%s", product_str);
1432 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1434 * mpt_attach - Install a PCI intelligent MPT adapter.
1435 * @pdev: Pointer to pci_dev structure
1436 * @id: PCI device ID information
1438 * This routine performs all the steps necessary to bring the IOC of
1439 * a MPT adapter to a OPERATIONAL state. This includes registering
1440 * memory regions, registering the interrupt, and allocating request
1441 * and reply memory pools.
1443 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1446 * Returns 0 for success, non-zero for failure.
1448 * TODO: Add support for polled controllers
1451 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1456 unsigned long mem_phys;
1465 static int mpt_ids = 0;
1466 #ifdef CONFIG_PROC_FS
1467 struct proc_dir_entry *dent, *ent;
1470 if (mpt_debug_level)
1471 printk(KERN_INFO MYNAM ": mpt_debug_level=%xh\n", mpt_debug_level);
1473 if (pci_enable_device(pdev))
1476 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1478 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1481 ioc->debug_level = mpt_debug_level;
1482 ioc->id = mpt_ids++;
1483 sprintf(ioc->name, "ioc%d", ioc->id);
1485 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name));
1487 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
1488 dprintk(ioc, printk(MYIOC_s_INFO_FMT
1489 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n", ioc->name));
1490 } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
1491 printk(MYIOC_s_WARN_FMT ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n",
1497 if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
1498 dprintk(ioc, printk(MYIOC_s_INFO_FMT
1499 ": Using 64 bit consistent mask\n", ioc->name));
1501 dprintk(ioc, printk(MYIOC_s_INFO_FMT
1502 ": Not using 64 bit consistent mask\n", ioc->name));
1505 ioc->alloc_total = sizeof(MPT_ADAPTER);
1506 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1507 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1510 ioc->diagPending = 0;
1511 spin_lock_init(&ioc->diagLock);
1512 spin_lock_init(&ioc->initializing_hba_lock);
1514 /* Initialize the event logging.
1516 ioc->eventTypes = 0; /* None */
1517 ioc->eventContext = 0;
1518 ioc->eventLogSize = 0;
1525 ioc->cached_fw = NULL;
1527 /* Initilize SCSI Config Data structure
1529 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1531 /* Initialize the running configQ head.
1533 INIT_LIST_HEAD(&ioc->configQ);
1535 /* Initialize the fc rport list head.
1537 INIT_LIST_HEAD(&ioc->fc_rports);
1539 /* Find lookup slot. */
1540 INIT_LIST_HEAD(&ioc->list);
1542 mem_phys = msize = 0;
1544 for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1545 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1548 /* Get I/O space! */
1549 port = pci_resource_start(pdev, ii);
1550 psize = pci_resource_len(pdev,ii);
1555 mem_phys = pci_resource_start(pdev, ii);
1556 msize = pci_resource_len(pdev,ii);
1559 ioc->mem_size = msize;
1562 /* Get logical ptr for PciMem0 space */
1563 /*mem = ioremap(mem_phys, msize);*/
1564 mem = ioremap(mem_phys, msize);
1566 printk(MYIOC_s_ERR_FMT "Unable to map adapter memory!\n", ioc->name);
1571 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %lx\n", ioc->name, mem, mem_phys));
1573 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",
1574 ioc->name, &ioc->facts, &ioc->pfacts[0]));
1576 ioc->mem_phys = mem_phys;
1577 ioc->chip = (SYSIF_REGS __iomem *)mem;
1579 /* Save Port IO values in case we need to do downloadboot */
1580 ioc->pio_mem_phys = port;
1581 pmem = (u8 __iomem *)port;
1582 ioc->pio_chip = (SYSIF_REGS __iomem *)pmem;
1584 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1585 mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name);
1587 switch (pdev->device)
1589 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1590 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1591 ioc->errata_flag_1064 = 1;
1592 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1593 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1594 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1595 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1599 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1600 if (revision < XL_929) {
1601 /* 929X Chip Fix. Set Split transactions level
1602 * for PCIX. Set MOST bits to zero.
1604 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1606 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1608 /* 929XL Chip Fix. Set MMRBC to 0x08.
1610 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1612 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1617 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1618 /* 919X Chip Fix. Set Split transactions level
1619 * for PCIX. Set MOST bits to zero.
1621 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1623 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1627 case MPI_MANUFACTPAGE_DEVID_53C1030:
1628 /* 1030 Chip Fix. Disable Split transactions
1629 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1631 if (revision < C0_1030) {
1632 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1634 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1637 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1638 ioc->bus_type = SPI;
1641 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1642 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1643 ioc->errata_flag_1064 = 1;
1645 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1646 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1647 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1648 ioc->bus_type = SAS;
1651 if (ioc->errata_flag_1064)
1652 pci_disable_io_access(pdev);
1654 spin_lock_init(&ioc->FreeQlock);
1657 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1659 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1661 /* Set lookup ptr. */
1662 list_add_tail(&ioc->list, &ioc_list);
1664 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1666 mpt_detect_bound_ports(ioc, pdev);
1668 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1670 printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",
1673 list_del(&ioc->list);
1675 ioc->alt_ioc->alt_ioc = NULL;
1678 pci_set_drvdata(pdev, NULL);
1682 /* call per device driver probe entry point */
1683 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
1684 if(MptDeviceDriverHandlers[cb_idx] &&
1685 MptDeviceDriverHandlers[cb_idx]->probe) {
1686 MptDeviceDriverHandlers[cb_idx]->probe(pdev,id);
1690 #ifdef CONFIG_PROC_FS
1692 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1694 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1696 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1698 ent->read_proc = procmpt_iocinfo_read;
1701 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1703 ent->read_proc = procmpt_summary_read;
1712 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1714 * mpt_detach - Remove a PCI intelligent MPT adapter.
1715 * @pdev: Pointer to pci_dev structure
1719 mpt_detach(struct pci_dev *pdev)
1721 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1725 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
1726 remove_proc_entry(pname, NULL);
1727 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
1728 remove_proc_entry(pname, NULL);
1729 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
1730 remove_proc_entry(pname, NULL);
1732 /* call per device driver remove entry point */
1733 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
1734 if(MptDeviceDriverHandlers[cb_idx] &&
1735 MptDeviceDriverHandlers[cb_idx]->remove) {
1736 MptDeviceDriverHandlers[cb_idx]->remove(pdev);
1740 /* Disable interrupts! */
1741 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1744 synchronize_irq(pdev->irq);
1746 /* Clear any lingering interrupt */
1747 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1749 CHIPREG_READ32(&ioc->chip->IntStatus);
1751 mpt_adapter_dispose(ioc);
1753 pci_set_drvdata(pdev, NULL);
1756 /**************************************************************************
1760 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1762 * mpt_suspend - Fusion MPT base driver suspend routine.
1763 * @pdev: Pointer to pci_dev structure
1764 * @state: new state to enter
1767 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
1770 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1772 device_state=pci_choose_state(pdev, state);
1774 printk(MYIOC_s_INFO_FMT
1775 "pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
1776 ioc->name, pdev, pci_name(pdev), device_state);
1778 pci_save_state(pdev);
1780 /* put ioc into READY_STATE */
1781 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
1782 printk(MYIOC_s_ERR_FMT
1783 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
1786 /* disable interrupts */
1787 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1790 /* Clear any lingering interrupt */
1791 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1793 pci_disable_device(pdev);
1794 pci_set_power_state(pdev, device_state);
1799 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1801 * mpt_resume - Fusion MPT base driver resume routine.
1802 * @pdev: Pointer to pci_dev structure
1805 mpt_resume(struct pci_dev *pdev)
1807 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1808 u32 device_state = pdev->current_state;
1812 printk(MYIOC_s_INFO_FMT
1813 "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
1814 ioc->name, pdev, pci_name(pdev), device_state);
1816 pci_set_power_state(pdev, 0);
1817 pci_restore_state(pdev);
1818 err = pci_enable_device(pdev);
1822 /* enable interrupts */
1823 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
1826 printk(MYIOC_s_INFO_FMT
1827 "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1829 (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1830 CHIPREG_READ32(&ioc->chip->Doorbell));
1832 /* bring ioc to operational state */
1833 if ((recovery_state = mpt_do_ioc_recovery(ioc,
1834 MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {
1835 printk(MYIOC_s_INFO_FMT
1836 "pci-resume: Cannot recover, error:[%x]\n",
1837 ioc->name, recovery_state);
1839 printk(MYIOC_s_INFO_FMT
1840 "pci-resume: success\n", ioc->name);
1848 mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase)
1850 if ((MptDriverClass[index] == MPTSPI_DRIVER &&
1851 ioc->bus_type != SPI) ||
1852 (MptDriverClass[index] == MPTFC_DRIVER &&
1853 ioc->bus_type != FC) ||
1854 (MptDriverClass[index] == MPTSAS_DRIVER &&
1855 ioc->bus_type != SAS))
1856 /* make sure we only call the relevant reset handler
1859 return (MptResetHandlers[index])(ioc, reset_phase);
1862 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1864 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1865 * @ioc: Pointer to MPT adapter structure
1866 * @reason: Event word / reason
1867 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1869 * This routine performs all the steps necessary to bring the IOC
1870 * to a OPERATIONAL state.
1872 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1877 * -1 if failed to get board READY
1878 * -2 if READY but IOCFacts Failed
1879 * -3 if READY but PrimeIOCFifos Failed
1880 * -4 if READY but IOCInit Failed
1883 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1885 int hard_reset_done = 0;
1886 int alt_ioc_ready = 0;
1893 int reset_alt_ioc_active = 0;
1894 int irq_allocated = 0;
1897 printk(MYIOC_s_INFO_FMT "Initiating %s\n", ioc->name,
1898 reason == MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
1900 /* Disable reply interrupts (also blocks FreeQ) */
1901 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1905 if (ioc->alt_ioc->active)
1906 reset_alt_ioc_active = 1;
1908 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1909 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
1910 ioc->alt_ioc->active = 0;
1914 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
1917 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
1918 if (hard_reset_done == -4) {
1919 printk(MYIOC_s_WARN_FMT "Owned by PEER..skipping!\n",
1922 if (reset_alt_ioc_active && ioc->alt_ioc) {
1923 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1924 dprintk(ioc, printk(MYIOC_s_INFO_FMT
1925 "alt_ioc reply irq re-enabled\n", ioc->alt_ioc->name));
1926 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
1927 ioc->alt_ioc->active = 1;
1931 printk(MYIOC_s_WARN_FMT "NOT READY!\n", ioc->name);
1936 /* hard_reset_done = 0 if a soft reset was performed
1937 * and 1 if a hard reset was performed.
1939 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
1940 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
1943 printk(MYIOC_s_WARN_FMT "alt_ioc not ready!\n", ioc->alt_ioc->name);
1946 for (ii=0; ii<5; ii++) {
1947 /* Get IOC facts! Allow 5 retries */
1948 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
1954 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1955 "Retry IocFacts failed rc=%x\n", ioc->name, rc));
1957 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1958 MptDisplayIocCapabilities(ioc);
1961 if (alt_ioc_ready) {
1962 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
1963 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1964 "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
1965 /* Retry - alt IOC was initialized once
1967 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
1970 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1971 "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
1973 reset_alt_ioc_active = 0;
1974 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1975 MptDisplayIocCapabilities(ioc->alt_ioc);
1980 * Device is reset now. It must have de-asserted the interrupt line
1981 * (if it was asserted) and it should be safe to register for the
1984 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1986 if (ioc->pcidev->irq) {
1987 if (mpt_msi_enable && !pci_enable_msi(ioc->pcidev))
1988 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
1990 rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
1991 IRQF_SHARED, ioc->name, ioc);
1993 printk(MYIOC_s_ERR_FMT "Unable to allocate "
1994 "interrupt %d!\n", ioc->name, ioc->pcidev->irq);
1996 pci_disable_msi(ioc->pcidev);
2000 ioc->pci_irq = ioc->pcidev->irq;
2001 pci_set_master(ioc->pcidev); /* ?? */
2002 pci_set_drvdata(ioc->pcidev, ioc);
2003 dprintk(ioc, printk(MYIOC_s_INFO_FMT "installed at interrupt "
2004 "%d\n", ioc->name, ioc->pcidev->irq));
2008 /* Prime reply & request queues!
2009 * (mucho alloc's) Must be done prior to
2010 * init as upper addresses are needed for init.
2011 * If fails, continue with alt-ioc processing
2013 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
2016 /* May need to check/upload firmware & data here!
2017 * If fails, continue with alt-ioc processing
2019 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
2022 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
2023 printk(MYIOC_s_WARN_FMT ": alt_ioc (%d) FIFO mgmt alloc!\n",
2024 ioc->alt_ioc->name, rc);
2026 reset_alt_ioc_active = 0;
2029 if (alt_ioc_ready) {
2030 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
2032 reset_alt_ioc_active = 0;
2033 printk(MYIOC_s_WARN_FMT "alt_ioc (%d) init failure!\n",
2034 ioc->alt_ioc->name, rc);
2038 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
2039 if (ioc->upload_fw) {
2040 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2041 "firmware upload required!\n", ioc->name));
2043 /* Controller is not operational, cannot do upload
2046 rc = mpt_do_upload(ioc, sleepFlag);
2048 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2050 * Maintain only one pointer to FW memory
2051 * so there will not be two attempt to
2052 * downloadboot onboard dual function
2053 * chips (mpt_adapter_disable,
2056 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2057 "mpt_upload: alt_%s has cached_fw=%p \n",
2058 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
2059 ioc->cached_fw = NULL;
2062 printk(MYIOC_s_WARN_FMT
2063 "firmware upload failure!\n", ioc->name);
2071 /* Enable! (reply interrupt) */
2072 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
2076 if (reset_alt_ioc_active && ioc->alt_ioc) {
2077 /* (re)Enable alt-IOC! (reply interrupt) */
2078 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "alt_ioc reply irq re-enabled\n",
2079 ioc->alt_ioc->name));
2080 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2081 ioc->alt_ioc->active = 1;
2084 /* Enable MPT base driver management of EventNotification
2085 * and EventAck handling.
2087 if ((ret == 0) && (!ioc->facts.EventState))
2088 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
2090 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2091 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
2093 /* Add additional "reason" check before call to GetLanConfigPages
2094 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2095 * recursive scenario; GetLanConfigPages times out, timer expired
2096 * routine calls HardResetHandler, which calls into here again,
2097 * and we try GetLanConfigPages again...
2099 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2102 * Initalize link list for inactive raid volumes.
2104 init_MUTEX(&ioc->raid_data.inactive_list_mutex);
2105 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2107 if (ioc->bus_type == SAS) {
2109 /* clear persistency table */
2110 if(ioc->facts.IOCExceptions &
2111 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
2112 ret = mptbase_sas_persist_operation(ioc,
2113 MPI_SAS_OP_CLEAR_NOT_PRESENT);
2120 mpt_findImVolumes(ioc);
2122 } else if (ioc->bus_type == FC) {
2123 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
2124 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2126 * Pre-fetch the ports LAN MAC address!
2127 * (LANPage1_t stuff)
2129 (void) GetLanConfigPages(ioc);
2130 a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2131 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2132 "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
2133 ioc->name, a[5], a[4], a[3], a[2], a[1], a[0]));
2137 /* Get NVRAM and adapter maximums from SPP 0 and 2
2139 mpt_GetScsiPortSettings(ioc, 0);
2141 /* Get version and length of SDP 1
2143 mpt_readScsiDevicePageHeaders(ioc, 0);
2147 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
2148 mpt_findImVolumes(ioc);
2150 /* Check, and possibly reset, the coalescing value
2152 mpt_read_ioc_pg_1(ioc);
2154 mpt_read_ioc_pg_4(ioc);
2157 GetIoUnitPage2(ioc);
2158 mpt_get_manufacturing_pg_0(ioc);
2162 * Call each currently registered protocol IOC reset handler
2163 * with post-reset indication.
2164 * NOTE: If we're doing _IOC_BRINGUP, there can be no
2165 * MptResetHandlers[] registered yet.
2167 if (hard_reset_done) {
2169 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
2170 if ((ret == 0) && MptResetHandlers[cb_idx]) {
2171 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2172 "Calling IOC post_reset handler #%d\n",
2173 ioc->name, cb_idx));
2174 rc += mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET);
2178 if (alt_ioc_ready && MptResetHandlers[cb_idx]) {
2179 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2180 "Calling IOC post_reset handler #%d\n",
2181 ioc->alt_ioc->name, cb_idx));
2182 rc += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_POST_RESET);
2186 /* FIXME? Examine results here? */
2190 if ((ret != 0) && irq_allocated) {
2191 free_irq(ioc->pci_irq, ioc);
2193 pci_disable_msi(ioc->pcidev);
2198 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2200 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2201 * @ioc: Pointer to MPT adapter structure
2202 * @pdev: Pointer to (struct pci_dev) structure
2204 * Search for PCI bus/dev_function which matches
2205 * PCI bus/dev_function (+/-1) for newly discovered 929,
2206 * 929X, 1030 or 1035.
2208 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2209 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2212 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
2214 struct pci_dev *peer=NULL;
2215 unsigned int slot = PCI_SLOT(pdev->devfn);
2216 unsigned int func = PCI_FUNC(pdev->devfn);
2217 MPT_ADAPTER *ioc_srch;
2219 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PCI device %s devfn=%x/%x,"
2220 " searching for devfn match on %x or %x\n",
2221 ioc->name, pci_name(pdev), pdev->bus->number,
2222 pdev->devfn, func-1, func+1));
2224 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
2226 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
2231 list_for_each_entry(ioc_srch, &ioc_list, list) {
2232 struct pci_dev *_pcidev = ioc_srch->pcidev;
2233 if (_pcidev == peer) {
2234 /* Paranoia checks */
2235 if (ioc->alt_ioc != NULL) {
2236 printk(MYIOC_s_WARN_FMT "Oops, already bound to %s!\n",
2237 ioc->name, ioc->alt_ioc->name);
2239 } else if (ioc_srch->alt_ioc != NULL) {
2240 printk(MYIOC_s_WARN_FMT "Oops, already bound to %s!\n",
2241 ioc_srch->name, ioc_srch->alt_ioc->name);
2244 dprintk(ioc, printk(MYIOC_s_INFO_FMT "FOUND! binding to %s\n",
2245 ioc->name, ioc_srch->name));
2246 ioc_srch->alt_ioc = ioc;
2247 ioc->alt_ioc = ioc_srch;
2253 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2255 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2256 * @ioc: Pointer to MPT adapter structure
2259 mpt_adapter_disable(MPT_ADAPTER *ioc)
2264 if (ioc->cached_fw != NULL) {
2265 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: Pushing FW onto "
2266 "adapter\n", __FUNCTION__, ioc->name));
2267 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)
2268 ioc->cached_fw, CAN_SLEEP)) < 0) {
2269 printk(MYIOC_s_WARN_FMT
2270 ": firmware downloadboot failure (%d)!\n",
2275 /* Disable adapter interrupts! */
2276 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2278 /* Clear any lingering interrupt */
2279 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2281 if (ioc->alloc != NULL) {
2283 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "free @ %p, sz=%d bytes\n",
2284 ioc->name, ioc->alloc, ioc->alloc_sz));
2285 pci_free_consistent(ioc->pcidev, sz,
2286 ioc->alloc, ioc->alloc_dma);
2287 ioc->reply_frames = NULL;
2288 ioc->req_frames = NULL;
2290 ioc->alloc_total -= sz;
2293 if (ioc->sense_buf_pool != NULL) {
2294 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2295 pci_free_consistent(ioc->pcidev, sz,
2296 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2297 ioc->sense_buf_pool = NULL;
2298 ioc->alloc_total -= sz;
2301 if (ioc->events != NULL){
2302 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2305 ioc->alloc_total -= sz;
2308 mpt_free_fw_memory(ioc);
2310 kfree(ioc->spi_data.nvram);
2311 mpt_inactive_raid_list_free(ioc);
2312 kfree(ioc->raid_data.pIocPg2);
2313 kfree(ioc->raid_data.pIocPg3);
2314 ioc->spi_data.nvram = NULL;
2315 ioc->raid_data.pIocPg3 = NULL;
2317 if (ioc->spi_data.pIocPg4 != NULL) {
2318 sz = ioc->spi_data.IocPg4Sz;
2319 pci_free_consistent(ioc->pcidev, sz,
2320 ioc->spi_data.pIocPg4,
2321 ioc->spi_data.IocPg4_dma);
2322 ioc->spi_data.pIocPg4 = NULL;
2323 ioc->alloc_total -= sz;
2326 if (ioc->ReqToChain != NULL) {
2327 kfree(ioc->ReqToChain);
2328 kfree(ioc->RequestNB);
2329 ioc->ReqToChain = NULL;
2332 kfree(ioc->ChainToChain);
2333 ioc->ChainToChain = NULL;
2335 if (ioc->HostPageBuffer != NULL) {
2336 if((ret = mpt_host_page_access_control(ioc,
2337 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2338 printk(MYIOC_s_ERR_FMT
2339 "host page buffers free failed (%d)!\n",
2342 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "HostPageBuffer free @ %p, sz=%d bytes\n",
2343 ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
2344 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2345 ioc->HostPageBuffer, ioc->HostPageBuffer_dma);
2346 ioc->HostPageBuffer = NULL;
2347 ioc->HostPageBuffer_sz = 0;
2348 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2352 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2354 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2355 * @ioc: Pointer to MPT adapter structure
2357 * This routine unregisters h/w resources and frees all alloc'd memory
2358 * associated with a MPT adapter structure.
2361 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2363 int sz_first, sz_last;
2368 sz_first = ioc->alloc_total;
2370 mpt_adapter_disable(ioc);
2372 if (ioc->pci_irq != -1) {
2373 free_irq(ioc->pci_irq, ioc);
2375 pci_disable_msi(ioc->pcidev);
2379 if (ioc->memmap != NULL) {
2380 iounmap(ioc->memmap);
2384 #if defined(CONFIG_MTRR) && 0
2385 if (ioc->mtrr_reg > 0) {
2386 mtrr_del(ioc->mtrr_reg, 0, 0);
2387 dprintk(ioc, printk(MYIOC_s_INFO_FMT "MTRR region de-registered\n", ioc->name));
2391 /* Zap the adapter lookup ptr! */
2392 list_del(&ioc->list);
2394 sz_last = ioc->alloc_total;
2395 dprintk(ioc, printk(MYIOC_s_INFO_FMT "free'd %d of %d bytes\n",
2396 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2399 ioc->alt_ioc->alt_ioc = NULL;
2404 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2406 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2407 * @ioc: Pointer to MPT adapter structure
2410 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2414 printk(KERN_INFO "%s: ", ioc->name);
2416 printk("%s: ", ioc->prod_name);
2417 printk("Capabilities={");
2419 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2420 printk("Initiator");
2424 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2425 printk("%sTarget", i ? "," : "");
2429 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2430 printk("%sLAN", i ? "," : "");
2436 * This would probably evoke more questions than it's worth
2438 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2439 printk("%sLogBusAddr", i ? "," : "");
2447 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2449 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2450 * @ioc: Pointer to MPT_ADAPTER structure
2451 * @force: Force hard KickStart of IOC
2452 * @sleepFlag: Specifies whether the process can sleep
2455 * 1 - DIAG reset and READY
2456 * 0 - READY initially OR soft reset and READY
2457 * -1 - Any failure on KickStart
2458 * -2 - Msg Unit Reset Failed
2459 * -3 - IO Unit Reset Failed
2460 * -4 - IOC owned by a PEER
2463 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2468 int hard_reset_done = 0;
2473 /* Get current [raw] IOC state */
2474 ioc_state = mpt_GetIocState(ioc, 0);
2475 dhsprintk(ioc, printk(MYIOC_s_INFO_FMT "MakeIocReady [raw] state=%08x\n", ioc->name, ioc_state));
2478 * Check to see if IOC got left/stuck in doorbell handshake
2479 * grip of death. If so, hard reset the IOC.
2481 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2483 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2487 /* Is it already READY? */
2488 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
2492 * Check to see if IOC is in FAULT state.
2494 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2496 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2498 printk(MYIOC_s_WARN_FMT " FAULT code = %04xh\n",
2499 ioc->name, ioc_state & MPI_DOORBELL_DATA_MASK);
2503 * Hmmm... Did it get left operational?
2505 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2506 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC operational unexpected\n",
2510 * If PCI Peer, exit.
2511 * Else, if no fault conditions are present, issue a MessageUnitReset
2512 * Else, fall through to KickStart case
2514 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2515 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2516 "whoinit 0x%x statefault %d force %d\n",
2517 ioc->name, whoinit, statefault, force));
2518 if (whoinit == MPI_WHOINIT_PCI_PEER)
2521 if ((statefault == 0 ) && (force == 0)) {
2522 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2529 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2530 if (hard_reset_done < 0)
2534 * Loop here waiting for IOC to come READY.
2537 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2539 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2540 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2542 * BIOS or previous driver load left IOC in OP state.
2543 * Reset messaging FIFOs.
2545 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2546 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2549 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2551 * Something is wrong. Try to get IOC back
2554 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2555 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2562 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2563 ioc->name, (int)((ii+5)/HZ));
2567 if (sleepFlag == CAN_SLEEP) {
2570 mdelay (1); /* 1 msec delay */
2575 if (statefault < 3) {
2576 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2578 statefault==1 ? "stuck handshake" : "IOC FAULT");
2581 return hard_reset_done;
2584 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2586 * mpt_GetIocState - Get the current state of a MPT adapter.
2587 * @ioc: Pointer to MPT_ADAPTER structure
2588 * @cooked: Request raw or cooked IOC state
2590 * Returns all IOC Doorbell register bits if cooked==0, else just the
2591 * Doorbell bits in MPI_IOC_STATE_MASK.
2594 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2599 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2600 sc = s & MPI_IOC_STATE_MASK;
2603 ioc->last_state = sc;
2605 return cooked ? sc : s;
2608 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2610 * GetIocFacts - Send IOCFacts request to MPT adapter.
2611 * @ioc: Pointer to MPT_ADAPTER structure
2612 * @sleepFlag: Specifies whether the process can sleep
2613 * @reason: If recovery, only update facts.
2615 * Returns 0 for success, non-zero for failure.
2618 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2620 IOCFacts_t get_facts;
2621 IOCFactsReply_t *facts;
2629 /* IOC *must* NOT be in RESET state! */
2630 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2631 printk(MYIOC_s_ERR_FMT "Can't get IOCFacts NOT READY! (%08x)\n",
2632 ioc->name, ioc->last_state );
2636 facts = &ioc->facts;
2638 /* Destination (reply area)... */
2639 reply_sz = sizeof(*facts);
2640 memset(facts, 0, reply_sz);
2642 /* Request area (get_facts on the stack right now!) */
2643 req_sz = sizeof(get_facts);
2644 memset(&get_facts, 0, req_sz);
2646 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2647 /* Assert: All other get_facts fields are zero! */
2649 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2650 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2651 ioc->name, req_sz, reply_sz));
2653 /* No non-zero fields in the get_facts request are greater than
2654 * 1 byte in size, so we can just fire it off as is.
2656 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2657 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2662 * Now byte swap (GRRR) the necessary fields before any further
2663 * inspection of reply contents.
2665 * But need to do some sanity checks on MsgLength (byte) field
2666 * to make sure we don't zero IOC's req_sz!
2668 /* Did we get a valid reply? */
2669 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2670 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2672 * If not been here, done that, save off first WhoInit value
2674 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2675 ioc->FirstWhoInit = facts->WhoInit;
2678 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2679 facts->MsgContext = le32_to_cpu(facts->MsgContext);
2680 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2681 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2682 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2683 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
2684 /* CHECKME! IOCStatus, IOCLogInfo */
2686 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2687 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2690 * FC f/w version changed between 1.1 and 1.2
2691 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2692 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2694 if (facts->MsgVersion < 0x0102) {
2696 * Handle old FC f/w style, convert to new...
2698 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2699 facts->FWVersion.Word =
2700 ((oldv<<12) & 0xFF000000) |
2701 ((oldv<<8) & 0x000FFF00);
2703 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2705 facts->ProductID = le16_to_cpu(facts->ProductID);
2706 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
2707 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
2708 ioc->ir_firmware = 1;
2709 facts->CurrentHostMfaHighAddr =
2710 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2711 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2712 facts->CurrentSenseBufferHighAddr =
2713 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2714 facts->CurReplyFrameSize =
2715 le16_to_cpu(facts->CurReplyFrameSize);
2716 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
2719 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2720 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2721 * to 14 in MPI-1.01.0x.
2723 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2724 facts->MsgVersion > 0x0100) {
2725 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2728 sz = facts->FWImageSize;
2733 facts->FWImageSize = sz;
2735 if (!facts->RequestFrameSize) {
2736 /* Something is wrong! */
2737 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2742 r = sz = facts->BlockSize;
2743 vv = ((63 / (sz * 4)) + 1) & 0x03;
2744 ioc->NB_for_64_byte_frame = vv;
2750 ioc->NBShiftFactor = shiftFactor;
2751 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2752 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2753 ioc->name, vv, shiftFactor, r));
2755 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2757 * Set values for this IOC's request & reply frame sizes,
2758 * and request & reply queue depths...
2760 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2761 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2762 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2763 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2765 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "reply_sz=%3d, reply_depth=%4d\n",
2766 ioc->name, ioc->reply_sz, ioc->reply_depth));
2767 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "req_sz =%3d, req_depth =%4d\n",
2768 ioc->name, ioc->req_sz, ioc->req_depth));
2770 /* Get port facts! */
2771 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2775 printk(MYIOC_s_ERR_FMT
2776 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2777 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2778 RequestFrameSize)/sizeof(u32)));
2785 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2787 * GetPortFacts - Send PortFacts request to MPT adapter.
2788 * @ioc: Pointer to MPT_ADAPTER structure
2789 * @portnum: Port number
2790 * @sleepFlag: Specifies whether the process can sleep
2792 * Returns 0 for success, non-zero for failure.
2795 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2797 PortFacts_t get_pfacts;
2798 PortFactsReply_t *pfacts;
2804 /* IOC *must* NOT be in RESET state! */
2805 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2806 printk(MYIOC_s_ERR_FMT "Can't get PortFacts NOT READY! (%08x)\n",
2807 ioc->name, ioc->last_state );
2811 pfacts = &ioc->pfacts[portnum];
2813 /* Destination (reply area)... */
2814 reply_sz = sizeof(*pfacts);
2815 memset(pfacts, 0, reply_sz);
2817 /* Request area (get_pfacts on the stack right now!) */
2818 req_sz = sizeof(get_pfacts);
2819 memset(&get_pfacts, 0, req_sz);
2821 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2822 get_pfacts.PortNumber = portnum;
2823 /* Assert: All other get_pfacts fields are zero! */
2825 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending get PortFacts(%d) request\n",
2826 ioc->name, portnum));
2828 /* No non-zero fields in the get_pfacts request are greater than
2829 * 1 byte in size, so we can just fire it off as is.
2831 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2832 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2836 /* Did we get a valid reply? */
2838 /* Now byte swap the necessary fields in the response. */
2839 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2840 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2841 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2842 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2843 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2844 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2845 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2846 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2847 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2849 max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
2851 ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
2852 ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
2855 * Place all the devices on channels
2859 if (mpt_channel_mapping) {
2860 ioc->devices_per_bus = 1;
2861 ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
2867 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2869 * SendIocInit - Send IOCInit request to MPT adapter.
2870 * @ioc: Pointer to MPT_ADAPTER structure
2871 * @sleepFlag: Specifies whether the process can sleep
2873 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2875 * Returns 0 for success, non-zero for failure.
2878 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2881 MPIDefaultReply_t init_reply;
2887 memset(&ioc_init, 0, sizeof(ioc_init));
2888 memset(&init_reply, 0, sizeof(init_reply));
2890 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2891 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2893 /* If we are in a recovery mode and we uploaded the FW image,
2894 * then this pointer is not NULL. Skip the upload a second time.
2895 * Set this flag if cached_fw set for either IOC.
2897 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
2901 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "upload_fw %d facts.Flags=%x\n",
2902 ioc->name, ioc->upload_fw, ioc->facts.Flags));
2904 ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
2905 ioc_init.MaxBuses = (U8)ioc->number_of_buses;
2906 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n",
2907 ioc->name, ioc->facts.MsgVersion));
2908 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
2909 // set MsgVersion and HeaderVersion host driver was built with
2910 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
2911 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
2913 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
2914 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
2915 } else if(mpt_host_page_alloc(ioc, &ioc_init))
2918 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
2920 if (sizeof(dma_addr_t) == sizeof(u64)) {
2921 /* Save the upper 32-bits of the request
2922 * (reply) and sense buffers.
2924 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
2925 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2927 /* Force 32-bit addressing */
2928 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
2929 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
2932 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
2933 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
2934 ioc->facts.MaxDevices = ioc_init.MaxDevices;
2935 ioc->facts.MaxBuses = ioc_init.MaxBuses;
2937 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOCInit (req @ %p)\n",
2938 ioc->name, &ioc_init));
2940 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
2941 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
2943 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
2947 /* No need to byte swap the multibyte fields in the reply
2948 * since we don't even look at its contents.
2951 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending PortEnable (req @ %p)\n",
2952 ioc->name, &ioc_init));
2954 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
2955 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
2959 /* YIKES! SUPER IMPORTANT!!!
2960 * Poll IocState until _OPERATIONAL while IOC is doing
2961 * LoopInit and TargetDiscovery!
2964 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
2965 state = mpt_GetIocState(ioc, 1);
2966 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
2967 if (sleepFlag == CAN_SLEEP) {
2974 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
2975 ioc->name, (int)((count+5)/HZ));
2979 state = mpt_GetIocState(ioc, 1);
2982 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wait IOC_OPERATIONAL state (cnt=%d)\n",
2985 ioc->aen_event_read_flag=0;
2989 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2991 * SendPortEnable - Send PortEnable request to MPT adapter port.
2992 * @ioc: Pointer to MPT_ADAPTER structure
2993 * @portnum: Port number to enable
2994 * @sleepFlag: Specifies whether the process can sleep
2996 * Send PortEnable to bring IOC to OPERATIONAL state.
2998 * Returns 0 for success, non-zero for failure.
3001 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3003 PortEnable_t port_enable;
3004 MPIDefaultReply_t reply_buf;
3009 /* Destination... */
3010 reply_sz = sizeof(MPIDefaultReply_t);
3011 memset(&reply_buf, 0, reply_sz);
3013 req_sz = sizeof(PortEnable_t);
3014 memset(&port_enable, 0, req_sz);
3016 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
3017 port_enable.PortNumber = portnum;
3018 /* port_enable.ChainOffset = 0; */
3019 /* port_enable.MsgFlags = 0; */
3020 /* port_enable.MsgContext = 0; */
3022 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Port(%d)Enable (req @ %p)\n",
3023 ioc->name, portnum, &port_enable));
3025 /* RAID FW may take a long time to enable
3027 if (ioc->ir_firmware || ioc->bus_type == SAS) {
3028 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3029 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3030 300 /*seconds*/, sleepFlag);
3032 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3033 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3034 30 /*seconds*/, sleepFlag);
3040 * mpt_alloc_fw_memory - allocate firmware memory
3041 * @ioc: Pointer to MPT_ADAPTER structure
3042 * @size: total FW bytes
3044 * If memory has already been allocated, the same (cached) value
3047 * Return 0 if successfull, or non-zero for failure
3050 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
3054 if (ioc->cached_fw) {
3055 rc = 0; /* use already allocated memory */
3058 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
3059 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
3060 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
3064 ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma);
3065 if (!ioc->cached_fw) {
3066 printk(MYIOC_s_ERR_FMT "Unable to allocate memory for the cached firmware image!\n",
3070 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Image @ %p[%p], sz=%d[%x] bytes\n",
3071 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, size, size));
3072 ioc->alloc_total += size;
3080 * mpt_free_fw_memory - free firmware memory
3081 * @ioc: Pointer to MPT_ADAPTER structure
3083 * If alt_img is NULL, delete from ioc structure.
3084 * Else, delete a secondary image in same format.
3087 mpt_free_fw_memory(MPT_ADAPTER *ioc)
3091 if (!ioc->cached_fw)
3094 sz = ioc->facts.FWImageSize;
3095 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3096 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3097 pci_free_consistent(ioc->pcidev, sz, ioc->cached_fw, ioc->cached_fw_dma);
3098 ioc->alloc_total -= sz;
3099 ioc->cached_fw = NULL;
3102 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3104 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3105 * @ioc: Pointer to MPT_ADAPTER structure
3106 * @sleepFlag: Specifies whether the process can sleep
3108 * Returns 0 for success, >0 for handshake failure
3109 * <0 for fw upload failure.
3111 * Remark: If bound IOC and a successful FWUpload was performed
3112 * on the bound IOC, the second image is discarded
3113 * and memory is free'd. Both channels must upload to prevent
3114 * IOC from running in degraded mode.
3117 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3119 u8 reply[sizeof(FWUploadReply_t)];
3120 FWUpload_t *prequest;
3121 FWUploadReply_t *preply;
3122 FWUploadTCSGE_t *ptcsge;
3125 int ii, sz, reply_sz;
3128 /* If the image size is 0, we are done.
3130 if ((sz = ioc->facts.FWImageSize) == 0)
3133 if (mpt_alloc_fw_memory(ioc, ioc->facts.FWImageSize) != 0)
3136 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3137 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3139 prequest = (sleepFlag == NO_SLEEP) ? kzalloc(ioc->req_sz, GFP_ATOMIC) :
3140 kzalloc(ioc->req_sz, GFP_KERNEL);
3142 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed "
3143 "while allocating memory \n", ioc->name));
3144 mpt_free_fw_memory(ioc);
3148 preply = (FWUploadReply_t *)&reply;
3150 reply_sz = sizeof(reply);
3151 memset(preply, 0, reply_sz);
3153 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
3154 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
3156 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
3157 ptcsge->DetailsLength = 12;
3158 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
3159 ptcsge->ImageSize = cpu_to_le32(sz);
3162 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
3164 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3165 mpt_add_sge((char *)ptcsge, flagsLength, ioc->cached_fw_dma);
3167 sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
3168 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": Sending FW Upload (req @ %p) sgeoffset=%d \n",
3169 ioc->name, prequest, sgeoffset));
3170 DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest);
3172 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
3173 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
3175 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Upload completed rc=%x \n", ioc->name, ii));
3177 cmdStatus = -EFAULT;
3179 /* Handshake transfer was complete and successful.
3180 * Check the Reply Frame.
3182 int status, transfer_sz;
3183 status = le16_to_cpu(preply->IOCStatus);
3184 if (status == MPI_IOCSTATUS_SUCCESS) {
3185 transfer_sz = le32_to_cpu(preply->ActualImageSize);
3186 if (transfer_sz == sz)
3190 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n",
3191 ioc->name, cmdStatus));
3196 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": fw upload failed, freeing image \n",
3198 mpt_free_fw_memory(ioc);
3205 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3207 * mpt_downloadboot - DownloadBoot code
3208 * @ioc: Pointer to MPT_ADAPTER structure
3209 * @pFwHeader: Pointer to firmware header info
3210 * @sleepFlag: Specifies whether the process can sleep
3212 * FwDownloadBoot requires Programmed IO access.
3214 * Returns 0 for success
3215 * -1 FW Image size is 0
3216 * -2 No valid cached_fw Pointer
3217 * <0 for fw upload failure.
3220 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3222 MpiExtImageHeader_t *pExtImage;
3232 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3233 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
3235 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3236 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3237 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3238 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3239 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3240 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3242 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
3245 if (sleepFlag == CAN_SLEEP) {
3251 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3252 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3254 for (count = 0; count < 30; count ++) {
3255 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3256 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3257 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESET_ADAPTER cleared, count=%d\n",
3262 if (sleepFlag == CAN_SLEEP) {
3269 if ( count == 30 ) {
3270 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot failed! "
3271 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3272 ioc->name, diag0val));
3276 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3277 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3278 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3279 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3280 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3281 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3283 /* Set the DiagRwEn and Disable ARM bits */
3284 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3286 fwSize = (pFwHeader->ImageSize + 3)/4;
3287 ptrFw = (u32 *) pFwHeader;
3289 /* Write the LoadStartAddress to the DiagRw Address Register
3290 * using Programmed IO
3292 if (ioc->errata_flag_1064)
3293 pci_enable_io_access(ioc->pcidev);
3295 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3296 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "LoadStart addr written 0x%x \n",
3297 ioc->name, pFwHeader->LoadStartAddress));
3299 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write FW Image: 0x%x bytes @ %p\n",
3300 ioc->name, fwSize*4, ptrFw));
3302 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3305 nextImage = pFwHeader->NextImageHeaderOffset;
3307 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3309 load_addr = pExtImage->LoadStartAddress;
3311 fwSize = (pExtImage->ImageSize + 3) >> 2;
3312 ptrFw = (u32 *)pExtImage;
3314 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3315 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3316 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3319 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3321 nextImage = pExtImage->NextImageHeaderOffset;
3324 /* Write the IopResetVectorRegAddr */
3325 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
3326 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3328 /* Write the IopResetVectorValue */
3329 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3330 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3332 /* Clear the internal flash bad bit - autoincrementing register,
3333 * so must do two writes.
3335 if (ioc->bus_type == SPI) {
3337 * 1030 and 1035 H/W errata, workaround to access
3338 * the ClearFlashBadSignatureBit
3340 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3341 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3342 diagRwData |= 0x40000000;
3343 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3344 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3346 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3347 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3348 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3349 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3352 if (sleepFlag == CAN_SLEEP) {
3359 if (ioc->errata_flag_1064)
3360 pci_disable_io_access(ioc->pcidev);
3362 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3363 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot diag0val=%x, "
3364 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3365 ioc->name, diag0val));
3366 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3367 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot now diag0val=%x\n",
3368 ioc->name, diag0val));
3369 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3371 /* Write 0xFF to reset the sequencer */
3372 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3374 if (ioc->bus_type == SAS) {
3375 ioc_state = mpt_GetIocState(ioc, 0);
3376 if ( (GetIocFacts(ioc, sleepFlag,
3377 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3378 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "GetIocFacts failed: IocState=%x\n",
3379 ioc->name, ioc_state));
3384 for (count=0; count<HZ*20; count++) {
3385 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3386 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3387 "downloadboot successful! (count=%d) IocState=%x\n",
3388 ioc->name, count, ioc_state));
3389 if (ioc->bus_type == SAS) {
3392 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3393 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3394 "downloadboot: SendIocInit failed\n",
3398 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3399 "downloadboot: SendIocInit successful\n",
3403 if (sleepFlag == CAN_SLEEP) {
3409 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3410 "downloadboot failed! IocState=%x\n",ioc->name, ioc_state));
3414 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3416 * KickStart - Perform hard reset of MPT adapter.
3417 * @ioc: Pointer to MPT_ADAPTER structure
3418 * @force: Force hard reset
3419 * @sleepFlag: Specifies whether the process can sleep
3421 * This routine places MPT adapter in diagnostic mode via the
3422 * WriteSequence register, and then performs a hard reset of adapter
3423 * via the Diagnostic register.
3425 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3426 * or NO_SLEEP (interrupt thread, use mdelay)
3427 * force - 1 if doorbell active, board fault state
3428 * board operational, IOC_RECOVERY or
3429 * IOC_BRINGUP and there is an alt_ioc.
3433 * 1 - hard reset, READY
3434 * 0 - no reset due to History bit, READY
3435 * -1 - no reset due to History bit but not READY
3436 * OR reset but failed to come READY
3437 * -2 - no reset, could not enter DIAG mode
3438 * -3 - reset but bad FW bit
3441 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3443 int hard_reset_done = 0;
3447 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStarting!\n", ioc->name));
3448 if (ioc->bus_type == SPI) {
3449 /* Always issue a Msg Unit Reset first. This will clear some
3450 * SCSI bus hang conditions.
3452 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3454 if (sleepFlag == CAN_SLEEP) {
3461 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3462 if (hard_reset_done < 0)
3463 return hard_reset_done;
3465 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n",
3468 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3469 for (cnt=0; cnt<cntdn; cnt++) {
3470 ioc_state = mpt_GetIocState(ioc, 1);
3471 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3472 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStart successful! (cnt=%d)\n",
3474 return hard_reset_done;
3476 if (sleepFlag == CAN_SLEEP) {
3483 dinitprintk(ioc, printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3484 ioc->name, mpt_GetIocState(ioc, 0)));
3488 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3490 * mpt_diag_reset - Perform hard reset of the adapter.
3491 * @ioc: Pointer to MPT_ADAPTER structure
3492 * @ignore: Set if to honor and clear to ignore
3493 * the reset history bit
3494 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3495 * else set to NO_SLEEP (use mdelay instead)
3497 * This routine places the adapter in diagnostic mode via the
3498 * WriteSequence register and then performs a hard reset of adapter
3499 * via the Diagnostic register. Adapter should be in ready state
3500 * upon successful completion.
3502 * Returns: 1 hard reset successful
3503 * 0 no reset performed because reset history bit set
3504 * -2 enabling diagnostic mode failed
3505 * -3 diagnostic reset failed
3508 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3512 int hard_reset_done = 0;
3515 MpiFwHeader_t *cached_fw; /* Pointer to FW */
3517 /* Clear any existing interrupts */
3518 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3520 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3521 drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3522 "address=%p\n", ioc->name, __FUNCTION__,
3523 &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3524 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3525 if (sleepFlag == CAN_SLEEP)
3530 for (count = 0; count < 60; count ++) {
3531 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3532 doorbell &= MPI_IOC_STATE_MASK;
3534 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3535 "looking for READY STATE: doorbell=%x"
3537 ioc->name, doorbell, count));
3538 if (doorbell == MPI_IOC_STATE_READY) {
3543 if (sleepFlag == CAN_SLEEP)
3551 /* Use "Diagnostic reset" method! (only thing available!) */
3552 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3554 if (ioc->debug_level & MPT_DEBUG) {
3556 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3557 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3558 ioc->name, diag0val, diag1val));
3561 /* Do the reset if we are told to ignore the reset history
3562 * or if the reset history is 0
3564 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3565 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3566 /* Write magic sequence to WriteSequence register
3567 * Loop until in diagnostic mode
3569 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3570 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3571 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3572 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3573 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3574 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3577 if (sleepFlag == CAN_SLEEP) {
3585 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3586 ioc->name, diag0val);
3591 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3593 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3594 ioc->name, diag0val));
3597 if (ioc->debug_level & MPT_DEBUG) {
3599 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3600 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3601 ioc->name, diag0val, diag1val));
3604 * Disable the ARM (Bug fix)
3607 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3611 * Now hit the reset bit in the Diagnostic register
3612 * (THE BIG HAMMER!) (Clears DRWE bit).
3614 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3615 hard_reset_done = 1;
3616 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset performed\n",
3620 * Call each currently registered protocol IOC reset handler
3621 * with pre-reset indication.
3622 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3623 * MptResetHandlers[] registered yet.
3629 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
3630 if (MptResetHandlers[cb_idx]) {
3631 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3632 "Calling IOC pre_reset handler #%d\n",
3633 ioc->name, cb_idx));
3634 r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET);
3636 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3637 "Calling alt-%s pre_reset handler #%d\n",
3638 ioc->name, ioc->alt_ioc->name, cb_idx));
3639 r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_PRE_RESET);
3643 /* FIXME? Examine results here? */
3647 cached_fw = (MpiFwHeader_t *)ioc->cached_fw;
3648 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
3649 cached_fw = (MpiFwHeader_t *)ioc->alt_ioc->cached_fw;
3653 /* If the DownloadBoot operation fails, the
3654 * IOC will be left unusable. This is a fatal error
3655 * case. _diag_reset will return < 0
3657 for (count = 0; count < 30; count ++) {
3658 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3659 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3663 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n",
3664 ioc->name, diag0val, count));
3666 if (sleepFlag == CAN_SLEEP) {
3672 if ((count = mpt_downloadboot(ioc, cached_fw, sleepFlag)) < 0) {
3673 printk(MYIOC_s_WARN_FMT
3674 "firmware downloadboot failure (%d)!\n", ioc->name, count);
3678 /* Wait for FW to reload and for board
3679 * to go to the READY state.
3680 * Maximum wait is 60 seconds.
3681 * If fail, no error will check again
3682 * with calling program.
3684 for (count = 0; count < 60; count ++) {
3685 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3686 doorbell &= MPI_IOC_STATE_MASK;
3688 if (doorbell == MPI_IOC_STATE_READY) {
3693 if (sleepFlag == CAN_SLEEP) {
3702 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3703 if (ioc->debug_level & MPT_DEBUG) {
3705 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3706 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3707 ioc->name, diag0val, diag1val));
3710 /* Clear RESET_HISTORY bit! Place board in the
3711 * diagnostic mode to update the diag register.
3713 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3715 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3716 /* Write magic sequence to WriteSequence register
3717 * Loop until in diagnostic mode
3719 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3720 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3721 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3722 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3723 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3724 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3727 if (sleepFlag == CAN_SLEEP) {
3735 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3736 ioc->name, diag0val);
3739 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3741 diag0val &= ~MPI_DIAG_RESET_HISTORY;
3742 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3743 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3744 if (diag0val & MPI_DIAG_RESET_HISTORY) {
3745 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3749 /* Disable Diagnostic Mode
3751 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3753 /* Check FW reload status flags.
3755 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3756 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3757 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3758 ioc->name, diag0val);
3762 if (ioc->debug_level & MPT_DEBUG) {
3764 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3765 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3766 ioc->name, diag0val, diag1val));
3770 * Reset flag that says we've enabled event notification
3772 ioc->facts.EventState = 0;
3775 ioc->alt_ioc->facts.EventState = 0;
3777 return hard_reset_done;
3780 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3782 * SendIocReset - Send IOCReset request to MPT adapter.
3783 * @ioc: Pointer to MPT_ADAPTER structure
3784 * @reset_type: reset type, expected values are
3785 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3786 * @sleepFlag: Specifies whether the process can sleep
3788 * Send IOCReset request to the MPT adapter.
3790 * Returns 0 for success, non-zero for failure.
3793 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3799 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOC reset(0x%02x)!\n",
3800 ioc->name, reset_type));
3801 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3802 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3805 /* FW ACK'd request, wait for READY state
3808 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
3810 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3814 if (sleepFlag != CAN_SLEEP)
3817 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
3818 ioc->name, (int)((count+5)/HZ));
3822 if (sleepFlag == CAN_SLEEP) {
3825 mdelay (1); /* 1 msec delay */
3830 * Cleanup all event stuff for this IOC; re-issue EventNotification
3831 * request if needed.
3833 if (ioc->facts.Function)
3834 ioc->facts.EventState = 0;
3839 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3841 * initChainBuffers - Allocate memory for and initialize chain buffers
3842 * @ioc: Pointer to MPT_ADAPTER structure
3844 * Allocates memory for and initializes chain buffers,
3845 * chain buffer control arrays and spinlock.
3848 initChainBuffers(MPT_ADAPTER *ioc)
3851 int sz, ii, num_chain;
3852 int scale, num_sge, numSGE;
3854 /* ReqToChain size must equal the req_depth
3857 if (ioc->ReqToChain == NULL) {
3858 sz = ioc->req_depth * sizeof(int);
3859 mem = kmalloc(sz, GFP_ATOMIC);
3863 ioc->ReqToChain = (int *) mem;
3864 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReqToChain alloc @ %p, sz=%d bytes\n",
3865 ioc->name, mem, sz));
3866 mem = kmalloc(sz, GFP_ATOMIC);
3870 ioc->RequestNB = (int *) mem;
3871 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestNB alloc @ %p, sz=%d bytes\n",
3872 ioc->name, mem, sz));
3874 for (ii = 0; ii < ioc->req_depth; ii++) {
3875 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
3878 /* ChainToChain size must equal the total number
3879 * of chain buffers to be allocated.
3882 * Calculate the number of chain buffers needed(plus 1) per I/O
3883 * then multiply the maximum number of simultaneous cmds
3885 * num_sge = num sge in request frame + last chain buffer
3886 * scale = num sge per chain buffer if no chain element
3888 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3889 if (sizeof(dma_addr_t) == sizeof(u64))
3890 num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3892 num_sge = 1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3894 if (sizeof(dma_addr_t) == sizeof(u64)) {
3895 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3896 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3898 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3899 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3901 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n",
3902 ioc->name, num_sge, numSGE));
3904 if ( numSGE > MPT_SCSI_SG_DEPTH )
3905 numSGE = MPT_SCSI_SG_DEPTH;
3908 while (numSGE - num_sge > 0) {
3910 num_sge += (scale - 1);
3914 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Now numSGE=%d num_sge=%d num_chain=%d\n",
3915 ioc->name, numSGE, num_sge, num_chain));
3917 if (ioc->bus_type == SPI)
3918 num_chain *= MPT_SCSI_CAN_QUEUE;
3920 num_chain *= MPT_FC_CAN_QUEUE;
3922 ioc->num_chain = num_chain;
3924 sz = num_chain * sizeof(int);
3925 if (ioc->ChainToChain == NULL) {
3926 mem = kmalloc(sz, GFP_ATOMIC);
3930 ioc->ChainToChain = (int *) mem;
3931 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainToChain alloc @ %p, sz=%d bytes\n",
3932 ioc->name, mem, sz));
3934 mem = (u8 *) ioc->ChainToChain;
3936 memset(mem, 0xFF, sz);
3940 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3942 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
3943 * @ioc: Pointer to MPT_ADAPTER structure
3945 * This routine allocates memory for the MPT reply and request frame
3946 * pools (if necessary), and primes the IOC reply FIFO with
3949 * Returns 0 for success, non-zero for failure.
3952 PrimeIocFifos(MPT_ADAPTER *ioc)
3955 unsigned long flags;
3956 dma_addr_t alloc_dma;
3958 int i, reply_sz, sz, total_size, num_chain;
3960 /* Prime reply FIFO... */
3962 if (ioc->reply_frames == NULL) {
3963 if ( (num_chain = initChainBuffers(ioc)) < 0)
3966 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
3967 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
3968 ioc->name, ioc->reply_sz, ioc->reply_depth));
3969 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d[%x] bytes\n",
3970 ioc->name, reply_sz, reply_sz));
3972 sz = (ioc->req_sz * ioc->req_depth);
3973 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d bytes, RequestDepth=%d\n",
3974 ioc->name, ioc->req_sz, ioc->req_depth));
3975 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d[%x] bytes\n",
3976 ioc->name, sz, sz));
3979 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
3980 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d bytes, ChainDepth=%d\n",
3981 ioc->name, ioc->req_sz, num_chain));
3982 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
3983 ioc->name, sz, sz, num_chain));
3986 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
3988 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
3993 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Total alloc @ %p[%p], sz=%d[%x] bytes\n",
3994 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
3996 memset(mem, 0, total_size);
3997 ioc->alloc_total += total_size;
3999 ioc->alloc_dma = alloc_dma;
4000 ioc->alloc_sz = total_size;
4001 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
4002 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4004 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4005 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4007 alloc_dma += reply_sz;
4010 /* Request FIFO - WE manage this! */
4012 ioc->req_frames = (MPT_FRAME_HDR *) mem;
4013 ioc->req_frames_dma = alloc_dma;
4015 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffers @ %p[%p]\n",
4016 ioc->name, mem, (void *)(ulong)alloc_dma));
4018 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4020 #if defined(CONFIG_MTRR) && 0
4022 * Enable Write Combining MTRR for IOC's memory region.
4023 * (at least as much as we can; "size and base must be
4024 * multiples of 4 kiB"
4026 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
4028 MTRR_TYPE_WRCOMB, 1);
4029 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MTRR region registered (base:size=%08x:%x)\n",
4030 ioc->name, ioc->req_frames_dma, sz));
4033 for (i = 0; i < ioc->req_depth; i++) {
4034 alloc_dma += ioc->req_sz;
4038 ioc->ChainBuffer = mem;
4039 ioc->ChainBufferDMA = alloc_dma;
4041 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffers @ %p(%p)\n",
4042 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
4044 /* Initialize the free chain Q.
4047 INIT_LIST_HEAD(&ioc->FreeChainQ);
4049 /* Post the chain buffers to the FreeChainQ.
4051 mem = (u8 *)ioc->ChainBuffer;
4052 for (i=0; i < num_chain; i++) {
4053 mf = (MPT_FRAME_HDR *) mem;
4054 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
4058 /* Initialize Request frames linked list
4060 alloc_dma = ioc->req_frames_dma;
4061 mem = (u8 *) ioc->req_frames;
4063 spin_lock_irqsave(&ioc->FreeQlock, flags);
4064 INIT_LIST_HEAD(&ioc->FreeQ);
4065 for (i = 0; i < ioc->req_depth; i++) {
4066 mf = (MPT_FRAME_HDR *) mem;
4068 /* Queue REQUESTs *internally*! */
4069 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
4073 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4075 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4076 ioc->sense_buf_pool =
4077 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
4078 if (ioc->sense_buf_pool == NULL) {
4079 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
4084 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
4085 ioc->alloc_total += sz;
4086 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SenseBuffers @ %p[%p]\n",
4087 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
4091 /* Post Reply frames to FIFO
4093 alloc_dma = ioc->alloc_dma;
4094 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4095 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4097 for (i = 0; i < ioc->reply_depth; i++) {
4098 /* Write each address to the IOC! */
4099 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
4100 alloc_dma += ioc->reply_sz;
4106 if (ioc->alloc != NULL) {
4108 pci_free_consistent(ioc->pcidev,
4110 ioc->alloc, ioc->alloc_dma);
4111 ioc->reply_frames = NULL;
4112 ioc->req_frames = NULL;
4113 ioc->alloc_total -= sz;
4115 if (ioc->sense_buf_pool != NULL) {
4116 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4117 pci_free_consistent(ioc->pcidev,
4119 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
4120 ioc->sense_buf_pool = NULL;
4125 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4127 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4128 * from IOC via doorbell handshake method.
4129 * @ioc: Pointer to MPT_ADAPTER structure
4130 * @reqBytes: Size of the request in bytes
4131 * @req: Pointer to MPT request frame
4132 * @replyBytes: Expected size of the reply in bytes
4133 * @u16reply: Pointer to area where reply should be written
4134 * @maxwait: Max wait time for a reply (in seconds)
4135 * @sleepFlag: Specifies whether the process can sleep
4137 * NOTES: It is the callers responsibility to byte-swap fields in the
4138 * request which are greater than 1 byte in size. It is also the
4139 * callers responsibility to byte-swap response fields which are
4140 * greater than 1 byte in size.
4142 * Returns 0 for success, non-zero for failure.
4145 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
4146 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
4148 MPIDefaultReply_t *mptReply;
4153 * Get ready to cache a handshake reply
4155 ioc->hs_reply_idx = 0;
4156 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4157 mptReply->MsgLength = 0;
4160 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4161 * then tell IOC that we want to handshake a request of N words.
4162 * (WRITE u32val to Doorbell reg).
4164 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4165 CHIPREG_WRITE32(&ioc->chip->Doorbell,
4166 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
4167 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
4170 * Wait for IOC's doorbell handshake int
4172 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4175 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4176 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4178 /* Read doorbell and check for active bit */
4179 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
4183 * Clear doorbell int (WRITE 0 to IntStatus reg),
4184 * then wait for IOC to ACKnowledge that it's ready for
4185 * our handshake request.
4187 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4188 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4193 u8 *req_as_bytes = (u8 *) req;
4196 * Stuff request words via doorbell handshake,
4197 * with ACK from IOC for each.
4199 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
4200 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
4201 (req_as_bytes[(ii*4) + 1] << 8) |
4202 (req_as_bytes[(ii*4) + 2] << 16) |
4203 (req_as_bytes[(ii*4) + 3] << 24));
4205 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
4206 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4210 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req));
4211 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req);
4213 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n",
4214 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
4217 * Wait for completion of doorbell handshake reply from the IOC
4219 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
4222 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake reply count=%d%s\n",
4223 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
4226 * Copy out the cached reply...
4228 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
4229 u16reply[ii] = ioc->hs_reply[ii];
4237 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4239 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4240 * @ioc: Pointer to MPT_ADAPTER structure
4241 * @howlong: How long to wait (in seconds)
4242 * @sleepFlag: Specifies whether the process can sleep
4244 * This routine waits (up to ~2 seconds max) for IOC doorbell
4245 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4246 * bit in its IntStatus register being clear.
4248 * Returns a negative value on failure, else wait loop count.
4251 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4257 cntdn = 1000 * howlong;
4259 if (sleepFlag == CAN_SLEEP) {
4262 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4263 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4270 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4271 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4278 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell ACK (count=%d)\n",
4283 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4284 ioc->name, count, intstat);
4288 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4290 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4291 * @ioc: Pointer to MPT_ADAPTER structure
4292 * @howlong: How long to wait (in seconds)
4293 * @sleepFlag: Specifies whether the process can sleep
4295 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4296 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4298 * Returns a negative value on failure, else wait loop count.
4301 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4307 cntdn = 1000 * howlong;
4308 if (sleepFlag == CAN_SLEEP) {
4310 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4311 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4318 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4319 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4327 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4328 ioc->name, count, howlong));
4332 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4333 ioc->name, count, intstat);
4337 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4339 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4340 * @ioc: Pointer to MPT_ADAPTER structure
4341 * @howlong: How long to wait (in seconds)
4342 * @sleepFlag: Specifies whether the process can sleep
4344 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4345 * Reply is cached to IOC private area large enough to hold a maximum
4346 * of 128 bytes of reply data.
4348 * Returns a negative value on failure, else size of reply in WORDS.
4351 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4356 u16 *hs_reply = ioc->hs_reply;
4357 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4360 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4363 * Get first two u16's so we can look at IOC's intended reply MsgLength
4366 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4369 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4370 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4371 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4374 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4375 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4379 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4380 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4381 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4384 * If no error (and IOC said MsgLength is > 0), piece together
4385 * reply 16 bits at a time.
4387 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4388 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4390 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4391 /* don't overflow our IOC hs_reply[] buffer! */
4392 if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
4393 hs_reply[u16cnt] = hword;
4394 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4397 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4399 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4402 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4407 else if (u16cnt != (2 * mptReply->MsgLength)) {
4410 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4415 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name));
4416 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply);
4418 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4419 ioc->name, t, u16cnt/2));
4423 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4425 * GetLanConfigPages - Fetch LANConfig pages.
4426 * @ioc: Pointer to MPT_ADAPTER structure
4428 * Return: 0 for success
4429 * -ENOMEM if no memory available
4430 * -EPERM if not allowed due to ISR context
4431 * -EAGAIN if no msg frames currently available
4432 * -EFAULT for non-successful reply or no reply (timeout)
4435 GetLanConfigPages(MPT_ADAPTER *ioc)
4437 ConfigPageHeader_t hdr;
4439 LANPage0_t *ppage0_alloc;
4440 dma_addr_t page0_dma;
4441 LANPage1_t *ppage1_alloc;
4442 dma_addr_t page1_dma;
4447 /* Get LAN Page 0 header */
4448 hdr.PageVersion = 0;
4451 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4452 cfg.cfghdr.hdr = &hdr;
4454 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4459 if ((rc = mpt_config(ioc, &cfg)) != 0)
4462 if (hdr.PageLength > 0) {
4463 data_sz = hdr.PageLength * 4;
4464 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4467 memset((u8 *)ppage0_alloc, 0, data_sz);
4468 cfg.physAddr = page0_dma;
4469 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4471 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4473 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4474 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4478 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4481 * Normalize endianness of structure data,
4482 * by byte-swapping all > 1 byte fields!
4491 /* Get LAN Page 1 header */
4492 hdr.PageVersion = 0;
4495 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4496 cfg.cfghdr.hdr = &hdr;
4498 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4502 if ((rc = mpt_config(ioc, &cfg)) != 0)
4505 if (hdr.PageLength == 0)
4508 data_sz = hdr.PageLength * 4;
4510 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4512 memset((u8 *)ppage1_alloc, 0, data_sz);
4513 cfg.physAddr = page1_dma;
4514 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4516 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4518 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4519 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4522 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4525 * Normalize endianness of structure data,
4526 * by byte-swapping all > 1 byte fields!
4534 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4536 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
4537 * @ioc: Pointer to MPT_ADAPTER structure
4538 * @persist_opcode: see below
4540 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4541 * devices not currently present.
4542 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4544 * NOTE: Don't use not this function during interrupt time.
4546 * Returns 0 for success, non-zero error
4549 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4551 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4553 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
4554 SasIoUnitControlReply_t *sasIoUnitCntrReply;
4555 MPT_FRAME_HDR *mf = NULL;
4556 MPIHeader_t *mpi_hdr;
4559 /* insure garbage is not sent to fw */
4560 switch(persist_opcode) {
4562 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
4563 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
4571 printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode);
4573 /* Get a MF for this command.
4575 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4576 printk("%s: no msg frames!\n",__FUNCTION__);
4580 mpi_hdr = (MPIHeader_t *) mf;
4581 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
4582 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
4583 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
4584 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
4585 sasIoUnitCntrReq->Operation = persist_opcode;
4587 init_timer(&ioc->persist_timer);
4588 ioc->persist_timer.data = (unsigned long) ioc;
4589 ioc->persist_timer.function = mpt_timer_expired;
4590 ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
4591 ioc->persist_wait_done=0;
4592 add_timer(&ioc->persist_timer);
4593 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4594 wait_event(mpt_waitq, ioc->persist_wait_done);
4596 sasIoUnitCntrReply =
4597 (SasIoUnitControlReply_t *)ioc->persist_reply_frame;
4598 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
4599 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4601 sasIoUnitCntrReply->IOCStatus,
4602 sasIoUnitCntrReply->IOCLogInfo);
4606 printk("%s: success\n",__FUNCTION__);
4610 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4613 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
4614 MpiEventDataRaid_t * pRaidEventData)
4623 volume = pRaidEventData->VolumeID;
4624 reason = pRaidEventData->ReasonCode;
4625 disk = pRaidEventData->PhysDiskNum;
4626 status = le32_to_cpu(pRaidEventData->SettingsStatus);
4627 flags = (status >> 0) & 0xff;
4628 state = (status >> 8) & 0xff;
4630 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
4634 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
4635 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
4636 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
4637 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
4638 ioc->name, disk, volume);
4640 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
4645 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4646 printk(MYIOC_s_INFO_FMT " volume has been created\n",
4650 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4652 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
4656 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
4657 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
4661 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4662 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
4664 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
4666 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
4668 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
4671 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
4673 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
4674 ? ", quiesced" : "",
4675 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
4676 ? ", resync in progress" : "" );
4679 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
4680 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
4684 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4685 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
4689 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4690 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
4694 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
4695 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
4699 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4700 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
4702 state == MPI_PHYSDISK0_STATUS_ONLINE
4704 : state == MPI_PHYSDISK0_STATUS_MISSING
4706 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
4708 : state == MPI_PHYSDISK0_STATUS_FAILED
4710 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
4712 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
4713 ? "offline requested"
4714 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
4715 ? "failed requested"
4716 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
4719 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
4720 ? ", out of sync" : "",
4721 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
4722 ? ", quiesced" : "" );
4725 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
4726 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
4730 case MPI_EVENT_RAID_RC_SMART_DATA:
4731 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
4732 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
4735 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
4736 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
4742 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4744 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4745 * @ioc: Pointer to MPT_ADAPTER structure
4747 * Returns: 0 for success
4748 * -ENOMEM if no memory available
4749 * -EPERM if not allowed due to ISR context
4750 * -EAGAIN if no msg frames currently available
4751 * -EFAULT for non-successful reply or no reply (timeout)
4754 GetIoUnitPage2(MPT_ADAPTER *ioc)
4756 ConfigPageHeader_t hdr;
4758 IOUnitPage2_t *ppage_alloc;
4759 dma_addr_t page_dma;
4763 /* Get the page header */
4764 hdr.PageVersion = 0;
4767 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4768 cfg.cfghdr.hdr = &hdr;
4770 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4775 if ((rc = mpt_config(ioc, &cfg)) != 0)
4778 if (hdr.PageLength == 0)
4781 /* Read the config page */
4782 data_sz = hdr.PageLength * 4;
4784 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4786 memset((u8 *)ppage_alloc, 0, data_sz);
4787 cfg.physAddr = page_dma;
4788 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4790 /* If Good, save data */
4791 if ((rc = mpt_config(ioc, &cfg)) == 0)
4792 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4794 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4800 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4802 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4803 * @ioc: Pointer to a Adapter Strucutre
4804 * @portnum: IOC port number
4806 * Return: -EFAULT if read of config page header fails
4808 * If read of SCSI Port Page 0 fails,
4809 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4810 * Adapter settings: async, narrow
4812 * If read of SCSI Port Page 2 fails,
4813 * Adapter settings valid
4814 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4819 * CHECK - what type of locking mechanisms should be used????
4822 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4827 ConfigPageHeader_t header;
4833 if (!ioc->spi_data.nvram) {
4836 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4837 mem = kmalloc(sz, GFP_ATOMIC);
4841 ioc->spi_data.nvram = (int *) mem;
4843 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4844 ioc->name, ioc->spi_data.nvram, sz));
4847 /* Invalidate NVRAM information
4849 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4850 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4853 /* Read SPP0 header, allocate memory, then read page.
4855 header.PageVersion = 0;
4856 header.PageLength = 0;
4857 header.PageNumber = 0;
4858 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4859 cfg.cfghdr.hdr = &header;
4861 cfg.pageAddr = portnum;
4862 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4864 cfg.timeout = 0; /* use default */
4865 if (mpt_config(ioc, &cfg) != 0)
4868 if (header.PageLength > 0) {
4869 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4871 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4872 cfg.physAddr = buf_dma;
4873 if (mpt_config(ioc, &cfg) != 0) {
4874 ioc->spi_data.maxBusWidth = MPT_NARROW;
4875 ioc->spi_data.maxSyncOffset = 0;
4876 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4877 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4879 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4880 "Unable to read PortPage0 minSyncFactor=%x\n",
4881 ioc->name, ioc->spi_data.minSyncFactor));
4883 /* Save the Port Page 0 data
4885 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
4886 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4887 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4889 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
4890 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4891 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4892 "noQas due to Capabilities=%x\n",
4893 ioc->name, pPP0->Capabilities));
4895 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4896 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4898 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4899 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4900 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4901 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4902 "PortPage0 minSyncFactor=%x\n",
4903 ioc->name, ioc->spi_data.minSyncFactor));
4905 ioc->spi_data.maxSyncOffset = 0;
4906 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4909 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4911 /* Update the minSyncFactor based on bus type.
4913 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4914 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
4916 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
4917 ioc->spi_data.minSyncFactor = MPT_ULTRA;
4918 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4919 "HVD or SE detected, minSyncFactor=%x\n",
4920 ioc->name, ioc->spi_data.minSyncFactor));
4925 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4930 /* SCSI Port Page 2 - Read the header then the page.
4932 header.PageVersion = 0;
4933 header.PageLength = 0;
4934 header.PageNumber = 2;
4935 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4936 cfg.cfghdr.hdr = &header;
4938 cfg.pageAddr = portnum;
4939 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4941 if (mpt_config(ioc, &cfg) != 0)
4944 if (header.PageLength > 0) {
4945 /* Allocate memory and read SCSI Port Page 2
4947 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4949 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
4950 cfg.physAddr = buf_dma;
4951 if (mpt_config(ioc, &cfg) != 0) {
4952 /* Nvram data is left with INVALID mark
4955 } else if (ioc->pcidev->vendor == PCI_VENDOR_ID_ATTO) {
4957 /* This is an ATTO adapter, read Page2 accordingly
4959 ATTO_SCSIPortPage2_t *pPP2 = (ATTO_SCSIPortPage2_t *) pbuf;
4960 ATTODeviceInfo_t *pdevice = NULL;
4963 /* Save the Port Page 2 data
4964 * (reformat into a 32bit quantity)
4966 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4967 pdevice = &pPP2->DeviceSettings[ii];
4968 ATTOFlags = le16_to_cpu(pdevice->ATTOFlags);
4971 /* Translate ATTO device flags to LSI format
4973 if (ATTOFlags & ATTOFLAG_DISC)
4974 data |= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE);
4975 if (ATTOFlags & ATTOFLAG_ID_ENB)
4976 data |= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE);
4977 if (ATTOFlags & ATTOFLAG_LUN_ENB)
4978 data |= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE);
4979 if (ATTOFlags & ATTOFLAG_TAGGED)
4980 data |= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE);
4981 if (!(ATTOFlags & ATTOFLAG_WIDE_ENB))
4982 data |= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE);
4984 data = (data << 16) | (pdevice->Period << 8) | 10;
4985 ioc->spi_data.nvram[ii] = data;
4988 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
4989 MpiDeviceInfo_t *pdevice = NULL;
4992 * Save "Set to Avoid SCSI Bus Resets" flag
4994 ioc->spi_data.bus_reset =
4995 (le32_to_cpu(pPP2->PortFlags) &
4996 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
4999 /* Save the Port Page 2 data
5000 * (reformat into a 32bit quantity)
5002 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
5003 ioc->spi_data.PortFlags = data;
5004 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5005 pdevice = &pPP2->DeviceSettings[ii];
5006 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
5007 (pdevice->SyncFactor << 8) | pdevice->Timeout;
5008 ioc->spi_data.nvram[ii] = data;
5012 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5016 /* Update Adapter limits with those from NVRAM
5017 * Comment: Don't need to do this. Target performance
5018 * parameters will never exceed the adapters limits.
5024 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5026 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
5027 * @ioc: Pointer to a Adapter Strucutre
5028 * @portnum: IOC port number
5030 * Return: -EFAULT if read of config page header fails
5034 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
5037 ConfigPageHeader_t header;
5039 /* Read the SCSI Device Page 1 header
5041 header.PageVersion = 0;
5042 header.PageLength = 0;
5043 header.PageNumber = 1;
5044 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5045 cfg.cfghdr.hdr = &header;
5047 cfg.pageAddr = portnum;
5048 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5051 if (mpt_config(ioc, &cfg) != 0)
5054 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
5055 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
5057 header.PageVersion = 0;
5058 header.PageLength = 0;
5059 header.PageNumber = 0;
5060 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5061 if (mpt_config(ioc, &cfg) != 0)
5064 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
5065 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
5067 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 0: version %d length %d\n",
5068 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
5070 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 1: version %d length %d\n",
5071 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
5076 * mpt_inactive_raid_list_free - This clears this link list.
5077 * @ioc : pointer to per adapter structure
5080 mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
5082 struct inactive_raid_component_info *component_info, *pNext;
5084 if (list_empty(&ioc->raid_data.inactive_list))
5087 down(&ioc->raid_data.inactive_list_mutex);
5088 list_for_each_entry_safe(component_info, pNext,
5089 &ioc->raid_data.inactive_list, list) {
5090 list_del(&component_info->list);
5091 kfree(component_info);
5093 up(&ioc->raid_data.inactive_list_mutex);
5097 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5099 * @ioc : pointer to per adapter structure
5100 * @channel : volume channel
5101 * @id : volume target id
5104 mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
5107 ConfigPageHeader_t hdr;
5108 dma_addr_t dma_handle;
5109 pRaidVolumePage0_t buffer = NULL;
5111 RaidPhysDiskPage0_t phys_disk;
5112 struct inactive_raid_component_info *component_info;
5113 int handle_inactive_volumes;
5115 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5116 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5117 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
5118 cfg.pageAddr = (channel << 8) + id;
5119 cfg.cfghdr.hdr = &hdr;
5120 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5122 if (mpt_config(ioc, &cfg) != 0)
5125 if (!hdr.PageLength)
5128 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5134 cfg.physAddr = dma_handle;
5135 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5137 if (mpt_config(ioc, &cfg) != 0)
5140 if (!buffer->NumPhysDisks)
5143 handle_inactive_volumes =
5144 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
5145 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
5146 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
5147 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
5149 if (!handle_inactive_volumes)
5152 down(&ioc->raid_data.inactive_list_mutex);
5153 for (i = 0; i < buffer->NumPhysDisks; i++) {
5154 if(mpt_raid_phys_disk_pg0(ioc,
5155 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
5158 if ((component_info = kmalloc(sizeof (*component_info),
5159 GFP_KERNEL)) == NULL)
5162 component_info->volumeID = id;
5163 component_info->volumeBus = channel;
5164 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
5165 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
5166 component_info->d.PhysDiskID = phys_disk.PhysDiskID;
5167 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
5169 list_add_tail(&component_info->list,
5170 &ioc->raid_data.inactive_list);
5172 up(&ioc->raid_data.inactive_list_mutex);
5176 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5181 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5182 * @ioc: Pointer to a Adapter Structure
5183 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5184 * @phys_disk: requested payload data returned
5188 * -EFAULT if read of config page header fails or data pointer not NULL
5189 * -ENOMEM if pci_alloc failed
5192 mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk)
5195 ConfigPageHeader_t hdr;
5196 dma_addr_t dma_handle;
5197 pRaidPhysDiskPage0_t buffer = NULL;
5200 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5201 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5203 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5204 cfg.cfghdr.hdr = &hdr;
5206 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5208 if (mpt_config(ioc, &cfg) != 0) {
5213 if (!hdr.PageLength) {
5218 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5226 cfg.physAddr = dma_handle;
5227 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5228 cfg.pageAddr = phys_disk_num;
5230 if (mpt_config(ioc, &cfg) != 0) {
5236 memcpy(phys_disk, buffer, sizeof(*buffer));
5237 phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
5242 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5249 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5250 * @ioc: Pointer to a Adapter Strucutre
5251 * @portnum: IOC port number
5255 * -EFAULT if read of config page header fails or data pointer not NULL
5256 * -ENOMEM if pci_alloc failed
5259 mpt_findImVolumes(MPT_ADAPTER *ioc)
5263 dma_addr_t ioc2_dma;
5265 ConfigPageHeader_t header;
5270 if (!ioc->ir_firmware)
5273 /* Free the old page
5275 kfree(ioc->raid_data.pIocPg2);
5276 ioc->raid_data.pIocPg2 = NULL;
5277 mpt_inactive_raid_list_free(ioc);
5279 /* Read IOCP2 header then the page.
5281 header.PageVersion = 0;
5282 header.PageLength = 0;
5283 header.PageNumber = 2;
5284 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5285 cfg.cfghdr.hdr = &header;
5288 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5291 if (mpt_config(ioc, &cfg) != 0)
5294 if (header.PageLength == 0)
5297 iocpage2sz = header.PageLength * 4;
5298 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
5302 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5303 cfg.physAddr = ioc2_dma;
5304 if (mpt_config(ioc, &cfg) != 0)
5307 mem = kmalloc(iocpage2sz, GFP_KERNEL);
5311 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
5312 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
5314 mpt_read_ioc_pg_3(ioc);
5316 for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
5317 mpt_inactive_raid_volumes(ioc,
5318 pIoc2->RaidVolume[i].VolumeBus,
5319 pIoc2->RaidVolume[i].VolumeID);
5322 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
5328 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
5333 ConfigPageHeader_t header;
5334 dma_addr_t ioc3_dma;
5337 /* Free the old page
5339 kfree(ioc->raid_data.pIocPg3);
5340 ioc->raid_data.pIocPg3 = NULL;
5342 /* There is at least one physical disk.
5343 * Read and save IOC Page 3
5345 header.PageVersion = 0;
5346 header.PageLength = 0;
5347 header.PageNumber = 3;
5348 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5349 cfg.cfghdr.hdr = &header;
5352 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5355 if (mpt_config(ioc, &cfg) != 0)
5358 if (header.PageLength == 0)
5361 /* Read Header good, alloc memory
5363 iocpage3sz = header.PageLength * 4;
5364 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
5368 /* Read the Page and save the data
5369 * into malloc'd memory.
5371 cfg.physAddr = ioc3_dma;
5372 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5373 if (mpt_config(ioc, &cfg) == 0) {
5374 mem = kmalloc(iocpage3sz, GFP_KERNEL);
5376 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
5377 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
5381 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
5387 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
5391 ConfigPageHeader_t header;
5392 dma_addr_t ioc4_dma;
5395 /* Read and save IOC Page 4
5397 header.PageVersion = 0;
5398 header.PageLength = 0;
5399 header.PageNumber = 4;
5400 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5401 cfg.cfghdr.hdr = &header;
5404 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5407 if (mpt_config(ioc, &cfg) != 0)
5410 if (header.PageLength == 0)
5413 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
5414 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
5415 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
5418 ioc->alloc_total += iocpage4sz;
5420 ioc4_dma = ioc->spi_data.IocPg4_dma;
5421 iocpage4sz = ioc->spi_data.IocPg4Sz;
5424 /* Read the Page into dma memory.
5426 cfg.physAddr = ioc4_dma;
5427 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5428 if (mpt_config(ioc, &cfg) == 0) {
5429 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
5430 ioc->spi_data.IocPg4_dma = ioc4_dma;
5431 ioc->spi_data.IocPg4Sz = iocpage4sz;
5433 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
5434 ioc->spi_data.pIocPg4 = NULL;
5435 ioc->alloc_total -= iocpage4sz;
5440 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
5444 ConfigPageHeader_t header;
5445 dma_addr_t ioc1_dma;
5449 /* Check the Coalescing Timeout in IOC Page 1
5451 header.PageVersion = 0;
5452 header.PageLength = 0;
5453 header.PageNumber = 1;
5454 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5455 cfg.cfghdr.hdr = &header;
5458 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5461 if (mpt_config(ioc, &cfg) != 0)
5464 if (header.PageLength == 0)
5467 /* Read Header good, alloc memory
5469 iocpage1sz = header.PageLength * 4;
5470 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
5474 /* Read the Page and check coalescing timeout
5476 cfg.physAddr = ioc1_dma;
5477 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5478 if (mpt_config(ioc, &cfg) == 0) {
5480 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
5481 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
5482 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
5484 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Coalescing Enabled Timeout = %d\n",
5487 if (tmp > MPT_COALESCING_TIMEOUT) {
5488 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
5490 /* Write NVRAM and current
5493 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5494 if (mpt_config(ioc, &cfg) == 0) {
5495 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Reset Current Coalescing Timeout to = %d\n",
5496 ioc->name, MPT_COALESCING_TIMEOUT));
5498 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
5499 if (mpt_config(ioc, &cfg) == 0) {
5500 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5501 "Reset NVRAM Coalescing Timeout to = %d\n",
5502 ioc->name, MPT_COALESCING_TIMEOUT));
5504 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5505 "Reset NVRAM Coalescing Timeout Failed\n",
5510 dprintk(ioc, printk(MYIOC_s_WARN_FMT
5511 "Reset of Current Coalescing Timeout Failed!\n",
5517 dprintk(ioc, printk(MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
5521 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
5527 mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
5530 ConfigPageHeader_t hdr;
5532 ManufacturingPage0_t *pbuf = NULL;
5534 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5535 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5537 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
5538 cfg.cfghdr.hdr = &hdr;
5540 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5543 if (mpt_config(ioc, &cfg) != 0)
5546 if (!cfg.cfghdr.hdr->PageLength)
5549 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5550 pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
5554 cfg.physAddr = buf_dma;
5556 if (mpt_config(ioc, &cfg) != 0)
5559 memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name));
5560 memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
5561 memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
5566 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
5569 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5571 * SendEventNotification - Send EventNotification (on or off) request to adapter
5572 * @ioc: Pointer to MPT_ADAPTER structure
5573 * @EvSwitch: Event switch flags
5576 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
5578 EventNotification_t *evnp;
5580 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
5582 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
5586 memset(evnp, 0, sizeof(*evnp));
5588 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
5590 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
5591 evnp->ChainOffset = 0;
5593 evnp->Switch = EvSwitch;
5595 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
5600 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5602 * SendEventAck - Send EventAck request to MPT adapter.
5603 * @ioc: Pointer to MPT_ADAPTER structure
5604 * @evnp: Pointer to original EventNotification request
5607 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
5611 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5612 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
5613 ioc->name,__FUNCTION__));
5617 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventAck\n", ioc->name));
5619 pAck->Function = MPI_FUNCTION_EVENT_ACK;
5620 pAck->ChainOffset = 0;
5621 pAck->Reserved[0] = pAck->Reserved[1] = 0;
5623 pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
5624 pAck->Event = evnp->Event;
5625 pAck->EventContext = evnp->EventContext;
5627 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
5632 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5634 * mpt_config - Generic function to issue config message
5635 * @ioc: Pointer to an adapter structure
5636 * @pCfg: Pointer to a configuration structure. Struct contains
5637 * action, page address, direction, physical address
5638 * and pointer to a configuration page header
5639 * Page header is updated.
5641 * Returns 0 for success
5642 * -EPERM if not allowed due to ISR context
5643 * -EAGAIN if no msg frames currently available
5644 * -EFAULT for non-successful reply or no reply (timeout)
5647 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5650 ConfigExtendedPageHeader_t *pExtHdr = NULL;
5652 unsigned long flags;
5657 /* Prevent calling wait_event() (below), if caller happens
5658 * to be in ISR context, because that is fatal!
5660 in_isr = in_interrupt();
5662 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
5667 /* Get and Populate a free Frame
5669 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5670 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
5674 pReq = (Config_t *)mf;
5675 pReq->Action = pCfg->action;
5677 pReq->ChainOffset = 0;
5678 pReq->Function = MPI_FUNCTION_CONFIG;
5680 /* Assume page type is not extended and clear "reserved" fields. */
5681 pReq->ExtPageLength = 0;
5682 pReq->ExtPageType = 0;
5685 for (ii=0; ii < 8; ii++)
5686 pReq->Reserved2[ii] = 0;
5688 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
5689 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
5690 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
5691 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
5693 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5694 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
5695 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
5696 pReq->ExtPageType = pExtHdr->ExtPageType;
5697 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
5699 /* Page Length must be treated as a reserved field for the extended header. */
5700 pReq->Header.PageLength = 0;
5703 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
5705 /* Add a SGE to the config request.
5708 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
5710 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
5712 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5713 flagsLength |= pExtHdr->ExtPageLength * 4;
5715 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n",
5716 ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action));
5719 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
5721 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n",
5722 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
5725 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
5727 /* Append pCfg pointer to end of mf
5729 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5731 /* Initalize the timer
5733 init_timer(&pCfg->timer);
5734 pCfg->timer.data = (unsigned long) ioc;
5735 pCfg->timer.function = mpt_timer_expired;
5736 pCfg->wait_done = 0;
5738 /* Set the timer; ensure 10 second minimum */
5739 if (pCfg->timeout < 10)
5740 pCfg->timer.expires = jiffies + HZ*10;
5742 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5744 /* Add to end of Q, set timer and then issue this command */
5745 spin_lock_irqsave(&ioc->FreeQlock, flags);
5746 list_add_tail(&pCfg->linkage, &ioc->configQ);
5747 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5749 add_timer(&pCfg->timer);
5750 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5751 wait_event(mpt_waitq, pCfg->wait_done);
5753 /* mf has been freed - do not access */
5760 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5762 * mpt_timer_expired - Callback for timer process.
5763 * Used only internal config functionality.
5764 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5767 mpt_timer_expired(unsigned long data)
5769 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
5771 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired! \n", ioc->name));
5773 /* Perform a FW reload */
5774 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
5775 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
5777 /* No more processing.
5778 * Hard reset clean-up will wake up
5779 * process and free all resources.
5781 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired complete!\n", ioc->name));
5786 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5788 * mpt_ioc_reset - Base cleanup for hard reset
5789 * @ioc: Pointer to the adapter structure
5790 * @reset_phase: Indicates pre- or post-reset functionality
5792 * Remark: Frees resources with internally generated commands.
5795 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
5798 unsigned long flags;
5800 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5801 ": IOC %s_reset routed to MPT base driver!\n",
5802 ioc->name, reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
5803 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
5805 if (reset_phase == MPT_IOC_SETUP_RESET) {
5807 } else if (reset_phase == MPT_IOC_PRE_RESET) {
5808 /* If the internal config Q is not empty -
5809 * delete timer. MF resources will be freed when
5810 * the FIFO's are primed.
5812 spin_lock_irqsave(&ioc->FreeQlock, flags);
5813 list_for_each_entry(pCfg, &ioc->configQ, linkage)
5814 del_timer(&pCfg->timer);
5815 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5820 /* Search the configQ for internal commands.
5821 * Flush the Q, and wake up all suspended threads.
5823 spin_lock_irqsave(&ioc->FreeQlock, flags);
5824 list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
5825 list_del(&pCfg->linkage);
5827 pCfg->status = MPT_CONFIG_ERROR;
5828 pCfg->wait_done = 1;
5829 wake_up(&mpt_waitq);
5831 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5834 return 1; /* currently means nothing really */
5838 #ifdef CONFIG_PROC_FS /* { */
5839 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5841 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5843 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5845 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5847 * Returns 0 for success, non-zero for failure.
5850 procmpt_create(void)
5852 struct proc_dir_entry *ent;
5854 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
5855 if (mpt_proc_root_dir == NULL)
5858 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5860 ent->read_proc = procmpt_summary_read;
5862 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5864 ent->read_proc = procmpt_version_read;
5869 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5871 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5873 * Returns 0 for success, non-zero for failure.
5876 procmpt_destroy(void)
5878 remove_proc_entry("version", mpt_proc_root_dir);
5879 remove_proc_entry("summary", mpt_proc_root_dir);
5880 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
5883 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5885 * procmpt_summary_read - Handle read request of a summary file
5886 * @buf: Pointer to area to write information
5887 * @start: Pointer to start pointer
5888 * @offset: Offset to start writing
5889 * @request: Amount of read data requested
5890 * @eof: Pointer to EOF integer
5893 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
5894 * Returns number of characters written to process performing the read.
5897 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5907 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5911 list_for_each_entry(ioc, &ioc_list, list) {
5914 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5917 if ((out-buf) >= request)
5924 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5927 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5929 * procmpt_version_read - Handle read request from /proc/mpt/version.
5930 * @buf: Pointer to area to write information
5931 * @start: Pointer to start pointer
5932 * @offset: Offset to start writing
5933 * @request: Amount of read data requested
5934 * @eof: Pointer to EOF integer
5937 * Returns number of characters written to process performing the read.
5940 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5943 int scsi, fc, sas, lan, ctl, targ, dmp;
5947 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
5948 len += sprintf(buf+len, " Fusion MPT base driver\n");
5950 scsi = fc = sas = lan = ctl = targ = dmp = 0;
5951 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
5953 if (MptCallbacks[cb_idx]) {
5954 switch (MptDriverClass[cb_idx]) {
5956 if (!scsi++) drvname = "SPI host";
5959 if (!fc++) drvname = "FC host";
5962 if (!sas++) drvname = "SAS host";
5965 if (!lan++) drvname = "LAN";
5968 if (!targ++) drvname = "SCSI target";
5971 if (!ctl++) drvname = "ioctl";
5976 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
5980 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5983 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5985 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
5986 * @buf: Pointer to area to write information
5987 * @start: Pointer to start pointer
5988 * @offset: Offset to start writing
5989 * @request: Amount of read data requested
5990 * @eof: Pointer to EOF integer
5993 * Returns number of characters written to process performing the read.
5996 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5998 MPT_ADAPTER *ioc = data;
6004 mpt_get_fw_exp_ver(expVer, ioc);
6006 len = sprintf(buf, "%s:", ioc->name);
6007 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
6008 len += sprintf(buf+len, " (f/w download boot flag set)");
6009 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6010 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
6012 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
6013 ioc->facts.ProductID,
6015 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
6016 if (ioc->facts.FWImageSize)
6017 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
6018 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
6019 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
6020 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
6022 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
6023 ioc->facts.CurrentHostMfaHighAddr);
6024 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
6025 ioc->facts.CurrentSenseBufferHighAddr);
6027 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
6028 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
6030 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6031 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
6033 * Rounding UP to nearest 4-kB boundary here...
6035 sz = (ioc->req_sz * ioc->req_depth) + 128;
6036 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
6037 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6038 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
6039 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
6040 4*ioc->facts.RequestFrameSize,
6041 ioc->facts.GlobalCredits);
6043 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
6044 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
6045 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
6046 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6047 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
6048 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
6049 ioc->facts.CurReplyFrameSize,
6050 ioc->facts.ReplyQueueDepth);
6052 len += sprintf(buf+len, " MaxDevices = %d\n",
6053 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
6054 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
6057 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
6058 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
6060 ioc->facts.NumberOfPorts);
6061 if (ioc->bus_type == FC) {
6062 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
6063 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6064 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6065 a[5], a[4], a[3], a[2], a[1], a[0]);
6067 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
6068 ioc->fc_port_page0[p].WWNN.High,
6069 ioc->fc_port_page0[p].WWNN.Low,
6070 ioc->fc_port_page0[p].WWPN.High,
6071 ioc->fc_port_page0[p].WWPN.Low);
6075 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6078 #endif /* CONFIG_PROC_FS } */
6080 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6082 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
6085 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
6086 sprintf(buf, " (Exp %02d%02d)",
6087 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
6088 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
6091 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
6092 strcat(buf, " [MDBG]");
6096 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6098 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6099 * @ioc: Pointer to MPT_ADAPTER structure
6100 * @buffer: Pointer to buffer where IOC summary info should be written
6101 * @size: Pointer to number of bytes we wrote (set by this routine)
6102 * @len: Offset at which to start writing in buffer
6103 * @showlan: Display LAN stuff?
6105 * This routine writes (english readable) ASCII text, which represents
6106 * a summary of IOC information, to a buffer.
6109 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
6114 mpt_get_fw_exp_ver(expVer, ioc);
6117 * Shorter summary of attached ioc's...
6119 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6122 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
6123 ioc->facts.FWVersion.Word,
6125 ioc->facts.NumberOfPorts,
6128 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6129 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6130 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6131 a[5], a[4], a[3], a[2], a[1], a[0]);
6134 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
6137 y += sprintf(buffer+len+y, " (disabled)");
6139 y += sprintf(buffer+len+y, "\n");
6144 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6148 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6150 * mpt_HardResetHandler - Generic reset handler
6151 * @ioc: Pointer to MPT_ADAPTER structure
6152 * @sleepFlag: Indicates if sleep or schedule must be called.
6154 * Issues SCSI Task Management call based on input arg values.
6155 * If TaskMgmt fails, returns associated SCSI request.
6157 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
6158 * or a non-interrupt thread. In the former, must not call schedule().
6160 * Note: A return of -1 is a FATAL error case, as it means a
6161 * FW reload/initialization failed.
6163 * Returns 0 for SUCCESS or -1 if FAILED.
6166 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6169 unsigned long flags;
6171 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name));
6173 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
6174 printk("MF count 0x%x !\n", ioc->mfcnt);
6177 /* Reset the adapter. Prevent more than 1 call to
6178 * mpt_do_ioc_recovery at any instant in time.
6180 spin_lock_irqsave(&ioc->diagLock, flags);
6181 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
6182 spin_unlock_irqrestore(&ioc->diagLock, flags);
6185 ioc->diagPending = 1;
6187 spin_unlock_irqrestore(&ioc->diagLock, flags);
6189 /* FIXME: If do_ioc_recovery fails, repeat....
6192 /* The SCSI driver needs to adjust timeouts on all current
6193 * commands prior to the diagnostic reset being issued.
6194 * Prevents timeouts occurring during a diagnostic reset...very bad.
6195 * For all other protocol drivers, this is a no-op.
6201 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6202 if (MptResetHandlers[cb_idx]) {
6203 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling IOC reset_setup handler #%d\n",
6204 ioc->name, cb_idx));
6205 r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
6207 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling alt-%s setup reset handler #%d\n",
6208 ioc->name, ioc->alt_ioc->name, cb_idx));
6209 r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_SETUP_RESET);
6215 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
6216 printk(MYIOC_s_WARN_FMT "Cannot recover rc = %d!\n", ioc->name, rc);
6220 ioc->alt_ioc->reload_fw = 0;
6222 spin_lock_irqsave(&ioc->diagLock, flags);
6223 ioc->diagPending = 0;
6225 ioc->alt_ioc->diagPending = 0;
6226 spin_unlock_irqrestore(&ioc->diagLock, flags);
6228 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
6233 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6235 EventDescriptionStr(u8 event, u32 evData0, char *evStr)
6240 case MPI_EVENT_NONE:
6243 case MPI_EVENT_LOG_DATA:
6246 case MPI_EVENT_STATE_CHANGE:
6247 ds = "State Change";
6249 case MPI_EVENT_UNIT_ATTENTION:
6250 ds = "Unit Attention";
6252 case MPI_EVENT_IOC_BUS_RESET:
6253 ds = "IOC Bus Reset";
6255 case MPI_EVENT_EXT_BUS_RESET:
6256 ds = "External Bus Reset";
6258 case MPI_EVENT_RESCAN:
6259 ds = "Bus Rescan Event";
6261 case MPI_EVENT_LINK_STATUS_CHANGE:
6262 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
6263 ds = "Link Status(FAILURE) Change";
6265 ds = "Link Status(ACTIVE) Change";
6267 case MPI_EVENT_LOOP_STATE_CHANGE:
6268 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
6269 ds = "Loop State(LIP) Change";
6270 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
6271 ds = "Loop State(LPE) Change"; /* ??? */
6273 ds = "Loop State(LPB) Change"; /* ??? */
6275 case MPI_EVENT_LOGOUT:
6278 case MPI_EVENT_EVENT_CHANGE:
6284 case MPI_EVENT_INTEGRATED_RAID:
6286 u8 ReasonCode = (u8)(evData0 >> 16);
6287 switch (ReasonCode) {
6288 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
6289 ds = "Integrated Raid: Volume Created";
6291 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
6292 ds = "Integrated Raid: Volume Deleted";
6294 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
6295 ds = "Integrated Raid: Volume Settings Changed";
6297 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
6298 ds = "Integrated Raid: Volume Status Changed";
6300 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
6301 ds = "Integrated Raid: Volume Physdisk Changed";
6303 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
6304 ds = "Integrated Raid: Physdisk Created";
6306 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
6307 ds = "Integrated Raid: Physdisk Deleted";
6309 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
6310 ds = "Integrated Raid: Physdisk Settings Changed";
6312 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
6313 ds = "Integrated Raid: Physdisk Status Changed";
6315 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
6316 ds = "Integrated Raid: Domain Validation Needed";
6318 case MPI_EVENT_RAID_RC_SMART_DATA :
6319 ds = "Integrated Raid; Smart Data";
6321 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
6322 ds = "Integrated Raid: Replace Action Started";
6325 ds = "Integrated Raid";
6330 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
6331 ds = "SCSI Device Status Change";
6333 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
6335 u8 id = (u8)(evData0);
6336 u8 channel = (u8)(evData0 >> 8);
6337 u8 ReasonCode = (u8)(evData0 >> 16);
6338 switch (ReasonCode) {
6339 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
6340 snprintf(evStr, EVENT_DESCR_STR_SZ,
6341 "SAS Device Status Change: Added: "
6342 "id=%d channel=%d", id, channel);
6344 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
6345 snprintf(evStr, EVENT_DESCR_STR_SZ,
6346 "SAS Device Status Change: Deleted: "
6347 "id=%d channel=%d", id, channel);
6349 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
6350 snprintf(evStr, EVENT_DESCR_STR_SZ,
6351 "SAS Device Status Change: SMART Data: "
6352 "id=%d channel=%d", id, channel);
6354 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
6355 snprintf(evStr, EVENT_DESCR_STR_SZ,
6356 "SAS Device Status Change: No Persistancy: "
6357 "id=%d channel=%d", id, channel);
6359 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
6360 snprintf(evStr, EVENT_DESCR_STR_SZ,
6361 "SAS Device Status Change: Unsupported Device "
6362 "Discovered : id=%d channel=%d", id, channel);
6364 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
6365 snprintf(evStr, EVENT_DESCR_STR_SZ,
6366 "SAS Device Status Change: Internal Device "
6367 "Reset : id=%d channel=%d", id, channel);
6369 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
6370 snprintf(evStr, EVENT_DESCR_STR_SZ,
6371 "SAS Device Status Change: Internal Task "
6372 "Abort : id=%d channel=%d", id, channel);
6374 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
6375 snprintf(evStr, EVENT_DESCR_STR_SZ,
6376 "SAS Device Status Change: Internal Abort "
6377 "Task Set : id=%d channel=%d", id, channel);
6379 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
6380 snprintf(evStr, EVENT_DESCR_STR_SZ,
6381 "SAS Device Status Change: Internal Clear "
6382 "Task Set : id=%d channel=%d", id, channel);
6384 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
6385 snprintf(evStr, EVENT_DESCR_STR_SZ,
6386 "SAS Device Status Change: Internal Query "
6387 "Task : id=%d channel=%d", id, channel);
6390 snprintf(evStr, EVENT_DESCR_STR_SZ,
6391 "SAS Device Status Change: Unknown: "
6392 "id=%d channel=%d", id, channel);
6397 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
6398 ds = "Bus Timer Expired";
6400 case MPI_EVENT_QUEUE_FULL:
6402 u16 curr_depth = (u16)(evData0 >> 16);
6403 u8 channel = (u8)(evData0 >> 8);
6404 u8 id = (u8)(evData0);
6406 snprintf(evStr, EVENT_DESCR_STR_SZ,
6407 "Queue Full: channel=%d id=%d depth=%d",
6408 channel, id, curr_depth);
6411 case MPI_EVENT_SAS_SES:
6412 ds = "SAS SES Event";
6414 case MPI_EVENT_PERSISTENT_TABLE_FULL:
6415 ds = "Persistent Table Full";
6417 case MPI_EVENT_SAS_PHY_LINK_STATUS:
6419 u8 LinkRates = (u8)(evData0 >> 8);
6420 u8 PhyNumber = (u8)(evData0);
6421 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
6422 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
6423 switch (LinkRates) {
6424 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
6425 snprintf(evStr, EVENT_DESCR_STR_SZ,
6426 "SAS PHY Link Status: Phy=%d:"
6427 " Rate Unknown",PhyNumber);
6429 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
6430 snprintf(evStr, EVENT_DESCR_STR_SZ,
6431 "SAS PHY Link Status: Phy=%d:"
6432 " Phy Disabled",PhyNumber);
6434 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
6435 snprintf(evStr, EVENT_DESCR_STR_SZ,
6436 "SAS PHY Link Status: Phy=%d:"
6437 " Failed Speed Nego",PhyNumber);
6439 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
6440 snprintf(evStr, EVENT_DESCR_STR_SZ,
6441 "SAS PHY Link Status: Phy=%d:"
6442 " Sata OOB Completed",PhyNumber);
6444 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
6445 snprintf(evStr, EVENT_DESCR_STR_SZ,
6446 "SAS PHY Link Status: Phy=%d:"
6447 " Rate 1.5 Gbps",PhyNumber);
6449 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
6450 snprintf(evStr, EVENT_DESCR_STR_SZ,
6451 "SAS PHY Link Status: Phy=%d:"
6452 " Rate 3.0 Gpbs",PhyNumber);
6455 snprintf(evStr, EVENT_DESCR_STR_SZ,
6456 "SAS PHY Link Status: Phy=%d", PhyNumber);
6461 case MPI_EVENT_SAS_DISCOVERY_ERROR:
6462 ds = "SAS Discovery Error";
6464 case MPI_EVENT_IR_RESYNC_UPDATE:
6466 u8 resync_complete = (u8)(evData0 >> 16);
6467 snprintf(evStr, EVENT_DESCR_STR_SZ,
6468 "IR Resync Update: Complete = %d:",resync_complete);
6473 u8 ReasonCode = (u8)(evData0 >> 16);
6474 switch (ReasonCode) {
6475 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
6476 ds = "IR2: LD State Changed";
6478 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
6479 ds = "IR2: PD State Changed";
6481 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
6482 ds = "IR2: Bad Block Table Full";
6484 case MPI_EVENT_IR2_RC_PD_INSERTED:
6485 ds = "IR2: PD Inserted";
6487 case MPI_EVENT_IR2_RC_PD_REMOVED:
6488 ds = "IR2: PD Removed";
6490 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
6491 ds = "IR2: Foreign CFG Detected";
6493 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
6494 ds = "IR2: Rebuild Medium Error";
6502 case MPI_EVENT_SAS_DISCOVERY:
6505 ds = "SAS Discovery: Start";
6507 ds = "SAS Discovery: Stop";
6510 case MPI_EVENT_LOG_ENTRY_ADDED:
6511 ds = "SAS Log Entry Added";
6514 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
6516 u8 phy_num = (u8)(evData0);
6517 u8 port_num = (u8)(evData0 >> 8);
6518 u8 port_width = (u8)(evData0 >> 16);
6519 u8 primative = (u8)(evData0 >> 24);
6520 snprintf(evStr, EVENT_DESCR_STR_SZ,
6521 "SAS Broadcase Primative: phy=%d port=%d "
6522 "width=%d primative=0x%02x",
6523 phy_num, port_num, port_width, primative);
6527 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
6529 u8 reason = (u8)(evData0);
6530 u8 port_num = (u8)(evData0 >> 8);
6531 u16 handle = le16_to_cpu(evData0 >> 16);
6533 snprintf(evStr, EVENT_DESCR_STR_SZ,
6534 "SAS Initiator Device Status Change: reason=0x%02x "
6535 "port=%d handle=0x%04x",
6536 reason, port_num, handle);
6540 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
6542 u8 max_init = (u8)(evData0);
6543 u8 current_init = (u8)(evData0 >> 8);
6545 snprintf(evStr, EVENT_DESCR_STR_SZ,
6546 "SAS Initiator Device Table Overflow: max initiators=%02d "
6547 "current initators=%02d",
6548 max_init, current_init);
6551 case MPI_EVENT_SAS_SMP_ERROR:
6553 u8 status = (u8)(evData0);
6554 u8 port_num = (u8)(evData0 >> 8);
6555 u8 result = (u8)(evData0 >> 16);
6557 if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
6558 snprintf(evStr, EVENT_DESCR_STR_SZ,
6559 "SAS SMP Error: port=%d result=0x%02x",
6561 else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
6562 snprintf(evStr, EVENT_DESCR_STR_SZ,
6563 "SAS SMP Error: port=%d : CRC Error",
6565 else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
6566 snprintf(evStr, EVENT_DESCR_STR_SZ,
6567 "SAS SMP Error: port=%d : Timeout",
6569 else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
6570 snprintf(evStr, EVENT_DESCR_STR_SZ,
6571 "SAS SMP Error: port=%d : No Destination",
6573 else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
6574 snprintf(evStr, EVENT_DESCR_STR_SZ,
6575 "SAS SMP Error: port=%d : Bad Destination",
6578 snprintf(evStr, EVENT_DESCR_STR_SZ,
6579 "SAS SMP Error: port=%d : status=0x%02x",
6585 * MPT base "custom" events may be added here...
6592 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
6595 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6597 * ProcessEventNotification - Route EventNotificationReply to all event handlers
6598 * @ioc: Pointer to MPT_ADAPTER structure
6599 * @pEventReply: Pointer to EventNotification reply frame
6600 * @evHandlers: Pointer to integer, number of event handlers
6602 * Routes a received EventNotificationReply to all currently registered
6604 * Returns sum of event handlers return values.
6607 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
6616 char evStr[EVENT_DESCR_STR_SZ];
6620 * Do platform normalization of values
6622 event = le32_to_cpu(pEventReply->Event) & 0xFF;
6623 // evCtx = le32_to_cpu(pEventReply->EventContext);
6624 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
6626 evData0 = le32_to_cpu(pEventReply->Data[0]);
6629 EventDescriptionStr(event, evData0, evStr);
6630 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event:(%02Xh) : %s\n",
6635 #ifdef CONFIG_FUSION_LOGGING
6636 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6637 ": Event data:\n", ioc->name));
6638 for (ii = 0; ii < evDataLen; ii++)
6639 devtverboseprintk(ioc, printk(" %08x",
6640 le32_to_cpu(pEventReply->Data[ii])));
6641 devtverboseprintk(ioc, printk("\n"));
6645 * Do general / base driver event processing
6648 case MPI_EVENT_EVENT_CHANGE: /* 0A */
6650 u8 evState = evData0 & 0xFF;
6652 /* CHECKME! What if evState unexpectedly says OFF (0)? */
6654 /* Update EventState field in cached IocFacts */
6655 if (ioc->facts.Function) {
6656 ioc->facts.EventState = evState;
6660 case MPI_EVENT_INTEGRATED_RAID:
6661 mptbase_raid_process_event_data(ioc,
6662 (MpiEventDataRaid_t *)pEventReply->Data);
6669 * Should this event be logged? Events are written sequentially.
6670 * When buffer is full, start again at the top.
6672 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
6675 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
6677 ioc->events[idx].event = event;
6678 ioc->events[idx].eventContext = ioc->eventContext;
6680 for (ii = 0; ii < 2; ii++) {
6682 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
6684 ioc->events[idx].data[ii] = 0;
6687 ioc->eventContext++;
6692 * Call each currently registered protocol event handler.
6694 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6695 if (MptEvHandlers[cb_idx]) {
6696 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Routing Event to event handler #%d\n",
6697 ioc->name, cb_idx));
6698 r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply);
6702 /* FIXME? Examine results here? */
6705 * If needed, send (a single) EventAck.
6707 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
6708 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6709 "EventAck required\n",ioc->name));
6710 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
6711 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SendEventAck returned %d\n",
6716 *evHandlers = handlers;
6720 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6722 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
6723 * @ioc: Pointer to MPT_ADAPTER structure
6724 * @log_info: U32 LogInfo reply word from the IOC
6726 * Refer to lsi/mpi_log_fc.h.
6729 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
6731 char *desc = "unknown";
6733 switch (log_info & 0xFF000000) {
6734 case MPI_IOCLOGINFO_FC_INIT_BASE:
6735 desc = "FCP Initiator";
6737 case MPI_IOCLOGINFO_FC_TARGET_BASE:
6738 desc = "FCP Target";
6740 case MPI_IOCLOGINFO_FC_LAN_BASE:
6743 case MPI_IOCLOGINFO_FC_MSG_BASE:
6744 desc = "MPI Message Layer";
6746 case MPI_IOCLOGINFO_FC_LINK_BASE:
6749 case MPI_IOCLOGINFO_FC_CTX_BASE:
6750 desc = "Context Manager";
6752 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
6753 desc = "Invalid Field Offset";
6755 case MPI_IOCLOGINFO_FC_STATE_CHANGE:
6756 desc = "State Change Info";
6760 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
6761 ioc->name, log_info, desc, (log_info & 0xFFFFFF));
6764 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6766 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
6767 * @ioc: Pointer to MPT_ADAPTER structure
6768 * @mr: Pointer to MPT reply frame
6769 * @log_info: U32 LogInfo word from the IOC
6771 * Refer to lsi/sp_log.h.
6774 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
6776 u32 info = log_info & 0x00FF0000;
6777 char *desc = "unknown";
6781 desc = "bug! MID not found";
6782 if (ioc->reload_fw == 0)
6787 desc = "Parity Error";
6791 desc = "ASYNC Outbound Overrun";
6795 desc = "SYNC Offset Error";
6803 desc = "Msg In Overflow";
6811 desc = "Outbound DMA Overrun";
6815 desc = "Task Management";
6819 desc = "Device Problem";
6823 desc = "Invalid Phase Change";
6827 desc = "Untagged Table Size";
6832 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
6835 /* strings for sas loginfo */
6836 static char *originator_str[] = {
6841 static char *iop_code_str[] = {
6843 "Invalid SAS Address", /* 01h */
6845 "Invalid Page", /* 03h */
6846 "Diag Message Error", /* 04h */
6847 "Task Terminated", /* 05h */
6848 "Enclosure Management", /* 06h */
6849 "Target Mode" /* 07h */
6851 static char *pl_code_str[] = {
6853 "Open Failure", /* 01h */
6854 "Invalid Scatter Gather List", /* 02h */
6855 "Wrong Relative Offset or Frame Length", /* 03h */
6856 "Frame Transfer Error", /* 04h */
6857 "Transmit Frame Connected Low", /* 05h */
6858 "SATA Non-NCQ RW Error Bit Set", /* 06h */
6859 "SATA Read Log Receive Data Error", /* 07h */
6860 "SATA NCQ Fail All Commands After Error", /* 08h */
6861 "SATA Error in Receive Set Device Bit FIS", /* 09h */
6862 "Receive Frame Invalid Message", /* 0Ah */
6863 "Receive Context Message Valid Error", /* 0Bh */
6864 "Receive Frame Current Frame Error", /* 0Ch */
6865 "SATA Link Down", /* 0Dh */
6866 "Discovery SATA Init W IOS", /* 0Eh */
6867 "Config Invalid Page", /* 0Fh */
6868 "Discovery SATA Init Timeout", /* 10h */
6871 "IO Not Yet Executed", /* 13h */
6872 "IO Executed", /* 14h */
6873 "Persistent Reservation Out Not Affiliation "
6875 "Open Transmit DMA Abort", /* 16h */
6876 "IO Device Missing Delay Retry", /* 17h */
6877 "IO Cancelled Due to Recieve Error", /* 18h */
6885 "Enclosure Management" /* 20h */
6887 static char *ir_code_str[] = {
6888 "Raid Action Error", /* 00h */
6898 static char *raid_sub_code_str[] = {
6900 "Volume Creation Failed: Data Passed too "
6902 "Volume Creation Failed: Duplicate Volumes "
6903 "Attempted", /* 02h */
6904 "Volume Creation Failed: Max Number "
6905 "Supported Volumes Exceeded", /* 03h */
6906 "Volume Creation Failed: DMA Error", /* 04h */
6907 "Volume Creation Failed: Invalid Volume Type", /* 05h */
6908 "Volume Creation Failed: Error Reading "
6909 "MFG Page 4", /* 06h */
6910 "Volume Creation Failed: Creating Internal "
6911 "Structures", /* 07h */
6920 "Activation failed: Already Active Volume", /* 10h */
6921 "Activation failed: Unsupported Volume Type", /* 11h */
6922 "Activation failed: Too Many Active Volumes", /* 12h */
6923 "Activation failed: Volume ID in Use", /* 13h */
6924 "Activation failed: Reported Failure", /* 14h */
6925 "Activation failed: Importing a Volume", /* 15h */
6936 "Phys Disk failed: Too Many Phys Disks", /* 20h */
6937 "Phys Disk failed: Data Passed too Large", /* 21h */
6938 "Phys Disk failed: DMA Error", /* 22h */
6939 "Phys Disk failed: Invalid <channel:id>", /* 23h */
6940 "Phys Disk failed: Creating Phys Disk Config "
6953 "Compatibility Error: IR Disabled", /* 30h */
6954 "Compatibility Error: Inquiry Comand Failed", /* 31h */
6955 "Compatibility Error: Device not Direct Access "
6956 "Device ", /* 32h */
6957 "Compatibility Error: Removable Device Found", /* 33h */
6958 "Compatibility Error: Device SCSI Version not "
6959 "2 or Higher", /* 34h */
6960 "Compatibility Error: SATA Device, 48 BIT LBA "
6961 "not Supported", /* 35h */
6962 "Compatibility Error: Device doesn't have "
6963 "512 Byte Block Sizes", /* 36h */
6964 "Compatibility Error: Volume Type Check Failed", /* 37h */
6965 "Compatibility Error: Volume Type is "
6966 "Unsupported by FW", /* 38h */
6967 "Compatibility Error: Disk Drive too Small for "
6968 "use in Volume", /* 39h */
6969 "Compatibility Error: Phys Disk for Create "
6970 "Volume not Found", /* 3Ah */
6971 "Compatibility Error: Too Many or too Few "
6972 "Disks for Volume Type", /* 3Bh */
6973 "Compatibility Error: Disk stripe Sizes "
6974 "Must be 64KB", /* 3Ch */
6975 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
6978 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6980 * mpt_sas_log_info - Log information returned from SAS IOC.
6981 * @ioc: Pointer to MPT_ADAPTER structure
6982 * @log_info: U32 LogInfo reply word from the IOC
6984 * Refer to lsi/mpi_log_sas.h.
6987 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
6989 union loginfo_type {
6998 union loginfo_type sas_loginfo;
6999 char *originator_desc = NULL;
7000 char *code_desc = NULL;
7001 char *sub_code_desc = NULL;
7003 sas_loginfo.loginfo = log_info;
7004 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
7005 (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
7008 originator_desc = originator_str[sas_loginfo.dw.originator];
7010 switch (sas_loginfo.dw.originator) {
7013 if (sas_loginfo.dw.code <
7014 sizeof(iop_code_str)/sizeof(char*))
7015 code_desc = iop_code_str[sas_loginfo.dw.code];
7018 if (sas_loginfo.dw.code <
7019 sizeof(pl_code_str)/sizeof(char*))
7020 code_desc = pl_code_str[sas_loginfo.dw.code];
7023 if (sas_loginfo.dw.code >=
7024 sizeof(ir_code_str)/sizeof(char*))
7026 code_desc = ir_code_str[sas_loginfo.dw.code];
7027 if (sas_loginfo.dw.subcode >=
7028 sizeof(raid_sub_code_str)/sizeof(char*))
7030 if (sas_loginfo.dw.code == 0)
7032 raid_sub_code_str[sas_loginfo.dw.subcode];
7038 if (sub_code_desc != NULL)
7039 printk(MYIOC_s_INFO_FMT
7040 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7042 ioc->name, log_info, originator_desc, code_desc,
7044 else if (code_desc != NULL)
7045 printk(MYIOC_s_INFO_FMT
7046 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7047 " SubCode(0x%04x)\n",
7048 ioc->name, log_info, originator_desc, code_desc,
7049 sas_loginfo.dw.subcode);
7051 printk(MYIOC_s_INFO_FMT
7052 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
7053 " SubCode(0x%04x)\n",
7054 ioc->name, log_info, originator_desc,
7055 sas_loginfo.dw.code, sas_loginfo.dw.subcode);
7058 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7060 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
7061 * @ioc: Pointer to MPT_ADAPTER structure
7062 * @ioc_status: U32 IOCStatus word from IOC
7063 * @mf: Pointer to MPT request frame
7065 * Refer to lsi/mpi.h.
7068 mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7070 Config_t *pReq = (Config_t *)mf;
7071 char extend_desc[EVENT_DESCR_STR_SZ];
7076 if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
7077 page_type = pReq->ExtPageType;
7079 page_type = pReq->Header.PageType;
7082 * ignore invalid page messages for GET_NEXT_HANDLE
7084 form = le32_to_cpu(pReq->PageAddress);
7085 if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
7086 if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
7087 page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
7088 page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
7089 if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
7090 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
7093 if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
7094 if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
7095 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
7099 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
7100 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
7101 page_type, pReq->Header.PageNumber, pReq->Action, form);
7103 switch (ioc_status) {
7105 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7106 desc = "Config Page Invalid Action";
7109 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7110 desc = "Config Page Invalid Type";
7113 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7114 desc = "Config Page Invalid Page";
7117 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7118 desc = "Config Page Invalid Data";
7121 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7122 desc = "Config Page No Defaults";
7125 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7126 desc = "Config Page Can't Commit";
7133 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s: %s\n",
7134 ioc->name, ioc_status, desc, extend_desc));
7138 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
7139 * @ioc: Pointer to MPT_ADAPTER structure
7140 * @ioc_status: U32 IOCStatus word from IOC
7141 * @mf: Pointer to MPT request frame
7143 * Refer to lsi/mpi.h.
7146 mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7148 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
7153 /****************************************************************************/
7154 /* Common IOCStatus values for all replies */
7155 /****************************************************************************/
7157 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
7158 desc = "Invalid Function";
7161 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
7165 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
7166 desc = "Invalid SGL";
7169 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
7170 desc = "Internal Error";
7173 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
7177 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
7178 desc = "Insufficient Resources";
7181 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
7182 desc = "Invalid Field";
7185 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
7186 desc = "Invalid State";
7189 /****************************************************************************/
7190 /* Config IOCStatus values */
7191 /****************************************************************************/
7193 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7194 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7195 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7196 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7197 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7198 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7199 mpt_iocstatus_info_config(ioc, status, mf);
7202 /****************************************************************************/
7203 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
7205 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
7207 /****************************************************************************/
7209 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
7210 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
7211 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
7212 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
7213 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
7214 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
7215 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
7216 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
7217 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
7218 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
7219 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
7220 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
7221 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
7224 /****************************************************************************/
7225 /* SCSI Target values */
7226 /****************************************************************************/
7228 case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
7229 desc = "Target: Priority IO";
7232 case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
7233 desc = "Target: Invalid Port";
7236 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
7237 desc = "Target Invalid IO Index:";
7240 case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
7241 desc = "Target: Aborted";
7244 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
7245 desc = "Target: No Conn Retryable";
7248 case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
7249 desc = "Target: No Connection";
7252 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
7253 desc = "Target: Transfer Count Mismatch";
7256 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
7257 desc = "Target: STS Data not Sent";
7260 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
7261 desc = "Target: Data Offset Error";
7264 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
7265 desc = "Target: Too Much Write Data";
7268 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
7269 desc = "Target: IU Too Short";
7272 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
7273 desc = "Target: ACK NAK Timeout";
7276 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
7277 desc = "Target: Nak Received";
7280 /****************************************************************************/
7281 /* Fibre Channel Direct Access values */
7282 /****************************************************************************/
7284 case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
7285 desc = "FC: Aborted";
7288 case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
7289 desc = "FC: RX ID Invalid";
7292 case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
7293 desc = "FC: DID Invalid";
7296 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
7297 desc = "FC: Node Logged Out";
7300 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
7301 desc = "FC: Exchange Canceled";
7304 /****************************************************************************/
7306 /****************************************************************************/
7308 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
7309 desc = "LAN: Device not Found";
7312 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
7313 desc = "LAN: Device Failure";
7316 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
7317 desc = "LAN: Transmit Error";
7320 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
7321 desc = "LAN: Transmit Aborted";
7324 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
7325 desc = "LAN: Receive Error";
7328 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
7329 desc = "LAN: Receive Aborted";
7332 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
7333 desc = "LAN: Partial Packet";
7336 case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
7337 desc = "LAN: Canceled";
7340 /****************************************************************************/
7341 /* Serial Attached SCSI values */
7342 /****************************************************************************/
7344 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
7345 desc = "SAS: SMP Request Failed";
7348 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
7349 desc = "SAS: SMP Data Overrun";
7360 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s\n",
7361 ioc->name, status, desc));
7364 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7365 EXPORT_SYMBOL(mpt_attach);
7366 EXPORT_SYMBOL(mpt_detach);
7368 EXPORT_SYMBOL(mpt_resume);
7369 EXPORT_SYMBOL(mpt_suspend);
7371 EXPORT_SYMBOL(ioc_list);
7372 EXPORT_SYMBOL(mpt_proc_root_dir);
7373 EXPORT_SYMBOL(mpt_register);
7374 EXPORT_SYMBOL(mpt_deregister);
7375 EXPORT_SYMBOL(mpt_event_register);
7376 EXPORT_SYMBOL(mpt_event_deregister);
7377 EXPORT_SYMBOL(mpt_reset_register);
7378 EXPORT_SYMBOL(mpt_reset_deregister);
7379 EXPORT_SYMBOL(mpt_device_driver_register);
7380 EXPORT_SYMBOL(mpt_device_driver_deregister);
7381 EXPORT_SYMBOL(mpt_get_msg_frame);
7382 EXPORT_SYMBOL(mpt_put_msg_frame);
7383 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri);
7384 EXPORT_SYMBOL(mpt_free_msg_frame);
7385 EXPORT_SYMBOL(mpt_add_sge);
7386 EXPORT_SYMBOL(mpt_send_handshake_request);
7387 EXPORT_SYMBOL(mpt_verify_adapter);
7388 EXPORT_SYMBOL(mpt_GetIocState);
7389 EXPORT_SYMBOL(mpt_print_ioc_summary);
7390 EXPORT_SYMBOL(mpt_HardResetHandler);
7391 EXPORT_SYMBOL(mpt_config);
7392 EXPORT_SYMBOL(mpt_findImVolumes);
7393 EXPORT_SYMBOL(mpt_alloc_fw_memory);
7394 EXPORT_SYMBOL(mpt_free_fw_memory);
7395 EXPORT_SYMBOL(mptbase_sas_persist_operation);
7396 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
7398 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7400 * fusion_init - Fusion MPT base driver initialization routine.
7402 * Returns 0 for success, non-zero for failure.
7409 show_mptmod_ver(my_NAME, my_VERSION);
7410 printk(KERN_INFO COPYRIGHT "\n");
7412 for (cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
7413 MptCallbacks[cb_idx] = NULL;
7414 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
7415 MptEvHandlers[cb_idx] = NULL;
7416 MptResetHandlers[cb_idx] = NULL;
7419 /* Register ourselves (mptbase) in order to facilitate
7420 * EventNotification handling.
7422 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
7424 /* Register for hard reset handling callbacks.
7426 mpt_reset_register(mpt_base_index, mpt_ioc_reset);
7428 #ifdef CONFIG_PROC_FS
7429 (void) procmpt_create();
7434 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7436 * fusion_exit - Perform driver unload cleanup.
7438 * This routine frees all resources associated with each MPT adapter
7439 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
7445 mpt_reset_deregister(mpt_base_index);
7447 #ifdef CONFIG_PROC_FS
7452 module_init(fusion_init);
7453 module_exit(fusion_exit);