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 handler.
636 * @cb_idx: previously registered (via mpt_register) callback handle
637 * @ev_cbfunc: callback function
639 * This routine can be called by one or more protocol-specific drivers
640 * if/when they choose to be notified of MPT events.
642 * Returns 0 for success.
645 mpt_event_register(u8 cb_idx
, MPT_EVHANDLER ev_cbfunc
)
647 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
650 MptEvHandlers
[cb_idx
] = ev_cbfunc
;
654 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
656 * mpt_event_deregister - Deregister protocol-specific event callback handler
657 * @cb_idx: previously registered callback handle
659 * Each protocol-specific driver should call this routine
660 * when it does not (or can no longer) handle events,
661 * or when its module is unloaded.
664 mpt_event_deregister(u8 cb_idx
)
666 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
669 MptEvHandlers
[cb_idx
] = NULL
;
672 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
674 * mpt_reset_register - Register protocol-specific IOC reset handler.
675 * @cb_idx: previously registered (via mpt_register) callback handle
676 * @reset_func: reset function
678 * This routine can be called by one or more protocol-specific drivers
679 * if/when they choose to be notified of IOC resets.
681 * Returns 0 for success.
684 mpt_reset_register(u8 cb_idx
, MPT_RESETHANDLER reset_func
)
686 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
689 MptResetHandlers
[cb_idx
] = reset_func
;
693 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
695 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
696 * @cb_idx: previously registered callback handle
698 * Each protocol-specific driver should call this routine
699 * when it does not (or can no longer) handle IOC reset handling,
700 * or when its module is unloaded.
703 mpt_reset_deregister(u8 cb_idx
)
705 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
708 MptResetHandlers
[cb_idx
] = NULL
;
711 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
713 * mpt_device_driver_register - Register device driver hooks
714 * @dd_cbfunc: driver callbacks struct
715 * @cb_idx: MPT protocol driver index
718 mpt_device_driver_register(struct mpt_pci_driver
* dd_cbfunc
, u8 cb_idx
)
721 const struct pci_device_id
*id
;
723 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
726 MptDeviceDriverHandlers
[cb_idx
] = dd_cbfunc
;
728 /* call per pci device probe entry point */
729 list_for_each_entry(ioc
, &ioc_list
, list
) {
730 id
= ioc
->pcidev
->driver
?
731 ioc
->pcidev
->driver
->id_table
: NULL
;
732 if (dd_cbfunc
->probe
)
733 dd_cbfunc
->probe(ioc
->pcidev
, id
);
739 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
741 * mpt_device_driver_deregister - DeRegister device driver hooks
742 * @cb_idx: MPT protocol driver index
745 mpt_device_driver_deregister(u8 cb_idx
)
747 struct mpt_pci_driver
*dd_cbfunc
;
750 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
753 dd_cbfunc
= MptDeviceDriverHandlers
[cb_idx
];
755 list_for_each_entry(ioc
, &ioc_list
, list
) {
756 if (dd_cbfunc
->remove
)
757 dd_cbfunc
->remove(ioc
->pcidev
);
760 MptDeviceDriverHandlers
[cb_idx
] = NULL
;
764 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
766 * mpt_get_msg_frame - Obtain an MPT request frame from the pool
767 * @cb_idx: Handle of registered MPT protocol driver
768 * @ioc: Pointer to MPT adapter structure
770 * Obtain an MPT request frame from the pool (of 1024) that are
771 * allocated per MPT adapter.
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 to an IOC
838 * @cb_idx: Handle of registered MPT protocol driver
839 * @ioc: Pointer to MPT adapter structure
840 * @mf: Pointer to MPT request frame
842 * This routine posts an MPT request frame to the request post FIFO of a
843 * specific MPT adapter.
846 mpt_put_msg_frame(u8 cb_idx
, MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
)
850 u16 req_idx
; /* Request index */
852 /* ensure values are reset properly! */
853 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= cb_idx
; /* byte */
854 req_offset
= (u8
*)mf
- (u8
*)ioc
->req_frames
;
856 req_idx
= req_offset
/ ioc
->req_sz
;
857 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(req_idx
);
858 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.rsvd
= 0;
860 DBG_DUMP_PUT_MSG_FRAME(ioc
, (u32
*)mf
);
862 mf_dma_addr
= (ioc
->req_frames_low_dma
+ req_offset
) | ioc
->RequestNB
[req_idx
];
863 dsgprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mf_dma_addr=%x req_idx=%d "
864 "RequestNB=%x\n", ioc
->name
, mf_dma_addr
, req_idx
,
865 ioc
->RequestNB
[req_idx
]));
866 CHIPREG_WRITE32(&ioc
->chip
->RequestFifo
, mf_dma_addr
);
870 * mpt_put_msg_frame_hi_pri - Send a hi-pri protocol-specific MPT request frame
871 * @cb_idx: Handle of registered MPT protocol driver
872 * @ioc: Pointer to MPT adapter structure
873 * @mf: Pointer to MPT request frame
875 * Send a protocol-specific MPT request frame to an IOC using
876 * hi-priority request queue.
878 * This routine posts an MPT request frame to the request post FIFO of a
879 * specific MPT adapter.
882 mpt_put_msg_frame_hi_pri(u8 cb_idx
, MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
)
886 u16 req_idx
; /* Request index */
888 /* ensure values are reset properly! */
889 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= cb_idx
;
890 req_offset
= (u8
*)mf
- (u8
*)ioc
->req_frames
;
891 req_idx
= req_offset
/ ioc
->req_sz
;
892 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(req_idx
);
893 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.rsvd
= 0;
895 DBG_DUMP_PUT_MSG_FRAME(ioc
, (u32
*)mf
);
897 mf_dma_addr
= (ioc
->req_frames_low_dma
+ req_offset
);
898 dsgprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mf_dma_addr=%x req_idx=%d\n",
899 ioc
->name
, mf_dma_addr
, req_idx
));
900 CHIPREG_WRITE32(&ioc
->chip
->RequestHiPriFifo
, mf_dma_addr
);
903 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
905 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
906 * @handle: Handle of registered MPT protocol driver
907 * @ioc: Pointer to MPT adapter structure
908 * @mf: Pointer to MPT request frame
910 * This routine places a MPT request frame back on the MPT adapter's
914 mpt_free_msg_frame(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
)
918 /* Put Request back on FreeQ! */
919 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
920 mf
->u
.frame
.linkage
.arg1
= 0xdeadbeaf; /* signature to know if this mf is freed */
921 list_add_tail(&mf
->u
.frame
.linkage
.list
, &ioc
->FreeQ
);
925 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
928 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
930 * mpt_add_sge - Place a simple SGE at address pAddr.
931 * @pAddr: virtual address for SGE
932 * @flagslength: SGE flags and data transfer length
933 * @dma_addr: Physical address
935 * This routine places a MPT request frame back on the MPT adapter's
939 mpt_add_sge(char *pAddr
, u32 flagslength
, dma_addr_t dma_addr
)
941 if (sizeof(dma_addr_t
) == sizeof(u64
)) {
942 SGESimple64_t
*pSge
= (SGESimple64_t
*) pAddr
;
943 u32 tmp
= dma_addr
& 0xFFFFFFFF;
945 pSge
->FlagsLength
= cpu_to_le32(flagslength
);
946 pSge
->Address
.Low
= cpu_to_le32(tmp
);
947 tmp
= (u32
) ((u64
)dma_addr
>> 32);
948 pSge
->Address
.High
= cpu_to_le32(tmp
);
951 SGESimple32_t
*pSge
= (SGESimple32_t
*) pAddr
;
952 pSge
->FlagsLength
= cpu_to_le32(flagslength
);
953 pSge
->Address
= cpu_to_le32(dma_addr
);
957 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
959 * mpt_send_handshake_request - Send MPT request via doorbell handshake method.
960 * @cb_idx: Handle of registered MPT protocol driver
961 * @ioc: Pointer to MPT adapter structure
962 * @reqBytes: Size of the request in bytes
963 * @req: Pointer to MPT request frame
964 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
966 * This routine is used exclusively to send MptScsiTaskMgmt
967 * requests since they are required to be sent via doorbell handshake.
969 * NOTE: It is the callers responsibility to byte-swap fields in the
970 * request which are greater than 1 byte in size.
972 * Returns 0 for success, non-zero for failure.
975 mpt_send_handshake_request(u8 cb_idx
, MPT_ADAPTER
*ioc
, int reqBytes
, u32
*req
, int sleepFlag
)
981 /* State is known to be good upon entering
982 * this function so issue the bus reset
987 * Emulate what mpt_put_msg_frame() does /wrt to sanity
988 * setting cb_idx/req_idx. But ONLY if this request
989 * is in proper (pre-alloc'd) request buffer range...
991 ii
= MFPTR_2_MPT_INDEX(ioc
,(MPT_FRAME_HDR
*)req
);
992 if (reqBytes
>= 12 && ii
>= 0 && ii
< ioc
->req_depth
) {
993 MPT_FRAME_HDR
*mf
= (MPT_FRAME_HDR
*)req
;
994 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(ii
);
995 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= cb_idx
;
998 /* Make sure there are no doorbells */
999 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1001 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
,
1002 ((MPI_FUNCTION_HANDSHAKE
<<MPI_DOORBELL_FUNCTION_SHIFT
) |
1003 ((reqBytes
/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT
)));
1005 /* Wait for IOC doorbell int */
1006 if ((ii
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0) {
1010 /* Read doorbell and check for active bit */
1011 if (!(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & MPI_DOORBELL_ACTIVE
))
1014 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mpt_send_handshake_request start, WaitCnt=%d\n",
1017 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1019 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0) {
1023 /* Send request via doorbell handshake */
1024 req_as_bytes
= (u8
*) req
;
1025 for (ii
= 0; ii
< reqBytes
/4; ii
++) {
1028 word
= ((req_as_bytes
[(ii
*4) + 0] << 0) |
1029 (req_as_bytes
[(ii
*4) + 1] << 8) |
1030 (req_as_bytes
[(ii
*4) + 2] << 16) |
1031 (req_as_bytes
[(ii
*4) + 3] << 24));
1032 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, word
);
1033 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0) {
1039 if (r
>= 0 && WaitForDoorbellInt(ioc
, 10, sleepFlag
) >= 0)
1044 /* Make sure there are no doorbells */
1045 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1050 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1052 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
1053 * @ioc: Pointer to MPT adapter structure
1054 * @access_control_value: define bits below
1055 * @sleepFlag: Specifies whether the process can sleep
1057 * Provides mechanism for the host driver to control the IOC's
1058 * Host Page Buffer access.
1060 * Access Control Value - bits[15:12]
1062 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1063 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1064 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1066 * Returns 0 for success, non-zero for failure.
1070 mpt_host_page_access_control(MPT_ADAPTER
*ioc
, u8 access_control_value
, int sleepFlag
)
1074 /* return if in use */
1075 if (CHIPREG_READ32(&ioc
->chip
->Doorbell
)
1076 & MPI_DOORBELL_ACTIVE
)
1079 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1081 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
,
1082 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1083 <<MPI_DOORBELL_FUNCTION_SHIFT
) |
1084 (access_control_value
<<12)));
1086 /* Wait for IOC to clear Doorbell Status bit */
1087 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0) {
1093 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1095 * mpt_host_page_alloc - allocate system memory for the fw
1096 * @ioc: Pointer to pointer to IOC adapter
1097 * @ioc_init: Pointer to ioc init config page
1099 * If we already allocated memory in past, then resend the same pointer.
1100 * Returns 0 for success, non-zero for failure.
1103 mpt_host_page_alloc(MPT_ADAPTER
*ioc
, pIOCInit_t ioc_init
)
1107 u32 host_page_buffer_sz
=0;
1109 if(!ioc
->HostPageBuffer
) {
1111 host_page_buffer_sz
=
1112 le32_to_cpu(ioc
->facts
.HostPageBufferSGE
.FlagsLength
) & 0xFFFFFF;
1114 if(!host_page_buffer_sz
)
1115 return 0; /* fw doesn't need any host buffers */
1117 /* spin till we get enough memory */
1118 while(host_page_buffer_sz
> 0) {
1120 if((ioc
->HostPageBuffer
= pci_alloc_consistent(
1122 host_page_buffer_sz
,
1123 &ioc
->HostPageBuffer_dma
)) != NULL
) {
1125 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
1126 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1127 ioc
->name
, ioc
->HostPageBuffer
,
1128 (u32
)ioc
->HostPageBuffer_dma
,
1129 host_page_buffer_sz
));
1130 ioc
->alloc_total
+= host_page_buffer_sz
;
1131 ioc
->HostPageBuffer_sz
= host_page_buffer_sz
;
1135 host_page_buffer_sz
-= (4*1024);
1139 if(!ioc
->HostPageBuffer
) {
1140 printk(MYIOC_s_ERR_FMT
1141 "Failed to alloc memory for host_page_buffer!\n",
1146 psge
= (char *)&ioc_init
->HostPageBufferSGE
;
1147 flags_length
= MPI_SGE_FLAGS_SIMPLE_ELEMENT
|
1148 MPI_SGE_FLAGS_SYSTEM_ADDRESS
|
1149 MPI_SGE_FLAGS_32_BIT_ADDRESSING
|
1150 MPI_SGE_FLAGS_HOST_TO_IOC
|
1151 MPI_SGE_FLAGS_END_OF_BUFFER
;
1152 if (sizeof(dma_addr_t
) == sizeof(u64
)) {
1153 flags_length
|= MPI_SGE_FLAGS_64_BIT_ADDRESSING
;
1155 flags_length
= flags_length
<< MPI_SGE_FLAGS_SHIFT
;
1156 flags_length
|= ioc
->HostPageBuffer_sz
;
1157 mpt_add_sge(psge
, flags_length
, ioc
->HostPageBuffer_dma
);
1158 ioc
->facts
.HostPageBufferSGE
= ioc_init
->HostPageBufferSGE
;
1163 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1165 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1166 * @iocid: IOC unique identifier (integer)
1167 * @iocpp: Pointer to pointer to IOC adapter
1169 * Given a unique IOC identifier, set pointer to the associated MPT
1170 * adapter structure.
1172 * Returns iocid and sets iocpp if iocid is found.
1173 * Returns -1 if iocid is not found.
1176 mpt_verify_adapter(int iocid
, MPT_ADAPTER
**iocpp
)
1180 list_for_each_entry(ioc
,&ioc_list
,list
) {
1181 if (ioc
->id
== iocid
) {
1192 * mpt_get_product_name - returns product string
1193 * @vendor: pci vendor id
1194 * @device: pci device id
1195 * @revision: pci revision id
1196 * @prod_name: string returned
1198 * Returns product string displayed when driver loads,
1199 * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1203 mpt_get_product_name(u16 vendor
, u16 device
, u8 revision
, char *prod_name
)
1205 char *product_str
= NULL
;
1207 if (vendor
== PCI_VENDOR_ID_BROCADE
) {
1210 case MPI_MANUFACTPAGE_DEVICEID_FC949E
:
1214 product_str
= "BRE040 A0";
1217 product_str
= "BRE040 A1";
1220 product_str
= "BRE040";
1230 case MPI_MANUFACTPAGE_DEVICEID_FC909
:
1231 product_str
= "LSIFC909 B1";
1233 case MPI_MANUFACTPAGE_DEVICEID_FC919
:
1234 product_str
= "LSIFC919 B0";
1236 case MPI_MANUFACTPAGE_DEVICEID_FC929
:
1237 product_str
= "LSIFC929 B0";
1239 case MPI_MANUFACTPAGE_DEVICEID_FC919X
:
1240 if (revision
< 0x80)
1241 product_str
= "LSIFC919X A0";
1243 product_str
= "LSIFC919XL A1";
1245 case MPI_MANUFACTPAGE_DEVICEID_FC929X
:
1246 if (revision
< 0x80)
1247 product_str
= "LSIFC929X A0";
1249 product_str
= "LSIFC929XL A1";
1251 case MPI_MANUFACTPAGE_DEVICEID_FC939X
:
1252 product_str
= "LSIFC939X A1";
1254 case MPI_MANUFACTPAGE_DEVICEID_FC949X
:
1255 product_str
= "LSIFC949X A1";
1257 case MPI_MANUFACTPAGE_DEVICEID_FC949E
:
1261 product_str
= "LSIFC949E A0";
1264 product_str
= "LSIFC949E A1";
1267 product_str
= "LSIFC949E";
1271 case MPI_MANUFACTPAGE_DEVID_53C1030
:
1275 product_str
= "LSI53C1030 A0";
1278 product_str
= "LSI53C1030 B0";
1281 product_str
= "LSI53C1030 B1";
1284 product_str
= "LSI53C1030 B2";
1287 product_str
= "LSI53C1030 C0";
1290 product_str
= "LSI53C1030T A0";
1293 product_str
= "LSI53C1030T A2";
1296 product_str
= "LSI53C1030T A3";
1299 product_str
= "LSI53C1020A A1";
1302 product_str
= "LSI53C1030";
1306 case MPI_MANUFACTPAGE_DEVID_1030_53C1035
:
1310 product_str
= "LSI53C1035 A2";
1313 product_str
= "LSI53C1035 B0";
1316 product_str
= "LSI53C1035";
1320 case MPI_MANUFACTPAGE_DEVID_SAS1064
:
1324 product_str
= "LSISAS1064 A1";
1327 product_str
= "LSISAS1064 A2";
1330 product_str
= "LSISAS1064 A3";
1333 product_str
= "LSISAS1064 A4";
1336 product_str
= "LSISAS1064";
1340 case MPI_MANUFACTPAGE_DEVID_SAS1064E
:
1344 product_str
= "LSISAS1064E A0";
1347 product_str
= "LSISAS1064E B0";
1350 product_str
= "LSISAS1064E B1";
1353 product_str
= "LSISAS1064E B2";
1356 product_str
= "LSISAS1064E B3";
1359 product_str
= "LSISAS1064E";
1363 case MPI_MANUFACTPAGE_DEVID_SAS1068
:
1367 product_str
= "LSISAS1068 A0";
1370 product_str
= "LSISAS1068 B0";
1373 product_str
= "LSISAS1068 B1";
1376 product_str
= "LSISAS1068";
1380 case MPI_MANUFACTPAGE_DEVID_SAS1068E
:
1384 product_str
= "LSISAS1068E A0";
1387 product_str
= "LSISAS1068E B0";
1390 product_str
= "LSISAS1068E B1";
1393 product_str
= "LSISAS1068E B2";
1396 product_str
= "LSISAS1068E B3";
1399 product_str
= "LSISAS1068E";
1403 case MPI_MANUFACTPAGE_DEVID_SAS1078
:
1407 product_str
= "LSISAS1078 A0";
1410 product_str
= "LSISAS1078 B0";
1413 product_str
= "LSISAS1078 C0";
1416 product_str
= "LSISAS1078 C1";
1419 product_str
= "LSISAS1078 C2";
1422 product_str
= "LSISAS1078";
1430 sprintf(prod_name
, "%s", product_str
);
1434 * mpt_mapresources - map in memory mapped io
1435 * @ioc: Pointer to pointer to IOC adapter
1439 mpt_mapresources(MPT_ADAPTER
*ioc
)
1443 unsigned long mem_phys
;
1449 struct pci_dev
*pdev
;
1452 ioc
->bars
= pci_select_bars(pdev
, IORESOURCE_MEM
);
1453 if (pci_enable_device_mem(pdev
)) {
1454 printk(MYIOC_s_ERR_FMT
"pci_enable_device_mem() "
1455 "failed\n", ioc
->name
);
1458 if (pci_request_selected_regions(pdev
, ioc
->bars
, "mpt")) {
1459 printk(MYIOC_s_ERR_FMT
"pci_request_selected_regions() with "
1460 "MEM failed\n", ioc
->name
);
1464 pci_read_config_byte(pdev
, PCI_CLASS_REVISION
, &revision
);
1466 if (!pci_set_dma_mask(pdev
, DMA_64BIT_MASK
)
1467 && !pci_set_consistent_dma_mask(pdev
, DMA_64BIT_MASK
)) {
1468 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
1469 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1471 } else if (!pci_set_dma_mask(pdev
, DMA_32BIT_MASK
)
1472 && !pci_set_consistent_dma_mask(pdev
, DMA_32BIT_MASK
)) {
1473 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
1474 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1477 printk(MYIOC_s_WARN_FMT
"no suitable DMA mask for %s\n",
1478 ioc
->name
, pci_name(pdev
));
1479 pci_release_selected_regions(pdev
, ioc
->bars
);
1483 mem_phys
= msize
= 0;
1485 for (ii
= 0; ii
< DEVICE_COUNT_RESOURCE
; ii
++) {
1486 if (pci_resource_flags(pdev
, ii
) & PCI_BASE_ADDRESS_SPACE_IO
) {
1489 /* Get I/O space! */
1490 port
= pci_resource_start(pdev
, ii
);
1491 psize
= pci_resource_len(pdev
, ii
);
1496 mem_phys
= pci_resource_start(pdev
, ii
);
1497 msize
= pci_resource_len(pdev
, ii
);
1500 ioc
->mem_size
= msize
;
1503 /* Get logical ptr for PciMem0 space */
1504 /*mem = ioremap(mem_phys, msize);*/
1505 mem
= ioremap(mem_phys
, msize
);
1507 printk(MYIOC_s_ERR_FMT
": ERROR - Unable to map adapter"
1508 " memory!\n", ioc
->name
);
1512 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"mem = %p, mem_phys = %lx\n",
1513 ioc
->name
, mem
, mem_phys
));
1515 ioc
->mem_phys
= mem_phys
;
1516 ioc
->chip
= (SYSIF_REGS __iomem
*)mem
;
1518 /* Save Port IO values in case we need to do downloadboot */
1519 ioc
->pio_mem_phys
= port
;
1520 ioc
->pio_chip
= (SYSIF_REGS __iomem
*)port
;
1525 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1527 * mpt_attach - Install a PCI intelligent MPT adapter.
1528 * @pdev: Pointer to pci_dev structure
1529 * @id: PCI device ID information
1531 * This routine performs all the steps necessary to bring the IOC of
1532 * a MPT adapter to a OPERATIONAL state. This includes registering
1533 * memory regions, registering the interrupt, and allocating request
1534 * and reply memory pools.
1536 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1539 * Returns 0 for success, non-zero for failure.
1541 * TODO: Add support for polled controllers
1544 mpt_attach(struct pci_dev
*pdev
, const struct pci_device_id
*id
)
1551 static int mpt_ids
= 0;
1552 #ifdef CONFIG_PROC_FS
1553 struct proc_dir_entry
*dent
, *ent
;
1556 ioc
= kzalloc(sizeof(MPT_ADAPTER
), GFP_ATOMIC
);
1558 printk(KERN_ERR MYNAM
": ERROR - Insufficient memory to add adapter!\n");
1562 ioc
->id
= mpt_ids
++;
1563 sprintf(ioc
->name
, "ioc%d", ioc
->id
);
1566 * set initial debug level
1567 * (refer to mptdebug.h)
1570 ioc
->debug_level
= mpt_debug_level
;
1571 if (mpt_debug_level
)
1572 printk(KERN_INFO
"mpt_debug_level=%xh\n", mpt_debug_level
);
1574 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
": mpt_adapter_install\n", ioc
->name
));
1577 if (mpt_mapresources(ioc
)) {
1582 ioc
->alloc_total
= sizeof(MPT_ADAPTER
);
1583 ioc
->req_sz
= MPT_DEFAULT_FRAME_SIZE
; /* avoid div by zero! */
1584 ioc
->reply_sz
= MPT_REPLY_FRAME_SIZE
;
1587 ioc
->diagPending
= 0;
1588 spin_lock_init(&ioc
->diagLock
);
1589 spin_lock_init(&ioc
->initializing_hba_lock
);
1591 /* Initialize the event logging.
1593 ioc
->eventTypes
= 0; /* None */
1594 ioc
->eventContext
= 0;
1595 ioc
->eventLogSize
= 0;
1602 ioc
->cached_fw
= NULL
;
1604 /* Initilize SCSI Config Data structure
1606 memset(&ioc
->spi_data
, 0, sizeof(SpiCfgData
));
1608 /* Initialize the running configQ head.
1610 INIT_LIST_HEAD(&ioc
->configQ
);
1612 /* Initialize the fc rport list head.
1614 INIT_LIST_HEAD(&ioc
->fc_rports
);
1616 /* Find lookup slot. */
1617 INIT_LIST_HEAD(&ioc
->list
);
1619 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"facts @ %p, pfacts[0] @ %p\n",
1620 ioc
->name
, &ioc
->facts
, &ioc
->pfacts
[0]));
1622 pci_read_config_byte(pdev
, PCI_CLASS_REVISION
, &revision
);
1623 mpt_get_product_name(pdev
->vendor
, pdev
->device
, revision
, ioc
->prod_name
);
1625 switch (pdev
->device
)
1627 case MPI_MANUFACTPAGE_DEVICEID_FC939X
:
1628 case MPI_MANUFACTPAGE_DEVICEID_FC949X
:
1629 ioc
->errata_flag_1064
= 1;
1630 case MPI_MANUFACTPAGE_DEVICEID_FC909
:
1631 case MPI_MANUFACTPAGE_DEVICEID_FC929
:
1632 case MPI_MANUFACTPAGE_DEVICEID_FC919
:
1633 case MPI_MANUFACTPAGE_DEVICEID_FC949E
:
1637 case MPI_MANUFACTPAGE_DEVICEID_FC929X
:
1638 if (revision
< XL_929
) {
1639 /* 929X Chip Fix. Set Split transactions level
1640 * for PCIX. Set MOST bits to zero.
1642 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1644 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1646 /* 929XL Chip Fix. Set MMRBC to 0x08.
1648 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1650 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1655 case MPI_MANUFACTPAGE_DEVICEID_FC919X
:
1656 /* 919X Chip Fix. Set Split transactions level
1657 * for PCIX. Set MOST bits to zero.
1659 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1661 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1665 case MPI_MANUFACTPAGE_DEVID_53C1030
:
1666 /* 1030 Chip Fix. Disable Split transactions
1667 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1669 if (revision
< C0_1030
) {
1670 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1672 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1675 case MPI_MANUFACTPAGE_DEVID_1030_53C1035
:
1676 ioc
->bus_type
= SPI
;
1679 case MPI_MANUFACTPAGE_DEVID_SAS1064
:
1680 case MPI_MANUFACTPAGE_DEVID_SAS1068
:
1681 ioc
->errata_flag_1064
= 1;
1683 case MPI_MANUFACTPAGE_DEVID_SAS1064E
:
1684 case MPI_MANUFACTPAGE_DEVID_SAS1068E
:
1685 case MPI_MANUFACTPAGE_DEVID_SAS1078
:
1686 ioc
->bus_type
= SAS
;
1689 if (ioc
->errata_flag_1064
)
1690 pci_disable_io_access(pdev
);
1692 spin_lock_init(&ioc
->FreeQlock
);
1695 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
1697 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1699 /* Set IOC ptr in the pcidev's driver data. */
1700 pci_set_drvdata(ioc
->pcidev
, ioc
);
1702 /* Set lookup ptr. */
1703 list_add_tail(&ioc
->list
, &ioc_list
);
1705 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1707 mpt_detect_bound_ports(ioc
, pdev
);
1709 if ((r
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_BRINGUP
,
1711 printk(MYIOC_s_ERR_FMT
"didn't initialize properly! (%d)\n",
1714 list_del(&ioc
->list
);
1716 ioc
->alt_ioc
->alt_ioc
= NULL
;
1717 iounmap(ioc
->memmap
);
1719 pci_release_selected_regions(pdev
, ioc
->bars
);
1721 pci_set_drvdata(pdev
, NULL
);
1725 /* call per device driver probe entry point */
1726 for(cb_idx
= 0; cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
; cb_idx
++) {
1727 if(MptDeviceDriverHandlers
[cb_idx
] &&
1728 MptDeviceDriverHandlers
[cb_idx
]->probe
) {
1729 MptDeviceDriverHandlers
[cb_idx
]->probe(pdev
,id
);
1733 #ifdef CONFIG_PROC_FS
1735 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1737 dent
= proc_mkdir(ioc
->name
, mpt_proc_root_dir
);
1739 ent
= create_proc_entry("info", S_IFREG
|S_IRUGO
, dent
);
1741 ent
->read_proc
= procmpt_iocinfo_read
;
1744 ent
= create_proc_entry("summary", S_IFREG
|S_IRUGO
, dent
);
1746 ent
->read_proc
= procmpt_summary_read
;
1755 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1757 * mpt_detach - Remove a PCI intelligent MPT adapter.
1758 * @pdev: Pointer to pci_dev structure
1762 mpt_detach(struct pci_dev
*pdev
)
1764 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
1768 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s/summary", ioc
->name
);
1769 remove_proc_entry(pname
, NULL
);
1770 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s/info", ioc
->name
);
1771 remove_proc_entry(pname
, NULL
);
1772 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s", ioc
->name
);
1773 remove_proc_entry(pname
, NULL
);
1775 /* call per device driver remove entry point */
1776 for(cb_idx
= 0; cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
; cb_idx
++) {
1777 if(MptDeviceDriverHandlers
[cb_idx
] &&
1778 MptDeviceDriverHandlers
[cb_idx
]->remove
) {
1779 MptDeviceDriverHandlers
[cb_idx
]->remove(pdev
);
1783 /* Disable interrupts! */
1784 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
1787 synchronize_irq(pdev
->irq
);
1789 /* Clear any lingering interrupt */
1790 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1792 CHIPREG_READ32(&ioc
->chip
->IntStatus
);
1794 mpt_adapter_dispose(ioc
);
1796 pci_set_drvdata(pdev
, NULL
);
1799 /**************************************************************************
1803 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1805 * mpt_suspend - Fusion MPT base driver suspend routine.
1806 * @pdev: Pointer to pci_dev structure
1807 * @state: new state to enter
1810 mpt_suspend(struct pci_dev
*pdev
, pm_message_t state
)
1813 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
1815 device_state
= pci_choose_state(pdev
, state
);
1816 printk(MYIOC_s_INFO_FMT
"pci-suspend: pdev=0x%p, slot=%s, Entering "
1817 "operating state [D%d]\n", ioc
->name
, pdev
, pci_name(pdev
),
1820 /* put ioc into READY_STATE */
1821 if(SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, CAN_SLEEP
)) {
1822 printk(MYIOC_s_ERR_FMT
1823 "pci-suspend: IOC msg unit reset failed!\n", ioc
->name
);
1826 /* disable interrupts */
1827 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
1830 /* Clear any lingering interrupt */
1831 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1833 free_irq(ioc
->pci_irq
, ioc
);
1835 pci_disable_msi(ioc
->pcidev
);
1837 pci_save_state(pdev
);
1838 pci_disable_device(pdev
);
1839 pci_release_selected_regions(pdev
, ioc
->bars
);
1840 pci_set_power_state(pdev
, device_state
);
1844 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1846 * mpt_resume - Fusion MPT base driver resume routine.
1847 * @pdev: Pointer to pci_dev structure
1850 mpt_resume(struct pci_dev
*pdev
)
1852 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
1853 u32 device_state
= pdev
->current_state
;
1857 printk(MYIOC_s_INFO_FMT
"pci-resume: pdev=0x%p, slot=%s, Previous "
1858 "operating state [D%d]\n", ioc
->name
, pdev
, pci_name(pdev
),
1861 pci_set_power_state(pdev
, PCI_D0
);
1862 pci_enable_wake(pdev
, PCI_D0
, 0);
1863 pci_restore_state(pdev
);
1865 err
= mpt_mapresources(ioc
);
1869 printk(MYIOC_s_INFO_FMT
"pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1870 ioc
->name
, (mpt_GetIocState(ioc
, 1) >> MPI_IOC_STATE_SHIFT
),
1871 CHIPREG_READ32(&ioc
->chip
->Doorbell
));
1874 * Errata workaround for SAS pci express:
1875 * Upon returning to the D0 state, the contents of the doorbell will be
1876 * stale data, and this will incorrectly signal to the host driver that
1877 * the firmware is ready to process mpt commands. The workaround is
1878 * to issue a diagnostic reset.
1880 if (ioc
->bus_type
== SAS
&& (pdev
->device
==
1881 MPI_MANUFACTPAGE_DEVID_SAS1068E
|| pdev
->device
==
1882 MPI_MANUFACTPAGE_DEVID_SAS1064E
)) {
1883 if (KickStart(ioc
, 1, CAN_SLEEP
) < 0) {
1884 printk(MYIOC_s_WARN_FMT
"pci-resume: Cannot recover\n",
1890 /* bring ioc to operational state */
1891 printk(MYIOC_s_INFO_FMT
"Sending mpt_do_ioc_recovery\n", ioc
->name
);
1892 recovery_state
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_BRINGUP
,
1894 if (recovery_state
!= 0)
1895 printk(MYIOC_s_WARN_FMT
"pci-resume: Cannot recover, "
1896 "error:[%x]\n", ioc
->name
, recovery_state
);
1898 printk(MYIOC_s_INFO_FMT
1899 "pci-resume: success\n", ioc
->name
);
1907 mpt_signal_reset(u8 index
, MPT_ADAPTER
*ioc
, int reset_phase
)
1909 if ((MptDriverClass
[index
] == MPTSPI_DRIVER
&&
1910 ioc
->bus_type
!= SPI
) ||
1911 (MptDriverClass
[index
] == MPTFC_DRIVER
&&
1912 ioc
->bus_type
!= FC
) ||
1913 (MptDriverClass
[index
] == MPTSAS_DRIVER
&&
1914 ioc
->bus_type
!= SAS
))
1915 /* make sure we only call the relevant reset handler
1918 return (MptResetHandlers
[index
])(ioc
, reset_phase
);
1921 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1923 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1924 * @ioc: Pointer to MPT adapter structure
1925 * @reason: Event word / reason
1926 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1928 * This routine performs all the steps necessary to bring the IOC
1929 * to a OPERATIONAL state.
1931 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1936 * -1 if failed to get board READY
1937 * -2 if READY but IOCFacts Failed
1938 * -3 if READY but PrimeIOCFifos Failed
1939 * -4 if READY but IOCInit Failed
1940 * -5 if failed to enable_device and/or request_selected_regions
1941 * -6 if failed to upload firmware
1944 mpt_do_ioc_recovery(MPT_ADAPTER
*ioc
, u32 reason
, int sleepFlag
)
1946 int hard_reset_done
= 0;
1947 int alt_ioc_ready
= 0;
1954 int reset_alt_ioc_active
= 0;
1955 int irq_allocated
= 0;
1958 printk(MYIOC_s_INFO_FMT
"Initiating %s\n", ioc
->name
,
1959 reason
== MPT_HOSTEVENT_IOC_BRINGUP
? "bringup" : "recovery");
1961 /* Disable reply interrupts (also blocks FreeQ) */
1962 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
1966 if (ioc
->alt_ioc
->active
)
1967 reset_alt_ioc_active
= 1;
1969 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1970 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
, 0xFFFFFFFF);
1971 ioc
->alt_ioc
->active
= 0;
1975 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)
1978 if ((hard_reset_done
= MakeIocReady(ioc
, hard
, sleepFlag
)) < 0) {
1979 if (hard_reset_done
== -4) {
1980 printk(MYIOC_s_WARN_FMT
"Owned by PEER..skipping!\n",
1983 if (reset_alt_ioc_active
&& ioc
->alt_ioc
) {
1984 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1985 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
1986 "alt_ioc reply irq re-enabled\n", ioc
->alt_ioc
->name
));
1987 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
, MPI_HIM_DIM
);
1988 ioc
->alt_ioc
->active
= 1;
1992 printk(MYIOC_s_WARN_FMT
"NOT READY!\n", ioc
->name
);
1997 /* hard_reset_done = 0 if a soft reset was performed
1998 * and 1 if a hard reset was performed.
2000 if (hard_reset_done
&& reset_alt_ioc_active
&& ioc
->alt_ioc
) {
2001 if ((rc
= MakeIocReady(ioc
->alt_ioc
, 0, sleepFlag
)) == 0)
2004 printk(MYIOC_s_WARN_FMT
"alt_ioc not ready!\n", ioc
->alt_ioc
->name
);
2007 for (ii
=0; ii
<5; ii
++) {
2008 /* Get IOC facts! Allow 5 retries */
2009 if ((rc
= GetIocFacts(ioc
, sleepFlag
, reason
)) == 0)
2015 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2016 "Retry IocFacts failed rc=%x\n", ioc
->name
, rc
));
2018 } else if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
2019 MptDisplayIocCapabilities(ioc
);
2022 if (alt_ioc_ready
) {
2023 if ((rc
= GetIocFacts(ioc
->alt_ioc
, sleepFlag
, reason
)) != 0) {
2024 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2025 "Initial Alt IocFacts failed rc=%x\n", ioc
->name
, rc
));
2026 /* Retry - alt IOC was initialized once
2028 rc
= GetIocFacts(ioc
->alt_ioc
, sleepFlag
, reason
);
2031 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2032 "Retry Alt IocFacts failed rc=%x\n", ioc
->name
, rc
));
2034 reset_alt_ioc_active
= 0;
2035 } else if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
2036 MptDisplayIocCapabilities(ioc
->alt_ioc
);
2040 if ((ret
== 0) && (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) &&
2041 (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)) {
2042 pci_release_selected_regions(ioc
->pcidev
, ioc
->bars
);
2043 ioc
->bars
= pci_select_bars(ioc
->pcidev
, IORESOURCE_MEM
|
2045 if (pci_enable_device(ioc
->pcidev
))
2047 if (pci_request_selected_regions(ioc
->pcidev
, ioc
->bars
,
2053 * Device is reset now. It must have de-asserted the interrupt line
2054 * (if it was asserted) and it should be safe to register for the
2057 if ((ret
== 0) && (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)) {
2059 if (ioc
->pcidev
->irq
) {
2060 if (mpt_msi_enable
&& !pci_enable_msi(ioc
->pcidev
))
2061 printk(MYIOC_s_INFO_FMT
"PCI-MSI enabled\n",
2063 rc
= request_irq(ioc
->pcidev
->irq
, mpt_interrupt
,
2064 IRQF_SHARED
, ioc
->name
, ioc
);
2066 printk(MYIOC_s_ERR_FMT
"Unable to allocate "
2067 "interrupt %d!\n", ioc
->name
, ioc
->pcidev
->irq
);
2069 pci_disable_msi(ioc
->pcidev
);
2073 ioc
->pci_irq
= ioc
->pcidev
->irq
;
2074 pci_set_master(ioc
->pcidev
); /* ?? */
2075 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
"installed at interrupt "
2076 "%d\n", ioc
->name
, ioc
->pcidev
->irq
));
2080 /* Prime reply & request queues!
2081 * (mucho alloc's) Must be done prior to
2082 * init as upper addresses are needed for init.
2083 * If fails, continue with alt-ioc processing
2085 if ((ret
== 0) && ((rc
= PrimeIocFifos(ioc
)) != 0))
2088 /* May need to check/upload firmware & data here!
2089 * If fails, continue with alt-ioc processing
2091 if ((ret
== 0) && ((rc
= SendIocInit(ioc
, sleepFlag
)) != 0))
2094 if (alt_ioc_ready
&& ((rc
= PrimeIocFifos(ioc
->alt_ioc
)) != 0)) {
2095 printk(MYIOC_s_WARN_FMT
": alt_ioc (%d) FIFO mgmt alloc!\n",
2096 ioc
->alt_ioc
->name
, rc
);
2098 reset_alt_ioc_active
= 0;
2101 if (alt_ioc_ready
) {
2102 if ((rc
= SendIocInit(ioc
->alt_ioc
, sleepFlag
)) != 0) {
2104 reset_alt_ioc_active
= 0;
2105 printk(MYIOC_s_WARN_FMT
"alt_ioc (%d) init failure!\n",
2106 ioc
->alt_ioc
->name
, rc
);
2110 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
){
2111 if (ioc
->upload_fw
) {
2112 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2113 "firmware upload required!\n", ioc
->name
));
2115 /* Controller is not operational, cannot do upload
2118 rc
= mpt_do_upload(ioc
, sleepFlag
);
2120 if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
) {
2122 * Maintain only one pointer to FW memory
2123 * so there will not be two attempt to
2124 * downloadboot onboard dual function
2125 * chips (mpt_adapter_disable,
2128 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2129 "mpt_upload: alt_%s has cached_fw=%p \n",
2130 ioc
->name
, ioc
->alt_ioc
->name
, ioc
->alt_ioc
->cached_fw
));
2131 ioc
->cached_fw
= NULL
;
2134 printk(MYIOC_s_WARN_FMT
2135 "firmware upload failure!\n", ioc
->name
);
2143 /* Enable! (reply interrupt) */
2144 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, MPI_HIM_DIM
);
2148 if (reset_alt_ioc_active
&& ioc
->alt_ioc
) {
2149 /* (re)Enable alt-IOC! (reply interrupt) */
2150 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"alt_ioc reply irq re-enabled\n",
2151 ioc
->alt_ioc
->name
));
2152 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
, MPI_HIM_DIM
);
2153 ioc
->alt_ioc
->active
= 1;
2156 /* Enable MPT base driver management of EventNotification
2157 * and EventAck handling.
2159 if ((ret
== 0) && (!ioc
->facts
.EventState
))
2160 (void) SendEventNotification(ioc
, 1); /* 1=Enable EventNotification */
2162 if (ioc
->alt_ioc
&& alt_ioc_ready
&& !ioc
->alt_ioc
->facts
.EventState
)
2163 (void) SendEventNotification(ioc
->alt_ioc
, 1); /* 1=Enable EventNotification */
2165 /* Add additional "reason" check before call to GetLanConfigPages
2166 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2167 * recursive scenario; GetLanConfigPages times out, timer expired
2168 * routine calls HardResetHandler, which calls into here again,
2169 * and we try GetLanConfigPages again...
2171 if ((ret
== 0) && (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)) {
2174 * Initalize link list for inactive raid volumes.
2176 init_MUTEX(&ioc
->raid_data
.inactive_list_mutex
);
2177 INIT_LIST_HEAD(&ioc
->raid_data
.inactive_list
);
2179 if (ioc
->bus_type
== SAS
) {
2181 /* clear persistency table */
2182 if(ioc
->facts
.IOCExceptions
&
2183 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL
) {
2184 ret
= mptbase_sas_persist_operation(ioc
,
2185 MPI_SAS_OP_CLEAR_NOT_PRESENT
);
2192 mpt_findImVolumes(ioc
);
2194 } else if (ioc
->bus_type
== FC
) {
2195 if ((ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
) &&
2196 (ioc
->lan_cnfg_page0
.Header
.PageLength
== 0)) {
2198 * Pre-fetch the ports LAN MAC address!
2199 * (LANPage1_t stuff)
2201 (void) GetLanConfigPages(ioc
);
2202 a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
2203 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2204 "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
2205 ioc
->name
, a
[5], a
[4], a
[3], a
[2], a
[1], a
[0]));
2209 /* Get NVRAM and adapter maximums from SPP 0 and 2
2211 mpt_GetScsiPortSettings(ioc
, 0);
2213 /* Get version and length of SDP 1
2215 mpt_readScsiDevicePageHeaders(ioc
, 0);
2219 if (ioc
->facts
.MsgVersion
>= MPI_VERSION_01_02
)
2220 mpt_findImVolumes(ioc
);
2222 /* Check, and possibly reset, the coalescing value
2224 mpt_read_ioc_pg_1(ioc
);
2226 mpt_read_ioc_pg_4(ioc
);
2229 GetIoUnitPage2(ioc
);
2230 mpt_get_manufacturing_pg_0(ioc
);
2234 * Call each currently registered protocol IOC reset handler
2235 * with post-reset indication.
2236 * NOTE: If we're doing _IOC_BRINGUP, there can be no
2237 * MptResetHandlers[] registered yet.
2239 if (hard_reset_done
) {
2241 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
2242 if ((ret
== 0) && MptResetHandlers
[cb_idx
]) {
2243 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2244 "Calling IOC post_reset handler #%d\n",
2245 ioc
->name
, cb_idx
));
2246 rc
+= mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_POST_RESET
);
2250 if (alt_ioc_ready
&& MptResetHandlers
[cb_idx
]) {
2251 drsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2252 "Calling IOC post_reset handler #%d\n",
2253 ioc
->alt_ioc
->name
, cb_idx
));
2254 rc
+= mpt_signal_reset(cb_idx
, ioc
->alt_ioc
, MPT_IOC_POST_RESET
);
2258 /* FIXME? Examine results here? */
2262 if ((ret
!= 0) && irq_allocated
) {
2263 free_irq(ioc
->pci_irq
, ioc
);
2265 pci_disable_msi(ioc
->pcidev
);
2270 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2272 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2273 * @ioc: Pointer to MPT adapter structure
2274 * @pdev: Pointer to (struct pci_dev) structure
2276 * Search for PCI bus/dev_function which matches
2277 * PCI bus/dev_function (+/-1) for newly discovered 929,
2278 * 929X, 1030 or 1035.
2280 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2281 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2284 mpt_detect_bound_ports(MPT_ADAPTER
*ioc
, struct pci_dev
*pdev
)
2286 struct pci_dev
*peer
=NULL
;
2287 unsigned int slot
= PCI_SLOT(pdev
->devfn
);
2288 unsigned int func
= PCI_FUNC(pdev
->devfn
);
2289 MPT_ADAPTER
*ioc_srch
;
2291 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"PCI device %s devfn=%x/%x,"
2292 " searching for devfn match on %x or %x\n",
2293 ioc
->name
, pci_name(pdev
), pdev
->bus
->number
,
2294 pdev
->devfn
, func
-1, func
+1));
2296 peer
= pci_get_slot(pdev
->bus
, PCI_DEVFN(slot
,func
-1));
2298 peer
= pci_get_slot(pdev
->bus
, PCI_DEVFN(slot
,func
+1));
2303 list_for_each_entry(ioc_srch
, &ioc_list
, list
) {
2304 struct pci_dev
*_pcidev
= ioc_srch
->pcidev
;
2305 if (_pcidev
== peer
) {
2306 /* Paranoia checks */
2307 if (ioc
->alt_ioc
!= NULL
) {
2308 printk(MYIOC_s_WARN_FMT
"Oops, already bound to %s!\n",
2309 ioc
->name
, ioc
->alt_ioc
->name
);
2311 } else if (ioc_srch
->alt_ioc
!= NULL
) {
2312 printk(MYIOC_s_WARN_FMT
"Oops, already bound to %s!\n",
2313 ioc_srch
->name
, ioc_srch
->alt_ioc
->name
);
2316 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
"FOUND! binding to %s\n",
2317 ioc
->name
, ioc_srch
->name
));
2318 ioc_srch
->alt_ioc
= ioc
;
2319 ioc
->alt_ioc
= ioc_srch
;
2325 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2327 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2328 * @ioc: Pointer to MPT adapter structure
2331 mpt_adapter_disable(MPT_ADAPTER
*ioc
)
2336 if (ioc
->cached_fw
!= NULL
) {
2337 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"%s: Pushing FW onto "
2338 "adapter\n", __FUNCTION__
, ioc
->name
));
2339 if ((ret
= mpt_downloadboot(ioc
, (MpiFwHeader_t
*)
2340 ioc
->cached_fw
, CAN_SLEEP
)) < 0) {
2341 printk(MYIOC_s_WARN_FMT
2342 ": firmware downloadboot failure (%d)!\n",
2347 /* Disable adapter interrupts! */
2348 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2350 /* Clear any lingering interrupt */
2351 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
2353 if (ioc
->alloc
!= NULL
) {
2355 dexitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"free @ %p, sz=%d bytes\n",
2356 ioc
->name
, ioc
->alloc
, ioc
->alloc_sz
));
2357 pci_free_consistent(ioc
->pcidev
, sz
,
2358 ioc
->alloc
, ioc
->alloc_dma
);
2359 ioc
->reply_frames
= NULL
;
2360 ioc
->req_frames
= NULL
;
2362 ioc
->alloc_total
-= sz
;
2365 if (ioc
->sense_buf_pool
!= NULL
) {
2366 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
2367 pci_free_consistent(ioc
->pcidev
, sz
,
2368 ioc
->sense_buf_pool
, ioc
->sense_buf_pool_dma
);
2369 ioc
->sense_buf_pool
= NULL
;
2370 ioc
->alloc_total
-= sz
;
2373 if (ioc
->events
!= NULL
){
2374 sz
= MPTCTL_EVENT_LOG_SIZE
* sizeof(MPT_IOCTL_EVENTS
);
2377 ioc
->alloc_total
-= sz
;
2380 mpt_free_fw_memory(ioc
);
2382 kfree(ioc
->spi_data
.nvram
);
2383 mpt_inactive_raid_list_free(ioc
);
2384 kfree(ioc
->raid_data
.pIocPg2
);
2385 kfree(ioc
->raid_data
.pIocPg3
);
2386 ioc
->spi_data
.nvram
= NULL
;
2387 ioc
->raid_data
.pIocPg3
= NULL
;
2389 if (ioc
->spi_data
.pIocPg4
!= NULL
) {
2390 sz
= ioc
->spi_data
.IocPg4Sz
;
2391 pci_free_consistent(ioc
->pcidev
, sz
,
2392 ioc
->spi_data
.pIocPg4
,
2393 ioc
->spi_data
.IocPg4_dma
);
2394 ioc
->spi_data
.pIocPg4
= NULL
;
2395 ioc
->alloc_total
-= sz
;
2398 if (ioc
->ReqToChain
!= NULL
) {
2399 kfree(ioc
->ReqToChain
);
2400 kfree(ioc
->RequestNB
);
2401 ioc
->ReqToChain
= NULL
;
2404 kfree(ioc
->ChainToChain
);
2405 ioc
->ChainToChain
= NULL
;
2407 if (ioc
->HostPageBuffer
!= NULL
) {
2408 if((ret
= mpt_host_page_access_control(ioc
,
2409 MPI_DB_HPBAC_FREE_BUFFER
, NO_SLEEP
)) != 0) {
2410 printk(MYIOC_s_ERR_FMT
2411 "host page buffers free failed (%d)!\n",
2414 dexitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"HostPageBuffer free @ %p, sz=%d bytes\n",
2415 ioc
->name
, ioc
->HostPageBuffer
, ioc
->HostPageBuffer_sz
));
2416 pci_free_consistent(ioc
->pcidev
, ioc
->HostPageBuffer_sz
,
2417 ioc
->HostPageBuffer
, ioc
->HostPageBuffer_dma
);
2418 ioc
->HostPageBuffer
= NULL
;
2419 ioc
->HostPageBuffer_sz
= 0;
2420 ioc
->alloc_total
-= ioc
->HostPageBuffer_sz
;
2424 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2426 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2427 * @ioc: Pointer to MPT adapter structure
2429 * This routine unregisters h/w resources and frees all alloc'd memory
2430 * associated with a MPT adapter structure.
2433 mpt_adapter_dispose(MPT_ADAPTER
*ioc
)
2435 int sz_first
, sz_last
;
2440 sz_first
= ioc
->alloc_total
;
2442 mpt_adapter_disable(ioc
);
2444 if (ioc
->pci_irq
!= -1) {
2445 free_irq(ioc
->pci_irq
, ioc
);
2447 pci_disable_msi(ioc
->pcidev
);
2451 if (ioc
->memmap
!= NULL
) {
2452 iounmap(ioc
->memmap
);
2456 pci_disable_device(ioc
->pcidev
);
2457 pci_release_selected_regions(ioc
->pcidev
, ioc
->bars
);
2459 #if defined(CONFIG_MTRR) && 0
2460 if (ioc
->mtrr_reg
> 0) {
2461 mtrr_del(ioc
->mtrr_reg
, 0, 0);
2462 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
"MTRR region de-registered\n", ioc
->name
));
2466 /* Zap the adapter lookup ptr! */
2467 list_del(&ioc
->list
);
2469 sz_last
= ioc
->alloc_total
;
2470 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
"free'd %d of %d bytes\n",
2471 ioc
->name
, sz_first
-sz_last
+(int)sizeof(*ioc
), sz_first
));
2474 ioc
->alt_ioc
->alt_ioc
= NULL
;
2479 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2481 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2482 * @ioc: Pointer to MPT adapter structure
2485 MptDisplayIocCapabilities(MPT_ADAPTER
*ioc
)
2489 printk(KERN_INFO
"%s: ", ioc
->name
);
2491 printk("%s: ", ioc
->prod_name
);
2492 printk("Capabilities={");
2494 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_INITIATOR
) {
2495 printk("Initiator");
2499 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_TARGET
) {
2500 printk("%sTarget", i
? "," : "");
2504 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
) {
2505 printk("%sLAN", i
? "," : "");
2511 * This would probably evoke more questions than it's worth
2513 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_TARGET
) {
2514 printk("%sLogBusAddr", i
? "," : "");
2522 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2524 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2525 * @ioc: Pointer to MPT_ADAPTER structure
2526 * @force: Force hard KickStart of IOC
2527 * @sleepFlag: Specifies whether the process can sleep
2530 * 1 - DIAG reset and READY
2531 * 0 - READY initially OR soft reset and READY
2532 * -1 - Any failure on KickStart
2533 * -2 - Msg Unit Reset Failed
2534 * -3 - IO Unit Reset Failed
2535 * -4 - IOC owned by a PEER
2538 MakeIocReady(MPT_ADAPTER
*ioc
, int force
, int sleepFlag
)
2543 int hard_reset_done
= 0;
2548 /* Get current [raw] IOC state */
2549 ioc_state
= mpt_GetIocState(ioc
, 0);
2550 dhsprintk(ioc
, printk(MYIOC_s_INFO_FMT
"MakeIocReady [raw] state=%08x\n", ioc
->name
, ioc_state
));
2553 * Check to see if IOC got left/stuck in doorbell handshake
2554 * grip of death. If so, hard reset the IOC.
2556 if (ioc_state
& MPI_DOORBELL_ACTIVE
) {
2558 printk(MYIOC_s_WARN_FMT
"Unexpected doorbell active!\n",
2562 /* Is it already READY? */
2563 if (!statefault
&& (ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_READY
)
2567 * Check to see if IOC is in FAULT state.
2569 if ((ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_FAULT
) {
2571 printk(MYIOC_s_WARN_FMT
"IOC is in FAULT state!!!\n",
2573 printk(MYIOC_s_WARN_FMT
" FAULT code = %04xh\n",
2574 ioc
->name
, ioc_state
& MPI_DOORBELL_DATA_MASK
);
2578 * Hmmm... Did it get left operational?
2580 if ((ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_OPERATIONAL
) {
2581 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"IOC operational unexpected\n",
2585 * If PCI Peer, exit.
2586 * Else, if no fault conditions are present, issue a MessageUnitReset
2587 * Else, fall through to KickStart case
2589 whoinit
= (ioc_state
& MPI_DOORBELL_WHO_INIT_MASK
) >> MPI_DOORBELL_WHO_INIT_SHIFT
;
2590 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
2591 "whoinit 0x%x statefault %d force %d\n",
2592 ioc
->name
, whoinit
, statefault
, force
));
2593 if (whoinit
== MPI_WHOINIT_PCI_PEER
)
2596 if ((statefault
== 0 ) && (force
== 0)) {
2597 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
)) == 0)
2604 hard_reset_done
= KickStart(ioc
, statefault
||force
, sleepFlag
);
2605 if (hard_reset_done
< 0)
2609 * Loop here waiting for IOC to come READY.
2612 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 5; /* 5 seconds */
2614 while ((ioc_state
= mpt_GetIocState(ioc
, 1)) != MPI_IOC_STATE_READY
) {
2615 if (ioc_state
== MPI_IOC_STATE_OPERATIONAL
) {
2617 * BIOS or previous driver load left IOC in OP state.
2618 * Reset messaging FIFOs.
2620 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
)) != 0) {
2621 printk(MYIOC_s_ERR_FMT
"IOC msg unit reset failed!\n", ioc
->name
);
2624 } else if (ioc_state
== MPI_IOC_STATE_RESET
) {
2626 * Something is wrong. Try to get IOC back
2629 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IO_UNIT_RESET
, sleepFlag
)) != 0) {
2630 printk(MYIOC_s_ERR_FMT
"IO unit reset failed!\n", ioc
->name
);
2637 printk(MYIOC_s_ERR_FMT
"Wait IOC_READY state timeout(%d)!\n",
2638 ioc
->name
, (int)((ii
+5)/HZ
));
2642 if (sleepFlag
== CAN_SLEEP
) {
2645 mdelay (1); /* 1 msec delay */
2650 if (statefault
< 3) {
2651 printk(MYIOC_s_INFO_FMT
"Recovered from %s\n",
2653 statefault
==1 ? "stuck handshake" : "IOC FAULT");
2656 return hard_reset_done
;
2659 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2661 * mpt_GetIocState - Get the current state of a MPT adapter.
2662 * @ioc: Pointer to MPT_ADAPTER structure
2663 * @cooked: Request raw or cooked IOC state
2665 * Returns all IOC Doorbell register bits if cooked==0, else just the
2666 * Doorbell bits in MPI_IOC_STATE_MASK.
2669 mpt_GetIocState(MPT_ADAPTER
*ioc
, int cooked
)
2674 s
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
2675 sc
= s
& MPI_IOC_STATE_MASK
;
2678 ioc
->last_state
= sc
;
2680 return cooked
? sc
: s
;
2683 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2685 * GetIocFacts - Send IOCFacts request to MPT adapter.
2686 * @ioc: Pointer to MPT_ADAPTER structure
2687 * @sleepFlag: Specifies whether the process can sleep
2688 * @reason: If recovery, only update facts.
2690 * Returns 0 for success, non-zero for failure.
2693 GetIocFacts(MPT_ADAPTER
*ioc
, int sleepFlag
, int reason
)
2695 IOCFacts_t get_facts
;
2696 IOCFactsReply_t
*facts
;
2704 /* IOC *must* NOT be in RESET state! */
2705 if (ioc
->last_state
== MPI_IOC_STATE_RESET
) {
2706 printk(MYIOC_s_ERR_FMT
"Can't get IOCFacts NOT READY! (%08x)\n",
2707 ioc
->name
, ioc
->last_state
);
2711 facts
= &ioc
->facts
;
2713 /* Destination (reply area)... */
2714 reply_sz
= sizeof(*facts
);
2715 memset(facts
, 0, reply_sz
);
2717 /* Request area (get_facts on the stack right now!) */
2718 req_sz
= sizeof(get_facts
);
2719 memset(&get_facts
, 0, req_sz
);
2721 get_facts
.Function
= MPI_FUNCTION_IOC_FACTS
;
2722 /* Assert: All other get_facts fields are zero! */
2724 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2725 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2726 ioc
->name
, req_sz
, reply_sz
));
2728 /* No non-zero fields in the get_facts request are greater than
2729 * 1 byte in size, so we can just fire it off as is.
2731 r
= mpt_handshake_req_reply_wait(ioc
, req_sz
, (u32
*)&get_facts
,
2732 reply_sz
, (u16
*)facts
, 5 /*seconds*/, sleepFlag
);
2737 * Now byte swap (GRRR) the necessary fields before any further
2738 * inspection of reply contents.
2740 * But need to do some sanity checks on MsgLength (byte) field
2741 * to make sure we don't zero IOC's req_sz!
2743 /* Did we get a valid reply? */
2744 if (facts
->MsgLength
> offsetof(IOCFactsReply_t
, RequestFrameSize
)/sizeof(u32
)) {
2745 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
2747 * If not been here, done that, save off first WhoInit value
2749 if (ioc
->FirstWhoInit
== WHOINIT_UNKNOWN
)
2750 ioc
->FirstWhoInit
= facts
->WhoInit
;
2753 facts
->MsgVersion
= le16_to_cpu(facts
->MsgVersion
);
2754 facts
->MsgContext
= le32_to_cpu(facts
->MsgContext
);
2755 facts
->IOCExceptions
= le16_to_cpu(facts
->IOCExceptions
);
2756 facts
->IOCStatus
= le16_to_cpu(facts
->IOCStatus
);
2757 facts
->IOCLogInfo
= le32_to_cpu(facts
->IOCLogInfo
);
2758 status
= le16_to_cpu(facts
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
2759 /* CHECKME! IOCStatus, IOCLogInfo */
2761 facts
->ReplyQueueDepth
= le16_to_cpu(facts
->ReplyQueueDepth
);
2762 facts
->RequestFrameSize
= le16_to_cpu(facts
->RequestFrameSize
);
2765 * FC f/w version changed between 1.1 and 1.2
2766 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2767 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2769 if (facts
->MsgVersion
< 0x0102) {
2771 * Handle old FC f/w style, convert to new...
2773 u16 oldv
= le16_to_cpu(facts
->Reserved_0101_FWVersion
);
2774 facts
->FWVersion
.Word
=
2775 ((oldv
<<12) & 0xFF000000) |
2776 ((oldv
<<8) & 0x000FFF00);
2778 facts
->FWVersion
.Word
= le32_to_cpu(facts
->FWVersion
.Word
);
2780 facts
->ProductID
= le16_to_cpu(facts
->ProductID
);
2781 if ((ioc
->facts
.ProductID
& MPI_FW_HEADER_PID_PROD_MASK
)
2782 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI
)
2783 ioc
->ir_firmware
= 1;
2784 facts
->CurrentHostMfaHighAddr
=
2785 le32_to_cpu(facts
->CurrentHostMfaHighAddr
);
2786 facts
->GlobalCredits
= le16_to_cpu(facts
->GlobalCredits
);
2787 facts
->CurrentSenseBufferHighAddr
=
2788 le32_to_cpu(facts
->CurrentSenseBufferHighAddr
);
2789 facts
->CurReplyFrameSize
=
2790 le16_to_cpu(facts
->CurReplyFrameSize
);
2791 facts
->IOCCapabilities
= le32_to_cpu(facts
->IOCCapabilities
);
2794 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2795 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2796 * to 14 in MPI-1.01.0x.
2798 if (facts
->MsgLength
>= (offsetof(IOCFactsReply_t
,FWImageSize
) + 7)/4 &&
2799 facts
->MsgVersion
> 0x0100) {
2800 facts
->FWImageSize
= le32_to_cpu(facts
->FWImageSize
);
2803 sz
= facts
->FWImageSize
;
2808 facts
->FWImageSize
= sz
;
2810 if (!facts
->RequestFrameSize
) {
2811 /* Something is wrong! */
2812 printk(MYIOC_s_ERR_FMT
"IOC reported invalid 0 request size!\n",
2817 r
= sz
= facts
->BlockSize
;
2818 vv
= ((63 / (sz
* 4)) + 1) & 0x03;
2819 ioc
->NB_for_64_byte_frame
= vv
;
2825 ioc
->NBShiftFactor
= shiftFactor
;
2826 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2827 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2828 ioc
->name
, vv
, shiftFactor
, r
));
2830 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
2832 * Set values for this IOC's request & reply frame sizes,
2833 * and request & reply queue depths...
2835 ioc
->req_sz
= min(MPT_DEFAULT_FRAME_SIZE
, facts
->RequestFrameSize
* 4);
2836 ioc
->req_depth
= min_t(int, MPT_MAX_REQ_DEPTH
, facts
->GlobalCredits
);
2837 ioc
->reply_sz
= MPT_REPLY_FRAME_SIZE
;
2838 ioc
->reply_depth
= min_t(int, MPT_DEFAULT_REPLY_DEPTH
, facts
->ReplyQueueDepth
);
2840 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"reply_sz=%3d, reply_depth=%4d\n",
2841 ioc
->name
, ioc
->reply_sz
, ioc
->reply_depth
));
2842 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"req_sz =%3d, req_depth =%4d\n",
2843 ioc
->name
, ioc
->req_sz
, ioc
->req_depth
));
2845 /* Get port facts! */
2846 if ( (r
= GetPortFacts(ioc
, 0, sleepFlag
)) != 0 )
2850 printk(MYIOC_s_ERR_FMT
2851 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2852 ioc
->name
, facts
->MsgLength
, (offsetof(IOCFactsReply_t
,
2853 RequestFrameSize
)/sizeof(u32
)));
2860 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2862 * GetPortFacts - Send PortFacts request to MPT adapter.
2863 * @ioc: Pointer to MPT_ADAPTER structure
2864 * @portnum: Port number
2865 * @sleepFlag: Specifies whether the process can sleep
2867 * Returns 0 for success, non-zero for failure.
2870 GetPortFacts(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
)
2872 PortFacts_t get_pfacts
;
2873 PortFactsReply_t
*pfacts
;
2879 /* IOC *must* NOT be in RESET state! */
2880 if (ioc
->last_state
== MPI_IOC_STATE_RESET
) {
2881 printk(MYIOC_s_ERR_FMT
"Can't get PortFacts NOT READY! (%08x)\n",
2882 ioc
->name
, ioc
->last_state
);
2886 pfacts
= &ioc
->pfacts
[portnum
];
2888 /* Destination (reply area)... */
2889 reply_sz
= sizeof(*pfacts
);
2890 memset(pfacts
, 0, reply_sz
);
2892 /* Request area (get_pfacts on the stack right now!) */
2893 req_sz
= sizeof(get_pfacts
);
2894 memset(&get_pfacts
, 0, req_sz
);
2896 get_pfacts
.Function
= MPI_FUNCTION_PORT_FACTS
;
2897 get_pfacts
.PortNumber
= portnum
;
2898 /* Assert: All other get_pfacts fields are zero! */
2900 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending get PortFacts(%d) request\n",
2901 ioc
->name
, portnum
));
2903 /* No non-zero fields in the get_pfacts request are greater than
2904 * 1 byte in size, so we can just fire it off as is.
2906 ii
= mpt_handshake_req_reply_wait(ioc
, req_sz
, (u32
*)&get_pfacts
,
2907 reply_sz
, (u16
*)pfacts
, 5 /*seconds*/, sleepFlag
);
2911 /* Did we get a valid reply? */
2913 /* Now byte swap the necessary fields in the response. */
2914 pfacts
->MsgContext
= le32_to_cpu(pfacts
->MsgContext
);
2915 pfacts
->IOCStatus
= le16_to_cpu(pfacts
->IOCStatus
);
2916 pfacts
->IOCLogInfo
= le32_to_cpu(pfacts
->IOCLogInfo
);
2917 pfacts
->MaxDevices
= le16_to_cpu(pfacts
->MaxDevices
);
2918 pfacts
->PortSCSIID
= le16_to_cpu(pfacts
->PortSCSIID
);
2919 pfacts
->ProtocolFlags
= le16_to_cpu(pfacts
->ProtocolFlags
);
2920 pfacts
->MaxPostedCmdBuffers
= le16_to_cpu(pfacts
->MaxPostedCmdBuffers
);
2921 pfacts
->MaxPersistentIDs
= le16_to_cpu(pfacts
->MaxPersistentIDs
);
2922 pfacts
->MaxLanBuckets
= le16_to_cpu(pfacts
->MaxLanBuckets
);
2924 max_id
= (ioc
->bus_type
== SAS
) ? pfacts
->PortSCSIID
:
2926 ioc
->devices_per_bus
= (max_id
> 255) ? 256 : max_id
;
2927 ioc
->number_of_buses
= (ioc
->devices_per_bus
< 256) ? 1 : max_id
/256;
2930 * Place all the devices on channels
2934 if (mpt_channel_mapping
) {
2935 ioc
->devices_per_bus
= 1;
2936 ioc
->number_of_buses
= (max_id
> 255) ? 255 : max_id
;
2942 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2944 * SendIocInit - Send IOCInit request to MPT adapter.
2945 * @ioc: Pointer to MPT_ADAPTER structure
2946 * @sleepFlag: Specifies whether the process can sleep
2948 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2950 * Returns 0 for success, non-zero for failure.
2953 SendIocInit(MPT_ADAPTER
*ioc
, int sleepFlag
)
2956 MPIDefaultReply_t init_reply
;
2962 memset(&ioc_init
, 0, sizeof(ioc_init
));
2963 memset(&init_reply
, 0, sizeof(init_reply
));
2965 ioc_init
.WhoInit
= MPI_WHOINIT_HOST_DRIVER
;
2966 ioc_init
.Function
= MPI_FUNCTION_IOC_INIT
;
2968 /* If we are in a recovery mode and we uploaded the FW image,
2969 * then this pointer is not NULL. Skip the upload a second time.
2970 * Set this flag if cached_fw set for either IOC.
2972 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)
2976 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"upload_fw %d facts.Flags=%x\n",
2977 ioc
->name
, ioc
->upload_fw
, ioc
->facts
.Flags
));
2979 ioc_init
.MaxDevices
= (U8
)ioc
->devices_per_bus
;
2980 ioc_init
.MaxBuses
= (U8
)ioc
->number_of_buses
;
2981 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"facts.MsgVersion=%x\n",
2982 ioc
->name
, ioc
->facts
.MsgVersion
));
2983 if (ioc
->facts
.MsgVersion
>= MPI_VERSION_01_05
) {
2984 // set MsgVersion and HeaderVersion host driver was built with
2985 ioc_init
.MsgVersion
= cpu_to_le16(MPI_VERSION
);
2986 ioc_init
.HeaderVersion
= cpu_to_le16(MPI_HEADER_VERSION
);
2988 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT
) {
2989 ioc_init
.HostPageBufferSGE
= ioc
->facts
.HostPageBufferSGE
;
2990 } else if(mpt_host_page_alloc(ioc
, &ioc_init
))
2993 ioc_init
.ReplyFrameSize
= cpu_to_le16(ioc
->reply_sz
); /* in BYTES */
2995 if (sizeof(dma_addr_t
) == sizeof(u64
)) {
2996 /* Save the upper 32-bits of the request
2997 * (reply) and sense buffers.
2999 ioc_init
.HostMfaHighAddr
= cpu_to_le32((u32
)((u64
)ioc
->alloc_dma
>> 32));
3000 ioc_init
.SenseBufferHighAddr
= cpu_to_le32((u32
)((u64
)ioc
->sense_buf_pool_dma
>> 32));
3002 /* Force 32-bit addressing */
3003 ioc_init
.HostMfaHighAddr
= cpu_to_le32(0);
3004 ioc_init
.SenseBufferHighAddr
= cpu_to_le32(0);
3007 ioc
->facts
.CurrentHostMfaHighAddr
= ioc_init
.HostMfaHighAddr
;
3008 ioc
->facts
.CurrentSenseBufferHighAddr
= ioc_init
.SenseBufferHighAddr
;
3009 ioc
->facts
.MaxDevices
= ioc_init
.MaxDevices
;
3010 ioc
->facts
.MaxBuses
= ioc_init
.MaxBuses
;
3012 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending IOCInit (req @ %p)\n",
3013 ioc
->name
, &ioc_init
));
3015 r
= mpt_handshake_req_reply_wait(ioc
, sizeof(IOCInit_t
), (u32
*)&ioc_init
,
3016 sizeof(MPIDefaultReply_t
), (u16
*)&init_reply
, 10 /*seconds*/, sleepFlag
);
3018 printk(MYIOC_s_ERR_FMT
"Sending IOCInit failed(%d)!\n",ioc
->name
, r
);
3022 /* No need to byte swap the multibyte fields in the reply
3023 * since we don't even look at its contents.
3026 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending PortEnable (req @ %p)\n",
3027 ioc
->name
, &ioc_init
));
3029 if ((r
= SendPortEnable(ioc
, 0, sleepFlag
)) != 0) {
3030 printk(MYIOC_s_ERR_FMT
"Sending PortEnable failed(%d)!\n",ioc
->name
, r
);
3034 /* YIKES! SUPER IMPORTANT!!!
3035 * Poll IocState until _OPERATIONAL while IOC is doing
3036 * LoopInit and TargetDiscovery!
3039 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 60; /* 60 seconds */
3040 state
= mpt_GetIocState(ioc
, 1);
3041 while (state
!= MPI_IOC_STATE_OPERATIONAL
&& --cntdn
) {
3042 if (sleepFlag
== CAN_SLEEP
) {
3049 printk(MYIOC_s_ERR_FMT
"Wait IOC_OP state timeout(%d)!\n",
3050 ioc
->name
, (int)((count
+5)/HZ
));
3054 state
= mpt_GetIocState(ioc
, 1);
3057 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Wait IOC_OPERATIONAL state (cnt=%d)\n",
3060 ioc
->aen_event_read_flag
=0;
3064 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3066 * SendPortEnable - Send PortEnable request to MPT adapter port.
3067 * @ioc: Pointer to MPT_ADAPTER structure
3068 * @portnum: Port number to enable
3069 * @sleepFlag: Specifies whether the process can sleep
3071 * Send PortEnable to bring IOC to OPERATIONAL state.
3073 * Returns 0 for success, non-zero for failure.
3076 SendPortEnable(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
)
3078 PortEnable_t port_enable
;
3079 MPIDefaultReply_t reply_buf
;
3084 /* Destination... */
3085 reply_sz
= sizeof(MPIDefaultReply_t
);
3086 memset(&reply_buf
, 0, reply_sz
);
3088 req_sz
= sizeof(PortEnable_t
);
3089 memset(&port_enable
, 0, req_sz
);
3091 port_enable
.Function
= MPI_FUNCTION_PORT_ENABLE
;
3092 port_enable
.PortNumber
= portnum
;
3093 /* port_enable.ChainOffset = 0; */
3094 /* port_enable.MsgFlags = 0; */
3095 /* port_enable.MsgContext = 0; */
3097 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending Port(%d)Enable (req @ %p)\n",
3098 ioc
->name
, portnum
, &port_enable
));
3100 /* RAID FW may take a long time to enable
3102 if (ioc
->ir_firmware
|| ioc
->bus_type
== SAS
) {
3103 rc
= mpt_handshake_req_reply_wait(ioc
, req_sz
,
3104 (u32
*)&port_enable
, reply_sz
, (u16
*)&reply_buf
,
3105 300 /*seconds*/, sleepFlag
);
3107 rc
= mpt_handshake_req_reply_wait(ioc
, req_sz
,
3108 (u32
*)&port_enable
, reply_sz
, (u16
*)&reply_buf
,
3109 30 /*seconds*/, sleepFlag
);
3115 * mpt_alloc_fw_memory - allocate firmware memory
3116 * @ioc: Pointer to MPT_ADAPTER structure
3117 * @size: total FW bytes
3119 * If memory has already been allocated, the same (cached) value
3122 * Return 0 if successfull, or non-zero for failure
3125 mpt_alloc_fw_memory(MPT_ADAPTER
*ioc
, int size
)
3129 if (ioc
->cached_fw
) {
3130 rc
= 0; /* use already allocated memory */
3133 else if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
) {
3134 ioc
->cached_fw
= ioc
->alt_ioc
->cached_fw
; /* use alt_ioc's memory */
3135 ioc
->cached_fw_dma
= ioc
->alt_ioc
->cached_fw_dma
;
3139 ioc
->cached_fw
= pci_alloc_consistent(ioc
->pcidev
, size
, &ioc
->cached_fw_dma
);
3140 if (!ioc
->cached_fw
) {
3141 printk(MYIOC_s_ERR_FMT
"Unable to allocate memory for the cached firmware image!\n",
3145 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"FW Image @ %p[%p], sz=%d[%x] bytes\n",
3146 ioc
->name
, ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, size
, size
));
3147 ioc
->alloc_total
+= size
;
3155 * mpt_free_fw_memory - free firmware memory
3156 * @ioc: Pointer to MPT_ADAPTER structure
3158 * If alt_img is NULL, delete from ioc structure.
3159 * Else, delete a secondary image in same format.
3162 mpt_free_fw_memory(MPT_ADAPTER
*ioc
)
3166 if (!ioc
->cached_fw
)
3169 sz
= ioc
->facts
.FWImageSize
;
3170 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3171 ioc
->name
, ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, sz
, sz
));
3172 pci_free_consistent(ioc
->pcidev
, sz
, ioc
->cached_fw
, ioc
->cached_fw_dma
);
3173 ioc
->alloc_total
-= sz
;
3174 ioc
->cached_fw
= NULL
;
3177 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3179 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3180 * @ioc: Pointer to MPT_ADAPTER structure
3181 * @sleepFlag: Specifies whether the process can sleep
3183 * Returns 0 for success, >0 for handshake failure
3184 * <0 for fw upload failure.
3186 * Remark: If bound IOC and a successful FWUpload was performed
3187 * on the bound IOC, the second image is discarded
3188 * and memory is free'd. Both channels must upload to prevent
3189 * IOC from running in degraded mode.
3192 mpt_do_upload(MPT_ADAPTER
*ioc
, int sleepFlag
)
3194 u8 reply
[sizeof(FWUploadReply_t
)];
3195 FWUpload_t
*prequest
;
3196 FWUploadReply_t
*preply
;
3197 FWUploadTCSGE_t
*ptcsge
;
3200 int ii
, sz
, reply_sz
;
3203 /* If the image size is 0, we are done.
3205 if ((sz
= ioc
->facts
.FWImageSize
) == 0)
3208 if (mpt_alloc_fw_memory(ioc
, ioc
->facts
.FWImageSize
) != 0)
3211 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3212 ioc
->name
, ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, sz
, sz
));
3214 prequest
= (sleepFlag
== NO_SLEEP
) ? kzalloc(ioc
->req_sz
, GFP_ATOMIC
) :
3215 kzalloc(ioc
->req_sz
, GFP_KERNEL
);
3217 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"fw upload failed "
3218 "while allocating memory \n", ioc
->name
));
3219 mpt_free_fw_memory(ioc
);
3223 preply
= (FWUploadReply_t
*)&reply
;
3225 reply_sz
= sizeof(reply
);
3226 memset(preply
, 0, reply_sz
);
3228 prequest
->ImageType
= MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM
;
3229 prequest
->Function
= MPI_FUNCTION_FW_UPLOAD
;
3231 ptcsge
= (FWUploadTCSGE_t
*) &prequest
->SGL
;
3232 ptcsge
->DetailsLength
= 12;
3233 ptcsge
->Flags
= MPI_SGE_FLAGS_TRANSACTION_ELEMENT
;
3234 ptcsge
->ImageSize
= cpu_to_le32(sz
);
3237 sgeoffset
= sizeof(FWUpload_t
) - sizeof(SGE_MPI_UNION
) + sizeof(FWUploadTCSGE_t
);
3239 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_READ
| sz
;
3240 mpt_add_sge((char *)ptcsge
, flagsLength
, ioc
->cached_fw_dma
);
3242 sgeoffset
+= sizeof(u32
) + sizeof(dma_addr_t
);
3243 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
": Sending FW Upload (req @ %p) sgeoffset=%d \n",
3244 ioc
->name
, prequest
, sgeoffset
));
3245 DBG_DUMP_FW_REQUEST_FRAME(ioc
, (u32
*)prequest
);
3247 ii
= mpt_handshake_req_reply_wait(ioc
, sgeoffset
, (u32
*)prequest
,
3248 reply_sz
, (u16
*)preply
, 65 /*seconds*/, sleepFlag
);
3250 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
": FW Upload completed rc=%x \n", ioc
->name
, ii
));
3252 cmdStatus
= -EFAULT
;
3254 /* Handshake transfer was complete and successful.
3255 * Check the Reply Frame.
3257 int status
, transfer_sz
;
3258 status
= le16_to_cpu(preply
->IOCStatus
);
3259 if (status
== MPI_IOCSTATUS_SUCCESS
) {
3260 transfer_sz
= le32_to_cpu(preply
->ActualImageSize
);
3261 if (transfer_sz
== sz
)
3265 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
": do_upload cmdStatus=%d \n",
3266 ioc
->name
, cmdStatus
));
3271 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
": fw upload failed, freeing image \n",
3273 mpt_free_fw_memory(ioc
);
3280 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3282 * mpt_downloadboot - DownloadBoot code
3283 * @ioc: Pointer to MPT_ADAPTER structure
3284 * @pFwHeader: Pointer to firmware header info
3285 * @sleepFlag: Specifies whether the process can sleep
3287 * FwDownloadBoot requires Programmed IO access.
3289 * Returns 0 for success
3290 * -1 FW Image size is 0
3291 * -2 No valid cached_fw Pointer
3292 * <0 for fw upload failure.
3295 mpt_downloadboot(MPT_ADAPTER
*ioc
, MpiFwHeader_t
*pFwHeader
, int sleepFlag
)
3297 MpiExtImageHeader_t
*pExtImage
;
3307 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3308 ioc
->name
, pFwHeader
->ImageSize
, pFwHeader
->ImageSize
, pFwHeader
));
3310 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3311 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3312 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3313 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3314 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3315 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3317 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, (MPI_DIAG_PREVENT_IOC_BOOT
| MPI_DIAG_DISABLE_ARM
));
3320 if (sleepFlag
== CAN_SLEEP
) {
3326 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3327 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_RESET_ADAPTER
);
3329 for (count
= 0; count
< 30; count
++) {
3330 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3331 if (!(diag0val
& MPI_DIAG_RESET_ADAPTER
)) {
3332 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RESET_ADAPTER cleared, count=%d\n",
3337 if (sleepFlag
== CAN_SLEEP
) {
3344 if ( count
== 30 ) {
3345 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot failed! "
3346 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3347 ioc
->name
, diag0val
));
3351 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3352 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3353 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3354 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3355 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3356 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3358 /* Set the DiagRwEn and Disable ARM bits */
3359 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, (MPI_DIAG_RW_ENABLE
| MPI_DIAG_DISABLE_ARM
));
3361 fwSize
= (pFwHeader
->ImageSize
+ 3)/4;
3362 ptrFw
= (u32
*) pFwHeader
;
3364 /* Write the LoadStartAddress to the DiagRw Address Register
3365 * using Programmed IO
3367 if (ioc
->errata_flag_1064
)
3368 pci_enable_io_access(ioc
->pcidev
);
3370 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, pFwHeader
->LoadStartAddress
);
3371 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"LoadStart addr written 0x%x \n",
3372 ioc
->name
, pFwHeader
->LoadStartAddress
));
3374 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write FW Image: 0x%x bytes @ %p\n",
3375 ioc
->name
, fwSize
*4, ptrFw
));
3377 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, *ptrFw
++);
3380 nextImage
= pFwHeader
->NextImageHeaderOffset
;
3382 pExtImage
= (MpiExtImageHeader_t
*) ((char *)pFwHeader
+ nextImage
);
3384 load_addr
= pExtImage
->LoadStartAddress
;
3386 fwSize
= (pExtImage
->ImageSize
+ 3) >> 2;
3387 ptrFw
= (u32
*)pExtImage
;
3389 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3390 ioc
->name
, fwSize
*4, fwSize
*4, ptrFw
, load_addr
));
3391 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, load_addr
);
3394 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, *ptrFw
++);
3396 nextImage
= pExtImage
->NextImageHeaderOffset
;
3399 /* Write the IopResetVectorRegAddr */
3400 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write IopResetVector Addr=%x! \n", ioc
->name
, pFwHeader
->IopResetRegAddr
));
3401 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, pFwHeader
->IopResetRegAddr
);
3403 /* Write the IopResetVectorValue */
3404 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write IopResetVector Value=%x! \n", ioc
->name
, pFwHeader
->IopResetVectorValue
));
3405 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, pFwHeader
->IopResetVectorValue
);
3407 /* Clear the internal flash bad bit - autoincrementing register,
3408 * so must do two writes.
3410 if (ioc
->bus_type
== SPI
) {
3412 * 1030 and 1035 H/W errata, workaround to access
3413 * the ClearFlashBadSignatureBit
3415 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, 0x3F000000);
3416 diagRwData
= CHIPREG_PIO_READ32(&ioc
->pio_chip
->DiagRwData
);
3417 diagRwData
|= 0x40000000;
3418 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, 0x3F000000);
3419 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, diagRwData
);
3421 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3422 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3423 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
|
3424 MPI_DIAG_CLEAR_FLASH_BAD_SIG
);
3427 if (sleepFlag
== CAN_SLEEP
) {
3434 if (ioc
->errata_flag_1064
)
3435 pci_disable_io_access(ioc
->pcidev
);
3437 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3438 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot diag0val=%x, "
3439 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3440 ioc
->name
, diag0val
));
3441 diag0val
&= ~(MPI_DIAG_PREVENT_IOC_BOOT
| MPI_DIAG_DISABLE_ARM
| MPI_DIAG_RW_ENABLE
);
3442 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot now diag0val=%x\n",
3443 ioc
->name
, diag0val
));
3444 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
);
3446 /* Write 0xFF to reset the sequencer */
3447 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3449 if (ioc
->bus_type
== SAS
) {
3450 ioc_state
= mpt_GetIocState(ioc
, 0);
3451 if ( (GetIocFacts(ioc
, sleepFlag
,
3452 MPT_HOSTEVENT_IOC_BRINGUP
)) != 0 ) {
3453 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"GetIocFacts failed: IocState=%x\n",
3454 ioc
->name
, ioc_state
));
3459 for (count
=0; count
<HZ
*20; count
++) {
3460 if ((ioc_state
= mpt_GetIocState(ioc
, 0)) & MPI_IOC_STATE_READY
) {
3461 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3462 "downloadboot successful! (count=%d) IocState=%x\n",
3463 ioc
->name
, count
, ioc_state
));
3464 if (ioc
->bus_type
== SAS
) {
3467 if ((SendIocInit(ioc
, sleepFlag
)) != 0) {
3468 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3469 "downloadboot: SendIocInit failed\n",
3473 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3474 "downloadboot: SendIocInit successful\n",
3478 if (sleepFlag
== CAN_SLEEP
) {
3484 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3485 "downloadboot failed! IocState=%x\n",ioc
->name
, ioc_state
));
3489 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3491 * KickStart - Perform hard reset of MPT adapter.
3492 * @ioc: Pointer to MPT_ADAPTER structure
3493 * @force: Force hard reset
3494 * @sleepFlag: Specifies whether the process can sleep
3496 * This routine places MPT adapter in diagnostic mode via the
3497 * WriteSequence register, and then performs a hard reset of adapter
3498 * via the Diagnostic register.
3500 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3501 * or NO_SLEEP (interrupt thread, use mdelay)
3502 * force - 1 if doorbell active, board fault state
3503 * board operational, IOC_RECOVERY or
3504 * IOC_BRINGUP and there is an alt_ioc.
3508 * 1 - hard reset, READY
3509 * 0 - no reset due to History bit, READY
3510 * -1 - no reset due to History bit but not READY
3511 * OR reset but failed to come READY
3512 * -2 - no reset, could not enter DIAG mode
3513 * -3 - reset but bad FW bit
3516 KickStart(MPT_ADAPTER
*ioc
, int force
, int sleepFlag
)
3518 int hard_reset_done
= 0;
3522 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"KickStarting!\n", ioc
->name
));
3523 if (ioc
->bus_type
== SPI
) {
3524 /* Always issue a Msg Unit Reset first. This will clear some
3525 * SCSI bus hang conditions.
3527 SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
);
3529 if (sleepFlag
== CAN_SLEEP
) {
3536 hard_reset_done
= mpt_diag_reset(ioc
, force
, sleepFlag
);
3537 if (hard_reset_done
< 0)
3538 return hard_reset_done
;
3540 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Diagnostic reset successful!\n",
3543 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 2; /* 2 seconds */
3544 for (cnt
=0; cnt
<cntdn
; cnt
++) {
3545 ioc_state
= mpt_GetIocState(ioc
, 1);
3546 if ((ioc_state
== MPI_IOC_STATE_READY
) || (ioc_state
== MPI_IOC_STATE_OPERATIONAL
)) {
3547 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"KickStart successful! (cnt=%d)\n",
3549 return hard_reset_done
;
3551 if (sleepFlag
== CAN_SLEEP
) {
3558 dinitprintk(ioc
, printk(MYIOC_s_ERR_FMT
"Failed to come READY after reset! IocState=%x\n",
3559 ioc
->name
, mpt_GetIocState(ioc
, 0)));
3563 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3565 * mpt_diag_reset - Perform hard reset of the adapter.
3566 * @ioc: Pointer to MPT_ADAPTER structure
3567 * @ignore: Set if to honor and clear to ignore
3568 * the reset history bit
3569 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3570 * else set to NO_SLEEP (use mdelay instead)
3572 * This routine places the adapter in diagnostic mode via the
3573 * WriteSequence register and then performs a hard reset of adapter
3574 * via the Diagnostic register. Adapter should be in ready state
3575 * upon successful completion.
3577 * Returns: 1 hard reset successful
3578 * 0 no reset performed because reset history bit set
3579 * -2 enabling diagnostic mode failed
3580 * -3 diagnostic reset failed
3583 mpt_diag_reset(MPT_ADAPTER
*ioc
, int ignore
, int sleepFlag
)
3587 int hard_reset_done
= 0;
3590 MpiFwHeader_t
*cached_fw
; /* Pointer to FW */
3592 /* Clear any existing interrupts */
3593 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
3595 if (ioc
->pcidev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1078
) {
3596 drsprintk(ioc
, printk(MYIOC_s_WARN_FMT
"%s: Doorbell=%p; 1078 reset "
3597 "address=%p\n", ioc
->name
, __FUNCTION__
,
3598 &ioc
->chip
->Doorbell
, &ioc
->chip
->Reset_1078
));
3599 CHIPREG_WRITE32(&ioc
->chip
->Reset_1078
, 0x07);
3600 if (sleepFlag
== CAN_SLEEP
)
3605 for (count
= 0; count
< 60; count
++) {
3606 doorbell
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
3607 doorbell
&= MPI_IOC_STATE_MASK
;
3609 drsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3610 "looking for READY STATE: doorbell=%x"
3612 ioc
->name
, doorbell
, count
));
3613 if (doorbell
== MPI_IOC_STATE_READY
) {
3618 if (sleepFlag
== CAN_SLEEP
)
3626 /* Use "Diagnostic reset" method! (only thing available!) */
3627 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3629 if (ioc
->debug_level
& MPT_DEBUG
) {
3631 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
3632 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG1: diag0=%08x, diag1=%08x\n",
3633 ioc
->name
, diag0val
, diag1val
));
3636 /* Do the reset if we are told to ignore the reset history
3637 * or if the reset history is 0
3639 if (ignore
|| !(diag0val
& MPI_DIAG_RESET_HISTORY
)) {
3640 while ((diag0val
& MPI_DIAG_DRWE
) == 0) {
3641 /* Write magic sequence to WriteSequence register
3642 * Loop until in diagnostic mode
3644 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3645 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3646 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3647 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3648 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3649 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3652 if (sleepFlag
== CAN_SLEEP
) {
3660 printk(MYIOC_s_ERR_FMT
"Enable Diagnostic mode FAILED! (%02xh)\n",
3661 ioc
->name
, diag0val
);
3666 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3668 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Wrote magic DiagWriteEn sequence (%x)\n",
3669 ioc
->name
, diag0val
));
3672 if (ioc
->debug_level
& MPT_DEBUG
) {
3674 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
3675 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG2: diag0=%08x, diag1=%08x\n",
3676 ioc
->name
, diag0val
, diag1val
));
3679 * Disable the ARM (Bug fix)
3682 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_DISABLE_ARM
);
3686 * Now hit the reset bit in the Diagnostic register
3687 * (THE BIG HAMMER!) (Clears DRWE bit).
3689 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_RESET_ADAPTER
);
3690 hard_reset_done
= 1;
3691 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Diagnostic reset performed\n",
3695 * Call each currently registered protocol IOC reset handler
3696 * with pre-reset indication.
3697 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3698 * MptResetHandlers[] registered yet.
3704 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
3705 if (MptResetHandlers
[cb_idx
]) {
3706 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3707 "Calling IOC pre_reset handler #%d\n",
3708 ioc
->name
, cb_idx
));
3709 r
+= mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_PRE_RESET
);
3711 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3712 "Calling alt-%s pre_reset handler #%d\n",
3713 ioc
->name
, ioc
->alt_ioc
->name
, cb_idx
));
3714 r
+= mpt_signal_reset(cb_idx
, ioc
->alt_ioc
, MPT_IOC_PRE_RESET
);
3718 /* FIXME? Examine results here? */
3722 cached_fw
= (MpiFwHeader_t
*)ioc
->cached_fw
;
3723 else if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
)
3724 cached_fw
= (MpiFwHeader_t
*)ioc
->alt_ioc
->cached_fw
;
3728 /* If the DownloadBoot operation fails, the
3729 * IOC will be left unusable. This is a fatal error
3730 * case. _diag_reset will return < 0
3732 for (count
= 0; count
< 30; count
++) {
3733 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3734 if (!(diag0val
& MPI_DIAG_RESET_ADAPTER
)) {
3738 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"cached_fw: diag0val=%x count=%d\n",
3739 ioc
->name
, diag0val
, count
));
3741 if (sleepFlag
== CAN_SLEEP
) {
3747 if ((count
= mpt_downloadboot(ioc
, cached_fw
, sleepFlag
)) < 0) {
3748 printk(MYIOC_s_WARN_FMT
3749 "firmware downloadboot failure (%d)!\n", ioc
->name
, count
);
3753 /* Wait for FW to reload and for board
3754 * to go to the READY state.
3755 * Maximum wait is 60 seconds.
3756 * If fail, no error will check again
3757 * with calling program.
3759 for (count
= 0; count
< 60; count
++) {
3760 doorbell
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
3761 doorbell
&= MPI_IOC_STATE_MASK
;
3763 if (doorbell
== MPI_IOC_STATE_READY
) {
3768 if (sleepFlag
== CAN_SLEEP
) {
3777 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3778 if (ioc
->debug_level
& MPT_DEBUG
) {
3780 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
3781 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG3: diag0=%08x, diag1=%08x\n",
3782 ioc
->name
, diag0val
, diag1val
));
3785 /* Clear RESET_HISTORY bit! Place board in the
3786 * diagnostic mode to update the diag register.
3788 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3790 while ((diag0val
& MPI_DIAG_DRWE
) == 0) {
3791 /* Write magic sequence to WriteSequence register
3792 * Loop until in diagnostic mode
3794 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3795 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3796 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3797 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3798 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3799 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3802 if (sleepFlag
== CAN_SLEEP
) {
3810 printk(MYIOC_s_ERR_FMT
"Enable Diagnostic mode FAILED! (%02xh)\n",
3811 ioc
->name
, diag0val
);
3814 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3816 diag0val
&= ~MPI_DIAG_RESET_HISTORY
;
3817 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
);
3818 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3819 if (diag0val
& MPI_DIAG_RESET_HISTORY
) {
3820 printk(MYIOC_s_WARN_FMT
"ResetHistory bit failed to clear!\n",
3824 /* Disable Diagnostic Mode
3826 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFFFFFFFF);
3828 /* Check FW reload status flags.
3830 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3831 if (diag0val
& (MPI_DIAG_FLASH_BAD_SIG
| MPI_DIAG_RESET_ADAPTER
| MPI_DIAG_DISABLE_ARM
)) {
3832 printk(MYIOC_s_ERR_FMT
"Diagnostic reset FAILED! (%02xh)\n",
3833 ioc
->name
, diag0val
);
3837 if (ioc
->debug_level
& MPT_DEBUG
) {
3839 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
3840 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG4: diag0=%08x, diag1=%08x\n",
3841 ioc
->name
, diag0val
, diag1val
));
3845 * Reset flag that says we've enabled event notification
3847 ioc
->facts
.EventState
= 0;
3850 ioc
->alt_ioc
->facts
.EventState
= 0;
3852 return hard_reset_done
;
3855 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3857 * SendIocReset - Send IOCReset request to MPT adapter.
3858 * @ioc: Pointer to MPT_ADAPTER structure
3859 * @reset_type: reset type, expected values are
3860 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3861 * @sleepFlag: Specifies whether the process can sleep
3863 * Send IOCReset request to the MPT adapter.
3865 * Returns 0 for success, non-zero for failure.
3868 SendIocReset(MPT_ADAPTER
*ioc
, u8 reset_type
, int sleepFlag
)
3874 drsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending IOC reset(0x%02x)!\n",
3875 ioc
->name
, reset_type
));
3876 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, reset_type
<<MPI_DOORBELL_FUNCTION_SHIFT
);
3877 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
3880 /* FW ACK'd request, wait for READY state
3883 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 15; /* 15 seconds */
3885 while ((state
= mpt_GetIocState(ioc
, 1)) != MPI_IOC_STATE_READY
) {
3889 if (sleepFlag
!= CAN_SLEEP
)
3892 printk(MYIOC_s_ERR_FMT
"Wait IOC_READY state timeout(%d)!\n",
3893 ioc
->name
, (int)((count
+5)/HZ
));
3897 if (sleepFlag
== CAN_SLEEP
) {
3900 mdelay (1); /* 1 msec delay */
3905 * Cleanup all event stuff for this IOC; re-issue EventNotification
3906 * request if needed.
3908 if (ioc
->facts
.Function
)
3909 ioc
->facts
.EventState
= 0;
3914 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3916 * initChainBuffers - Allocate memory for and initialize chain buffers
3917 * @ioc: Pointer to MPT_ADAPTER structure
3919 * Allocates memory for and initializes chain buffers,
3920 * chain buffer control arrays and spinlock.
3923 initChainBuffers(MPT_ADAPTER
*ioc
)
3926 int sz
, ii
, num_chain
;
3927 int scale
, num_sge
, numSGE
;
3929 /* ReqToChain size must equal the req_depth
3932 if (ioc
->ReqToChain
== NULL
) {
3933 sz
= ioc
->req_depth
* sizeof(int);
3934 mem
= kmalloc(sz
, GFP_ATOMIC
);
3938 ioc
->ReqToChain
= (int *) mem
;
3939 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReqToChain alloc @ %p, sz=%d bytes\n",
3940 ioc
->name
, mem
, sz
));
3941 mem
= kmalloc(sz
, GFP_ATOMIC
);
3945 ioc
->RequestNB
= (int *) mem
;
3946 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestNB alloc @ %p, sz=%d bytes\n",
3947 ioc
->name
, mem
, sz
));
3949 for (ii
= 0; ii
< ioc
->req_depth
; ii
++) {
3950 ioc
->ReqToChain
[ii
] = MPT_HOST_NO_CHAIN
;
3953 /* ChainToChain size must equal the total number
3954 * of chain buffers to be allocated.
3957 * Calculate the number of chain buffers needed(plus 1) per I/O
3958 * then multiply the maximum number of simultaneous cmds
3960 * num_sge = num sge in request frame + last chain buffer
3961 * scale = num sge per chain buffer if no chain element
3963 scale
= ioc
->req_sz
/(sizeof(dma_addr_t
) + sizeof(u32
));
3964 if (sizeof(dma_addr_t
) == sizeof(u64
))
3965 num_sge
= scale
+ (ioc
->req_sz
- 60) / (sizeof(dma_addr_t
) + sizeof(u32
));
3967 num_sge
= 1+ scale
+ (ioc
->req_sz
- 64) / (sizeof(dma_addr_t
) + sizeof(u32
));
3969 if (sizeof(dma_addr_t
) == sizeof(u64
)) {
3970 numSGE
= (scale
- 1) * (ioc
->facts
.MaxChainDepth
-1) + scale
+
3971 (ioc
->req_sz
- 60) / (sizeof(dma_addr_t
) + sizeof(u32
));
3973 numSGE
= 1 + (scale
- 1) * (ioc
->facts
.MaxChainDepth
-1) + scale
+
3974 (ioc
->req_sz
- 64) / (sizeof(dma_addr_t
) + sizeof(u32
));
3976 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"num_sge=%d numSGE=%d\n",
3977 ioc
->name
, num_sge
, numSGE
));
3979 if ( numSGE
> MPT_SCSI_SG_DEPTH
)
3980 numSGE
= MPT_SCSI_SG_DEPTH
;
3983 while (numSGE
- num_sge
> 0) {
3985 num_sge
+= (scale
- 1);
3989 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Now numSGE=%d num_sge=%d num_chain=%d\n",
3990 ioc
->name
, numSGE
, num_sge
, num_chain
));
3992 if (ioc
->bus_type
== SPI
)
3993 num_chain
*= MPT_SCSI_CAN_QUEUE
;
3995 num_chain
*= MPT_FC_CAN_QUEUE
;
3997 ioc
->num_chain
= num_chain
;
3999 sz
= num_chain
* sizeof(int);
4000 if (ioc
->ChainToChain
== NULL
) {
4001 mem
= kmalloc(sz
, GFP_ATOMIC
);
4005 ioc
->ChainToChain
= (int *) mem
;
4006 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainToChain alloc @ %p, sz=%d bytes\n",
4007 ioc
->name
, mem
, sz
));
4009 mem
= (u8
*) ioc
->ChainToChain
;
4011 memset(mem
, 0xFF, sz
);
4015 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4017 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
4018 * @ioc: Pointer to MPT_ADAPTER structure
4020 * This routine allocates memory for the MPT reply and request frame
4021 * pools (if necessary), and primes the IOC reply FIFO with
4024 * Returns 0 for success, non-zero for failure.
4027 PrimeIocFifos(MPT_ADAPTER
*ioc
)
4030 unsigned long flags
;
4031 dma_addr_t alloc_dma
;
4033 int i
, reply_sz
, sz
, total_size
, num_chain
;
4035 /* Prime reply FIFO... */
4037 if (ioc
->reply_frames
== NULL
) {
4038 if ( (num_chain
= initChainBuffers(ioc
)) < 0)
4041 total_size
= reply_sz
= (ioc
->reply_sz
* ioc
->reply_depth
);
4042 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
4043 ioc
->name
, ioc
->reply_sz
, ioc
->reply_depth
));
4044 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffer sz=%d[%x] bytes\n",
4045 ioc
->name
, reply_sz
, reply_sz
));
4047 sz
= (ioc
->req_sz
* ioc
->req_depth
);
4048 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestBuffer sz=%d bytes, RequestDepth=%d\n",
4049 ioc
->name
, ioc
->req_sz
, ioc
->req_depth
));
4050 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestBuffer sz=%d[%x] bytes\n",
4051 ioc
->name
, sz
, sz
));
4054 sz
= num_chain
* ioc
->req_sz
; /* chain buffer pool size */
4055 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainBuffer sz=%d bytes, ChainDepth=%d\n",
4056 ioc
->name
, ioc
->req_sz
, num_chain
));
4057 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
4058 ioc
->name
, sz
, sz
, num_chain
));
4061 mem
= pci_alloc_consistent(ioc
->pcidev
, total_size
, &alloc_dma
);
4063 printk(MYIOC_s_ERR_FMT
"Unable to allocate Reply, Request, Chain Buffers!\n",
4068 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Total alloc @ %p[%p], sz=%d[%x] bytes\n",
4069 ioc
->name
, mem
, (void *)(ulong
)alloc_dma
, total_size
, total_size
));
4071 memset(mem
, 0, total_size
);
4072 ioc
->alloc_total
+= total_size
;
4074 ioc
->alloc_dma
= alloc_dma
;
4075 ioc
->alloc_sz
= total_size
;
4076 ioc
->reply_frames
= (MPT_FRAME_HDR
*) mem
;
4077 ioc
->reply_frames_low_dma
= (u32
) (alloc_dma
& 0xFFFFFFFF);
4079 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffers @ %p[%p]\n",
4080 ioc
->name
, ioc
->reply_frames
, (void *)(ulong
)alloc_dma
));
4082 alloc_dma
+= reply_sz
;
4085 /* Request FIFO - WE manage this! */
4087 ioc
->req_frames
= (MPT_FRAME_HDR
*) mem
;
4088 ioc
->req_frames_dma
= alloc_dma
;
4090 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestBuffers @ %p[%p]\n",
4091 ioc
->name
, mem
, (void *)(ulong
)alloc_dma
));
4093 ioc
->req_frames_low_dma
= (u32
) (alloc_dma
& 0xFFFFFFFF);
4095 #if defined(CONFIG_MTRR) && 0
4097 * Enable Write Combining MTRR for IOC's memory region.
4098 * (at least as much as we can; "size and base must be
4099 * multiples of 4 kiB"
4101 ioc
->mtrr_reg
= mtrr_add(ioc
->req_frames_dma
,
4103 MTRR_TYPE_WRCOMB
, 1);
4104 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"MTRR region registered (base:size=%08x:%x)\n",
4105 ioc
->name
, ioc
->req_frames_dma
, sz
));
4108 for (i
= 0; i
< ioc
->req_depth
; i
++) {
4109 alloc_dma
+= ioc
->req_sz
;
4113 ioc
->ChainBuffer
= mem
;
4114 ioc
->ChainBufferDMA
= alloc_dma
;
4116 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainBuffers @ %p(%p)\n",
4117 ioc
->name
, ioc
->ChainBuffer
, (void *)(ulong
)ioc
->ChainBufferDMA
));
4119 /* Initialize the free chain Q.
4122 INIT_LIST_HEAD(&ioc
->FreeChainQ
);
4124 /* Post the chain buffers to the FreeChainQ.
4126 mem
= (u8
*)ioc
->ChainBuffer
;
4127 for (i
=0; i
< num_chain
; i
++) {
4128 mf
= (MPT_FRAME_HDR
*) mem
;
4129 list_add_tail(&mf
->u
.frame
.linkage
.list
, &ioc
->FreeChainQ
);
4133 /* Initialize Request frames linked list
4135 alloc_dma
= ioc
->req_frames_dma
;
4136 mem
= (u8
*) ioc
->req_frames
;
4138 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
4139 INIT_LIST_HEAD(&ioc
->FreeQ
);
4140 for (i
= 0; i
< ioc
->req_depth
; i
++) {
4141 mf
= (MPT_FRAME_HDR
*) mem
;
4143 /* Queue REQUESTs *internally*! */
4144 list_add_tail(&mf
->u
.frame
.linkage
.list
, &ioc
->FreeQ
);
4148 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
4150 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
4151 ioc
->sense_buf_pool
=
4152 pci_alloc_consistent(ioc
->pcidev
, sz
, &ioc
->sense_buf_pool_dma
);
4153 if (ioc
->sense_buf_pool
== NULL
) {
4154 printk(MYIOC_s_ERR_FMT
"Unable to allocate Sense Buffers!\n",
4159 ioc
->sense_buf_low_dma
= (u32
) (ioc
->sense_buf_pool_dma
& 0xFFFFFFFF);
4160 ioc
->alloc_total
+= sz
;
4161 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SenseBuffers @ %p[%p]\n",
4162 ioc
->name
, ioc
->sense_buf_pool
, (void *)(ulong
)ioc
->sense_buf_pool_dma
));
4166 /* Post Reply frames to FIFO
4168 alloc_dma
= ioc
->alloc_dma
;
4169 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffers @ %p[%p]\n",
4170 ioc
->name
, ioc
->reply_frames
, (void *)(ulong
)alloc_dma
));
4172 for (i
= 0; i
< ioc
->reply_depth
; i
++) {
4173 /* Write each address to the IOC! */
4174 CHIPREG_WRITE32(&ioc
->chip
->ReplyFifo
, alloc_dma
);
4175 alloc_dma
+= ioc
->reply_sz
;
4181 if (ioc
->alloc
!= NULL
) {
4183 pci_free_consistent(ioc
->pcidev
,
4185 ioc
->alloc
, ioc
->alloc_dma
);
4186 ioc
->reply_frames
= NULL
;
4187 ioc
->req_frames
= NULL
;
4188 ioc
->alloc_total
-= sz
;
4190 if (ioc
->sense_buf_pool
!= NULL
) {
4191 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
4192 pci_free_consistent(ioc
->pcidev
,
4194 ioc
->sense_buf_pool
, ioc
->sense_buf_pool_dma
);
4195 ioc
->sense_buf_pool
= NULL
;
4200 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4202 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4203 * from IOC via doorbell handshake method.
4204 * @ioc: Pointer to MPT_ADAPTER structure
4205 * @reqBytes: Size of the request in bytes
4206 * @req: Pointer to MPT request frame
4207 * @replyBytes: Expected size of the reply in bytes
4208 * @u16reply: Pointer to area where reply should be written
4209 * @maxwait: Max wait time for a reply (in seconds)
4210 * @sleepFlag: Specifies whether the process can sleep
4212 * NOTES: It is the callers responsibility to byte-swap fields in the
4213 * request which are greater than 1 byte in size. It is also the
4214 * callers responsibility to byte-swap response fields which are
4215 * greater than 1 byte in size.
4217 * Returns 0 for success, non-zero for failure.
4220 mpt_handshake_req_reply_wait(MPT_ADAPTER
*ioc
, int reqBytes
, u32
*req
,
4221 int replyBytes
, u16
*u16reply
, int maxwait
, int sleepFlag
)
4223 MPIDefaultReply_t
*mptReply
;
4228 * Get ready to cache a handshake reply
4230 ioc
->hs_reply_idx
= 0;
4231 mptReply
= (MPIDefaultReply_t
*) ioc
->hs_reply
;
4232 mptReply
->MsgLength
= 0;
4235 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4236 * then tell IOC that we want to handshake a request of N words.
4237 * (WRITE u32val to Doorbell reg).
4239 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4240 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
,
4241 ((MPI_FUNCTION_HANDSHAKE
<<MPI_DOORBELL_FUNCTION_SHIFT
) |
4242 ((reqBytes
/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT
)));
4245 * Wait for IOC's doorbell handshake int
4247 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4250 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4251 ioc
->name
, reqBytes
, t
, failcnt
? " - MISSING DOORBELL HANDSHAKE!" : ""));
4253 /* Read doorbell and check for active bit */
4254 if (!(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & MPI_DOORBELL_ACTIVE
))
4258 * Clear doorbell int (WRITE 0 to IntStatus reg),
4259 * then wait for IOC to ACKnowledge that it's ready for
4260 * our handshake request.
4262 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4263 if (!failcnt
&& (t
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
4268 u8
*req_as_bytes
= (u8
*) req
;
4271 * Stuff request words via doorbell handshake,
4272 * with ACK from IOC for each.
4274 for (ii
= 0; !failcnt
&& ii
< reqBytes
/4; ii
++) {
4275 u32 word
= ((req_as_bytes
[(ii
*4) + 0] << 0) |
4276 (req_as_bytes
[(ii
*4) + 1] << 8) |
4277 (req_as_bytes
[(ii
*4) + 2] << 16) |
4278 (req_as_bytes
[(ii
*4) + 3] << 24));
4280 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, word
);
4281 if ((t
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
4285 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Handshake request frame (@%p) header\n", ioc
->name
, req
));
4286 DBG_DUMP_REQUEST_FRAME_HDR(ioc
, (u32
*)req
);
4288 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HandShake request post done, WaitCnt=%d%s\n",
4289 ioc
->name
, t
, failcnt
? " - MISSING DOORBELL ACK!" : ""));
4292 * Wait for completion of doorbell handshake reply from the IOC
4294 if (!failcnt
&& (t
= WaitForDoorbellReply(ioc
, maxwait
, sleepFlag
)) < 0)
4297 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HandShake reply count=%d%s\n",
4298 ioc
->name
, t
, failcnt
? " - MISSING DOORBELL REPLY!" : ""));
4301 * Copy out the cached reply...
4303 for (ii
=0; ii
< min(replyBytes
/2,mptReply
->MsgLength
*2); ii
++)
4304 u16reply
[ii
] = ioc
->hs_reply
[ii
];
4312 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4314 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4315 * @ioc: Pointer to MPT_ADAPTER structure
4316 * @howlong: How long to wait (in seconds)
4317 * @sleepFlag: Specifies whether the process can sleep
4319 * This routine waits (up to ~2 seconds max) for IOC doorbell
4320 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4321 * bit in its IntStatus register being clear.
4323 * Returns a negative value on failure, else wait loop count.
4326 WaitForDoorbellAck(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
4332 cntdn
= 1000 * howlong
;
4334 if (sleepFlag
== CAN_SLEEP
) {
4337 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4338 if (! (intstat
& MPI_HIS_IOP_DOORBELL_STATUS
))
4345 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4346 if (! (intstat
& MPI_HIS_IOP_DOORBELL_STATUS
))
4353 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitForDoorbell ACK (count=%d)\n",
4358 printk(MYIOC_s_ERR_FMT
"Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4359 ioc
->name
, count
, intstat
);
4363 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4365 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4366 * @ioc: Pointer to MPT_ADAPTER structure
4367 * @howlong: How long to wait (in seconds)
4368 * @sleepFlag: Specifies whether the process can sleep
4370 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4371 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4373 * Returns a negative value on failure, else wait loop count.
4376 WaitForDoorbellInt(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
4382 cntdn
= 1000 * howlong
;
4383 if (sleepFlag
== CAN_SLEEP
) {
4385 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4386 if (intstat
& MPI_HIS_DOORBELL_INTERRUPT
)
4393 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4394 if (intstat
& MPI_HIS_DOORBELL_INTERRUPT
)
4402 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4403 ioc
->name
, count
, howlong
));
4407 printk(MYIOC_s_ERR_FMT
"Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4408 ioc
->name
, count
, intstat
);
4412 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4414 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4415 * @ioc: Pointer to MPT_ADAPTER structure
4416 * @howlong: How long to wait (in seconds)
4417 * @sleepFlag: Specifies whether the process can sleep
4419 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4420 * Reply is cached to IOC private area large enough to hold a maximum
4421 * of 128 bytes of reply data.
4423 * Returns a negative value on failure, else size of reply in WORDS.
4426 WaitForDoorbellReply(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
4431 u16
*hs_reply
= ioc
->hs_reply
;
4432 volatile MPIDefaultReply_t
*mptReply
= (MPIDefaultReply_t
*) ioc
->hs_reply
;
4435 hs_reply
[0] = hs_reply
[1] = hs_reply
[7] = 0;
4438 * Get first two u16's so we can look at IOC's intended reply MsgLength
4441 if ((t
= WaitForDoorbellInt(ioc
, howlong
, sleepFlag
)) < 0) {
4444 hs_reply
[u16cnt
++] = le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4445 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4446 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4449 hs_reply
[u16cnt
++] = le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4450 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4454 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitCnt=%d First handshake reply word=%08x%s\n",
4455 ioc
->name
, t
, le32_to_cpu(*(u32
*)hs_reply
),
4456 failcnt
? " - MISSING DOORBELL HANDSHAKE!" : ""));
4459 * If no error (and IOC said MsgLength is > 0), piece together
4460 * reply 16 bits at a time.
4462 for (u16cnt
=2; !failcnt
&& u16cnt
< (2 * mptReply
->MsgLength
); u16cnt
++) {
4463 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4465 hword
= le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4466 /* don't overflow our IOC hs_reply[] buffer! */
4467 if (u16cnt
< sizeof(ioc
->hs_reply
) / sizeof(ioc
->hs_reply
[0]))
4468 hs_reply
[u16cnt
] = hword
;
4469 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4472 if (!failcnt
&& (t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4474 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4477 printk(MYIOC_s_ERR_FMT
"Handshake reply failure!\n",
4482 else if (u16cnt
!= (2 * mptReply
->MsgLength
)) {
4485 else if ((mptReply
->IOCStatus
& MPI_IOCSTATUS_MASK
) != MPI_IOCSTATUS_SUCCESS
) {
4490 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Got Handshake reply:\n", ioc
->name
));
4491 DBG_DUMP_REPLY_FRAME(ioc
, (u32
*)mptReply
);
4493 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4494 ioc
->name
, t
, u16cnt
/2));
4498 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4500 * GetLanConfigPages - Fetch LANConfig pages.
4501 * @ioc: Pointer to MPT_ADAPTER structure
4503 * Return: 0 for success
4504 * -ENOMEM if no memory available
4505 * -EPERM if not allowed due to ISR context
4506 * -EAGAIN if no msg frames currently available
4507 * -EFAULT for non-successful reply or no reply (timeout)
4510 GetLanConfigPages(MPT_ADAPTER
*ioc
)
4512 ConfigPageHeader_t hdr
;
4514 LANPage0_t
*ppage0_alloc
;
4515 dma_addr_t page0_dma
;
4516 LANPage1_t
*ppage1_alloc
;
4517 dma_addr_t page1_dma
;
4522 /* Get LAN Page 0 header */
4523 hdr
.PageVersion
= 0;
4526 hdr
.PageType
= MPI_CONFIG_PAGETYPE_LAN
;
4527 cfg
.cfghdr
.hdr
= &hdr
;
4529 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4534 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
4537 if (hdr
.PageLength
> 0) {
4538 data_sz
= hdr
.PageLength
* 4;
4539 ppage0_alloc
= (LANPage0_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page0_dma
);
4542 memset((u8
*)ppage0_alloc
, 0, data_sz
);
4543 cfg
.physAddr
= page0_dma
;
4544 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4546 if ((rc
= mpt_config(ioc
, &cfg
)) == 0) {
4548 copy_sz
= min_t(int, sizeof(LANPage0_t
), data_sz
);
4549 memcpy(&ioc
->lan_cnfg_page0
, ppage0_alloc
, copy_sz
);
4553 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage0_alloc
, page0_dma
);
4556 * Normalize endianness of structure data,
4557 * by byte-swapping all > 1 byte fields!
4566 /* Get LAN Page 1 header */
4567 hdr
.PageVersion
= 0;
4570 hdr
.PageType
= MPI_CONFIG_PAGETYPE_LAN
;
4571 cfg
.cfghdr
.hdr
= &hdr
;
4573 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4577 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
4580 if (hdr
.PageLength
== 0)
4583 data_sz
= hdr
.PageLength
* 4;
4585 ppage1_alloc
= (LANPage1_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page1_dma
);
4587 memset((u8
*)ppage1_alloc
, 0, data_sz
);
4588 cfg
.physAddr
= page1_dma
;
4589 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4591 if ((rc
= mpt_config(ioc
, &cfg
)) == 0) {
4593 copy_sz
= min_t(int, sizeof(LANPage1_t
), data_sz
);
4594 memcpy(&ioc
->lan_cnfg_page1
, ppage1_alloc
, copy_sz
);
4597 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage1_alloc
, page1_dma
);
4600 * Normalize endianness of structure data,
4601 * by byte-swapping all > 1 byte fields!
4609 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4611 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
4612 * @ioc: Pointer to MPT_ADAPTER structure
4613 * @persist_opcode: see below
4615 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4616 * devices not currently present.
4617 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4619 * NOTE: Don't use not this function during interrupt time.
4621 * Returns 0 for success, non-zero error
4624 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4626 mptbase_sas_persist_operation(MPT_ADAPTER
*ioc
, u8 persist_opcode
)
4628 SasIoUnitControlRequest_t
*sasIoUnitCntrReq
;
4629 SasIoUnitControlReply_t
*sasIoUnitCntrReply
;
4630 MPT_FRAME_HDR
*mf
= NULL
;
4631 MPIHeader_t
*mpi_hdr
;
4634 /* insure garbage is not sent to fw */
4635 switch(persist_opcode
) {
4637 case MPI_SAS_OP_CLEAR_NOT_PRESENT
:
4638 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT
:
4646 printk("%s: persist_opcode=%x\n",__FUNCTION__
, persist_opcode
);
4648 /* Get a MF for this command.
4650 if ((mf
= mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
4651 printk("%s: no msg frames!\n",__FUNCTION__
);
4655 mpi_hdr
= (MPIHeader_t
*) mf
;
4656 sasIoUnitCntrReq
= (SasIoUnitControlRequest_t
*)mf
;
4657 memset(sasIoUnitCntrReq
,0,sizeof(SasIoUnitControlRequest_t
));
4658 sasIoUnitCntrReq
->Function
= MPI_FUNCTION_SAS_IO_UNIT_CONTROL
;
4659 sasIoUnitCntrReq
->MsgContext
= mpi_hdr
->MsgContext
;
4660 sasIoUnitCntrReq
->Operation
= persist_opcode
;
4662 init_timer(&ioc
->persist_timer
);
4663 ioc
->persist_timer
.data
= (unsigned long) ioc
;
4664 ioc
->persist_timer
.function
= mpt_timer_expired
;
4665 ioc
->persist_timer
.expires
= jiffies
+ HZ
*10 /* 10 sec */;
4666 ioc
->persist_wait_done
=0;
4667 add_timer(&ioc
->persist_timer
);
4668 mpt_put_msg_frame(mpt_base_index
, ioc
, mf
);
4669 wait_event(mpt_waitq
, ioc
->persist_wait_done
);
4671 sasIoUnitCntrReply
=
4672 (SasIoUnitControlReply_t
*)ioc
->persist_reply_frame
;
4673 if (le16_to_cpu(sasIoUnitCntrReply
->IOCStatus
) != MPI_IOCSTATUS_SUCCESS
) {
4674 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4676 sasIoUnitCntrReply
->IOCStatus
,
4677 sasIoUnitCntrReply
->IOCLogInfo
);
4681 printk("%s: success\n",__FUNCTION__
);
4685 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4688 mptbase_raid_process_event_data(MPT_ADAPTER
*ioc
,
4689 MpiEventDataRaid_t
* pRaidEventData
)
4698 volume
= pRaidEventData
->VolumeID
;
4699 reason
= pRaidEventData
->ReasonCode
;
4700 disk
= pRaidEventData
->PhysDiskNum
;
4701 status
= le32_to_cpu(pRaidEventData
->SettingsStatus
);
4702 flags
= (status
>> 0) & 0xff;
4703 state
= (status
>> 8) & 0xff;
4705 if (reason
== MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
) {
4709 if ((reason
>= MPI_EVENT_RAID_RC_PHYSDISK_CREATED
&&
4710 reason
<= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
) ||
4711 (reason
== MPI_EVENT_RAID_RC_SMART_DATA
)) {
4712 printk(MYIOC_s_INFO_FMT
"RAID STATUS CHANGE for PhysDisk %d id=%d\n",
4713 ioc
->name
, disk
, volume
);
4715 printk(MYIOC_s_INFO_FMT
"RAID STATUS CHANGE for VolumeID %d\n",
4720 case MPI_EVENT_RAID_RC_VOLUME_CREATED
:
4721 printk(MYIOC_s_INFO_FMT
" volume has been created\n",
4725 case MPI_EVENT_RAID_RC_VOLUME_DELETED
:
4727 printk(MYIOC_s_INFO_FMT
" volume has been deleted\n",
4731 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED
:
4732 printk(MYIOC_s_INFO_FMT
" volume settings have been changed\n",
4736 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED
:
4737 printk(MYIOC_s_INFO_FMT
" volume is now %s%s%s%s\n",
4739 state
== MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
4741 : state
== MPI_RAIDVOL0_STATUS_STATE_DEGRADED
4743 : state
== MPI_RAIDVOL0_STATUS_STATE_FAILED
4746 flags
& MPI_RAIDVOL0_STATUS_FLAG_ENABLED
4748 flags
& MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
4749 ? ", quiesced" : "",
4750 flags
& MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
4751 ? ", resync in progress" : "" );
4754 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED
:
4755 printk(MYIOC_s_INFO_FMT
" volume membership of PhysDisk %d has changed\n",
4759 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED
:
4760 printk(MYIOC_s_INFO_FMT
" PhysDisk has been created\n",
4764 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED
:
4765 printk(MYIOC_s_INFO_FMT
" PhysDisk has been deleted\n",
4769 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED
:
4770 printk(MYIOC_s_INFO_FMT
" PhysDisk settings have been changed\n",
4774 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
:
4775 printk(MYIOC_s_INFO_FMT
" PhysDisk is now %s%s%s\n",
4777 state
== MPI_PHYSDISK0_STATUS_ONLINE
4779 : state
== MPI_PHYSDISK0_STATUS_MISSING
4781 : state
== MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
4783 : state
== MPI_PHYSDISK0_STATUS_FAILED
4785 : state
== MPI_PHYSDISK0_STATUS_INITIALIZING
4787 : state
== MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
4788 ? "offline requested"
4789 : state
== MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
4790 ? "failed requested"
4791 : state
== MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
4794 flags
& MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
4795 ? ", out of sync" : "",
4796 flags
& MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
4797 ? ", quiesced" : "" );
4800 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
:
4801 printk(MYIOC_s_INFO_FMT
" Domain Validation needed for PhysDisk %d\n",
4805 case MPI_EVENT_RAID_RC_SMART_DATA
:
4806 printk(MYIOC_s_INFO_FMT
" SMART data received, ASC/ASCQ = %02xh/%02xh\n",
4807 ioc
->name
, pRaidEventData
->ASC
, pRaidEventData
->ASCQ
);
4810 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED
:
4811 printk(MYIOC_s_INFO_FMT
" replacement of PhysDisk %d has started\n",
4817 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4819 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4820 * @ioc: Pointer to MPT_ADAPTER structure
4822 * Returns: 0 for success
4823 * -ENOMEM if no memory available
4824 * -EPERM if not allowed due to ISR context
4825 * -EAGAIN if no msg frames currently available
4826 * -EFAULT for non-successful reply or no reply (timeout)
4829 GetIoUnitPage2(MPT_ADAPTER
*ioc
)
4831 ConfigPageHeader_t hdr
;
4833 IOUnitPage2_t
*ppage_alloc
;
4834 dma_addr_t page_dma
;
4838 /* Get the page header */
4839 hdr
.PageVersion
= 0;
4842 hdr
.PageType
= MPI_CONFIG_PAGETYPE_IO_UNIT
;
4843 cfg
.cfghdr
.hdr
= &hdr
;
4845 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4850 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
4853 if (hdr
.PageLength
== 0)
4856 /* Read the config page */
4857 data_sz
= hdr
.PageLength
* 4;
4859 ppage_alloc
= (IOUnitPage2_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page_dma
);
4861 memset((u8
*)ppage_alloc
, 0, data_sz
);
4862 cfg
.physAddr
= page_dma
;
4863 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4865 /* If Good, save data */
4866 if ((rc
= mpt_config(ioc
, &cfg
)) == 0)
4867 ioc
->biosVersion
= le32_to_cpu(ppage_alloc
->BiosVersion
);
4869 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage_alloc
, page_dma
);
4875 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4877 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4878 * @ioc: Pointer to a Adapter Strucutre
4879 * @portnum: IOC port number
4881 * Return: -EFAULT if read of config page header fails
4883 * If read of SCSI Port Page 0 fails,
4884 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4885 * Adapter settings: async, narrow
4887 * If read of SCSI Port Page 2 fails,
4888 * Adapter settings valid
4889 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4894 * CHECK - what type of locking mechanisms should be used????
4897 mpt_GetScsiPortSettings(MPT_ADAPTER
*ioc
, int portnum
)
4902 ConfigPageHeader_t header
;
4908 if (!ioc
->spi_data
.nvram
) {
4911 sz
= MPT_MAX_SCSI_DEVICES
* sizeof(int);
4912 mem
= kmalloc(sz
, GFP_ATOMIC
);
4916 ioc
->spi_data
.nvram
= (int *) mem
;
4918 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SCSI device NVRAM settings @ %p, sz=%d\n",
4919 ioc
->name
, ioc
->spi_data
.nvram
, sz
));
4922 /* Invalidate NVRAM information
4924 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
4925 ioc
->spi_data
.nvram
[ii
] = MPT_HOST_NVRAM_INVALID
;
4928 /* Read SPP0 header, allocate memory, then read page.
4930 header
.PageVersion
= 0;
4931 header
.PageLength
= 0;
4932 header
.PageNumber
= 0;
4933 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_PORT
;
4934 cfg
.cfghdr
.hdr
= &header
;
4936 cfg
.pageAddr
= portnum
;
4937 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4939 cfg
.timeout
= 0; /* use default */
4940 if (mpt_config(ioc
, &cfg
) != 0)
4943 if (header
.PageLength
> 0) {
4944 pbuf
= pci_alloc_consistent(ioc
->pcidev
, header
.PageLength
* 4, &buf_dma
);
4946 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4947 cfg
.physAddr
= buf_dma
;
4948 if (mpt_config(ioc
, &cfg
) != 0) {
4949 ioc
->spi_data
.maxBusWidth
= MPT_NARROW
;
4950 ioc
->spi_data
.maxSyncOffset
= 0;
4951 ioc
->spi_data
.minSyncFactor
= MPT_ASYNC
;
4952 ioc
->spi_data
.busType
= MPT_HOST_BUS_UNKNOWN
;
4954 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4955 "Unable to read PortPage0 minSyncFactor=%x\n",
4956 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
4958 /* Save the Port Page 0 data
4960 SCSIPortPage0_t
*pPP0
= (SCSIPortPage0_t
*) pbuf
;
4961 pPP0
->Capabilities
= le32_to_cpu(pPP0
->Capabilities
);
4962 pPP0
->PhysicalInterface
= le32_to_cpu(pPP0
->PhysicalInterface
);
4964 if ( (pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_QAS
) == 0 ) {
4965 ioc
->spi_data
.noQas
|= MPT_TARGET_NO_NEGO_QAS
;
4966 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4967 "noQas due to Capabilities=%x\n",
4968 ioc
->name
, pPP0
->Capabilities
));
4970 ioc
->spi_data
.maxBusWidth
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_WIDE
? 1 : 0;
4971 data
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK
;
4973 ioc
->spi_data
.maxSyncOffset
= (u8
) (data
>> 16);
4974 data
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK
;
4975 ioc
->spi_data
.minSyncFactor
= (u8
) (data
>> 8);
4976 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4977 "PortPage0 minSyncFactor=%x\n",
4978 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
4980 ioc
->spi_data
.maxSyncOffset
= 0;
4981 ioc
->spi_data
.minSyncFactor
= MPT_ASYNC
;
4984 ioc
->spi_data
.busType
= pPP0
->PhysicalInterface
& MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK
;
4986 /* Update the minSyncFactor based on bus type.
4988 if ((ioc
->spi_data
.busType
== MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD
) ||
4989 (ioc
->spi_data
.busType
== MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE
)) {
4991 if (ioc
->spi_data
.minSyncFactor
< MPT_ULTRA
) {
4992 ioc
->spi_data
.minSyncFactor
= MPT_ULTRA
;
4993 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4994 "HVD or SE detected, minSyncFactor=%x\n",
4995 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
5000 pci_free_consistent(ioc
->pcidev
, header
.PageLength
* 4, pbuf
, buf_dma
);
5005 /* SCSI Port Page 2 - Read the header then the page.
5007 header
.PageVersion
= 0;
5008 header
.PageLength
= 0;
5009 header
.PageNumber
= 2;
5010 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_PORT
;
5011 cfg
.cfghdr
.hdr
= &header
;
5013 cfg
.pageAddr
= portnum
;
5014 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5016 if (mpt_config(ioc
, &cfg
) != 0)
5019 if (header
.PageLength
> 0) {
5020 /* Allocate memory and read SCSI Port Page 2
5022 pbuf
= pci_alloc_consistent(ioc
->pcidev
, header
.PageLength
* 4, &buf_dma
);
5024 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_NVRAM
;
5025 cfg
.physAddr
= buf_dma
;
5026 if (mpt_config(ioc
, &cfg
) != 0) {
5027 /* Nvram data is left with INVALID mark
5030 } else if (ioc
->pcidev
->vendor
== PCI_VENDOR_ID_ATTO
) {
5032 /* This is an ATTO adapter, read Page2 accordingly
5034 ATTO_SCSIPortPage2_t
*pPP2
= (ATTO_SCSIPortPage2_t
*) pbuf
;
5035 ATTODeviceInfo_t
*pdevice
= NULL
;
5038 /* Save the Port Page 2 data
5039 * (reformat into a 32bit quantity)
5041 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
5042 pdevice
= &pPP2
->DeviceSettings
[ii
];
5043 ATTOFlags
= le16_to_cpu(pdevice
->ATTOFlags
);
5046 /* Translate ATTO device flags to LSI format
5048 if (ATTOFlags
& ATTOFLAG_DISC
)
5049 data
|= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE
);
5050 if (ATTOFlags
& ATTOFLAG_ID_ENB
)
5051 data
|= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE
);
5052 if (ATTOFlags
& ATTOFLAG_LUN_ENB
)
5053 data
|= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE
);
5054 if (ATTOFlags
& ATTOFLAG_TAGGED
)
5055 data
|= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE
);
5056 if (!(ATTOFlags
& ATTOFLAG_WIDE_ENB
))
5057 data
|= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE
);
5059 data
= (data
<< 16) | (pdevice
->Period
<< 8) | 10;
5060 ioc
->spi_data
.nvram
[ii
] = data
;
5063 SCSIPortPage2_t
*pPP2
= (SCSIPortPage2_t
*) pbuf
;
5064 MpiDeviceInfo_t
*pdevice
= NULL
;
5067 * Save "Set to Avoid SCSI Bus Resets" flag
5069 ioc
->spi_data
.bus_reset
=
5070 (le32_to_cpu(pPP2
->PortFlags
) &
5071 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET
) ?
5074 /* Save the Port Page 2 data
5075 * (reformat into a 32bit quantity)
5077 data
= le32_to_cpu(pPP2
->PortFlags
) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK
;
5078 ioc
->spi_data
.PortFlags
= data
;
5079 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
5080 pdevice
= &pPP2
->DeviceSettings
[ii
];
5081 data
= (le16_to_cpu(pdevice
->DeviceFlags
) << 16) |
5082 (pdevice
->SyncFactor
<< 8) | pdevice
->Timeout
;
5083 ioc
->spi_data
.nvram
[ii
] = data
;
5087 pci_free_consistent(ioc
->pcidev
, header
.PageLength
* 4, pbuf
, buf_dma
);
5091 /* Update Adapter limits with those from NVRAM
5092 * Comment: Don't need to do this. Target performance
5093 * parameters will never exceed the adapters limits.
5099 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5101 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
5102 * @ioc: Pointer to a Adapter Strucutre
5103 * @portnum: IOC port number
5105 * Return: -EFAULT if read of config page header fails
5109 mpt_readScsiDevicePageHeaders(MPT_ADAPTER
*ioc
, int portnum
)
5112 ConfigPageHeader_t header
;
5114 /* Read the SCSI Device Page 1 header
5116 header
.PageVersion
= 0;
5117 header
.PageLength
= 0;
5118 header
.PageNumber
= 1;
5119 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_DEVICE
;
5120 cfg
.cfghdr
.hdr
= &header
;
5122 cfg
.pageAddr
= portnum
;
5123 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5126 if (mpt_config(ioc
, &cfg
) != 0)
5129 ioc
->spi_data
.sdp1version
= cfg
.cfghdr
.hdr
->PageVersion
;
5130 ioc
->spi_data
.sdp1length
= cfg
.cfghdr
.hdr
->PageLength
;
5132 header
.PageVersion
= 0;
5133 header
.PageLength
= 0;
5134 header
.PageNumber
= 0;
5135 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_DEVICE
;
5136 if (mpt_config(ioc
, &cfg
) != 0)
5139 ioc
->spi_data
.sdp0version
= cfg
.cfghdr
.hdr
->PageVersion
;
5140 ioc
->spi_data
.sdp0length
= cfg
.cfghdr
.hdr
->PageLength
;
5142 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Headers: 0: version %d length %d\n",
5143 ioc
->name
, ioc
->spi_data
.sdp0version
, ioc
->spi_data
.sdp0length
));
5145 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Headers: 1: version %d length %d\n",
5146 ioc
->name
, ioc
->spi_data
.sdp1version
, ioc
->spi_data
.sdp1length
));
5151 * mpt_inactive_raid_list_free - This clears this link list.
5152 * @ioc : pointer to per adapter structure
5155 mpt_inactive_raid_list_free(MPT_ADAPTER
*ioc
)
5157 struct inactive_raid_component_info
*component_info
, *pNext
;
5159 if (list_empty(&ioc
->raid_data
.inactive_list
))
5162 down(&ioc
->raid_data
.inactive_list_mutex
);
5163 list_for_each_entry_safe(component_info
, pNext
,
5164 &ioc
->raid_data
.inactive_list
, list
) {
5165 list_del(&component_info
->list
);
5166 kfree(component_info
);
5168 up(&ioc
->raid_data
.inactive_list_mutex
);
5172 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5174 * @ioc : pointer to per adapter structure
5175 * @channel : volume channel
5176 * @id : volume target id
5179 mpt_inactive_raid_volumes(MPT_ADAPTER
*ioc
, u8 channel
, u8 id
)
5182 ConfigPageHeader_t hdr
;
5183 dma_addr_t dma_handle
;
5184 pRaidVolumePage0_t buffer
= NULL
;
5186 RaidPhysDiskPage0_t phys_disk
;
5187 struct inactive_raid_component_info
*component_info
;
5188 int handle_inactive_volumes
;
5190 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5191 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5192 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_VOLUME
;
5193 cfg
.pageAddr
= (channel
<< 8) + id
;
5194 cfg
.cfghdr
.hdr
= &hdr
;
5195 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5197 if (mpt_config(ioc
, &cfg
) != 0)
5200 if (!hdr
.PageLength
)
5203 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5209 cfg
.physAddr
= dma_handle
;
5210 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5212 if (mpt_config(ioc
, &cfg
) != 0)
5215 if (!buffer
->NumPhysDisks
)
5218 handle_inactive_volumes
=
5219 (buffer
->VolumeStatus
.Flags
& MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE
||
5220 (buffer
->VolumeStatus
.Flags
& MPI_RAIDVOL0_STATUS_FLAG_ENABLED
) == 0 ||
5221 buffer
->VolumeStatus
.State
== MPI_RAIDVOL0_STATUS_STATE_FAILED
||
5222 buffer
->VolumeStatus
.State
== MPI_RAIDVOL0_STATUS_STATE_MISSING
) ? 1 : 0;
5224 if (!handle_inactive_volumes
)
5227 down(&ioc
->raid_data
.inactive_list_mutex
);
5228 for (i
= 0; i
< buffer
->NumPhysDisks
; i
++) {
5229 if(mpt_raid_phys_disk_pg0(ioc
,
5230 buffer
->PhysDisk
[i
].PhysDiskNum
, &phys_disk
) != 0)
5233 if ((component_info
= kmalloc(sizeof (*component_info
),
5234 GFP_KERNEL
)) == NULL
)
5237 component_info
->volumeID
= id
;
5238 component_info
->volumeBus
= channel
;
5239 component_info
->d
.PhysDiskNum
= phys_disk
.PhysDiskNum
;
5240 component_info
->d
.PhysDiskBus
= phys_disk
.PhysDiskBus
;
5241 component_info
->d
.PhysDiskID
= phys_disk
.PhysDiskID
;
5242 component_info
->d
.PhysDiskIOC
= phys_disk
.PhysDiskIOC
;
5244 list_add_tail(&component_info
->list
,
5245 &ioc
->raid_data
.inactive_list
);
5247 up(&ioc
->raid_data
.inactive_list_mutex
);
5251 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5256 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5257 * @ioc: Pointer to a Adapter Structure
5258 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5259 * @phys_disk: requested payload data returned
5263 * -EFAULT if read of config page header fails or data pointer not NULL
5264 * -ENOMEM if pci_alloc failed
5267 mpt_raid_phys_disk_pg0(MPT_ADAPTER
*ioc
, u8 phys_disk_num
, pRaidPhysDiskPage0_t phys_disk
)
5270 ConfigPageHeader_t hdr
;
5271 dma_addr_t dma_handle
;
5272 pRaidPhysDiskPage0_t buffer
= NULL
;
5275 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5276 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5278 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_PHYSDISK
;
5279 cfg
.cfghdr
.hdr
= &hdr
;
5281 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5283 if (mpt_config(ioc
, &cfg
) != 0) {
5288 if (!hdr
.PageLength
) {
5293 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5301 cfg
.physAddr
= dma_handle
;
5302 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5303 cfg
.pageAddr
= phys_disk_num
;
5305 if (mpt_config(ioc
, &cfg
) != 0) {
5311 memcpy(phys_disk
, buffer
, sizeof(*buffer
));
5312 phys_disk
->MaxLBA
= le32_to_cpu(buffer
->MaxLBA
);
5317 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5324 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5325 * @ioc: Pointer to a Adapter Strucutre
5326 * @portnum: IOC port number
5330 * -EFAULT if read of config page header fails or data pointer not NULL
5331 * -ENOMEM if pci_alloc failed
5334 mpt_findImVolumes(MPT_ADAPTER
*ioc
)
5338 dma_addr_t ioc2_dma
;
5340 ConfigPageHeader_t header
;
5345 if (!ioc
->ir_firmware
)
5348 /* Free the old page
5350 kfree(ioc
->raid_data
.pIocPg2
);
5351 ioc
->raid_data
.pIocPg2
= NULL
;
5352 mpt_inactive_raid_list_free(ioc
);
5354 /* Read IOCP2 header then the page.
5356 header
.PageVersion
= 0;
5357 header
.PageLength
= 0;
5358 header
.PageNumber
= 2;
5359 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
5360 cfg
.cfghdr
.hdr
= &header
;
5363 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5366 if (mpt_config(ioc
, &cfg
) != 0)
5369 if (header
.PageLength
== 0)
5372 iocpage2sz
= header
.PageLength
* 4;
5373 pIoc2
= pci_alloc_consistent(ioc
->pcidev
, iocpage2sz
, &ioc2_dma
);
5377 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5378 cfg
.physAddr
= ioc2_dma
;
5379 if (mpt_config(ioc
, &cfg
) != 0)
5382 mem
= kmalloc(iocpage2sz
, GFP_KERNEL
);
5386 memcpy(mem
, (u8
*)pIoc2
, iocpage2sz
);
5387 ioc
->raid_data
.pIocPg2
= (IOCPage2_t
*) mem
;
5389 mpt_read_ioc_pg_3(ioc
);
5391 for (i
= 0; i
< pIoc2
->NumActiveVolumes
; i
++)
5392 mpt_inactive_raid_volumes(ioc
,
5393 pIoc2
->RaidVolume
[i
].VolumeBus
,
5394 pIoc2
->RaidVolume
[i
].VolumeID
);
5397 pci_free_consistent(ioc
->pcidev
, iocpage2sz
, pIoc2
, ioc2_dma
);
5403 mpt_read_ioc_pg_3(MPT_ADAPTER
*ioc
)
5408 ConfigPageHeader_t header
;
5409 dma_addr_t ioc3_dma
;
5412 /* Free the old page
5414 kfree(ioc
->raid_data
.pIocPg3
);
5415 ioc
->raid_data
.pIocPg3
= NULL
;
5417 /* There is at least one physical disk.
5418 * Read and save IOC Page 3
5420 header
.PageVersion
= 0;
5421 header
.PageLength
= 0;
5422 header
.PageNumber
= 3;
5423 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
5424 cfg
.cfghdr
.hdr
= &header
;
5427 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5430 if (mpt_config(ioc
, &cfg
) != 0)
5433 if (header
.PageLength
== 0)
5436 /* Read Header good, alloc memory
5438 iocpage3sz
= header
.PageLength
* 4;
5439 pIoc3
= pci_alloc_consistent(ioc
->pcidev
, iocpage3sz
, &ioc3_dma
);
5443 /* Read the Page and save the data
5444 * into malloc'd memory.
5446 cfg
.physAddr
= ioc3_dma
;
5447 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5448 if (mpt_config(ioc
, &cfg
) == 0) {
5449 mem
= kmalloc(iocpage3sz
, GFP_KERNEL
);
5451 memcpy(mem
, (u8
*)pIoc3
, iocpage3sz
);
5452 ioc
->raid_data
.pIocPg3
= (IOCPage3_t
*) mem
;
5456 pci_free_consistent(ioc
->pcidev
, iocpage3sz
, pIoc3
, ioc3_dma
);
5462 mpt_read_ioc_pg_4(MPT_ADAPTER
*ioc
)
5466 ConfigPageHeader_t header
;
5467 dma_addr_t ioc4_dma
;
5470 /* Read and save IOC Page 4
5472 header
.PageVersion
= 0;
5473 header
.PageLength
= 0;
5474 header
.PageNumber
= 4;
5475 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
5476 cfg
.cfghdr
.hdr
= &header
;
5479 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5482 if (mpt_config(ioc
, &cfg
) != 0)
5485 if (header
.PageLength
== 0)
5488 if ( (pIoc4
= ioc
->spi_data
.pIocPg4
) == NULL
) {
5489 iocpage4sz
= (header
.PageLength
+ 4) * 4; /* Allow 4 additional SEP's */
5490 pIoc4
= pci_alloc_consistent(ioc
->pcidev
, iocpage4sz
, &ioc4_dma
);
5493 ioc
->alloc_total
+= iocpage4sz
;
5495 ioc4_dma
= ioc
->spi_data
.IocPg4_dma
;
5496 iocpage4sz
= ioc
->spi_data
.IocPg4Sz
;
5499 /* Read the Page into dma memory.
5501 cfg
.physAddr
= ioc4_dma
;
5502 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5503 if (mpt_config(ioc
, &cfg
) == 0) {
5504 ioc
->spi_data
.pIocPg4
= (IOCPage4_t
*) pIoc4
;
5505 ioc
->spi_data
.IocPg4_dma
= ioc4_dma
;
5506 ioc
->spi_data
.IocPg4Sz
= iocpage4sz
;
5508 pci_free_consistent(ioc
->pcidev
, iocpage4sz
, pIoc4
, ioc4_dma
);
5509 ioc
->spi_data
.pIocPg4
= NULL
;
5510 ioc
->alloc_total
-= iocpage4sz
;
5515 mpt_read_ioc_pg_1(MPT_ADAPTER
*ioc
)
5519 ConfigPageHeader_t header
;
5520 dma_addr_t ioc1_dma
;
5524 /* Check the Coalescing Timeout in IOC Page 1
5526 header
.PageVersion
= 0;
5527 header
.PageLength
= 0;
5528 header
.PageNumber
= 1;
5529 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
5530 cfg
.cfghdr
.hdr
= &header
;
5533 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5536 if (mpt_config(ioc
, &cfg
) != 0)
5539 if (header
.PageLength
== 0)
5542 /* Read Header good, alloc memory
5544 iocpage1sz
= header
.PageLength
* 4;
5545 pIoc1
= pci_alloc_consistent(ioc
->pcidev
, iocpage1sz
, &ioc1_dma
);
5549 /* Read the Page and check coalescing timeout
5551 cfg
.physAddr
= ioc1_dma
;
5552 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5553 if (mpt_config(ioc
, &cfg
) == 0) {
5555 tmp
= le32_to_cpu(pIoc1
->Flags
) & MPI_IOCPAGE1_REPLY_COALESCING
;
5556 if (tmp
== MPI_IOCPAGE1_REPLY_COALESCING
) {
5557 tmp
= le32_to_cpu(pIoc1
->CoalescingTimeout
);
5559 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Coalescing Enabled Timeout = %d\n",
5562 if (tmp
> MPT_COALESCING_TIMEOUT
) {
5563 pIoc1
->CoalescingTimeout
= cpu_to_le32(MPT_COALESCING_TIMEOUT
);
5565 /* Write NVRAM and current
5568 cfg
.action
= MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT
;
5569 if (mpt_config(ioc
, &cfg
) == 0) {
5570 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Reset Current Coalescing Timeout to = %d\n",
5571 ioc
->name
, MPT_COALESCING_TIMEOUT
));
5573 cfg
.action
= MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM
;
5574 if (mpt_config(ioc
, &cfg
) == 0) {
5575 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5576 "Reset NVRAM Coalescing Timeout to = %d\n",
5577 ioc
->name
, MPT_COALESCING_TIMEOUT
));
5579 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5580 "Reset NVRAM Coalescing Timeout Failed\n",
5585 dprintk(ioc
, printk(MYIOC_s_WARN_FMT
5586 "Reset of Current Coalescing Timeout Failed!\n",
5592 dprintk(ioc
, printk(MYIOC_s_WARN_FMT
"Coalescing Disabled\n", ioc
->name
));
5596 pci_free_consistent(ioc
->pcidev
, iocpage1sz
, pIoc1
, ioc1_dma
);
5602 mpt_get_manufacturing_pg_0(MPT_ADAPTER
*ioc
)
5605 ConfigPageHeader_t hdr
;
5607 ManufacturingPage0_t
*pbuf
= NULL
;
5609 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5610 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5612 hdr
.PageType
= MPI_CONFIG_PAGETYPE_MANUFACTURING
;
5613 cfg
.cfghdr
.hdr
= &hdr
;
5615 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5618 if (mpt_config(ioc
, &cfg
) != 0)
5621 if (!cfg
.cfghdr
.hdr
->PageLength
)
5624 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5625 pbuf
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, &buf_dma
);
5629 cfg
.physAddr
= buf_dma
;
5631 if (mpt_config(ioc
, &cfg
) != 0)
5634 memcpy(ioc
->board_name
, pbuf
->BoardName
, sizeof(ioc
->board_name
));
5635 memcpy(ioc
->board_assembly
, pbuf
->BoardAssembly
, sizeof(ioc
->board_assembly
));
5636 memcpy(ioc
->board_tracer
, pbuf
->BoardTracerNumber
, sizeof(ioc
->board_tracer
));
5641 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, pbuf
, buf_dma
);
5644 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5646 * SendEventNotification - Send EventNotification (on or off) request to adapter
5647 * @ioc: Pointer to MPT_ADAPTER structure
5648 * @EvSwitch: Event switch flags
5651 SendEventNotification(MPT_ADAPTER
*ioc
, u8 EvSwitch
)
5653 EventNotification_t
*evnp
;
5655 evnp
= (EventNotification_t
*) mpt_get_msg_frame(mpt_base_index
, ioc
);
5657 devtverboseprintk(ioc
, printk(MYIOC_s_WARN_FMT
"Unable to allocate event request frame!\n",
5661 memset(evnp
, 0, sizeof(*evnp
));
5663 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending EventNotification (%d) request %p\n", ioc
->name
, EvSwitch
, evnp
));
5665 evnp
->Function
= MPI_FUNCTION_EVENT_NOTIFICATION
;
5666 evnp
->ChainOffset
= 0;
5668 evnp
->Switch
= EvSwitch
;
5670 mpt_put_msg_frame(mpt_base_index
, ioc
, (MPT_FRAME_HDR
*)evnp
);
5675 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5677 * SendEventAck - Send EventAck request to MPT adapter.
5678 * @ioc: Pointer to MPT_ADAPTER structure
5679 * @evnp: Pointer to original EventNotification request
5682 SendEventAck(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*evnp
)
5686 if ((pAck
= (EventAck_t
*) mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
5687 dfailprintk(ioc
, printk(MYIOC_s_WARN_FMT
"%s, no msg frames!!\n",
5688 ioc
->name
,__FUNCTION__
));
5692 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending EventAck\n", ioc
->name
));
5694 pAck
->Function
= MPI_FUNCTION_EVENT_ACK
;
5695 pAck
->ChainOffset
= 0;
5696 pAck
->Reserved
[0] = pAck
->Reserved
[1] = 0;
5698 pAck
->Reserved1
[0] = pAck
->Reserved1
[1] = pAck
->Reserved1
[2] = 0;
5699 pAck
->Event
= evnp
->Event
;
5700 pAck
->EventContext
= evnp
->EventContext
;
5702 mpt_put_msg_frame(mpt_base_index
, ioc
, (MPT_FRAME_HDR
*)pAck
);
5707 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5709 * mpt_config - Generic function to issue config message
5710 * @ioc: Pointer to an adapter structure
5711 * @pCfg: Pointer to a configuration structure. Struct contains
5712 * action, page address, direction, physical address
5713 * and pointer to a configuration page header
5714 * Page header is updated.
5716 * Returns 0 for success
5717 * -EPERM if not allowed due to ISR context
5718 * -EAGAIN if no msg frames currently available
5719 * -EFAULT for non-successful reply or no reply (timeout)
5722 mpt_config(MPT_ADAPTER
*ioc
, CONFIGPARMS
*pCfg
)
5725 ConfigExtendedPageHeader_t
*pExtHdr
= NULL
;
5727 unsigned long flags
;
5732 /* Prevent calling wait_event() (below), if caller happens
5733 * to be in ISR context, because that is fatal!
5735 in_isr
= in_interrupt();
5737 dcprintk(ioc
, printk(MYIOC_s_WARN_FMT
"Config request not allowed in ISR context!\n",
5742 /* Get and Populate a free Frame
5744 if ((mf
= mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
5745 dcprintk(ioc
, printk(MYIOC_s_WARN_FMT
"mpt_config: no msg frames!\n",
5749 pReq
= (Config_t
*)mf
;
5750 pReq
->Action
= pCfg
->action
;
5752 pReq
->ChainOffset
= 0;
5753 pReq
->Function
= MPI_FUNCTION_CONFIG
;
5755 /* Assume page type is not extended and clear "reserved" fields. */
5756 pReq
->ExtPageLength
= 0;
5757 pReq
->ExtPageType
= 0;
5760 for (ii
=0; ii
< 8; ii
++)
5761 pReq
->Reserved2
[ii
] = 0;
5763 pReq
->Header
.PageVersion
= pCfg
->cfghdr
.hdr
->PageVersion
;
5764 pReq
->Header
.PageLength
= pCfg
->cfghdr
.hdr
->PageLength
;
5765 pReq
->Header
.PageNumber
= pCfg
->cfghdr
.hdr
->PageNumber
;
5766 pReq
->Header
.PageType
= (pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
);
5768 if ((pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
) == MPI_CONFIG_PAGETYPE_EXTENDED
) {
5769 pExtHdr
= (ConfigExtendedPageHeader_t
*)pCfg
->cfghdr
.ehdr
;
5770 pReq
->ExtPageLength
= cpu_to_le16(pExtHdr
->ExtPageLength
);
5771 pReq
->ExtPageType
= pExtHdr
->ExtPageType
;
5772 pReq
->Header
.PageType
= MPI_CONFIG_PAGETYPE_EXTENDED
;
5774 /* Page Length must be treated as a reserved field for the extended header. */
5775 pReq
->Header
.PageLength
= 0;
5778 pReq
->PageAddress
= cpu_to_le32(pCfg
->pageAddr
);
5780 /* Add a SGE to the config request.
5783 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_WRITE
;
5785 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_READ
;
5787 if ((pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
) == MPI_CONFIG_PAGETYPE_EXTENDED
) {
5788 flagsLength
|= pExtHdr
->ExtPageLength
* 4;
5790 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending Config request type %d, page %d and action %d\n",
5791 ioc
->name
, pReq
->ExtPageType
, pReq
->Header
.PageNumber
, pReq
->Action
));
5794 flagsLength
|= pCfg
->cfghdr
.hdr
->PageLength
* 4;
5796 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending Config request type %d, page %d and action %d\n",
5797 ioc
->name
, pReq
->Header
.PageType
, pReq
->Header
.PageNumber
, pReq
->Action
));
5800 mpt_add_sge((char *)&pReq
->PageBufferSGE
, flagsLength
, pCfg
->physAddr
);
5802 /* Append pCfg pointer to end of mf
5804 *((void **) (((u8
*) mf
) + (ioc
->req_sz
- sizeof(void *)))) = (void *) pCfg
;
5806 /* Initalize the timer
5808 init_timer(&pCfg
->timer
);
5809 pCfg
->timer
.data
= (unsigned long) ioc
;
5810 pCfg
->timer
.function
= mpt_timer_expired
;
5811 pCfg
->wait_done
= 0;
5813 /* Set the timer; ensure 10 second minimum */
5814 if (pCfg
->timeout
< 10)
5815 pCfg
->timer
.expires
= jiffies
+ HZ
*10;
5817 pCfg
->timer
.expires
= jiffies
+ HZ
*pCfg
->timeout
;
5819 /* Add to end of Q, set timer and then issue this command */
5820 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
5821 list_add_tail(&pCfg
->linkage
, &ioc
->configQ
);
5822 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
5824 add_timer(&pCfg
->timer
);
5825 mpt_put_msg_frame(mpt_base_index
, ioc
, mf
);
5826 wait_event(mpt_waitq
, pCfg
->wait_done
);
5828 /* mf has been freed - do not access */
5835 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5837 * mpt_timer_expired - Callback for timer process.
5838 * Used only internal config functionality.
5839 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5842 mpt_timer_expired(unsigned long data
)
5844 MPT_ADAPTER
*ioc
= (MPT_ADAPTER
*) data
;
5846 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mpt_timer_expired! \n", ioc
->name
));
5848 /* Perform a FW reload */
5849 if (mpt_HardResetHandler(ioc
, NO_SLEEP
) < 0)
5850 printk(MYIOC_s_WARN_FMT
"Firmware Reload FAILED!\n", ioc
->name
);
5852 /* No more processing.
5853 * Hard reset clean-up will wake up
5854 * process and free all resources.
5856 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mpt_timer_expired complete!\n", ioc
->name
));
5861 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5863 * mpt_ioc_reset - Base cleanup for hard reset
5864 * @ioc: Pointer to the adapter structure
5865 * @reset_phase: Indicates pre- or post-reset functionality
5867 * Remark: Frees resources with internally generated commands.
5870 mpt_ioc_reset(MPT_ADAPTER
*ioc
, int reset_phase
)
5873 unsigned long flags
;
5875 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5876 ": IOC %s_reset routed to MPT base driver!\n",
5877 ioc
->name
, reset_phase
==MPT_IOC_SETUP_RESET
? "setup" : (
5878 reset_phase
==MPT_IOC_PRE_RESET
? "pre" : "post")));
5880 if (reset_phase
== MPT_IOC_SETUP_RESET
) {
5882 } else if (reset_phase
== MPT_IOC_PRE_RESET
) {
5883 /* If the internal config Q is not empty -
5884 * delete timer. MF resources will be freed when
5885 * the FIFO's are primed.
5887 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
5888 list_for_each_entry(pCfg
, &ioc
->configQ
, linkage
)
5889 del_timer(&pCfg
->timer
);
5890 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
5895 /* Search the configQ for internal commands.
5896 * Flush the Q, and wake up all suspended threads.
5898 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
5899 list_for_each_entry_safe(pCfg
, pNext
, &ioc
->configQ
, linkage
) {
5900 list_del(&pCfg
->linkage
);
5902 pCfg
->status
= MPT_CONFIG_ERROR
;
5903 pCfg
->wait_done
= 1;
5904 wake_up(&mpt_waitq
);
5906 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
5909 return 1; /* currently means nothing really */
5913 #ifdef CONFIG_PROC_FS /* { */
5914 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5916 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5918 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5920 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5922 * Returns 0 for success, non-zero for failure.
5925 procmpt_create(void)
5927 struct proc_dir_entry
*ent
;
5929 mpt_proc_root_dir
= proc_mkdir(MPT_PROCFS_MPTBASEDIR
, NULL
);
5930 if (mpt_proc_root_dir
== NULL
)
5933 ent
= create_proc_entry("summary", S_IFREG
|S_IRUGO
, mpt_proc_root_dir
);
5935 ent
->read_proc
= procmpt_summary_read
;
5937 ent
= create_proc_entry("version", S_IFREG
|S_IRUGO
, mpt_proc_root_dir
);
5939 ent
->read_proc
= procmpt_version_read
;
5944 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5946 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5948 * Returns 0 for success, non-zero for failure.
5951 procmpt_destroy(void)
5953 remove_proc_entry("version", mpt_proc_root_dir
);
5954 remove_proc_entry("summary", mpt_proc_root_dir
);
5955 remove_proc_entry(MPT_PROCFS_MPTBASEDIR
, NULL
);
5958 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5960 * procmpt_summary_read - Handle read request of a summary file
5961 * @buf: Pointer to area to write information
5962 * @start: Pointer to start pointer
5963 * @offset: Offset to start writing
5964 * @request: Amount of read data requested
5965 * @eof: Pointer to EOF integer
5968 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
5969 * Returns number of characters written to process performing the read.
5972 procmpt_summary_read(char *buf
, char **start
, off_t offset
, int request
, int *eof
, void *data
)
5982 mpt_print_ioc_summary(ioc
, out
, &more
, 0, 1);
5986 list_for_each_entry(ioc
, &ioc_list
, list
) {
5989 mpt_print_ioc_summary(ioc
, out
, &more
, 0, 1);
5992 if ((out
-buf
) >= request
)
5999 MPT_PROC_READ_RETURN(buf
,start
,offset
,request
,eof
,len
);
6002 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6004 * procmpt_version_read - Handle read request from /proc/mpt/version.
6005 * @buf: Pointer to area to write information
6006 * @start: Pointer to start pointer
6007 * @offset: Offset to start writing
6008 * @request: Amount of read data requested
6009 * @eof: Pointer to EOF integer
6012 * Returns number of characters written to process performing the read.
6015 procmpt_version_read(char *buf
, char **start
, off_t offset
, int request
, int *eof
, void *data
)
6018 int scsi
, fc
, sas
, lan
, ctl
, targ
, dmp
;
6022 len
= sprintf(buf
, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON
);
6023 len
+= sprintf(buf
+len
, " Fusion MPT base driver\n");
6025 scsi
= fc
= sas
= lan
= ctl
= targ
= dmp
= 0;
6026 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
6028 if (MptCallbacks
[cb_idx
]) {
6029 switch (MptDriverClass
[cb_idx
]) {
6031 if (!scsi
++) drvname
= "SPI host";
6034 if (!fc
++) drvname
= "FC host";
6037 if (!sas
++) drvname
= "SAS host";
6040 if (!lan
++) drvname
= "LAN";
6043 if (!targ
++) drvname
= "SCSI target";
6046 if (!ctl
++) drvname
= "ioctl";
6051 len
+= sprintf(buf
+len
, " Fusion MPT %s driver\n", drvname
);
6055 MPT_PROC_READ_RETURN(buf
,start
,offset
,request
,eof
,len
);
6058 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6060 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
6061 * @buf: Pointer to area to write information
6062 * @start: Pointer to start pointer
6063 * @offset: Offset to start writing
6064 * @request: Amount of read data requested
6065 * @eof: Pointer to EOF integer
6068 * Returns number of characters written to process performing the read.
6071 procmpt_iocinfo_read(char *buf
, char **start
, off_t offset
, int request
, int *eof
, void *data
)
6073 MPT_ADAPTER
*ioc
= data
;
6079 mpt_get_fw_exp_ver(expVer
, ioc
);
6081 len
= sprintf(buf
, "%s:", ioc
->name
);
6082 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)
6083 len
+= sprintf(buf
+len
, " (f/w download boot flag set)");
6084 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6085 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
6087 len
+= sprintf(buf
+len
, "\n ProductID = 0x%04x (%s)\n",
6088 ioc
->facts
.ProductID
,
6090 len
+= sprintf(buf
+len
, " FWVersion = 0x%08x%s", ioc
->facts
.FWVersion
.Word
, expVer
);
6091 if (ioc
->facts
.FWImageSize
)
6092 len
+= sprintf(buf
+len
, " (fw_size=%d)", ioc
->facts
.FWImageSize
);
6093 len
+= sprintf(buf
+len
, "\n MsgVersion = 0x%04x\n", ioc
->facts
.MsgVersion
);
6094 len
+= sprintf(buf
+len
, " FirstWhoInit = 0x%02x\n", ioc
->FirstWhoInit
);
6095 len
+= sprintf(buf
+len
, " EventState = 0x%02x\n", ioc
->facts
.EventState
);
6097 len
+= sprintf(buf
+len
, " CurrentHostMfaHighAddr = 0x%08x\n",
6098 ioc
->facts
.CurrentHostMfaHighAddr
);
6099 len
+= sprintf(buf
+len
, " CurrentSenseBufferHighAddr = 0x%08x\n",
6100 ioc
->facts
.CurrentSenseBufferHighAddr
);
6102 len
+= sprintf(buf
+len
, " MaxChainDepth = 0x%02x frames\n", ioc
->facts
.MaxChainDepth
);
6103 len
+= sprintf(buf
+len
, " MinBlockSize = 0x%02x bytes\n", 4*ioc
->facts
.BlockSize
);
6105 len
+= sprintf(buf
+len
, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6106 (void *)ioc
->req_frames
, (void *)(ulong
)ioc
->req_frames_dma
);
6108 * Rounding UP to nearest 4-kB boundary here...
6110 sz
= (ioc
->req_sz
* ioc
->req_depth
) + 128;
6111 sz
= ((sz
+ 0x1000UL
- 1UL) / 0x1000) * 0x1000;
6112 len
+= sprintf(buf
+len
, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6113 ioc
->req_sz
, ioc
->req_depth
, ioc
->req_sz
*ioc
->req_depth
, sz
);
6114 len
+= sprintf(buf
+len
, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
6115 4*ioc
->facts
.RequestFrameSize
,
6116 ioc
->facts
.GlobalCredits
);
6118 len
+= sprintf(buf
+len
, " Frames @ 0x%p (Dma @ 0x%p)\n",
6119 (void *)ioc
->alloc
, (void *)(ulong
)ioc
->alloc_dma
);
6120 sz
= (ioc
->reply_sz
* ioc
->reply_depth
) + 128;
6121 len
+= sprintf(buf
+len
, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6122 ioc
->reply_sz
, ioc
->reply_depth
, ioc
->reply_sz
*ioc
->reply_depth
, sz
);
6123 len
+= sprintf(buf
+len
, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
6124 ioc
->facts
.CurReplyFrameSize
,
6125 ioc
->facts
.ReplyQueueDepth
);
6127 len
+= sprintf(buf
+len
, " MaxDevices = %d\n",
6128 (ioc
->facts
.MaxDevices
==0) ? 255 : ioc
->facts
.MaxDevices
);
6129 len
+= sprintf(buf
+len
, " MaxBuses = %d\n", ioc
->facts
.MaxBuses
);
6132 for (p
=0; p
< ioc
->facts
.NumberOfPorts
; p
++) {
6133 len
+= sprintf(buf
+len
, " PortNumber = %d (of %d)\n",
6135 ioc
->facts
.NumberOfPorts
);
6136 if (ioc
->bus_type
== FC
) {
6137 if (ioc
->pfacts
[p
].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
) {
6138 u8
*a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
6139 len
+= sprintf(buf
+len
, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6140 a
[5], a
[4], a
[3], a
[2], a
[1], a
[0]);
6142 len
+= sprintf(buf
+len
, " WWN = %08X%08X:%08X%08X\n",
6143 ioc
->fc_port_page0
[p
].WWNN
.High
,
6144 ioc
->fc_port_page0
[p
].WWNN
.Low
,
6145 ioc
->fc_port_page0
[p
].WWPN
.High
,
6146 ioc
->fc_port_page0
[p
].WWPN
.Low
);
6150 MPT_PROC_READ_RETURN(buf
,start
,offset
,request
,eof
,len
);
6153 #endif /* CONFIG_PROC_FS } */
6155 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6157 mpt_get_fw_exp_ver(char *buf
, MPT_ADAPTER
*ioc
)
6160 if ((ioc
->facts
.FWVersion
.Word
>> 24) == 0x0E) {
6161 sprintf(buf
, " (Exp %02d%02d)",
6162 (ioc
->facts
.FWVersion
.Word
>> 16) & 0x00FF, /* Month */
6163 (ioc
->facts
.FWVersion
.Word
>> 8) & 0x1F); /* Day */
6166 if ((ioc
->facts
.FWVersion
.Word
>> 8) & 0x80)
6167 strcat(buf
, " [MDBG]");
6171 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6173 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6174 * @ioc: Pointer to MPT_ADAPTER structure
6175 * @buffer: Pointer to buffer where IOC summary info should be written
6176 * @size: Pointer to number of bytes we wrote (set by this routine)
6177 * @len: Offset at which to start writing in buffer
6178 * @showlan: Display LAN stuff?
6180 * This routine writes (english readable) ASCII text, which represents
6181 * a summary of IOC information, to a buffer.
6184 mpt_print_ioc_summary(MPT_ADAPTER
*ioc
, char *buffer
, int *size
, int len
, int showlan
)
6189 mpt_get_fw_exp_ver(expVer
, ioc
);
6192 * Shorter summary of attached ioc's...
6194 y
= sprintf(buffer
+len
, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6197 MPT_FW_REV_MAGIC_ID_STRING
, /* "FwRev=" or somesuch */
6198 ioc
->facts
.FWVersion
.Word
,
6200 ioc
->facts
.NumberOfPorts
,
6203 if (showlan
&& (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
)) {
6204 u8
*a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
6205 y
+= sprintf(buffer
+len
+y
, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6206 a
[5], a
[4], a
[3], a
[2], a
[1], a
[0]);
6209 y
+= sprintf(buffer
+len
+y
, ", IRQ=%d", ioc
->pci_irq
);
6212 y
+= sprintf(buffer
+len
+y
, " (disabled)");
6214 y
+= sprintf(buffer
+len
+y
, "\n");
6219 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6223 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6225 * mpt_HardResetHandler - Generic reset handler
6226 * @ioc: Pointer to MPT_ADAPTER structure
6227 * @sleepFlag: Indicates if sleep or schedule must be called.
6229 * Issues SCSI Task Management call based on input arg values.
6230 * If TaskMgmt fails, returns associated SCSI request.
6232 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
6233 * or a non-interrupt thread. In the former, must not call schedule().
6235 * Note: A return of -1 is a FATAL error case, as it means a
6236 * FW reload/initialization failed.
6238 * Returns 0 for SUCCESS or -1 if FAILED.
6241 mpt_HardResetHandler(MPT_ADAPTER
*ioc
, int sleepFlag
)
6244 unsigned long flags
;
6246 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HardResetHandler Entered!\n", ioc
->name
));
6248 printk(MYIOC_s_INFO_FMT
"HardResetHandler Entered!\n", ioc
->name
);
6249 printk("MF count 0x%x !\n", ioc
->mfcnt
);
6252 /* Reset the adapter. Prevent more than 1 call to
6253 * mpt_do_ioc_recovery at any instant in time.
6255 spin_lock_irqsave(&ioc
->diagLock
, flags
);
6256 if ((ioc
->diagPending
) || (ioc
->alt_ioc
&& ioc
->alt_ioc
->diagPending
)){
6257 spin_unlock_irqrestore(&ioc
->diagLock
, flags
);
6260 ioc
->diagPending
= 1;
6262 spin_unlock_irqrestore(&ioc
->diagLock
, flags
);
6264 /* FIXME: If do_ioc_recovery fails, repeat....
6267 /* The SCSI driver needs to adjust timeouts on all current
6268 * commands prior to the diagnostic reset being issued.
6269 * Prevents timeouts occurring during a diagnostic reset...very bad.
6270 * For all other protocol drivers, this is a no-op.
6276 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
6277 if (MptResetHandlers
[cb_idx
]) {
6278 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Calling IOC reset_setup handler #%d\n",
6279 ioc
->name
, cb_idx
));
6280 r
+= mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_SETUP_RESET
);
6282 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Calling alt-%s setup reset handler #%d\n",
6283 ioc
->name
, ioc
->alt_ioc
->name
, cb_idx
));
6284 r
+= mpt_signal_reset(cb_idx
, ioc
->alt_ioc
, MPT_IOC_SETUP_RESET
);
6290 if ((rc
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_RECOVER
, sleepFlag
)) != 0) {
6291 printk(MYIOC_s_WARN_FMT
"Cannot recover rc = %d!\n", ioc
->name
, rc
);
6295 ioc
->alt_ioc
->reload_fw
= 0;
6297 spin_lock_irqsave(&ioc
->diagLock
, flags
);
6298 ioc
->diagPending
= 0;
6300 ioc
->alt_ioc
->diagPending
= 0;
6301 spin_unlock_irqrestore(&ioc
->diagLock
, flags
);
6303 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HardResetHandler rc = %d!\n", ioc
->name
, rc
));
6308 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6310 EventDescriptionStr(u8 event
, u32 evData0
, char *evStr
)
6315 case MPI_EVENT_NONE
:
6318 case MPI_EVENT_LOG_DATA
:
6321 case MPI_EVENT_STATE_CHANGE
:
6322 ds
= "State Change";
6324 case MPI_EVENT_UNIT_ATTENTION
:
6325 ds
= "Unit Attention";
6327 case MPI_EVENT_IOC_BUS_RESET
:
6328 ds
= "IOC Bus Reset";
6330 case MPI_EVENT_EXT_BUS_RESET
:
6331 ds
= "External Bus Reset";
6333 case MPI_EVENT_RESCAN
:
6334 ds
= "Bus Rescan Event";
6336 case MPI_EVENT_LINK_STATUS_CHANGE
:
6337 if (evData0
== MPI_EVENT_LINK_STATUS_FAILURE
)
6338 ds
= "Link Status(FAILURE) Change";
6340 ds
= "Link Status(ACTIVE) Change";
6342 case MPI_EVENT_LOOP_STATE_CHANGE
:
6343 if (evData0
== MPI_EVENT_LOOP_STATE_CHANGE_LIP
)
6344 ds
= "Loop State(LIP) Change";
6345 else if (evData0
== MPI_EVENT_LOOP_STATE_CHANGE_LPE
)
6346 ds
= "Loop State(LPE) Change"; /* ??? */
6348 ds
= "Loop State(LPB) Change"; /* ??? */
6350 case MPI_EVENT_LOGOUT
:
6353 case MPI_EVENT_EVENT_CHANGE
:
6359 case MPI_EVENT_INTEGRATED_RAID
:
6361 u8 ReasonCode
= (u8
)(evData0
>> 16);
6362 switch (ReasonCode
) {
6363 case MPI_EVENT_RAID_RC_VOLUME_CREATED
:
6364 ds
= "Integrated Raid: Volume Created";
6366 case MPI_EVENT_RAID_RC_VOLUME_DELETED
:
6367 ds
= "Integrated Raid: Volume Deleted";
6369 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED
:
6370 ds
= "Integrated Raid: Volume Settings Changed";
6372 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED
:
6373 ds
= "Integrated Raid: Volume Status Changed";
6375 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED
:
6376 ds
= "Integrated Raid: Volume Physdisk Changed";
6378 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED
:
6379 ds
= "Integrated Raid: Physdisk Created";
6381 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED
:
6382 ds
= "Integrated Raid: Physdisk Deleted";
6384 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED
:
6385 ds
= "Integrated Raid: Physdisk Settings Changed";
6387 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
:
6388 ds
= "Integrated Raid: Physdisk Status Changed";
6390 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
:
6391 ds
= "Integrated Raid: Domain Validation Needed";
6393 case MPI_EVENT_RAID_RC_SMART_DATA
:
6394 ds
= "Integrated Raid; Smart Data";
6396 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED
:
6397 ds
= "Integrated Raid: Replace Action Started";
6400 ds
= "Integrated Raid";
6405 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE
:
6406 ds
= "SCSI Device Status Change";
6408 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE
:
6410 u8 id
= (u8
)(evData0
);
6411 u8 channel
= (u8
)(evData0
>> 8);
6412 u8 ReasonCode
= (u8
)(evData0
>> 16);
6413 switch (ReasonCode
) {
6414 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED
:
6415 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6416 "SAS Device Status Change: Added: "
6417 "id=%d channel=%d", id
, channel
);
6419 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING
:
6420 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6421 "SAS Device Status Change: Deleted: "
6422 "id=%d channel=%d", id
, channel
);
6424 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA
:
6425 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6426 "SAS Device Status Change: SMART Data: "
6427 "id=%d channel=%d", id
, channel
);
6429 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED
:
6430 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6431 "SAS Device Status Change: No Persistancy: "
6432 "id=%d channel=%d", id
, channel
);
6434 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED
:
6435 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6436 "SAS Device Status Change: Unsupported Device "
6437 "Discovered : id=%d channel=%d", id
, channel
);
6439 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET
:
6440 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6441 "SAS Device Status Change: Internal Device "
6442 "Reset : id=%d channel=%d", id
, channel
);
6444 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL
:
6445 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6446 "SAS Device Status Change: Internal Task "
6447 "Abort : id=%d channel=%d", id
, channel
);
6449 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL
:
6450 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6451 "SAS Device Status Change: Internal Abort "
6452 "Task Set : id=%d channel=%d", id
, channel
);
6454 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL
:
6455 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6456 "SAS Device Status Change: Internal Clear "
6457 "Task Set : id=%d channel=%d", id
, channel
);
6459 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL
:
6460 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6461 "SAS Device Status Change: Internal Query "
6462 "Task : id=%d channel=%d", id
, channel
);
6465 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6466 "SAS Device Status Change: Unknown: "
6467 "id=%d channel=%d", id
, channel
);
6472 case MPI_EVENT_ON_BUS_TIMER_EXPIRED
:
6473 ds
= "Bus Timer Expired";
6475 case MPI_EVENT_QUEUE_FULL
:
6477 u16 curr_depth
= (u16
)(evData0
>> 16);
6478 u8 channel
= (u8
)(evData0
>> 8);
6479 u8 id
= (u8
)(evData0
);
6481 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6482 "Queue Full: channel=%d id=%d depth=%d",
6483 channel
, id
, curr_depth
);
6486 case MPI_EVENT_SAS_SES
:
6487 ds
= "SAS SES Event";
6489 case MPI_EVENT_PERSISTENT_TABLE_FULL
:
6490 ds
= "Persistent Table Full";
6492 case MPI_EVENT_SAS_PHY_LINK_STATUS
:
6494 u8 LinkRates
= (u8
)(evData0
>> 8);
6495 u8 PhyNumber
= (u8
)(evData0
);
6496 LinkRates
= (LinkRates
& MPI_EVENT_SAS_PLS_LR_CURRENT_MASK
) >>
6497 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT
;
6498 switch (LinkRates
) {
6499 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN
:
6500 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6501 "SAS PHY Link Status: Phy=%d:"
6502 " Rate Unknown",PhyNumber
);
6504 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED
:
6505 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6506 "SAS PHY Link Status: Phy=%d:"
6507 " Phy Disabled",PhyNumber
);
6509 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION
:
6510 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6511 "SAS PHY Link Status: Phy=%d:"
6512 " Failed Speed Nego",PhyNumber
);
6514 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE
:
6515 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6516 "SAS PHY Link Status: Phy=%d:"
6517 " Sata OOB Completed",PhyNumber
);
6519 case MPI_EVENT_SAS_PLS_LR_RATE_1_5
:
6520 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6521 "SAS PHY Link Status: Phy=%d:"
6522 " Rate 1.5 Gbps",PhyNumber
);
6524 case MPI_EVENT_SAS_PLS_LR_RATE_3_0
:
6525 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6526 "SAS PHY Link Status: Phy=%d:"
6527 " Rate 3.0 Gpbs",PhyNumber
);
6530 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6531 "SAS PHY Link Status: Phy=%d", PhyNumber
);
6536 case MPI_EVENT_SAS_DISCOVERY_ERROR
:
6537 ds
= "SAS Discovery Error";
6539 case MPI_EVENT_IR_RESYNC_UPDATE
:
6541 u8 resync_complete
= (u8
)(evData0
>> 16);
6542 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6543 "IR Resync Update: Complete = %d:",resync_complete
);
6548 u8 ReasonCode
= (u8
)(evData0
>> 16);
6549 switch (ReasonCode
) {
6550 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED
:
6551 ds
= "IR2: LD State Changed";
6553 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED
:
6554 ds
= "IR2: PD State Changed";
6556 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL
:
6557 ds
= "IR2: Bad Block Table Full";
6559 case MPI_EVENT_IR2_RC_PD_INSERTED
:
6560 ds
= "IR2: PD Inserted";
6562 case MPI_EVENT_IR2_RC_PD_REMOVED
:
6563 ds
= "IR2: PD Removed";
6565 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED
:
6566 ds
= "IR2: Foreign CFG Detected";
6568 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR
:
6569 ds
= "IR2: Rebuild Medium Error";
6577 case MPI_EVENT_SAS_DISCOVERY
:
6580 ds
= "SAS Discovery: Start";
6582 ds
= "SAS Discovery: Stop";
6585 case MPI_EVENT_LOG_ENTRY_ADDED
:
6586 ds
= "SAS Log Entry Added";
6589 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE
:
6591 u8 phy_num
= (u8
)(evData0
);
6592 u8 port_num
= (u8
)(evData0
>> 8);
6593 u8 port_width
= (u8
)(evData0
>> 16);
6594 u8 primative
= (u8
)(evData0
>> 24);
6595 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6596 "SAS Broadcase Primative: phy=%d port=%d "
6597 "width=%d primative=0x%02x",
6598 phy_num
, port_num
, port_width
, primative
);
6602 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE
:
6604 u8 reason
= (u8
)(evData0
);
6605 u8 port_num
= (u8
)(evData0
>> 8);
6606 u16 handle
= le16_to_cpu(evData0
>> 16);
6608 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6609 "SAS Initiator Device Status Change: reason=0x%02x "
6610 "port=%d handle=0x%04x",
6611 reason
, port_num
, handle
);
6615 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW
:
6617 u8 max_init
= (u8
)(evData0
);
6618 u8 current_init
= (u8
)(evData0
>> 8);
6620 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6621 "SAS Initiator Device Table Overflow: max initiators=%02d "
6622 "current initators=%02d",
6623 max_init
, current_init
);
6626 case MPI_EVENT_SAS_SMP_ERROR
:
6628 u8 status
= (u8
)(evData0
);
6629 u8 port_num
= (u8
)(evData0
>> 8);
6630 u8 result
= (u8
)(evData0
>> 16);
6632 if (status
== MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID
)
6633 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6634 "SAS SMP Error: port=%d result=0x%02x",
6636 else if (status
== MPI_EVENT_SAS_SMP_CRC_ERROR
)
6637 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6638 "SAS SMP Error: port=%d : CRC Error",
6640 else if (status
== MPI_EVENT_SAS_SMP_TIMEOUT
)
6641 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6642 "SAS SMP Error: port=%d : Timeout",
6644 else if (status
== MPI_EVENT_SAS_SMP_NO_DESTINATION
)
6645 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6646 "SAS SMP Error: port=%d : No Destination",
6648 else if (status
== MPI_EVENT_SAS_SMP_BAD_DESTINATION
)
6649 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6650 "SAS SMP Error: port=%d : Bad Destination",
6653 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6654 "SAS SMP Error: port=%d : status=0x%02x",
6660 * MPT base "custom" events may be added here...
6667 strncpy(evStr
, ds
, EVENT_DESCR_STR_SZ
);
6670 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6672 * ProcessEventNotification - Route EventNotificationReply to all event handlers
6673 * @ioc: Pointer to MPT_ADAPTER structure
6674 * @pEventReply: Pointer to EventNotification reply frame
6675 * @evHandlers: Pointer to integer, number of event handlers
6677 * Routes a received EventNotificationReply to all currently registered
6679 * Returns sum of event handlers return values.
6682 ProcessEventNotification(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*pEventReply
, int *evHandlers
)
6691 char evStr
[EVENT_DESCR_STR_SZ
];
6695 * Do platform normalization of values
6697 event
= le32_to_cpu(pEventReply
->Event
) & 0xFF;
6698 // evCtx = le32_to_cpu(pEventReply->EventContext);
6699 evDataLen
= le16_to_cpu(pEventReply
->EventDataLength
);
6701 evData0
= le32_to_cpu(pEventReply
->Data
[0]);
6704 EventDescriptionStr(event
, evData0
, evStr
);
6705 devtprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"MPT event:(%02Xh) : %s\n",
6710 #ifdef CONFIG_FUSION_LOGGING
6711 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6712 ": Event data:\n", ioc
->name
));
6713 for (ii
= 0; ii
< evDataLen
; ii
++)
6714 devtverboseprintk(ioc
, printk(" %08x",
6715 le32_to_cpu(pEventReply
->Data
[ii
])));
6716 devtverboseprintk(ioc
, printk("\n"));
6720 * Do general / base driver event processing
6723 case MPI_EVENT_EVENT_CHANGE
: /* 0A */
6725 u8 evState
= evData0
& 0xFF;
6727 /* CHECKME! What if evState unexpectedly says OFF (0)? */
6729 /* Update EventState field in cached IocFacts */
6730 if (ioc
->facts
.Function
) {
6731 ioc
->facts
.EventState
= evState
;
6735 case MPI_EVENT_INTEGRATED_RAID
:
6736 mptbase_raid_process_event_data(ioc
,
6737 (MpiEventDataRaid_t
*)pEventReply
->Data
);
6744 * Should this event be logged? Events are written sequentially.
6745 * When buffer is full, start again at the top.
6747 if (ioc
->events
&& (ioc
->eventTypes
& ( 1 << event
))) {
6750 idx
= ioc
->eventContext
% MPTCTL_EVENT_LOG_SIZE
;
6752 ioc
->events
[idx
].event
= event
;
6753 ioc
->events
[idx
].eventContext
= ioc
->eventContext
;
6755 for (ii
= 0; ii
< 2; ii
++) {
6757 ioc
->events
[idx
].data
[ii
] = le32_to_cpu(pEventReply
->Data
[ii
]);
6759 ioc
->events
[idx
].data
[ii
] = 0;
6762 ioc
->eventContext
++;
6767 * Call each currently registered protocol event handler.
6769 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
6770 if (MptEvHandlers
[cb_idx
]) {
6771 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Routing Event to event handler #%d\n",
6772 ioc
->name
, cb_idx
));
6773 r
+= (*(MptEvHandlers
[cb_idx
]))(ioc
, pEventReply
);
6777 /* FIXME? Examine results here? */
6780 * If needed, send (a single) EventAck.
6782 if (pEventReply
->AckRequired
== MPI_EVENT_NOTIFICATION_ACK_REQUIRED
) {
6783 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6784 "EventAck required\n",ioc
->name
));
6785 if ((ii
= SendEventAck(ioc
, pEventReply
)) != 0) {
6786 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SendEventAck returned %d\n",
6791 *evHandlers
= handlers
;
6795 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6797 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
6798 * @ioc: Pointer to MPT_ADAPTER structure
6799 * @log_info: U32 LogInfo reply word from the IOC
6801 * Refer to lsi/mpi_log_fc.h.
6804 mpt_fc_log_info(MPT_ADAPTER
*ioc
, u32 log_info
)
6806 char *desc
= "unknown";
6808 switch (log_info
& 0xFF000000) {
6809 case MPI_IOCLOGINFO_FC_INIT_BASE
:
6810 desc
= "FCP Initiator";
6812 case MPI_IOCLOGINFO_FC_TARGET_BASE
:
6813 desc
= "FCP Target";
6815 case MPI_IOCLOGINFO_FC_LAN_BASE
:
6818 case MPI_IOCLOGINFO_FC_MSG_BASE
:
6819 desc
= "MPI Message Layer";
6821 case MPI_IOCLOGINFO_FC_LINK_BASE
:
6824 case MPI_IOCLOGINFO_FC_CTX_BASE
:
6825 desc
= "Context Manager";
6827 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET
:
6828 desc
= "Invalid Field Offset";
6830 case MPI_IOCLOGINFO_FC_STATE_CHANGE
:
6831 desc
= "State Change Info";
6835 printk(MYIOC_s_INFO_FMT
"LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
6836 ioc
->name
, log_info
, desc
, (log_info
& 0xFFFFFF));
6839 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6841 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
6842 * @ioc: Pointer to MPT_ADAPTER structure
6843 * @mr: Pointer to MPT reply frame
6844 * @log_info: U32 LogInfo word from the IOC
6846 * Refer to lsi/sp_log.h.
6849 mpt_spi_log_info(MPT_ADAPTER
*ioc
, u32 log_info
)
6851 u32 info
= log_info
& 0x00FF0000;
6852 char *desc
= "unknown";
6856 desc
= "bug! MID not found";
6857 if (ioc
->reload_fw
== 0)
6862 desc
= "Parity Error";
6866 desc
= "ASYNC Outbound Overrun";
6870 desc
= "SYNC Offset Error";
6878 desc
= "Msg In Overflow";
6886 desc
= "Outbound DMA Overrun";
6890 desc
= "Task Management";
6894 desc
= "Device Problem";
6898 desc
= "Invalid Phase Change";
6902 desc
= "Untagged Table Size";
6907 printk(MYIOC_s_INFO_FMT
"LogInfo(0x%08x): F/W: %s\n", ioc
->name
, log_info
, desc
);
6910 /* strings for sas loginfo */
6911 static char *originator_str
[] = {
6916 static char *iop_code_str
[] = {
6918 "Invalid SAS Address", /* 01h */
6920 "Invalid Page", /* 03h */
6921 "Diag Message Error", /* 04h */
6922 "Task Terminated", /* 05h */
6923 "Enclosure Management", /* 06h */
6924 "Target Mode" /* 07h */
6926 static char *pl_code_str
[] = {
6928 "Open Failure", /* 01h */
6929 "Invalid Scatter Gather List", /* 02h */
6930 "Wrong Relative Offset or Frame Length", /* 03h */
6931 "Frame Transfer Error", /* 04h */
6932 "Transmit Frame Connected Low", /* 05h */
6933 "SATA Non-NCQ RW Error Bit Set", /* 06h */
6934 "SATA Read Log Receive Data Error", /* 07h */
6935 "SATA NCQ Fail All Commands After Error", /* 08h */
6936 "SATA Error in Receive Set Device Bit FIS", /* 09h */
6937 "Receive Frame Invalid Message", /* 0Ah */
6938 "Receive Context Message Valid Error", /* 0Bh */
6939 "Receive Frame Current Frame Error", /* 0Ch */
6940 "SATA Link Down", /* 0Dh */
6941 "Discovery SATA Init W IOS", /* 0Eh */
6942 "Config Invalid Page", /* 0Fh */
6943 "Discovery SATA Init Timeout", /* 10h */
6946 "IO Not Yet Executed", /* 13h */
6947 "IO Executed", /* 14h */
6948 "Persistent Reservation Out Not Affiliation "
6950 "Open Transmit DMA Abort", /* 16h */
6951 "IO Device Missing Delay Retry", /* 17h */
6952 "IO Cancelled Due to Recieve Error", /* 18h */
6960 "Enclosure Management" /* 20h */
6962 static char *ir_code_str
[] = {
6963 "Raid Action Error", /* 00h */
6973 static char *raid_sub_code_str
[] = {
6975 "Volume Creation Failed: Data Passed too "
6977 "Volume Creation Failed: Duplicate Volumes "
6978 "Attempted", /* 02h */
6979 "Volume Creation Failed: Max Number "
6980 "Supported Volumes Exceeded", /* 03h */
6981 "Volume Creation Failed: DMA Error", /* 04h */
6982 "Volume Creation Failed: Invalid Volume Type", /* 05h */
6983 "Volume Creation Failed: Error Reading "
6984 "MFG Page 4", /* 06h */
6985 "Volume Creation Failed: Creating Internal "
6986 "Structures", /* 07h */
6995 "Activation failed: Already Active Volume", /* 10h */
6996 "Activation failed: Unsupported Volume Type", /* 11h */
6997 "Activation failed: Too Many Active Volumes", /* 12h */
6998 "Activation failed: Volume ID in Use", /* 13h */
6999 "Activation failed: Reported Failure", /* 14h */
7000 "Activation failed: Importing a Volume", /* 15h */
7011 "Phys Disk failed: Too Many Phys Disks", /* 20h */
7012 "Phys Disk failed: Data Passed too Large", /* 21h */
7013 "Phys Disk failed: DMA Error", /* 22h */
7014 "Phys Disk failed: Invalid <channel:id>", /* 23h */
7015 "Phys Disk failed: Creating Phys Disk Config "
7028 "Compatibility Error: IR Disabled", /* 30h */
7029 "Compatibility Error: Inquiry Comand Failed", /* 31h */
7030 "Compatibility Error: Device not Direct Access "
7031 "Device ", /* 32h */
7032 "Compatibility Error: Removable Device Found", /* 33h */
7033 "Compatibility Error: Device SCSI Version not "
7034 "2 or Higher", /* 34h */
7035 "Compatibility Error: SATA Device, 48 BIT LBA "
7036 "not Supported", /* 35h */
7037 "Compatibility Error: Device doesn't have "
7038 "512 Byte Block Sizes", /* 36h */
7039 "Compatibility Error: Volume Type Check Failed", /* 37h */
7040 "Compatibility Error: Volume Type is "
7041 "Unsupported by FW", /* 38h */
7042 "Compatibility Error: Disk Drive too Small for "
7043 "use in Volume", /* 39h */
7044 "Compatibility Error: Phys Disk for Create "
7045 "Volume not Found", /* 3Ah */
7046 "Compatibility Error: Too Many or too Few "
7047 "Disks for Volume Type", /* 3Bh */
7048 "Compatibility Error: Disk stripe Sizes "
7049 "Must be 64KB", /* 3Ch */
7050 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
7053 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7055 * mpt_sas_log_info - Log information returned from SAS IOC.
7056 * @ioc: Pointer to MPT_ADAPTER structure
7057 * @log_info: U32 LogInfo reply word from the IOC
7059 * Refer to lsi/mpi_log_sas.h.
7062 mpt_sas_log_info(MPT_ADAPTER
*ioc
, u32 log_info
)
7064 union loginfo_type
{
7073 union loginfo_type sas_loginfo
;
7074 char *originator_desc
= NULL
;
7075 char *code_desc
= NULL
;
7076 char *sub_code_desc
= NULL
;
7078 sas_loginfo
.loginfo
= log_info
;
7079 if ((sas_loginfo
.dw
.bus_type
!= 3 /*SAS*/) &&
7080 (sas_loginfo
.dw
.originator
< sizeof(originator_str
)/sizeof(char*)))
7083 originator_desc
= originator_str
[sas_loginfo
.dw
.originator
];
7085 switch (sas_loginfo
.dw
.originator
) {
7088 if (sas_loginfo
.dw
.code
<
7089 sizeof(iop_code_str
)/sizeof(char*))
7090 code_desc
= iop_code_str
[sas_loginfo
.dw
.code
];
7093 if (sas_loginfo
.dw
.code
<
7094 sizeof(pl_code_str
)/sizeof(char*))
7095 code_desc
= pl_code_str
[sas_loginfo
.dw
.code
];
7098 if (sas_loginfo
.dw
.code
>=
7099 sizeof(ir_code_str
)/sizeof(char*))
7101 code_desc
= ir_code_str
[sas_loginfo
.dw
.code
];
7102 if (sas_loginfo
.dw
.subcode
>=
7103 sizeof(raid_sub_code_str
)/sizeof(char*))
7105 if (sas_loginfo
.dw
.code
== 0)
7107 raid_sub_code_str
[sas_loginfo
.dw
.subcode
];
7113 if (sub_code_desc
!= NULL
)
7114 printk(MYIOC_s_INFO_FMT
7115 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7117 ioc
->name
, log_info
, originator_desc
, code_desc
,
7119 else if (code_desc
!= NULL
)
7120 printk(MYIOC_s_INFO_FMT
7121 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7122 " SubCode(0x%04x)\n",
7123 ioc
->name
, log_info
, originator_desc
, code_desc
,
7124 sas_loginfo
.dw
.subcode
);
7126 printk(MYIOC_s_INFO_FMT
7127 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
7128 " SubCode(0x%04x)\n",
7129 ioc
->name
, log_info
, originator_desc
,
7130 sas_loginfo
.dw
.code
, sas_loginfo
.dw
.subcode
);
7133 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7135 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
7136 * @ioc: Pointer to MPT_ADAPTER structure
7137 * @ioc_status: U32 IOCStatus word from IOC
7138 * @mf: Pointer to MPT request frame
7140 * Refer to lsi/mpi.h.
7143 mpt_iocstatus_info_config(MPT_ADAPTER
*ioc
, u32 ioc_status
, MPT_FRAME_HDR
*mf
)
7145 Config_t
*pReq
= (Config_t
*)mf
;
7146 char extend_desc
[EVENT_DESCR_STR_SZ
];
7151 if (pReq
->Header
.PageType
== MPI_CONFIG_PAGETYPE_EXTENDED
)
7152 page_type
= pReq
->ExtPageType
;
7154 page_type
= pReq
->Header
.PageType
;
7157 * ignore invalid page messages for GET_NEXT_HANDLE
7159 form
= le32_to_cpu(pReq
->PageAddress
);
7160 if (ioc_status
== MPI_IOCSTATUS_CONFIG_INVALID_PAGE
) {
7161 if (page_type
== MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE
||
7162 page_type
== MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER
||
7163 page_type
== MPI_CONFIG_EXTPAGETYPE_ENCLOSURE
) {
7164 if ((form
>> MPI_SAS_DEVICE_PGAD_FORM_SHIFT
) ==
7165 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE
)
7168 if (page_type
== MPI_CONFIG_PAGETYPE_FC_DEVICE
)
7169 if ((form
& MPI_FC_DEVICE_PGAD_FORM_MASK
) ==
7170 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID
)
7174 snprintf(extend_desc
, EVENT_DESCR_STR_SZ
,
7175 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
7176 page_type
, pReq
->Header
.PageNumber
, pReq
->Action
, form
);
7178 switch (ioc_status
) {
7180 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION
: /* 0x0020 */
7181 desc
= "Config Page Invalid Action";
7184 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE
: /* 0x0021 */
7185 desc
= "Config Page Invalid Type";
7188 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE
: /* 0x0022 */
7189 desc
= "Config Page Invalid Page";
7192 case MPI_IOCSTATUS_CONFIG_INVALID_DATA
: /* 0x0023 */
7193 desc
= "Config Page Invalid Data";
7196 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS
: /* 0x0024 */
7197 desc
= "Config Page No Defaults";
7200 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT
: /* 0x0025 */
7201 desc
= "Config Page Can't Commit";
7208 dreplyprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"IOCStatus(0x%04X): %s: %s\n",
7209 ioc
->name
, ioc_status
, desc
, extend_desc
));
7213 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
7214 * @ioc: Pointer to MPT_ADAPTER structure
7215 * @ioc_status: U32 IOCStatus word from IOC
7216 * @mf: Pointer to MPT request frame
7218 * Refer to lsi/mpi.h.
7221 mpt_iocstatus_info(MPT_ADAPTER
*ioc
, u32 ioc_status
, MPT_FRAME_HDR
*mf
)
7223 u32 status
= ioc_status
& MPI_IOCSTATUS_MASK
;
7228 /****************************************************************************/
7229 /* Common IOCStatus values for all replies */
7230 /****************************************************************************/
7232 case MPI_IOCSTATUS_INVALID_FUNCTION
: /* 0x0001 */
7233 desc
= "Invalid Function";
7236 case MPI_IOCSTATUS_BUSY
: /* 0x0002 */
7240 case MPI_IOCSTATUS_INVALID_SGL
: /* 0x0003 */
7241 desc
= "Invalid SGL";
7244 case MPI_IOCSTATUS_INTERNAL_ERROR
: /* 0x0004 */
7245 desc
= "Internal Error";
7248 case MPI_IOCSTATUS_RESERVED
: /* 0x0005 */
7252 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES
: /* 0x0006 */
7253 desc
= "Insufficient Resources";
7256 case MPI_IOCSTATUS_INVALID_FIELD
: /* 0x0007 */
7257 desc
= "Invalid Field";
7260 case MPI_IOCSTATUS_INVALID_STATE
: /* 0x0008 */
7261 desc
= "Invalid State";
7264 /****************************************************************************/
7265 /* Config IOCStatus values */
7266 /****************************************************************************/
7268 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION
: /* 0x0020 */
7269 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE
: /* 0x0021 */
7270 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE
: /* 0x0022 */
7271 case MPI_IOCSTATUS_CONFIG_INVALID_DATA
: /* 0x0023 */
7272 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS
: /* 0x0024 */
7273 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT
: /* 0x0025 */
7274 mpt_iocstatus_info_config(ioc
, status
, mf
);
7277 /****************************************************************************/
7278 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
7280 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
7282 /****************************************************************************/
7284 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR
: /* 0x0040 */
7285 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN
: /* 0x0045 */
7286 case MPI_IOCSTATUS_SCSI_INVALID_BUS
: /* 0x0041 */
7287 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID
: /* 0x0042 */
7288 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE
: /* 0x0043 */
7289 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN
: /* 0x0044 */
7290 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR
: /* 0x0046 */
7291 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR
: /* 0x0047 */
7292 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED
: /* 0x0048 */
7293 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH
: /* 0x0049 */
7294 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED
: /* 0x004A */
7295 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED
: /* 0x004B */
7296 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED
: /* 0x004C */
7299 /****************************************************************************/
7300 /* SCSI Target values */
7301 /****************************************************************************/
7303 case MPI_IOCSTATUS_TARGET_PRIORITY_IO
: /* 0x0060 */
7304 desc
= "Target: Priority IO";
7307 case MPI_IOCSTATUS_TARGET_INVALID_PORT
: /* 0x0061 */
7308 desc
= "Target: Invalid Port";
7311 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX
: /* 0x0062 */
7312 desc
= "Target Invalid IO Index:";
7315 case MPI_IOCSTATUS_TARGET_ABORTED
: /* 0x0063 */
7316 desc
= "Target: Aborted";
7319 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE
: /* 0x0064 */
7320 desc
= "Target: No Conn Retryable";
7323 case MPI_IOCSTATUS_TARGET_NO_CONNECTION
: /* 0x0065 */
7324 desc
= "Target: No Connection";
7327 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH
: /* 0x006A */
7328 desc
= "Target: Transfer Count Mismatch";
7331 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT
: /* 0x006B */
7332 desc
= "Target: STS Data not Sent";
7335 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR
: /* 0x006D */
7336 desc
= "Target: Data Offset Error";
7339 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA
: /* 0x006E */
7340 desc
= "Target: Too Much Write Data";
7343 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT
: /* 0x006F */
7344 desc
= "Target: IU Too Short";
7347 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT
: /* 0x0070 */
7348 desc
= "Target: ACK NAK Timeout";
7351 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED
: /* 0x0071 */
7352 desc
= "Target: Nak Received";
7355 /****************************************************************************/
7356 /* Fibre Channel Direct Access values */
7357 /****************************************************************************/
7359 case MPI_IOCSTATUS_FC_ABORTED
: /* 0x0066 */
7360 desc
= "FC: Aborted";
7363 case MPI_IOCSTATUS_FC_RX_ID_INVALID
: /* 0x0067 */
7364 desc
= "FC: RX ID Invalid";
7367 case MPI_IOCSTATUS_FC_DID_INVALID
: /* 0x0068 */
7368 desc
= "FC: DID Invalid";
7371 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT
: /* 0x0069 */
7372 desc
= "FC: Node Logged Out";
7375 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED
: /* 0x006C */
7376 desc
= "FC: Exchange Canceled";
7379 /****************************************************************************/
7381 /****************************************************************************/
7383 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND
: /* 0x0080 */
7384 desc
= "LAN: Device not Found";
7387 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE
: /* 0x0081 */
7388 desc
= "LAN: Device Failure";
7391 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR
: /* 0x0082 */
7392 desc
= "LAN: Transmit Error";
7395 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED
: /* 0x0083 */
7396 desc
= "LAN: Transmit Aborted";
7399 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR
: /* 0x0084 */
7400 desc
= "LAN: Receive Error";
7403 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED
: /* 0x0085 */
7404 desc
= "LAN: Receive Aborted";
7407 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET
: /* 0x0086 */
7408 desc
= "LAN: Partial Packet";
7411 case MPI_IOCSTATUS_LAN_CANCELED
: /* 0x0087 */
7412 desc
= "LAN: Canceled";
7415 /****************************************************************************/
7416 /* Serial Attached SCSI values */
7417 /****************************************************************************/
7419 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED
: /* 0x0090 */
7420 desc
= "SAS: SMP Request Failed";
7423 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN
: /* 0x0090 */
7424 desc
= "SAS: SMP Data Overrun";
7435 dreplyprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"IOCStatus(0x%04X): %s\n",
7436 ioc
->name
, status
, desc
));
7439 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7440 EXPORT_SYMBOL(mpt_attach
);
7441 EXPORT_SYMBOL(mpt_detach
);
7443 EXPORT_SYMBOL(mpt_resume
);
7444 EXPORT_SYMBOL(mpt_suspend
);
7446 EXPORT_SYMBOL(ioc_list
);
7447 EXPORT_SYMBOL(mpt_proc_root_dir
);
7448 EXPORT_SYMBOL(mpt_register
);
7449 EXPORT_SYMBOL(mpt_deregister
);
7450 EXPORT_SYMBOL(mpt_event_register
);
7451 EXPORT_SYMBOL(mpt_event_deregister
);
7452 EXPORT_SYMBOL(mpt_reset_register
);
7453 EXPORT_SYMBOL(mpt_reset_deregister
);
7454 EXPORT_SYMBOL(mpt_device_driver_register
);
7455 EXPORT_SYMBOL(mpt_device_driver_deregister
);
7456 EXPORT_SYMBOL(mpt_get_msg_frame
);
7457 EXPORT_SYMBOL(mpt_put_msg_frame
);
7458 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri
);
7459 EXPORT_SYMBOL(mpt_free_msg_frame
);
7460 EXPORT_SYMBOL(mpt_add_sge
);
7461 EXPORT_SYMBOL(mpt_send_handshake_request
);
7462 EXPORT_SYMBOL(mpt_verify_adapter
);
7463 EXPORT_SYMBOL(mpt_GetIocState
);
7464 EXPORT_SYMBOL(mpt_print_ioc_summary
);
7465 EXPORT_SYMBOL(mpt_HardResetHandler
);
7466 EXPORT_SYMBOL(mpt_config
);
7467 EXPORT_SYMBOL(mpt_findImVolumes
);
7468 EXPORT_SYMBOL(mpt_alloc_fw_memory
);
7469 EXPORT_SYMBOL(mpt_free_fw_memory
);
7470 EXPORT_SYMBOL(mptbase_sas_persist_operation
);
7471 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0
);
7473 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7475 * fusion_init - Fusion MPT base driver initialization routine.
7477 * Returns 0 for success, non-zero for failure.
7484 show_mptmod_ver(my_NAME
, my_VERSION
);
7485 printk(KERN_INFO COPYRIGHT
"\n");
7487 for (cb_idx
= 0; cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
; cb_idx
++) {
7488 MptCallbacks
[cb_idx
] = NULL
;
7489 MptDriverClass
[cb_idx
] = MPTUNKNOWN_DRIVER
;
7490 MptEvHandlers
[cb_idx
] = NULL
;
7491 MptResetHandlers
[cb_idx
] = NULL
;
7494 /* Register ourselves (mptbase) in order to facilitate
7495 * EventNotification handling.
7497 mpt_base_index
= mpt_register(mpt_base_reply
, MPTBASE_DRIVER
);
7499 /* Register for hard reset handling callbacks.
7501 mpt_reset_register(mpt_base_index
, mpt_ioc_reset
);
7503 #ifdef CONFIG_PROC_FS
7504 (void) procmpt_create();
7509 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7511 * fusion_exit - Perform driver unload cleanup.
7513 * This routine frees all resources associated with each MPT adapter
7514 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
7520 mpt_reset_deregister(mpt_base_index
);
7522 #ifdef CONFIG_PROC_FS
7527 module_init(fusion_init
);
7528 module_exit(fusion_exit
);