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 IOC ptr in the pcidev's driver data. */
1662 pci_set_drvdata(ioc->pcidev, ioc);
1664 /* Set lookup ptr. */
1665 list_add_tail(&ioc->list, &ioc_list);
1667 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1669 mpt_detect_bound_ports(ioc, pdev);
1671 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1673 printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",
1676 list_del(&ioc->list);
1678 ioc->alt_ioc->alt_ioc = NULL;
1681 pci_set_drvdata(pdev, NULL);
1685 /* call per device driver probe entry point */
1686 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
1687 if(MptDeviceDriverHandlers[cb_idx] &&
1688 MptDeviceDriverHandlers[cb_idx]->probe) {
1689 MptDeviceDriverHandlers[cb_idx]->probe(pdev,id);
1693 #ifdef CONFIG_PROC_FS
1695 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1697 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1699 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1701 ent->read_proc = procmpt_iocinfo_read;
1704 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1706 ent->read_proc = procmpt_summary_read;
1715 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1717 * mpt_detach - Remove a PCI intelligent MPT adapter.
1718 * @pdev: Pointer to pci_dev structure
1722 mpt_detach(struct pci_dev *pdev)
1724 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1728 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
1729 remove_proc_entry(pname, NULL);
1730 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
1731 remove_proc_entry(pname, NULL);
1732 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
1733 remove_proc_entry(pname, NULL);
1735 /* call per device driver remove entry point */
1736 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
1737 if(MptDeviceDriverHandlers[cb_idx] &&
1738 MptDeviceDriverHandlers[cb_idx]->remove) {
1739 MptDeviceDriverHandlers[cb_idx]->remove(pdev);
1743 /* Disable interrupts! */
1744 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1747 synchronize_irq(pdev->irq);
1749 /* Clear any lingering interrupt */
1750 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1752 CHIPREG_READ32(&ioc->chip->IntStatus);
1754 mpt_adapter_dispose(ioc);
1756 pci_set_drvdata(pdev, NULL);
1759 /**************************************************************************
1763 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1765 * mpt_suspend - Fusion MPT base driver suspend routine.
1766 * @pdev: Pointer to pci_dev structure
1767 * @state: new state to enter
1770 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
1773 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1775 device_state=pci_choose_state(pdev, state);
1777 printk(MYIOC_s_INFO_FMT
1778 "pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
1779 ioc->name, pdev, pci_name(pdev), device_state);
1781 pci_save_state(pdev);
1783 /* put ioc into READY_STATE */
1784 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
1785 printk(MYIOC_s_ERR_FMT
1786 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
1789 /* disable interrupts */
1790 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1793 /* Clear any lingering interrupt */
1794 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1796 pci_disable_device(pdev);
1797 pci_set_power_state(pdev, device_state);
1802 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1804 * mpt_resume - Fusion MPT base driver resume routine.
1805 * @pdev: Pointer to pci_dev structure
1808 mpt_resume(struct pci_dev *pdev)
1810 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1811 u32 device_state = pdev->current_state;
1815 printk(MYIOC_s_INFO_FMT
1816 "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
1817 ioc->name, pdev, pci_name(pdev), device_state);
1819 pci_set_power_state(pdev, 0);
1820 pci_restore_state(pdev);
1821 err = pci_enable_device(pdev);
1825 /* enable interrupts */
1826 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
1829 printk(MYIOC_s_INFO_FMT
1830 "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1832 (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1833 CHIPREG_READ32(&ioc->chip->Doorbell));
1835 /* bring ioc to operational state */
1836 if ((recovery_state = mpt_do_ioc_recovery(ioc,
1837 MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {
1838 printk(MYIOC_s_INFO_FMT
1839 "pci-resume: Cannot recover, error:[%x]\n",
1840 ioc->name, recovery_state);
1842 printk(MYIOC_s_INFO_FMT
1843 "pci-resume: success\n", ioc->name);
1851 mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase)
1853 if ((MptDriverClass[index] == MPTSPI_DRIVER &&
1854 ioc->bus_type != SPI) ||
1855 (MptDriverClass[index] == MPTFC_DRIVER &&
1856 ioc->bus_type != FC) ||
1857 (MptDriverClass[index] == MPTSAS_DRIVER &&
1858 ioc->bus_type != SAS))
1859 /* make sure we only call the relevant reset handler
1862 return (MptResetHandlers[index])(ioc, reset_phase);
1865 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1867 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1868 * @ioc: Pointer to MPT adapter structure
1869 * @reason: Event word / reason
1870 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1872 * This routine performs all the steps necessary to bring the IOC
1873 * to a OPERATIONAL state.
1875 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1880 * -1 if failed to get board READY
1881 * -2 if READY but IOCFacts Failed
1882 * -3 if READY but PrimeIOCFifos Failed
1883 * -4 if READY but IOCInit Failed
1886 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1888 int hard_reset_done = 0;
1889 int alt_ioc_ready = 0;
1896 int reset_alt_ioc_active = 0;
1897 int irq_allocated = 0;
1900 printk(MYIOC_s_INFO_FMT "Initiating %s\n", ioc->name,
1901 reason == MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
1903 /* Disable reply interrupts (also blocks FreeQ) */
1904 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1908 if (ioc->alt_ioc->active)
1909 reset_alt_ioc_active = 1;
1911 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1912 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
1913 ioc->alt_ioc->active = 0;
1917 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
1920 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
1921 if (hard_reset_done == -4) {
1922 printk(MYIOC_s_WARN_FMT "Owned by PEER..skipping!\n",
1925 if (reset_alt_ioc_active && ioc->alt_ioc) {
1926 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1927 dprintk(ioc, printk(MYIOC_s_INFO_FMT
1928 "alt_ioc reply irq re-enabled\n", ioc->alt_ioc->name));
1929 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
1930 ioc->alt_ioc->active = 1;
1934 printk(MYIOC_s_WARN_FMT "NOT READY!\n", ioc->name);
1939 /* hard_reset_done = 0 if a soft reset was performed
1940 * and 1 if a hard reset was performed.
1942 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
1943 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
1946 printk(MYIOC_s_WARN_FMT "alt_ioc not ready!\n", ioc->alt_ioc->name);
1949 for (ii=0; ii<5; ii++) {
1950 /* Get IOC facts! Allow 5 retries */
1951 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
1957 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1958 "Retry IocFacts failed rc=%x\n", ioc->name, rc));
1960 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1961 MptDisplayIocCapabilities(ioc);
1964 if (alt_ioc_ready) {
1965 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
1966 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1967 "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
1968 /* Retry - alt IOC was initialized once
1970 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
1973 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1974 "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
1976 reset_alt_ioc_active = 0;
1977 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1978 MptDisplayIocCapabilities(ioc->alt_ioc);
1983 * Device is reset now. It must have de-asserted the interrupt line
1984 * (if it was asserted) and it should be safe to register for the
1987 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1989 if (ioc->pcidev->irq) {
1990 if (mpt_msi_enable && !pci_enable_msi(ioc->pcidev))
1991 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
1993 rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
1994 IRQF_SHARED, ioc->name, ioc);
1996 printk(MYIOC_s_ERR_FMT "Unable to allocate "
1997 "interrupt %d!\n", ioc->name, ioc->pcidev->irq);
1999 pci_disable_msi(ioc->pcidev);
2003 ioc->pci_irq = ioc->pcidev->irq;
2004 pci_set_master(ioc->pcidev); /* ?? */
2005 dprintk(ioc, printk(MYIOC_s_INFO_FMT "installed at interrupt "
2006 "%d\n", ioc->name, ioc->pcidev->irq));
2010 /* Prime reply & request queues!
2011 * (mucho alloc's) Must be done prior to
2012 * init as upper addresses are needed for init.
2013 * If fails, continue with alt-ioc processing
2015 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
2018 /* May need to check/upload firmware & data here!
2019 * If fails, continue with alt-ioc processing
2021 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
2024 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
2025 printk(MYIOC_s_WARN_FMT ": alt_ioc (%d) FIFO mgmt alloc!\n",
2026 ioc->alt_ioc->name, rc);
2028 reset_alt_ioc_active = 0;
2031 if (alt_ioc_ready) {
2032 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
2034 reset_alt_ioc_active = 0;
2035 printk(MYIOC_s_WARN_FMT "alt_ioc (%d) init failure!\n",
2036 ioc->alt_ioc->name, rc);
2040 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
2041 if (ioc->upload_fw) {
2042 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2043 "firmware upload required!\n", ioc->name));
2045 /* Controller is not operational, cannot do upload
2048 rc = mpt_do_upload(ioc, sleepFlag);
2050 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2052 * Maintain only one pointer to FW memory
2053 * so there will not be two attempt to
2054 * downloadboot onboard dual function
2055 * chips (mpt_adapter_disable,
2058 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2059 "mpt_upload: alt_%s has cached_fw=%p \n",
2060 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
2061 ioc->cached_fw = NULL;
2064 printk(MYIOC_s_WARN_FMT
2065 "firmware upload failure!\n", ioc->name);
2073 /* Enable! (reply interrupt) */
2074 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
2078 if (reset_alt_ioc_active && ioc->alt_ioc) {
2079 /* (re)Enable alt-IOC! (reply interrupt) */
2080 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "alt_ioc reply irq re-enabled\n",
2081 ioc->alt_ioc->name));
2082 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2083 ioc->alt_ioc->active = 1;
2086 /* Enable MPT base driver management of EventNotification
2087 * and EventAck handling.
2089 if ((ret == 0) && (!ioc->facts.EventState))
2090 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
2092 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2093 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
2095 /* Add additional "reason" check before call to GetLanConfigPages
2096 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2097 * recursive scenario; GetLanConfigPages times out, timer expired
2098 * routine calls HardResetHandler, which calls into here again,
2099 * and we try GetLanConfigPages again...
2101 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2104 * Initalize link list for inactive raid volumes.
2106 init_MUTEX(&ioc->raid_data.inactive_list_mutex);
2107 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2109 if (ioc->bus_type == SAS) {
2111 /* clear persistency table */
2112 if(ioc->facts.IOCExceptions &
2113 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
2114 ret = mptbase_sas_persist_operation(ioc,
2115 MPI_SAS_OP_CLEAR_NOT_PRESENT);
2122 mpt_findImVolumes(ioc);
2124 } else if (ioc->bus_type == FC) {
2125 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
2126 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2128 * Pre-fetch the ports LAN MAC address!
2129 * (LANPage1_t stuff)
2131 (void) GetLanConfigPages(ioc);
2132 a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2133 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2134 "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
2135 ioc->name, a[5], a[4], a[3], a[2], a[1], a[0]));
2139 /* Get NVRAM and adapter maximums from SPP 0 and 2
2141 mpt_GetScsiPortSettings(ioc, 0);
2143 /* Get version and length of SDP 1
2145 mpt_readScsiDevicePageHeaders(ioc, 0);
2149 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
2150 mpt_findImVolumes(ioc);
2152 /* Check, and possibly reset, the coalescing value
2154 mpt_read_ioc_pg_1(ioc);
2156 mpt_read_ioc_pg_4(ioc);
2159 GetIoUnitPage2(ioc);
2160 mpt_get_manufacturing_pg_0(ioc);
2164 * Call each currently registered protocol IOC reset handler
2165 * with post-reset indication.
2166 * NOTE: If we're doing _IOC_BRINGUP, there can be no
2167 * MptResetHandlers[] registered yet.
2169 if (hard_reset_done) {
2171 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
2172 if ((ret == 0) && MptResetHandlers[cb_idx]) {
2173 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2174 "Calling IOC post_reset handler #%d\n",
2175 ioc->name, cb_idx));
2176 rc += mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET);
2180 if (alt_ioc_ready && MptResetHandlers[cb_idx]) {
2181 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2182 "Calling IOC post_reset handler #%d\n",
2183 ioc->alt_ioc->name, cb_idx));
2184 rc += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_POST_RESET);
2188 /* FIXME? Examine results here? */
2192 if ((ret != 0) && irq_allocated) {
2193 free_irq(ioc->pci_irq, ioc);
2195 pci_disable_msi(ioc->pcidev);
2200 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2202 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2203 * @ioc: Pointer to MPT adapter structure
2204 * @pdev: Pointer to (struct pci_dev) structure
2206 * Search for PCI bus/dev_function which matches
2207 * PCI bus/dev_function (+/-1) for newly discovered 929,
2208 * 929X, 1030 or 1035.
2210 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2211 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2214 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
2216 struct pci_dev *peer=NULL;
2217 unsigned int slot = PCI_SLOT(pdev->devfn);
2218 unsigned int func = PCI_FUNC(pdev->devfn);
2219 MPT_ADAPTER *ioc_srch;
2221 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PCI device %s devfn=%x/%x,"
2222 " searching for devfn match on %x or %x\n",
2223 ioc->name, pci_name(pdev), pdev->bus->number,
2224 pdev->devfn, func-1, func+1));
2226 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
2228 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
2233 list_for_each_entry(ioc_srch, &ioc_list, list) {
2234 struct pci_dev *_pcidev = ioc_srch->pcidev;
2235 if (_pcidev == peer) {
2236 /* Paranoia checks */
2237 if (ioc->alt_ioc != NULL) {
2238 printk(MYIOC_s_WARN_FMT "Oops, already bound to %s!\n",
2239 ioc->name, ioc->alt_ioc->name);
2241 } else if (ioc_srch->alt_ioc != NULL) {
2242 printk(MYIOC_s_WARN_FMT "Oops, already bound to %s!\n",
2243 ioc_srch->name, ioc_srch->alt_ioc->name);
2246 dprintk(ioc, printk(MYIOC_s_INFO_FMT "FOUND! binding to %s\n",
2247 ioc->name, ioc_srch->name));
2248 ioc_srch->alt_ioc = ioc;
2249 ioc->alt_ioc = ioc_srch;
2255 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2257 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2258 * @ioc: Pointer to MPT adapter structure
2261 mpt_adapter_disable(MPT_ADAPTER *ioc)
2266 if (ioc->cached_fw != NULL) {
2267 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: Pushing FW onto "
2268 "adapter\n", __FUNCTION__, ioc->name));
2269 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)
2270 ioc->cached_fw, CAN_SLEEP)) < 0) {
2271 printk(MYIOC_s_WARN_FMT
2272 ": firmware downloadboot failure (%d)!\n",
2277 /* Disable adapter interrupts! */
2278 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2280 /* Clear any lingering interrupt */
2281 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2283 if (ioc->alloc != NULL) {
2285 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "free @ %p, sz=%d bytes\n",
2286 ioc->name, ioc->alloc, ioc->alloc_sz));
2287 pci_free_consistent(ioc->pcidev, sz,
2288 ioc->alloc, ioc->alloc_dma);
2289 ioc->reply_frames = NULL;
2290 ioc->req_frames = NULL;
2292 ioc->alloc_total -= sz;
2295 if (ioc->sense_buf_pool != NULL) {
2296 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2297 pci_free_consistent(ioc->pcidev, sz,
2298 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2299 ioc->sense_buf_pool = NULL;
2300 ioc->alloc_total -= sz;
2303 if (ioc->events != NULL){
2304 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2307 ioc->alloc_total -= sz;
2310 mpt_free_fw_memory(ioc);
2312 kfree(ioc->spi_data.nvram);
2313 mpt_inactive_raid_list_free(ioc);
2314 kfree(ioc->raid_data.pIocPg2);
2315 kfree(ioc->raid_data.pIocPg3);
2316 ioc->spi_data.nvram = NULL;
2317 ioc->raid_data.pIocPg3 = NULL;
2319 if (ioc->spi_data.pIocPg4 != NULL) {
2320 sz = ioc->spi_data.IocPg4Sz;
2321 pci_free_consistent(ioc->pcidev, sz,
2322 ioc->spi_data.pIocPg4,
2323 ioc->spi_data.IocPg4_dma);
2324 ioc->spi_data.pIocPg4 = NULL;
2325 ioc->alloc_total -= sz;
2328 if (ioc->ReqToChain != NULL) {
2329 kfree(ioc->ReqToChain);
2330 kfree(ioc->RequestNB);
2331 ioc->ReqToChain = NULL;
2334 kfree(ioc->ChainToChain);
2335 ioc->ChainToChain = NULL;
2337 if (ioc->HostPageBuffer != NULL) {
2338 if((ret = mpt_host_page_access_control(ioc,
2339 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2340 printk(MYIOC_s_ERR_FMT
2341 "host page buffers free failed (%d)!\n",
2344 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "HostPageBuffer free @ %p, sz=%d bytes\n",
2345 ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
2346 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2347 ioc->HostPageBuffer, ioc->HostPageBuffer_dma);
2348 ioc->HostPageBuffer = NULL;
2349 ioc->HostPageBuffer_sz = 0;
2350 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2354 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2356 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2357 * @ioc: Pointer to MPT adapter structure
2359 * This routine unregisters h/w resources and frees all alloc'd memory
2360 * associated with a MPT adapter structure.
2363 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2365 int sz_first, sz_last;
2370 sz_first = ioc->alloc_total;
2372 mpt_adapter_disable(ioc);
2374 if (ioc->pci_irq != -1) {
2375 free_irq(ioc->pci_irq, ioc);
2377 pci_disable_msi(ioc->pcidev);
2381 if (ioc->memmap != NULL) {
2382 iounmap(ioc->memmap);
2386 #if defined(CONFIG_MTRR) && 0
2387 if (ioc->mtrr_reg > 0) {
2388 mtrr_del(ioc->mtrr_reg, 0, 0);
2389 dprintk(ioc, printk(MYIOC_s_INFO_FMT "MTRR region de-registered\n", ioc->name));
2393 /* Zap the adapter lookup ptr! */
2394 list_del(&ioc->list);
2396 sz_last = ioc->alloc_total;
2397 dprintk(ioc, printk(MYIOC_s_INFO_FMT "free'd %d of %d bytes\n",
2398 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2401 ioc->alt_ioc->alt_ioc = NULL;
2406 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2408 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2409 * @ioc: Pointer to MPT adapter structure
2412 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2416 printk(KERN_INFO "%s: ", ioc->name);
2418 printk("%s: ", ioc->prod_name);
2419 printk("Capabilities={");
2421 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2422 printk("Initiator");
2426 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2427 printk("%sTarget", i ? "," : "");
2431 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2432 printk("%sLAN", i ? "," : "");
2438 * This would probably evoke more questions than it's worth
2440 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2441 printk("%sLogBusAddr", i ? "," : "");
2449 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2451 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2452 * @ioc: Pointer to MPT_ADAPTER structure
2453 * @force: Force hard KickStart of IOC
2454 * @sleepFlag: Specifies whether the process can sleep
2457 * 1 - DIAG reset and READY
2458 * 0 - READY initially OR soft reset and READY
2459 * -1 - Any failure on KickStart
2460 * -2 - Msg Unit Reset Failed
2461 * -3 - IO Unit Reset Failed
2462 * -4 - IOC owned by a PEER
2465 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2470 int hard_reset_done = 0;
2475 /* Get current [raw] IOC state */
2476 ioc_state = mpt_GetIocState(ioc, 0);
2477 dhsprintk(ioc, printk(MYIOC_s_INFO_FMT "MakeIocReady [raw] state=%08x\n", ioc->name, ioc_state));
2480 * Check to see if IOC got left/stuck in doorbell handshake
2481 * grip of death. If so, hard reset the IOC.
2483 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2485 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2489 /* Is it already READY? */
2490 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
2494 * Check to see if IOC is in FAULT state.
2496 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2498 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2500 printk(MYIOC_s_WARN_FMT " FAULT code = %04xh\n",
2501 ioc->name, ioc_state & MPI_DOORBELL_DATA_MASK);
2505 * Hmmm... Did it get left operational?
2507 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2508 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC operational unexpected\n",
2512 * If PCI Peer, exit.
2513 * Else, if no fault conditions are present, issue a MessageUnitReset
2514 * Else, fall through to KickStart case
2516 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2517 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2518 "whoinit 0x%x statefault %d force %d\n",
2519 ioc->name, whoinit, statefault, force));
2520 if (whoinit == MPI_WHOINIT_PCI_PEER)
2523 if ((statefault == 0 ) && (force == 0)) {
2524 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2531 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2532 if (hard_reset_done < 0)
2536 * Loop here waiting for IOC to come READY.
2539 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2541 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2542 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2544 * BIOS or previous driver load left IOC in OP state.
2545 * Reset messaging FIFOs.
2547 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2548 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2551 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2553 * Something is wrong. Try to get IOC back
2556 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2557 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2564 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2565 ioc->name, (int)((ii+5)/HZ));
2569 if (sleepFlag == CAN_SLEEP) {
2572 mdelay (1); /* 1 msec delay */
2577 if (statefault < 3) {
2578 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2580 statefault==1 ? "stuck handshake" : "IOC FAULT");
2583 return hard_reset_done;
2586 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2588 * mpt_GetIocState - Get the current state of a MPT adapter.
2589 * @ioc: Pointer to MPT_ADAPTER structure
2590 * @cooked: Request raw or cooked IOC state
2592 * Returns all IOC Doorbell register bits if cooked==0, else just the
2593 * Doorbell bits in MPI_IOC_STATE_MASK.
2596 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2601 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2602 sc = s & MPI_IOC_STATE_MASK;
2605 ioc->last_state = sc;
2607 return cooked ? sc : s;
2610 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2612 * GetIocFacts - Send IOCFacts request to MPT adapter.
2613 * @ioc: Pointer to MPT_ADAPTER structure
2614 * @sleepFlag: Specifies whether the process can sleep
2615 * @reason: If recovery, only update facts.
2617 * Returns 0 for success, non-zero for failure.
2620 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2622 IOCFacts_t get_facts;
2623 IOCFactsReply_t *facts;
2631 /* IOC *must* NOT be in RESET state! */
2632 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2633 printk(MYIOC_s_ERR_FMT "Can't get IOCFacts NOT READY! (%08x)\n",
2634 ioc->name, ioc->last_state );
2638 facts = &ioc->facts;
2640 /* Destination (reply area)... */
2641 reply_sz = sizeof(*facts);
2642 memset(facts, 0, reply_sz);
2644 /* Request area (get_facts on the stack right now!) */
2645 req_sz = sizeof(get_facts);
2646 memset(&get_facts, 0, req_sz);
2648 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2649 /* Assert: All other get_facts fields are zero! */
2651 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2652 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2653 ioc->name, req_sz, reply_sz));
2655 /* No non-zero fields in the get_facts request are greater than
2656 * 1 byte in size, so we can just fire it off as is.
2658 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2659 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2664 * Now byte swap (GRRR) the necessary fields before any further
2665 * inspection of reply contents.
2667 * But need to do some sanity checks on MsgLength (byte) field
2668 * to make sure we don't zero IOC's req_sz!
2670 /* Did we get a valid reply? */
2671 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2672 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2674 * If not been here, done that, save off first WhoInit value
2676 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2677 ioc->FirstWhoInit = facts->WhoInit;
2680 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2681 facts->MsgContext = le32_to_cpu(facts->MsgContext);
2682 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2683 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2684 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2685 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
2686 /* CHECKME! IOCStatus, IOCLogInfo */
2688 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2689 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2692 * FC f/w version changed between 1.1 and 1.2
2693 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2694 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2696 if (facts->MsgVersion < 0x0102) {
2698 * Handle old FC f/w style, convert to new...
2700 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2701 facts->FWVersion.Word =
2702 ((oldv<<12) & 0xFF000000) |
2703 ((oldv<<8) & 0x000FFF00);
2705 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2707 facts->ProductID = le16_to_cpu(facts->ProductID);
2708 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
2709 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
2710 ioc->ir_firmware = 1;
2711 facts->CurrentHostMfaHighAddr =
2712 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2713 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2714 facts->CurrentSenseBufferHighAddr =
2715 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2716 facts->CurReplyFrameSize =
2717 le16_to_cpu(facts->CurReplyFrameSize);
2718 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
2721 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2722 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2723 * to 14 in MPI-1.01.0x.
2725 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2726 facts->MsgVersion > 0x0100) {
2727 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2730 sz = facts->FWImageSize;
2735 facts->FWImageSize = sz;
2737 if (!facts->RequestFrameSize) {
2738 /* Something is wrong! */
2739 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2744 r = sz = facts->BlockSize;
2745 vv = ((63 / (sz * 4)) + 1) & 0x03;
2746 ioc->NB_for_64_byte_frame = vv;
2752 ioc->NBShiftFactor = shiftFactor;
2753 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2754 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2755 ioc->name, vv, shiftFactor, r));
2757 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2759 * Set values for this IOC's request & reply frame sizes,
2760 * and request & reply queue depths...
2762 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2763 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2764 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2765 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2767 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "reply_sz=%3d, reply_depth=%4d\n",
2768 ioc->name, ioc->reply_sz, ioc->reply_depth));
2769 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "req_sz =%3d, req_depth =%4d\n",
2770 ioc->name, ioc->req_sz, ioc->req_depth));
2772 /* Get port facts! */
2773 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2777 printk(MYIOC_s_ERR_FMT
2778 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2779 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2780 RequestFrameSize)/sizeof(u32)));
2787 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2789 * GetPortFacts - Send PortFacts request to MPT adapter.
2790 * @ioc: Pointer to MPT_ADAPTER structure
2791 * @portnum: Port number
2792 * @sleepFlag: Specifies whether the process can sleep
2794 * Returns 0 for success, non-zero for failure.
2797 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2799 PortFacts_t get_pfacts;
2800 PortFactsReply_t *pfacts;
2806 /* IOC *must* NOT be in RESET state! */
2807 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2808 printk(MYIOC_s_ERR_FMT "Can't get PortFacts NOT READY! (%08x)\n",
2809 ioc->name, ioc->last_state );
2813 pfacts = &ioc->pfacts[portnum];
2815 /* Destination (reply area)... */
2816 reply_sz = sizeof(*pfacts);
2817 memset(pfacts, 0, reply_sz);
2819 /* Request area (get_pfacts on the stack right now!) */
2820 req_sz = sizeof(get_pfacts);
2821 memset(&get_pfacts, 0, req_sz);
2823 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2824 get_pfacts.PortNumber = portnum;
2825 /* Assert: All other get_pfacts fields are zero! */
2827 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending get PortFacts(%d) request\n",
2828 ioc->name, portnum));
2830 /* No non-zero fields in the get_pfacts request are greater than
2831 * 1 byte in size, so we can just fire it off as is.
2833 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2834 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2838 /* Did we get a valid reply? */
2840 /* Now byte swap the necessary fields in the response. */
2841 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2842 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2843 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2844 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2845 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2846 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2847 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2848 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2849 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2851 max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
2853 ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
2854 ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
2857 * Place all the devices on channels
2861 if (mpt_channel_mapping) {
2862 ioc->devices_per_bus = 1;
2863 ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
2869 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2871 * SendIocInit - Send IOCInit request to MPT adapter.
2872 * @ioc: Pointer to MPT_ADAPTER structure
2873 * @sleepFlag: Specifies whether the process can sleep
2875 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2877 * Returns 0 for success, non-zero for failure.
2880 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2883 MPIDefaultReply_t init_reply;
2889 memset(&ioc_init, 0, sizeof(ioc_init));
2890 memset(&init_reply, 0, sizeof(init_reply));
2892 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2893 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2895 /* If we are in a recovery mode and we uploaded the FW image,
2896 * then this pointer is not NULL. Skip the upload a second time.
2897 * Set this flag if cached_fw set for either IOC.
2899 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
2903 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "upload_fw %d facts.Flags=%x\n",
2904 ioc->name, ioc->upload_fw, ioc->facts.Flags));
2906 ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
2907 ioc_init.MaxBuses = (U8)ioc->number_of_buses;
2908 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n",
2909 ioc->name, ioc->facts.MsgVersion));
2910 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
2911 // set MsgVersion and HeaderVersion host driver was built with
2912 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
2913 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
2915 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
2916 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
2917 } else if(mpt_host_page_alloc(ioc, &ioc_init))
2920 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
2922 if (sizeof(dma_addr_t) == sizeof(u64)) {
2923 /* Save the upper 32-bits of the request
2924 * (reply) and sense buffers.
2926 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
2927 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2929 /* Force 32-bit addressing */
2930 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
2931 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
2934 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
2935 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
2936 ioc->facts.MaxDevices = ioc_init.MaxDevices;
2937 ioc->facts.MaxBuses = ioc_init.MaxBuses;
2939 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOCInit (req @ %p)\n",
2940 ioc->name, &ioc_init));
2942 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
2943 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
2945 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
2949 /* No need to byte swap the multibyte fields in the reply
2950 * since we don't even look at its contents.
2953 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending PortEnable (req @ %p)\n",
2954 ioc->name, &ioc_init));
2956 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
2957 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
2961 /* YIKES! SUPER IMPORTANT!!!
2962 * Poll IocState until _OPERATIONAL while IOC is doing
2963 * LoopInit and TargetDiscovery!
2966 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
2967 state = mpt_GetIocState(ioc, 1);
2968 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
2969 if (sleepFlag == CAN_SLEEP) {
2976 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
2977 ioc->name, (int)((count+5)/HZ));
2981 state = mpt_GetIocState(ioc, 1);
2984 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wait IOC_OPERATIONAL state (cnt=%d)\n",
2987 ioc->aen_event_read_flag=0;
2991 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2993 * SendPortEnable - Send PortEnable request to MPT adapter port.
2994 * @ioc: Pointer to MPT_ADAPTER structure
2995 * @portnum: Port number to enable
2996 * @sleepFlag: Specifies whether the process can sleep
2998 * Send PortEnable to bring IOC to OPERATIONAL state.
3000 * Returns 0 for success, non-zero for failure.
3003 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3005 PortEnable_t port_enable;
3006 MPIDefaultReply_t reply_buf;
3011 /* Destination... */
3012 reply_sz = sizeof(MPIDefaultReply_t);
3013 memset(&reply_buf, 0, reply_sz);
3015 req_sz = sizeof(PortEnable_t);
3016 memset(&port_enable, 0, req_sz);
3018 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
3019 port_enable.PortNumber = portnum;
3020 /* port_enable.ChainOffset = 0; */
3021 /* port_enable.MsgFlags = 0; */
3022 /* port_enable.MsgContext = 0; */
3024 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Port(%d)Enable (req @ %p)\n",
3025 ioc->name, portnum, &port_enable));
3027 /* RAID FW may take a long time to enable
3029 if (ioc->ir_firmware || ioc->bus_type == SAS) {
3030 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3031 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3032 300 /*seconds*/, sleepFlag);
3034 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3035 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3036 30 /*seconds*/, sleepFlag);
3042 * mpt_alloc_fw_memory - allocate firmware memory
3043 * @ioc: Pointer to MPT_ADAPTER structure
3044 * @size: total FW bytes
3046 * If memory has already been allocated, the same (cached) value
3049 * Return 0 if successfull, or non-zero for failure
3052 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
3056 if (ioc->cached_fw) {
3057 rc = 0; /* use already allocated memory */
3060 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
3061 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
3062 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
3066 ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma);
3067 if (!ioc->cached_fw) {
3068 printk(MYIOC_s_ERR_FMT "Unable to allocate memory for the cached firmware image!\n",
3072 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Image @ %p[%p], sz=%d[%x] bytes\n",
3073 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, size, size));
3074 ioc->alloc_total += size;
3082 * mpt_free_fw_memory - free firmware memory
3083 * @ioc: Pointer to MPT_ADAPTER structure
3085 * If alt_img is NULL, delete from ioc structure.
3086 * Else, delete a secondary image in same format.
3089 mpt_free_fw_memory(MPT_ADAPTER *ioc)
3093 if (!ioc->cached_fw)
3096 sz = ioc->facts.FWImageSize;
3097 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3098 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3099 pci_free_consistent(ioc->pcidev, sz, ioc->cached_fw, ioc->cached_fw_dma);
3100 ioc->alloc_total -= sz;
3101 ioc->cached_fw = NULL;
3104 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3106 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3107 * @ioc: Pointer to MPT_ADAPTER structure
3108 * @sleepFlag: Specifies whether the process can sleep
3110 * Returns 0 for success, >0 for handshake failure
3111 * <0 for fw upload failure.
3113 * Remark: If bound IOC and a successful FWUpload was performed
3114 * on the bound IOC, the second image is discarded
3115 * and memory is free'd. Both channels must upload to prevent
3116 * IOC from running in degraded mode.
3119 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3121 u8 reply[sizeof(FWUploadReply_t)];
3122 FWUpload_t *prequest;
3123 FWUploadReply_t *preply;
3124 FWUploadTCSGE_t *ptcsge;
3127 int ii, sz, reply_sz;
3130 /* If the image size is 0, we are done.
3132 if ((sz = ioc->facts.FWImageSize) == 0)
3135 if (mpt_alloc_fw_memory(ioc, ioc->facts.FWImageSize) != 0)
3138 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3139 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3141 prequest = (sleepFlag == NO_SLEEP) ? kzalloc(ioc->req_sz, GFP_ATOMIC) :
3142 kzalloc(ioc->req_sz, GFP_KERNEL);
3144 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed "
3145 "while allocating memory \n", ioc->name));
3146 mpt_free_fw_memory(ioc);
3150 preply = (FWUploadReply_t *)&reply;
3152 reply_sz = sizeof(reply);
3153 memset(preply, 0, reply_sz);
3155 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
3156 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
3158 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
3159 ptcsge->DetailsLength = 12;
3160 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
3161 ptcsge->ImageSize = cpu_to_le32(sz);
3164 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
3166 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3167 mpt_add_sge((char *)ptcsge, flagsLength, ioc->cached_fw_dma);
3169 sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
3170 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": Sending FW Upload (req @ %p) sgeoffset=%d \n",
3171 ioc->name, prequest, sgeoffset));
3172 DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest);
3174 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
3175 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
3177 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Upload completed rc=%x \n", ioc->name, ii));
3179 cmdStatus = -EFAULT;
3181 /* Handshake transfer was complete and successful.
3182 * Check the Reply Frame.
3184 int status, transfer_sz;
3185 status = le16_to_cpu(preply->IOCStatus);
3186 if (status == MPI_IOCSTATUS_SUCCESS) {
3187 transfer_sz = le32_to_cpu(preply->ActualImageSize);
3188 if (transfer_sz == sz)
3192 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n",
3193 ioc->name, cmdStatus));
3198 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": fw upload failed, freeing image \n",
3200 mpt_free_fw_memory(ioc);
3207 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3209 * mpt_downloadboot - DownloadBoot code
3210 * @ioc: Pointer to MPT_ADAPTER structure
3211 * @pFwHeader: Pointer to firmware header info
3212 * @sleepFlag: Specifies whether the process can sleep
3214 * FwDownloadBoot requires Programmed IO access.
3216 * Returns 0 for success
3217 * -1 FW Image size is 0
3218 * -2 No valid cached_fw Pointer
3219 * <0 for fw upload failure.
3222 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3224 MpiExtImageHeader_t *pExtImage;
3234 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3235 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
3237 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3238 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3239 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3240 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3241 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3242 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3244 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
3247 if (sleepFlag == CAN_SLEEP) {
3253 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3254 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3256 for (count = 0; count < 30; count ++) {
3257 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3258 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3259 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESET_ADAPTER cleared, count=%d\n",
3264 if (sleepFlag == CAN_SLEEP) {
3271 if ( count == 30 ) {
3272 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot failed! "
3273 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3274 ioc->name, diag0val));
3278 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3279 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3280 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3281 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3282 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3283 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3285 /* Set the DiagRwEn and Disable ARM bits */
3286 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3288 fwSize = (pFwHeader->ImageSize + 3)/4;
3289 ptrFw = (u32 *) pFwHeader;
3291 /* Write the LoadStartAddress to the DiagRw Address Register
3292 * using Programmed IO
3294 if (ioc->errata_flag_1064)
3295 pci_enable_io_access(ioc->pcidev);
3297 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3298 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "LoadStart addr written 0x%x \n",
3299 ioc->name, pFwHeader->LoadStartAddress));
3301 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write FW Image: 0x%x bytes @ %p\n",
3302 ioc->name, fwSize*4, ptrFw));
3304 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3307 nextImage = pFwHeader->NextImageHeaderOffset;
3309 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3311 load_addr = pExtImage->LoadStartAddress;
3313 fwSize = (pExtImage->ImageSize + 3) >> 2;
3314 ptrFw = (u32 *)pExtImage;
3316 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3317 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3318 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3321 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3323 nextImage = pExtImage->NextImageHeaderOffset;
3326 /* Write the IopResetVectorRegAddr */
3327 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
3328 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3330 /* Write the IopResetVectorValue */
3331 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3332 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3334 /* Clear the internal flash bad bit - autoincrementing register,
3335 * so must do two writes.
3337 if (ioc->bus_type == SPI) {
3339 * 1030 and 1035 H/W errata, workaround to access
3340 * the ClearFlashBadSignatureBit
3342 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3343 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3344 diagRwData |= 0x40000000;
3345 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3346 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3348 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3349 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3350 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3351 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3354 if (sleepFlag == CAN_SLEEP) {
3361 if (ioc->errata_flag_1064)
3362 pci_disable_io_access(ioc->pcidev);
3364 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3365 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot diag0val=%x, "
3366 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3367 ioc->name, diag0val));
3368 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3369 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot now diag0val=%x\n",
3370 ioc->name, diag0val));
3371 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3373 /* Write 0xFF to reset the sequencer */
3374 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3376 if (ioc->bus_type == SAS) {
3377 ioc_state = mpt_GetIocState(ioc, 0);
3378 if ( (GetIocFacts(ioc, sleepFlag,
3379 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3380 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "GetIocFacts failed: IocState=%x\n",
3381 ioc->name, ioc_state));
3386 for (count=0; count<HZ*20; count++) {
3387 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3388 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3389 "downloadboot successful! (count=%d) IocState=%x\n",
3390 ioc->name, count, ioc_state));
3391 if (ioc->bus_type == SAS) {
3394 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3395 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3396 "downloadboot: SendIocInit failed\n",
3400 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3401 "downloadboot: SendIocInit successful\n",
3405 if (sleepFlag == CAN_SLEEP) {
3411 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3412 "downloadboot failed! IocState=%x\n",ioc->name, ioc_state));
3416 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3418 * KickStart - Perform hard reset of MPT adapter.
3419 * @ioc: Pointer to MPT_ADAPTER structure
3420 * @force: Force hard reset
3421 * @sleepFlag: Specifies whether the process can sleep
3423 * This routine places MPT adapter in diagnostic mode via the
3424 * WriteSequence register, and then performs a hard reset of adapter
3425 * via the Diagnostic register.
3427 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3428 * or NO_SLEEP (interrupt thread, use mdelay)
3429 * force - 1 if doorbell active, board fault state
3430 * board operational, IOC_RECOVERY or
3431 * IOC_BRINGUP and there is an alt_ioc.
3435 * 1 - hard reset, READY
3436 * 0 - no reset due to History bit, READY
3437 * -1 - no reset due to History bit but not READY
3438 * OR reset but failed to come READY
3439 * -2 - no reset, could not enter DIAG mode
3440 * -3 - reset but bad FW bit
3443 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3445 int hard_reset_done = 0;
3449 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStarting!\n", ioc->name));
3450 if (ioc->bus_type == SPI) {
3451 /* Always issue a Msg Unit Reset first. This will clear some
3452 * SCSI bus hang conditions.
3454 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3456 if (sleepFlag == CAN_SLEEP) {
3463 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3464 if (hard_reset_done < 0)
3465 return hard_reset_done;
3467 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n",
3470 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3471 for (cnt=0; cnt<cntdn; cnt++) {
3472 ioc_state = mpt_GetIocState(ioc, 1);
3473 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3474 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStart successful! (cnt=%d)\n",
3476 return hard_reset_done;
3478 if (sleepFlag == CAN_SLEEP) {
3485 dinitprintk(ioc, printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3486 ioc->name, mpt_GetIocState(ioc, 0)));
3490 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3492 * mpt_diag_reset - Perform hard reset of the adapter.
3493 * @ioc: Pointer to MPT_ADAPTER structure
3494 * @ignore: Set if to honor and clear to ignore
3495 * the reset history bit
3496 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3497 * else set to NO_SLEEP (use mdelay instead)
3499 * This routine places the adapter in diagnostic mode via the
3500 * WriteSequence register and then performs a hard reset of adapter
3501 * via the Diagnostic register. Adapter should be in ready state
3502 * upon successful completion.
3504 * Returns: 1 hard reset successful
3505 * 0 no reset performed because reset history bit set
3506 * -2 enabling diagnostic mode failed
3507 * -3 diagnostic reset failed
3510 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3514 int hard_reset_done = 0;
3517 MpiFwHeader_t *cached_fw; /* Pointer to FW */
3519 /* Clear any existing interrupts */
3520 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3522 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3523 drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3524 "address=%p\n", ioc->name, __FUNCTION__,
3525 &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3526 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3527 if (sleepFlag == CAN_SLEEP)
3532 for (count = 0; count < 60; count ++) {
3533 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3534 doorbell &= MPI_IOC_STATE_MASK;
3536 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3537 "looking for READY STATE: doorbell=%x"
3539 ioc->name, doorbell, count));
3540 if (doorbell == MPI_IOC_STATE_READY) {
3545 if (sleepFlag == CAN_SLEEP)
3553 /* Use "Diagnostic reset" method! (only thing available!) */
3554 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3556 if (ioc->debug_level & MPT_DEBUG) {
3558 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3559 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3560 ioc->name, diag0val, diag1val));
3563 /* Do the reset if we are told to ignore the reset history
3564 * or if the reset history is 0
3566 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3567 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3568 /* Write magic sequence to WriteSequence register
3569 * Loop until in diagnostic mode
3571 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3572 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3573 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3574 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3575 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3576 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3579 if (sleepFlag == CAN_SLEEP) {
3587 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3588 ioc->name, diag0val);
3593 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3595 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3596 ioc->name, diag0val));
3599 if (ioc->debug_level & MPT_DEBUG) {
3601 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3602 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3603 ioc->name, diag0val, diag1val));
3606 * Disable the ARM (Bug fix)
3609 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3613 * Now hit the reset bit in the Diagnostic register
3614 * (THE BIG HAMMER!) (Clears DRWE bit).
3616 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3617 hard_reset_done = 1;
3618 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset performed\n",
3622 * Call each currently registered protocol IOC reset handler
3623 * with pre-reset indication.
3624 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3625 * MptResetHandlers[] registered yet.
3631 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
3632 if (MptResetHandlers[cb_idx]) {
3633 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3634 "Calling IOC pre_reset handler #%d\n",
3635 ioc->name, cb_idx));
3636 r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET);
3638 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3639 "Calling alt-%s pre_reset handler #%d\n",
3640 ioc->name, ioc->alt_ioc->name, cb_idx));
3641 r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_PRE_RESET);
3645 /* FIXME? Examine results here? */
3649 cached_fw = (MpiFwHeader_t *)ioc->cached_fw;
3650 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
3651 cached_fw = (MpiFwHeader_t *)ioc->alt_ioc->cached_fw;
3655 /* If the DownloadBoot operation fails, the
3656 * IOC will be left unusable. This is a fatal error
3657 * case. _diag_reset will return < 0
3659 for (count = 0; count < 30; count ++) {
3660 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3661 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3665 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n",
3666 ioc->name, diag0val, count));
3668 if (sleepFlag == CAN_SLEEP) {
3674 if ((count = mpt_downloadboot(ioc, cached_fw, sleepFlag)) < 0) {
3675 printk(MYIOC_s_WARN_FMT
3676 "firmware downloadboot failure (%d)!\n", ioc->name, count);
3680 /* Wait for FW to reload and for board
3681 * to go to the READY state.
3682 * Maximum wait is 60 seconds.
3683 * If fail, no error will check again
3684 * with calling program.
3686 for (count = 0; count < 60; count ++) {
3687 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3688 doorbell &= MPI_IOC_STATE_MASK;
3690 if (doorbell == MPI_IOC_STATE_READY) {
3695 if (sleepFlag == CAN_SLEEP) {
3704 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3705 if (ioc->debug_level & MPT_DEBUG) {
3707 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3708 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3709 ioc->name, diag0val, diag1val));
3712 /* Clear RESET_HISTORY bit! Place board in the
3713 * diagnostic mode to update the diag register.
3715 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3717 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3718 /* Write magic sequence to WriteSequence register
3719 * Loop until in diagnostic mode
3721 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3722 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3723 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3724 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3725 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3726 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3729 if (sleepFlag == CAN_SLEEP) {
3737 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3738 ioc->name, diag0val);
3741 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3743 diag0val &= ~MPI_DIAG_RESET_HISTORY;
3744 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3745 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3746 if (diag0val & MPI_DIAG_RESET_HISTORY) {
3747 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3751 /* Disable Diagnostic Mode
3753 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3755 /* Check FW reload status flags.
3757 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3758 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3759 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3760 ioc->name, diag0val);
3764 if (ioc->debug_level & MPT_DEBUG) {
3766 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3767 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3768 ioc->name, diag0val, diag1val));
3772 * Reset flag that says we've enabled event notification
3774 ioc->facts.EventState = 0;
3777 ioc->alt_ioc->facts.EventState = 0;
3779 return hard_reset_done;
3782 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3784 * SendIocReset - Send IOCReset request to MPT adapter.
3785 * @ioc: Pointer to MPT_ADAPTER structure
3786 * @reset_type: reset type, expected values are
3787 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3788 * @sleepFlag: Specifies whether the process can sleep
3790 * Send IOCReset request to the MPT adapter.
3792 * Returns 0 for success, non-zero for failure.
3795 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3801 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOC reset(0x%02x)!\n",
3802 ioc->name, reset_type));
3803 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3804 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3807 /* FW ACK'd request, wait for READY state
3810 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
3812 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3816 if (sleepFlag != CAN_SLEEP)
3819 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
3820 ioc->name, (int)((count+5)/HZ));
3824 if (sleepFlag == CAN_SLEEP) {
3827 mdelay (1); /* 1 msec delay */
3832 * Cleanup all event stuff for this IOC; re-issue EventNotification
3833 * request if needed.
3835 if (ioc->facts.Function)
3836 ioc->facts.EventState = 0;
3841 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3843 * initChainBuffers - Allocate memory for and initialize chain buffers
3844 * @ioc: Pointer to MPT_ADAPTER structure
3846 * Allocates memory for and initializes chain buffers,
3847 * chain buffer control arrays and spinlock.
3850 initChainBuffers(MPT_ADAPTER *ioc)
3853 int sz, ii, num_chain;
3854 int scale, num_sge, numSGE;
3856 /* ReqToChain size must equal the req_depth
3859 if (ioc->ReqToChain == NULL) {
3860 sz = ioc->req_depth * sizeof(int);
3861 mem = kmalloc(sz, GFP_ATOMIC);
3865 ioc->ReqToChain = (int *) mem;
3866 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReqToChain alloc @ %p, sz=%d bytes\n",
3867 ioc->name, mem, sz));
3868 mem = kmalloc(sz, GFP_ATOMIC);
3872 ioc->RequestNB = (int *) mem;
3873 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestNB alloc @ %p, sz=%d bytes\n",
3874 ioc->name, mem, sz));
3876 for (ii = 0; ii < ioc->req_depth; ii++) {
3877 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
3880 /* ChainToChain size must equal the total number
3881 * of chain buffers to be allocated.
3884 * Calculate the number of chain buffers needed(plus 1) per I/O
3885 * then multiply the maximum number of simultaneous cmds
3887 * num_sge = num sge in request frame + last chain buffer
3888 * scale = num sge per chain buffer if no chain element
3890 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3891 if (sizeof(dma_addr_t) == sizeof(u64))
3892 num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3894 num_sge = 1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3896 if (sizeof(dma_addr_t) == sizeof(u64)) {
3897 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3898 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3900 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3901 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3903 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n",
3904 ioc->name, num_sge, numSGE));
3906 if ( numSGE > MPT_SCSI_SG_DEPTH )
3907 numSGE = MPT_SCSI_SG_DEPTH;
3910 while (numSGE - num_sge > 0) {
3912 num_sge += (scale - 1);
3916 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Now numSGE=%d num_sge=%d num_chain=%d\n",
3917 ioc->name, numSGE, num_sge, num_chain));
3919 if (ioc->bus_type == SPI)
3920 num_chain *= MPT_SCSI_CAN_QUEUE;
3922 num_chain *= MPT_FC_CAN_QUEUE;
3924 ioc->num_chain = num_chain;
3926 sz = num_chain * sizeof(int);
3927 if (ioc->ChainToChain == NULL) {
3928 mem = kmalloc(sz, GFP_ATOMIC);
3932 ioc->ChainToChain = (int *) mem;
3933 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainToChain alloc @ %p, sz=%d bytes\n",
3934 ioc->name, mem, sz));
3936 mem = (u8 *) ioc->ChainToChain;
3938 memset(mem, 0xFF, sz);
3942 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3944 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
3945 * @ioc: Pointer to MPT_ADAPTER structure
3947 * This routine allocates memory for the MPT reply and request frame
3948 * pools (if necessary), and primes the IOC reply FIFO with
3951 * Returns 0 for success, non-zero for failure.
3954 PrimeIocFifos(MPT_ADAPTER *ioc)
3957 unsigned long flags;
3958 dma_addr_t alloc_dma;
3960 int i, reply_sz, sz, total_size, num_chain;
3962 /* Prime reply FIFO... */
3964 if (ioc->reply_frames == NULL) {
3965 if ( (num_chain = initChainBuffers(ioc)) < 0)
3968 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
3969 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
3970 ioc->name, ioc->reply_sz, ioc->reply_depth));
3971 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d[%x] bytes\n",
3972 ioc->name, reply_sz, reply_sz));
3974 sz = (ioc->req_sz * ioc->req_depth);
3975 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d bytes, RequestDepth=%d\n",
3976 ioc->name, ioc->req_sz, ioc->req_depth));
3977 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d[%x] bytes\n",
3978 ioc->name, sz, sz));
3981 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
3982 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d bytes, ChainDepth=%d\n",
3983 ioc->name, ioc->req_sz, num_chain));
3984 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
3985 ioc->name, sz, sz, num_chain));
3988 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
3990 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
3995 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Total alloc @ %p[%p], sz=%d[%x] bytes\n",
3996 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
3998 memset(mem, 0, total_size);
3999 ioc->alloc_total += total_size;
4001 ioc->alloc_dma = alloc_dma;
4002 ioc->alloc_sz = total_size;
4003 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
4004 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4006 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4007 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4009 alloc_dma += reply_sz;
4012 /* Request FIFO - WE manage this! */
4014 ioc->req_frames = (MPT_FRAME_HDR *) mem;
4015 ioc->req_frames_dma = alloc_dma;
4017 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffers @ %p[%p]\n",
4018 ioc->name, mem, (void *)(ulong)alloc_dma));
4020 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4022 #if defined(CONFIG_MTRR) && 0
4024 * Enable Write Combining MTRR for IOC's memory region.
4025 * (at least as much as we can; "size and base must be
4026 * multiples of 4 kiB"
4028 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
4030 MTRR_TYPE_WRCOMB, 1);
4031 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MTRR region registered (base:size=%08x:%x)\n",
4032 ioc->name, ioc->req_frames_dma, sz));
4035 for (i = 0; i < ioc->req_depth; i++) {
4036 alloc_dma += ioc->req_sz;
4040 ioc->ChainBuffer = mem;
4041 ioc->ChainBufferDMA = alloc_dma;
4043 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffers @ %p(%p)\n",
4044 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
4046 /* Initialize the free chain Q.
4049 INIT_LIST_HEAD(&ioc->FreeChainQ);
4051 /* Post the chain buffers to the FreeChainQ.
4053 mem = (u8 *)ioc->ChainBuffer;
4054 for (i=0; i < num_chain; i++) {
4055 mf = (MPT_FRAME_HDR *) mem;
4056 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
4060 /* Initialize Request frames linked list
4062 alloc_dma = ioc->req_frames_dma;
4063 mem = (u8 *) ioc->req_frames;
4065 spin_lock_irqsave(&ioc->FreeQlock, flags);
4066 INIT_LIST_HEAD(&ioc->FreeQ);
4067 for (i = 0; i < ioc->req_depth; i++) {
4068 mf = (MPT_FRAME_HDR *) mem;
4070 /* Queue REQUESTs *internally*! */
4071 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
4075 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4077 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4078 ioc->sense_buf_pool =
4079 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
4080 if (ioc->sense_buf_pool == NULL) {
4081 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
4086 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
4087 ioc->alloc_total += sz;
4088 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SenseBuffers @ %p[%p]\n",
4089 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
4093 /* Post Reply frames to FIFO
4095 alloc_dma = ioc->alloc_dma;
4096 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4097 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4099 for (i = 0; i < ioc->reply_depth; i++) {
4100 /* Write each address to the IOC! */
4101 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
4102 alloc_dma += ioc->reply_sz;
4108 if (ioc->alloc != NULL) {
4110 pci_free_consistent(ioc->pcidev,
4112 ioc->alloc, ioc->alloc_dma);
4113 ioc->reply_frames = NULL;
4114 ioc->req_frames = NULL;
4115 ioc->alloc_total -= sz;
4117 if (ioc->sense_buf_pool != NULL) {
4118 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4119 pci_free_consistent(ioc->pcidev,
4121 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
4122 ioc->sense_buf_pool = NULL;
4127 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4129 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4130 * from IOC via doorbell handshake method.
4131 * @ioc: Pointer to MPT_ADAPTER structure
4132 * @reqBytes: Size of the request in bytes
4133 * @req: Pointer to MPT request frame
4134 * @replyBytes: Expected size of the reply in bytes
4135 * @u16reply: Pointer to area where reply should be written
4136 * @maxwait: Max wait time for a reply (in seconds)
4137 * @sleepFlag: Specifies whether the process can sleep
4139 * NOTES: It is the callers responsibility to byte-swap fields in the
4140 * request which are greater than 1 byte in size. It is also the
4141 * callers responsibility to byte-swap response fields which are
4142 * greater than 1 byte in size.
4144 * Returns 0 for success, non-zero for failure.
4147 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
4148 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
4150 MPIDefaultReply_t *mptReply;
4155 * Get ready to cache a handshake reply
4157 ioc->hs_reply_idx = 0;
4158 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4159 mptReply->MsgLength = 0;
4162 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4163 * then tell IOC that we want to handshake a request of N words.
4164 * (WRITE u32val to Doorbell reg).
4166 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4167 CHIPREG_WRITE32(&ioc->chip->Doorbell,
4168 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
4169 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
4172 * Wait for IOC's doorbell handshake int
4174 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4177 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4178 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4180 /* Read doorbell and check for active bit */
4181 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
4185 * Clear doorbell int (WRITE 0 to IntStatus reg),
4186 * then wait for IOC to ACKnowledge that it's ready for
4187 * our handshake request.
4189 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4190 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4195 u8 *req_as_bytes = (u8 *) req;
4198 * Stuff request words via doorbell handshake,
4199 * with ACK from IOC for each.
4201 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
4202 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
4203 (req_as_bytes[(ii*4) + 1] << 8) |
4204 (req_as_bytes[(ii*4) + 2] << 16) |
4205 (req_as_bytes[(ii*4) + 3] << 24));
4207 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
4208 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4212 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req));
4213 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req);
4215 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n",
4216 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
4219 * Wait for completion of doorbell handshake reply from the IOC
4221 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
4224 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake reply count=%d%s\n",
4225 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
4228 * Copy out the cached reply...
4230 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
4231 u16reply[ii] = ioc->hs_reply[ii];
4239 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4241 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4242 * @ioc: Pointer to MPT_ADAPTER structure
4243 * @howlong: How long to wait (in seconds)
4244 * @sleepFlag: Specifies whether the process can sleep
4246 * This routine waits (up to ~2 seconds max) for IOC doorbell
4247 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4248 * bit in its IntStatus register being clear.
4250 * Returns a negative value on failure, else wait loop count.
4253 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4259 cntdn = 1000 * howlong;
4261 if (sleepFlag == CAN_SLEEP) {
4264 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4265 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4272 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4273 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4280 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell ACK (count=%d)\n",
4285 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4286 ioc->name, count, intstat);
4290 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4292 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4293 * @ioc: Pointer to MPT_ADAPTER structure
4294 * @howlong: How long to wait (in seconds)
4295 * @sleepFlag: Specifies whether the process can sleep
4297 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4298 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4300 * Returns a negative value on failure, else wait loop count.
4303 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4309 cntdn = 1000 * howlong;
4310 if (sleepFlag == CAN_SLEEP) {
4312 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4313 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4320 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4321 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4329 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4330 ioc->name, count, howlong));
4334 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4335 ioc->name, count, intstat);
4339 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4341 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4342 * @ioc: Pointer to MPT_ADAPTER structure
4343 * @howlong: How long to wait (in seconds)
4344 * @sleepFlag: Specifies whether the process can sleep
4346 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4347 * Reply is cached to IOC private area large enough to hold a maximum
4348 * of 128 bytes of reply data.
4350 * Returns a negative value on failure, else size of reply in WORDS.
4353 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4358 u16 *hs_reply = ioc->hs_reply;
4359 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4362 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4365 * Get first two u16's so we can look at IOC's intended reply MsgLength
4368 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4371 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4372 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4373 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4376 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4377 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4381 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4382 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4383 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4386 * If no error (and IOC said MsgLength is > 0), piece together
4387 * reply 16 bits at a time.
4389 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4390 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4392 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4393 /* don't overflow our IOC hs_reply[] buffer! */
4394 if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
4395 hs_reply[u16cnt] = hword;
4396 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4399 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4401 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4404 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4409 else if (u16cnt != (2 * mptReply->MsgLength)) {
4412 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4417 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name));
4418 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply);
4420 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4421 ioc->name, t, u16cnt/2));
4425 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4427 * GetLanConfigPages - Fetch LANConfig pages.
4428 * @ioc: Pointer to MPT_ADAPTER structure
4430 * Return: 0 for success
4431 * -ENOMEM if no memory available
4432 * -EPERM if not allowed due to ISR context
4433 * -EAGAIN if no msg frames currently available
4434 * -EFAULT for non-successful reply or no reply (timeout)
4437 GetLanConfigPages(MPT_ADAPTER *ioc)
4439 ConfigPageHeader_t hdr;
4441 LANPage0_t *ppage0_alloc;
4442 dma_addr_t page0_dma;
4443 LANPage1_t *ppage1_alloc;
4444 dma_addr_t page1_dma;
4449 /* Get LAN Page 0 header */
4450 hdr.PageVersion = 0;
4453 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4454 cfg.cfghdr.hdr = &hdr;
4456 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4461 if ((rc = mpt_config(ioc, &cfg)) != 0)
4464 if (hdr.PageLength > 0) {
4465 data_sz = hdr.PageLength * 4;
4466 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4469 memset((u8 *)ppage0_alloc, 0, data_sz);
4470 cfg.physAddr = page0_dma;
4471 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4473 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4475 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4476 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4480 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4483 * Normalize endianness of structure data,
4484 * by byte-swapping all > 1 byte fields!
4493 /* Get LAN Page 1 header */
4494 hdr.PageVersion = 0;
4497 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4498 cfg.cfghdr.hdr = &hdr;
4500 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4504 if ((rc = mpt_config(ioc, &cfg)) != 0)
4507 if (hdr.PageLength == 0)
4510 data_sz = hdr.PageLength * 4;
4512 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4514 memset((u8 *)ppage1_alloc, 0, data_sz);
4515 cfg.physAddr = page1_dma;
4516 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4518 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4520 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4521 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4524 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4527 * Normalize endianness of structure data,
4528 * by byte-swapping all > 1 byte fields!
4536 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4538 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
4539 * @ioc: Pointer to MPT_ADAPTER structure
4540 * @persist_opcode: see below
4542 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4543 * devices not currently present.
4544 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4546 * NOTE: Don't use not this function during interrupt time.
4548 * Returns 0 for success, non-zero error
4551 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4553 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4555 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
4556 SasIoUnitControlReply_t *sasIoUnitCntrReply;
4557 MPT_FRAME_HDR *mf = NULL;
4558 MPIHeader_t *mpi_hdr;
4561 /* insure garbage is not sent to fw */
4562 switch(persist_opcode) {
4564 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
4565 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
4573 printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode);
4575 /* Get a MF for this command.
4577 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4578 printk("%s: no msg frames!\n",__FUNCTION__);
4582 mpi_hdr = (MPIHeader_t *) mf;
4583 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
4584 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
4585 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
4586 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
4587 sasIoUnitCntrReq->Operation = persist_opcode;
4589 init_timer(&ioc->persist_timer);
4590 ioc->persist_timer.data = (unsigned long) ioc;
4591 ioc->persist_timer.function = mpt_timer_expired;
4592 ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
4593 ioc->persist_wait_done=0;
4594 add_timer(&ioc->persist_timer);
4595 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4596 wait_event(mpt_waitq, ioc->persist_wait_done);
4598 sasIoUnitCntrReply =
4599 (SasIoUnitControlReply_t *)ioc->persist_reply_frame;
4600 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
4601 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4603 sasIoUnitCntrReply->IOCStatus,
4604 sasIoUnitCntrReply->IOCLogInfo);
4608 printk("%s: success\n",__FUNCTION__);
4612 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4615 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
4616 MpiEventDataRaid_t * pRaidEventData)
4625 volume = pRaidEventData->VolumeID;
4626 reason = pRaidEventData->ReasonCode;
4627 disk = pRaidEventData->PhysDiskNum;
4628 status = le32_to_cpu(pRaidEventData->SettingsStatus);
4629 flags = (status >> 0) & 0xff;
4630 state = (status >> 8) & 0xff;
4632 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
4636 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
4637 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
4638 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
4639 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
4640 ioc->name, disk, volume);
4642 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
4647 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4648 printk(MYIOC_s_INFO_FMT " volume has been created\n",
4652 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4654 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
4658 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
4659 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
4663 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4664 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
4666 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
4668 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
4670 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
4673 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
4675 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
4676 ? ", quiesced" : "",
4677 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
4678 ? ", resync in progress" : "" );
4681 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
4682 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
4686 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4687 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
4691 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4692 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
4696 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
4697 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
4701 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4702 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
4704 state == MPI_PHYSDISK0_STATUS_ONLINE
4706 : state == MPI_PHYSDISK0_STATUS_MISSING
4708 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
4710 : state == MPI_PHYSDISK0_STATUS_FAILED
4712 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
4714 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
4715 ? "offline requested"
4716 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
4717 ? "failed requested"
4718 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
4721 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
4722 ? ", out of sync" : "",
4723 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
4724 ? ", quiesced" : "" );
4727 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
4728 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
4732 case MPI_EVENT_RAID_RC_SMART_DATA:
4733 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
4734 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
4737 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
4738 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
4744 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4746 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4747 * @ioc: Pointer to MPT_ADAPTER structure
4749 * Returns: 0 for success
4750 * -ENOMEM if no memory available
4751 * -EPERM if not allowed due to ISR context
4752 * -EAGAIN if no msg frames currently available
4753 * -EFAULT for non-successful reply or no reply (timeout)
4756 GetIoUnitPage2(MPT_ADAPTER *ioc)
4758 ConfigPageHeader_t hdr;
4760 IOUnitPage2_t *ppage_alloc;
4761 dma_addr_t page_dma;
4765 /* Get the page header */
4766 hdr.PageVersion = 0;
4769 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4770 cfg.cfghdr.hdr = &hdr;
4772 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4777 if ((rc = mpt_config(ioc, &cfg)) != 0)
4780 if (hdr.PageLength == 0)
4783 /* Read the config page */
4784 data_sz = hdr.PageLength * 4;
4786 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4788 memset((u8 *)ppage_alloc, 0, data_sz);
4789 cfg.physAddr = page_dma;
4790 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4792 /* If Good, save data */
4793 if ((rc = mpt_config(ioc, &cfg)) == 0)
4794 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4796 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4802 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4804 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4805 * @ioc: Pointer to a Adapter Strucutre
4806 * @portnum: IOC port number
4808 * Return: -EFAULT if read of config page header fails
4810 * If read of SCSI Port Page 0 fails,
4811 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4812 * Adapter settings: async, narrow
4814 * If read of SCSI Port Page 2 fails,
4815 * Adapter settings valid
4816 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4821 * CHECK - what type of locking mechanisms should be used????
4824 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4829 ConfigPageHeader_t header;
4835 if (!ioc->spi_data.nvram) {
4838 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4839 mem = kmalloc(sz, GFP_ATOMIC);
4843 ioc->spi_data.nvram = (int *) mem;
4845 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4846 ioc->name, ioc->spi_data.nvram, sz));
4849 /* Invalidate NVRAM information
4851 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4852 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4855 /* Read SPP0 header, allocate memory, then read page.
4857 header.PageVersion = 0;
4858 header.PageLength = 0;
4859 header.PageNumber = 0;
4860 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4861 cfg.cfghdr.hdr = &header;
4863 cfg.pageAddr = portnum;
4864 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4866 cfg.timeout = 0; /* use default */
4867 if (mpt_config(ioc, &cfg) != 0)
4870 if (header.PageLength > 0) {
4871 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4873 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4874 cfg.physAddr = buf_dma;
4875 if (mpt_config(ioc, &cfg) != 0) {
4876 ioc->spi_data.maxBusWidth = MPT_NARROW;
4877 ioc->spi_data.maxSyncOffset = 0;
4878 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4879 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4881 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4882 "Unable to read PortPage0 minSyncFactor=%x\n",
4883 ioc->name, ioc->spi_data.minSyncFactor));
4885 /* Save the Port Page 0 data
4887 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
4888 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4889 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4891 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
4892 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4893 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4894 "noQas due to Capabilities=%x\n",
4895 ioc->name, pPP0->Capabilities));
4897 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4898 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4900 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4901 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4902 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4903 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4904 "PortPage0 minSyncFactor=%x\n",
4905 ioc->name, ioc->spi_data.minSyncFactor));
4907 ioc->spi_data.maxSyncOffset = 0;
4908 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4911 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4913 /* Update the minSyncFactor based on bus type.
4915 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4916 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
4918 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
4919 ioc->spi_data.minSyncFactor = MPT_ULTRA;
4920 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4921 "HVD or SE detected, minSyncFactor=%x\n",
4922 ioc->name, ioc->spi_data.minSyncFactor));
4927 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4932 /* SCSI Port Page 2 - Read the header then the page.
4934 header.PageVersion = 0;
4935 header.PageLength = 0;
4936 header.PageNumber = 2;
4937 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4938 cfg.cfghdr.hdr = &header;
4940 cfg.pageAddr = portnum;
4941 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4943 if (mpt_config(ioc, &cfg) != 0)
4946 if (header.PageLength > 0) {
4947 /* Allocate memory and read SCSI Port Page 2
4949 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4951 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
4952 cfg.physAddr = buf_dma;
4953 if (mpt_config(ioc, &cfg) != 0) {
4954 /* Nvram data is left with INVALID mark
4957 } else if (ioc->pcidev->vendor == PCI_VENDOR_ID_ATTO) {
4959 /* This is an ATTO adapter, read Page2 accordingly
4961 ATTO_SCSIPortPage2_t *pPP2 = (ATTO_SCSIPortPage2_t *) pbuf;
4962 ATTODeviceInfo_t *pdevice = NULL;
4965 /* Save the Port Page 2 data
4966 * (reformat into a 32bit quantity)
4968 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4969 pdevice = &pPP2->DeviceSettings[ii];
4970 ATTOFlags = le16_to_cpu(pdevice->ATTOFlags);
4973 /* Translate ATTO device flags to LSI format
4975 if (ATTOFlags & ATTOFLAG_DISC)
4976 data |= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE);
4977 if (ATTOFlags & ATTOFLAG_ID_ENB)
4978 data |= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE);
4979 if (ATTOFlags & ATTOFLAG_LUN_ENB)
4980 data |= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE);
4981 if (ATTOFlags & ATTOFLAG_TAGGED)
4982 data |= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE);
4983 if (!(ATTOFlags & ATTOFLAG_WIDE_ENB))
4984 data |= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE);
4986 data = (data << 16) | (pdevice->Period << 8) | 10;
4987 ioc->spi_data.nvram[ii] = data;
4990 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
4991 MpiDeviceInfo_t *pdevice = NULL;
4994 * Save "Set to Avoid SCSI Bus Resets" flag
4996 ioc->spi_data.bus_reset =
4997 (le32_to_cpu(pPP2->PortFlags) &
4998 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
5001 /* Save the Port Page 2 data
5002 * (reformat into a 32bit quantity)
5004 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
5005 ioc->spi_data.PortFlags = data;
5006 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5007 pdevice = &pPP2->DeviceSettings[ii];
5008 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
5009 (pdevice->SyncFactor << 8) | pdevice->Timeout;
5010 ioc->spi_data.nvram[ii] = data;
5014 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5018 /* Update Adapter limits with those from NVRAM
5019 * Comment: Don't need to do this. Target performance
5020 * parameters will never exceed the adapters limits.
5026 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5028 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
5029 * @ioc: Pointer to a Adapter Strucutre
5030 * @portnum: IOC port number
5032 * Return: -EFAULT if read of config page header fails
5036 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
5039 ConfigPageHeader_t header;
5041 /* Read the SCSI Device Page 1 header
5043 header.PageVersion = 0;
5044 header.PageLength = 0;
5045 header.PageNumber = 1;
5046 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5047 cfg.cfghdr.hdr = &header;
5049 cfg.pageAddr = portnum;
5050 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5053 if (mpt_config(ioc, &cfg) != 0)
5056 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
5057 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
5059 header.PageVersion = 0;
5060 header.PageLength = 0;
5061 header.PageNumber = 0;
5062 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5063 if (mpt_config(ioc, &cfg) != 0)
5066 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
5067 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
5069 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 0: version %d length %d\n",
5070 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
5072 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 1: version %d length %d\n",
5073 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
5078 * mpt_inactive_raid_list_free - This clears this link list.
5079 * @ioc : pointer to per adapter structure
5082 mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
5084 struct inactive_raid_component_info *component_info, *pNext;
5086 if (list_empty(&ioc->raid_data.inactive_list))
5089 down(&ioc->raid_data.inactive_list_mutex);
5090 list_for_each_entry_safe(component_info, pNext,
5091 &ioc->raid_data.inactive_list, list) {
5092 list_del(&component_info->list);
5093 kfree(component_info);
5095 up(&ioc->raid_data.inactive_list_mutex);
5099 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5101 * @ioc : pointer to per adapter structure
5102 * @channel : volume channel
5103 * @id : volume target id
5106 mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
5109 ConfigPageHeader_t hdr;
5110 dma_addr_t dma_handle;
5111 pRaidVolumePage0_t buffer = NULL;
5113 RaidPhysDiskPage0_t phys_disk;
5114 struct inactive_raid_component_info *component_info;
5115 int handle_inactive_volumes;
5117 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5118 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5119 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
5120 cfg.pageAddr = (channel << 8) + id;
5121 cfg.cfghdr.hdr = &hdr;
5122 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5124 if (mpt_config(ioc, &cfg) != 0)
5127 if (!hdr.PageLength)
5130 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5136 cfg.physAddr = dma_handle;
5137 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5139 if (mpt_config(ioc, &cfg) != 0)
5142 if (!buffer->NumPhysDisks)
5145 handle_inactive_volumes =
5146 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
5147 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
5148 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
5149 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
5151 if (!handle_inactive_volumes)
5154 down(&ioc->raid_data.inactive_list_mutex);
5155 for (i = 0; i < buffer->NumPhysDisks; i++) {
5156 if(mpt_raid_phys_disk_pg0(ioc,
5157 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
5160 if ((component_info = kmalloc(sizeof (*component_info),
5161 GFP_KERNEL)) == NULL)
5164 component_info->volumeID = id;
5165 component_info->volumeBus = channel;
5166 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
5167 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
5168 component_info->d.PhysDiskID = phys_disk.PhysDiskID;
5169 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
5171 list_add_tail(&component_info->list,
5172 &ioc->raid_data.inactive_list);
5174 up(&ioc->raid_data.inactive_list_mutex);
5178 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5183 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5184 * @ioc: Pointer to a Adapter Structure
5185 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5186 * @phys_disk: requested payload data returned
5190 * -EFAULT if read of config page header fails or data pointer not NULL
5191 * -ENOMEM if pci_alloc failed
5194 mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk)
5197 ConfigPageHeader_t hdr;
5198 dma_addr_t dma_handle;
5199 pRaidPhysDiskPage0_t buffer = NULL;
5202 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5203 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5205 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5206 cfg.cfghdr.hdr = &hdr;
5208 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5210 if (mpt_config(ioc, &cfg) != 0) {
5215 if (!hdr.PageLength) {
5220 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5228 cfg.physAddr = dma_handle;
5229 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5230 cfg.pageAddr = phys_disk_num;
5232 if (mpt_config(ioc, &cfg) != 0) {
5238 memcpy(phys_disk, buffer, sizeof(*buffer));
5239 phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
5244 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5251 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5252 * @ioc: Pointer to a Adapter Strucutre
5253 * @portnum: IOC port number
5257 * -EFAULT if read of config page header fails or data pointer not NULL
5258 * -ENOMEM if pci_alloc failed
5261 mpt_findImVolumes(MPT_ADAPTER *ioc)
5265 dma_addr_t ioc2_dma;
5267 ConfigPageHeader_t header;
5272 if (!ioc->ir_firmware)
5275 /* Free the old page
5277 kfree(ioc->raid_data.pIocPg2);
5278 ioc->raid_data.pIocPg2 = NULL;
5279 mpt_inactive_raid_list_free(ioc);
5281 /* Read IOCP2 header then the page.
5283 header.PageVersion = 0;
5284 header.PageLength = 0;
5285 header.PageNumber = 2;
5286 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5287 cfg.cfghdr.hdr = &header;
5290 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5293 if (mpt_config(ioc, &cfg) != 0)
5296 if (header.PageLength == 0)
5299 iocpage2sz = header.PageLength * 4;
5300 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
5304 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5305 cfg.physAddr = ioc2_dma;
5306 if (mpt_config(ioc, &cfg) != 0)
5309 mem = kmalloc(iocpage2sz, GFP_KERNEL);
5313 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
5314 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
5316 mpt_read_ioc_pg_3(ioc);
5318 for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
5319 mpt_inactive_raid_volumes(ioc,
5320 pIoc2->RaidVolume[i].VolumeBus,
5321 pIoc2->RaidVolume[i].VolumeID);
5324 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
5330 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
5335 ConfigPageHeader_t header;
5336 dma_addr_t ioc3_dma;
5339 /* Free the old page
5341 kfree(ioc->raid_data.pIocPg3);
5342 ioc->raid_data.pIocPg3 = NULL;
5344 /* There is at least one physical disk.
5345 * Read and save IOC Page 3
5347 header.PageVersion = 0;
5348 header.PageLength = 0;
5349 header.PageNumber = 3;
5350 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5351 cfg.cfghdr.hdr = &header;
5354 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5357 if (mpt_config(ioc, &cfg) != 0)
5360 if (header.PageLength == 0)
5363 /* Read Header good, alloc memory
5365 iocpage3sz = header.PageLength * 4;
5366 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
5370 /* Read the Page and save the data
5371 * into malloc'd memory.
5373 cfg.physAddr = ioc3_dma;
5374 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5375 if (mpt_config(ioc, &cfg) == 0) {
5376 mem = kmalloc(iocpage3sz, GFP_KERNEL);
5378 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
5379 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
5383 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
5389 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
5393 ConfigPageHeader_t header;
5394 dma_addr_t ioc4_dma;
5397 /* Read and save IOC Page 4
5399 header.PageVersion = 0;
5400 header.PageLength = 0;
5401 header.PageNumber = 4;
5402 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5403 cfg.cfghdr.hdr = &header;
5406 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5409 if (mpt_config(ioc, &cfg) != 0)
5412 if (header.PageLength == 0)
5415 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
5416 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
5417 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
5420 ioc->alloc_total += iocpage4sz;
5422 ioc4_dma = ioc->spi_data.IocPg4_dma;
5423 iocpage4sz = ioc->spi_data.IocPg4Sz;
5426 /* Read the Page into dma memory.
5428 cfg.physAddr = ioc4_dma;
5429 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5430 if (mpt_config(ioc, &cfg) == 0) {
5431 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
5432 ioc->spi_data.IocPg4_dma = ioc4_dma;
5433 ioc->spi_data.IocPg4Sz = iocpage4sz;
5435 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
5436 ioc->spi_data.pIocPg4 = NULL;
5437 ioc->alloc_total -= iocpage4sz;
5442 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
5446 ConfigPageHeader_t header;
5447 dma_addr_t ioc1_dma;
5451 /* Check the Coalescing Timeout in IOC Page 1
5453 header.PageVersion = 0;
5454 header.PageLength = 0;
5455 header.PageNumber = 1;
5456 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5457 cfg.cfghdr.hdr = &header;
5460 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5463 if (mpt_config(ioc, &cfg) != 0)
5466 if (header.PageLength == 0)
5469 /* Read Header good, alloc memory
5471 iocpage1sz = header.PageLength * 4;
5472 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
5476 /* Read the Page and check coalescing timeout
5478 cfg.physAddr = ioc1_dma;
5479 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5480 if (mpt_config(ioc, &cfg) == 0) {
5482 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
5483 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
5484 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
5486 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Coalescing Enabled Timeout = %d\n",
5489 if (tmp > MPT_COALESCING_TIMEOUT) {
5490 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
5492 /* Write NVRAM and current
5495 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5496 if (mpt_config(ioc, &cfg) == 0) {
5497 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Reset Current Coalescing Timeout to = %d\n",
5498 ioc->name, MPT_COALESCING_TIMEOUT));
5500 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
5501 if (mpt_config(ioc, &cfg) == 0) {
5502 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5503 "Reset NVRAM Coalescing Timeout to = %d\n",
5504 ioc->name, MPT_COALESCING_TIMEOUT));
5506 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5507 "Reset NVRAM Coalescing Timeout Failed\n",
5512 dprintk(ioc, printk(MYIOC_s_WARN_FMT
5513 "Reset of Current Coalescing Timeout Failed!\n",
5519 dprintk(ioc, printk(MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
5523 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
5529 mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
5532 ConfigPageHeader_t hdr;
5534 ManufacturingPage0_t *pbuf = NULL;
5536 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5537 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5539 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
5540 cfg.cfghdr.hdr = &hdr;
5542 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5545 if (mpt_config(ioc, &cfg) != 0)
5548 if (!cfg.cfghdr.hdr->PageLength)
5551 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5552 pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
5556 cfg.physAddr = buf_dma;
5558 if (mpt_config(ioc, &cfg) != 0)
5561 memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name));
5562 memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
5563 memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
5568 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
5571 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5573 * SendEventNotification - Send EventNotification (on or off) request to adapter
5574 * @ioc: Pointer to MPT_ADAPTER structure
5575 * @EvSwitch: Event switch flags
5578 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
5580 EventNotification_t *evnp;
5582 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
5584 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
5588 memset(evnp, 0, sizeof(*evnp));
5590 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
5592 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
5593 evnp->ChainOffset = 0;
5595 evnp->Switch = EvSwitch;
5597 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
5602 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5604 * SendEventAck - Send EventAck request to MPT adapter.
5605 * @ioc: Pointer to MPT_ADAPTER structure
5606 * @evnp: Pointer to original EventNotification request
5609 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
5613 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5614 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
5615 ioc->name,__FUNCTION__));
5619 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventAck\n", ioc->name));
5621 pAck->Function = MPI_FUNCTION_EVENT_ACK;
5622 pAck->ChainOffset = 0;
5623 pAck->Reserved[0] = pAck->Reserved[1] = 0;
5625 pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
5626 pAck->Event = evnp->Event;
5627 pAck->EventContext = evnp->EventContext;
5629 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
5634 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5636 * mpt_config - Generic function to issue config message
5637 * @ioc: Pointer to an adapter structure
5638 * @pCfg: Pointer to a configuration structure. Struct contains
5639 * action, page address, direction, physical address
5640 * and pointer to a configuration page header
5641 * Page header is updated.
5643 * Returns 0 for success
5644 * -EPERM if not allowed due to ISR context
5645 * -EAGAIN if no msg frames currently available
5646 * -EFAULT for non-successful reply or no reply (timeout)
5649 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5652 ConfigExtendedPageHeader_t *pExtHdr = NULL;
5654 unsigned long flags;
5659 /* Prevent calling wait_event() (below), if caller happens
5660 * to be in ISR context, because that is fatal!
5662 in_isr = in_interrupt();
5664 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
5669 /* Get and Populate a free Frame
5671 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5672 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
5676 pReq = (Config_t *)mf;
5677 pReq->Action = pCfg->action;
5679 pReq->ChainOffset = 0;
5680 pReq->Function = MPI_FUNCTION_CONFIG;
5682 /* Assume page type is not extended and clear "reserved" fields. */
5683 pReq->ExtPageLength = 0;
5684 pReq->ExtPageType = 0;
5687 for (ii=0; ii < 8; ii++)
5688 pReq->Reserved2[ii] = 0;
5690 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
5691 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
5692 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
5693 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
5695 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5696 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
5697 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
5698 pReq->ExtPageType = pExtHdr->ExtPageType;
5699 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
5701 /* Page Length must be treated as a reserved field for the extended header. */
5702 pReq->Header.PageLength = 0;
5705 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
5707 /* Add a SGE to the config request.
5710 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
5712 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
5714 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5715 flagsLength |= pExtHdr->ExtPageLength * 4;
5717 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n",
5718 ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action));
5721 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
5723 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n",
5724 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
5727 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
5729 /* Append pCfg pointer to end of mf
5731 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5733 /* Initalize the timer
5735 init_timer(&pCfg->timer);
5736 pCfg->timer.data = (unsigned long) ioc;
5737 pCfg->timer.function = mpt_timer_expired;
5738 pCfg->wait_done = 0;
5740 /* Set the timer; ensure 10 second minimum */
5741 if (pCfg->timeout < 10)
5742 pCfg->timer.expires = jiffies + HZ*10;
5744 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5746 /* Add to end of Q, set timer and then issue this command */
5747 spin_lock_irqsave(&ioc->FreeQlock, flags);
5748 list_add_tail(&pCfg->linkage, &ioc->configQ);
5749 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5751 add_timer(&pCfg->timer);
5752 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5753 wait_event(mpt_waitq, pCfg->wait_done);
5755 /* mf has been freed - do not access */
5762 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5764 * mpt_timer_expired - Callback for timer process.
5765 * Used only internal config functionality.
5766 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5769 mpt_timer_expired(unsigned long data)
5771 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
5773 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired! \n", ioc->name));
5775 /* Perform a FW reload */
5776 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
5777 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
5779 /* No more processing.
5780 * Hard reset clean-up will wake up
5781 * process and free all resources.
5783 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired complete!\n", ioc->name));
5788 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5790 * mpt_ioc_reset - Base cleanup for hard reset
5791 * @ioc: Pointer to the adapter structure
5792 * @reset_phase: Indicates pre- or post-reset functionality
5794 * Remark: Frees resources with internally generated commands.
5797 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
5800 unsigned long flags;
5802 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5803 ": IOC %s_reset routed to MPT base driver!\n",
5804 ioc->name, reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
5805 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
5807 if (reset_phase == MPT_IOC_SETUP_RESET) {
5809 } else if (reset_phase == MPT_IOC_PRE_RESET) {
5810 /* If the internal config Q is not empty -
5811 * delete timer. MF resources will be freed when
5812 * the FIFO's are primed.
5814 spin_lock_irqsave(&ioc->FreeQlock, flags);
5815 list_for_each_entry(pCfg, &ioc->configQ, linkage)
5816 del_timer(&pCfg->timer);
5817 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5822 /* Search the configQ for internal commands.
5823 * Flush the Q, and wake up all suspended threads.
5825 spin_lock_irqsave(&ioc->FreeQlock, flags);
5826 list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
5827 list_del(&pCfg->linkage);
5829 pCfg->status = MPT_CONFIG_ERROR;
5830 pCfg->wait_done = 1;
5831 wake_up(&mpt_waitq);
5833 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5836 return 1; /* currently means nothing really */
5840 #ifdef CONFIG_PROC_FS /* { */
5841 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5843 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5845 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5847 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5849 * Returns 0 for success, non-zero for failure.
5852 procmpt_create(void)
5854 struct proc_dir_entry *ent;
5856 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
5857 if (mpt_proc_root_dir == NULL)
5860 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5862 ent->read_proc = procmpt_summary_read;
5864 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5866 ent->read_proc = procmpt_version_read;
5871 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5873 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5875 * Returns 0 for success, non-zero for failure.
5878 procmpt_destroy(void)
5880 remove_proc_entry("version", mpt_proc_root_dir);
5881 remove_proc_entry("summary", mpt_proc_root_dir);
5882 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
5885 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5887 * procmpt_summary_read - Handle read request of a summary file
5888 * @buf: Pointer to area to write information
5889 * @start: Pointer to start pointer
5890 * @offset: Offset to start writing
5891 * @request: Amount of read data requested
5892 * @eof: Pointer to EOF integer
5895 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
5896 * Returns number of characters written to process performing the read.
5899 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5909 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5913 list_for_each_entry(ioc, &ioc_list, list) {
5916 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5919 if ((out-buf) >= request)
5926 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5929 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5931 * procmpt_version_read - Handle read request from /proc/mpt/version.
5932 * @buf: Pointer to area to write information
5933 * @start: Pointer to start pointer
5934 * @offset: Offset to start writing
5935 * @request: Amount of read data requested
5936 * @eof: Pointer to EOF integer
5939 * Returns number of characters written to process performing the read.
5942 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5945 int scsi, fc, sas, lan, ctl, targ, dmp;
5949 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
5950 len += sprintf(buf+len, " Fusion MPT base driver\n");
5952 scsi = fc = sas = lan = ctl = targ = dmp = 0;
5953 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
5955 if (MptCallbacks[cb_idx]) {
5956 switch (MptDriverClass[cb_idx]) {
5958 if (!scsi++) drvname = "SPI host";
5961 if (!fc++) drvname = "FC host";
5964 if (!sas++) drvname = "SAS host";
5967 if (!lan++) drvname = "LAN";
5970 if (!targ++) drvname = "SCSI target";
5973 if (!ctl++) drvname = "ioctl";
5978 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
5982 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5985 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5987 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
5988 * @buf: Pointer to area to write information
5989 * @start: Pointer to start pointer
5990 * @offset: Offset to start writing
5991 * @request: Amount of read data requested
5992 * @eof: Pointer to EOF integer
5995 * Returns number of characters written to process performing the read.
5998 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6000 MPT_ADAPTER *ioc = data;
6006 mpt_get_fw_exp_ver(expVer, ioc);
6008 len = sprintf(buf, "%s:", ioc->name);
6009 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
6010 len += sprintf(buf+len, " (f/w download boot flag set)");
6011 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6012 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
6014 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
6015 ioc->facts.ProductID,
6017 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
6018 if (ioc->facts.FWImageSize)
6019 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
6020 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
6021 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
6022 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
6024 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
6025 ioc->facts.CurrentHostMfaHighAddr);
6026 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
6027 ioc->facts.CurrentSenseBufferHighAddr);
6029 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
6030 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
6032 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6033 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
6035 * Rounding UP to nearest 4-kB boundary here...
6037 sz = (ioc->req_sz * ioc->req_depth) + 128;
6038 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
6039 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6040 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
6041 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
6042 4*ioc->facts.RequestFrameSize,
6043 ioc->facts.GlobalCredits);
6045 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
6046 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
6047 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
6048 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6049 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
6050 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
6051 ioc->facts.CurReplyFrameSize,
6052 ioc->facts.ReplyQueueDepth);
6054 len += sprintf(buf+len, " MaxDevices = %d\n",
6055 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
6056 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
6059 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
6060 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
6062 ioc->facts.NumberOfPorts);
6063 if (ioc->bus_type == FC) {
6064 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
6065 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6066 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6067 a[5], a[4], a[3], a[2], a[1], a[0]);
6069 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
6070 ioc->fc_port_page0[p].WWNN.High,
6071 ioc->fc_port_page0[p].WWNN.Low,
6072 ioc->fc_port_page0[p].WWPN.High,
6073 ioc->fc_port_page0[p].WWPN.Low);
6077 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6080 #endif /* CONFIG_PROC_FS } */
6082 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6084 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
6087 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
6088 sprintf(buf, " (Exp %02d%02d)",
6089 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
6090 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
6093 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
6094 strcat(buf, " [MDBG]");
6098 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6100 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6101 * @ioc: Pointer to MPT_ADAPTER structure
6102 * @buffer: Pointer to buffer where IOC summary info should be written
6103 * @size: Pointer to number of bytes we wrote (set by this routine)
6104 * @len: Offset at which to start writing in buffer
6105 * @showlan: Display LAN stuff?
6107 * This routine writes (english readable) ASCII text, which represents
6108 * a summary of IOC information, to a buffer.
6111 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
6116 mpt_get_fw_exp_ver(expVer, ioc);
6119 * Shorter summary of attached ioc's...
6121 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6124 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
6125 ioc->facts.FWVersion.Word,
6127 ioc->facts.NumberOfPorts,
6130 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6131 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6132 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6133 a[5], a[4], a[3], a[2], a[1], a[0]);
6136 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
6139 y += sprintf(buffer+len+y, " (disabled)");
6141 y += sprintf(buffer+len+y, "\n");
6146 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6150 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6152 * mpt_HardResetHandler - Generic reset handler
6153 * @ioc: Pointer to MPT_ADAPTER structure
6154 * @sleepFlag: Indicates if sleep or schedule must be called.
6156 * Issues SCSI Task Management call based on input arg values.
6157 * If TaskMgmt fails, returns associated SCSI request.
6159 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
6160 * or a non-interrupt thread. In the former, must not call schedule().
6162 * Note: A return of -1 is a FATAL error case, as it means a
6163 * FW reload/initialization failed.
6165 * Returns 0 for SUCCESS or -1 if FAILED.
6168 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6171 unsigned long flags;
6173 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name));
6175 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
6176 printk("MF count 0x%x !\n", ioc->mfcnt);
6179 /* Reset the adapter. Prevent more than 1 call to
6180 * mpt_do_ioc_recovery at any instant in time.
6182 spin_lock_irqsave(&ioc->diagLock, flags);
6183 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
6184 spin_unlock_irqrestore(&ioc->diagLock, flags);
6187 ioc->diagPending = 1;
6189 spin_unlock_irqrestore(&ioc->diagLock, flags);
6191 /* FIXME: If do_ioc_recovery fails, repeat....
6194 /* The SCSI driver needs to adjust timeouts on all current
6195 * commands prior to the diagnostic reset being issued.
6196 * Prevents timeouts occurring during a diagnostic reset...very bad.
6197 * For all other protocol drivers, this is a no-op.
6203 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6204 if (MptResetHandlers[cb_idx]) {
6205 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling IOC reset_setup handler #%d\n",
6206 ioc->name, cb_idx));
6207 r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
6209 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling alt-%s setup reset handler #%d\n",
6210 ioc->name, ioc->alt_ioc->name, cb_idx));
6211 r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_SETUP_RESET);
6217 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
6218 printk(MYIOC_s_WARN_FMT "Cannot recover rc = %d!\n", ioc->name, rc);
6222 ioc->alt_ioc->reload_fw = 0;
6224 spin_lock_irqsave(&ioc->diagLock, flags);
6225 ioc->diagPending = 0;
6227 ioc->alt_ioc->diagPending = 0;
6228 spin_unlock_irqrestore(&ioc->diagLock, flags);
6230 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
6235 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6237 EventDescriptionStr(u8 event, u32 evData0, char *evStr)
6242 case MPI_EVENT_NONE:
6245 case MPI_EVENT_LOG_DATA:
6248 case MPI_EVENT_STATE_CHANGE:
6249 ds = "State Change";
6251 case MPI_EVENT_UNIT_ATTENTION:
6252 ds = "Unit Attention";
6254 case MPI_EVENT_IOC_BUS_RESET:
6255 ds = "IOC Bus Reset";
6257 case MPI_EVENT_EXT_BUS_RESET:
6258 ds = "External Bus Reset";
6260 case MPI_EVENT_RESCAN:
6261 ds = "Bus Rescan Event";
6263 case MPI_EVENT_LINK_STATUS_CHANGE:
6264 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
6265 ds = "Link Status(FAILURE) Change";
6267 ds = "Link Status(ACTIVE) Change";
6269 case MPI_EVENT_LOOP_STATE_CHANGE:
6270 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
6271 ds = "Loop State(LIP) Change";
6272 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
6273 ds = "Loop State(LPE) Change"; /* ??? */
6275 ds = "Loop State(LPB) Change"; /* ??? */
6277 case MPI_EVENT_LOGOUT:
6280 case MPI_EVENT_EVENT_CHANGE:
6286 case MPI_EVENT_INTEGRATED_RAID:
6288 u8 ReasonCode = (u8)(evData0 >> 16);
6289 switch (ReasonCode) {
6290 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
6291 ds = "Integrated Raid: Volume Created";
6293 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
6294 ds = "Integrated Raid: Volume Deleted";
6296 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
6297 ds = "Integrated Raid: Volume Settings Changed";
6299 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
6300 ds = "Integrated Raid: Volume Status Changed";
6302 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
6303 ds = "Integrated Raid: Volume Physdisk Changed";
6305 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
6306 ds = "Integrated Raid: Physdisk Created";
6308 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
6309 ds = "Integrated Raid: Physdisk Deleted";
6311 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
6312 ds = "Integrated Raid: Physdisk Settings Changed";
6314 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
6315 ds = "Integrated Raid: Physdisk Status Changed";
6317 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
6318 ds = "Integrated Raid: Domain Validation Needed";
6320 case MPI_EVENT_RAID_RC_SMART_DATA :
6321 ds = "Integrated Raid; Smart Data";
6323 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
6324 ds = "Integrated Raid: Replace Action Started";
6327 ds = "Integrated Raid";
6332 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
6333 ds = "SCSI Device Status Change";
6335 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
6337 u8 id = (u8)(evData0);
6338 u8 channel = (u8)(evData0 >> 8);
6339 u8 ReasonCode = (u8)(evData0 >> 16);
6340 switch (ReasonCode) {
6341 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
6342 snprintf(evStr, EVENT_DESCR_STR_SZ,
6343 "SAS Device Status Change: Added: "
6344 "id=%d channel=%d", id, channel);
6346 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
6347 snprintf(evStr, EVENT_DESCR_STR_SZ,
6348 "SAS Device Status Change: Deleted: "
6349 "id=%d channel=%d", id, channel);
6351 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
6352 snprintf(evStr, EVENT_DESCR_STR_SZ,
6353 "SAS Device Status Change: SMART Data: "
6354 "id=%d channel=%d", id, channel);
6356 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
6357 snprintf(evStr, EVENT_DESCR_STR_SZ,
6358 "SAS Device Status Change: No Persistancy: "
6359 "id=%d channel=%d", id, channel);
6361 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
6362 snprintf(evStr, EVENT_DESCR_STR_SZ,
6363 "SAS Device Status Change: Unsupported Device "
6364 "Discovered : id=%d channel=%d", id, channel);
6366 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
6367 snprintf(evStr, EVENT_DESCR_STR_SZ,
6368 "SAS Device Status Change: Internal Device "
6369 "Reset : id=%d channel=%d", id, channel);
6371 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
6372 snprintf(evStr, EVENT_DESCR_STR_SZ,
6373 "SAS Device Status Change: Internal Task "
6374 "Abort : id=%d channel=%d", id, channel);
6376 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
6377 snprintf(evStr, EVENT_DESCR_STR_SZ,
6378 "SAS Device Status Change: Internal Abort "
6379 "Task Set : id=%d channel=%d", id, channel);
6381 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
6382 snprintf(evStr, EVENT_DESCR_STR_SZ,
6383 "SAS Device Status Change: Internal Clear "
6384 "Task Set : id=%d channel=%d", id, channel);
6386 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
6387 snprintf(evStr, EVENT_DESCR_STR_SZ,
6388 "SAS Device Status Change: Internal Query "
6389 "Task : id=%d channel=%d", id, channel);
6392 snprintf(evStr, EVENT_DESCR_STR_SZ,
6393 "SAS Device Status Change: Unknown: "
6394 "id=%d channel=%d", id, channel);
6399 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
6400 ds = "Bus Timer Expired";
6402 case MPI_EVENT_QUEUE_FULL:
6404 u16 curr_depth = (u16)(evData0 >> 16);
6405 u8 channel = (u8)(evData0 >> 8);
6406 u8 id = (u8)(evData0);
6408 snprintf(evStr, EVENT_DESCR_STR_SZ,
6409 "Queue Full: channel=%d id=%d depth=%d",
6410 channel, id, curr_depth);
6413 case MPI_EVENT_SAS_SES:
6414 ds = "SAS SES Event";
6416 case MPI_EVENT_PERSISTENT_TABLE_FULL:
6417 ds = "Persistent Table Full";
6419 case MPI_EVENT_SAS_PHY_LINK_STATUS:
6421 u8 LinkRates = (u8)(evData0 >> 8);
6422 u8 PhyNumber = (u8)(evData0);
6423 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
6424 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
6425 switch (LinkRates) {
6426 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
6427 snprintf(evStr, EVENT_DESCR_STR_SZ,
6428 "SAS PHY Link Status: Phy=%d:"
6429 " Rate Unknown",PhyNumber);
6431 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
6432 snprintf(evStr, EVENT_DESCR_STR_SZ,
6433 "SAS PHY Link Status: Phy=%d:"
6434 " Phy Disabled",PhyNumber);
6436 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
6437 snprintf(evStr, EVENT_DESCR_STR_SZ,
6438 "SAS PHY Link Status: Phy=%d:"
6439 " Failed Speed Nego",PhyNumber);
6441 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
6442 snprintf(evStr, EVENT_DESCR_STR_SZ,
6443 "SAS PHY Link Status: Phy=%d:"
6444 " Sata OOB Completed",PhyNumber);
6446 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
6447 snprintf(evStr, EVENT_DESCR_STR_SZ,
6448 "SAS PHY Link Status: Phy=%d:"
6449 " Rate 1.5 Gbps",PhyNumber);
6451 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
6452 snprintf(evStr, EVENT_DESCR_STR_SZ,
6453 "SAS PHY Link Status: Phy=%d:"
6454 " Rate 3.0 Gpbs",PhyNumber);
6457 snprintf(evStr, EVENT_DESCR_STR_SZ,
6458 "SAS PHY Link Status: Phy=%d", PhyNumber);
6463 case MPI_EVENT_SAS_DISCOVERY_ERROR:
6464 ds = "SAS Discovery Error";
6466 case MPI_EVENT_IR_RESYNC_UPDATE:
6468 u8 resync_complete = (u8)(evData0 >> 16);
6469 snprintf(evStr, EVENT_DESCR_STR_SZ,
6470 "IR Resync Update: Complete = %d:",resync_complete);
6475 u8 ReasonCode = (u8)(evData0 >> 16);
6476 switch (ReasonCode) {
6477 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
6478 ds = "IR2: LD State Changed";
6480 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
6481 ds = "IR2: PD State Changed";
6483 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
6484 ds = "IR2: Bad Block Table Full";
6486 case MPI_EVENT_IR2_RC_PD_INSERTED:
6487 ds = "IR2: PD Inserted";
6489 case MPI_EVENT_IR2_RC_PD_REMOVED:
6490 ds = "IR2: PD Removed";
6492 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
6493 ds = "IR2: Foreign CFG Detected";
6495 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
6496 ds = "IR2: Rebuild Medium Error";
6504 case MPI_EVENT_SAS_DISCOVERY:
6507 ds = "SAS Discovery: Start";
6509 ds = "SAS Discovery: Stop";
6512 case MPI_EVENT_LOG_ENTRY_ADDED:
6513 ds = "SAS Log Entry Added";
6516 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
6518 u8 phy_num = (u8)(evData0);
6519 u8 port_num = (u8)(evData0 >> 8);
6520 u8 port_width = (u8)(evData0 >> 16);
6521 u8 primative = (u8)(evData0 >> 24);
6522 snprintf(evStr, EVENT_DESCR_STR_SZ,
6523 "SAS Broadcase Primative: phy=%d port=%d "
6524 "width=%d primative=0x%02x",
6525 phy_num, port_num, port_width, primative);
6529 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
6531 u8 reason = (u8)(evData0);
6532 u8 port_num = (u8)(evData0 >> 8);
6533 u16 handle = le16_to_cpu(evData0 >> 16);
6535 snprintf(evStr, EVENT_DESCR_STR_SZ,
6536 "SAS Initiator Device Status Change: reason=0x%02x "
6537 "port=%d handle=0x%04x",
6538 reason, port_num, handle);
6542 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
6544 u8 max_init = (u8)(evData0);
6545 u8 current_init = (u8)(evData0 >> 8);
6547 snprintf(evStr, EVENT_DESCR_STR_SZ,
6548 "SAS Initiator Device Table Overflow: max initiators=%02d "
6549 "current initators=%02d",
6550 max_init, current_init);
6553 case MPI_EVENT_SAS_SMP_ERROR:
6555 u8 status = (u8)(evData0);
6556 u8 port_num = (u8)(evData0 >> 8);
6557 u8 result = (u8)(evData0 >> 16);
6559 if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
6560 snprintf(evStr, EVENT_DESCR_STR_SZ,
6561 "SAS SMP Error: port=%d result=0x%02x",
6563 else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
6564 snprintf(evStr, EVENT_DESCR_STR_SZ,
6565 "SAS SMP Error: port=%d : CRC Error",
6567 else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
6568 snprintf(evStr, EVENT_DESCR_STR_SZ,
6569 "SAS SMP Error: port=%d : Timeout",
6571 else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
6572 snprintf(evStr, EVENT_DESCR_STR_SZ,
6573 "SAS SMP Error: port=%d : No Destination",
6575 else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
6576 snprintf(evStr, EVENT_DESCR_STR_SZ,
6577 "SAS SMP Error: port=%d : Bad Destination",
6580 snprintf(evStr, EVENT_DESCR_STR_SZ,
6581 "SAS SMP Error: port=%d : status=0x%02x",
6587 * MPT base "custom" events may be added here...
6594 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
6597 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6599 * ProcessEventNotification - Route EventNotificationReply to all event handlers
6600 * @ioc: Pointer to MPT_ADAPTER structure
6601 * @pEventReply: Pointer to EventNotification reply frame
6602 * @evHandlers: Pointer to integer, number of event handlers
6604 * Routes a received EventNotificationReply to all currently registered
6606 * Returns sum of event handlers return values.
6609 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
6618 char evStr[EVENT_DESCR_STR_SZ];
6622 * Do platform normalization of values
6624 event = le32_to_cpu(pEventReply->Event) & 0xFF;
6625 // evCtx = le32_to_cpu(pEventReply->EventContext);
6626 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
6628 evData0 = le32_to_cpu(pEventReply->Data[0]);
6631 EventDescriptionStr(event, evData0, evStr);
6632 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event:(%02Xh) : %s\n",
6637 #ifdef CONFIG_FUSION_LOGGING
6638 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6639 ": Event data:\n", ioc->name));
6640 for (ii = 0; ii < evDataLen; ii++)
6641 devtverboseprintk(ioc, printk(" %08x",
6642 le32_to_cpu(pEventReply->Data[ii])));
6643 devtverboseprintk(ioc, printk("\n"));
6647 * Do general / base driver event processing
6650 case MPI_EVENT_EVENT_CHANGE: /* 0A */
6652 u8 evState = evData0 & 0xFF;
6654 /* CHECKME! What if evState unexpectedly says OFF (0)? */
6656 /* Update EventState field in cached IocFacts */
6657 if (ioc->facts.Function) {
6658 ioc->facts.EventState = evState;
6662 case MPI_EVENT_INTEGRATED_RAID:
6663 mptbase_raid_process_event_data(ioc,
6664 (MpiEventDataRaid_t *)pEventReply->Data);
6671 * Should this event be logged? Events are written sequentially.
6672 * When buffer is full, start again at the top.
6674 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
6677 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
6679 ioc->events[idx].event = event;
6680 ioc->events[idx].eventContext = ioc->eventContext;
6682 for (ii = 0; ii < 2; ii++) {
6684 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
6686 ioc->events[idx].data[ii] = 0;
6689 ioc->eventContext++;
6694 * Call each currently registered protocol event handler.
6696 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6697 if (MptEvHandlers[cb_idx]) {
6698 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Routing Event to event handler #%d\n",
6699 ioc->name, cb_idx));
6700 r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply);
6704 /* FIXME? Examine results here? */
6707 * If needed, send (a single) EventAck.
6709 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
6710 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6711 "EventAck required\n",ioc->name));
6712 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
6713 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SendEventAck returned %d\n",
6718 *evHandlers = handlers;
6722 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6724 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
6725 * @ioc: Pointer to MPT_ADAPTER structure
6726 * @log_info: U32 LogInfo reply word from the IOC
6728 * Refer to lsi/mpi_log_fc.h.
6731 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
6733 char *desc = "unknown";
6735 switch (log_info & 0xFF000000) {
6736 case MPI_IOCLOGINFO_FC_INIT_BASE:
6737 desc = "FCP Initiator";
6739 case MPI_IOCLOGINFO_FC_TARGET_BASE:
6740 desc = "FCP Target";
6742 case MPI_IOCLOGINFO_FC_LAN_BASE:
6745 case MPI_IOCLOGINFO_FC_MSG_BASE:
6746 desc = "MPI Message Layer";
6748 case MPI_IOCLOGINFO_FC_LINK_BASE:
6751 case MPI_IOCLOGINFO_FC_CTX_BASE:
6752 desc = "Context Manager";
6754 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
6755 desc = "Invalid Field Offset";
6757 case MPI_IOCLOGINFO_FC_STATE_CHANGE:
6758 desc = "State Change Info";
6762 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
6763 ioc->name, log_info, desc, (log_info & 0xFFFFFF));
6766 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6768 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
6769 * @ioc: Pointer to MPT_ADAPTER structure
6770 * @mr: Pointer to MPT reply frame
6771 * @log_info: U32 LogInfo word from the IOC
6773 * Refer to lsi/sp_log.h.
6776 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
6778 u32 info = log_info & 0x00FF0000;
6779 char *desc = "unknown";
6783 desc = "bug! MID not found";
6784 if (ioc->reload_fw == 0)
6789 desc = "Parity Error";
6793 desc = "ASYNC Outbound Overrun";
6797 desc = "SYNC Offset Error";
6805 desc = "Msg In Overflow";
6813 desc = "Outbound DMA Overrun";
6817 desc = "Task Management";
6821 desc = "Device Problem";
6825 desc = "Invalid Phase Change";
6829 desc = "Untagged Table Size";
6834 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
6837 /* strings for sas loginfo */
6838 static char *originator_str[] = {
6843 static char *iop_code_str[] = {
6845 "Invalid SAS Address", /* 01h */
6847 "Invalid Page", /* 03h */
6848 "Diag Message Error", /* 04h */
6849 "Task Terminated", /* 05h */
6850 "Enclosure Management", /* 06h */
6851 "Target Mode" /* 07h */
6853 static char *pl_code_str[] = {
6855 "Open Failure", /* 01h */
6856 "Invalid Scatter Gather List", /* 02h */
6857 "Wrong Relative Offset or Frame Length", /* 03h */
6858 "Frame Transfer Error", /* 04h */
6859 "Transmit Frame Connected Low", /* 05h */
6860 "SATA Non-NCQ RW Error Bit Set", /* 06h */
6861 "SATA Read Log Receive Data Error", /* 07h */
6862 "SATA NCQ Fail All Commands After Error", /* 08h */
6863 "SATA Error in Receive Set Device Bit FIS", /* 09h */
6864 "Receive Frame Invalid Message", /* 0Ah */
6865 "Receive Context Message Valid Error", /* 0Bh */
6866 "Receive Frame Current Frame Error", /* 0Ch */
6867 "SATA Link Down", /* 0Dh */
6868 "Discovery SATA Init W IOS", /* 0Eh */
6869 "Config Invalid Page", /* 0Fh */
6870 "Discovery SATA Init Timeout", /* 10h */
6873 "IO Not Yet Executed", /* 13h */
6874 "IO Executed", /* 14h */
6875 "Persistent Reservation Out Not Affiliation "
6877 "Open Transmit DMA Abort", /* 16h */
6878 "IO Device Missing Delay Retry", /* 17h */
6879 "IO Cancelled Due to Recieve Error", /* 18h */
6887 "Enclosure Management" /* 20h */
6889 static char *ir_code_str[] = {
6890 "Raid Action Error", /* 00h */
6900 static char *raid_sub_code_str[] = {
6902 "Volume Creation Failed: Data Passed too "
6904 "Volume Creation Failed: Duplicate Volumes "
6905 "Attempted", /* 02h */
6906 "Volume Creation Failed: Max Number "
6907 "Supported Volumes Exceeded", /* 03h */
6908 "Volume Creation Failed: DMA Error", /* 04h */
6909 "Volume Creation Failed: Invalid Volume Type", /* 05h */
6910 "Volume Creation Failed: Error Reading "
6911 "MFG Page 4", /* 06h */
6912 "Volume Creation Failed: Creating Internal "
6913 "Structures", /* 07h */
6922 "Activation failed: Already Active Volume", /* 10h */
6923 "Activation failed: Unsupported Volume Type", /* 11h */
6924 "Activation failed: Too Many Active Volumes", /* 12h */
6925 "Activation failed: Volume ID in Use", /* 13h */
6926 "Activation failed: Reported Failure", /* 14h */
6927 "Activation failed: Importing a Volume", /* 15h */
6938 "Phys Disk failed: Too Many Phys Disks", /* 20h */
6939 "Phys Disk failed: Data Passed too Large", /* 21h */
6940 "Phys Disk failed: DMA Error", /* 22h */
6941 "Phys Disk failed: Invalid <channel:id>", /* 23h */
6942 "Phys Disk failed: Creating Phys Disk Config "
6955 "Compatibility Error: IR Disabled", /* 30h */
6956 "Compatibility Error: Inquiry Comand Failed", /* 31h */
6957 "Compatibility Error: Device not Direct Access "
6958 "Device ", /* 32h */
6959 "Compatibility Error: Removable Device Found", /* 33h */
6960 "Compatibility Error: Device SCSI Version not "
6961 "2 or Higher", /* 34h */
6962 "Compatibility Error: SATA Device, 48 BIT LBA "
6963 "not Supported", /* 35h */
6964 "Compatibility Error: Device doesn't have "
6965 "512 Byte Block Sizes", /* 36h */
6966 "Compatibility Error: Volume Type Check Failed", /* 37h */
6967 "Compatibility Error: Volume Type is "
6968 "Unsupported by FW", /* 38h */
6969 "Compatibility Error: Disk Drive too Small for "
6970 "use in Volume", /* 39h */
6971 "Compatibility Error: Phys Disk for Create "
6972 "Volume not Found", /* 3Ah */
6973 "Compatibility Error: Too Many or too Few "
6974 "Disks for Volume Type", /* 3Bh */
6975 "Compatibility Error: Disk stripe Sizes "
6976 "Must be 64KB", /* 3Ch */
6977 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
6980 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6982 * mpt_sas_log_info - Log information returned from SAS IOC.
6983 * @ioc: Pointer to MPT_ADAPTER structure
6984 * @log_info: U32 LogInfo reply word from the IOC
6986 * Refer to lsi/mpi_log_sas.h.
6989 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
6991 union loginfo_type {
7000 union loginfo_type sas_loginfo;
7001 char *originator_desc = NULL;
7002 char *code_desc = NULL;
7003 char *sub_code_desc = NULL;
7005 sas_loginfo.loginfo = log_info;
7006 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
7007 (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
7010 originator_desc = originator_str[sas_loginfo.dw.originator];
7012 switch (sas_loginfo.dw.originator) {
7015 if (sas_loginfo.dw.code <
7016 sizeof(iop_code_str)/sizeof(char*))
7017 code_desc = iop_code_str[sas_loginfo.dw.code];
7020 if (sas_loginfo.dw.code <
7021 sizeof(pl_code_str)/sizeof(char*))
7022 code_desc = pl_code_str[sas_loginfo.dw.code];
7025 if (sas_loginfo.dw.code >=
7026 sizeof(ir_code_str)/sizeof(char*))
7028 code_desc = ir_code_str[sas_loginfo.dw.code];
7029 if (sas_loginfo.dw.subcode >=
7030 sizeof(raid_sub_code_str)/sizeof(char*))
7032 if (sas_loginfo.dw.code == 0)
7034 raid_sub_code_str[sas_loginfo.dw.subcode];
7040 if (sub_code_desc != NULL)
7041 printk(MYIOC_s_INFO_FMT
7042 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7044 ioc->name, log_info, originator_desc, code_desc,
7046 else if (code_desc != NULL)
7047 printk(MYIOC_s_INFO_FMT
7048 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7049 " SubCode(0x%04x)\n",
7050 ioc->name, log_info, originator_desc, code_desc,
7051 sas_loginfo.dw.subcode);
7053 printk(MYIOC_s_INFO_FMT
7054 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
7055 " SubCode(0x%04x)\n",
7056 ioc->name, log_info, originator_desc,
7057 sas_loginfo.dw.code, sas_loginfo.dw.subcode);
7060 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7062 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
7063 * @ioc: Pointer to MPT_ADAPTER structure
7064 * @ioc_status: U32 IOCStatus word from IOC
7065 * @mf: Pointer to MPT request frame
7067 * Refer to lsi/mpi.h.
7070 mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7072 Config_t *pReq = (Config_t *)mf;
7073 char extend_desc[EVENT_DESCR_STR_SZ];
7078 if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
7079 page_type = pReq->ExtPageType;
7081 page_type = pReq->Header.PageType;
7084 * ignore invalid page messages for GET_NEXT_HANDLE
7086 form = le32_to_cpu(pReq->PageAddress);
7087 if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
7088 if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
7089 page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
7090 page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
7091 if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
7092 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
7095 if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
7096 if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
7097 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
7101 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
7102 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
7103 page_type, pReq->Header.PageNumber, pReq->Action, form);
7105 switch (ioc_status) {
7107 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7108 desc = "Config Page Invalid Action";
7111 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7112 desc = "Config Page Invalid Type";
7115 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7116 desc = "Config Page Invalid Page";
7119 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7120 desc = "Config Page Invalid Data";
7123 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7124 desc = "Config Page No Defaults";
7127 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7128 desc = "Config Page Can't Commit";
7135 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s: %s\n",
7136 ioc->name, ioc_status, desc, extend_desc));
7140 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
7141 * @ioc: Pointer to MPT_ADAPTER structure
7142 * @ioc_status: U32 IOCStatus word from IOC
7143 * @mf: Pointer to MPT request frame
7145 * Refer to lsi/mpi.h.
7148 mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7150 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
7155 /****************************************************************************/
7156 /* Common IOCStatus values for all replies */
7157 /****************************************************************************/
7159 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
7160 desc = "Invalid Function";
7163 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
7167 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
7168 desc = "Invalid SGL";
7171 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
7172 desc = "Internal Error";
7175 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
7179 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
7180 desc = "Insufficient Resources";
7183 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
7184 desc = "Invalid Field";
7187 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
7188 desc = "Invalid State";
7191 /****************************************************************************/
7192 /* Config IOCStatus values */
7193 /****************************************************************************/
7195 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7196 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7197 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7198 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7199 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7200 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7201 mpt_iocstatus_info_config(ioc, status, mf);
7204 /****************************************************************************/
7205 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
7207 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
7209 /****************************************************************************/
7211 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
7212 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
7213 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
7214 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
7215 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
7216 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
7217 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
7218 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
7219 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
7220 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
7221 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
7222 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
7223 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
7226 /****************************************************************************/
7227 /* SCSI Target values */
7228 /****************************************************************************/
7230 case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
7231 desc = "Target: Priority IO";
7234 case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
7235 desc = "Target: Invalid Port";
7238 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
7239 desc = "Target Invalid IO Index:";
7242 case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
7243 desc = "Target: Aborted";
7246 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
7247 desc = "Target: No Conn Retryable";
7250 case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
7251 desc = "Target: No Connection";
7254 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
7255 desc = "Target: Transfer Count Mismatch";
7258 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
7259 desc = "Target: STS Data not Sent";
7262 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
7263 desc = "Target: Data Offset Error";
7266 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
7267 desc = "Target: Too Much Write Data";
7270 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
7271 desc = "Target: IU Too Short";
7274 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
7275 desc = "Target: ACK NAK Timeout";
7278 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
7279 desc = "Target: Nak Received";
7282 /****************************************************************************/
7283 /* Fibre Channel Direct Access values */
7284 /****************************************************************************/
7286 case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
7287 desc = "FC: Aborted";
7290 case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
7291 desc = "FC: RX ID Invalid";
7294 case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
7295 desc = "FC: DID Invalid";
7298 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
7299 desc = "FC: Node Logged Out";
7302 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
7303 desc = "FC: Exchange Canceled";
7306 /****************************************************************************/
7308 /****************************************************************************/
7310 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
7311 desc = "LAN: Device not Found";
7314 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
7315 desc = "LAN: Device Failure";
7318 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
7319 desc = "LAN: Transmit Error";
7322 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
7323 desc = "LAN: Transmit Aborted";
7326 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
7327 desc = "LAN: Receive Error";
7330 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
7331 desc = "LAN: Receive Aborted";
7334 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
7335 desc = "LAN: Partial Packet";
7338 case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
7339 desc = "LAN: Canceled";
7342 /****************************************************************************/
7343 /* Serial Attached SCSI values */
7344 /****************************************************************************/
7346 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
7347 desc = "SAS: SMP Request Failed";
7350 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
7351 desc = "SAS: SMP Data Overrun";
7362 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s\n",
7363 ioc->name, status, desc));
7366 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7367 EXPORT_SYMBOL(mpt_attach);
7368 EXPORT_SYMBOL(mpt_detach);
7370 EXPORT_SYMBOL(mpt_resume);
7371 EXPORT_SYMBOL(mpt_suspend);
7373 EXPORT_SYMBOL(ioc_list);
7374 EXPORT_SYMBOL(mpt_proc_root_dir);
7375 EXPORT_SYMBOL(mpt_register);
7376 EXPORT_SYMBOL(mpt_deregister);
7377 EXPORT_SYMBOL(mpt_event_register);
7378 EXPORT_SYMBOL(mpt_event_deregister);
7379 EXPORT_SYMBOL(mpt_reset_register);
7380 EXPORT_SYMBOL(mpt_reset_deregister);
7381 EXPORT_SYMBOL(mpt_device_driver_register);
7382 EXPORT_SYMBOL(mpt_device_driver_deregister);
7383 EXPORT_SYMBOL(mpt_get_msg_frame);
7384 EXPORT_SYMBOL(mpt_put_msg_frame);
7385 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri);
7386 EXPORT_SYMBOL(mpt_free_msg_frame);
7387 EXPORT_SYMBOL(mpt_add_sge);
7388 EXPORT_SYMBOL(mpt_send_handshake_request);
7389 EXPORT_SYMBOL(mpt_verify_adapter);
7390 EXPORT_SYMBOL(mpt_GetIocState);
7391 EXPORT_SYMBOL(mpt_print_ioc_summary);
7392 EXPORT_SYMBOL(mpt_HardResetHandler);
7393 EXPORT_SYMBOL(mpt_config);
7394 EXPORT_SYMBOL(mpt_findImVolumes);
7395 EXPORT_SYMBOL(mpt_alloc_fw_memory);
7396 EXPORT_SYMBOL(mpt_free_fw_memory);
7397 EXPORT_SYMBOL(mptbase_sas_persist_operation);
7398 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
7400 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7402 * fusion_init - Fusion MPT base driver initialization routine.
7404 * Returns 0 for success, non-zero for failure.
7411 show_mptmod_ver(my_NAME, my_VERSION);
7412 printk(KERN_INFO COPYRIGHT "\n");
7414 for (cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
7415 MptCallbacks[cb_idx] = NULL;
7416 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
7417 MptEvHandlers[cb_idx] = NULL;
7418 MptResetHandlers[cb_idx] = NULL;
7421 /* Register ourselves (mptbase) in order to facilitate
7422 * EventNotification handling.
7424 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
7426 /* Register for hard reset handling callbacks.
7428 mpt_reset_register(mpt_base_index, mpt_ioc_reset);
7430 #ifdef CONFIG_PROC_FS
7431 (void) procmpt_create();
7436 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7438 * fusion_exit - Perform driver unload cleanup.
7440 * This routine frees all resources associated with each MPT adapter
7441 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
7447 mpt_reset_deregister(mpt_base_index);
7449 #ifdef CONFIG_PROC_FS
7454 module_init(fusion_init);
7455 module_exit(fusion_exit);