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-2008 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
= -1;
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 static 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 * mpt_fault_reset_work - work performed on workq after ioc fault
258 * @work: input argument, used to derive ioc
262 mpt_fault_reset_work(struct work_struct
*work
)
265 container_of(work
, MPT_ADAPTER
, fault_reset_work
.work
);
270 if (ioc
->diagPending
|| !ioc
->active
)
273 ioc_raw_state
= mpt_GetIocState(ioc
, 0);
274 if ((ioc_raw_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_FAULT
) {
275 printk(MYIOC_s_WARN_FMT
"IOC is in FAULT state (%04xh)!!!\n",
276 ioc
->name
, ioc_raw_state
& MPI_DOORBELL_DATA_MASK
);
277 printk(MYIOC_s_WARN_FMT
"Issuing HardReset from %s!!\n",
278 ioc
->name
, __func__
);
279 rc
= mpt_HardResetHandler(ioc
, CAN_SLEEP
);
280 printk(MYIOC_s_WARN_FMT
"%s: HardReset: %s\n", ioc
->name
,
281 __func__
, (rc
== 0) ? "success" : "failed");
282 ioc_raw_state
= mpt_GetIocState(ioc
, 0);
283 if ((ioc_raw_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_FAULT
)
284 printk(MYIOC_s_WARN_FMT
"IOC is in FAULT state after "
285 "reset (%04xh)\n", ioc
->name
, ioc_raw_state
&
286 MPI_DOORBELL_DATA_MASK
);
291 * Take turns polling alternate controller
296 /* rearm the timer */
297 spin_lock_irqsave(&ioc
->fault_reset_work_lock
, flags
);
298 if (ioc
->reset_work_q
)
299 queue_delayed_work(ioc
->reset_work_q
, &ioc
->fault_reset_work
,
300 msecs_to_jiffies(MPT_POLLING_INTERVAL
));
301 spin_unlock_irqrestore(&ioc
->fault_reset_work_lock
, flags
);
306 * Process turbo (context) reply...
309 mpt_turbo_reply(MPT_ADAPTER
*ioc
, u32 pa
)
311 MPT_FRAME_HDR
*mf
= NULL
;
312 MPT_FRAME_HDR
*mr
= NULL
;
316 dmfprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Got TURBO reply req_idx=%08x\n",
319 switch (pa
>> MPI_CONTEXT_REPLY_TYPE_SHIFT
) {
320 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT
:
321 req_idx
= pa
& 0x0000FFFF;
322 cb_idx
= (pa
& 0x00FF0000) >> 16;
323 mf
= MPT_INDEX_2_MFPTR(ioc
, req_idx
);
325 case MPI_CONTEXT_REPLY_TYPE_LAN
:
326 cb_idx
= mpt_get_cb_idx(MPTLAN_DRIVER
);
328 * Blind set of mf to NULL here was fatal
329 * after lan_reply says "freeme"
330 * Fix sort of combined with an optimization here;
331 * added explicit check for case where lan_reply
332 * was just returning 1 and doing nothing else.
333 * For this case skip the callback, but set up
334 * proper mf value first here:-)
336 if ((pa
& 0x58000000) == 0x58000000) {
337 req_idx
= pa
& 0x0000FFFF;
338 mf
= MPT_INDEX_2_MFPTR(ioc
, req_idx
);
339 mpt_free_msg_frame(ioc
, mf
);
344 mr
= (MPT_FRAME_HDR
*) CAST_U32_TO_PTR(pa
);
346 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET
:
347 cb_idx
= mpt_get_cb_idx(MPTSTM_DRIVER
);
348 mr
= (MPT_FRAME_HDR
*) CAST_U32_TO_PTR(pa
);
355 /* Check for (valid) IO callback! */
356 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
||
357 MptCallbacks
[cb_idx
] == NULL
) {
358 printk(MYIOC_s_WARN_FMT
"%s: Invalid cb_idx (%d)!\n",
359 __func__
, ioc
->name
, cb_idx
);
363 if (MptCallbacks
[cb_idx
](ioc
, mf
, mr
))
364 mpt_free_msg_frame(ioc
, mf
);
370 mpt_reply(MPT_ADAPTER
*ioc
, u32 pa
)
381 /* non-TURBO reply! Hmmm, something may be up...
382 * Newest turbo reply mechanism; get address
383 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
386 /* Map DMA address of reply header to cpu address.
387 * pa is 32 bits - but the dma address may be 32 or 64 bits
388 * get offset based only only the low addresses
391 reply_dma_low
= (pa
<<= 1);
392 mr
= (MPT_FRAME_HDR
*)((u8
*)ioc
->reply_frames
+
393 (reply_dma_low
- ioc
->reply_frames_low_dma
));
395 req_idx
= le16_to_cpu(mr
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
);
396 cb_idx
= mr
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
;
397 mf
= MPT_INDEX_2_MFPTR(ioc
, req_idx
);
399 dmfprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
400 ioc
->name
, mr
, req_idx
, cb_idx
, mr
->u
.hdr
.Function
));
401 DBG_DUMP_REPLY_FRAME(ioc
, (u32
*)mr
);
403 /* Check/log IOC log info
405 ioc_stat
= le16_to_cpu(mr
->u
.reply
.IOCStatus
);
406 if (ioc_stat
& MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE
) {
407 u32 log_info
= le32_to_cpu(mr
->u
.reply
.IOCLogInfo
);
408 if (ioc
->bus_type
== FC
)
409 mpt_fc_log_info(ioc
, log_info
);
410 else if (ioc
->bus_type
== SPI
)
411 mpt_spi_log_info(ioc
, log_info
);
412 else if (ioc
->bus_type
== SAS
)
413 mpt_sas_log_info(ioc
, log_info
);
416 if (ioc_stat
& MPI_IOCSTATUS_MASK
)
417 mpt_iocstatus_info(ioc
, (u32
)ioc_stat
, mf
);
419 /* Check for (valid) IO callback! */
420 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
||
421 MptCallbacks
[cb_idx
] == NULL
) {
422 printk(MYIOC_s_WARN_FMT
"%s: Invalid cb_idx (%d)!\n",
423 __func__
, ioc
->name
, cb_idx
);
428 freeme
= MptCallbacks
[cb_idx
](ioc
, mf
, mr
);
431 /* Flush (non-TURBO) reply with a WRITE! */
432 CHIPREG_WRITE32(&ioc
->chip
->ReplyFifo
, pa
);
435 mpt_free_msg_frame(ioc
, mf
);
439 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
441 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
442 * @irq: irq number (not used)
443 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
445 * This routine is registered via the request_irq() kernel API call,
446 * and handles all interrupts generated from a specific MPT adapter
447 * (also referred to as a IO Controller or IOC).
448 * This routine must clear the interrupt from the adapter and does
449 * so by reading the reply FIFO. Multiple replies may be processed
450 * per single call to this routine.
452 * This routine handles register-level access of the adapter but
453 * dispatches (calls) a protocol-specific callback routine to handle
454 * the protocol-specific details of the MPT request completion.
457 mpt_interrupt(int irq
, void *bus_id
)
459 MPT_ADAPTER
*ioc
= bus_id
;
460 u32 pa
= CHIPREG_READ32_dmasync(&ioc
->chip
->ReplyFifo
);
462 if (pa
== 0xFFFFFFFF)
466 * Drain the reply FIFO!
469 if (pa
& MPI_ADDRESS_REPLY_A_BIT
)
472 mpt_turbo_reply(ioc
, pa
);
473 pa
= CHIPREG_READ32_dmasync(&ioc
->chip
->ReplyFifo
);
474 } while (pa
!= 0xFFFFFFFF);
479 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
481 * mpt_base_reply - MPT base driver's callback routine
482 * @ioc: Pointer to MPT_ADAPTER structure
483 * @mf: Pointer to original MPT request frame
484 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
486 * MPT base driver's callback routine; all base driver
487 * "internal" request/reply processing is routed here.
488 * Currently used for EventNotification and EventAck handling.
490 * Returns 1 indicating original alloc'd request frame ptr
491 * should be freed, or 0 if it shouldn't.
494 mpt_base_reply(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
, MPT_FRAME_HDR
*reply
)
499 dmfprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mpt_base_reply() called\n", ioc
->name
));
500 #ifdef CONFIG_FUSION_LOGGING
501 if ((ioc
->debug_level
& MPT_DEBUG_MSG_FRAME
) &&
502 !(reply
->u
.hdr
.MsgFlags
& MPI_MSGFLAGS_CONTINUATION_REPLY
)) {
503 dmfprintk(ioc
, printk(MYIOC_s_INFO_FMT
": Original request frame (@%p) header\n",
505 DBG_DUMP_REQUEST_FRAME_HDR(ioc
, (u32
*)mf
);
509 func
= reply
->u
.hdr
.Function
;
510 dmfprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mpt_base_reply, Function=%02Xh\n",
513 if (func
== MPI_FUNCTION_EVENT_NOTIFICATION
) {
514 EventNotificationReply_t
*pEvReply
= (EventNotificationReply_t
*) reply
;
518 results
= ProcessEventNotification(ioc
, pEvReply
, &evHandlers
);
519 if (results
!= evHandlers
) {
520 /* CHECKME! Any special handling needed here? */
521 devtverboseprintk(ioc
, printk(MYIOC_s_WARN_FMT
"Called %d event handlers, sum results = %d\n",
522 ioc
->name
, evHandlers
, results
));
526 * Hmmm... It seems that EventNotificationReply is an exception
527 * to the rule of one reply per request.
529 if (pEvReply
->MsgFlags
& MPI_MSGFLAGS_CONTINUATION_REPLY
) {
532 devtverboseprintk(ioc
, printk(MYIOC_s_WARN_FMT
"EVENT_NOTIFICATION reply %p returns Request frame\n",
533 ioc
->name
, pEvReply
));
536 #ifdef CONFIG_PROC_FS
537 // LogEvent(ioc, pEvReply);
540 } else if (func
== MPI_FUNCTION_EVENT_ACK
) {
541 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mpt_base_reply, EventAck reply received\n",
543 } else if (func
== MPI_FUNCTION_CONFIG
) {
547 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"config_complete (mf=%p,mr=%p)\n",
548 ioc
->name
, mf
, reply
));
550 pCfg
= * ((CONFIGPARMS
**)((u8
*) mf
+ ioc
->req_sz
- sizeof(void *)));
553 /* disable timer and remove from linked list */
554 del_timer(&pCfg
->timer
);
556 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
557 list_del(&pCfg
->linkage
);
558 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
561 * If IOC Status is SUCCESS, save the header
562 * and set the status code to GOOD.
564 pCfg
->status
= MPT_CONFIG_ERROR
;
566 ConfigReply_t
*pReply
= (ConfigReply_t
*)reply
;
569 status
= le16_to_cpu(pReply
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
570 dcprintk(ioc
, printk(MYIOC_s_NOTE_FMT
" IOCStatus=%04xh, IOCLogInfo=%08xh\n",
571 ioc
->name
, status
, le32_to_cpu(pReply
->IOCLogInfo
)));
573 pCfg
->status
= status
;
574 if (status
== MPI_IOCSTATUS_SUCCESS
) {
575 if ((pReply
->Header
.PageType
&
576 MPI_CONFIG_PAGETYPE_MASK
) ==
577 MPI_CONFIG_PAGETYPE_EXTENDED
) {
578 pCfg
->cfghdr
.ehdr
->ExtPageLength
=
579 le16_to_cpu(pReply
->ExtPageLength
);
580 pCfg
->cfghdr
.ehdr
->ExtPageType
=
583 pCfg
->cfghdr
.hdr
->PageVersion
= pReply
->Header
.PageVersion
;
585 /* If this is a regular header, save PageLength. */
586 /* LMP Do this better so not using a reserved field! */
587 pCfg
->cfghdr
.hdr
->PageLength
= pReply
->Header
.PageLength
;
588 pCfg
->cfghdr
.hdr
->PageNumber
= pReply
->Header
.PageNumber
;
589 pCfg
->cfghdr
.hdr
->PageType
= pReply
->Header
.PageType
;
594 * Wake up the original calling thread
599 } else if (func
== MPI_FUNCTION_SAS_IO_UNIT_CONTROL
) {
600 /* we should be always getting a reply frame */
601 memcpy(ioc
->persist_reply_frame
, reply
,
602 min(MPT_DEFAULT_FRAME_SIZE
,
603 4*reply
->u
.reply
.MsgLength
));
604 del_timer(&ioc
->persist_timer
);
605 ioc
->persist_wait_done
= 1;
608 printk(MYIOC_s_ERR_FMT
"Unexpected msg function (=%02Xh) reply received!\n",
613 * Conditionally tell caller to free the original
614 * EventNotification/EventAck/unexpected request frame!
619 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
621 * mpt_register - Register protocol-specific main callback handler.
622 * @cbfunc: callback function pointer
623 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
625 * This routine is called by a protocol-specific driver (SCSI host,
626 * LAN, SCSI target) to register its reply callback routine. Each
627 * protocol-specific driver must do this before it will be able to
628 * use any IOC resources, such as obtaining request frames.
630 * NOTES: The SCSI protocol driver currently calls this routine thrice
631 * in order to register separate callbacks; one for "normal" SCSI IO;
632 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
634 * Returns u8 valued "handle" in the range (and S.O.D. order)
635 * {N,...,7,6,5,...,1} if successful.
636 * A return value of MPT_MAX_PROTOCOL_DRIVERS (including zero!) should be
637 * considered an error by the caller.
640 mpt_register(MPT_CALLBACK cbfunc
, MPT_DRIVER_CLASS dclass
)
643 last_drv_idx
= MPT_MAX_PROTOCOL_DRIVERS
;
646 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
647 * (slot/handle 0 is reserved!)
649 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
650 if (MptCallbacks
[cb_idx
] == NULL
) {
651 MptCallbacks
[cb_idx
] = cbfunc
;
652 MptDriverClass
[cb_idx
] = dclass
;
653 MptEvHandlers
[cb_idx
] = NULL
;
654 last_drv_idx
= cb_idx
;
662 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
664 * mpt_deregister - Deregister a protocol drivers resources.
665 * @cb_idx: previously registered callback handle
667 * Each protocol-specific driver should call this routine when its
668 * module is unloaded.
671 mpt_deregister(u8 cb_idx
)
673 if (cb_idx
&& (cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
)) {
674 MptCallbacks
[cb_idx
] = NULL
;
675 MptDriverClass
[cb_idx
] = MPTUNKNOWN_DRIVER
;
676 MptEvHandlers
[cb_idx
] = NULL
;
682 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
684 * mpt_event_register - Register protocol-specific event callback handler.
685 * @cb_idx: previously registered (via mpt_register) callback handle
686 * @ev_cbfunc: callback function
688 * This routine can be called by one or more protocol-specific drivers
689 * if/when they choose to be notified of MPT events.
691 * Returns 0 for success.
694 mpt_event_register(u8 cb_idx
, MPT_EVHANDLER ev_cbfunc
)
696 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
699 MptEvHandlers
[cb_idx
] = ev_cbfunc
;
703 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
705 * mpt_event_deregister - Deregister protocol-specific event callback handler
706 * @cb_idx: previously registered callback handle
708 * Each protocol-specific driver should call this routine
709 * when it does not (or can no longer) handle events,
710 * or when its module is unloaded.
713 mpt_event_deregister(u8 cb_idx
)
715 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
718 MptEvHandlers
[cb_idx
] = NULL
;
721 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
723 * mpt_reset_register - Register protocol-specific IOC reset handler.
724 * @cb_idx: previously registered (via mpt_register) callback handle
725 * @reset_func: reset function
727 * This routine can be called by one or more protocol-specific drivers
728 * if/when they choose to be notified of IOC resets.
730 * Returns 0 for success.
733 mpt_reset_register(u8 cb_idx
, MPT_RESETHANDLER reset_func
)
735 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
738 MptResetHandlers
[cb_idx
] = reset_func
;
742 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
744 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
745 * @cb_idx: previously registered callback handle
747 * Each protocol-specific driver should call this routine
748 * when it does not (or can no longer) handle IOC reset handling,
749 * or when its module is unloaded.
752 mpt_reset_deregister(u8 cb_idx
)
754 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
757 MptResetHandlers
[cb_idx
] = NULL
;
760 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
762 * mpt_device_driver_register - Register device driver hooks
763 * @dd_cbfunc: driver callbacks struct
764 * @cb_idx: MPT protocol driver index
767 mpt_device_driver_register(struct mpt_pci_driver
* dd_cbfunc
, u8 cb_idx
)
770 const struct pci_device_id
*id
;
772 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
775 MptDeviceDriverHandlers
[cb_idx
] = dd_cbfunc
;
777 /* call per pci device probe entry point */
778 list_for_each_entry(ioc
, &ioc_list
, list
) {
779 id
= ioc
->pcidev
->driver
?
780 ioc
->pcidev
->driver
->id_table
: NULL
;
781 if (dd_cbfunc
->probe
)
782 dd_cbfunc
->probe(ioc
->pcidev
, id
);
788 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
790 * mpt_device_driver_deregister - DeRegister device driver hooks
791 * @cb_idx: MPT protocol driver index
794 mpt_device_driver_deregister(u8 cb_idx
)
796 struct mpt_pci_driver
*dd_cbfunc
;
799 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
802 dd_cbfunc
= MptDeviceDriverHandlers
[cb_idx
];
804 list_for_each_entry(ioc
, &ioc_list
, list
) {
805 if (dd_cbfunc
->remove
)
806 dd_cbfunc
->remove(ioc
->pcidev
);
809 MptDeviceDriverHandlers
[cb_idx
] = NULL
;
813 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
815 * mpt_get_msg_frame - Obtain an MPT request frame from the pool
816 * @cb_idx: Handle of registered MPT protocol driver
817 * @ioc: Pointer to MPT adapter structure
819 * Obtain an MPT request frame from the pool (of 1024) that are
820 * allocated per MPT adapter.
822 * Returns pointer to a MPT request frame or %NULL if none are available
823 * or IOC is not active.
826 mpt_get_msg_frame(u8 cb_idx
, MPT_ADAPTER
*ioc
)
830 u16 req_idx
; /* Request index */
832 /* validate handle and ioc identifier */
836 printk(MYIOC_s_WARN_FMT
"IOC Not Active! mpt_get_msg_frame "
837 "returning NULL!\n", ioc
->name
);
840 /* If interrupts are not attached, do not return a request frame */
844 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
845 if (!list_empty(&ioc
->FreeQ
)) {
848 mf
= list_entry(ioc
->FreeQ
.next
, MPT_FRAME_HDR
,
849 u
.frame
.linkage
.list
);
850 list_del(&mf
->u
.frame
.linkage
.list
);
851 mf
->u
.frame
.linkage
.arg1
= 0;
852 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= cb_idx
; /* byte */
853 req_offset
= (u8
*)mf
- (u8
*)ioc
->req_frames
;
855 req_idx
= req_offset
/ ioc
->req_sz
;
856 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(req_idx
);
857 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.rsvd
= 0;
858 /* Default, will be changed if necessary in SG generation */
859 ioc
->RequestNB
[req_idx
] = ioc
->NB_for_64_byte_frame
;
866 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
870 printk(MYIOC_s_WARN_FMT
"IOC Active. No free Msg Frames! "
871 "Count 0x%x Max 0x%x\n", ioc
->name
, ioc
->mfcnt
,
874 if (mfcounter
== PRINT_MF_COUNT
)
875 printk(MYIOC_s_INFO_FMT
"MF Count 0x%x Max 0x%x \n", ioc
->name
,
876 ioc
->mfcnt
, ioc
->req_depth
);
879 dmfprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mpt_get_msg_frame(%d,%d), got mf=%p\n",
880 ioc
->name
, cb_idx
, ioc
->id
, mf
));
884 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
886 * mpt_put_msg_frame - Send a protocol-specific MPT request frame to an IOC
887 * @cb_idx: Handle of registered MPT protocol driver
888 * @ioc: Pointer to MPT adapter structure
889 * @mf: Pointer to MPT request frame
891 * This routine posts an MPT request frame to the request post FIFO of a
892 * specific MPT adapter.
895 mpt_put_msg_frame(u8 cb_idx
, MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
)
899 u16 req_idx
; /* Request index */
901 /* ensure values are reset properly! */
902 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= cb_idx
; /* byte */
903 req_offset
= (u8
*)mf
- (u8
*)ioc
->req_frames
;
905 req_idx
= req_offset
/ ioc
->req_sz
;
906 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(req_idx
);
907 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.rsvd
= 0;
909 DBG_DUMP_PUT_MSG_FRAME(ioc
, (u32
*)mf
);
911 mf_dma_addr
= (ioc
->req_frames_low_dma
+ req_offset
) | ioc
->RequestNB
[req_idx
];
912 dsgprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mf_dma_addr=%x req_idx=%d "
913 "RequestNB=%x\n", ioc
->name
, mf_dma_addr
, req_idx
,
914 ioc
->RequestNB
[req_idx
]));
915 CHIPREG_WRITE32(&ioc
->chip
->RequestFifo
, mf_dma_addr
);
919 * mpt_put_msg_frame_hi_pri - Send a hi-pri protocol-specific MPT request frame
920 * @cb_idx: Handle of registered MPT protocol driver
921 * @ioc: Pointer to MPT adapter structure
922 * @mf: Pointer to MPT request frame
924 * Send a protocol-specific MPT request frame to an IOC using
925 * hi-priority request queue.
927 * This routine posts an MPT request frame to the request post FIFO of a
928 * specific MPT adapter.
931 mpt_put_msg_frame_hi_pri(u8 cb_idx
, MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
)
935 u16 req_idx
; /* Request index */
937 /* ensure values are reset properly! */
938 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= cb_idx
;
939 req_offset
= (u8
*)mf
- (u8
*)ioc
->req_frames
;
940 req_idx
= req_offset
/ ioc
->req_sz
;
941 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(req_idx
);
942 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.rsvd
= 0;
944 DBG_DUMP_PUT_MSG_FRAME(ioc
, (u32
*)mf
);
946 mf_dma_addr
= (ioc
->req_frames_low_dma
+ req_offset
);
947 dsgprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mf_dma_addr=%x req_idx=%d\n",
948 ioc
->name
, mf_dma_addr
, req_idx
));
949 CHIPREG_WRITE32(&ioc
->chip
->RequestHiPriFifo
, mf_dma_addr
);
952 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
954 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
955 * @handle: Handle of registered MPT protocol driver
956 * @ioc: Pointer to MPT adapter structure
957 * @mf: Pointer to MPT request frame
959 * This routine places a MPT request frame back on the MPT adapter's
963 mpt_free_msg_frame(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
)
967 /* Put Request back on FreeQ! */
968 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
969 mf
->u
.frame
.linkage
.arg1
= 0xdeadbeaf; /* signature to know if this mf is freed */
970 list_add_tail(&mf
->u
.frame
.linkage
.list
, &ioc
->FreeQ
);
974 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
977 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
979 * mpt_add_sge - Place a simple SGE at address pAddr.
980 * @pAddr: virtual address for SGE
981 * @flagslength: SGE flags and data transfer length
982 * @dma_addr: Physical address
984 * This routine places a MPT request frame back on the MPT adapter's
988 mpt_add_sge(char *pAddr
, u32 flagslength
, dma_addr_t dma_addr
)
990 if (sizeof(dma_addr_t
) == sizeof(u64
)) {
991 SGESimple64_t
*pSge
= (SGESimple64_t
*) pAddr
;
992 u32 tmp
= dma_addr
& 0xFFFFFFFF;
994 pSge
->FlagsLength
= cpu_to_le32(flagslength
);
995 pSge
->Address
.Low
= cpu_to_le32(tmp
);
996 tmp
= (u32
) ((u64
)dma_addr
>> 32);
997 pSge
->Address
.High
= cpu_to_le32(tmp
);
1000 SGESimple32_t
*pSge
= (SGESimple32_t
*) pAddr
;
1001 pSge
->FlagsLength
= cpu_to_le32(flagslength
);
1002 pSge
->Address
= cpu_to_le32(dma_addr
);
1006 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1008 * mpt_send_handshake_request - Send MPT request via doorbell handshake method.
1009 * @cb_idx: Handle of registered MPT protocol driver
1010 * @ioc: Pointer to MPT adapter structure
1011 * @reqBytes: Size of the request in bytes
1012 * @req: Pointer to MPT request frame
1013 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1015 * This routine is used exclusively to send MptScsiTaskMgmt
1016 * requests since they are required to be sent via doorbell handshake.
1018 * NOTE: It is the callers responsibility to byte-swap fields in the
1019 * request which are greater than 1 byte in size.
1021 * Returns 0 for success, non-zero for failure.
1024 mpt_send_handshake_request(u8 cb_idx
, MPT_ADAPTER
*ioc
, int reqBytes
, u32
*req
, int sleepFlag
)
1030 /* State is known to be good upon entering
1031 * this function so issue the bus reset
1036 * Emulate what mpt_put_msg_frame() does /wrt to sanity
1037 * setting cb_idx/req_idx. But ONLY if this request
1038 * is in proper (pre-alloc'd) request buffer range...
1040 ii
= MFPTR_2_MPT_INDEX(ioc
,(MPT_FRAME_HDR
*)req
);
1041 if (reqBytes
>= 12 && ii
>= 0 && ii
< ioc
->req_depth
) {
1042 MPT_FRAME_HDR
*mf
= (MPT_FRAME_HDR
*)req
;
1043 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(ii
);
1044 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= cb_idx
;
1047 /* Make sure there are no doorbells */
1048 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1050 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
,
1051 ((MPI_FUNCTION_HANDSHAKE
<<MPI_DOORBELL_FUNCTION_SHIFT
) |
1052 ((reqBytes
/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT
)));
1054 /* Wait for IOC doorbell int */
1055 if ((ii
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0) {
1059 /* Read doorbell and check for active bit */
1060 if (!(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & MPI_DOORBELL_ACTIVE
))
1063 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mpt_send_handshake_request start, WaitCnt=%d\n",
1066 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1068 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0) {
1072 /* Send request via doorbell handshake */
1073 req_as_bytes
= (u8
*) req
;
1074 for (ii
= 0; ii
< reqBytes
/4; ii
++) {
1077 word
= ((req_as_bytes
[(ii
*4) + 0] << 0) |
1078 (req_as_bytes
[(ii
*4) + 1] << 8) |
1079 (req_as_bytes
[(ii
*4) + 2] << 16) |
1080 (req_as_bytes
[(ii
*4) + 3] << 24));
1081 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, word
);
1082 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0) {
1088 if (r
>= 0 && WaitForDoorbellInt(ioc
, 10, sleepFlag
) >= 0)
1093 /* Make sure there are no doorbells */
1094 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1099 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1101 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
1102 * @ioc: Pointer to MPT adapter structure
1103 * @access_control_value: define bits below
1104 * @sleepFlag: Specifies whether the process can sleep
1106 * Provides mechanism for the host driver to control the IOC's
1107 * Host Page Buffer access.
1109 * Access Control Value - bits[15:12]
1111 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1112 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1113 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1115 * Returns 0 for success, non-zero for failure.
1119 mpt_host_page_access_control(MPT_ADAPTER
*ioc
, u8 access_control_value
, int sleepFlag
)
1123 /* return if in use */
1124 if (CHIPREG_READ32(&ioc
->chip
->Doorbell
)
1125 & MPI_DOORBELL_ACTIVE
)
1128 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1130 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
,
1131 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1132 <<MPI_DOORBELL_FUNCTION_SHIFT
) |
1133 (access_control_value
<<12)));
1135 /* Wait for IOC to clear Doorbell Status bit */
1136 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0) {
1142 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1144 * mpt_host_page_alloc - allocate system memory for the fw
1145 * @ioc: Pointer to pointer to IOC adapter
1146 * @ioc_init: Pointer to ioc init config page
1148 * If we already allocated memory in past, then resend the same pointer.
1149 * Returns 0 for success, non-zero for failure.
1152 mpt_host_page_alloc(MPT_ADAPTER
*ioc
, pIOCInit_t ioc_init
)
1156 u32 host_page_buffer_sz
=0;
1158 if(!ioc
->HostPageBuffer
) {
1160 host_page_buffer_sz
=
1161 le32_to_cpu(ioc
->facts
.HostPageBufferSGE
.FlagsLength
) & 0xFFFFFF;
1163 if(!host_page_buffer_sz
)
1164 return 0; /* fw doesn't need any host buffers */
1166 /* spin till we get enough memory */
1167 while(host_page_buffer_sz
> 0) {
1169 if((ioc
->HostPageBuffer
= pci_alloc_consistent(
1171 host_page_buffer_sz
,
1172 &ioc
->HostPageBuffer_dma
)) != NULL
) {
1174 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
1175 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1176 ioc
->name
, ioc
->HostPageBuffer
,
1177 (u32
)ioc
->HostPageBuffer_dma
,
1178 host_page_buffer_sz
));
1179 ioc
->alloc_total
+= host_page_buffer_sz
;
1180 ioc
->HostPageBuffer_sz
= host_page_buffer_sz
;
1184 host_page_buffer_sz
-= (4*1024);
1188 if(!ioc
->HostPageBuffer
) {
1189 printk(MYIOC_s_ERR_FMT
1190 "Failed to alloc memory for host_page_buffer!\n",
1195 psge
= (char *)&ioc_init
->HostPageBufferSGE
;
1196 flags_length
= MPI_SGE_FLAGS_SIMPLE_ELEMENT
|
1197 MPI_SGE_FLAGS_SYSTEM_ADDRESS
|
1198 MPI_SGE_FLAGS_32_BIT_ADDRESSING
|
1199 MPI_SGE_FLAGS_HOST_TO_IOC
|
1200 MPI_SGE_FLAGS_END_OF_BUFFER
;
1201 if (sizeof(dma_addr_t
) == sizeof(u64
)) {
1202 flags_length
|= MPI_SGE_FLAGS_64_BIT_ADDRESSING
;
1204 flags_length
= flags_length
<< MPI_SGE_FLAGS_SHIFT
;
1205 flags_length
|= ioc
->HostPageBuffer_sz
;
1206 mpt_add_sge(psge
, flags_length
, ioc
->HostPageBuffer_dma
);
1207 ioc
->facts
.HostPageBufferSGE
= ioc_init
->HostPageBufferSGE
;
1212 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1214 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1215 * @iocid: IOC unique identifier (integer)
1216 * @iocpp: Pointer to pointer to IOC adapter
1218 * Given a unique IOC identifier, set pointer to the associated MPT
1219 * adapter structure.
1221 * Returns iocid and sets iocpp if iocid is found.
1222 * Returns -1 if iocid is not found.
1225 mpt_verify_adapter(int iocid
, MPT_ADAPTER
**iocpp
)
1229 list_for_each_entry(ioc
,&ioc_list
,list
) {
1230 if (ioc
->id
== iocid
) {
1241 * mpt_get_product_name - returns product string
1242 * @vendor: pci vendor id
1243 * @device: pci device id
1244 * @revision: pci revision id
1245 * @prod_name: string returned
1247 * Returns product string displayed when driver loads,
1248 * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1252 mpt_get_product_name(u16 vendor
, u16 device
, u8 revision
, char *prod_name
)
1254 char *product_str
= NULL
;
1256 if (vendor
== PCI_VENDOR_ID_BROCADE
) {
1259 case MPI_MANUFACTPAGE_DEVICEID_FC949E
:
1263 product_str
= "BRE040 A0";
1266 product_str
= "BRE040 A1";
1269 product_str
= "BRE040";
1279 case MPI_MANUFACTPAGE_DEVICEID_FC909
:
1280 product_str
= "LSIFC909 B1";
1282 case MPI_MANUFACTPAGE_DEVICEID_FC919
:
1283 product_str
= "LSIFC919 B0";
1285 case MPI_MANUFACTPAGE_DEVICEID_FC929
:
1286 product_str
= "LSIFC929 B0";
1288 case MPI_MANUFACTPAGE_DEVICEID_FC919X
:
1289 if (revision
< 0x80)
1290 product_str
= "LSIFC919X A0";
1292 product_str
= "LSIFC919XL A1";
1294 case MPI_MANUFACTPAGE_DEVICEID_FC929X
:
1295 if (revision
< 0x80)
1296 product_str
= "LSIFC929X A0";
1298 product_str
= "LSIFC929XL A1";
1300 case MPI_MANUFACTPAGE_DEVICEID_FC939X
:
1301 product_str
= "LSIFC939X A1";
1303 case MPI_MANUFACTPAGE_DEVICEID_FC949X
:
1304 product_str
= "LSIFC949X A1";
1306 case MPI_MANUFACTPAGE_DEVICEID_FC949E
:
1310 product_str
= "LSIFC949E A0";
1313 product_str
= "LSIFC949E A1";
1316 product_str
= "LSIFC949E";
1320 case MPI_MANUFACTPAGE_DEVID_53C1030
:
1324 product_str
= "LSI53C1030 A0";
1327 product_str
= "LSI53C1030 B0";
1330 product_str
= "LSI53C1030 B1";
1333 product_str
= "LSI53C1030 B2";
1336 product_str
= "LSI53C1030 C0";
1339 product_str
= "LSI53C1030T A0";
1342 product_str
= "LSI53C1030T A2";
1345 product_str
= "LSI53C1030T A3";
1348 product_str
= "LSI53C1020A A1";
1351 product_str
= "LSI53C1030";
1355 case MPI_MANUFACTPAGE_DEVID_1030_53C1035
:
1359 product_str
= "LSI53C1035 A2";
1362 product_str
= "LSI53C1035 B0";
1365 product_str
= "LSI53C1035";
1369 case MPI_MANUFACTPAGE_DEVID_SAS1064
:
1373 product_str
= "LSISAS1064 A1";
1376 product_str
= "LSISAS1064 A2";
1379 product_str
= "LSISAS1064 A3";
1382 product_str
= "LSISAS1064 A4";
1385 product_str
= "LSISAS1064";
1389 case MPI_MANUFACTPAGE_DEVID_SAS1064E
:
1393 product_str
= "LSISAS1064E A0";
1396 product_str
= "LSISAS1064E B0";
1399 product_str
= "LSISAS1064E B1";
1402 product_str
= "LSISAS1064E B2";
1405 product_str
= "LSISAS1064E B3";
1408 product_str
= "LSISAS1064E";
1412 case MPI_MANUFACTPAGE_DEVID_SAS1068
:
1416 product_str
= "LSISAS1068 A0";
1419 product_str
= "LSISAS1068 B0";
1422 product_str
= "LSISAS1068 B1";
1425 product_str
= "LSISAS1068";
1429 case MPI_MANUFACTPAGE_DEVID_SAS1068E
:
1433 product_str
= "LSISAS1068E A0";
1436 product_str
= "LSISAS1068E B0";
1439 product_str
= "LSISAS1068E B1";
1442 product_str
= "LSISAS1068E B2";
1445 product_str
= "LSISAS1068E B3";
1448 product_str
= "LSISAS1068E";
1452 case MPI_MANUFACTPAGE_DEVID_SAS1078
:
1456 product_str
= "LSISAS1078 A0";
1459 product_str
= "LSISAS1078 B0";
1462 product_str
= "LSISAS1078 C0";
1465 product_str
= "LSISAS1078 C1";
1468 product_str
= "LSISAS1078 C2";
1471 product_str
= "LSISAS1078";
1479 sprintf(prod_name
, "%s", product_str
);
1483 * mpt_mapresources - map in memory mapped io
1484 * @ioc: Pointer to pointer to IOC adapter
1488 mpt_mapresources(MPT_ADAPTER
*ioc
)
1492 unsigned long mem_phys
;
1498 struct pci_dev
*pdev
;
1501 ioc
->bars
= pci_select_bars(pdev
, IORESOURCE_MEM
);
1502 if (pci_enable_device_mem(pdev
)) {
1503 printk(MYIOC_s_ERR_FMT
"pci_enable_device_mem() "
1504 "failed\n", ioc
->name
);
1507 if (pci_request_selected_regions(pdev
, ioc
->bars
, "mpt")) {
1508 printk(MYIOC_s_ERR_FMT
"pci_request_selected_regions() with "
1509 "MEM failed\n", ioc
->name
);
1513 pci_read_config_byte(pdev
, PCI_CLASS_REVISION
, &revision
);
1515 if (!pci_set_dma_mask(pdev
, DMA_64BIT_MASK
)
1516 && !pci_set_consistent_dma_mask(pdev
, DMA_64BIT_MASK
)) {
1517 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
1518 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1520 } else if (!pci_set_dma_mask(pdev
, DMA_32BIT_MASK
)
1521 && !pci_set_consistent_dma_mask(pdev
, DMA_32BIT_MASK
)) {
1522 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
1523 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1526 printk(MYIOC_s_WARN_FMT
"no suitable DMA mask for %s\n",
1527 ioc
->name
, pci_name(pdev
));
1528 pci_release_selected_regions(pdev
, ioc
->bars
);
1532 mem_phys
= msize
= 0;
1534 for (ii
= 0; ii
< DEVICE_COUNT_RESOURCE
; ii
++) {
1535 if (pci_resource_flags(pdev
, ii
) & PCI_BASE_ADDRESS_SPACE_IO
) {
1538 /* Get I/O space! */
1539 port
= pci_resource_start(pdev
, ii
);
1540 psize
= pci_resource_len(pdev
, ii
);
1545 mem_phys
= pci_resource_start(pdev
, ii
);
1546 msize
= pci_resource_len(pdev
, ii
);
1549 ioc
->mem_size
= msize
;
1552 /* Get logical ptr for PciMem0 space */
1553 /*mem = ioremap(mem_phys, msize);*/
1554 mem
= ioremap(mem_phys
, msize
);
1556 printk(MYIOC_s_ERR_FMT
": ERROR - Unable to map adapter"
1557 " memory!\n", ioc
->name
);
1561 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"mem = %p, mem_phys = %lx\n",
1562 ioc
->name
, mem
, mem_phys
));
1564 ioc
->mem_phys
= mem_phys
;
1565 ioc
->chip
= (SYSIF_REGS __iomem
*)mem
;
1567 /* Save Port IO values in case we need to do downloadboot */
1568 ioc
->pio_mem_phys
= port
;
1569 ioc
->pio_chip
= (SYSIF_REGS __iomem
*)port
;
1574 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1576 * mpt_attach - Install a PCI intelligent MPT adapter.
1577 * @pdev: Pointer to pci_dev structure
1578 * @id: PCI device ID information
1580 * This routine performs all the steps necessary to bring the IOC of
1581 * a MPT adapter to a OPERATIONAL state. This includes registering
1582 * memory regions, registering the interrupt, and allocating request
1583 * and reply memory pools.
1585 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1588 * Returns 0 for success, non-zero for failure.
1590 * TODO: Add support for polled controllers
1593 mpt_attach(struct pci_dev
*pdev
, const struct pci_device_id
*id
)
1600 static int mpt_ids
= 0;
1601 #ifdef CONFIG_PROC_FS
1602 struct proc_dir_entry
*dent
, *ent
;
1605 ioc
= kzalloc(sizeof(MPT_ADAPTER
), GFP_ATOMIC
);
1607 printk(KERN_ERR MYNAM
": ERROR - Insufficient memory to add adapter!\n");
1611 ioc
->id
= mpt_ids
++;
1612 sprintf(ioc
->name
, "ioc%d", ioc
->id
);
1615 * set initial debug level
1616 * (refer to mptdebug.h)
1619 ioc
->debug_level
= mpt_debug_level
;
1620 if (mpt_debug_level
)
1621 printk(KERN_INFO
"mpt_debug_level=%xh\n", mpt_debug_level
);
1623 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
": mpt_adapter_install\n", ioc
->name
));
1626 if (mpt_mapresources(ioc
)) {
1631 ioc
->alloc_total
= sizeof(MPT_ADAPTER
);
1632 ioc
->req_sz
= MPT_DEFAULT_FRAME_SIZE
; /* avoid div by zero! */
1633 ioc
->reply_sz
= MPT_REPLY_FRAME_SIZE
;
1636 ioc
->diagPending
= 0;
1637 spin_lock_init(&ioc
->diagLock
);
1638 spin_lock_init(&ioc
->initializing_hba_lock
);
1640 /* Initialize the event logging.
1642 ioc
->eventTypes
= 0; /* None */
1643 ioc
->eventContext
= 0;
1644 ioc
->eventLogSize
= 0;
1651 ioc
->cached_fw
= NULL
;
1653 /* Initilize SCSI Config Data structure
1655 memset(&ioc
->spi_data
, 0, sizeof(SpiCfgData
));
1657 /* Initialize the running configQ head.
1659 INIT_LIST_HEAD(&ioc
->configQ
);
1661 /* Initialize the fc rport list head.
1663 INIT_LIST_HEAD(&ioc
->fc_rports
);
1665 /* Find lookup slot. */
1666 INIT_LIST_HEAD(&ioc
->list
);
1669 /* Initialize workqueue */
1670 INIT_DELAYED_WORK(&ioc
->fault_reset_work
, mpt_fault_reset_work
);
1671 spin_lock_init(&ioc
->fault_reset_work_lock
);
1673 snprintf(ioc
->reset_work_q_name
, sizeof(ioc
->reset_work_q_name
),
1674 "mpt_poll_%d", ioc
->id
);
1676 create_singlethread_workqueue(ioc
->reset_work_q_name
);
1677 if (!ioc
->reset_work_q
) {
1678 printk(MYIOC_s_ERR_FMT
"Insufficient memory to add adapter!\n",
1680 pci_release_selected_regions(pdev
, ioc
->bars
);
1685 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"facts @ %p, pfacts[0] @ %p\n",
1686 ioc
->name
, &ioc
->facts
, &ioc
->pfacts
[0]));
1688 pci_read_config_byte(pdev
, PCI_CLASS_REVISION
, &revision
);
1689 mpt_get_product_name(pdev
->vendor
, pdev
->device
, revision
, ioc
->prod_name
);
1691 switch (pdev
->device
)
1693 case MPI_MANUFACTPAGE_DEVICEID_FC939X
:
1694 case MPI_MANUFACTPAGE_DEVICEID_FC949X
:
1695 ioc
->errata_flag_1064
= 1;
1696 case MPI_MANUFACTPAGE_DEVICEID_FC909
:
1697 case MPI_MANUFACTPAGE_DEVICEID_FC929
:
1698 case MPI_MANUFACTPAGE_DEVICEID_FC919
:
1699 case MPI_MANUFACTPAGE_DEVICEID_FC949E
:
1703 case MPI_MANUFACTPAGE_DEVICEID_FC929X
:
1704 if (revision
< XL_929
) {
1705 /* 929X Chip Fix. Set Split transactions level
1706 * for PCIX. Set MOST bits to zero.
1708 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1710 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1712 /* 929XL Chip Fix. Set MMRBC to 0x08.
1714 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1716 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1721 case MPI_MANUFACTPAGE_DEVICEID_FC919X
:
1722 /* 919X Chip Fix. Set Split transactions level
1723 * for PCIX. Set MOST bits to zero.
1725 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1727 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1731 case MPI_MANUFACTPAGE_DEVID_53C1030
:
1732 /* 1030 Chip Fix. Disable Split transactions
1733 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1735 if (revision
< C0_1030
) {
1736 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1738 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1741 case MPI_MANUFACTPAGE_DEVID_1030_53C1035
:
1742 ioc
->bus_type
= SPI
;
1745 case MPI_MANUFACTPAGE_DEVID_SAS1064
:
1746 case MPI_MANUFACTPAGE_DEVID_SAS1068
:
1747 ioc
->errata_flag_1064
= 1;
1749 case MPI_MANUFACTPAGE_DEVID_SAS1064E
:
1750 case MPI_MANUFACTPAGE_DEVID_SAS1068E
:
1751 case MPI_MANUFACTPAGE_DEVID_SAS1078
:
1752 ioc
->bus_type
= SAS
;
1755 if (mpt_msi_enable
== -1) {
1756 /* Enable on SAS, disable on FC and SPI */
1757 if (ioc
->bus_type
== SAS
)
1758 ioc
->msi_enable
= 1;
1760 ioc
->msi_enable
= 0;
1762 /* follow flag: 0 - disable; 1 - enable */
1763 ioc
->msi_enable
= mpt_msi_enable
;
1765 if (ioc
->errata_flag_1064
)
1766 pci_disable_io_access(pdev
);
1768 spin_lock_init(&ioc
->FreeQlock
);
1771 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
1773 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1775 /* Set IOC ptr in the pcidev's driver data. */
1776 pci_set_drvdata(ioc
->pcidev
, ioc
);
1778 /* Set lookup ptr. */
1779 list_add_tail(&ioc
->list
, &ioc_list
);
1781 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1783 mpt_detect_bound_ports(ioc
, pdev
);
1785 if ((r
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_BRINGUP
,
1787 printk(MYIOC_s_ERR_FMT
"didn't initialize properly! (%d)\n",
1790 list_del(&ioc
->list
);
1792 ioc
->alt_ioc
->alt_ioc
= NULL
;
1793 iounmap(ioc
->memmap
);
1795 pci_release_selected_regions(pdev
, ioc
->bars
);
1797 destroy_workqueue(ioc
->reset_work_q
);
1798 ioc
->reset_work_q
= NULL
;
1801 pci_set_drvdata(pdev
, NULL
);
1805 /* call per device driver probe entry point */
1806 for(cb_idx
= 0; cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
; cb_idx
++) {
1807 if(MptDeviceDriverHandlers
[cb_idx
] &&
1808 MptDeviceDriverHandlers
[cb_idx
]->probe
) {
1809 MptDeviceDriverHandlers
[cb_idx
]->probe(pdev
,id
);
1813 #ifdef CONFIG_PROC_FS
1815 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1817 dent
= proc_mkdir(ioc
->name
, mpt_proc_root_dir
);
1819 ent
= create_proc_entry("info", S_IFREG
|S_IRUGO
, dent
);
1821 ent
->read_proc
= procmpt_iocinfo_read
;
1824 ent
= create_proc_entry("summary", S_IFREG
|S_IRUGO
, dent
);
1826 ent
->read_proc
= procmpt_summary_read
;
1833 queue_delayed_work(ioc
->reset_work_q
, &ioc
->fault_reset_work
,
1834 msecs_to_jiffies(MPT_POLLING_INTERVAL
));
1839 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1841 * mpt_detach - Remove a PCI intelligent MPT adapter.
1842 * @pdev: Pointer to pci_dev structure
1846 mpt_detach(struct pci_dev
*pdev
)
1848 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
1851 unsigned long flags
;
1852 struct workqueue_struct
*wq
;
1855 * Stop polling ioc for fault condition
1857 spin_lock_irqsave(&ioc
->fault_reset_work_lock
, flags
);
1858 wq
= ioc
->reset_work_q
;
1859 ioc
->reset_work_q
= NULL
;
1860 spin_unlock_irqrestore(&ioc
->fault_reset_work_lock
, flags
);
1861 cancel_delayed_work(&ioc
->fault_reset_work
);
1862 destroy_workqueue(wq
);
1865 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s/summary", ioc
->name
);
1866 remove_proc_entry(pname
, NULL
);
1867 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s/info", ioc
->name
);
1868 remove_proc_entry(pname
, NULL
);
1869 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s", ioc
->name
);
1870 remove_proc_entry(pname
, NULL
);
1872 /* call per device driver remove entry point */
1873 for(cb_idx
= 0; cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
; cb_idx
++) {
1874 if(MptDeviceDriverHandlers
[cb_idx
] &&
1875 MptDeviceDriverHandlers
[cb_idx
]->remove
) {
1876 MptDeviceDriverHandlers
[cb_idx
]->remove(pdev
);
1880 /* Disable interrupts! */
1881 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
1884 synchronize_irq(pdev
->irq
);
1886 /* Clear any lingering interrupt */
1887 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1889 CHIPREG_READ32(&ioc
->chip
->IntStatus
);
1891 mpt_adapter_dispose(ioc
);
1893 pci_set_drvdata(pdev
, NULL
);
1896 /**************************************************************************
1900 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1902 * mpt_suspend - Fusion MPT base driver suspend routine.
1903 * @pdev: Pointer to pci_dev structure
1904 * @state: new state to enter
1907 mpt_suspend(struct pci_dev
*pdev
, pm_message_t state
)
1910 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
1912 device_state
= pci_choose_state(pdev
, state
);
1913 printk(MYIOC_s_INFO_FMT
"pci-suspend: pdev=0x%p, slot=%s, Entering "
1914 "operating state [D%d]\n", ioc
->name
, pdev
, pci_name(pdev
),
1917 /* put ioc into READY_STATE */
1918 if(SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, CAN_SLEEP
)) {
1919 printk(MYIOC_s_ERR_FMT
1920 "pci-suspend: IOC msg unit reset failed!\n", ioc
->name
);
1923 /* disable interrupts */
1924 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
1927 /* Clear any lingering interrupt */
1928 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1930 free_irq(ioc
->pci_irq
, ioc
);
1931 if (ioc
->msi_enable
)
1932 pci_disable_msi(ioc
->pcidev
);
1934 pci_save_state(pdev
);
1935 pci_disable_device(pdev
);
1936 pci_release_selected_regions(pdev
, ioc
->bars
);
1937 pci_set_power_state(pdev
, device_state
);
1941 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1943 * mpt_resume - Fusion MPT base driver resume routine.
1944 * @pdev: Pointer to pci_dev structure
1947 mpt_resume(struct pci_dev
*pdev
)
1949 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
1950 u32 device_state
= pdev
->current_state
;
1954 printk(MYIOC_s_INFO_FMT
"pci-resume: pdev=0x%p, slot=%s, Previous "
1955 "operating state [D%d]\n", ioc
->name
, pdev
, pci_name(pdev
),
1958 pci_set_power_state(pdev
, PCI_D0
);
1959 pci_enable_wake(pdev
, PCI_D0
, 0);
1960 pci_restore_state(pdev
);
1962 err
= mpt_mapresources(ioc
);
1966 printk(MYIOC_s_INFO_FMT
"pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1967 ioc
->name
, (mpt_GetIocState(ioc
, 1) >> MPI_IOC_STATE_SHIFT
),
1968 CHIPREG_READ32(&ioc
->chip
->Doorbell
));
1971 * Errata workaround for SAS pci express:
1972 * Upon returning to the D0 state, the contents of the doorbell will be
1973 * stale data, and this will incorrectly signal to the host driver that
1974 * the firmware is ready to process mpt commands. The workaround is
1975 * to issue a diagnostic reset.
1977 if (ioc
->bus_type
== SAS
&& (pdev
->device
==
1978 MPI_MANUFACTPAGE_DEVID_SAS1068E
|| pdev
->device
==
1979 MPI_MANUFACTPAGE_DEVID_SAS1064E
)) {
1980 if (KickStart(ioc
, 1, CAN_SLEEP
) < 0) {
1981 printk(MYIOC_s_WARN_FMT
"pci-resume: Cannot recover\n",
1987 /* bring ioc to operational state */
1988 printk(MYIOC_s_INFO_FMT
"Sending mpt_do_ioc_recovery\n", ioc
->name
);
1989 recovery_state
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_BRINGUP
,
1991 if (recovery_state
!= 0)
1992 printk(MYIOC_s_WARN_FMT
"pci-resume: Cannot recover, "
1993 "error:[%x]\n", ioc
->name
, recovery_state
);
1995 printk(MYIOC_s_INFO_FMT
1996 "pci-resume: success\n", ioc
->name
);
2004 mpt_signal_reset(u8 index
, MPT_ADAPTER
*ioc
, int reset_phase
)
2006 if ((MptDriverClass
[index
] == MPTSPI_DRIVER
&&
2007 ioc
->bus_type
!= SPI
) ||
2008 (MptDriverClass
[index
] == MPTFC_DRIVER
&&
2009 ioc
->bus_type
!= FC
) ||
2010 (MptDriverClass
[index
] == MPTSAS_DRIVER
&&
2011 ioc
->bus_type
!= SAS
))
2012 /* make sure we only call the relevant reset handler
2015 return (MptResetHandlers
[index
])(ioc
, reset_phase
);
2018 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2020 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
2021 * @ioc: Pointer to MPT adapter structure
2022 * @reason: Event word / reason
2023 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
2025 * This routine performs all the steps necessary to bring the IOC
2026 * to a OPERATIONAL state.
2028 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
2033 * -1 if failed to get board READY
2034 * -2 if READY but IOCFacts Failed
2035 * -3 if READY but PrimeIOCFifos Failed
2036 * -4 if READY but IOCInit Failed
2037 * -5 if failed to enable_device and/or request_selected_regions
2038 * -6 if failed to upload firmware
2041 mpt_do_ioc_recovery(MPT_ADAPTER
*ioc
, u32 reason
, int sleepFlag
)
2043 int hard_reset_done
= 0;
2044 int alt_ioc_ready
= 0;
2051 int reset_alt_ioc_active
= 0;
2052 int irq_allocated
= 0;
2055 printk(MYIOC_s_INFO_FMT
"Initiating %s\n", ioc
->name
,
2056 reason
== MPT_HOSTEVENT_IOC_BRINGUP
? "bringup" : "recovery");
2058 /* Disable reply interrupts (also blocks FreeQ) */
2059 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2063 if (ioc
->alt_ioc
->active
)
2064 reset_alt_ioc_active
= 1;
2066 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
2067 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
, 0xFFFFFFFF);
2068 ioc
->alt_ioc
->active
= 0;
2072 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)
2075 if ((hard_reset_done
= MakeIocReady(ioc
, hard
, sleepFlag
)) < 0) {
2076 if (hard_reset_done
== -4) {
2077 printk(MYIOC_s_WARN_FMT
"Owned by PEER..skipping!\n",
2080 if (reset_alt_ioc_active
&& ioc
->alt_ioc
) {
2081 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
2082 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
2083 "alt_ioc reply irq re-enabled\n", ioc
->alt_ioc
->name
));
2084 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
, MPI_HIM_DIM
);
2085 ioc
->alt_ioc
->active
= 1;
2089 printk(MYIOC_s_WARN_FMT
"NOT READY!\n", ioc
->name
);
2094 /* hard_reset_done = 0 if a soft reset was performed
2095 * and 1 if a hard reset was performed.
2097 if (hard_reset_done
&& reset_alt_ioc_active
&& ioc
->alt_ioc
) {
2098 if ((rc
= MakeIocReady(ioc
->alt_ioc
, 0, sleepFlag
)) == 0)
2101 printk(MYIOC_s_WARN_FMT
"alt_ioc not ready!\n", ioc
->alt_ioc
->name
);
2104 for (ii
=0; ii
<5; ii
++) {
2105 /* Get IOC facts! Allow 5 retries */
2106 if ((rc
= GetIocFacts(ioc
, sleepFlag
, reason
)) == 0)
2112 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2113 "Retry IocFacts failed rc=%x\n", ioc
->name
, rc
));
2115 } else if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
2116 MptDisplayIocCapabilities(ioc
);
2119 if (alt_ioc_ready
) {
2120 if ((rc
= GetIocFacts(ioc
->alt_ioc
, sleepFlag
, reason
)) != 0) {
2121 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2122 "Initial Alt IocFacts failed rc=%x\n", ioc
->name
, rc
));
2123 /* Retry - alt IOC was initialized once
2125 rc
= GetIocFacts(ioc
->alt_ioc
, sleepFlag
, reason
);
2128 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2129 "Retry Alt IocFacts failed rc=%x\n", ioc
->name
, rc
));
2131 reset_alt_ioc_active
= 0;
2132 } else if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
2133 MptDisplayIocCapabilities(ioc
->alt_ioc
);
2137 if ((ret
== 0) && (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) &&
2138 (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)) {
2139 pci_release_selected_regions(ioc
->pcidev
, ioc
->bars
);
2140 ioc
->bars
= pci_select_bars(ioc
->pcidev
, IORESOURCE_MEM
|
2142 if (pci_enable_device(ioc
->pcidev
))
2144 if (pci_request_selected_regions(ioc
->pcidev
, ioc
->bars
,
2150 * Device is reset now. It must have de-asserted the interrupt line
2151 * (if it was asserted) and it should be safe to register for the
2154 if ((ret
== 0) && (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)) {
2156 if (ioc
->pcidev
->irq
) {
2157 if (ioc
->msi_enable
&& !pci_enable_msi(ioc
->pcidev
))
2158 printk(MYIOC_s_INFO_FMT
"PCI-MSI enabled\n",
2161 ioc
->msi_enable
= 0;
2162 rc
= request_irq(ioc
->pcidev
->irq
, mpt_interrupt
,
2163 IRQF_SHARED
, ioc
->name
, ioc
);
2165 printk(MYIOC_s_ERR_FMT
"Unable to allocate "
2166 "interrupt %d!\n", ioc
->name
, ioc
->pcidev
->irq
);
2167 if (ioc
->msi_enable
)
2168 pci_disable_msi(ioc
->pcidev
);
2172 ioc
->pci_irq
= ioc
->pcidev
->irq
;
2173 pci_set_master(ioc
->pcidev
); /* ?? */
2174 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
"installed at interrupt "
2175 "%d\n", ioc
->name
, ioc
->pcidev
->irq
));
2179 /* Prime reply & request queues!
2180 * (mucho alloc's) Must be done prior to
2181 * init as upper addresses are needed for init.
2182 * If fails, continue with alt-ioc processing
2184 if ((ret
== 0) && ((rc
= PrimeIocFifos(ioc
)) != 0))
2187 /* May need to check/upload firmware & data here!
2188 * If fails, continue with alt-ioc processing
2190 if ((ret
== 0) && ((rc
= SendIocInit(ioc
, sleepFlag
)) != 0))
2193 if (alt_ioc_ready
&& ((rc
= PrimeIocFifos(ioc
->alt_ioc
)) != 0)) {
2194 printk(MYIOC_s_WARN_FMT
": alt_ioc (%d) FIFO mgmt alloc!\n",
2195 ioc
->alt_ioc
->name
, rc
);
2197 reset_alt_ioc_active
= 0;
2200 if (alt_ioc_ready
) {
2201 if ((rc
= SendIocInit(ioc
->alt_ioc
, sleepFlag
)) != 0) {
2203 reset_alt_ioc_active
= 0;
2204 printk(MYIOC_s_WARN_FMT
"alt_ioc (%d) init failure!\n",
2205 ioc
->alt_ioc
->name
, rc
);
2209 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
){
2210 if (ioc
->upload_fw
) {
2211 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2212 "firmware upload required!\n", ioc
->name
));
2214 /* Controller is not operational, cannot do upload
2217 rc
= mpt_do_upload(ioc
, sleepFlag
);
2219 if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
) {
2221 * Maintain only one pointer to FW memory
2222 * so there will not be two attempt to
2223 * downloadboot onboard dual function
2224 * chips (mpt_adapter_disable,
2227 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2228 "mpt_upload: alt_%s has cached_fw=%p \n",
2229 ioc
->name
, ioc
->alt_ioc
->name
, ioc
->alt_ioc
->cached_fw
));
2230 ioc
->cached_fw
= NULL
;
2233 printk(MYIOC_s_WARN_FMT
2234 "firmware upload failure!\n", ioc
->name
);
2242 /* Enable! (reply interrupt) */
2243 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, MPI_HIM_DIM
);
2247 if (reset_alt_ioc_active
&& ioc
->alt_ioc
) {
2248 /* (re)Enable alt-IOC! (reply interrupt) */
2249 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"alt_ioc reply irq re-enabled\n",
2250 ioc
->alt_ioc
->name
));
2251 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
, MPI_HIM_DIM
);
2252 ioc
->alt_ioc
->active
= 1;
2255 /* Enable MPT base driver management of EventNotification
2256 * and EventAck handling.
2258 if ((ret
== 0) && (!ioc
->facts
.EventState
))
2259 (void) SendEventNotification(ioc
, 1); /* 1=Enable EventNotification */
2261 if (ioc
->alt_ioc
&& alt_ioc_ready
&& !ioc
->alt_ioc
->facts
.EventState
)
2262 (void) SendEventNotification(ioc
->alt_ioc
, 1); /* 1=Enable EventNotification */
2264 /* Add additional "reason" check before call to GetLanConfigPages
2265 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2266 * recursive scenario; GetLanConfigPages times out, timer expired
2267 * routine calls HardResetHandler, which calls into here again,
2268 * and we try GetLanConfigPages again...
2270 if ((ret
== 0) && (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)) {
2273 * Initalize link list for inactive raid volumes.
2275 mutex_init(&ioc
->raid_data
.inactive_list_mutex
);
2276 INIT_LIST_HEAD(&ioc
->raid_data
.inactive_list
);
2278 if (ioc
->bus_type
== SAS
) {
2280 /* clear persistency table */
2281 if(ioc
->facts
.IOCExceptions
&
2282 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL
) {
2283 ret
= mptbase_sas_persist_operation(ioc
,
2284 MPI_SAS_OP_CLEAR_NOT_PRESENT
);
2291 mpt_findImVolumes(ioc
);
2293 } else if (ioc
->bus_type
== FC
) {
2294 if ((ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
) &&
2295 (ioc
->lan_cnfg_page0
.Header
.PageLength
== 0)) {
2297 * Pre-fetch the ports LAN MAC address!
2298 * (LANPage1_t stuff)
2300 (void) GetLanConfigPages(ioc
);
2301 a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
2302 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2303 "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
2304 ioc
->name
, a
[5], a
[4], a
[3], a
[2], a
[1], a
[0]));
2308 /* Get NVRAM and adapter maximums from SPP 0 and 2
2310 mpt_GetScsiPortSettings(ioc
, 0);
2312 /* Get version and length of SDP 1
2314 mpt_readScsiDevicePageHeaders(ioc
, 0);
2318 if (ioc
->facts
.MsgVersion
>= MPI_VERSION_01_02
)
2319 mpt_findImVolumes(ioc
);
2321 /* Check, and possibly reset, the coalescing value
2323 mpt_read_ioc_pg_1(ioc
);
2325 mpt_read_ioc_pg_4(ioc
);
2328 GetIoUnitPage2(ioc
);
2329 mpt_get_manufacturing_pg_0(ioc
);
2333 * Call each currently registered protocol IOC reset handler
2334 * with post-reset indication.
2335 * NOTE: If we're doing _IOC_BRINGUP, there can be no
2336 * MptResetHandlers[] registered yet.
2338 if (hard_reset_done
) {
2340 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
2341 if ((ret
== 0) && MptResetHandlers
[cb_idx
]) {
2342 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2343 "Calling IOC post_reset handler #%d\n",
2344 ioc
->name
, cb_idx
));
2345 rc
+= mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_POST_RESET
);
2349 if (alt_ioc_ready
&& MptResetHandlers
[cb_idx
]) {
2350 drsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2351 "Calling IOC post_reset handler #%d\n",
2352 ioc
->alt_ioc
->name
, cb_idx
));
2353 rc
+= mpt_signal_reset(cb_idx
, ioc
->alt_ioc
, MPT_IOC_POST_RESET
);
2357 /* FIXME? Examine results here? */
2361 if ((ret
!= 0) && irq_allocated
) {
2362 free_irq(ioc
->pci_irq
, ioc
);
2363 if (ioc
->msi_enable
)
2364 pci_disable_msi(ioc
->pcidev
);
2369 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2371 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2372 * @ioc: Pointer to MPT adapter structure
2373 * @pdev: Pointer to (struct pci_dev) structure
2375 * Search for PCI bus/dev_function which matches
2376 * PCI bus/dev_function (+/-1) for newly discovered 929,
2377 * 929X, 1030 or 1035.
2379 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2380 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2383 mpt_detect_bound_ports(MPT_ADAPTER
*ioc
, struct pci_dev
*pdev
)
2385 struct pci_dev
*peer
=NULL
;
2386 unsigned int slot
= PCI_SLOT(pdev
->devfn
);
2387 unsigned int func
= PCI_FUNC(pdev
->devfn
);
2388 MPT_ADAPTER
*ioc_srch
;
2390 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"PCI device %s devfn=%x/%x,"
2391 " searching for devfn match on %x or %x\n",
2392 ioc
->name
, pci_name(pdev
), pdev
->bus
->number
,
2393 pdev
->devfn
, func
-1, func
+1));
2395 peer
= pci_get_slot(pdev
->bus
, PCI_DEVFN(slot
,func
-1));
2397 peer
= pci_get_slot(pdev
->bus
, PCI_DEVFN(slot
,func
+1));
2402 list_for_each_entry(ioc_srch
, &ioc_list
, list
) {
2403 struct pci_dev
*_pcidev
= ioc_srch
->pcidev
;
2404 if (_pcidev
== peer
) {
2405 /* Paranoia checks */
2406 if (ioc
->alt_ioc
!= NULL
) {
2407 printk(MYIOC_s_WARN_FMT
"Oops, already bound to %s!\n",
2408 ioc
->name
, ioc
->alt_ioc
->name
);
2410 } else if (ioc_srch
->alt_ioc
!= NULL
) {
2411 printk(MYIOC_s_WARN_FMT
"Oops, already bound to %s!\n",
2412 ioc_srch
->name
, ioc_srch
->alt_ioc
->name
);
2415 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
"FOUND! binding to %s\n",
2416 ioc
->name
, ioc_srch
->name
));
2417 ioc_srch
->alt_ioc
= ioc
;
2418 ioc
->alt_ioc
= ioc_srch
;
2424 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2426 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2427 * @ioc: Pointer to MPT adapter structure
2430 mpt_adapter_disable(MPT_ADAPTER
*ioc
)
2435 if (ioc
->cached_fw
!= NULL
) {
2436 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"%s: Pushing FW onto "
2437 "adapter\n", __func__
, ioc
->name
));
2438 if ((ret
= mpt_downloadboot(ioc
, (MpiFwHeader_t
*)
2439 ioc
->cached_fw
, CAN_SLEEP
)) < 0) {
2440 printk(MYIOC_s_WARN_FMT
2441 ": firmware downloadboot failure (%d)!\n",
2446 /* Disable adapter interrupts! */
2447 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2449 /* Clear any lingering interrupt */
2450 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
2452 if (ioc
->alloc
!= NULL
) {
2454 dexitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"free @ %p, sz=%d bytes\n",
2455 ioc
->name
, ioc
->alloc
, ioc
->alloc_sz
));
2456 pci_free_consistent(ioc
->pcidev
, sz
,
2457 ioc
->alloc
, ioc
->alloc_dma
);
2458 ioc
->reply_frames
= NULL
;
2459 ioc
->req_frames
= NULL
;
2461 ioc
->alloc_total
-= sz
;
2464 if (ioc
->sense_buf_pool
!= NULL
) {
2465 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
2466 pci_free_consistent(ioc
->pcidev
, sz
,
2467 ioc
->sense_buf_pool
, ioc
->sense_buf_pool_dma
);
2468 ioc
->sense_buf_pool
= NULL
;
2469 ioc
->alloc_total
-= sz
;
2472 if (ioc
->events
!= NULL
){
2473 sz
= MPTCTL_EVENT_LOG_SIZE
* sizeof(MPT_IOCTL_EVENTS
);
2476 ioc
->alloc_total
-= sz
;
2479 mpt_free_fw_memory(ioc
);
2481 kfree(ioc
->spi_data
.nvram
);
2482 mpt_inactive_raid_list_free(ioc
);
2483 kfree(ioc
->raid_data
.pIocPg2
);
2484 kfree(ioc
->raid_data
.pIocPg3
);
2485 ioc
->spi_data
.nvram
= NULL
;
2486 ioc
->raid_data
.pIocPg3
= NULL
;
2488 if (ioc
->spi_data
.pIocPg4
!= NULL
) {
2489 sz
= ioc
->spi_data
.IocPg4Sz
;
2490 pci_free_consistent(ioc
->pcidev
, sz
,
2491 ioc
->spi_data
.pIocPg4
,
2492 ioc
->spi_data
.IocPg4_dma
);
2493 ioc
->spi_data
.pIocPg4
= NULL
;
2494 ioc
->alloc_total
-= sz
;
2497 if (ioc
->ReqToChain
!= NULL
) {
2498 kfree(ioc
->ReqToChain
);
2499 kfree(ioc
->RequestNB
);
2500 ioc
->ReqToChain
= NULL
;
2503 kfree(ioc
->ChainToChain
);
2504 ioc
->ChainToChain
= NULL
;
2506 if (ioc
->HostPageBuffer
!= NULL
) {
2507 if((ret
= mpt_host_page_access_control(ioc
,
2508 MPI_DB_HPBAC_FREE_BUFFER
, NO_SLEEP
)) != 0) {
2509 printk(MYIOC_s_ERR_FMT
2510 "host page buffers free failed (%d)!\n",
2513 dexitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"HostPageBuffer free @ %p, sz=%d bytes\n",
2514 ioc
->name
, ioc
->HostPageBuffer
, ioc
->HostPageBuffer_sz
));
2515 pci_free_consistent(ioc
->pcidev
, ioc
->HostPageBuffer_sz
,
2516 ioc
->HostPageBuffer
, ioc
->HostPageBuffer_dma
);
2517 ioc
->HostPageBuffer
= NULL
;
2518 ioc
->HostPageBuffer_sz
= 0;
2519 ioc
->alloc_total
-= ioc
->HostPageBuffer_sz
;
2523 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2525 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2526 * @ioc: Pointer to MPT adapter structure
2528 * This routine unregisters h/w resources and frees all alloc'd memory
2529 * associated with a MPT adapter structure.
2532 mpt_adapter_dispose(MPT_ADAPTER
*ioc
)
2534 int sz_first
, sz_last
;
2539 sz_first
= ioc
->alloc_total
;
2541 mpt_adapter_disable(ioc
);
2543 if (ioc
->pci_irq
!= -1) {
2544 free_irq(ioc
->pci_irq
, ioc
);
2545 if (ioc
->msi_enable
)
2546 pci_disable_msi(ioc
->pcidev
);
2550 if (ioc
->memmap
!= NULL
) {
2551 iounmap(ioc
->memmap
);
2555 pci_disable_device(ioc
->pcidev
);
2556 pci_release_selected_regions(ioc
->pcidev
, ioc
->bars
);
2558 #if defined(CONFIG_MTRR) && 0
2559 if (ioc
->mtrr_reg
> 0) {
2560 mtrr_del(ioc
->mtrr_reg
, 0, 0);
2561 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
"MTRR region de-registered\n", ioc
->name
));
2565 /* Zap the adapter lookup ptr! */
2566 list_del(&ioc
->list
);
2568 sz_last
= ioc
->alloc_total
;
2569 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
"free'd %d of %d bytes\n",
2570 ioc
->name
, sz_first
-sz_last
+(int)sizeof(*ioc
), sz_first
));
2573 ioc
->alt_ioc
->alt_ioc
= NULL
;
2578 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2580 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2581 * @ioc: Pointer to MPT adapter structure
2584 MptDisplayIocCapabilities(MPT_ADAPTER
*ioc
)
2588 printk(KERN_INFO
"%s: ", ioc
->name
);
2590 printk("%s: ", ioc
->prod_name
);
2591 printk("Capabilities={");
2593 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_INITIATOR
) {
2594 printk("Initiator");
2598 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_TARGET
) {
2599 printk("%sTarget", i
? "," : "");
2603 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
) {
2604 printk("%sLAN", i
? "," : "");
2610 * This would probably evoke more questions than it's worth
2612 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_TARGET
) {
2613 printk("%sLogBusAddr", i
? "," : "");
2621 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2623 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2624 * @ioc: Pointer to MPT_ADAPTER structure
2625 * @force: Force hard KickStart of IOC
2626 * @sleepFlag: Specifies whether the process can sleep
2629 * 1 - DIAG reset and READY
2630 * 0 - READY initially OR soft reset and READY
2631 * -1 - Any failure on KickStart
2632 * -2 - Msg Unit Reset Failed
2633 * -3 - IO Unit Reset Failed
2634 * -4 - IOC owned by a PEER
2637 MakeIocReady(MPT_ADAPTER
*ioc
, int force
, int sleepFlag
)
2642 int hard_reset_done
= 0;
2647 /* Get current [raw] IOC state */
2648 ioc_state
= mpt_GetIocState(ioc
, 0);
2649 dhsprintk(ioc
, printk(MYIOC_s_INFO_FMT
"MakeIocReady [raw] state=%08x\n", ioc
->name
, ioc_state
));
2652 * Check to see if IOC got left/stuck in doorbell handshake
2653 * grip of death. If so, hard reset the IOC.
2655 if (ioc_state
& MPI_DOORBELL_ACTIVE
) {
2657 printk(MYIOC_s_WARN_FMT
"Unexpected doorbell active!\n",
2661 /* Is it already READY? */
2662 if (!statefault
&& (ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_READY
)
2666 * Check to see if IOC is in FAULT state.
2668 if ((ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_FAULT
) {
2670 printk(MYIOC_s_WARN_FMT
"IOC is in FAULT state!!!\n",
2672 printk(MYIOC_s_WARN_FMT
" FAULT code = %04xh\n",
2673 ioc
->name
, ioc_state
& MPI_DOORBELL_DATA_MASK
);
2677 * Hmmm... Did it get left operational?
2679 if ((ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_OPERATIONAL
) {
2680 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"IOC operational unexpected\n",
2684 * If PCI Peer, exit.
2685 * Else, if no fault conditions are present, issue a MessageUnitReset
2686 * Else, fall through to KickStart case
2688 whoinit
= (ioc_state
& MPI_DOORBELL_WHO_INIT_MASK
) >> MPI_DOORBELL_WHO_INIT_SHIFT
;
2689 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
2690 "whoinit 0x%x statefault %d force %d\n",
2691 ioc
->name
, whoinit
, statefault
, force
));
2692 if (whoinit
== MPI_WHOINIT_PCI_PEER
)
2695 if ((statefault
== 0 ) && (force
== 0)) {
2696 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
)) == 0)
2703 hard_reset_done
= KickStart(ioc
, statefault
||force
, sleepFlag
);
2704 if (hard_reset_done
< 0)
2708 * Loop here waiting for IOC to come READY.
2711 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 5; /* 5 seconds */
2713 while ((ioc_state
= mpt_GetIocState(ioc
, 1)) != MPI_IOC_STATE_READY
) {
2714 if (ioc_state
== MPI_IOC_STATE_OPERATIONAL
) {
2716 * BIOS or previous driver load left IOC in OP state.
2717 * Reset messaging FIFOs.
2719 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
)) != 0) {
2720 printk(MYIOC_s_ERR_FMT
"IOC msg unit reset failed!\n", ioc
->name
);
2723 } else if (ioc_state
== MPI_IOC_STATE_RESET
) {
2725 * Something is wrong. Try to get IOC back
2728 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IO_UNIT_RESET
, sleepFlag
)) != 0) {
2729 printk(MYIOC_s_ERR_FMT
"IO unit reset failed!\n", ioc
->name
);
2736 printk(MYIOC_s_ERR_FMT
"Wait IOC_READY state timeout(%d)!\n",
2737 ioc
->name
, (int)((ii
+5)/HZ
));
2741 if (sleepFlag
== CAN_SLEEP
) {
2744 mdelay (1); /* 1 msec delay */
2749 if (statefault
< 3) {
2750 printk(MYIOC_s_INFO_FMT
"Recovered from %s\n",
2752 statefault
==1 ? "stuck handshake" : "IOC FAULT");
2755 return hard_reset_done
;
2758 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2760 * mpt_GetIocState - Get the current state of a MPT adapter.
2761 * @ioc: Pointer to MPT_ADAPTER structure
2762 * @cooked: Request raw or cooked IOC state
2764 * Returns all IOC Doorbell register bits if cooked==0, else just the
2765 * Doorbell bits in MPI_IOC_STATE_MASK.
2768 mpt_GetIocState(MPT_ADAPTER
*ioc
, int cooked
)
2773 s
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
2774 sc
= s
& MPI_IOC_STATE_MASK
;
2777 ioc
->last_state
= sc
;
2779 return cooked
? sc
: s
;
2782 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2784 * GetIocFacts - Send IOCFacts request to MPT adapter.
2785 * @ioc: Pointer to MPT_ADAPTER structure
2786 * @sleepFlag: Specifies whether the process can sleep
2787 * @reason: If recovery, only update facts.
2789 * Returns 0 for success, non-zero for failure.
2792 GetIocFacts(MPT_ADAPTER
*ioc
, int sleepFlag
, int reason
)
2794 IOCFacts_t get_facts
;
2795 IOCFactsReply_t
*facts
;
2803 /* IOC *must* NOT be in RESET state! */
2804 if (ioc
->last_state
== MPI_IOC_STATE_RESET
) {
2805 printk(MYIOC_s_ERR_FMT
"Can't get IOCFacts NOT READY! (%08x)\n",
2806 ioc
->name
, ioc
->last_state
);
2810 facts
= &ioc
->facts
;
2812 /* Destination (reply area)... */
2813 reply_sz
= sizeof(*facts
);
2814 memset(facts
, 0, reply_sz
);
2816 /* Request area (get_facts on the stack right now!) */
2817 req_sz
= sizeof(get_facts
);
2818 memset(&get_facts
, 0, req_sz
);
2820 get_facts
.Function
= MPI_FUNCTION_IOC_FACTS
;
2821 /* Assert: All other get_facts fields are zero! */
2823 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2824 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2825 ioc
->name
, req_sz
, reply_sz
));
2827 /* No non-zero fields in the get_facts request are greater than
2828 * 1 byte in size, so we can just fire it off as is.
2830 r
= mpt_handshake_req_reply_wait(ioc
, req_sz
, (u32
*)&get_facts
,
2831 reply_sz
, (u16
*)facts
, 5 /*seconds*/, sleepFlag
);
2836 * Now byte swap (GRRR) the necessary fields before any further
2837 * inspection of reply contents.
2839 * But need to do some sanity checks on MsgLength (byte) field
2840 * to make sure we don't zero IOC's req_sz!
2842 /* Did we get a valid reply? */
2843 if (facts
->MsgLength
> offsetof(IOCFactsReply_t
, RequestFrameSize
)/sizeof(u32
)) {
2844 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
2846 * If not been here, done that, save off first WhoInit value
2848 if (ioc
->FirstWhoInit
== WHOINIT_UNKNOWN
)
2849 ioc
->FirstWhoInit
= facts
->WhoInit
;
2852 facts
->MsgVersion
= le16_to_cpu(facts
->MsgVersion
);
2853 facts
->MsgContext
= le32_to_cpu(facts
->MsgContext
);
2854 facts
->IOCExceptions
= le16_to_cpu(facts
->IOCExceptions
);
2855 facts
->IOCStatus
= le16_to_cpu(facts
->IOCStatus
);
2856 facts
->IOCLogInfo
= le32_to_cpu(facts
->IOCLogInfo
);
2857 status
= le16_to_cpu(facts
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
2858 /* CHECKME! IOCStatus, IOCLogInfo */
2860 facts
->ReplyQueueDepth
= le16_to_cpu(facts
->ReplyQueueDepth
);
2861 facts
->RequestFrameSize
= le16_to_cpu(facts
->RequestFrameSize
);
2864 * FC f/w version changed between 1.1 and 1.2
2865 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2866 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2868 if (facts
->MsgVersion
< 0x0102) {
2870 * Handle old FC f/w style, convert to new...
2872 u16 oldv
= le16_to_cpu(facts
->Reserved_0101_FWVersion
);
2873 facts
->FWVersion
.Word
=
2874 ((oldv
<<12) & 0xFF000000) |
2875 ((oldv
<<8) & 0x000FFF00);
2877 facts
->FWVersion
.Word
= le32_to_cpu(facts
->FWVersion
.Word
);
2879 facts
->ProductID
= le16_to_cpu(facts
->ProductID
);
2880 if ((ioc
->facts
.ProductID
& MPI_FW_HEADER_PID_PROD_MASK
)
2881 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI
)
2882 ioc
->ir_firmware
= 1;
2883 facts
->CurrentHostMfaHighAddr
=
2884 le32_to_cpu(facts
->CurrentHostMfaHighAddr
);
2885 facts
->GlobalCredits
= le16_to_cpu(facts
->GlobalCredits
);
2886 facts
->CurrentSenseBufferHighAddr
=
2887 le32_to_cpu(facts
->CurrentSenseBufferHighAddr
);
2888 facts
->CurReplyFrameSize
=
2889 le16_to_cpu(facts
->CurReplyFrameSize
);
2890 facts
->IOCCapabilities
= le32_to_cpu(facts
->IOCCapabilities
);
2893 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2894 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2895 * to 14 in MPI-1.01.0x.
2897 if (facts
->MsgLength
>= (offsetof(IOCFactsReply_t
,FWImageSize
) + 7)/4 &&
2898 facts
->MsgVersion
> 0x0100) {
2899 facts
->FWImageSize
= le32_to_cpu(facts
->FWImageSize
);
2902 sz
= facts
->FWImageSize
;
2907 facts
->FWImageSize
= sz
;
2909 if (!facts
->RequestFrameSize
) {
2910 /* Something is wrong! */
2911 printk(MYIOC_s_ERR_FMT
"IOC reported invalid 0 request size!\n",
2916 r
= sz
= facts
->BlockSize
;
2917 vv
= ((63 / (sz
* 4)) + 1) & 0x03;
2918 ioc
->NB_for_64_byte_frame
= vv
;
2924 ioc
->NBShiftFactor
= shiftFactor
;
2925 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2926 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2927 ioc
->name
, vv
, shiftFactor
, r
));
2929 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
2931 * Set values for this IOC's request & reply frame sizes,
2932 * and request & reply queue depths...
2934 ioc
->req_sz
= min(MPT_DEFAULT_FRAME_SIZE
, facts
->RequestFrameSize
* 4);
2935 ioc
->req_depth
= min_t(int, MPT_MAX_REQ_DEPTH
, facts
->GlobalCredits
);
2936 ioc
->reply_sz
= MPT_REPLY_FRAME_SIZE
;
2937 ioc
->reply_depth
= min_t(int, MPT_DEFAULT_REPLY_DEPTH
, facts
->ReplyQueueDepth
);
2939 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"reply_sz=%3d, reply_depth=%4d\n",
2940 ioc
->name
, ioc
->reply_sz
, ioc
->reply_depth
));
2941 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"req_sz =%3d, req_depth =%4d\n",
2942 ioc
->name
, ioc
->req_sz
, ioc
->req_depth
));
2944 /* Get port facts! */
2945 if ( (r
= GetPortFacts(ioc
, 0, sleepFlag
)) != 0 )
2949 printk(MYIOC_s_ERR_FMT
2950 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2951 ioc
->name
, facts
->MsgLength
, (offsetof(IOCFactsReply_t
,
2952 RequestFrameSize
)/sizeof(u32
)));
2959 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2961 * GetPortFacts - Send PortFacts request to MPT adapter.
2962 * @ioc: Pointer to MPT_ADAPTER structure
2963 * @portnum: Port number
2964 * @sleepFlag: Specifies whether the process can sleep
2966 * Returns 0 for success, non-zero for failure.
2969 GetPortFacts(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
)
2971 PortFacts_t get_pfacts
;
2972 PortFactsReply_t
*pfacts
;
2978 /* IOC *must* NOT be in RESET state! */
2979 if (ioc
->last_state
== MPI_IOC_STATE_RESET
) {
2980 printk(MYIOC_s_ERR_FMT
"Can't get PortFacts NOT READY! (%08x)\n",
2981 ioc
->name
, ioc
->last_state
);
2985 pfacts
= &ioc
->pfacts
[portnum
];
2987 /* Destination (reply area)... */
2988 reply_sz
= sizeof(*pfacts
);
2989 memset(pfacts
, 0, reply_sz
);
2991 /* Request area (get_pfacts on the stack right now!) */
2992 req_sz
= sizeof(get_pfacts
);
2993 memset(&get_pfacts
, 0, req_sz
);
2995 get_pfacts
.Function
= MPI_FUNCTION_PORT_FACTS
;
2996 get_pfacts
.PortNumber
= portnum
;
2997 /* Assert: All other get_pfacts fields are zero! */
2999 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending get PortFacts(%d) request\n",
3000 ioc
->name
, portnum
));
3002 /* No non-zero fields in the get_pfacts request are greater than
3003 * 1 byte in size, so we can just fire it off as is.
3005 ii
= mpt_handshake_req_reply_wait(ioc
, req_sz
, (u32
*)&get_pfacts
,
3006 reply_sz
, (u16
*)pfacts
, 5 /*seconds*/, sleepFlag
);
3010 /* Did we get a valid reply? */
3012 /* Now byte swap the necessary fields in the response. */
3013 pfacts
->MsgContext
= le32_to_cpu(pfacts
->MsgContext
);
3014 pfacts
->IOCStatus
= le16_to_cpu(pfacts
->IOCStatus
);
3015 pfacts
->IOCLogInfo
= le32_to_cpu(pfacts
->IOCLogInfo
);
3016 pfacts
->MaxDevices
= le16_to_cpu(pfacts
->MaxDevices
);
3017 pfacts
->PortSCSIID
= le16_to_cpu(pfacts
->PortSCSIID
);
3018 pfacts
->ProtocolFlags
= le16_to_cpu(pfacts
->ProtocolFlags
);
3019 pfacts
->MaxPostedCmdBuffers
= le16_to_cpu(pfacts
->MaxPostedCmdBuffers
);
3020 pfacts
->MaxPersistentIDs
= le16_to_cpu(pfacts
->MaxPersistentIDs
);
3021 pfacts
->MaxLanBuckets
= le16_to_cpu(pfacts
->MaxLanBuckets
);
3023 max_id
= (ioc
->bus_type
== SAS
) ? pfacts
->PortSCSIID
:
3025 ioc
->devices_per_bus
= (max_id
> 255) ? 256 : max_id
;
3026 ioc
->number_of_buses
= (ioc
->devices_per_bus
< 256) ? 1 : max_id
/256;
3029 * Place all the devices on channels
3033 if (mpt_channel_mapping
) {
3034 ioc
->devices_per_bus
= 1;
3035 ioc
->number_of_buses
= (max_id
> 255) ? 255 : max_id
;
3041 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3043 * SendIocInit - Send IOCInit request to MPT adapter.
3044 * @ioc: Pointer to MPT_ADAPTER structure
3045 * @sleepFlag: Specifies whether the process can sleep
3047 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
3049 * Returns 0 for success, non-zero for failure.
3052 SendIocInit(MPT_ADAPTER
*ioc
, int sleepFlag
)
3055 MPIDefaultReply_t init_reply
;
3061 memset(&ioc_init
, 0, sizeof(ioc_init
));
3062 memset(&init_reply
, 0, sizeof(init_reply
));
3064 ioc_init
.WhoInit
= MPI_WHOINIT_HOST_DRIVER
;
3065 ioc_init
.Function
= MPI_FUNCTION_IOC_INIT
;
3067 /* If we are in a recovery mode and we uploaded the FW image,
3068 * then this pointer is not NULL. Skip the upload a second time.
3069 * Set this flag if cached_fw set for either IOC.
3071 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)
3075 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"upload_fw %d facts.Flags=%x\n",
3076 ioc
->name
, ioc
->upload_fw
, ioc
->facts
.Flags
));
3078 ioc_init
.MaxDevices
= (U8
)ioc
->devices_per_bus
;
3079 ioc_init
.MaxBuses
= (U8
)ioc
->number_of_buses
;
3080 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"facts.MsgVersion=%x\n",
3081 ioc
->name
, ioc
->facts
.MsgVersion
));
3082 if (ioc
->facts
.MsgVersion
>= MPI_VERSION_01_05
) {
3083 // set MsgVersion and HeaderVersion host driver was built with
3084 ioc_init
.MsgVersion
= cpu_to_le16(MPI_VERSION
);
3085 ioc_init
.HeaderVersion
= cpu_to_le16(MPI_HEADER_VERSION
);
3087 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT
) {
3088 ioc_init
.HostPageBufferSGE
= ioc
->facts
.HostPageBufferSGE
;
3089 } else if(mpt_host_page_alloc(ioc
, &ioc_init
))
3092 ioc_init
.ReplyFrameSize
= cpu_to_le16(ioc
->reply_sz
); /* in BYTES */
3094 if (sizeof(dma_addr_t
) == sizeof(u64
)) {
3095 /* Save the upper 32-bits of the request
3096 * (reply) and sense buffers.
3098 ioc_init
.HostMfaHighAddr
= cpu_to_le32((u32
)((u64
)ioc
->alloc_dma
>> 32));
3099 ioc_init
.SenseBufferHighAddr
= cpu_to_le32((u32
)((u64
)ioc
->sense_buf_pool_dma
>> 32));
3101 /* Force 32-bit addressing */
3102 ioc_init
.HostMfaHighAddr
= cpu_to_le32(0);
3103 ioc_init
.SenseBufferHighAddr
= cpu_to_le32(0);
3106 ioc
->facts
.CurrentHostMfaHighAddr
= ioc_init
.HostMfaHighAddr
;
3107 ioc
->facts
.CurrentSenseBufferHighAddr
= ioc_init
.SenseBufferHighAddr
;
3108 ioc
->facts
.MaxDevices
= ioc_init
.MaxDevices
;
3109 ioc
->facts
.MaxBuses
= ioc_init
.MaxBuses
;
3111 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending IOCInit (req @ %p)\n",
3112 ioc
->name
, &ioc_init
));
3114 r
= mpt_handshake_req_reply_wait(ioc
, sizeof(IOCInit_t
), (u32
*)&ioc_init
,
3115 sizeof(MPIDefaultReply_t
), (u16
*)&init_reply
, 10 /*seconds*/, sleepFlag
);
3117 printk(MYIOC_s_ERR_FMT
"Sending IOCInit failed(%d)!\n",ioc
->name
, r
);
3121 /* No need to byte swap the multibyte fields in the reply
3122 * since we don't even look at its contents.
3125 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending PortEnable (req @ %p)\n",
3126 ioc
->name
, &ioc_init
));
3128 if ((r
= SendPortEnable(ioc
, 0, sleepFlag
)) != 0) {
3129 printk(MYIOC_s_ERR_FMT
"Sending PortEnable failed(%d)!\n",ioc
->name
, r
);
3133 /* YIKES! SUPER IMPORTANT!!!
3134 * Poll IocState until _OPERATIONAL while IOC is doing
3135 * LoopInit and TargetDiscovery!
3138 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 60; /* 60 seconds */
3139 state
= mpt_GetIocState(ioc
, 1);
3140 while (state
!= MPI_IOC_STATE_OPERATIONAL
&& --cntdn
) {
3141 if (sleepFlag
== CAN_SLEEP
) {
3148 printk(MYIOC_s_ERR_FMT
"Wait IOC_OP state timeout(%d)!\n",
3149 ioc
->name
, (int)((count
+5)/HZ
));
3153 state
= mpt_GetIocState(ioc
, 1);
3156 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Wait IOC_OPERATIONAL state (cnt=%d)\n",
3159 ioc
->aen_event_read_flag
=0;
3163 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3165 * SendPortEnable - Send PortEnable request to MPT adapter port.
3166 * @ioc: Pointer to MPT_ADAPTER structure
3167 * @portnum: Port number to enable
3168 * @sleepFlag: Specifies whether the process can sleep
3170 * Send PortEnable to bring IOC to OPERATIONAL state.
3172 * Returns 0 for success, non-zero for failure.
3175 SendPortEnable(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
)
3177 PortEnable_t port_enable
;
3178 MPIDefaultReply_t reply_buf
;
3183 /* Destination... */
3184 reply_sz
= sizeof(MPIDefaultReply_t
);
3185 memset(&reply_buf
, 0, reply_sz
);
3187 req_sz
= sizeof(PortEnable_t
);
3188 memset(&port_enable
, 0, req_sz
);
3190 port_enable
.Function
= MPI_FUNCTION_PORT_ENABLE
;
3191 port_enable
.PortNumber
= portnum
;
3192 /* port_enable.ChainOffset = 0; */
3193 /* port_enable.MsgFlags = 0; */
3194 /* port_enable.MsgContext = 0; */
3196 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending Port(%d)Enable (req @ %p)\n",
3197 ioc
->name
, portnum
, &port_enable
));
3199 /* RAID FW may take a long time to enable
3201 if (ioc
->ir_firmware
|| ioc
->bus_type
== SAS
) {
3202 rc
= mpt_handshake_req_reply_wait(ioc
, req_sz
,
3203 (u32
*)&port_enable
, reply_sz
, (u16
*)&reply_buf
,
3204 300 /*seconds*/, sleepFlag
);
3206 rc
= mpt_handshake_req_reply_wait(ioc
, req_sz
,
3207 (u32
*)&port_enable
, reply_sz
, (u16
*)&reply_buf
,
3208 30 /*seconds*/, sleepFlag
);
3214 * mpt_alloc_fw_memory - allocate firmware memory
3215 * @ioc: Pointer to MPT_ADAPTER structure
3216 * @size: total FW bytes
3218 * If memory has already been allocated, the same (cached) value
3221 * Return 0 if successfull, or non-zero for failure
3224 mpt_alloc_fw_memory(MPT_ADAPTER
*ioc
, int size
)
3228 if (ioc
->cached_fw
) {
3229 rc
= 0; /* use already allocated memory */
3232 else if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
) {
3233 ioc
->cached_fw
= ioc
->alt_ioc
->cached_fw
; /* use alt_ioc's memory */
3234 ioc
->cached_fw_dma
= ioc
->alt_ioc
->cached_fw_dma
;
3238 ioc
->cached_fw
= pci_alloc_consistent(ioc
->pcidev
, size
, &ioc
->cached_fw_dma
);
3239 if (!ioc
->cached_fw
) {
3240 printk(MYIOC_s_ERR_FMT
"Unable to allocate memory for the cached firmware image!\n",
3244 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"FW Image @ %p[%p], sz=%d[%x] bytes\n",
3245 ioc
->name
, ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, size
, size
));
3246 ioc
->alloc_total
+= size
;
3254 * mpt_free_fw_memory - free firmware memory
3255 * @ioc: Pointer to MPT_ADAPTER structure
3257 * If alt_img is NULL, delete from ioc structure.
3258 * Else, delete a secondary image in same format.
3261 mpt_free_fw_memory(MPT_ADAPTER
*ioc
)
3265 if (!ioc
->cached_fw
)
3268 sz
= ioc
->facts
.FWImageSize
;
3269 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3270 ioc
->name
, ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, sz
, sz
));
3271 pci_free_consistent(ioc
->pcidev
, sz
, ioc
->cached_fw
, ioc
->cached_fw_dma
);
3272 ioc
->alloc_total
-= sz
;
3273 ioc
->cached_fw
= NULL
;
3276 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3278 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3279 * @ioc: Pointer to MPT_ADAPTER structure
3280 * @sleepFlag: Specifies whether the process can sleep
3282 * Returns 0 for success, >0 for handshake failure
3283 * <0 for fw upload failure.
3285 * Remark: If bound IOC and a successful FWUpload was performed
3286 * on the bound IOC, the second image is discarded
3287 * and memory is free'd. Both channels must upload to prevent
3288 * IOC from running in degraded mode.
3291 mpt_do_upload(MPT_ADAPTER
*ioc
, int sleepFlag
)
3293 u8 reply
[sizeof(FWUploadReply_t
)];
3294 FWUpload_t
*prequest
;
3295 FWUploadReply_t
*preply
;
3296 FWUploadTCSGE_t
*ptcsge
;
3299 int ii
, sz
, reply_sz
;
3302 /* If the image size is 0, we are done.
3304 if ((sz
= ioc
->facts
.FWImageSize
) == 0)
3307 if (mpt_alloc_fw_memory(ioc
, ioc
->facts
.FWImageSize
) != 0)
3310 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3311 ioc
->name
, ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, sz
, sz
));
3313 prequest
= (sleepFlag
== NO_SLEEP
) ? kzalloc(ioc
->req_sz
, GFP_ATOMIC
) :
3314 kzalloc(ioc
->req_sz
, GFP_KERNEL
);
3316 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"fw upload failed "
3317 "while allocating memory \n", ioc
->name
));
3318 mpt_free_fw_memory(ioc
);
3322 preply
= (FWUploadReply_t
*)&reply
;
3324 reply_sz
= sizeof(reply
);
3325 memset(preply
, 0, reply_sz
);
3327 prequest
->ImageType
= MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM
;
3328 prequest
->Function
= MPI_FUNCTION_FW_UPLOAD
;
3330 ptcsge
= (FWUploadTCSGE_t
*) &prequest
->SGL
;
3331 ptcsge
->DetailsLength
= 12;
3332 ptcsge
->Flags
= MPI_SGE_FLAGS_TRANSACTION_ELEMENT
;
3333 ptcsge
->ImageSize
= cpu_to_le32(sz
);
3336 sgeoffset
= sizeof(FWUpload_t
) - sizeof(SGE_MPI_UNION
) + sizeof(FWUploadTCSGE_t
);
3338 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_READ
| sz
;
3339 mpt_add_sge((char *)ptcsge
, flagsLength
, ioc
->cached_fw_dma
);
3341 sgeoffset
+= sizeof(u32
) + sizeof(dma_addr_t
);
3342 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
": Sending FW Upload (req @ %p) sgeoffset=%d \n",
3343 ioc
->name
, prequest
, sgeoffset
));
3344 DBG_DUMP_FW_REQUEST_FRAME(ioc
, (u32
*)prequest
);
3346 ii
= mpt_handshake_req_reply_wait(ioc
, sgeoffset
, (u32
*)prequest
,
3347 reply_sz
, (u16
*)preply
, 65 /*seconds*/, sleepFlag
);
3349 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
": FW Upload completed rc=%x \n", ioc
->name
, ii
));
3351 cmdStatus
= -EFAULT
;
3353 /* Handshake transfer was complete and successful.
3354 * Check the Reply Frame.
3356 int status
, transfer_sz
;
3357 status
= le16_to_cpu(preply
->IOCStatus
);
3358 if (status
== MPI_IOCSTATUS_SUCCESS
) {
3359 transfer_sz
= le32_to_cpu(preply
->ActualImageSize
);
3360 if (transfer_sz
== sz
)
3364 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
": do_upload cmdStatus=%d \n",
3365 ioc
->name
, cmdStatus
));
3370 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
": fw upload failed, freeing image \n",
3372 mpt_free_fw_memory(ioc
);
3379 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3381 * mpt_downloadboot - DownloadBoot code
3382 * @ioc: Pointer to MPT_ADAPTER structure
3383 * @pFwHeader: Pointer to firmware header info
3384 * @sleepFlag: Specifies whether the process can sleep
3386 * FwDownloadBoot requires Programmed IO access.
3388 * Returns 0 for success
3389 * -1 FW Image size is 0
3390 * -2 No valid cached_fw Pointer
3391 * <0 for fw upload failure.
3394 mpt_downloadboot(MPT_ADAPTER
*ioc
, MpiFwHeader_t
*pFwHeader
, int sleepFlag
)
3396 MpiExtImageHeader_t
*pExtImage
;
3406 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3407 ioc
->name
, pFwHeader
->ImageSize
, pFwHeader
->ImageSize
, pFwHeader
));
3409 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3410 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3411 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3412 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3413 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3414 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3416 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, (MPI_DIAG_PREVENT_IOC_BOOT
| MPI_DIAG_DISABLE_ARM
));
3419 if (sleepFlag
== CAN_SLEEP
) {
3425 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3426 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_RESET_ADAPTER
);
3428 for (count
= 0; count
< 30; count
++) {
3429 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3430 if (!(diag0val
& MPI_DIAG_RESET_ADAPTER
)) {
3431 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RESET_ADAPTER cleared, count=%d\n",
3436 if (sleepFlag
== CAN_SLEEP
) {
3443 if ( count
== 30 ) {
3444 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot failed! "
3445 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3446 ioc
->name
, diag0val
));
3450 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3451 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3452 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3453 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3454 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3455 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3457 /* Set the DiagRwEn and Disable ARM bits */
3458 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, (MPI_DIAG_RW_ENABLE
| MPI_DIAG_DISABLE_ARM
));
3460 fwSize
= (pFwHeader
->ImageSize
+ 3)/4;
3461 ptrFw
= (u32
*) pFwHeader
;
3463 /* Write the LoadStartAddress to the DiagRw Address Register
3464 * using Programmed IO
3466 if (ioc
->errata_flag_1064
)
3467 pci_enable_io_access(ioc
->pcidev
);
3469 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, pFwHeader
->LoadStartAddress
);
3470 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"LoadStart addr written 0x%x \n",
3471 ioc
->name
, pFwHeader
->LoadStartAddress
));
3473 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write FW Image: 0x%x bytes @ %p\n",
3474 ioc
->name
, fwSize
*4, ptrFw
));
3476 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, *ptrFw
++);
3479 nextImage
= pFwHeader
->NextImageHeaderOffset
;
3481 pExtImage
= (MpiExtImageHeader_t
*) ((char *)pFwHeader
+ nextImage
);
3483 load_addr
= pExtImage
->LoadStartAddress
;
3485 fwSize
= (pExtImage
->ImageSize
+ 3) >> 2;
3486 ptrFw
= (u32
*)pExtImage
;
3488 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3489 ioc
->name
, fwSize
*4, fwSize
*4, ptrFw
, load_addr
));
3490 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, load_addr
);
3493 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, *ptrFw
++);
3495 nextImage
= pExtImage
->NextImageHeaderOffset
;
3498 /* Write the IopResetVectorRegAddr */
3499 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write IopResetVector Addr=%x! \n", ioc
->name
, pFwHeader
->IopResetRegAddr
));
3500 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, pFwHeader
->IopResetRegAddr
);
3502 /* Write the IopResetVectorValue */
3503 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write IopResetVector Value=%x! \n", ioc
->name
, pFwHeader
->IopResetVectorValue
));
3504 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, pFwHeader
->IopResetVectorValue
);
3506 /* Clear the internal flash bad bit - autoincrementing register,
3507 * so must do two writes.
3509 if (ioc
->bus_type
== SPI
) {
3511 * 1030 and 1035 H/W errata, workaround to access
3512 * the ClearFlashBadSignatureBit
3514 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, 0x3F000000);
3515 diagRwData
= CHIPREG_PIO_READ32(&ioc
->pio_chip
->DiagRwData
);
3516 diagRwData
|= 0x40000000;
3517 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, 0x3F000000);
3518 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, diagRwData
);
3520 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3521 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3522 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
|
3523 MPI_DIAG_CLEAR_FLASH_BAD_SIG
);
3526 if (sleepFlag
== CAN_SLEEP
) {
3533 if (ioc
->errata_flag_1064
)
3534 pci_disable_io_access(ioc
->pcidev
);
3536 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3537 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot diag0val=%x, "
3538 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3539 ioc
->name
, diag0val
));
3540 diag0val
&= ~(MPI_DIAG_PREVENT_IOC_BOOT
| MPI_DIAG_DISABLE_ARM
| MPI_DIAG_RW_ENABLE
);
3541 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot now diag0val=%x\n",
3542 ioc
->name
, diag0val
));
3543 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
);
3545 /* Write 0xFF to reset the sequencer */
3546 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3548 if (ioc
->bus_type
== SAS
) {
3549 ioc_state
= mpt_GetIocState(ioc
, 0);
3550 if ( (GetIocFacts(ioc
, sleepFlag
,
3551 MPT_HOSTEVENT_IOC_BRINGUP
)) != 0 ) {
3552 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"GetIocFacts failed: IocState=%x\n",
3553 ioc
->name
, ioc_state
));
3558 for (count
=0; count
<HZ
*20; count
++) {
3559 if ((ioc_state
= mpt_GetIocState(ioc
, 0)) & MPI_IOC_STATE_READY
) {
3560 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3561 "downloadboot successful! (count=%d) IocState=%x\n",
3562 ioc
->name
, count
, ioc_state
));
3563 if (ioc
->bus_type
== SAS
) {
3566 if ((SendIocInit(ioc
, sleepFlag
)) != 0) {
3567 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3568 "downloadboot: SendIocInit failed\n",
3572 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3573 "downloadboot: SendIocInit successful\n",
3577 if (sleepFlag
== CAN_SLEEP
) {
3583 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3584 "downloadboot failed! IocState=%x\n",ioc
->name
, ioc_state
));
3588 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3590 * KickStart - Perform hard reset of MPT adapter.
3591 * @ioc: Pointer to MPT_ADAPTER structure
3592 * @force: Force hard reset
3593 * @sleepFlag: Specifies whether the process can sleep
3595 * This routine places MPT adapter in diagnostic mode via the
3596 * WriteSequence register, and then performs a hard reset of adapter
3597 * via the Diagnostic register.
3599 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3600 * or NO_SLEEP (interrupt thread, use mdelay)
3601 * force - 1 if doorbell active, board fault state
3602 * board operational, IOC_RECOVERY or
3603 * IOC_BRINGUP and there is an alt_ioc.
3607 * 1 - hard reset, READY
3608 * 0 - no reset due to History bit, READY
3609 * -1 - no reset due to History bit but not READY
3610 * OR reset but failed to come READY
3611 * -2 - no reset, could not enter DIAG mode
3612 * -3 - reset but bad FW bit
3615 KickStart(MPT_ADAPTER
*ioc
, int force
, int sleepFlag
)
3617 int hard_reset_done
= 0;
3621 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"KickStarting!\n", ioc
->name
));
3622 if (ioc
->bus_type
== SPI
) {
3623 /* Always issue a Msg Unit Reset first. This will clear some
3624 * SCSI bus hang conditions.
3626 SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
);
3628 if (sleepFlag
== CAN_SLEEP
) {
3635 hard_reset_done
= mpt_diag_reset(ioc
, force
, sleepFlag
);
3636 if (hard_reset_done
< 0)
3637 return hard_reset_done
;
3639 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Diagnostic reset successful!\n",
3642 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 2; /* 2 seconds */
3643 for (cnt
=0; cnt
<cntdn
; cnt
++) {
3644 ioc_state
= mpt_GetIocState(ioc
, 1);
3645 if ((ioc_state
== MPI_IOC_STATE_READY
) || (ioc_state
== MPI_IOC_STATE_OPERATIONAL
)) {
3646 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"KickStart successful! (cnt=%d)\n",
3648 return hard_reset_done
;
3650 if (sleepFlag
== CAN_SLEEP
) {
3657 dinitprintk(ioc
, printk(MYIOC_s_ERR_FMT
"Failed to come READY after reset! IocState=%x\n",
3658 ioc
->name
, mpt_GetIocState(ioc
, 0)));
3662 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3664 * mpt_diag_reset - Perform hard reset of the adapter.
3665 * @ioc: Pointer to MPT_ADAPTER structure
3666 * @ignore: Set if to honor and clear to ignore
3667 * the reset history bit
3668 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3669 * else set to NO_SLEEP (use mdelay instead)
3671 * This routine places the adapter in diagnostic mode via the
3672 * WriteSequence register and then performs a hard reset of adapter
3673 * via the Diagnostic register. Adapter should be in ready state
3674 * upon successful completion.
3676 * Returns: 1 hard reset successful
3677 * 0 no reset performed because reset history bit set
3678 * -2 enabling diagnostic mode failed
3679 * -3 diagnostic reset failed
3682 mpt_diag_reset(MPT_ADAPTER
*ioc
, int ignore
, int sleepFlag
)
3686 int hard_reset_done
= 0;
3689 MpiFwHeader_t
*cached_fw
; /* Pointer to FW */
3691 /* Clear any existing interrupts */
3692 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
3694 if (ioc
->pcidev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1078
) {
3695 drsprintk(ioc
, printk(MYIOC_s_WARN_FMT
"%s: Doorbell=%p; 1078 reset "
3696 "address=%p\n", ioc
->name
, __func__
,
3697 &ioc
->chip
->Doorbell
, &ioc
->chip
->Reset_1078
));
3698 CHIPREG_WRITE32(&ioc
->chip
->Reset_1078
, 0x07);
3699 if (sleepFlag
== CAN_SLEEP
)
3704 for (count
= 0; count
< 60; count
++) {
3705 doorbell
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
3706 doorbell
&= MPI_IOC_STATE_MASK
;
3708 drsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3709 "looking for READY STATE: doorbell=%x"
3711 ioc
->name
, doorbell
, count
));
3712 if (doorbell
== MPI_IOC_STATE_READY
) {
3717 if (sleepFlag
== CAN_SLEEP
)
3725 /* Use "Diagnostic reset" method! (only thing available!) */
3726 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3728 if (ioc
->debug_level
& MPT_DEBUG
) {
3730 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
3731 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG1: diag0=%08x, diag1=%08x\n",
3732 ioc
->name
, diag0val
, diag1val
));
3735 /* Do the reset if we are told to ignore the reset history
3736 * or if the reset history is 0
3738 if (ignore
|| !(diag0val
& MPI_DIAG_RESET_HISTORY
)) {
3739 while ((diag0val
& MPI_DIAG_DRWE
) == 0) {
3740 /* Write magic sequence to WriteSequence register
3741 * Loop until in diagnostic mode
3743 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3744 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3745 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3746 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3747 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3748 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3751 if (sleepFlag
== CAN_SLEEP
) {
3759 printk(MYIOC_s_ERR_FMT
"Enable Diagnostic mode FAILED! (%02xh)\n",
3760 ioc
->name
, diag0val
);
3765 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3767 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Wrote magic DiagWriteEn sequence (%x)\n",
3768 ioc
->name
, diag0val
));
3771 if (ioc
->debug_level
& MPT_DEBUG
) {
3773 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
3774 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG2: diag0=%08x, diag1=%08x\n",
3775 ioc
->name
, diag0val
, diag1val
));
3778 * Disable the ARM (Bug fix)
3781 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_DISABLE_ARM
);
3785 * Now hit the reset bit in the Diagnostic register
3786 * (THE BIG HAMMER!) (Clears DRWE bit).
3788 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_RESET_ADAPTER
);
3789 hard_reset_done
= 1;
3790 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Diagnostic reset performed\n",
3794 * Call each currently registered protocol IOC reset handler
3795 * with pre-reset indication.
3796 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3797 * MptResetHandlers[] registered yet.
3803 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
3804 if (MptResetHandlers
[cb_idx
]) {
3805 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3806 "Calling IOC pre_reset handler #%d\n",
3807 ioc
->name
, cb_idx
));
3808 r
+= mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_PRE_RESET
);
3810 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3811 "Calling alt-%s pre_reset handler #%d\n",
3812 ioc
->name
, ioc
->alt_ioc
->name
, cb_idx
));
3813 r
+= mpt_signal_reset(cb_idx
, ioc
->alt_ioc
, MPT_IOC_PRE_RESET
);
3817 /* FIXME? Examine results here? */
3821 cached_fw
= (MpiFwHeader_t
*)ioc
->cached_fw
;
3822 else if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
)
3823 cached_fw
= (MpiFwHeader_t
*)ioc
->alt_ioc
->cached_fw
;
3827 /* If the DownloadBoot operation fails, the
3828 * IOC will be left unusable. This is a fatal error
3829 * case. _diag_reset will return < 0
3831 for (count
= 0; count
< 30; count
++) {
3832 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3833 if (!(diag0val
& MPI_DIAG_RESET_ADAPTER
)) {
3837 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"cached_fw: diag0val=%x count=%d\n",
3838 ioc
->name
, diag0val
, count
));
3840 if (sleepFlag
== CAN_SLEEP
) {
3846 if ((count
= mpt_downloadboot(ioc
, cached_fw
, sleepFlag
)) < 0) {
3847 printk(MYIOC_s_WARN_FMT
3848 "firmware downloadboot failure (%d)!\n", ioc
->name
, count
);
3852 /* Wait for FW to reload and for board
3853 * to go to the READY state.
3854 * Maximum wait is 60 seconds.
3855 * If fail, no error will check again
3856 * with calling program.
3858 for (count
= 0; count
< 60; count
++) {
3859 doorbell
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
3860 doorbell
&= MPI_IOC_STATE_MASK
;
3862 if (doorbell
== MPI_IOC_STATE_READY
) {
3867 if (sleepFlag
== CAN_SLEEP
) {
3876 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3877 if (ioc
->debug_level
& MPT_DEBUG
) {
3879 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
3880 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG3: diag0=%08x, diag1=%08x\n",
3881 ioc
->name
, diag0val
, diag1val
));
3884 /* Clear RESET_HISTORY bit! Place board in the
3885 * diagnostic mode to update the diag register.
3887 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3889 while ((diag0val
& MPI_DIAG_DRWE
) == 0) {
3890 /* Write magic sequence to WriteSequence register
3891 * Loop until in diagnostic mode
3893 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3894 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3895 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3896 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3897 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3898 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3901 if (sleepFlag
== CAN_SLEEP
) {
3909 printk(MYIOC_s_ERR_FMT
"Enable Diagnostic mode FAILED! (%02xh)\n",
3910 ioc
->name
, diag0val
);
3913 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3915 diag0val
&= ~MPI_DIAG_RESET_HISTORY
;
3916 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
);
3917 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3918 if (diag0val
& MPI_DIAG_RESET_HISTORY
) {
3919 printk(MYIOC_s_WARN_FMT
"ResetHistory bit failed to clear!\n",
3923 /* Disable Diagnostic Mode
3925 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFFFFFFFF);
3927 /* Check FW reload status flags.
3929 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3930 if (diag0val
& (MPI_DIAG_FLASH_BAD_SIG
| MPI_DIAG_RESET_ADAPTER
| MPI_DIAG_DISABLE_ARM
)) {
3931 printk(MYIOC_s_ERR_FMT
"Diagnostic reset FAILED! (%02xh)\n",
3932 ioc
->name
, diag0val
);
3936 if (ioc
->debug_level
& MPT_DEBUG
) {
3938 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
3939 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG4: diag0=%08x, diag1=%08x\n",
3940 ioc
->name
, diag0val
, diag1val
));
3944 * Reset flag that says we've enabled event notification
3946 ioc
->facts
.EventState
= 0;
3949 ioc
->alt_ioc
->facts
.EventState
= 0;
3951 return hard_reset_done
;
3954 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3956 * SendIocReset - Send IOCReset request to MPT adapter.
3957 * @ioc: Pointer to MPT_ADAPTER structure
3958 * @reset_type: reset type, expected values are
3959 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3960 * @sleepFlag: Specifies whether the process can sleep
3962 * Send IOCReset request to the MPT adapter.
3964 * Returns 0 for success, non-zero for failure.
3967 SendIocReset(MPT_ADAPTER
*ioc
, u8 reset_type
, int sleepFlag
)
3973 drsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending IOC reset(0x%02x)!\n",
3974 ioc
->name
, reset_type
));
3975 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, reset_type
<<MPI_DOORBELL_FUNCTION_SHIFT
);
3976 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
3979 /* FW ACK'd request, wait for READY state
3982 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 15; /* 15 seconds */
3984 while ((state
= mpt_GetIocState(ioc
, 1)) != MPI_IOC_STATE_READY
) {
3988 if (sleepFlag
!= CAN_SLEEP
)
3991 printk(MYIOC_s_ERR_FMT
"Wait IOC_READY state timeout(%d)!\n",
3992 ioc
->name
, (int)((count
+5)/HZ
));
3996 if (sleepFlag
== CAN_SLEEP
) {
3999 mdelay (1); /* 1 msec delay */
4004 * Cleanup all event stuff for this IOC; re-issue EventNotification
4005 * request if needed.
4007 if (ioc
->facts
.Function
)
4008 ioc
->facts
.EventState
= 0;
4013 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4015 * initChainBuffers - Allocate memory for and initialize chain buffers
4016 * @ioc: Pointer to MPT_ADAPTER structure
4018 * Allocates memory for and initializes chain buffers,
4019 * chain buffer control arrays and spinlock.
4022 initChainBuffers(MPT_ADAPTER
*ioc
)
4025 int sz
, ii
, num_chain
;
4026 int scale
, num_sge
, numSGE
;
4028 /* ReqToChain size must equal the req_depth
4031 if (ioc
->ReqToChain
== NULL
) {
4032 sz
= ioc
->req_depth
* sizeof(int);
4033 mem
= kmalloc(sz
, GFP_ATOMIC
);
4037 ioc
->ReqToChain
= (int *) mem
;
4038 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReqToChain alloc @ %p, sz=%d bytes\n",
4039 ioc
->name
, mem
, sz
));
4040 mem
= kmalloc(sz
, GFP_ATOMIC
);
4044 ioc
->RequestNB
= (int *) mem
;
4045 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestNB alloc @ %p, sz=%d bytes\n",
4046 ioc
->name
, mem
, sz
));
4048 for (ii
= 0; ii
< ioc
->req_depth
; ii
++) {
4049 ioc
->ReqToChain
[ii
] = MPT_HOST_NO_CHAIN
;
4052 /* ChainToChain size must equal the total number
4053 * of chain buffers to be allocated.
4056 * Calculate the number of chain buffers needed(plus 1) per I/O
4057 * then multiply the maximum number of simultaneous cmds
4059 * num_sge = num sge in request frame + last chain buffer
4060 * scale = num sge per chain buffer if no chain element
4062 scale
= ioc
->req_sz
/(sizeof(dma_addr_t
) + sizeof(u32
));
4063 if (sizeof(dma_addr_t
) == sizeof(u64
))
4064 num_sge
= scale
+ (ioc
->req_sz
- 60) / (sizeof(dma_addr_t
) + sizeof(u32
));
4066 num_sge
= 1+ scale
+ (ioc
->req_sz
- 64) / (sizeof(dma_addr_t
) + sizeof(u32
));
4068 if (sizeof(dma_addr_t
) == sizeof(u64
)) {
4069 numSGE
= (scale
- 1) * (ioc
->facts
.MaxChainDepth
-1) + scale
+
4070 (ioc
->req_sz
- 60) / (sizeof(dma_addr_t
) + sizeof(u32
));
4072 numSGE
= 1 + (scale
- 1) * (ioc
->facts
.MaxChainDepth
-1) + scale
+
4073 (ioc
->req_sz
- 64) / (sizeof(dma_addr_t
) + sizeof(u32
));
4075 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"num_sge=%d numSGE=%d\n",
4076 ioc
->name
, num_sge
, numSGE
));
4078 if ( numSGE
> MPT_SCSI_SG_DEPTH
)
4079 numSGE
= MPT_SCSI_SG_DEPTH
;
4082 while (numSGE
- num_sge
> 0) {
4084 num_sge
+= (scale
- 1);
4088 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Now numSGE=%d num_sge=%d num_chain=%d\n",
4089 ioc
->name
, numSGE
, num_sge
, num_chain
));
4091 if (ioc
->bus_type
== SPI
)
4092 num_chain
*= MPT_SCSI_CAN_QUEUE
;
4094 num_chain
*= MPT_FC_CAN_QUEUE
;
4096 ioc
->num_chain
= num_chain
;
4098 sz
= num_chain
* sizeof(int);
4099 if (ioc
->ChainToChain
== NULL
) {
4100 mem
= kmalloc(sz
, GFP_ATOMIC
);
4104 ioc
->ChainToChain
= (int *) mem
;
4105 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainToChain alloc @ %p, sz=%d bytes\n",
4106 ioc
->name
, mem
, sz
));
4108 mem
= (u8
*) ioc
->ChainToChain
;
4110 memset(mem
, 0xFF, sz
);
4114 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4116 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
4117 * @ioc: Pointer to MPT_ADAPTER structure
4119 * This routine allocates memory for the MPT reply and request frame
4120 * pools (if necessary), and primes the IOC reply FIFO with
4123 * Returns 0 for success, non-zero for failure.
4126 PrimeIocFifos(MPT_ADAPTER
*ioc
)
4129 unsigned long flags
;
4130 dma_addr_t alloc_dma
;
4132 int i
, reply_sz
, sz
, total_size
, num_chain
;
4134 /* Prime reply FIFO... */
4136 if (ioc
->reply_frames
== NULL
) {
4137 if ( (num_chain
= initChainBuffers(ioc
)) < 0)
4140 total_size
= reply_sz
= (ioc
->reply_sz
* ioc
->reply_depth
);
4141 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
4142 ioc
->name
, ioc
->reply_sz
, ioc
->reply_depth
));
4143 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffer sz=%d[%x] bytes\n",
4144 ioc
->name
, reply_sz
, reply_sz
));
4146 sz
= (ioc
->req_sz
* ioc
->req_depth
);
4147 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestBuffer sz=%d bytes, RequestDepth=%d\n",
4148 ioc
->name
, ioc
->req_sz
, ioc
->req_depth
));
4149 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestBuffer sz=%d[%x] bytes\n",
4150 ioc
->name
, sz
, sz
));
4153 sz
= num_chain
* ioc
->req_sz
; /* chain buffer pool size */
4154 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainBuffer sz=%d bytes, ChainDepth=%d\n",
4155 ioc
->name
, ioc
->req_sz
, num_chain
));
4156 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
4157 ioc
->name
, sz
, sz
, num_chain
));
4160 mem
= pci_alloc_consistent(ioc
->pcidev
, total_size
, &alloc_dma
);
4162 printk(MYIOC_s_ERR_FMT
"Unable to allocate Reply, Request, Chain Buffers!\n",
4167 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Total alloc @ %p[%p], sz=%d[%x] bytes\n",
4168 ioc
->name
, mem
, (void *)(ulong
)alloc_dma
, total_size
, total_size
));
4170 memset(mem
, 0, total_size
);
4171 ioc
->alloc_total
+= total_size
;
4173 ioc
->alloc_dma
= alloc_dma
;
4174 ioc
->alloc_sz
= total_size
;
4175 ioc
->reply_frames
= (MPT_FRAME_HDR
*) mem
;
4176 ioc
->reply_frames_low_dma
= (u32
) (alloc_dma
& 0xFFFFFFFF);
4178 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffers @ %p[%p]\n",
4179 ioc
->name
, ioc
->reply_frames
, (void *)(ulong
)alloc_dma
));
4181 alloc_dma
+= reply_sz
;
4184 /* Request FIFO - WE manage this! */
4186 ioc
->req_frames
= (MPT_FRAME_HDR
*) mem
;
4187 ioc
->req_frames_dma
= alloc_dma
;
4189 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestBuffers @ %p[%p]\n",
4190 ioc
->name
, mem
, (void *)(ulong
)alloc_dma
));
4192 ioc
->req_frames_low_dma
= (u32
) (alloc_dma
& 0xFFFFFFFF);
4194 #if defined(CONFIG_MTRR) && 0
4196 * Enable Write Combining MTRR for IOC's memory region.
4197 * (at least as much as we can; "size and base must be
4198 * multiples of 4 kiB"
4200 ioc
->mtrr_reg
= mtrr_add(ioc
->req_frames_dma
,
4202 MTRR_TYPE_WRCOMB
, 1);
4203 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"MTRR region registered (base:size=%08x:%x)\n",
4204 ioc
->name
, ioc
->req_frames_dma
, sz
));
4207 for (i
= 0; i
< ioc
->req_depth
; i
++) {
4208 alloc_dma
+= ioc
->req_sz
;
4212 ioc
->ChainBuffer
= mem
;
4213 ioc
->ChainBufferDMA
= alloc_dma
;
4215 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainBuffers @ %p(%p)\n",
4216 ioc
->name
, ioc
->ChainBuffer
, (void *)(ulong
)ioc
->ChainBufferDMA
));
4218 /* Initialize the free chain Q.
4221 INIT_LIST_HEAD(&ioc
->FreeChainQ
);
4223 /* Post the chain buffers to the FreeChainQ.
4225 mem
= (u8
*)ioc
->ChainBuffer
;
4226 for (i
=0; i
< num_chain
; i
++) {
4227 mf
= (MPT_FRAME_HDR
*) mem
;
4228 list_add_tail(&mf
->u
.frame
.linkage
.list
, &ioc
->FreeChainQ
);
4232 /* Initialize Request frames linked list
4234 alloc_dma
= ioc
->req_frames_dma
;
4235 mem
= (u8
*) ioc
->req_frames
;
4237 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
4238 INIT_LIST_HEAD(&ioc
->FreeQ
);
4239 for (i
= 0; i
< ioc
->req_depth
; i
++) {
4240 mf
= (MPT_FRAME_HDR
*) mem
;
4242 /* Queue REQUESTs *internally*! */
4243 list_add_tail(&mf
->u
.frame
.linkage
.list
, &ioc
->FreeQ
);
4247 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
4249 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
4250 ioc
->sense_buf_pool
=
4251 pci_alloc_consistent(ioc
->pcidev
, sz
, &ioc
->sense_buf_pool_dma
);
4252 if (ioc
->sense_buf_pool
== NULL
) {
4253 printk(MYIOC_s_ERR_FMT
"Unable to allocate Sense Buffers!\n",
4258 ioc
->sense_buf_low_dma
= (u32
) (ioc
->sense_buf_pool_dma
& 0xFFFFFFFF);
4259 ioc
->alloc_total
+= sz
;
4260 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SenseBuffers @ %p[%p]\n",
4261 ioc
->name
, ioc
->sense_buf_pool
, (void *)(ulong
)ioc
->sense_buf_pool_dma
));
4265 /* Post Reply frames to FIFO
4267 alloc_dma
= ioc
->alloc_dma
;
4268 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffers @ %p[%p]\n",
4269 ioc
->name
, ioc
->reply_frames
, (void *)(ulong
)alloc_dma
));
4271 for (i
= 0; i
< ioc
->reply_depth
; i
++) {
4272 /* Write each address to the IOC! */
4273 CHIPREG_WRITE32(&ioc
->chip
->ReplyFifo
, alloc_dma
);
4274 alloc_dma
+= ioc
->reply_sz
;
4280 if (ioc
->alloc
!= NULL
) {
4282 pci_free_consistent(ioc
->pcidev
,
4284 ioc
->alloc
, ioc
->alloc_dma
);
4285 ioc
->reply_frames
= NULL
;
4286 ioc
->req_frames
= NULL
;
4287 ioc
->alloc_total
-= sz
;
4289 if (ioc
->sense_buf_pool
!= NULL
) {
4290 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
4291 pci_free_consistent(ioc
->pcidev
,
4293 ioc
->sense_buf_pool
, ioc
->sense_buf_pool_dma
);
4294 ioc
->sense_buf_pool
= NULL
;
4299 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4301 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4302 * from IOC via doorbell handshake method.
4303 * @ioc: Pointer to MPT_ADAPTER structure
4304 * @reqBytes: Size of the request in bytes
4305 * @req: Pointer to MPT request frame
4306 * @replyBytes: Expected size of the reply in bytes
4307 * @u16reply: Pointer to area where reply should be written
4308 * @maxwait: Max wait time for a reply (in seconds)
4309 * @sleepFlag: Specifies whether the process can sleep
4311 * NOTES: It is the callers responsibility to byte-swap fields in the
4312 * request which are greater than 1 byte in size. It is also the
4313 * callers responsibility to byte-swap response fields which are
4314 * greater than 1 byte in size.
4316 * Returns 0 for success, non-zero for failure.
4319 mpt_handshake_req_reply_wait(MPT_ADAPTER
*ioc
, int reqBytes
, u32
*req
,
4320 int replyBytes
, u16
*u16reply
, int maxwait
, int sleepFlag
)
4322 MPIDefaultReply_t
*mptReply
;
4327 * Get ready to cache a handshake reply
4329 ioc
->hs_reply_idx
= 0;
4330 mptReply
= (MPIDefaultReply_t
*) ioc
->hs_reply
;
4331 mptReply
->MsgLength
= 0;
4334 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4335 * then tell IOC that we want to handshake a request of N words.
4336 * (WRITE u32val to Doorbell reg).
4338 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4339 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
,
4340 ((MPI_FUNCTION_HANDSHAKE
<<MPI_DOORBELL_FUNCTION_SHIFT
) |
4341 ((reqBytes
/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT
)));
4344 * Wait for IOC's doorbell handshake int
4346 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4349 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4350 ioc
->name
, reqBytes
, t
, failcnt
? " - MISSING DOORBELL HANDSHAKE!" : ""));
4352 /* Read doorbell and check for active bit */
4353 if (!(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & MPI_DOORBELL_ACTIVE
))
4357 * Clear doorbell int (WRITE 0 to IntStatus reg),
4358 * then wait for IOC to ACKnowledge that it's ready for
4359 * our handshake request.
4361 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4362 if (!failcnt
&& (t
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
4367 u8
*req_as_bytes
= (u8
*) req
;
4370 * Stuff request words via doorbell handshake,
4371 * with ACK from IOC for each.
4373 for (ii
= 0; !failcnt
&& ii
< reqBytes
/4; ii
++) {
4374 u32 word
= ((req_as_bytes
[(ii
*4) + 0] << 0) |
4375 (req_as_bytes
[(ii
*4) + 1] << 8) |
4376 (req_as_bytes
[(ii
*4) + 2] << 16) |
4377 (req_as_bytes
[(ii
*4) + 3] << 24));
4379 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, word
);
4380 if ((t
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
4384 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Handshake request frame (@%p) header\n", ioc
->name
, req
));
4385 DBG_DUMP_REQUEST_FRAME_HDR(ioc
, (u32
*)req
);
4387 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HandShake request post done, WaitCnt=%d%s\n",
4388 ioc
->name
, t
, failcnt
? " - MISSING DOORBELL ACK!" : ""));
4391 * Wait for completion of doorbell handshake reply from the IOC
4393 if (!failcnt
&& (t
= WaitForDoorbellReply(ioc
, maxwait
, sleepFlag
)) < 0)
4396 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HandShake reply count=%d%s\n",
4397 ioc
->name
, t
, failcnt
? " - MISSING DOORBELL REPLY!" : ""));
4400 * Copy out the cached reply...
4402 for (ii
=0; ii
< min(replyBytes
/2,mptReply
->MsgLength
*2); ii
++)
4403 u16reply
[ii
] = ioc
->hs_reply
[ii
];
4411 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4413 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4414 * @ioc: Pointer to MPT_ADAPTER structure
4415 * @howlong: How long to wait (in seconds)
4416 * @sleepFlag: Specifies whether the process can sleep
4418 * This routine waits (up to ~2 seconds max) for IOC doorbell
4419 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4420 * bit in its IntStatus register being clear.
4422 * Returns a negative value on failure, else wait loop count.
4425 WaitForDoorbellAck(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
4431 cntdn
= 1000 * howlong
;
4433 if (sleepFlag
== CAN_SLEEP
) {
4436 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4437 if (! (intstat
& MPI_HIS_IOP_DOORBELL_STATUS
))
4444 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4445 if (! (intstat
& MPI_HIS_IOP_DOORBELL_STATUS
))
4452 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitForDoorbell ACK (count=%d)\n",
4457 printk(MYIOC_s_ERR_FMT
"Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4458 ioc
->name
, count
, intstat
);
4462 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4464 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4465 * @ioc: Pointer to MPT_ADAPTER structure
4466 * @howlong: How long to wait (in seconds)
4467 * @sleepFlag: Specifies whether the process can sleep
4469 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4470 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4472 * Returns a negative value on failure, else wait loop count.
4475 WaitForDoorbellInt(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
4481 cntdn
= 1000 * howlong
;
4482 if (sleepFlag
== CAN_SLEEP
) {
4484 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4485 if (intstat
& MPI_HIS_DOORBELL_INTERRUPT
)
4492 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4493 if (intstat
& MPI_HIS_DOORBELL_INTERRUPT
)
4501 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4502 ioc
->name
, count
, howlong
));
4506 printk(MYIOC_s_ERR_FMT
"Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4507 ioc
->name
, count
, intstat
);
4511 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4513 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4514 * @ioc: Pointer to MPT_ADAPTER structure
4515 * @howlong: How long to wait (in seconds)
4516 * @sleepFlag: Specifies whether the process can sleep
4518 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4519 * Reply is cached to IOC private area large enough to hold a maximum
4520 * of 128 bytes of reply data.
4522 * Returns a negative value on failure, else size of reply in WORDS.
4525 WaitForDoorbellReply(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
4530 u16
*hs_reply
= ioc
->hs_reply
;
4531 volatile MPIDefaultReply_t
*mptReply
= (MPIDefaultReply_t
*) ioc
->hs_reply
;
4534 hs_reply
[0] = hs_reply
[1] = hs_reply
[7] = 0;
4537 * Get first two u16's so we can look at IOC's intended reply MsgLength
4540 if ((t
= WaitForDoorbellInt(ioc
, howlong
, sleepFlag
)) < 0) {
4543 hs_reply
[u16cnt
++] = le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4544 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4545 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4548 hs_reply
[u16cnt
++] = le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4549 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4553 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitCnt=%d First handshake reply word=%08x%s\n",
4554 ioc
->name
, t
, le32_to_cpu(*(u32
*)hs_reply
),
4555 failcnt
? " - MISSING DOORBELL HANDSHAKE!" : ""));
4558 * If no error (and IOC said MsgLength is > 0), piece together
4559 * reply 16 bits at a time.
4561 for (u16cnt
=2; !failcnt
&& u16cnt
< (2 * mptReply
->MsgLength
); u16cnt
++) {
4562 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4564 hword
= le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4565 /* don't overflow our IOC hs_reply[] buffer! */
4566 if (u16cnt
< sizeof(ioc
->hs_reply
) / sizeof(ioc
->hs_reply
[0]))
4567 hs_reply
[u16cnt
] = hword
;
4568 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4571 if (!failcnt
&& (t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4573 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4576 printk(MYIOC_s_ERR_FMT
"Handshake reply failure!\n",
4581 else if (u16cnt
!= (2 * mptReply
->MsgLength
)) {
4584 else if ((mptReply
->IOCStatus
& MPI_IOCSTATUS_MASK
) != MPI_IOCSTATUS_SUCCESS
) {
4589 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Got Handshake reply:\n", ioc
->name
));
4590 DBG_DUMP_REPLY_FRAME(ioc
, (u32
*)mptReply
);
4592 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4593 ioc
->name
, t
, u16cnt
/2));
4597 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4599 * GetLanConfigPages - Fetch LANConfig pages.
4600 * @ioc: Pointer to MPT_ADAPTER structure
4602 * Return: 0 for success
4603 * -ENOMEM if no memory available
4604 * -EPERM if not allowed due to ISR context
4605 * -EAGAIN if no msg frames currently available
4606 * -EFAULT for non-successful reply or no reply (timeout)
4609 GetLanConfigPages(MPT_ADAPTER
*ioc
)
4611 ConfigPageHeader_t hdr
;
4613 LANPage0_t
*ppage0_alloc
;
4614 dma_addr_t page0_dma
;
4615 LANPage1_t
*ppage1_alloc
;
4616 dma_addr_t page1_dma
;
4621 /* Get LAN Page 0 header */
4622 hdr
.PageVersion
= 0;
4625 hdr
.PageType
= MPI_CONFIG_PAGETYPE_LAN
;
4626 cfg
.cfghdr
.hdr
= &hdr
;
4628 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4633 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
4636 if (hdr
.PageLength
> 0) {
4637 data_sz
= hdr
.PageLength
* 4;
4638 ppage0_alloc
= (LANPage0_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page0_dma
);
4641 memset((u8
*)ppage0_alloc
, 0, data_sz
);
4642 cfg
.physAddr
= page0_dma
;
4643 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4645 if ((rc
= mpt_config(ioc
, &cfg
)) == 0) {
4647 copy_sz
= min_t(int, sizeof(LANPage0_t
), data_sz
);
4648 memcpy(&ioc
->lan_cnfg_page0
, ppage0_alloc
, copy_sz
);
4652 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage0_alloc
, page0_dma
);
4655 * Normalize endianness of structure data,
4656 * by byte-swapping all > 1 byte fields!
4665 /* Get LAN Page 1 header */
4666 hdr
.PageVersion
= 0;
4669 hdr
.PageType
= MPI_CONFIG_PAGETYPE_LAN
;
4670 cfg
.cfghdr
.hdr
= &hdr
;
4672 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4676 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
4679 if (hdr
.PageLength
== 0)
4682 data_sz
= hdr
.PageLength
* 4;
4684 ppage1_alloc
= (LANPage1_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page1_dma
);
4686 memset((u8
*)ppage1_alloc
, 0, data_sz
);
4687 cfg
.physAddr
= page1_dma
;
4688 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4690 if ((rc
= mpt_config(ioc
, &cfg
)) == 0) {
4692 copy_sz
= min_t(int, sizeof(LANPage1_t
), data_sz
);
4693 memcpy(&ioc
->lan_cnfg_page1
, ppage1_alloc
, copy_sz
);
4696 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage1_alloc
, page1_dma
);
4699 * Normalize endianness of structure data,
4700 * by byte-swapping all > 1 byte fields!
4708 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4710 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
4711 * @ioc: Pointer to MPT_ADAPTER structure
4712 * @persist_opcode: see below
4714 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4715 * devices not currently present.
4716 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4718 * NOTE: Don't use not this function during interrupt time.
4720 * Returns 0 for success, non-zero error
4723 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4725 mptbase_sas_persist_operation(MPT_ADAPTER
*ioc
, u8 persist_opcode
)
4727 SasIoUnitControlRequest_t
*sasIoUnitCntrReq
;
4728 SasIoUnitControlReply_t
*sasIoUnitCntrReply
;
4729 MPT_FRAME_HDR
*mf
= NULL
;
4730 MPIHeader_t
*mpi_hdr
;
4733 /* insure garbage is not sent to fw */
4734 switch(persist_opcode
) {
4736 case MPI_SAS_OP_CLEAR_NOT_PRESENT
:
4737 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT
:
4745 printk("%s: persist_opcode=%x\n",__func__
, persist_opcode
);
4747 /* Get a MF for this command.
4749 if ((mf
= mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
4750 printk("%s: no msg frames!\n",__func__
);
4754 mpi_hdr
= (MPIHeader_t
*) mf
;
4755 sasIoUnitCntrReq
= (SasIoUnitControlRequest_t
*)mf
;
4756 memset(sasIoUnitCntrReq
,0,sizeof(SasIoUnitControlRequest_t
));
4757 sasIoUnitCntrReq
->Function
= MPI_FUNCTION_SAS_IO_UNIT_CONTROL
;
4758 sasIoUnitCntrReq
->MsgContext
= mpi_hdr
->MsgContext
;
4759 sasIoUnitCntrReq
->Operation
= persist_opcode
;
4761 init_timer(&ioc
->persist_timer
);
4762 ioc
->persist_timer
.data
= (unsigned long) ioc
;
4763 ioc
->persist_timer
.function
= mpt_timer_expired
;
4764 ioc
->persist_timer
.expires
= jiffies
+ HZ
*10 /* 10 sec */;
4765 ioc
->persist_wait_done
=0;
4766 add_timer(&ioc
->persist_timer
);
4767 mpt_put_msg_frame(mpt_base_index
, ioc
, mf
);
4768 wait_event(mpt_waitq
, ioc
->persist_wait_done
);
4770 sasIoUnitCntrReply
=
4771 (SasIoUnitControlReply_t
*)ioc
->persist_reply_frame
;
4772 if (le16_to_cpu(sasIoUnitCntrReply
->IOCStatus
) != MPI_IOCSTATUS_SUCCESS
) {
4773 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4775 sasIoUnitCntrReply
->IOCStatus
,
4776 sasIoUnitCntrReply
->IOCLogInfo
);
4780 printk("%s: success\n",__func__
);
4784 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4787 mptbase_raid_process_event_data(MPT_ADAPTER
*ioc
,
4788 MpiEventDataRaid_t
* pRaidEventData
)
4797 volume
= pRaidEventData
->VolumeID
;
4798 reason
= pRaidEventData
->ReasonCode
;
4799 disk
= pRaidEventData
->PhysDiskNum
;
4800 status
= le32_to_cpu(pRaidEventData
->SettingsStatus
);
4801 flags
= (status
>> 0) & 0xff;
4802 state
= (status
>> 8) & 0xff;
4804 if (reason
== MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
) {
4808 if ((reason
>= MPI_EVENT_RAID_RC_PHYSDISK_CREATED
&&
4809 reason
<= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
) ||
4810 (reason
== MPI_EVENT_RAID_RC_SMART_DATA
)) {
4811 printk(MYIOC_s_INFO_FMT
"RAID STATUS CHANGE for PhysDisk %d id=%d\n",
4812 ioc
->name
, disk
, volume
);
4814 printk(MYIOC_s_INFO_FMT
"RAID STATUS CHANGE for VolumeID %d\n",
4819 case MPI_EVENT_RAID_RC_VOLUME_CREATED
:
4820 printk(MYIOC_s_INFO_FMT
" volume has been created\n",
4824 case MPI_EVENT_RAID_RC_VOLUME_DELETED
:
4826 printk(MYIOC_s_INFO_FMT
" volume has been deleted\n",
4830 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED
:
4831 printk(MYIOC_s_INFO_FMT
" volume settings have been changed\n",
4835 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED
:
4836 printk(MYIOC_s_INFO_FMT
" volume is now %s%s%s%s\n",
4838 state
== MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
4840 : state
== MPI_RAIDVOL0_STATUS_STATE_DEGRADED
4842 : state
== MPI_RAIDVOL0_STATUS_STATE_FAILED
4845 flags
& MPI_RAIDVOL0_STATUS_FLAG_ENABLED
4847 flags
& MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
4848 ? ", quiesced" : "",
4849 flags
& MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
4850 ? ", resync in progress" : "" );
4853 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED
:
4854 printk(MYIOC_s_INFO_FMT
" volume membership of PhysDisk %d has changed\n",
4858 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED
:
4859 printk(MYIOC_s_INFO_FMT
" PhysDisk has been created\n",
4863 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED
:
4864 printk(MYIOC_s_INFO_FMT
" PhysDisk has been deleted\n",
4868 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED
:
4869 printk(MYIOC_s_INFO_FMT
" PhysDisk settings have been changed\n",
4873 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
:
4874 printk(MYIOC_s_INFO_FMT
" PhysDisk is now %s%s%s\n",
4876 state
== MPI_PHYSDISK0_STATUS_ONLINE
4878 : state
== MPI_PHYSDISK0_STATUS_MISSING
4880 : state
== MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
4882 : state
== MPI_PHYSDISK0_STATUS_FAILED
4884 : state
== MPI_PHYSDISK0_STATUS_INITIALIZING
4886 : state
== MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
4887 ? "offline requested"
4888 : state
== MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
4889 ? "failed requested"
4890 : state
== MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
4893 flags
& MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
4894 ? ", out of sync" : "",
4895 flags
& MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
4896 ? ", quiesced" : "" );
4899 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
:
4900 printk(MYIOC_s_INFO_FMT
" Domain Validation needed for PhysDisk %d\n",
4904 case MPI_EVENT_RAID_RC_SMART_DATA
:
4905 printk(MYIOC_s_INFO_FMT
" SMART data received, ASC/ASCQ = %02xh/%02xh\n",
4906 ioc
->name
, pRaidEventData
->ASC
, pRaidEventData
->ASCQ
);
4909 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED
:
4910 printk(MYIOC_s_INFO_FMT
" replacement of PhysDisk %d has started\n",
4916 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4918 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4919 * @ioc: Pointer to MPT_ADAPTER structure
4921 * Returns: 0 for success
4922 * -ENOMEM if no memory available
4923 * -EPERM if not allowed due to ISR context
4924 * -EAGAIN if no msg frames currently available
4925 * -EFAULT for non-successful reply or no reply (timeout)
4928 GetIoUnitPage2(MPT_ADAPTER
*ioc
)
4930 ConfigPageHeader_t hdr
;
4932 IOUnitPage2_t
*ppage_alloc
;
4933 dma_addr_t page_dma
;
4937 /* Get the page header */
4938 hdr
.PageVersion
= 0;
4941 hdr
.PageType
= MPI_CONFIG_PAGETYPE_IO_UNIT
;
4942 cfg
.cfghdr
.hdr
= &hdr
;
4944 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4949 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
4952 if (hdr
.PageLength
== 0)
4955 /* Read the config page */
4956 data_sz
= hdr
.PageLength
* 4;
4958 ppage_alloc
= (IOUnitPage2_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page_dma
);
4960 memset((u8
*)ppage_alloc
, 0, data_sz
);
4961 cfg
.physAddr
= page_dma
;
4962 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4964 /* If Good, save data */
4965 if ((rc
= mpt_config(ioc
, &cfg
)) == 0)
4966 ioc
->biosVersion
= le32_to_cpu(ppage_alloc
->BiosVersion
);
4968 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage_alloc
, page_dma
);
4974 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4976 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4977 * @ioc: Pointer to a Adapter Strucutre
4978 * @portnum: IOC port number
4980 * Return: -EFAULT if read of config page header fails
4982 * If read of SCSI Port Page 0 fails,
4983 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4984 * Adapter settings: async, narrow
4986 * If read of SCSI Port Page 2 fails,
4987 * Adapter settings valid
4988 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4993 * CHECK - what type of locking mechanisms should be used????
4996 mpt_GetScsiPortSettings(MPT_ADAPTER
*ioc
, int portnum
)
5001 ConfigPageHeader_t header
;
5007 if (!ioc
->spi_data
.nvram
) {
5010 sz
= MPT_MAX_SCSI_DEVICES
* sizeof(int);
5011 mem
= kmalloc(sz
, GFP_ATOMIC
);
5015 ioc
->spi_data
.nvram
= (int *) mem
;
5017 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SCSI device NVRAM settings @ %p, sz=%d\n",
5018 ioc
->name
, ioc
->spi_data
.nvram
, sz
));
5021 /* Invalidate NVRAM information
5023 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
5024 ioc
->spi_data
.nvram
[ii
] = MPT_HOST_NVRAM_INVALID
;
5027 /* Read SPP0 header, allocate memory, then read page.
5029 header
.PageVersion
= 0;
5030 header
.PageLength
= 0;
5031 header
.PageNumber
= 0;
5032 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_PORT
;
5033 cfg
.cfghdr
.hdr
= &header
;
5035 cfg
.pageAddr
= portnum
;
5036 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5038 cfg
.timeout
= 0; /* use default */
5039 if (mpt_config(ioc
, &cfg
) != 0)
5042 if (header
.PageLength
> 0) {
5043 pbuf
= pci_alloc_consistent(ioc
->pcidev
, header
.PageLength
* 4, &buf_dma
);
5045 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5046 cfg
.physAddr
= buf_dma
;
5047 if (mpt_config(ioc
, &cfg
) != 0) {
5048 ioc
->spi_data
.maxBusWidth
= MPT_NARROW
;
5049 ioc
->spi_data
.maxSyncOffset
= 0;
5050 ioc
->spi_data
.minSyncFactor
= MPT_ASYNC
;
5051 ioc
->spi_data
.busType
= MPT_HOST_BUS_UNKNOWN
;
5053 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5054 "Unable to read PortPage0 minSyncFactor=%x\n",
5055 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
5057 /* Save the Port Page 0 data
5059 SCSIPortPage0_t
*pPP0
= (SCSIPortPage0_t
*) pbuf
;
5060 pPP0
->Capabilities
= le32_to_cpu(pPP0
->Capabilities
);
5061 pPP0
->PhysicalInterface
= le32_to_cpu(pPP0
->PhysicalInterface
);
5063 if ( (pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_QAS
) == 0 ) {
5064 ioc
->spi_data
.noQas
|= MPT_TARGET_NO_NEGO_QAS
;
5065 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5066 "noQas due to Capabilities=%x\n",
5067 ioc
->name
, pPP0
->Capabilities
));
5069 ioc
->spi_data
.maxBusWidth
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_WIDE
? 1 : 0;
5070 data
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK
;
5072 ioc
->spi_data
.maxSyncOffset
= (u8
) (data
>> 16);
5073 data
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK
;
5074 ioc
->spi_data
.minSyncFactor
= (u8
) (data
>> 8);
5075 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5076 "PortPage0 minSyncFactor=%x\n",
5077 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
5079 ioc
->spi_data
.maxSyncOffset
= 0;
5080 ioc
->spi_data
.minSyncFactor
= MPT_ASYNC
;
5083 ioc
->spi_data
.busType
= pPP0
->PhysicalInterface
& MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK
;
5085 /* Update the minSyncFactor based on bus type.
5087 if ((ioc
->spi_data
.busType
== MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD
) ||
5088 (ioc
->spi_data
.busType
== MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE
)) {
5090 if (ioc
->spi_data
.minSyncFactor
< MPT_ULTRA
) {
5091 ioc
->spi_data
.minSyncFactor
= MPT_ULTRA
;
5092 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5093 "HVD or SE detected, minSyncFactor=%x\n",
5094 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
5099 pci_free_consistent(ioc
->pcidev
, header
.PageLength
* 4, pbuf
, buf_dma
);
5104 /* SCSI Port Page 2 - Read the header then the page.
5106 header
.PageVersion
= 0;
5107 header
.PageLength
= 0;
5108 header
.PageNumber
= 2;
5109 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_PORT
;
5110 cfg
.cfghdr
.hdr
= &header
;
5112 cfg
.pageAddr
= portnum
;
5113 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5115 if (mpt_config(ioc
, &cfg
) != 0)
5118 if (header
.PageLength
> 0) {
5119 /* Allocate memory and read SCSI Port Page 2
5121 pbuf
= pci_alloc_consistent(ioc
->pcidev
, header
.PageLength
* 4, &buf_dma
);
5123 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_NVRAM
;
5124 cfg
.physAddr
= buf_dma
;
5125 if (mpt_config(ioc
, &cfg
) != 0) {
5126 /* Nvram data is left with INVALID mark
5129 } else if (ioc
->pcidev
->vendor
== PCI_VENDOR_ID_ATTO
) {
5131 /* This is an ATTO adapter, read Page2 accordingly
5133 ATTO_SCSIPortPage2_t
*pPP2
= (ATTO_SCSIPortPage2_t
*) pbuf
;
5134 ATTODeviceInfo_t
*pdevice
= NULL
;
5137 /* Save the Port Page 2 data
5138 * (reformat into a 32bit quantity)
5140 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
5141 pdevice
= &pPP2
->DeviceSettings
[ii
];
5142 ATTOFlags
= le16_to_cpu(pdevice
->ATTOFlags
);
5145 /* Translate ATTO device flags to LSI format
5147 if (ATTOFlags
& ATTOFLAG_DISC
)
5148 data
|= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE
);
5149 if (ATTOFlags
& ATTOFLAG_ID_ENB
)
5150 data
|= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE
);
5151 if (ATTOFlags
& ATTOFLAG_LUN_ENB
)
5152 data
|= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE
);
5153 if (ATTOFlags
& ATTOFLAG_TAGGED
)
5154 data
|= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE
);
5155 if (!(ATTOFlags
& ATTOFLAG_WIDE_ENB
))
5156 data
|= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE
);
5158 data
= (data
<< 16) | (pdevice
->Period
<< 8) | 10;
5159 ioc
->spi_data
.nvram
[ii
] = data
;
5162 SCSIPortPage2_t
*pPP2
= (SCSIPortPage2_t
*) pbuf
;
5163 MpiDeviceInfo_t
*pdevice
= NULL
;
5166 * Save "Set to Avoid SCSI Bus Resets" flag
5168 ioc
->spi_data
.bus_reset
=
5169 (le32_to_cpu(pPP2
->PortFlags
) &
5170 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET
) ?
5173 /* Save the Port Page 2 data
5174 * (reformat into a 32bit quantity)
5176 data
= le32_to_cpu(pPP2
->PortFlags
) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK
;
5177 ioc
->spi_data
.PortFlags
= data
;
5178 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
5179 pdevice
= &pPP2
->DeviceSettings
[ii
];
5180 data
= (le16_to_cpu(pdevice
->DeviceFlags
) << 16) |
5181 (pdevice
->SyncFactor
<< 8) | pdevice
->Timeout
;
5182 ioc
->spi_data
.nvram
[ii
] = data
;
5186 pci_free_consistent(ioc
->pcidev
, header
.PageLength
* 4, pbuf
, buf_dma
);
5190 /* Update Adapter limits with those from NVRAM
5191 * Comment: Don't need to do this. Target performance
5192 * parameters will never exceed the adapters limits.
5198 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5200 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
5201 * @ioc: Pointer to a Adapter Strucutre
5202 * @portnum: IOC port number
5204 * Return: -EFAULT if read of config page header fails
5208 mpt_readScsiDevicePageHeaders(MPT_ADAPTER
*ioc
, int portnum
)
5211 ConfigPageHeader_t header
;
5213 /* Read the SCSI Device Page 1 header
5215 header
.PageVersion
= 0;
5216 header
.PageLength
= 0;
5217 header
.PageNumber
= 1;
5218 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_DEVICE
;
5219 cfg
.cfghdr
.hdr
= &header
;
5221 cfg
.pageAddr
= portnum
;
5222 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5225 if (mpt_config(ioc
, &cfg
) != 0)
5228 ioc
->spi_data
.sdp1version
= cfg
.cfghdr
.hdr
->PageVersion
;
5229 ioc
->spi_data
.sdp1length
= cfg
.cfghdr
.hdr
->PageLength
;
5231 header
.PageVersion
= 0;
5232 header
.PageLength
= 0;
5233 header
.PageNumber
= 0;
5234 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_DEVICE
;
5235 if (mpt_config(ioc
, &cfg
) != 0)
5238 ioc
->spi_data
.sdp0version
= cfg
.cfghdr
.hdr
->PageVersion
;
5239 ioc
->spi_data
.sdp0length
= cfg
.cfghdr
.hdr
->PageLength
;
5241 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Headers: 0: version %d length %d\n",
5242 ioc
->name
, ioc
->spi_data
.sdp0version
, ioc
->spi_data
.sdp0length
));
5244 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Headers: 1: version %d length %d\n",
5245 ioc
->name
, ioc
->spi_data
.sdp1version
, ioc
->spi_data
.sdp1length
));
5250 * mpt_inactive_raid_list_free - This clears this link list.
5251 * @ioc : pointer to per adapter structure
5254 mpt_inactive_raid_list_free(MPT_ADAPTER
*ioc
)
5256 struct inactive_raid_component_info
*component_info
, *pNext
;
5258 if (list_empty(&ioc
->raid_data
.inactive_list
))
5261 mutex_lock(&ioc
->raid_data
.inactive_list_mutex
);
5262 list_for_each_entry_safe(component_info
, pNext
,
5263 &ioc
->raid_data
.inactive_list
, list
) {
5264 list_del(&component_info
->list
);
5265 kfree(component_info
);
5267 mutex_unlock(&ioc
->raid_data
.inactive_list_mutex
);
5271 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5273 * @ioc : pointer to per adapter structure
5274 * @channel : volume channel
5275 * @id : volume target id
5278 mpt_inactive_raid_volumes(MPT_ADAPTER
*ioc
, u8 channel
, u8 id
)
5281 ConfigPageHeader_t hdr
;
5282 dma_addr_t dma_handle
;
5283 pRaidVolumePage0_t buffer
= NULL
;
5285 RaidPhysDiskPage0_t phys_disk
;
5286 struct inactive_raid_component_info
*component_info
;
5287 int handle_inactive_volumes
;
5289 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5290 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5291 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_VOLUME
;
5292 cfg
.pageAddr
= (channel
<< 8) + id
;
5293 cfg
.cfghdr
.hdr
= &hdr
;
5294 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5296 if (mpt_config(ioc
, &cfg
) != 0)
5299 if (!hdr
.PageLength
)
5302 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5308 cfg
.physAddr
= dma_handle
;
5309 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5311 if (mpt_config(ioc
, &cfg
) != 0)
5314 if (!buffer
->NumPhysDisks
)
5317 handle_inactive_volumes
=
5318 (buffer
->VolumeStatus
.Flags
& MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE
||
5319 (buffer
->VolumeStatus
.Flags
& MPI_RAIDVOL0_STATUS_FLAG_ENABLED
) == 0 ||
5320 buffer
->VolumeStatus
.State
== MPI_RAIDVOL0_STATUS_STATE_FAILED
||
5321 buffer
->VolumeStatus
.State
== MPI_RAIDVOL0_STATUS_STATE_MISSING
) ? 1 : 0;
5323 if (!handle_inactive_volumes
)
5326 mutex_lock(&ioc
->raid_data
.inactive_list_mutex
);
5327 for (i
= 0; i
< buffer
->NumPhysDisks
; i
++) {
5328 if(mpt_raid_phys_disk_pg0(ioc
,
5329 buffer
->PhysDisk
[i
].PhysDiskNum
, &phys_disk
) != 0)
5332 if ((component_info
= kmalloc(sizeof (*component_info
),
5333 GFP_KERNEL
)) == NULL
)
5336 component_info
->volumeID
= id
;
5337 component_info
->volumeBus
= channel
;
5338 component_info
->d
.PhysDiskNum
= phys_disk
.PhysDiskNum
;
5339 component_info
->d
.PhysDiskBus
= phys_disk
.PhysDiskBus
;
5340 component_info
->d
.PhysDiskID
= phys_disk
.PhysDiskID
;
5341 component_info
->d
.PhysDiskIOC
= phys_disk
.PhysDiskIOC
;
5343 list_add_tail(&component_info
->list
,
5344 &ioc
->raid_data
.inactive_list
);
5346 mutex_unlock(&ioc
->raid_data
.inactive_list_mutex
);
5350 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5355 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5356 * @ioc: Pointer to a Adapter Structure
5357 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5358 * @phys_disk: requested payload data returned
5362 * -EFAULT if read of config page header fails or data pointer not NULL
5363 * -ENOMEM if pci_alloc failed
5366 mpt_raid_phys_disk_pg0(MPT_ADAPTER
*ioc
, u8 phys_disk_num
, pRaidPhysDiskPage0_t phys_disk
)
5369 ConfigPageHeader_t hdr
;
5370 dma_addr_t dma_handle
;
5371 pRaidPhysDiskPage0_t buffer
= NULL
;
5374 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5375 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5377 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_PHYSDISK
;
5378 cfg
.cfghdr
.hdr
= &hdr
;
5380 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5382 if (mpt_config(ioc
, &cfg
) != 0) {
5387 if (!hdr
.PageLength
) {
5392 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5400 cfg
.physAddr
= dma_handle
;
5401 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5402 cfg
.pageAddr
= phys_disk_num
;
5404 if (mpt_config(ioc
, &cfg
) != 0) {
5410 memcpy(phys_disk
, buffer
, sizeof(*buffer
));
5411 phys_disk
->MaxLBA
= le32_to_cpu(buffer
->MaxLBA
);
5416 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5423 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5424 * @ioc: Pointer to a Adapter Strucutre
5425 * @portnum: IOC port number
5429 * -EFAULT if read of config page header fails or data pointer not NULL
5430 * -ENOMEM if pci_alloc failed
5433 mpt_findImVolumes(MPT_ADAPTER
*ioc
)
5437 dma_addr_t ioc2_dma
;
5439 ConfigPageHeader_t header
;
5444 if (!ioc
->ir_firmware
)
5447 /* Free the old page
5449 kfree(ioc
->raid_data
.pIocPg2
);
5450 ioc
->raid_data
.pIocPg2
= NULL
;
5451 mpt_inactive_raid_list_free(ioc
);
5453 /* Read IOCP2 header then the page.
5455 header
.PageVersion
= 0;
5456 header
.PageLength
= 0;
5457 header
.PageNumber
= 2;
5458 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
5459 cfg
.cfghdr
.hdr
= &header
;
5462 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5465 if (mpt_config(ioc
, &cfg
) != 0)
5468 if (header
.PageLength
== 0)
5471 iocpage2sz
= header
.PageLength
* 4;
5472 pIoc2
= pci_alloc_consistent(ioc
->pcidev
, iocpage2sz
, &ioc2_dma
);
5476 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5477 cfg
.physAddr
= ioc2_dma
;
5478 if (mpt_config(ioc
, &cfg
) != 0)
5481 mem
= kmalloc(iocpage2sz
, GFP_KERNEL
);
5485 memcpy(mem
, (u8
*)pIoc2
, iocpage2sz
);
5486 ioc
->raid_data
.pIocPg2
= (IOCPage2_t
*) mem
;
5488 mpt_read_ioc_pg_3(ioc
);
5490 for (i
= 0; i
< pIoc2
->NumActiveVolumes
; i
++)
5491 mpt_inactive_raid_volumes(ioc
,
5492 pIoc2
->RaidVolume
[i
].VolumeBus
,
5493 pIoc2
->RaidVolume
[i
].VolumeID
);
5496 pci_free_consistent(ioc
->pcidev
, iocpage2sz
, pIoc2
, ioc2_dma
);
5502 mpt_read_ioc_pg_3(MPT_ADAPTER
*ioc
)
5507 ConfigPageHeader_t header
;
5508 dma_addr_t ioc3_dma
;
5511 /* Free the old page
5513 kfree(ioc
->raid_data
.pIocPg3
);
5514 ioc
->raid_data
.pIocPg3
= NULL
;
5516 /* There is at least one physical disk.
5517 * Read and save IOC Page 3
5519 header
.PageVersion
= 0;
5520 header
.PageLength
= 0;
5521 header
.PageNumber
= 3;
5522 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
5523 cfg
.cfghdr
.hdr
= &header
;
5526 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5529 if (mpt_config(ioc
, &cfg
) != 0)
5532 if (header
.PageLength
== 0)
5535 /* Read Header good, alloc memory
5537 iocpage3sz
= header
.PageLength
* 4;
5538 pIoc3
= pci_alloc_consistent(ioc
->pcidev
, iocpage3sz
, &ioc3_dma
);
5542 /* Read the Page and save the data
5543 * into malloc'd memory.
5545 cfg
.physAddr
= ioc3_dma
;
5546 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5547 if (mpt_config(ioc
, &cfg
) == 0) {
5548 mem
= kmalloc(iocpage3sz
, GFP_KERNEL
);
5550 memcpy(mem
, (u8
*)pIoc3
, iocpage3sz
);
5551 ioc
->raid_data
.pIocPg3
= (IOCPage3_t
*) mem
;
5555 pci_free_consistent(ioc
->pcidev
, iocpage3sz
, pIoc3
, ioc3_dma
);
5561 mpt_read_ioc_pg_4(MPT_ADAPTER
*ioc
)
5565 ConfigPageHeader_t header
;
5566 dma_addr_t ioc4_dma
;
5569 /* Read and save IOC Page 4
5571 header
.PageVersion
= 0;
5572 header
.PageLength
= 0;
5573 header
.PageNumber
= 4;
5574 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
5575 cfg
.cfghdr
.hdr
= &header
;
5578 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5581 if (mpt_config(ioc
, &cfg
) != 0)
5584 if (header
.PageLength
== 0)
5587 if ( (pIoc4
= ioc
->spi_data
.pIocPg4
) == NULL
) {
5588 iocpage4sz
= (header
.PageLength
+ 4) * 4; /* Allow 4 additional SEP's */
5589 pIoc4
= pci_alloc_consistent(ioc
->pcidev
, iocpage4sz
, &ioc4_dma
);
5592 ioc
->alloc_total
+= iocpage4sz
;
5594 ioc4_dma
= ioc
->spi_data
.IocPg4_dma
;
5595 iocpage4sz
= ioc
->spi_data
.IocPg4Sz
;
5598 /* Read the Page into dma memory.
5600 cfg
.physAddr
= ioc4_dma
;
5601 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5602 if (mpt_config(ioc
, &cfg
) == 0) {
5603 ioc
->spi_data
.pIocPg4
= (IOCPage4_t
*) pIoc4
;
5604 ioc
->spi_data
.IocPg4_dma
= ioc4_dma
;
5605 ioc
->spi_data
.IocPg4Sz
= iocpage4sz
;
5607 pci_free_consistent(ioc
->pcidev
, iocpage4sz
, pIoc4
, ioc4_dma
);
5608 ioc
->spi_data
.pIocPg4
= NULL
;
5609 ioc
->alloc_total
-= iocpage4sz
;
5614 mpt_read_ioc_pg_1(MPT_ADAPTER
*ioc
)
5618 ConfigPageHeader_t header
;
5619 dma_addr_t ioc1_dma
;
5623 /* Check the Coalescing Timeout in IOC Page 1
5625 header
.PageVersion
= 0;
5626 header
.PageLength
= 0;
5627 header
.PageNumber
= 1;
5628 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
5629 cfg
.cfghdr
.hdr
= &header
;
5632 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5635 if (mpt_config(ioc
, &cfg
) != 0)
5638 if (header
.PageLength
== 0)
5641 /* Read Header good, alloc memory
5643 iocpage1sz
= header
.PageLength
* 4;
5644 pIoc1
= pci_alloc_consistent(ioc
->pcidev
, iocpage1sz
, &ioc1_dma
);
5648 /* Read the Page and check coalescing timeout
5650 cfg
.physAddr
= ioc1_dma
;
5651 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5652 if (mpt_config(ioc
, &cfg
) == 0) {
5654 tmp
= le32_to_cpu(pIoc1
->Flags
) & MPI_IOCPAGE1_REPLY_COALESCING
;
5655 if (tmp
== MPI_IOCPAGE1_REPLY_COALESCING
) {
5656 tmp
= le32_to_cpu(pIoc1
->CoalescingTimeout
);
5658 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Coalescing Enabled Timeout = %d\n",
5661 if (tmp
> MPT_COALESCING_TIMEOUT
) {
5662 pIoc1
->CoalescingTimeout
= cpu_to_le32(MPT_COALESCING_TIMEOUT
);
5664 /* Write NVRAM and current
5667 cfg
.action
= MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT
;
5668 if (mpt_config(ioc
, &cfg
) == 0) {
5669 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Reset Current Coalescing Timeout to = %d\n",
5670 ioc
->name
, MPT_COALESCING_TIMEOUT
));
5672 cfg
.action
= MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM
;
5673 if (mpt_config(ioc
, &cfg
) == 0) {
5674 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5675 "Reset NVRAM Coalescing Timeout to = %d\n",
5676 ioc
->name
, MPT_COALESCING_TIMEOUT
));
5678 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5679 "Reset NVRAM Coalescing Timeout Failed\n",
5684 dprintk(ioc
, printk(MYIOC_s_WARN_FMT
5685 "Reset of Current Coalescing Timeout Failed!\n",
5691 dprintk(ioc
, printk(MYIOC_s_WARN_FMT
"Coalescing Disabled\n", ioc
->name
));
5695 pci_free_consistent(ioc
->pcidev
, iocpage1sz
, pIoc1
, ioc1_dma
);
5701 mpt_get_manufacturing_pg_0(MPT_ADAPTER
*ioc
)
5704 ConfigPageHeader_t hdr
;
5706 ManufacturingPage0_t
*pbuf
= NULL
;
5708 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5709 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5711 hdr
.PageType
= MPI_CONFIG_PAGETYPE_MANUFACTURING
;
5712 cfg
.cfghdr
.hdr
= &hdr
;
5714 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5717 if (mpt_config(ioc
, &cfg
) != 0)
5720 if (!cfg
.cfghdr
.hdr
->PageLength
)
5723 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5724 pbuf
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, &buf_dma
);
5728 cfg
.physAddr
= buf_dma
;
5730 if (mpt_config(ioc
, &cfg
) != 0)
5733 memcpy(ioc
->board_name
, pbuf
->BoardName
, sizeof(ioc
->board_name
));
5734 memcpy(ioc
->board_assembly
, pbuf
->BoardAssembly
, sizeof(ioc
->board_assembly
));
5735 memcpy(ioc
->board_tracer
, pbuf
->BoardTracerNumber
, sizeof(ioc
->board_tracer
));
5740 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, pbuf
, buf_dma
);
5743 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5745 * SendEventNotification - Send EventNotification (on or off) request to adapter
5746 * @ioc: Pointer to MPT_ADAPTER structure
5747 * @EvSwitch: Event switch flags
5750 SendEventNotification(MPT_ADAPTER
*ioc
, u8 EvSwitch
)
5752 EventNotification_t
*evnp
;
5754 evnp
= (EventNotification_t
*) mpt_get_msg_frame(mpt_base_index
, ioc
);
5756 devtverboseprintk(ioc
, printk(MYIOC_s_WARN_FMT
"Unable to allocate event request frame!\n",
5760 memset(evnp
, 0, sizeof(*evnp
));
5762 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending EventNotification (%d) request %p\n", ioc
->name
, EvSwitch
, evnp
));
5764 evnp
->Function
= MPI_FUNCTION_EVENT_NOTIFICATION
;
5765 evnp
->ChainOffset
= 0;
5767 evnp
->Switch
= EvSwitch
;
5769 mpt_put_msg_frame(mpt_base_index
, ioc
, (MPT_FRAME_HDR
*)evnp
);
5774 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5776 * SendEventAck - Send EventAck request to MPT adapter.
5777 * @ioc: Pointer to MPT_ADAPTER structure
5778 * @evnp: Pointer to original EventNotification request
5781 SendEventAck(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*evnp
)
5785 if ((pAck
= (EventAck_t
*) mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
5786 dfailprintk(ioc
, printk(MYIOC_s_WARN_FMT
"%s, no msg frames!!\n",
5787 ioc
->name
,__func__
));
5791 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending EventAck\n", ioc
->name
));
5793 pAck
->Function
= MPI_FUNCTION_EVENT_ACK
;
5794 pAck
->ChainOffset
= 0;
5795 pAck
->Reserved
[0] = pAck
->Reserved
[1] = 0;
5797 pAck
->Reserved1
[0] = pAck
->Reserved1
[1] = pAck
->Reserved1
[2] = 0;
5798 pAck
->Event
= evnp
->Event
;
5799 pAck
->EventContext
= evnp
->EventContext
;
5801 mpt_put_msg_frame(mpt_base_index
, ioc
, (MPT_FRAME_HDR
*)pAck
);
5806 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5808 * mpt_config - Generic function to issue config message
5809 * @ioc: Pointer to an adapter structure
5810 * @pCfg: Pointer to a configuration structure. Struct contains
5811 * action, page address, direction, physical address
5812 * and pointer to a configuration page header
5813 * Page header is updated.
5815 * Returns 0 for success
5816 * -EPERM if not allowed due to ISR context
5817 * -EAGAIN if no msg frames currently available
5818 * -EFAULT for non-successful reply or no reply (timeout)
5821 mpt_config(MPT_ADAPTER
*ioc
, CONFIGPARMS
*pCfg
)
5824 ConfigExtendedPageHeader_t
*pExtHdr
= NULL
;
5826 unsigned long flags
;
5831 /* Prevent calling wait_event() (below), if caller happens
5832 * to be in ISR context, because that is fatal!
5834 in_isr
= in_interrupt();
5836 dcprintk(ioc
, printk(MYIOC_s_WARN_FMT
"Config request not allowed in ISR context!\n",
5841 /* Get and Populate a free Frame
5843 if ((mf
= mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
5844 dcprintk(ioc
, printk(MYIOC_s_WARN_FMT
"mpt_config: no msg frames!\n",
5848 pReq
= (Config_t
*)mf
;
5849 pReq
->Action
= pCfg
->action
;
5851 pReq
->ChainOffset
= 0;
5852 pReq
->Function
= MPI_FUNCTION_CONFIG
;
5854 /* Assume page type is not extended and clear "reserved" fields. */
5855 pReq
->ExtPageLength
= 0;
5856 pReq
->ExtPageType
= 0;
5859 for (ii
=0; ii
< 8; ii
++)
5860 pReq
->Reserved2
[ii
] = 0;
5862 pReq
->Header
.PageVersion
= pCfg
->cfghdr
.hdr
->PageVersion
;
5863 pReq
->Header
.PageLength
= pCfg
->cfghdr
.hdr
->PageLength
;
5864 pReq
->Header
.PageNumber
= pCfg
->cfghdr
.hdr
->PageNumber
;
5865 pReq
->Header
.PageType
= (pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
);
5867 if ((pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
) == MPI_CONFIG_PAGETYPE_EXTENDED
) {
5868 pExtHdr
= (ConfigExtendedPageHeader_t
*)pCfg
->cfghdr
.ehdr
;
5869 pReq
->ExtPageLength
= cpu_to_le16(pExtHdr
->ExtPageLength
);
5870 pReq
->ExtPageType
= pExtHdr
->ExtPageType
;
5871 pReq
->Header
.PageType
= MPI_CONFIG_PAGETYPE_EXTENDED
;
5873 /* Page Length must be treated as a reserved field for the extended header. */
5874 pReq
->Header
.PageLength
= 0;
5877 pReq
->PageAddress
= cpu_to_le32(pCfg
->pageAddr
);
5879 /* Add a SGE to the config request.
5882 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_WRITE
;
5884 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_READ
;
5886 if ((pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
) == MPI_CONFIG_PAGETYPE_EXTENDED
) {
5887 flagsLength
|= pExtHdr
->ExtPageLength
* 4;
5889 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending Config request type %d, page %d and action %d\n",
5890 ioc
->name
, pReq
->ExtPageType
, pReq
->Header
.PageNumber
, pReq
->Action
));
5893 flagsLength
|= pCfg
->cfghdr
.hdr
->PageLength
* 4;
5895 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending Config request type %d, page %d and action %d\n",
5896 ioc
->name
, pReq
->Header
.PageType
, pReq
->Header
.PageNumber
, pReq
->Action
));
5899 mpt_add_sge((char *)&pReq
->PageBufferSGE
, flagsLength
, pCfg
->physAddr
);
5901 /* Append pCfg pointer to end of mf
5903 *((void **) (((u8
*) mf
) + (ioc
->req_sz
- sizeof(void *)))) = (void *) pCfg
;
5905 /* Initalize the timer
5907 init_timer(&pCfg
->timer
);
5908 pCfg
->timer
.data
= (unsigned long) ioc
;
5909 pCfg
->timer
.function
= mpt_timer_expired
;
5910 pCfg
->wait_done
= 0;
5912 /* Set the timer; ensure 10 second minimum */
5913 if (pCfg
->timeout
< 10)
5914 pCfg
->timer
.expires
= jiffies
+ HZ
*10;
5916 pCfg
->timer
.expires
= jiffies
+ HZ
*pCfg
->timeout
;
5918 /* Add to end of Q, set timer and then issue this command */
5919 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
5920 list_add_tail(&pCfg
->linkage
, &ioc
->configQ
);
5921 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
5923 add_timer(&pCfg
->timer
);
5924 mpt_put_msg_frame(mpt_base_index
, ioc
, mf
);
5925 wait_event(mpt_waitq
, pCfg
->wait_done
);
5927 /* mf has been freed - do not access */
5934 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5936 * mpt_timer_expired - Callback for timer process.
5937 * Used only internal config functionality.
5938 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5941 mpt_timer_expired(unsigned long data
)
5943 MPT_ADAPTER
*ioc
= (MPT_ADAPTER
*) data
;
5945 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mpt_timer_expired! \n", ioc
->name
));
5947 /* Perform a FW reload */
5948 if (mpt_HardResetHandler(ioc
, NO_SLEEP
) < 0)
5949 printk(MYIOC_s_WARN_FMT
"Firmware Reload FAILED!\n", ioc
->name
);
5951 /* No more processing.
5952 * Hard reset clean-up will wake up
5953 * process and free all resources.
5955 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mpt_timer_expired complete!\n", ioc
->name
));
5960 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5962 * mpt_ioc_reset - Base cleanup for hard reset
5963 * @ioc: Pointer to the adapter structure
5964 * @reset_phase: Indicates pre- or post-reset functionality
5966 * Remark: Frees resources with internally generated commands.
5969 mpt_ioc_reset(MPT_ADAPTER
*ioc
, int reset_phase
)
5972 unsigned long flags
;
5974 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5975 ": IOC %s_reset routed to MPT base driver!\n",
5976 ioc
->name
, reset_phase
==MPT_IOC_SETUP_RESET
? "setup" : (
5977 reset_phase
==MPT_IOC_PRE_RESET
? "pre" : "post")));
5979 if (reset_phase
== MPT_IOC_SETUP_RESET
) {
5981 } else if (reset_phase
== MPT_IOC_PRE_RESET
) {
5982 /* If the internal config Q is not empty -
5983 * delete timer. MF resources will be freed when
5984 * the FIFO's are primed.
5986 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
5987 list_for_each_entry(pCfg
, &ioc
->configQ
, linkage
)
5988 del_timer(&pCfg
->timer
);
5989 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
5994 /* Search the configQ for internal commands.
5995 * Flush the Q, and wake up all suspended threads.
5997 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
5998 list_for_each_entry_safe(pCfg
, pNext
, &ioc
->configQ
, linkage
) {
5999 list_del(&pCfg
->linkage
);
6001 pCfg
->status
= MPT_CONFIG_ERROR
;
6002 pCfg
->wait_done
= 1;
6003 wake_up(&mpt_waitq
);
6005 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
6008 return 1; /* currently means nothing really */
6012 #ifdef CONFIG_PROC_FS /* { */
6013 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6015 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
6017 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6019 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
6021 * Returns 0 for success, non-zero for failure.
6024 procmpt_create(void)
6026 struct proc_dir_entry
*ent
;
6028 mpt_proc_root_dir
= proc_mkdir(MPT_PROCFS_MPTBASEDIR
, NULL
);
6029 if (mpt_proc_root_dir
== NULL
)
6032 ent
= create_proc_entry("summary", S_IFREG
|S_IRUGO
, mpt_proc_root_dir
);
6034 ent
->read_proc
= procmpt_summary_read
;
6036 ent
= create_proc_entry("version", S_IFREG
|S_IRUGO
, mpt_proc_root_dir
);
6038 ent
->read_proc
= procmpt_version_read
;
6043 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6045 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
6047 * Returns 0 for success, non-zero for failure.
6050 procmpt_destroy(void)
6052 remove_proc_entry("version", mpt_proc_root_dir
);
6053 remove_proc_entry("summary", mpt_proc_root_dir
);
6054 remove_proc_entry(MPT_PROCFS_MPTBASEDIR
, NULL
);
6057 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6059 * procmpt_summary_read - Handle read request of a summary file
6060 * @buf: Pointer to area to write information
6061 * @start: Pointer to start pointer
6062 * @offset: Offset to start writing
6063 * @request: Amount of read data requested
6064 * @eof: Pointer to EOF integer
6067 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
6068 * Returns number of characters written to process performing the read.
6071 procmpt_summary_read(char *buf
, char **start
, off_t offset
, int request
, int *eof
, void *data
)
6081 mpt_print_ioc_summary(ioc
, out
, &more
, 0, 1);
6085 list_for_each_entry(ioc
, &ioc_list
, list
) {
6088 mpt_print_ioc_summary(ioc
, out
, &more
, 0, 1);
6091 if ((out
-buf
) >= request
)
6098 MPT_PROC_READ_RETURN(buf
,start
,offset
,request
,eof
,len
);
6101 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6103 * procmpt_version_read - Handle read request from /proc/mpt/version.
6104 * @buf: Pointer to area to write information
6105 * @start: Pointer to start pointer
6106 * @offset: Offset to start writing
6107 * @request: Amount of read data requested
6108 * @eof: Pointer to EOF integer
6111 * Returns number of characters written to process performing the read.
6114 procmpt_version_read(char *buf
, char **start
, off_t offset
, int request
, int *eof
, void *data
)
6117 int scsi
, fc
, sas
, lan
, ctl
, targ
, dmp
;
6121 len
= sprintf(buf
, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON
);
6122 len
+= sprintf(buf
+len
, " Fusion MPT base driver\n");
6124 scsi
= fc
= sas
= lan
= ctl
= targ
= dmp
= 0;
6125 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
6127 if (MptCallbacks
[cb_idx
]) {
6128 switch (MptDriverClass
[cb_idx
]) {
6130 if (!scsi
++) drvname
= "SPI host";
6133 if (!fc
++) drvname
= "FC host";
6136 if (!sas
++) drvname
= "SAS host";
6139 if (!lan
++) drvname
= "LAN";
6142 if (!targ
++) drvname
= "SCSI target";
6145 if (!ctl
++) drvname
= "ioctl";
6150 len
+= sprintf(buf
+len
, " Fusion MPT %s driver\n", drvname
);
6154 MPT_PROC_READ_RETURN(buf
,start
,offset
,request
,eof
,len
);
6157 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6159 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
6160 * @buf: Pointer to area to write information
6161 * @start: Pointer to start pointer
6162 * @offset: Offset to start writing
6163 * @request: Amount of read data requested
6164 * @eof: Pointer to EOF integer
6167 * Returns number of characters written to process performing the read.
6170 procmpt_iocinfo_read(char *buf
, char **start
, off_t offset
, int request
, int *eof
, void *data
)
6172 MPT_ADAPTER
*ioc
= data
;
6178 mpt_get_fw_exp_ver(expVer
, ioc
);
6180 len
= sprintf(buf
, "%s:", ioc
->name
);
6181 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)
6182 len
+= sprintf(buf
+len
, " (f/w download boot flag set)");
6183 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6184 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
6186 len
+= sprintf(buf
+len
, "\n ProductID = 0x%04x (%s)\n",
6187 ioc
->facts
.ProductID
,
6189 len
+= sprintf(buf
+len
, " FWVersion = 0x%08x%s", ioc
->facts
.FWVersion
.Word
, expVer
);
6190 if (ioc
->facts
.FWImageSize
)
6191 len
+= sprintf(buf
+len
, " (fw_size=%d)", ioc
->facts
.FWImageSize
);
6192 len
+= sprintf(buf
+len
, "\n MsgVersion = 0x%04x\n", ioc
->facts
.MsgVersion
);
6193 len
+= sprintf(buf
+len
, " FirstWhoInit = 0x%02x\n", ioc
->FirstWhoInit
);
6194 len
+= sprintf(buf
+len
, " EventState = 0x%02x\n", ioc
->facts
.EventState
);
6196 len
+= sprintf(buf
+len
, " CurrentHostMfaHighAddr = 0x%08x\n",
6197 ioc
->facts
.CurrentHostMfaHighAddr
);
6198 len
+= sprintf(buf
+len
, " CurrentSenseBufferHighAddr = 0x%08x\n",
6199 ioc
->facts
.CurrentSenseBufferHighAddr
);
6201 len
+= sprintf(buf
+len
, " MaxChainDepth = 0x%02x frames\n", ioc
->facts
.MaxChainDepth
);
6202 len
+= sprintf(buf
+len
, " MinBlockSize = 0x%02x bytes\n", 4*ioc
->facts
.BlockSize
);
6204 len
+= sprintf(buf
+len
, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6205 (void *)ioc
->req_frames
, (void *)(ulong
)ioc
->req_frames_dma
);
6207 * Rounding UP to nearest 4-kB boundary here...
6209 sz
= (ioc
->req_sz
* ioc
->req_depth
) + 128;
6210 sz
= ((sz
+ 0x1000UL
- 1UL) / 0x1000) * 0x1000;
6211 len
+= sprintf(buf
+len
, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6212 ioc
->req_sz
, ioc
->req_depth
, ioc
->req_sz
*ioc
->req_depth
, sz
);
6213 len
+= sprintf(buf
+len
, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
6214 4*ioc
->facts
.RequestFrameSize
,
6215 ioc
->facts
.GlobalCredits
);
6217 len
+= sprintf(buf
+len
, " Frames @ 0x%p (Dma @ 0x%p)\n",
6218 (void *)ioc
->alloc
, (void *)(ulong
)ioc
->alloc_dma
);
6219 sz
= (ioc
->reply_sz
* ioc
->reply_depth
) + 128;
6220 len
+= sprintf(buf
+len
, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6221 ioc
->reply_sz
, ioc
->reply_depth
, ioc
->reply_sz
*ioc
->reply_depth
, sz
);
6222 len
+= sprintf(buf
+len
, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
6223 ioc
->facts
.CurReplyFrameSize
,
6224 ioc
->facts
.ReplyQueueDepth
);
6226 len
+= sprintf(buf
+len
, " MaxDevices = %d\n",
6227 (ioc
->facts
.MaxDevices
==0) ? 255 : ioc
->facts
.MaxDevices
);
6228 len
+= sprintf(buf
+len
, " MaxBuses = %d\n", ioc
->facts
.MaxBuses
);
6231 for (p
=0; p
< ioc
->facts
.NumberOfPorts
; p
++) {
6232 len
+= sprintf(buf
+len
, " PortNumber = %d (of %d)\n",
6234 ioc
->facts
.NumberOfPorts
);
6235 if (ioc
->bus_type
== FC
) {
6236 if (ioc
->pfacts
[p
].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
) {
6237 u8
*a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
6238 len
+= sprintf(buf
+len
, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6239 a
[5], a
[4], a
[3], a
[2], a
[1], a
[0]);
6241 len
+= sprintf(buf
+len
, " WWN = %08X%08X:%08X%08X\n",
6242 ioc
->fc_port_page0
[p
].WWNN
.High
,
6243 ioc
->fc_port_page0
[p
].WWNN
.Low
,
6244 ioc
->fc_port_page0
[p
].WWPN
.High
,
6245 ioc
->fc_port_page0
[p
].WWPN
.Low
);
6249 MPT_PROC_READ_RETURN(buf
,start
,offset
,request
,eof
,len
);
6252 #endif /* CONFIG_PROC_FS } */
6254 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6256 mpt_get_fw_exp_ver(char *buf
, MPT_ADAPTER
*ioc
)
6259 if ((ioc
->facts
.FWVersion
.Word
>> 24) == 0x0E) {
6260 sprintf(buf
, " (Exp %02d%02d)",
6261 (ioc
->facts
.FWVersion
.Word
>> 16) & 0x00FF, /* Month */
6262 (ioc
->facts
.FWVersion
.Word
>> 8) & 0x1F); /* Day */
6265 if ((ioc
->facts
.FWVersion
.Word
>> 8) & 0x80)
6266 strcat(buf
, " [MDBG]");
6270 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6272 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6273 * @ioc: Pointer to MPT_ADAPTER structure
6274 * @buffer: Pointer to buffer where IOC summary info should be written
6275 * @size: Pointer to number of bytes we wrote (set by this routine)
6276 * @len: Offset at which to start writing in buffer
6277 * @showlan: Display LAN stuff?
6279 * This routine writes (english readable) ASCII text, which represents
6280 * a summary of IOC information, to a buffer.
6283 mpt_print_ioc_summary(MPT_ADAPTER
*ioc
, char *buffer
, int *size
, int len
, int showlan
)
6288 mpt_get_fw_exp_ver(expVer
, ioc
);
6291 * Shorter summary of attached ioc's...
6293 y
= sprintf(buffer
+len
, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6296 MPT_FW_REV_MAGIC_ID_STRING
, /* "FwRev=" or somesuch */
6297 ioc
->facts
.FWVersion
.Word
,
6299 ioc
->facts
.NumberOfPorts
,
6302 if (showlan
&& (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
)) {
6303 u8
*a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
6304 y
+= sprintf(buffer
+len
+y
, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6305 a
[5], a
[4], a
[3], a
[2], a
[1], a
[0]);
6308 y
+= sprintf(buffer
+len
+y
, ", IRQ=%d", ioc
->pci_irq
);
6311 y
+= sprintf(buffer
+len
+y
, " (disabled)");
6313 y
+= sprintf(buffer
+len
+y
, "\n");
6318 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6322 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6324 * mpt_HardResetHandler - Generic reset handler
6325 * @ioc: Pointer to MPT_ADAPTER structure
6326 * @sleepFlag: Indicates if sleep or schedule must be called.
6328 * Issues SCSI Task Management call based on input arg values.
6329 * If TaskMgmt fails, returns associated SCSI request.
6331 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
6332 * or a non-interrupt thread. In the former, must not call schedule().
6334 * Note: A return of -1 is a FATAL error case, as it means a
6335 * FW reload/initialization failed.
6337 * Returns 0 for SUCCESS or -1 if FAILED.
6340 mpt_HardResetHandler(MPT_ADAPTER
*ioc
, int sleepFlag
)
6343 unsigned long flags
;
6345 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HardResetHandler Entered!\n", ioc
->name
));
6347 printk(MYIOC_s_INFO_FMT
"HardResetHandler Entered!\n", ioc
->name
);
6348 printk("MF count 0x%x !\n", ioc
->mfcnt
);
6351 /* Reset the adapter. Prevent more than 1 call to
6352 * mpt_do_ioc_recovery at any instant in time.
6354 spin_lock_irqsave(&ioc
->diagLock
, flags
);
6355 if ((ioc
->diagPending
) || (ioc
->alt_ioc
&& ioc
->alt_ioc
->diagPending
)){
6356 spin_unlock_irqrestore(&ioc
->diagLock
, flags
);
6359 ioc
->diagPending
= 1;
6361 spin_unlock_irqrestore(&ioc
->diagLock
, flags
);
6363 /* FIXME: If do_ioc_recovery fails, repeat....
6366 /* The SCSI driver needs to adjust timeouts on all current
6367 * commands prior to the diagnostic reset being issued.
6368 * Prevents timeouts occurring during a diagnostic reset...very bad.
6369 * For all other protocol drivers, this is a no-op.
6375 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
6376 if (MptResetHandlers
[cb_idx
]) {
6377 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Calling IOC reset_setup handler #%d\n",
6378 ioc
->name
, cb_idx
));
6379 r
+= mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_SETUP_RESET
);
6381 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Calling alt-%s setup reset handler #%d\n",
6382 ioc
->name
, ioc
->alt_ioc
->name
, cb_idx
));
6383 r
+= mpt_signal_reset(cb_idx
, ioc
->alt_ioc
, MPT_IOC_SETUP_RESET
);
6389 if ((rc
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_RECOVER
, sleepFlag
)) != 0) {
6390 printk(MYIOC_s_WARN_FMT
"Cannot recover rc = %d!\n", ioc
->name
, rc
);
6394 ioc
->alt_ioc
->reload_fw
= 0;
6396 spin_lock_irqsave(&ioc
->diagLock
, flags
);
6397 ioc
->diagPending
= 0;
6399 ioc
->alt_ioc
->diagPending
= 0;
6400 spin_unlock_irqrestore(&ioc
->diagLock
, flags
);
6402 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HardResetHandler rc = %d!\n", ioc
->name
, rc
));
6407 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6409 EventDescriptionStr(u8 event
, u32 evData0
, char *evStr
)
6414 case MPI_EVENT_NONE
:
6417 case MPI_EVENT_LOG_DATA
:
6420 case MPI_EVENT_STATE_CHANGE
:
6421 ds
= "State Change";
6423 case MPI_EVENT_UNIT_ATTENTION
:
6424 ds
= "Unit Attention";
6426 case MPI_EVENT_IOC_BUS_RESET
:
6427 ds
= "IOC Bus Reset";
6429 case MPI_EVENT_EXT_BUS_RESET
:
6430 ds
= "External Bus Reset";
6432 case MPI_EVENT_RESCAN
:
6433 ds
= "Bus Rescan Event";
6435 case MPI_EVENT_LINK_STATUS_CHANGE
:
6436 if (evData0
== MPI_EVENT_LINK_STATUS_FAILURE
)
6437 ds
= "Link Status(FAILURE) Change";
6439 ds
= "Link Status(ACTIVE) Change";
6441 case MPI_EVENT_LOOP_STATE_CHANGE
:
6442 if (evData0
== MPI_EVENT_LOOP_STATE_CHANGE_LIP
)
6443 ds
= "Loop State(LIP) Change";
6444 else if (evData0
== MPI_EVENT_LOOP_STATE_CHANGE_LPE
)
6445 ds
= "Loop State(LPE) Change"; /* ??? */
6447 ds
= "Loop State(LPB) Change"; /* ??? */
6449 case MPI_EVENT_LOGOUT
:
6452 case MPI_EVENT_EVENT_CHANGE
:
6458 case MPI_EVENT_INTEGRATED_RAID
:
6460 u8 ReasonCode
= (u8
)(evData0
>> 16);
6461 switch (ReasonCode
) {
6462 case MPI_EVENT_RAID_RC_VOLUME_CREATED
:
6463 ds
= "Integrated Raid: Volume Created";
6465 case MPI_EVENT_RAID_RC_VOLUME_DELETED
:
6466 ds
= "Integrated Raid: Volume Deleted";
6468 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED
:
6469 ds
= "Integrated Raid: Volume Settings Changed";
6471 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED
:
6472 ds
= "Integrated Raid: Volume Status Changed";
6474 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED
:
6475 ds
= "Integrated Raid: Volume Physdisk Changed";
6477 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED
:
6478 ds
= "Integrated Raid: Physdisk Created";
6480 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED
:
6481 ds
= "Integrated Raid: Physdisk Deleted";
6483 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED
:
6484 ds
= "Integrated Raid: Physdisk Settings Changed";
6486 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
:
6487 ds
= "Integrated Raid: Physdisk Status Changed";
6489 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
:
6490 ds
= "Integrated Raid: Domain Validation Needed";
6492 case MPI_EVENT_RAID_RC_SMART_DATA
:
6493 ds
= "Integrated Raid; Smart Data";
6495 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED
:
6496 ds
= "Integrated Raid: Replace Action Started";
6499 ds
= "Integrated Raid";
6504 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE
:
6505 ds
= "SCSI Device Status Change";
6507 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE
:
6509 u8 id
= (u8
)(evData0
);
6510 u8 channel
= (u8
)(evData0
>> 8);
6511 u8 ReasonCode
= (u8
)(evData0
>> 16);
6512 switch (ReasonCode
) {
6513 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED
:
6514 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6515 "SAS Device Status Change: Added: "
6516 "id=%d channel=%d", id
, channel
);
6518 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING
:
6519 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6520 "SAS Device Status Change: Deleted: "
6521 "id=%d channel=%d", id
, channel
);
6523 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA
:
6524 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6525 "SAS Device Status Change: SMART Data: "
6526 "id=%d channel=%d", id
, channel
);
6528 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED
:
6529 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6530 "SAS Device Status Change: No Persistancy: "
6531 "id=%d channel=%d", id
, channel
);
6533 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED
:
6534 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6535 "SAS Device Status Change: Unsupported Device "
6536 "Discovered : id=%d channel=%d", id
, channel
);
6538 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET
:
6539 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6540 "SAS Device Status Change: Internal Device "
6541 "Reset : id=%d channel=%d", id
, channel
);
6543 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL
:
6544 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6545 "SAS Device Status Change: Internal Task "
6546 "Abort : id=%d channel=%d", id
, channel
);
6548 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL
:
6549 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6550 "SAS Device Status Change: Internal Abort "
6551 "Task Set : id=%d channel=%d", id
, channel
);
6553 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL
:
6554 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6555 "SAS Device Status Change: Internal Clear "
6556 "Task Set : id=%d channel=%d", id
, channel
);
6558 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL
:
6559 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6560 "SAS Device Status Change: Internal Query "
6561 "Task : id=%d channel=%d", id
, channel
);
6564 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6565 "SAS Device Status Change: Unknown: "
6566 "id=%d channel=%d", id
, channel
);
6571 case MPI_EVENT_ON_BUS_TIMER_EXPIRED
:
6572 ds
= "Bus Timer Expired";
6574 case MPI_EVENT_QUEUE_FULL
:
6576 u16 curr_depth
= (u16
)(evData0
>> 16);
6577 u8 channel
= (u8
)(evData0
>> 8);
6578 u8 id
= (u8
)(evData0
);
6580 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6581 "Queue Full: channel=%d id=%d depth=%d",
6582 channel
, id
, curr_depth
);
6585 case MPI_EVENT_SAS_SES
:
6586 ds
= "SAS SES Event";
6588 case MPI_EVENT_PERSISTENT_TABLE_FULL
:
6589 ds
= "Persistent Table Full";
6591 case MPI_EVENT_SAS_PHY_LINK_STATUS
:
6593 u8 LinkRates
= (u8
)(evData0
>> 8);
6594 u8 PhyNumber
= (u8
)(evData0
);
6595 LinkRates
= (LinkRates
& MPI_EVENT_SAS_PLS_LR_CURRENT_MASK
) >>
6596 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT
;
6597 switch (LinkRates
) {
6598 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN
:
6599 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6600 "SAS PHY Link Status: Phy=%d:"
6601 " Rate Unknown",PhyNumber
);
6603 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED
:
6604 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6605 "SAS PHY Link Status: Phy=%d:"
6606 " Phy Disabled",PhyNumber
);
6608 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION
:
6609 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6610 "SAS PHY Link Status: Phy=%d:"
6611 " Failed Speed Nego",PhyNumber
);
6613 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE
:
6614 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6615 "SAS PHY Link Status: Phy=%d:"
6616 " Sata OOB Completed",PhyNumber
);
6618 case MPI_EVENT_SAS_PLS_LR_RATE_1_5
:
6619 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6620 "SAS PHY Link Status: Phy=%d:"
6621 " Rate 1.5 Gbps",PhyNumber
);
6623 case MPI_EVENT_SAS_PLS_LR_RATE_3_0
:
6624 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6625 "SAS PHY Link Status: Phy=%d:"
6626 " Rate 3.0 Gpbs",PhyNumber
);
6629 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6630 "SAS PHY Link Status: Phy=%d", PhyNumber
);
6635 case MPI_EVENT_SAS_DISCOVERY_ERROR
:
6636 ds
= "SAS Discovery Error";
6638 case MPI_EVENT_IR_RESYNC_UPDATE
:
6640 u8 resync_complete
= (u8
)(evData0
>> 16);
6641 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6642 "IR Resync Update: Complete = %d:",resync_complete
);
6647 u8 ReasonCode
= (u8
)(evData0
>> 16);
6648 switch (ReasonCode
) {
6649 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED
:
6650 ds
= "IR2: LD State Changed";
6652 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED
:
6653 ds
= "IR2: PD State Changed";
6655 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL
:
6656 ds
= "IR2: Bad Block Table Full";
6658 case MPI_EVENT_IR2_RC_PD_INSERTED
:
6659 ds
= "IR2: PD Inserted";
6661 case MPI_EVENT_IR2_RC_PD_REMOVED
:
6662 ds
= "IR2: PD Removed";
6664 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED
:
6665 ds
= "IR2: Foreign CFG Detected";
6667 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR
:
6668 ds
= "IR2: Rebuild Medium Error";
6676 case MPI_EVENT_SAS_DISCOVERY
:
6679 ds
= "SAS Discovery: Start";
6681 ds
= "SAS Discovery: Stop";
6684 case MPI_EVENT_LOG_ENTRY_ADDED
:
6685 ds
= "SAS Log Entry Added";
6688 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE
:
6690 u8 phy_num
= (u8
)(evData0
);
6691 u8 port_num
= (u8
)(evData0
>> 8);
6692 u8 port_width
= (u8
)(evData0
>> 16);
6693 u8 primative
= (u8
)(evData0
>> 24);
6694 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6695 "SAS Broadcase Primative: phy=%d port=%d "
6696 "width=%d primative=0x%02x",
6697 phy_num
, port_num
, port_width
, primative
);
6701 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE
:
6703 u8 reason
= (u8
)(evData0
);
6704 u8 port_num
= (u8
)(evData0
>> 8);
6705 u16 handle
= le16_to_cpu(evData0
>> 16);
6707 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6708 "SAS Initiator Device Status Change: reason=0x%02x "
6709 "port=%d handle=0x%04x",
6710 reason
, port_num
, handle
);
6714 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW
:
6716 u8 max_init
= (u8
)(evData0
);
6717 u8 current_init
= (u8
)(evData0
>> 8);
6719 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6720 "SAS Initiator Device Table Overflow: max initiators=%02d "
6721 "current initators=%02d",
6722 max_init
, current_init
);
6725 case MPI_EVENT_SAS_SMP_ERROR
:
6727 u8 status
= (u8
)(evData0
);
6728 u8 port_num
= (u8
)(evData0
>> 8);
6729 u8 result
= (u8
)(evData0
>> 16);
6731 if (status
== MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID
)
6732 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6733 "SAS SMP Error: port=%d result=0x%02x",
6735 else if (status
== MPI_EVENT_SAS_SMP_CRC_ERROR
)
6736 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6737 "SAS SMP Error: port=%d : CRC Error",
6739 else if (status
== MPI_EVENT_SAS_SMP_TIMEOUT
)
6740 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6741 "SAS SMP Error: port=%d : Timeout",
6743 else if (status
== MPI_EVENT_SAS_SMP_NO_DESTINATION
)
6744 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6745 "SAS SMP Error: port=%d : No Destination",
6747 else if (status
== MPI_EVENT_SAS_SMP_BAD_DESTINATION
)
6748 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6749 "SAS SMP Error: port=%d : Bad Destination",
6752 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6753 "SAS SMP Error: port=%d : status=0x%02x",
6759 * MPT base "custom" events may be added here...
6766 strncpy(evStr
, ds
, EVENT_DESCR_STR_SZ
);
6769 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6771 * ProcessEventNotification - Route EventNotificationReply to all event handlers
6772 * @ioc: Pointer to MPT_ADAPTER structure
6773 * @pEventReply: Pointer to EventNotification reply frame
6774 * @evHandlers: Pointer to integer, number of event handlers
6776 * Routes a received EventNotificationReply to all currently registered
6778 * Returns sum of event handlers return values.
6781 ProcessEventNotification(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*pEventReply
, int *evHandlers
)
6790 char evStr
[EVENT_DESCR_STR_SZ
];
6794 * Do platform normalization of values
6796 event
= le32_to_cpu(pEventReply
->Event
) & 0xFF;
6797 // evCtx = le32_to_cpu(pEventReply->EventContext);
6798 evDataLen
= le16_to_cpu(pEventReply
->EventDataLength
);
6800 evData0
= le32_to_cpu(pEventReply
->Data
[0]);
6803 EventDescriptionStr(event
, evData0
, evStr
);
6804 devtprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"MPT event:(%02Xh) : %s\n",
6809 #ifdef CONFIG_FUSION_LOGGING
6810 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6811 ": Event data:\n", ioc
->name
));
6812 for (ii
= 0; ii
< evDataLen
; ii
++)
6813 devtverboseprintk(ioc
, printk(" %08x",
6814 le32_to_cpu(pEventReply
->Data
[ii
])));
6815 devtverboseprintk(ioc
, printk("\n"));
6819 * Do general / base driver event processing
6822 case MPI_EVENT_EVENT_CHANGE
: /* 0A */
6824 u8 evState
= evData0
& 0xFF;
6826 /* CHECKME! What if evState unexpectedly says OFF (0)? */
6828 /* Update EventState field in cached IocFacts */
6829 if (ioc
->facts
.Function
) {
6830 ioc
->facts
.EventState
= evState
;
6834 case MPI_EVENT_INTEGRATED_RAID
:
6835 mptbase_raid_process_event_data(ioc
,
6836 (MpiEventDataRaid_t
*)pEventReply
->Data
);
6843 * Should this event be logged? Events are written sequentially.
6844 * When buffer is full, start again at the top.
6846 if (ioc
->events
&& (ioc
->eventTypes
& ( 1 << event
))) {
6849 idx
= ioc
->eventContext
% MPTCTL_EVENT_LOG_SIZE
;
6851 ioc
->events
[idx
].event
= event
;
6852 ioc
->events
[idx
].eventContext
= ioc
->eventContext
;
6854 for (ii
= 0; ii
< 2; ii
++) {
6856 ioc
->events
[idx
].data
[ii
] = le32_to_cpu(pEventReply
->Data
[ii
]);
6858 ioc
->events
[idx
].data
[ii
] = 0;
6861 ioc
->eventContext
++;
6866 * Call each currently registered protocol event handler.
6868 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
6869 if (MptEvHandlers
[cb_idx
]) {
6870 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Routing Event to event handler #%d\n",
6871 ioc
->name
, cb_idx
));
6872 r
+= (*(MptEvHandlers
[cb_idx
]))(ioc
, pEventReply
);
6876 /* FIXME? Examine results here? */
6879 * If needed, send (a single) EventAck.
6881 if (pEventReply
->AckRequired
== MPI_EVENT_NOTIFICATION_ACK_REQUIRED
) {
6882 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6883 "EventAck required\n",ioc
->name
));
6884 if ((ii
= SendEventAck(ioc
, pEventReply
)) != 0) {
6885 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SendEventAck returned %d\n",
6890 *evHandlers
= handlers
;
6894 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6896 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
6897 * @ioc: Pointer to MPT_ADAPTER structure
6898 * @log_info: U32 LogInfo reply word from the IOC
6900 * Refer to lsi/mpi_log_fc.h.
6903 mpt_fc_log_info(MPT_ADAPTER
*ioc
, u32 log_info
)
6905 char *desc
= "unknown";
6907 switch (log_info
& 0xFF000000) {
6908 case MPI_IOCLOGINFO_FC_INIT_BASE
:
6909 desc
= "FCP Initiator";
6911 case MPI_IOCLOGINFO_FC_TARGET_BASE
:
6912 desc
= "FCP Target";
6914 case MPI_IOCLOGINFO_FC_LAN_BASE
:
6917 case MPI_IOCLOGINFO_FC_MSG_BASE
:
6918 desc
= "MPI Message Layer";
6920 case MPI_IOCLOGINFO_FC_LINK_BASE
:
6923 case MPI_IOCLOGINFO_FC_CTX_BASE
:
6924 desc
= "Context Manager";
6926 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET
:
6927 desc
= "Invalid Field Offset";
6929 case MPI_IOCLOGINFO_FC_STATE_CHANGE
:
6930 desc
= "State Change Info";
6934 printk(MYIOC_s_INFO_FMT
"LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
6935 ioc
->name
, log_info
, desc
, (log_info
& 0xFFFFFF));
6938 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6940 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
6941 * @ioc: Pointer to MPT_ADAPTER structure
6942 * @mr: Pointer to MPT reply frame
6943 * @log_info: U32 LogInfo word from the IOC
6945 * Refer to lsi/sp_log.h.
6948 mpt_spi_log_info(MPT_ADAPTER
*ioc
, u32 log_info
)
6950 u32 info
= log_info
& 0x00FF0000;
6951 char *desc
= "unknown";
6955 desc
= "bug! MID not found";
6956 if (ioc
->reload_fw
== 0)
6961 desc
= "Parity Error";
6965 desc
= "ASYNC Outbound Overrun";
6969 desc
= "SYNC Offset Error";
6977 desc
= "Msg In Overflow";
6985 desc
= "Outbound DMA Overrun";
6989 desc
= "Task Management";
6993 desc
= "Device Problem";
6997 desc
= "Invalid Phase Change";
7001 desc
= "Untagged Table Size";
7006 printk(MYIOC_s_INFO_FMT
"LogInfo(0x%08x): F/W: %s\n", ioc
->name
, log_info
, desc
);
7009 /* strings for sas loginfo */
7010 static char *originator_str
[] = {
7015 static char *iop_code_str
[] = {
7017 "Invalid SAS Address", /* 01h */
7019 "Invalid Page", /* 03h */
7020 "Diag Message Error", /* 04h */
7021 "Task Terminated", /* 05h */
7022 "Enclosure Management", /* 06h */
7023 "Target Mode" /* 07h */
7025 static char *pl_code_str
[] = {
7027 "Open Failure", /* 01h */
7028 "Invalid Scatter Gather List", /* 02h */
7029 "Wrong Relative Offset or Frame Length", /* 03h */
7030 "Frame Transfer Error", /* 04h */
7031 "Transmit Frame Connected Low", /* 05h */
7032 "SATA Non-NCQ RW Error Bit Set", /* 06h */
7033 "SATA Read Log Receive Data Error", /* 07h */
7034 "SATA NCQ Fail All Commands After Error", /* 08h */
7035 "SATA Error in Receive Set Device Bit FIS", /* 09h */
7036 "Receive Frame Invalid Message", /* 0Ah */
7037 "Receive Context Message Valid Error", /* 0Bh */
7038 "Receive Frame Current Frame Error", /* 0Ch */
7039 "SATA Link Down", /* 0Dh */
7040 "Discovery SATA Init W IOS", /* 0Eh */
7041 "Config Invalid Page", /* 0Fh */
7042 "Discovery SATA Init Timeout", /* 10h */
7045 "IO Not Yet Executed", /* 13h */
7046 "IO Executed", /* 14h */
7047 "Persistent Reservation Out Not Affiliation "
7049 "Open Transmit DMA Abort", /* 16h */
7050 "IO Device Missing Delay Retry", /* 17h */
7051 "IO Cancelled Due to Recieve Error", /* 18h */
7059 "Enclosure Management" /* 20h */
7061 static char *ir_code_str
[] = {
7062 "Raid Action Error", /* 00h */
7072 static char *raid_sub_code_str
[] = {
7074 "Volume Creation Failed: Data Passed too "
7076 "Volume Creation Failed: Duplicate Volumes "
7077 "Attempted", /* 02h */
7078 "Volume Creation Failed: Max Number "
7079 "Supported Volumes Exceeded", /* 03h */
7080 "Volume Creation Failed: DMA Error", /* 04h */
7081 "Volume Creation Failed: Invalid Volume Type", /* 05h */
7082 "Volume Creation Failed: Error Reading "
7083 "MFG Page 4", /* 06h */
7084 "Volume Creation Failed: Creating Internal "
7085 "Structures", /* 07h */
7094 "Activation failed: Already Active Volume", /* 10h */
7095 "Activation failed: Unsupported Volume Type", /* 11h */
7096 "Activation failed: Too Many Active Volumes", /* 12h */
7097 "Activation failed: Volume ID in Use", /* 13h */
7098 "Activation failed: Reported Failure", /* 14h */
7099 "Activation failed: Importing a Volume", /* 15h */
7110 "Phys Disk failed: Too Many Phys Disks", /* 20h */
7111 "Phys Disk failed: Data Passed too Large", /* 21h */
7112 "Phys Disk failed: DMA Error", /* 22h */
7113 "Phys Disk failed: Invalid <channel:id>", /* 23h */
7114 "Phys Disk failed: Creating Phys Disk Config "
7127 "Compatibility Error: IR Disabled", /* 30h */
7128 "Compatibility Error: Inquiry Comand Failed", /* 31h */
7129 "Compatibility Error: Device not Direct Access "
7130 "Device ", /* 32h */
7131 "Compatibility Error: Removable Device Found", /* 33h */
7132 "Compatibility Error: Device SCSI Version not "
7133 "2 or Higher", /* 34h */
7134 "Compatibility Error: SATA Device, 48 BIT LBA "
7135 "not Supported", /* 35h */
7136 "Compatibility Error: Device doesn't have "
7137 "512 Byte Block Sizes", /* 36h */
7138 "Compatibility Error: Volume Type Check Failed", /* 37h */
7139 "Compatibility Error: Volume Type is "
7140 "Unsupported by FW", /* 38h */
7141 "Compatibility Error: Disk Drive too Small for "
7142 "use in Volume", /* 39h */
7143 "Compatibility Error: Phys Disk for Create "
7144 "Volume not Found", /* 3Ah */
7145 "Compatibility Error: Too Many or too Few "
7146 "Disks for Volume Type", /* 3Bh */
7147 "Compatibility Error: Disk stripe Sizes "
7148 "Must be 64KB", /* 3Ch */
7149 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
7152 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7154 * mpt_sas_log_info - Log information returned from SAS IOC.
7155 * @ioc: Pointer to MPT_ADAPTER structure
7156 * @log_info: U32 LogInfo reply word from the IOC
7158 * Refer to lsi/mpi_log_sas.h.
7161 mpt_sas_log_info(MPT_ADAPTER
*ioc
, u32 log_info
)
7163 union loginfo_type
{
7172 union loginfo_type sas_loginfo
;
7173 char *originator_desc
= NULL
;
7174 char *code_desc
= NULL
;
7175 char *sub_code_desc
= NULL
;
7177 sas_loginfo
.loginfo
= log_info
;
7178 if ((sas_loginfo
.dw
.bus_type
!= 3 /*SAS*/) &&
7179 (sas_loginfo
.dw
.originator
< sizeof(originator_str
)/sizeof(char*)))
7182 originator_desc
= originator_str
[sas_loginfo
.dw
.originator
];
7184 switch (sas_loginfo
.dw
.originator
) {
7187 if (sas_loginfo
.dw
.code
<
7188 sizeof(iop_code_str
)/sizeof(char*))
7189 code_desc
= iop_code_str
[sas_loginfo
.dw
.code
];
7192 if (sas_loginfo
.dw
.code
<
7193 sizeof(pl_code_str
)/sizeof(char*))
7194 code_desc
= pl_code_str
[sas_loginfo
.dw
.code
];
7197 if (sas_loginfo
.dw
.code
>=
7198 sizeof(ir_code_str
)/sizeof(char*))
7200 code_desc
= ir_code_str
[sas_loginfo
.dw
.code
];
7201 if (sas_loginfo
.dw
.subcode
>=
7202 sizeof(raid_sub_code_str
)/sizeof(char*))
7204 if (sas_loginfo
.dw
.code
== 0)
7206 raid_sub_code_str
[sas_loginfo
.dw
.subcode
];
7212 if (sub_code_desc
!= NULL
)
7213 printk(MYIOC_s_INFO_FMT
7214 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7216 ioc
->name
, log_info
, originator_desc
, code_desc
,
7218 else if (code_desc
!= NULL
)
7219 printk(MYIOC_s_INFO_FMT
7220 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7221 " SubCode(0x%04x)\n",
7222 ioc
->name
, log_info
, originator_desc
, code_desc
,
7223 sas_loginfo
.dw
.subcode
);
7225 printk(MYIOC_s_INFO_FMT
7226 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
7227 " SubCode(0x%04x)\n",
7228 ioc
->name
, log_info
, originator_desc
,
7229 sas_loginfo
.dw
.code
, sas_loginfo
.dw
.subcode
);
7232 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7234 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
7235 * @ioc: Pointer to MPT_ADAPTER structure
7236 * @ioc_status: U32 IOCStatus word from IOC
7237 * @mf: Pointer to MPT request frame
7239 * Refer to lsi/mpi.h.
7242 mpt_iocstatus_info_config(MPT_ADAPTER
*ioc
, u32 ioc_status
, MPT_FRAME_HDR
*mf
)
7244 Config_t
*pReq
= (Config_t
*)mf
;
7245 char extend_desc
[EVENT_DESCR_STR_SZ
];
7250 if (pReq
->Header
.PageType
== MPI_CONFIG_PAGETYPE_EXTENDED
)
7251 page_type
= pReq
->ExtPageType
;
7253 page_type
= pReq
->Header
.PageType
;
7256 * ignore invalid page messages for GET_NEXT_HANDLE
7258 form
= le32_to_cpu(pReq
->PageAddress
);
7259 if (ioc_status
== MPI_IOCSTATUS_CONFIG_INVALID_PAGE
) {
7260 if (page_type
== MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE
||
7261 page_type
== MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER
||
7262 page_type
== MPI_CONFIG_EXTPAGETYPE_ENCLOSURE
) {
7263 if ((form
>> MPI_SAS_DEVICE_PGAD_FORM_SHIFT
) ==
7264 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE
)
7267 if (page_type
== MPI_CONFIG_PAGETYPE_FC_DEVICE
)
7268 if ((form
& MPI_FC_DEVICE_PGAD_FORM_MASK
) ==
7269 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID
)
7273 snprintf(extend_desc
, EVENT_DESCR_STR_SZ
,
7274 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
7275 page_type
, pReq
->Header
.PageNumber
, pReq
->Action
, form
);
7277 switch (ioc_status
) {
7279 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION
: /* 0x0020 */
7280 desc
= "Config Page Invalid Action";
7283 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE
: /* 0x0021 */
7284 desc
= "Config Page Invalid Type";
7287 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE
: /* 0x0022 */
7288 desc
= "Config Page Invalid Page";
7291 case MPI_IOCSTATUS_CONFIG_INVALID_DATA
: /* 0x0023 */
7292 desc
= "Config Page Invalid Data";
7295 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS
: /* 0x0024 */
7296 desc
= "Config Page No Defaults";
7299 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT
: /* 0x0025 */
7300 desc
= "Config Page Can't Commit";
7307 dreplyprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"IOCStatus(0x%04X): %s: %s\n",
7308 ioc
->name
, ioc_status
, desc
, extend_desc
));
7312 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
7313 * @ioc: Pointer to MPT_ADAPTER structure
7314 * @ioc_status: U32 IOCStatus word from IOC
7315 * @mf: Pointer to MPT request frame
7317 * Refer to lsi/mpi.h.
7320 mpt_iocstatus_info(MPT_ADAPTER
*ioc
, u32 ioc_status
, MPT_FRAME_HDR
*mf
)
7322 u32 status
= ioc_status
& MPI_IOCSTATUS_MASK
;
7327 /****************************************************************************/
7328 /* Common IOCStatus values for all replies */
7329 /****************************************************************************/
7331 case MPI_IOCSTATUS_INVALID_FUNCTION
: /* 0x0001 */
7332 desc
= "Invalid Function";
7335 case MPI_IOCSTATUS_BUSY
: /* 0x0002 */
7339 case MPI_IOCSTATUS_INVALID_SGL
: /* 0x0003 */
7340 desc
= "Invalid SGL";
7343 case MPI_IOCSTATUS_INTERNAL_ERROR
: /* 0x0004 */
7344 desc
= "Internal Error";
7347 case MPI_IOCSTATUS_RESERVED
: /* 0x0005 */
7351 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES
: /* 0x0006 */
7352 desc
= "Insufficient Resources";
7355 case MPI_IOCSTATUS_INVALID_FIELD
: /* 0x0007 */
7356 desc
= "Invalid Field";
7359 case MPI_IOCSTATUS_INVALID_STATE
: /* 0x0008 */
7360 desc
= "Invalid State";
7363 /****************************************************************************/
7364 /* Config IOCStatus values */
7365 /****************************************************************************/
7367 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION
: /* 0x0020 */
7368 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE
: /* 0x0021 */
7369 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE
: /* 0x0022 */
7370 case MPI_IOCSTATUS_CONFIG_INVALID_DATA
: /* 0x0023 */
7371 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS
: /* 0x0024 */
7372 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT
: /* 0x0025 */
7373 mpt_iocstatus_info_config(ioc
, status
, mf
);
7376 /****************************************************************************/
7377 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
7379 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
7381 /****************************************************************************/
7383 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR
: /* 0x0040 */
7384 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN
: /* 0x0045 */
7385 case MPI_IOCSTATUS_SCSI_INVALID_BUS
: /* 0x0041 */
7386 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID
: /* 0x0042 */
7387 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE
: /* 0x0043 */
7388 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN
: /* 0x0044 */
7389 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR
: /* 0x0046 */
7390 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR
: /* 0x0047 */
7391 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED
: /* 0x0048 */
7392 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH
: /* 0x0049 */
7393 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED
: /* 0x004A */
7394 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED
: /* 0x004B */
7395 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED
: /* 0x004C */
7398 /****************************************************************************/
7399 /* SCSI Target values */
7400 /****************************************************************************/
7402 case MPI_IOCSTATUS_TARGET_PRIORITY_IO
: /* 0x0060 */
7403 desc
= "Target: Priority IO";
7406 case MPI_IOCSTATUS_TARGET_INVALID_PORT
: /* 0x0061 */
7407 desc
= "Target: Invalid Port";
7410 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX
: /* 0x0062 */
7411 desc
= "Target Invalid IO Index:";
7414 case MPI_IOCSTATUS_TARGET_ABORTED
: /* 0x0063 */
7415 desc
= "Target: Aborted";
7418 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE
: /* 0x0064 */
7419 desc
= "Target: No Conn Retryable";
7422 case MPI_IOCSTATUS_TARGET_NO_CONNECTION
: /* 0x0065 */
7423 desc
= "Target: No Connection";
7426 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH
: /* 0x006A */
7427 desc
= "Target: Transfer Count Mismatch";
7430 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT
: /* 0x006B */
7431 desc
= "Target: STS Data not Sent";
7434 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR
: /* 0x006D */
7435 desc
= "Target: Data Offset Error";
7438 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA
: /* 0x006E */
7439 desc
= "Target: Too Much Write Data";
7442 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT
: /* 0x006F */
7443 desc
= "Target: IU Too Short";
7446 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT
: /* 0x0070 */
7447 desc
= "Target: ACK NAK Timeout";
7450 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED
: /* 0x0071 */
7451 desc
= "Target: Nak Received";
7454 /****************************************************************************/
7455 /* Fibre Channel Direct Access values */
7456 /****************************************************************************/
7458 case MPI_IOCSTATUS_FC_ABORTED
: /* 0x0066 */
7459 desc
= "FC: Aborted";
7462 case MPI_IOCSTATUS_FC_RX_ID_INVALID
: /* 0x0067 */
7463 desc
= "FC: RX ID Invalid";
7466 case MPI_IOCSTATUS_FC_DID_INVALID
: /* 0x0068 */
7467 desc
= "FC: DID Invalid";
7470 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT
: /* 0x0069 */
7471 desc
= "FC: Node Logged Out";
7474 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED
: /* 0x006C */
7475 desc
= "FC: Exchange Canceled";
7478 /****************************************************************************/
7480 /****************************************************************************/
7482 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND
: /* 0x0080 */
7483 desc
= "LAN: Device not Found";
7486 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE
: /* 0x0081 */
7487 desc
= "LAN: Device Failure";
7490 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR
: /* 0x0082 */
7491 desc
= "LAN: Transmit Error";
7494 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED
: /* 0x0083 */
7495 desc
= "LAN: Transmit Aborted";
7498 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR
: /* 0x0084 */
7499 desc
= "LAN: Receive Error";
7502 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED
: /* 0x0085 */
7503 desc
= "LAN: Receive Aborted";
7506 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET
: /* 0x0086 */
7507 desc
= "LAN: Partial Packet";
7510 case MPI_IOCSTATUS_LAN_CANCELED
: /* 0x0087 */
7511 desc
= "LAN: Canceled";
7514 /****************************************************************************/
7515 /* Serial Attached SCSI values */
7516 /****************************************************************************/
7518 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED
: /* 0x0090 */
7519 desc
= "SAS: SMP Request Failed";
7522 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN
: /* 0x0090 */
7523 desc
= "SAS: SMP Data Overrun";
7534 dreplyprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"IOCStatus(0x%04X): %s\n",
7535 ioc
->name
, status
, desc
));
7538 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7539 EXPORT_SYMBOL(mpt_attach
);
7540 EXPORT_SYMBOL(mpt_detach
);
7542 EXPORT_SYMBOL(mpt_resume
);
7543 EXPORT_SYMBOL(mpt_suspend
);
7545 EXPORT_SYMBOL(ioc_list
);
7546 EXPORT_SYMBOL(mpt_register
);
7547 EXPORT_SYMBOL(mpt_deregister
);
7548 EXPORT_SYMBOL(mpt_event_register
);
7549 EXPORT_SYMBOL(mpt_event_deregister
);
7550 EXPORT_SYMBOL(mpt_reset_register
);
7551 EXPORT_SYMBOL(mpt_reset_deregister
);
7552 EXPORT_SYMBOL(mpt_device_driver_register
);
7553 EXPORT_SYMBOL(mpt_device_driver_deregister
);
7554 EXPORT_SYMBOL(mpt_get_msg_frame
);
7555 EXPORT_SYMBOL(mpt_put_msg_frame
);
7556 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri
);
7557 EXPORT_SYMBOL(mpt_free_msg_frame
);
7558 EXPORT_SYMBOL(mpt_add_sge
);
7559 EXPORT_SYMBOL(mpt_send_handshake_request
);
7560 EXPORT_SYMBOL(mpt_verify_adapter
);
7561 EXPORT_SYMBOL(mpt_GetIocState
);
7562 EXPORT_SYMBOL(mpt_print_ioc_summary
);
7563 EXPORT_SYMBOL(mpt_HardResetHandler
);
7564 EXPORT_SYMBOL(mpt_config
);
7565 EXPORT_SYMBOL(mpt_findImVolumes
);
7566 EXPORT_SYMBOL(mpt_alloc_fw_memory
);
7567 EXPORT_SYMBOL(mpt_free_fw_memory
);
7568 EXPORT_SYMBOL(mptbase_sas_persist_operation
);
7569 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0
);
7571 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7573 * fusion_init - Fusion MPT base driver initialization routine.
7575 * Returns 0 for success, non-zero for failure.
7582 show_mptmod_ver(my_NAME
, my_VERSION
);
7583 printk(KERN_INFO COPYRIGHT
"\n");
7585 for (cb_idx
= 0; cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
; cb_idx
++) {
7586 MptCallbacks
[cb_idx
] = NULL
;
7587 MptDriverClass
[cb_idx
] = MPTUNKNOWN_DRIVER
;
7588 MptEvHandlers
[cb_idx
] = NULL
;
7589 MptResetHandlers
[cb_idx
] = NULL
;
7592 /* Register ourselves (mptbase) in order to facilitate
7593 * EventNotification handling.
7595 mpt_base_index
= mpt_register(mpt_base_reply
, MPTBASE_DRIVER
);
7597 /* Register for hard reset handling callbacks.
7599 mpt_reset_register(mpt_base_index
, mpt_ioc_reset
);
7601 #ifdef CONFIG_PROC_FS
7602 (void) procmpt_create();
7607 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7609 * fusion_exit - Perform driver unload cleanup.
7611 * This routine frees all resources associated with each MPT adapter
7612 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
7618 mpt_reset_deregister(mpt_base_index
);
7620 #ifdef CONFIG_PROC_FS
7625 module_init(fusion_init
);
7626 module_exit(fusion_exit
);