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
, __FUNCTION__
);
279 rc
= mpt_HardResetHandler(ioc
, CAN_SLEEP
);
280 printk(MYIOC_s_WARN_FMT
"%s: HardReset: %s\n", ioc
->name
,
281 __FUNCTION__
, (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 __FUNCTION__
, 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 __FUNCTION__
, 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
, KOBJ_NAME_LEN
, "mpt_poll_%d", ioc
->id
);
1675 create_singlethread_workqueue(ioc
->reset_work_q_name
);
1676 if (!ioc
->reset_work_q
) {
1677 printk(MYIOC_s_ERR_FMT
"Insufficient memory to add adapter!\n",
1679 pci_release_selected_regions(pdev
, ioc
->bars
);
1684 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"facts @ %p, pfacts[0] @ %p\n",
1685 ioc
->name
, &ioc
->facts
, &ioc
->pfacts
[0]));
1687 pci_read_config_byte(pdev
, PCI_CLASS_REVISION
, &revision
);
1688 mpt_get_product_name(pdev
->vendor
, pdev
->device
, revision
, ioc
->prod_name
);
1690 switch (pdev
->device
)
1692 case MPI_MANUFACTPAGE_DEVICEID_FC939X
:
1693 case MPI_MANUFACTPAGE_DEVICEID_FC949X
:
1694 ioc
->errata_flag_1064
= 1;
1695 case MPI_MANUFACTPAGE_DEVICEID_FC909
:
1696 case MPI_MANUFACTPAGE_DEVICEID_FC929
:
1697 case MPI_MANUFACTPAGE_DEVICEID_FC919
:
1698 case MPI_MANUFACTPAGE_DEVICEID_FC949E
:
1702 case MPI_MANUFACTPAGE_DEVICEID_FC929X
:
1703 if (revision
< XL_929
) {
1704 /* 929X Chip Fix. Set Split transactions level
1705 * for PCIX. Set MOST bits to zero.
1707 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1709 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1711 /* 929XL Chip Fix. Set MMRBC to 0x08.
1713 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1715 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1720 case MPI_MANUFACTPAGE_DEVICEID_FC919X
:
1721 /* 919X Chip Fix. Set Split transactions level
1722 * for PCIX. Set MOST bits to zero.
1724 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1726 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1730 case MPI_MANUFACTPAGE_DEVID_53C1030
:
1731 /* 1030 Chip Fix. Disable Split transactions
1732 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1734 if (revision
< C0_1030
) {
1735 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1737 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1740 case MPI_MANUFACTPAGE_DEVID_1030_53C1035
:
1741 ioc
->bus_type
= SPI
;
1744 case MPI_MANUFACTPAGE_DEVID_SAS1064
:
1745 case MPI_MANUFACTPAGE_DEVID_SAS1068
:
1746 ioc
->errata_flag_1064
= 1;
1748 case MPI_MANUFACTPAGE_DEVID_SAS1064E
:
1749 case MPI_MANUFACTPAGE_DEVID_SAS1068E
:
1750 case MPI_MANUFACTPAGE_DEVID_SAS1078
:
1751 ioc
->bus_type
= SAS
;
1754 if (mpt_msi_enable
== -1) {
1755 /* Enable on SAS, disable on FC and SPI */
1756 if (ioc
->bus_type
== SAS
)
1757 ioc
->msi_enable
= 1;
1759 ioc
->msi_enable
= 0;
1761 /* follow flag: 0 - disable; 1 - enable */
1762 ioc
->msi_enable
= mpt_msi_enable
;
1764 if (ioc
->errata_flag_1064
)
1765 pci_disable_io_access(pdev
);
1767 spin_lock_init(&ioc
->FreeQlock
);
1770 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
1772 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1774 /* Set IOC ptr in the pcidev's driver data. */
1775 pci_set_drvdata(ioc
->pcidev
, ioc
);
1777 /* Set lookup ptr. */
1778 list_add_tail(&ioc
->list
, &ioc_list
);
1780 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1782 mpt_detect_bound_ports(ioc
, pdev
);
1784 if ((r
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_BRINGUP
,
1786 printk(MYIOC_s_ERR_FMT
"didn't initialize properly! (%d)\n",
1789 list_del(&ioc
->list
);
1791 ioc
->alt_ioc
->alt_ioc
= NULL
;
1792 iounmap(ioc
->memmap
);
1794 pci_release_selected_regions(pdev
, ioc
->bars
);
1796 destroy_workqueue(ioc
->reset_work_q
);
1797 ioc
->reset_work_q
= NULL
;
1800 pci_set_drvdata(pdev
, NULL
);
1804 /* call per device driver probe entry point */
1805 for(cb_idx
= 0; cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
; cb_idx
++) {
1806 if(MptDeviceDriverHandlers
[cb_idx
] &&
1807 MptDeviceDriverHandlers
[cb_idx
]->probe
) {
1808 MptDeviceDriverHandlers
[cb_idx
]->probe(pdev
,id
);
1812 #ifdef CONFIG_PROC_FS
1814 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1816 dent
= proc_mkdir(ioc
->name
, mpt_proc_root_dir
);
1818 ent
= create_proc_entry("info", S_IFREG
|S_IRUGO
, dent
);
1820 ent
->read_proc
= procmpt_iocinfo_read
;
1823 ent
= create_proc_entry("summary", S_IFREG
|S_IRUGO
, dent
);
1825 ent
->read_proc
= procmpt_summary_read
;
1832 queue_delayed_work(ioc
->reset_work_q
, &ioc
->fault_reset_work
,
1833 msecs_to_jiffies(MPT_POLLING_INTERVAL
));
1838 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1840 * mpt_detach - Remove a PCI intelligent MPT adapter.
1841 * @pdev: Pointer to pci_dev structure
1845 mpt_detach(struct pci_dev
*pdev
)
1847 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
1850 unsigned long flags
;
1851 struct workqueue_struct
*wq
;
1854 * Stop polling ioc for fault condition
1856 spin_lock_irqsave(&ioc
->fault_reset_work_lock
, flags
);
1857 wq
= ioc
->reset_work_q
;
1858 ioc
->reset_work_q
= NULL
;
1859 spin_unlock_irqrestore(&ioc
->fault_reset_work_lock
, flags
);
1860 cancel_delayed_work(&ioc
->fault_reset_work
);
1861 destroy_workqueue(wq
);
1864 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s/summary", ioc
->name
);
1865 remove_proc_entry(pname
, NULL
);
1866 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s/info", ioc
->name
);
1867 remove_proc_entry(pname
, NULL
);
1868 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s", ioc
->name
);
1869 remove_proc_entry(pname
, NULL
);
1871 /* call per device driver remove entry point */
1872 for(cb_idx
= 0; cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
; cb_idx
++) {
1873 if(MptDeviceDriverHandlers
[cb_idx
] &&
1874 MptDeviceDriverHandlers
[cb_idx
]->remove
) {
1875 MptDeviceDriverHandlers
[cb_idx
]->remove(pdev
);
1879 /* Disable interrupts! */
1880 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
1883 synchronize_irq(pdev
->irq
);
1885 /* Clear any lingering interrupt */
1886 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1888 CHIPREG_READ32(&ioc
->chip
->IntStatus
);
1890 mpt_adapter_dispose(ioc
);
1892 pci_set_drvdata(pdev
, NULL
);
1895 /**************************************************************************
1899 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1901 * mpt_suspend - Fusion MPT base driver suspend routine.
1902 * @pdev: Pointer to pci_dev structure
1903 * @state: new state to enter
1906 mpt_suspend(struct pci_dev
*pdev
, pm_message_t state
)
1909 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
1911 device_state
= pci_choose_state(pdev
, state
);
1912 printk(MYIOC_s_INFO_FMT
"pci-suspend: pdev=0x%p, slot=%s, Entering "
1913 "operating state [D%d]\n", ioc
->name
, pdev
, pci_name(pdev
),
1916 /* put ioc into READY_STATE */
1917 if(SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, CAN_SLEEP
)) {
1918 printk(MYIOC_s_ERR_FMT
1919 "pci-suspend: IOC msg unit reset failed!\n", ioc
->name
);
1922 /* disable interrupts */
1923 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
1926 /* Clear any lingering interrupt */
1927 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1929 free_irq(ioc
->pci_irq
, ioc
);
1930 if (ioc
->msi_enable
)
1931 pci_disable_msi(ioc
->pcidev
);
1933 pci_save_state(pdev
);
1934 pci_disable_device(pdev
);
1935 pci_release_selected_regions(pdev
, ioc
->bars
);
1936 pci_set_power_state(pdev
, device_state
);
1940 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1942 * mpt_resume - Fusion MPT base driver resume routine.
1943 * @pdev: Pointer to pci_dev structure
1946 mpt_resume(struct pci_dev
*pdev
)
1948 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
1949 u32 device_state
= pdev
->current_state
;
1953 printk(MYIOC_s_INFO_FMT
"pci-resume: pdev=0x%p, slot=%s, Previous "
1954 "operating state [D%d]\n", ioc
->name
, pdev
, pci_name(pdev
),
1957 pci_set_power_state(pdev
, PCI_D0
);
1958 pci_enable_wake(pdev
, PCI_D0
, 0);
1959 pci_restore_state(pdev
);
1961 err
= mpt_mapresources(ioc
);
1965 printk(MYIOC_s_INFO_FMT
"pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1966 ioc
->name
, (mpt_GetIocState(ioc
, 1) >> MPI_IOC_STATE_SHIFT
),
1967 CHIPREG_READ32(&ioc
->chip
->Doorbell
));
1970 * Errata workaround for SAS pci express:
1971 * Upon returning to the D0 state, the contents of the doorbell will be
1972 * stale data, and this will incorrectly signal to the host driver that
1973 * the firmware is ready to process mpt commands. The workaround is
1974 * to issue a diagnostic reset.
1976 if (ioc
->bus_type
== SAS
&& (pdev
->device
==
1977 MPI_MANUFACTPAGE_DEVID_SAS1068E
|| pdev
->device
==
1978 MPI_MANUFACTPAGE_DEVID_SAS1064E
)) {
1979 if (KickStart(ioc
, 1, CAN_SLEEP
) < 0) {
1980 printk(MYIOC_s_WARN_FMT
"pci-resume: Cannot recover\n",
1986 /* bring ioc to operational state */
1987 printk(MYIOC_s_INFO_FMT
"Sending mpt_do_ioc_recovery\n", ioc
->name
);
1988 recovery_state
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_BRINGUP
,
1990 if (recovery_state
!= 0)
1991 printk(MYIOC_s_WARN_FMT
"pci-resume: Cannot recover, "
1992 "error:[%x]\n", ioc
->name
, recovery_state
);
1994 printk(MYIOC_s_INFO_FMT
1995 "pci-resume: success\n", ioc
->name
);
2003 mpt_signal_reset(u8 index
, MPT_ADAPTER
*ioc
, int reset_phase
)
2005 if ((MptDriverClass
[index
] == MPTSPI_DRIVER
&&
2006 ioc
->bus_type
!= SPI
) ||
2007 (MptDriverClass
[index
] == MPTFC_DRIVER
&&
2008 ioc
->bus_type
!= FC
) ||
2009 (MptDriverClass
[index
] == MPTSAS_DRIVER
&&
2010 ioc
->bus_type
!= SAS
))
2011 /* make sure we only call the relevant reset handler
2014 return (MptResetHandlers
[index
])(ioc
, reset_phase
);
2017 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2019 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
2020 * @ioc: Pointer to MPT adapter structure
2021 * @reason: Event word / reason
2022 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
2024 * This routine performs all the steps necessary to bring the IOC
2025 * to a OPERATIONAL state.
2027 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
2032 * -1 if failed to get board READY
2033 * -2 if READY but IOCFacts Failed
2034 * -3 if READY but PrimeIOCFifos Failed
2035 * -4 if READY but IOCInit Failed
2036 * -5 if failed to enable_device and/or request_selected_regions
2037 * -6 if failed to upload firmware
2040 mpt_do_ioc_recovery(MPT_ADAPTER
*ioc
, u32 reason
, int sleepFlag
)
2042 int hard_reset_done
= 0;
2043 int alt_ioc_ready
= 0;
2050 int reset_alt_ioc_active
= 0;
2051 int irq_allocated
= 0;
2054 printk(MYIOC_s_INFO_FMT
"Initiating %s\n", ioc
->name
,
2055 reason
== MPT_HOSTEVENT_IOC_BRINGUP
? "bringup" : "recovery");
2057 /* Disable reply interrupts (also blocks FreeQ) */
2058 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2062 if (ioc
->alt_ioc
->active
)
2063 reset_alt_ioc_active
= 1;
2065 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
2066 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
, 0xFFFFFFFF);
2067 ioc
->alt_ioc
->active
= 0;
2071 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)
2074 if ((hard_reset_done
= MakeIocReady(ioc
, hard
, sleepFlag
)) < 0) {
2075 if (hard_reset_done
== -4) {
2076 printk(MYIOC_s_WARN_FMT
"Owned by PEER..skipping!\n",
2079 if (reset_alt_ioc_active
&& ioc
->alt_ioc
) {
2080 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
2081 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
2082 "alt_ioc reply irq re-enabled\n", ioc
->alt_ioc
->name
));
2083 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
, MPI_HIM_DIM
);
2084 ioc
->alt_ioc
->active
= 1;
2088 printk(MYIOC_s_WARN_FMT
"NOT READY!\n", ioc
->name
);
2093 /* hard_reset_done = 0 if a soft reset was performed
2094 * and 1 if a hard reset was performed.
2096 if (hard_reset_done
&& reset_alt_ioc_active
&& ioc
->alt_ioc
) {
2097 if ((rc
= MakeIocReady(ioc
->alt_ioc
, 0, sleepFlag
)) == 0)
2100 printk(MYIOC_s_WARN_FMT
"alt_ioc not ready!\n", ioc
->alt_ioc
->name
);
2103 for (ii
=0; ii
<5; ii
++) {
2104 /* Get IOC facts! Allow 5 retries */
2105 if ((rc
= GetIocFacts(ioc
, sleepFlag
, reason
)) == 0)
2111 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2112 "Retry IocFacts failed rc=%x\n", ioc
->name
, rc
));
2114 } else if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
2115 MptDisplayIocCapabilities(ioc
);
2118 if (alt_ioc_ready
) {
2119 if ((rc
= GetIocFacts(ioc
->alt_ioc
, sleepFlag
, reason
)) != 0) {
2120 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2121 "Initial Alt IocFacts failed rc=%x\n", ioc
->name
, rc
));
2122 /* Retry - alt IOC was initialized once
2124 rc
= GetIocFacts(ioc
->alt_ioc
, sleepFlag
, reason
);
2127 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2128 "Retry Alt IocFacts failed rc=%x\n", ioc
->name
, rc
));
2130 reset_alt_ioc_active
= 0;
2131 } else if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
2132 MptDisplayIocCapabilities(ioc
->alt_ioc
);
2136 if ((ret
== 0) && (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) &&
2137 (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)) {
2138 pci_release_selected_regions(ioc
->pcidev
, ioc
->bars
);
2139 ioc
->bars
= pci_select_bars(ioc
->pcidev
, IORESOURCE_MEM
|
2141 if (pci_enable_device(ioc
->pcidev
))
2143 if (pci_request_selected_regions(ioc
->pcidev
, ioc
->bars
,
2149 * Device is reset now. It must have de-asserted the interrupt line
2150 * (if it was asserted) and it should be safe to register for the
2153 if ((ret
== 0) && (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)) {
2155 if (ioc
->pcidev
->irq
) {
2156 if (ioc
->msi_enable
&& !pci_enable_msi(ioc
->pcidev
))
2157 printk(MYIOC_s_INFO_FMT
"PCI-MSI enabled\n",
2160 ioc
->msi_enable
= 0;
2161 rc
= request_irq(ioc
->pcidev
->irq
, mpt_interrupt
,
2162 IRQF_SHARED
, ioc
->name
, ioc
);
2164 printk(MYIOC_s_ERR_FMT
"Unable to allocate "
2165 "interrupt %d!\n", ioc
->name
, ioc
->pcidev
->irq
);
2166 if (ioc
->msi_enable
)
2167 pci_disable_msi(ioc
->pcidev
);
2171 ioc
->pci_irq
= ioc
->pcidev
->irq
;
2172 pci_set_master(ioc
->pcidev
); /* ?? */
2173 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
"installed at interrupt "
2174 "%d\n", ioc
->name
, ioc
->pcidev
->irq
));
2178 /* Prime reply & request queues!
2179 * (mucho alloc's) Must be done prior to
2180 * init as upper addresses are needed for init.
2181 * If fails, continue with alt-ioc processing
2183 if ((ret
== 0) && ((rc
= PrimeIocFifos(ioc
)) != 0))
2186 /* May need to check/upload firmware & data here!
2187 * If fails, continue with alt-ioc processing
2189 if ((ret
== 0) && ((rc
= SendIocInit(ioc
, sleepFlag
)) != 0))
2192 if (alt_ioc_ready
&& ((rc
= PrimeIocFifos(ioc
->alt_ioc
)) != 0)) {
2193 printk(MYIOC_s_WARN_FMT
": alt_ioc (%d) FIFO mgmt alloc!\n",
2194 ioc
->alt_ioc
->name
, rc
);
2196 reset_alt_ioc_active
= 0;
2199 if (alt_ioc_ready
) {
2200 if ((rc
= SendIocInit(ioc
->alt_ioc
, sleepFlag
)) != 0) {
2202 reset_alt_ioc_active
= 0;
2203 printk(MYIOC_s_WARN_FMT
"alt_ioc (%d) init failure!\n",
2204 ioc
->alt_ioc
->name
, rc
);
2208 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
){
2209 if (ioc
->upload_fw
) {
2210 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2211 "firmware upload required!\n", ioc
->name
));
2213 /* Controller is not operational, cannot do upload
2216 rc
= mpt_do_upload(ioc
, sleepFlag
);
2218 if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
) {
2220 * Maintain only one pointer to FW memory
2221 * so there will not be two attempt to
2222 * downloadboot onboard dual function
2223 * chips (mpt_adapter_disable,
2226 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2227 "mpt_upload: alt_%s has cached_fw=%p \n",
2228 ioc
->name
, ioc
->alt_ioc
->name
, ioc
->alt_ioc
->cached_fw
));
2229 ioc
->cached_fw
= NULL
;
2232 printk(MYIOC_s_WARN_FMT
2233 "firmware upload failure!\n", ioc
->name
);
2241 /* Enable! (reply interrupt) */
2242 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, MPI_HIM_DIM
);
2246 if (reset_alt_ioc_active
&& ioc
->alt_ioc
) {
2247 /* (re)Enable alt-IOC! (reply interrupt) */
2248 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"alt_ioc reply irq re-enabled\n",
2249 ioc
->alt_ioc
->name
));
2250 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
, MPI_HIM_DIM
);
2251 ioc
->alt_ioc
->active
= 1;
2254 /* Enable MPT base driver management of EventNotification
2255 * and EventAck handling.
2257 if ((ret
== 0) && (!ioc
->facts
.EventState
))
2258 (void) SendEventNotification(ioc
, 1); /* 1=Enable EventNotification */
2260 if (ioc
->alt_ioc
&& alt_ioc_ready
&& !ioc
->alt_ioc
->facts
.EventState
)
2261 (void) SendEventNotification(ioc
->alt_ioc
, 1); /* 1=Enable EventNotification */
2263 /* Add additional "reason" check before call to GetLanConfigPages
2264 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2265 * recursive scenario; GetLanConfigPages times out, timer expired
2266 * routine calls HardResetHandler, which calls into here again,
2267 * and we try GetLanConfigPages again...
2269 if ((ret
== 0) && (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)) {
2272 * Initalize link list for inactive raid volumes.
2274 mutex_init(&ioc
->raid_data
.inactive_list_mutex
);
2275 INIT_LIST_HEAD(&ioc
->raid_data
.inactive_list
);
2277 if (ioc
->bus_type
== SAS
) {
2279 /* clear persistency table */
2280 if(ioc
->facts
.IOCExceptions
&
2281 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL
) {
2282 ret
= mptbase_sas_persist_operation(ioc
,
2283 MPI_SAS_OP_CLEAR_NOT_PRESENT
);
2290 mpt_findImVolumes(ioc
);
2292 } else if (ioc
->bus_type
== FC
) {
2293 if ((ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
) &&
2294 (ioc
->lan_cnfg_page0
.Header
.PageLength
== 0)) {
2296 * Pre-fetch the ports LAN MAC address!
2297 * (LANPage1_t stuff)
2299 (void) GetLanConfigPages(ioc
);
2300 a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
2301 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2302 "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
2303 ioc
->name
, a
[5], a
[4], a
[3], a
[2], a
[1], a
[0]));
2307 /* Get NVRAM and adapter maximums from SPP 0 and 2
2309 mpt_GetScsiPortSettings(ioc
, 0);
2311 /* Get version and length of SDP 1
2313 mpt_readScsiDevicePageHeaders(ioc
, 0);
2317 if (ioc
->facts
.MsgVersion
>= MPI_VERSION_01_02
)
2318 mpt_findImVolumes(ioc
);
2320 /* Check, and possibly reset, the coalescing value
2322 mpt_read_ioc_pg_1(ioc
);
2324 mpt_read_ioc_pg_4(ioc
);
2327 GetIoUnitPage2(ioc
);
2328 mpt_get_manufacturing_pg_0(ioc
);
2332 * Call each currently registered protocol IOC reset handler
2333 * with post-reset indication.
2334 * NOTE: If we're doing _IOC_BRINGUP, there can be no
2335 * MptResetHandlers[] registered yet.
2337 if (hard_reset_done
) {
2339 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
2340 if ((ret
== 0) && MptResetHandlers
[cb_idx
]) {
2341 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2342 "Calling IOC post_reset handler #%d\n",
2343 ioc
->name
, cb_idx
));
2344 rc
+= mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_POST_RESET
);
2348 if (alt_ioc_ready
&& MptResetHandlers
[cb_idx
]) {
2349 drsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2350 "Calling IOC post_reset handler #%d\n",
2351 ioc
->alt_ioc
->name
, cb_idx
));
2352 rc
+= mpt_signal_reset(cb_idx
, ioc
->alt_ioc
, MPT_IOC_POST_RESET
);
2356 /* FIXME? Examine results here? */
2360 if ((ret
!= 0) && irq_allocated
) {
2361 free_irq(ioc
->pci_irq
, ioc
);
2362 if (ioc
->msi_enable
)
2363 pci_disable_msi(ioc
->pcidev
);
2368 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2370 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2371 * @ioc: Pointer to MPT adapter structure
2372 * @pdev: Pointer to (struct pci_dev) structure
2374 * Search for PCI bus/dev_function which matches
2375 * PCI bus/dev_function (+/-1) for newly discovered 929,
2376 * 929X, 1030 or 1035.
2378 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2379 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2382 mpt_detect_bound_ports(MPT_ADAPTER
*ioc
, struct pci_dev
*pdev
)
2384 struct pci_dev
*peer
=NULL
;
2385 unsigned int slot
= PCI_SLOT(pdev
->devfn
);
2386 unsigned int func
= PCI_FUNC(pdev
->devfn
);
2387 MPT_ADAPTER
*ioc_srch
;
2389 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"PCI device %s devfn=%x/%x,"
2390 " searching for devfn match on %x or %x\n",
2391 ioc
->name
, pci_name(pdev
), pdev
->bus
->number
,
2392 pdev
->devfn
, func
-1, func
+1));
2394 peer
= pci_get_slot(pdev
->bus
, PCI_DEVFN(slot
,func
-1));
2396 peer
= pci_get_slot(pdev
->bus
, PCI_DEVFN(slot
,func
+1));
2401 list_for_each_entry(ioc_srch
, &ioc_list
, list
) {
2402 struct pci_dev
*_pcidev
= ioc_srch
->pcidev
;
2403 if (_pcidev
== peer
) {
2404 /* Paranoia checks */
2405 if (ioc
->alt_ioc
!= NULL
) {
2406 printk(MYIOC_s_WARN_FMT
"Oops, already bound to %s!\n",
2407 ioc
->name
, ioc
->alt_ioc
->name
);
2409 } else if (ioc_srch
->alt_ioc
!= NULL
) {
2410 printk(MYIOC_s_WARN_FMT
"Oops, already bound to %s!\n",
2411 ioc_srch
->name
, ioc_srch
->alt_ioc
->name
);
2414 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
"FOUND! binding to %s\n",
2415 ioc
->name
, ioc_srch
->name
));
2416 ioc_srch
->alt_ioc
= ioc
;
2417 ioc
->alt_ioc
= ioc_srch
;
2423 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2425 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2426 * @ioc: Pointer to MPT adapter structure
2429 mpt_adapter_disable(MPT_ADAPTER
*ioc
)
2434 if (ioc
->cached_fw
!= NULL
) {
2435 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"%s: Pushing FW onto "
2436 "adapter\n", __FUNCTION__
, ioc
->name
));
2437 if ((ret
= mpt_downloadboot(ioc
, (MpiFwHeader_t
*)
2438 ioc
->cached_fw
, CAN_SLEEP
)) < 0) {
2439 printk(MYIOC_s_WARN_FMT
2440 ": firmware downloadboot failure (%d)!\n",
2445 /* Disable adapter interrupts! */
2446 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2448 /* Clear any lingering interrupt */
2449 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
2451 if (ioc
->alloc
!= NULL
) {
2453 dexitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"free @ %p, sz=%d bytes\n",
2454 ioc
->name
, ioc
->alloc
, ioc
->alloc_sz
));
2455 pci_free_consistent(ioc
->pcidev
, sz
,
2456 ioc
->alloc
, ioc
->alloc_dma
);
2457 ioc
->reply_frames
= NULL
;
2458 ioc
->req_frames
= NULL
;
2460 ioc
->alloc_total
-= sz
;
2463 if (ioc
->sense_buf_pool
!= NULL
) {
2464 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
2465 pci_free_consistent(ioc
->pcidev
, sz
,
2466 ioc
->sense_buf_pool
, ioc
->sense_buf_pool_dma
);
2467 ioc
->sense_buf_pool
= NULL
;
2468 ioc
->alloc_total
-= sz
;
2471 if (ioc
->events
!= NULL
){
2472 sz
= MPTCTL_EVENT_LOG_SIZE
* sizeof(MPT_IOCTL_EVENTS
);
2475 ioc
->alloc_total
-= sz
;
2478 mpt_free_fw_memory(ioc
);
2480 kfree(ioc
->spi_data
.nvram
);
2481 mpt_inactive_raid_list_free(ioc
);
2482 kfree(ioc
->raid_data
.pIocPg2
);
2483 kfree(ioc
->raid_data
.pIocPg3
);
2484 ioc
->spi_data
.nvram
= NULL
;
2485 ioc
->raid_data
.pIocPg3
= NULL
;
2487 if (ioc
->spi_data
.pIocPg4
!= NULL
) {
2488 sz
= ioc
->spi_data
.IocPg4Sz
;
2489 pci_free_consistent(ioc
->pcidev
, sz
,
2490 ioc
->spi_data
.pIocPg4
,
2491 ioc
->spi_data
.IocPg4_dma
);
2492 ioc
->spi_data
.pIocPg4
= NULL
;
2493 ioc
->alloc_total
-= sz
;
2496 if (ioc
->ReqToChain
!= NULL
) {
2497 kfree(ioc
->ReqToChain
);
2498 kfree(ioc
->RequestNB
);
2499 ioc
->ReqToChain
= NULL
;
2502 kfree(ioc
->ChainToChain
);
2503 ioc
->ChainToChain
= NULL
;
2505 if (ioc
->HostPageBuffer
!= NULL
) {
2506 if((ret
= mpt_host_page_access_control(ioc
,
2507 MPI_DB_HPBAC_FREE_BUFFER
, NO_SLEEP
)) != 0) {
2508 printk(MYIOC_s_ERR_FMT
2509 "host page buffers free failed (%d)!\n",
2512 dexitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"HostPageBuffer free @ %p, sz=%d bytes\n",
2513 ioc
->name
, ioc
->HostPageBuffer
, ioc
->HostPageBuffer_sz
));
2514 pci_free_consistent(ioc
->pcidev
, ioc
->HostPageBuffer_sz
,
2515 ioc
->HostPageBuffer
, ioc
->HostPageBuffer_dma
);
2516 ioc
->HostPageBuffer
= NULL
;
2517 ioc
->HostPageBuffer_sz
= 0;
2518 ioc
->alloc_total
-= ioc
->HostPageBuffer_sz
;
2522 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2524 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2525 * @ioc: Pointer to MPT adapter structure
2527 * This routine unregisters h/w resources and frees all alloc'd memory
2528 * associated with a MPT adapter structure.
2531 mpt_adapter_dispose(MPT_ADAPTER
*ioc
)
2533 int sz_first
, sz_last
;
2538 sz_first
= ioc
->alloc_total
;
2540 mpt_adapter_disable(ioc
);
2542 if (ioc
->pci_irq
!= -1) {
2543 free_irq(ioc
->pci_irq
, ioc
);
2544 if (ioc
->msi_enable
)
2545 pci_disable_msi(ioc
->pcidev
);
2549 if (ioc
->memmap
!= NULL
) {
2550 iounmap(ioc
->memmap
);
2554 pci_disable_device(ioc
->pcidev
);
2555 pci_release_selected_regions(ioc
->pcidev
, ioc
->bars
);
2557 #if defined(CONFIG_MTRR) && 0
2558 if (ioc
->mtrr_reg
> 0) {
2559 mtrr_del(ioc
->mtrr_reg
, 0, 0);
2560 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
"MTRR region de-registered\n", ioc
->name
));
2564 /* Zap the adapter lookup ptr! */
2565 list_del(&ioc
->list
);
2567 sz_last
= ioc
->alloc_total
;
2568 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
"free'd %d of %d bytes\n",
2569 ioc
->name
, sz_first
-sz_last
+(int)sizeof(*ioc
), sz_first
));
2572 ioc
->alt_ioc
->alt_ioc
= NULL
;
2577 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2579 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2580 * @ioc: Pointer to MPT adapter structure
2583 MptDisplayIocCapabilities(MPT_ADAPTER
*ioc
)
2587 printk(KERN_INFO
"%s: ", ioc
->name
);
2589 printk("%s: ", ioc
->prod_name
);
2590 printk("Capabilities={");
2592 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_INITIATOR
) {
2593 printk("Initiator");
2597 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_TARGET
) {
2598 printk("%sTarget", i
? "," : "");
2602 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
) {
2603 printk("%sLAN", i
? "," : "");
2609 * This would probably evoke more questions than it's worth
2611 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_TARGET
) {
2612 printk("%sLogBusAddr", i
? "," : "");
2620 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2622 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2623 * @ioc: Pointer to MPT_ADAPTER structure
2624 * @force: Force hard KickStart of IOC
2625 * @sleepFlag: Specifies whether the process can sleep
2628 * 1 - DIAG reset and READY
2629 * 0 - READY initially OR soft reset and READY
2630 * -1 - Any failure on KickStart
2631 * -2 - Msg Unit Reset Failed
2632 * -3 - IO Unit Reset Failed
2633 * -4 - IOC owned by a PEER
2636 MakeIocReady(MPT_ADAPTER
*ioc
, int force
, int sleepFlag
)
2641 int hard_reset_done
= 0;
2646 /* Get current [raw] IOC state */
2647 ioc_state
= mpt_GetIocState(ioc
, 0);
2648 dhsprintk(ioc
, printk(MYIOC_s_INFO_FMT
"MakeIocReady [raw] state=%08x\n", ioc
->name
, ioc_state
));
2651 * Check to see if IOC got left/stuck in doorbell handshake
2652 * grip of death. If so, hard reset the IOC.
2654 if (ioc_state
& MPI_DOORBELL_ACTIVE
) {
2656 printk(MYIOC_s_WARN_FMT
"Unexpected doorbell active!\n",
2660 /* Is it already READY? */
2661 if (!statefault
&& (ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_READY
)
2665 * Check to see if IOC is in FAULT state.
2667 if ((ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_FAULT
) {
2669 printk(MYIOC_s_WARN_FMT
"IOC is in FAULT state!!!\n",
2671 printk(MYIOC_s_WARN_FMT
" FAULT code = %04xh\n",
2672 ioc
->name
, ioc_state
& MPI_DOORBELL_DATA_MASK
);
2676 * Hmmm... Did it get left operational?
2678 if ((ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_OPERATIONAL
) {
2679 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"IOC operational unexpected\n",
2683 * If PCI Peer, exit.
2684 * Else, if no fault conditions are present, issue a MessageUnitReset
2685 * Else, fall through to KickStart case
2687 whoinit
= (ioc_state
& MPI_DOORBELL_WHO_INIT_MASK
) >> MPI_DOORBELL_WHO_INIT_SHIFT
;
2688 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
2689 "whoinit 0x%x statefault %d force %d\n",
2690 ioc
->name
, whoinit
, statefault
, force
));
2691 if (whoinit
== MPI_WHOINIT_PCI_PEER
)
2694 if ((statefault
== 0 ) && (force
== 0)) {
2695 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
)) == 0)
2702 hard_reset_done
= KickStart(ioc
, statefault
||force
, sleepFlag
);
2703 if (hard_reset_done
< 0)
2707 * Loop here waiting for IOC to come READY.
2710 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 5; /* 5 seconds */
2712 while ((ioc_state
= mpt_GetIocState(ioc
, 1)) != MPI_IOC_STATE_READY
) {
2713 if (ioc_state
== MPI_IOC_STATE_OPERATIONAL
) {
2715 * BIOS or previous driver load left IOC in OP state.
2716 * Reset messaging FIFOs.
2718 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
)) != 0) {
2719 printk(MYIOC_s_ERR_FMT
"IOC msg unit reset failed!\n", ioc
->name
);
2722 } else if (ioc_state
== MPI_IOC_STATE_RESET
) {
2724 * Something is wrong. Try to get IOC back
2727 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IO_UNIT_RESET
, sleepFlag
)) != 0) {
2728 printk(MYIOC_s_ERR_FMT
"IO unit reset failed!\n", ioc
->name
);
2735 printk(MYIOC_s_ERR_FMT
"Wait IOC_READY state timeout(%d)!\n",
2736 ioc
->name
, (int)((ii
+5)/HZ
));
2740 if (sleepFlag
== CAN_SLEEP
) {
2743 mdelay (1); /* 1 msec delay */
2748 if (statefault
< 3) {
2749 printk(MYIOC_s_INFO_FMT
"Recovered from %s\n",
2751 statefault
==1 ? "stuck handshake" : "IOC FAULT");
2754 return hard_reset_done
;
2757 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2759 * mpt_GetIocState - Get the current state of a MPT adapter.
2760 * @ioc: Pointer to MPT_ADAPTER structure
2761 * @cooked: Request raw or cooked IOC state
2763 * Returns all IOC Doorbell register bits if cooked==0, else just the
2764 * Doorbell bits in MPI_IOC_STATE_MASK.
2767 mpt_GetIocState(MPT_ADAPTER
*ioc
, int cooked
)
2772 s
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
2773 sc
= s
& MPI_IOC_STATE_MASK
;
2776 ioc
->last_state
= sc
;
2778 return cooked
? sc
: s
;
2781 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2783 * GetIocFacts - Send IOCFacts request to MPT adapter.
2784 * @ioc: Pointer to MPT_ADAPTER structure
2785 * @sleepFlag: Specifies whether the process can sleep
2786 * @reason: If recovery, only update facts.
2788 * Returns 0 for success, non-zero for failure.
2791 GetIocFacts(MPT_ADAPTER
*ioc
, int sleepFlag
, int reason
)
2793 IOCFacts_t get_facts
;
2794 IOCFactsReply_t
*facts
;
2802 /* IOC *must* NOT be in RESET state! */
2803 if (ioc
->last_state
== MPI_IOC_STATE_RESET
) {
2804 printk(MYIOC_s_ERR_FMT
"Can't get IOCFacts NOT READY! (%08x)\n",
2805 ioc
->name
, ioc
->last_state
);
2809 facts
= &ioc
->facts
;
2811 /* Destination (reply area)... */
2812 reply_sz
= sizeof(*facts
);
2813 memset(facts
, 0, reply_sz
);
2815 /* Request area (get_facts on the stack right now!) */
2816 req_sz
= sizeof(get_facts
);
2817 memset(&get_facts
, 0, req_sz
);
2819 get_facts
.Function
= MPI_FUNCTION_IOC_FACTS
;
2820 /* Assert: All other get_facts fields are zero! */
2822 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2823 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2824 ioc
->name
, req_sz
, reply_sz
));
2826 /* No non-zero fields in the get_facts request are greater than
2827 * 1 byte in size, so we can just fire it off as is.
2829 r
= mpt_handshake_req_reply_wait(ioc
, req_sz
, (u32
*)&get_facts
,
2830 reply_sz
, (u16
*)facts
, 5 /*seconds*/, sleepFlag
);
2835 * Now byte swap (GRRR) the necessary fields before any further
2836 * inspection of reply contents.
2838 * But need to do some sanity checks on MsgLength (byte) field
2839 * to make sure we don't zero IOC's req_sz!
2841 /* Did we get a valid reply? */
2842 if (facts
->MsgLength
> offsetof(IOCFactsReply_t
, RequestFrameSize
)/sizeof(u32
)) {
2843 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
2845 * If not been here, done that, save off first WhoInit value
2847 if (ioc
->FirstWhoInit
== WHOINIT_UNKNOWN
)
2848 ioc
->FirstWhoInit
= facts
->WhoInit
;
2851 facts
->MsgVersion
= le16_to_cpu(facts
->MsgVersion
);
2852 facts
->MsgContext
= le32_to_cpu(facts
->MsgContext
);
2853 facts
->IOCExceptions
= le16_to_cpu(facts
->IOCExceptions
);
2854 facts
->IOCStatus
= le16_to_cpu(facts
->IOCStatus
);
2855 facts
->IOCLogInfo
= le32_to_cpu(facts
->IOCLogInfo
);
2856 status
= le16_to_cpu(facts
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
2857 /* CHECKME! IOCStatus, IOCLogInfo */
2859 facts
->ReplyQueueDepth
= le16_to_cpu(facts
->ReplyQueueDepth
);
2860 facts
->RequestFrameSize
= le16_to_cpu(facts
->RequestFrameSize
);
2863 * FC f/w version changed between 1.1 and 1.2
2864 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2865 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2867 if (facts
->MsgVersion
< 0x0102) {
2869 * Handle old FC f/w style, convert to new...
2871 u16 oldv
= le16_to_cpu(facts
->Reserved_0101_FWVersion
);
2872 facts
->FWVersion
.Word
=
2873 ((oldv
<<12) & 0xFF000000) |
2874 ((oldv
<<8) & 0x000FFF00);
2876 facts
->FWVersion
.Word
= le32_to_cpu(facts
->FWVersion
.Word
);
2878 facts
->ProductID
= le16_to_cpu(facts
->ProductID
);
2879 if ((ioc
->facts
.ProductID
& MPI_FW_HEADER_PID_PROD_MASK
)
2880 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI
)
2881 ioc
->ir_firmware
= 1;
2882 facts
->CurrentHostMfaHighAddr
=
2883 le32_to_cpu(facts
->CurrentHostMfaHighAddr
);
2884 facts
->GlobalCredits
= le16_to_cpu(facts
->GlobalCredits
);
2885 facts
->CurrentSenseBufferHighAddr
=
2886 le32_to_cpu(facts
->CurrentSenseBufferHighAddr
);
2887 facts
->CurReplyFrameSize
=
2888 le16_to_cpu(facts
->CurReplyFrameSize
);
2889 facts
->IOCCapabilities
= le32_to_cpu(facts
->IOCCapabilities
);
2892 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2893 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2894 * to 14 in MPI-1.01.0x.
2896 if (facts
->MsgLength
>= (offsetof(IOCFactsReply_t
,FWImageSize
) + 7)/4 &&
2897 facts
->MsgVersion
> 0x0100) {
2898 facts
->FWImageSize
= le32_to_cpu(facts
->FWImageSize
);
2901 sz
= facts
->FWImageSize
;
2906 facts
->FWImageSize
= sz
;
2908 if (!facts
->RequestFrameSize
) {
2909 /* Something is wrong! */
2910 printk(MYIOC_s_ERR_FMT
"IOC reported invalid 0 request size!\n",
2915 r
= sz
= facts
->BlockSize
;
2916 vv
= ((63 / (sz
* 4)) + 1) & 0x03;
2917 ioc
->NB_for_64_byte_frame
= vv
;
2923 ioc
->NBShiftFactor
= shiftFactor
;
2924 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2925 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2926 ioc
->name
, vv
, shiftFactor
, r
));
2928 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
2930 * Set values for this IOC's request & reply frame sizes,
2931 * and request & reply queue depths...
2933 ioc
->req_sz
= min(MPT_DEFAULT_FRAME_SIZE
, facts
->RequestFrameSize
* 4);
2934 ioc
->req_depth
= min_t(int, MPT_MAX_REQ_DEPTH
, facts
->GlobalCredits
);
2935 ioc
->reply_sz
= MPT_REPLY_FRAME_SIZE
;
2936 ioc
->reply_depth
= min_t(int, MPT_DEFAULT_REPLY_DEPTH
, facts
->ReplyQueueDepth
);
2938 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"reply_sz=%3d, reply_depth=%4d\n",
2939 ioc
->name
, ioc
->reply_sz
, ioc
->reply_depth
));
2940 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"req_sz =%3d, req_depth =%4d\n",
2941 ioc
->name
, ioc
->req_sz
, ioc
->req_depth
));
2943 /* Get port facts! */
2944 if ( (r
= GetPortFacts(ioc
, 0, sleepFlag
)) != 0 )
2948 printk(MYIOC_s_ERR_FMT
2949 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2950 ioc
->name
, facts
->MsgLength
, (offsetof(IOCFactsReply_t
,
2951 RequestFrameSize
)/sizeof(u32
)));
2958 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2960 * GetPortFacts - Send PortFacts request to MPT adapter.
2961 * @ioc: Pointer to MPT_ADAPTER structure
2962 * @portnum: Port number
2963 * @sleepFlag: Specifies whether the process can sleep
2965 * Returns 0 for success, non-zero for failure.
2968 GetPortFacts(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
)
2970 PortFacts_t get_pfacts
;
2971 PortFactsReply_t
*pfacts
;
2977 /* IOC *must* NOT be in RESET state! */
2978 if (ioc
->last_state
== MPI_IOC_STATE_RESET
) {
2979 printk(MYIOC_s_ERR_FMT
"Can't get PortFacts NOT READY! (%08x)\n",
2980 ioc
->name
, ioc
->last_state
);
2984 pfacts
= &ioc
->pfacts
[portnum
];
2986 /* Destination (reply area)... */
2987 reply_sz
= sizeof(*pfacts
);
2988 memset(pfacts
, 0, reply_sz
);
2990 /* Request area (get_pfacts on the stack right now!) */
2991 req_sz
= sizeof(get_pfacts
);
2992 memset(&get_pfacts
, 0, req_sz
);
2994 get_pfacts
.Function
= MPI_FUNCTION_PORT_FACTS
;
2995 get_pfacts
.PortNumber
= portnum
;
2996 /* Assert: All other get_pfacts fields are zero! */
2998 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending get PortFacts(%d) request\n",
2999 ioc
->name
, portnum
));
3001 /* No non-zero fields in the get_pfacts request are greater than
3002 * 1 byte in size, so we can just fire it off as is.
3004 ii
= mpt_handshake_req_reply_wait(ioc
, req_sz
, (u32
*)&get_pfacts
,
3005 reply_sz
, (u16
*)pfacts
, 5 /*seconds*/, sleepFlag
);
3009 /* Did we get a valid reply? */
3011 /* Now byte swap the necessary fields in the response. */
3012 pfacts
->MsgContext
= le32_to_cpu(pfacts
->MsgContext
);
3013 pfacts
->IOCStatus
= le16_to_cpu(pfacts
->IOCStatus
);
3014 pfacts
->IOCLogInfo
= le32_to_cpu(pfacts
->IOCLogInfo
);
3015 pfacts
->MaxDevices
= le16_to_cpu(pfacts
->MaxDevices
);
3016 pfacts
->PortSCSIID
= le16_to_cpu(pfacts
->PortSCSIID
);
3017 pfacts
->ProtocolFlags
= le16_to_cpu(pfacts
->ProtocolFlags
);
3018 pfacts
->MaxPostedCmdBuffers
= le16_to_cpu(pfacts
->MaxPostedCmdBuffers
);
3019 pfacts
->MaxPersistentIDs
= le16_to_cpu(pfacts
->MaxPersistentIDs
);
3020 pfacts
->MaxLanBuckets
= le16_to_cpu(pfacts
->MaxLanBuckets
);
3022 max_id
= (ioc
->bus_type
== SAS
) ? pfacts
->PortSCSIID
:
3024 ioc
->devices_per_bus
= (max_id
> 255) ? 256 : max_id
;
3025 ioc
->number_of_buses
= (ioc
->devices_per_bus
< 256) ? 1 : max_id
/256;
3028 * Place all the devices on channels
3032 if (mpt_channel_mapping
) {
3033 ioc
->devices_per_bus
= 1;
3034 ioc
->number_of_buses
= (max_id
> 255) ? 255 : max_id
;
3040 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3042 * SendIocInit - Send IOCInit request to MPT adapter.
3043 * @ioc: Pointer to MPT_ADAPTER structure
3044 * @sleepFlag: Specifies whether the process can sleep
3046 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
3048 * Returns 0 for success, non-zero for failure.
3051 SendIocInit(MPT_ADAPTER
*ioc
, int sleepFlag
)
3054 MPIDefaultReply_t init_reply
;
3060 memset(&ioc_init
, 0, sizeof(ioc_init
));
3061 memset(&init_reply
, 0, sizeof(init_reply
));
3063 ioc_init
.WhoInit
= MPI_WHOINIT_HOST_DRIVER
;
3064 ioc_init
.Function
= MPI_FUNCTION_IOC_INIT
;
3066 /* If we are in a recovery mode and we uploaded the FW image,
3067 * then this pointer is not NULL. Skip the upload a second time.
3068 * Set this flag if cached_fw set for either IOC.
3070 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)
3074 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"upload_fw %d facts.Flags=%x\n",
3075 ioc
->name
, ioc
->upload_fw
, ioc
->facts
.Flags
));
3077 ioc_init
.MaxDevices
= (U8
)ioc
->devices_per_bus
;
3078 ioc_init
.MaxBuses
= (U8
)ioc
->number_of_buses
;
3079 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"facts.MsgVersion=%x\n",
3080 ioc
->name
, ioc
->facts
.MsgVersion
));
3081 if (ioc
->facts
.MsgVersion
>= MPI_VERSION_01_05
) {
3082 // set MsgVersion and HeaderVersion host driver was built with
3083 ioc_init
.MsgVersion
= cpu_to_le16(MPI_VERSION
);
3084 ioc_init
.HeaderVersion
= cpu_to_le16(MPI_HEADER_VERSION
);
3086 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT
) {
3087 ioc_init
.HostPageBufferSGE
= ioc
->facts
.HostPageBufferSGE
;
3088 } else if(mpt_host_page_alloc(ioc
, &ioc_init
))
3091 ioc_init
.ReplyFrameSize
= cpu_to_le16(ioc
->reply_sz
); /* in BYTES */
3093 if (sizeof(dma_addr_t
) == sizeof(u64
)) {
3094 /* Save the upper 32-bits of the request
3095 * (reply) and sense buffers.
3097 ioc_init
.HostMfaHighAddr
= cpu_to_le32((u32
)((u64
)ioc
->alloc_dma
>> 32));
3098 ioc_init
.SenseBufferHighAddr
= cpu_to_le32((u32
)((u64
)ioc
->sense_buf_pool_dma
>> 32));
3100 /* Force 32-bit addressing */
3101 ioc_init
.HostMfaHighAddr
= cpu_to_le32(0);
3102 ioc_init
.SenseBufferHighAddr
= cpu_to_le32(0);
3105 ioc
->facts
.CurrentHostMfaHighAddr
= ioc_init
.HostMfaHighAddr
;
3106 ioc
->facts
.CurrentSenseBufferHighAddr
= ioc_init
.SenseBufferHighAddr
;
3107 ioc
->facts
.MaxDevices
= ioc_init
.MaxDevices
;
3108 ioc
->facts
.MaxBuses
= ioc_init
.MaxBuses
;
3110 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending IOCInit (req @ %p)\n",
3111 ioc
->name
, &ioc_init
));
3113 r
= mpt_handshake_req_reply_wait(ioc
, sizeof(IOCInit_t
), (u32
*)&ioc_init
,
3114 sizeof(MPIDefaultReply_t
), (u16
*)&init_reply
, 10 /*seconds*/, sleepFlag
);
3116 printk(MYIOC_s_ERR_FMT
"Sending IOCInit failed(%d)!\n",ioc
->name
, r
);
3120 /* No need to byte swap the multibyte fields in the reply
3121 * since we don't even look at its contents.
3124 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending PortEnable (req @ %p)\n",
3125 ioc
->name
, &ioc_init
));
3127 if ((r
= SendPortEnable(ioc
, 0, sleepFlag
)) != 0) {
3128 printk(MYIOC_s_ERR_FMT
"Sending PortEnable failed(%d)!\n",ioc
->name
, r
);
3132 /* YIKES! SUPER IMPORTANT!!!
3133 * Poll IocState until _OPERATIONAL while IOC is doing
3134 * LoopInit and TargetDiscovery!
3137 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 60; /* 60 seconds */
3138 state
= mpt_GetIocState(ioc
, 1);
3139 while (state
!= MPI_IOC_STATE_OPERATIONAL
&& --cntdn
) {
3140 if (sleepFlag
== CAN_SLEEP
) {
3147 printk(MYIOC_s_ERR_FMT
"Wait IOC_OP state timeout(%d)!\n",
3148 ioc
->name
, (int)((count
+5)/HZ
));
3152 state
= mpt_GetIocState(ioc
, 1);
3155 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Wait IOC_OPERATIONAL state (cnt=%d)\n",
3158 ioc
->aen_event_read_flag
=0;
3162 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3164 * SendPortEnable - Send PortEnable request to MPT adapter port.
3165 * @ioc: Pointer to MPT_ADAPTER structure
3166 * @portnum: Port number to enable
3167 * @sleepFlag: Specifies whether the process can sleep
3169 * Send PortEnable to bring IOC to OPERATIONAL state.
3171 * Returns 0 for success, non-zero for failure.
3174 SendPortEnable(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
)
3176 PortEnable_t port_enable
;
3177 MPIDefaultReply_t reply_buf
;
3182 /* Destination... */
3183 reply_sz
= sizeof(MPIDefaultReply_t
);
3184 memset(&reply_buf
, 0, reply_sz
);
3186 req_sz
= sizeof(PortEnable_t
);
3187 memset(&port_enable
, 0, req_sz
);
3189 port_enable
.Function
= MPI_FUNCTION_PORT_ENABLE
;
3190 port_enable
.PortNumber
= portnum
;
3191 /* port_enable.ChainOffset = 0; */
3192 /* port_enable.MsgFlags = 0; */
3193 /* port_enable.MsgContext = 0; */
3195 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending Port(%d)Enable (req @ %p)\n",
3196 ioc
->name
, portnum
, &port_enable
));
3198 /* RAID FW may take a long time to enable
3200 if (ioc
->ir_firmware
|| ioc
->bus_type
== SAS
) {
3201 rc
= mpt_handshake_req_reply_wait(ioc
, req_sz
,
3202 (u32
*)&port_enable
, reply_sz
, (u16
*)&reply_buf
,
3203 300 /*seconds*/, sleepFlag
);
3205 rc
= mpt_handshake_req_reply_wait(ioc
, req_sz
,
3206 (u32
*)&port_enable
, reply_sz
, (u16
*)&reply_buf
,
3207 30 /*seconds*/, sleepFlag
);
3213 * mpt_alloc_fw_memory - allocate firmware memory
3214 * @ioc: Pointer to MPT_ADAPTER structure
3215 * @size: total FW bytes
3217 * If memory has already been allocated, the same (cached) value
3220 * Return 0 if successfull, or non-zero for failure
3223 mpt_alloc_fw_memory(MPT_ADAPTER
*ioc
, int size
)
3227 if (ioc
->cached_fw
) {
3228 rc
= 0; /* use already allocated memory */
3231 else if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
) {
3232 ioc
->cached_fw
= ioc
->alt_ioc
->cached_fw
; /* use alt_ioc's memory */
3233 ioc
->cached_fw_dma
= ioc
->alt_ioc
->cached_fw_dma
;
3237 ioc
->cached_fw
= pci_alloc_consistent(ioc
->pcidev
, size
, &ioc
->cached_fw_dma
);
3238 if (!ioc
->cached_fw
) {
3239 printk(MYIOC_s_ERR_FMT
"Unable to allocate memory for the cached firmware image!\n",
3243 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"FW Image @ %p[%p], sz=%d[%x] bytes\n",
3244 ioc
->name
, ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, size
, size
));
3245 ioc
->alloc_total
+= size
;
3253 * mpt_free_fw_memory - free firmware memory
3254 * @ioc: Pointer to MPT_ADAPTER structure
3256 * If alt_img is NULL, delete from ioc structure.
3257 * Else, delete a secondary image in same format.
3260 mpt_free_fw_memory(MPT_ADAPTER
*ioc
)
3264 if (!ioc
->cached_fw
)
3267 sz
= ioc
->facts
.FWImageSize
;
3268 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3269 ioc
->name
, ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, sz
, sz
));
3270 pci_free_consistent(ioc
->pcidev
, sz
, ioc
->cached_fw
, ioc
->cached_fw_dma
);
3271 ioc
->alloc_total
-= sz
;
3272 ioc
->cached_fw
= NULL
;
3275 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3277 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3278 * @ioc: Pointer to MPT_ADAPTER structure
3279 * @sleepFlag: Specifies whether the process can sleep
3281 * Returns 0 for success, >0 for handshake failure
3282 * <0 for fw upload failure.
3284 * Remark: If bound IOC and a successful FWUpload was performed
3285 * on the bound IOC, the second image is discarded
3286 * and memory is free'd. Both channels must upload to prevent
3287 * IOC from running in degraded mode.
3290 mpt_do_upload(MPT_ADAPTER
*ioc
, int sleepFlag
)
3292 u8 reply
[sizeof(FWUploadReply_t
)];
3293 FWUpload_t
*prequest
;
3294 FWUploadReply_t
*preply
;
3295 FWUploadTCSGE_t
*ptcsge
;
3298 int ii
, sz
, reply_sz
;
3301 /* If the image size is 0, we are done.
3303 if ((sz
= ioc
->facts
.FWImageSize
) == 0)
3306 if (mpt_alloc_fw_memory(ioc
, ioc
->facts
.FWImageSize
) != 0)
3309 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3310 ioc
->name
, ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, sz
, sz
));
3312 prequest
= (sleepFlag
== NO_SLEEP
) ? kzalloc(ioc
->req_sz
, GFP_ATOMIC
) :
3313 kzalloc(ioc
->req_sz
, GFP_KERNEL
);
3315 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"fw upload failed "
3316 "while allocating memory \n", ioc
->name
));
3317 mpt_free_fw_memory(ioc
);
3321 preply
= (FWUploadReply_t
*)&reply
;
3323 reply_sz
= sizeof(reply
);
3324 memset(preply
, 0, reply_sz
);
3326 prequest
->ImageType
= MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM
;
3327 prequest
->Function
= MPI_FUNCTION_FW_UPLOAD
;
3329 ptcsge
= (FWUploadTCSGE_t
*) &prequest
->SGL
;
3330 ptcsge
->DetailsLength
= 12;
3331 ptcsge
->Flags
= MPI_SGE_FLAGS_TRANSACTION_ELEMENT
;
3332 ptcsge
->ImageSize
= cpu_to_le32(sz
);
3335 sgeoffset
= sizeof(FWUpload_t
) - sizeof(SGE_MPI_UNION
) + sizeof(FWUploadTCSGE_t
);
3337 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_READ
| sz
;
3338 mpt_add_sge((char *)ptcsge
, flagsLength
, ioc
->cached_fw_dma
);
3340 sgeoffset
+= sizeof(u32
) + sizeof(dma_addr_t
);
3341 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
": Sending FW Upload (req @ %p) sgeoffset=%d \n",
3342 ioc
->name
, prequest
, sgeoffset
));
3343 DBG_DUMP_FW_REQUEST_FRAME(ioc
, (u32
*)prequest
);
3345 ii
= mpt_handshake_req_reply_wait(ioc
, sgeoffset
, (u32
*)prequest
,
3346 reply_sz
, (u16
*)preply
, 65 /*seconds*/, sleepFlag
);
3348 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
": FW Upload completed rc=%x \n", ioc
->name
, ii
));
3350 cmdStatus
= -EFAULT
;
3352 /* Handshake transfer was complete and successful.
3353 * Check the Reply Frame.
3355 int status
, transfer_sz
;
3356 status
= le16_to_cpu(preply
->IOCStatus
);
3357 if (status
== MPI_IOCSTATUS_SUCCESS
) {
3358 transfer_sz
= le32_to_cpu(preply
->ActualImageSize
);
3359 if (transfer_sz
== sz
)
3363 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
": do_upload cmdStatus=%d \n",
3364 ioc
->name
, cmdStatus
));
3369 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
": fw upload failed, freeing image \n",
3371 mpt_free_fw_memory(ioc
);
3378 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3380 * mpt_downloadboot - DownloadBoot code
3381 * @ioc: Pointer to MPT_ADAPTER structure
3382 * @pFwHeader: Pointer to firmware header info
3383 * @sleepFlag: Specifies whether the process can sleep
3385 * FwDownloadBoot requires Programmed IO access.
3387 * Returns 0 for success
3388 * -1 FW Image size is 0
3389 * -2 No valid cached_fw Pointer
3390 * <0 for fw upload failure.
3393 mpt_downloadboot(MPT_ADAPTER
*ioc
, MpiFwHeader_t
*pFwHeader
, int sleepFlag
)
3395 MpiExtImageHeader_t
*pExtImage
;
3405 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3406 ioc
->name
, pFwHeader
->ImageSize
, pFwHeader
->ImageSize
, pFwHeader
));
3408 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3409 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3410 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3411 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3412 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3413 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3415 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, (MPI_DIAG_PREVENT_IOC_BOOT
| MPI_DIAG_DISABLE_ARM
));
3418 if (sleepFlag
== CAN_SLEEP
) {
3424 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3425 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_RESET_ADAPTER
);
3427 for (count
= 0; count
< 30; count
++) {
3428 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3429 if (!(diag0val
& MPI_DIAG_RESET_ADAPTER
)) {
3430 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RESET_ADAPTER cleared, count=%d\n",
3435 if (sleepFlag
== CAN_SLEEP
) {
3442 if ( count
== 30 ) {
3443 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot failed! "
3444 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3445 ioc
->name
, diag0val
));
3449 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3450 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3451 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3452 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3453 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3454 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3456 /* Set the DiagRwEn and Disable ARM bits */
3457 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, (MPI_DIAG_RW_ENABLE
| MPI_DIAG_DISABLE_ARM
));
3459 fwSize
= (pFwHeader
->ImageSize
+ 3)/4;
3460 ptrFw
= (u32
*) pFwHeader
;
3462 /* Write the LoadStartAddress to the DiagRw Address Register
3463 * using Programmed IO
3465 if (ioc
->errata_flag_1064
)
3466 pci_enable_io_access(ioc
->pcidev
);
3468 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, pFwHeader
->LoadStartAddress
);
3469 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"LoadStart addr written 0x%x \n",
3470 ioc
->name
, pFwHeader
->LoadStartAddress
));
3472 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write FW Image: 0x%x bytes @ %p\n",
3473 ioc
->name
, fwSize
*4, ptrFw
));
3475 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, *ptrFw
++);
3478 nextImage
= pFwHeader
->NextImageHeaderOffset
;
3480 pExtImage
= (MpiExtImageHeader_t
*) ((char *)pFwHeader
+ nextImage
);
3482 load_addr
= pExtImage
->LoadStartAddress
;
3484 fwSize
= (pExtImage
->ImageSize
+ 3) >> 2;
3485 ptrFw
= (u32
*)pExtImage
;
3487 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3488 ioc
->name
, fwSize
*4, fwSize
*4, ptrFw
, load_addr
));
3489 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, load_addr
);
3492 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, *ptrFw
++);
3494 nextImage
= pExtImage
->NextImageHeaderOffset
;
3497 /* Write the IopResetVectorRegAddr */
3498 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write IopResetVector Addr=%x! \n", ioc
->name
, pFwHeader
->IopResetRegAddr
));
3499 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, pFwHeader
->IopResetRegAddr
);
3501 /* Write the IopResetVectorValue */
3502 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write IopResetVector Value=%x! \n", ioc
->name
, pFwHeader
->IopResetVectorValue
));
3503 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, pFwHeader
->IopResetVectorValue
);
3505 /* Clear the internal flash bad bit - autoincrementing register,
3506 * so must do two writes.
3508 if (ioc
->bus_type
== SPI
) {
3510 * 1030 and 1035 H/W errata, workaround to access
3511 * the ClearFlashBadSignatureBit
3513 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, 0x3F000000);
3514 diagRwData
= CHIPREG_PIO_READ32(&ioc
->pio_chip
->DiagRwData
);
3515 diagRwData
|= 0x40000000;
3516 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, 0x3F000000);
3517 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, diagRwData
);
3519 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3520 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3521 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
|
3522 MPI_DIAG_CLEAR_FLASH_BAD_SIG
);
3525 if (sleepFlag
== CAN_SLEEP
) {
3532 if (ioc
->errata_flag_1064
)
3533 pci_disable_io_access(ioc
->pcidev
);
3535 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3536 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot diag0val=%x, "
3537 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3538 ioc
->name
, diag0val
));
3539 diag0val
&= ~(MPI_DIAG_PREVENT_IOC_BOOT
| MPI_DIAG_DISABLE_ARM
| MPI_DIAG_RW_ENABLE
);
3540 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot now diag0val=%x\n",
3541 ioc
->name
, diag0val
));
3542 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
);
3544 /* Write 0xFF to reset the sequencer */
3545 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3547 if (ioc
->bus_type
== SAS
) {
3548 ioc_state
= mpt_GetIocState(ioc
, 0);
3549 if ( (GetIocFacts(ioc
, sleepFlag
,
3550 MPT_HOSTEVENT_IOC_BRINGUP
)) != 0 ) {
3551 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"GetIocFacts failed: IocState=%x\n",
3552 ioc
->name
, ioc_state
));
3557 for (count
=0; count
<HZ
*20; count
++) {
3558 if ((ioc_state
= mpt_GetIocState(ioc
, 0)) & MPI_IOC_STATE_READY
) {
3559 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3560 "downloadboot successful! (count=%d) IocState=%x\n",
3561 ioc
->name
, count
, ioc_state
));
3562 if (ioc
->bus_type
== SAS
) {
3565 if ((SendIocInit(ioc
, sleepFlag
)) != 0) {
3566 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3567 "downloadboot: SendIocInit failed\n",
3571 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3572 "downloadboot: SendIocInit successful\n",
3576 if (sleepFlag
== CAN_SLEEP
) {
3582 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3583 "downloadboot failed! IocState=%x\n",ioc
->name
, ioc_state
));
3587 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3589 * KickStart - Perform hard reset of MPT adapter.
3590 * @ioc: Pointer to MPT_ADAPTER structure
3591 * @force: Force hard reset
3592 * @sleepFlag: Specifies whether the process can sleep
3594 * This routine places MPT adapter in diagnostic mode via the
3595 * WriteSequence register, and then performs a hard reset of adapter
3596 * via the Diagnostic register.
3598 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3599 * or NO_SLEEP (interrupt thread, use mdelay)
3600 * force - 1 if doorbell active, board fault state
3601 * board operational, IOC_RECOVERY or
3602 * IOC_BRINGUP and there is an alt_ioc.
3606 * 1 - hard reset, READY
3607 * 0 - no reset due to History bit, READY
3608 * -1 - no reset due to History bit but not READY
3609 * OR reset but failed to come READY
3610 * -2 - no reset, could not enter DIAG mode
3611 * -3 - reset but bad FW bit
3614 KickStart(MPT_ADAPTER
*ioc
, int force
, int sleepFlag
)
3616 int hard_reset_done
= 0;
3620 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"KickStarting!\n", ioc
->name
));
3621 if (ioc
->bus_type
== SPI
) {
3622 /* Always issue a Msg Unit Reset first. This will clear some
3623 * SCSI bus hang conditions.
3625 SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
);
3627 if (sleepFlag
== CAN_SLEEP
) {
3634 hard_reset_done
= mpt_diag_reset(ioc
, force
, sleepFlag
);
3635 if (hard_reset_done
< 0)
3636 return hard_reset_done
;
3638 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Diagnostic reset successful!\n",
3641 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 2; /* 2 seconds */
3642 for (cnt
=0; cnt
<cntdn
; cnt
++) {
3643 ioc_state
= mpt_GetIocState(ioc
, 1);
3644 if ((ioc_state
== MPI_IOC_STATE_READY
) || (ioc_state
== MPI_IOC_STATE_OPERATIONAL
)) {
3645 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"KickStart successful! (cnt=%d)\n",
3647 return hard_reset_done
;
3649 if (sleepFlag
== CAN_SLEEP
) {
3656 dinitprintk(ioc
, printk(MYIOC_s_ERR_FMT
"Failed to come READY after reset! IocState=%x\n",
3657 ioc
->name
, mpt_GetIocState(ioc
, 0)));
3661 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3663 * mpt_diag_reset - Perform hard reset of the adapter.
3664 * @ioc: Pointer to MPT_ADAPTER structure
3665 * @ignore: Set if to honor and clear to ignore
3666 * the reset history bit
3667 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3668 * else set to NO_SLEEP (use mdelay instead)
3670 * This routine places the adapter in diagnostic mode via the
3671 * WriteSequence register and then performs a hard reset of adapter
3672 * via the Diagnostic register. Adapter should be in ready state
3673 * upon successful completion.
3675 * Returns: 1 hard reset successful
3676 * 0 no reset performed because reset history bit set
3677 * -2 enabling diagnostic mode failed
3678 * -3 diagnostic reset failed
3681 mpt_diag_reset(MPT_ADAPTER
*ioc
, int ignore
, int sleepFlag
)
3685 int hard_reset_done
= 0;
3688 MpiFwHeader_t
*cached_fw
; /* Pointer to FW */
3690 /* Clear any existing interrupts */
3691 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
3693 if (ioc
->pcidev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1078
) {
3694 drsprintk(ioc
, printk(MYIOC_s_WARN_FMT
"%s: Doorbell=%p; 1078 reset "
3695 "address=%p\n", ioc
->name
, __FUNCTION__
,
3696 &ioc
->chip
->Doorbell
, &ioc
->chip
->Reset_1078
));
3697 CHIPREG_WRITE32(&ioc
->chip
->Reset_1078
, 0x07);
3698 if (sleepFlag
== CAN_SLEEP
)
3703 for (count
= 0; count
< 60; count
++) {
3704 doorbell
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
3705 doorbell
&= MPI_IOC_STATE_MASK
;
3707 drsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3708 "looking for READY STATE: doorbell=%x"
3710 ioc
->name
, doorbell
, count
));
3711 if (doorbell
== MPI_IOC_STATE_READY
) {
3716 if (sleepFlag
== CAN_SLEEP
)
3724 /* Use "Diagnostic reset" method! (only thing available!) */
3725 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3727 if (ioc
->debug_level
& MPT_DEBUG
) {
3729 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
3730 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG1: diag0=%08x, diag1=%08x\n",
3731 ioc
->name
, diag0val
, diag1val
));
3734 /* Do the reset if we are told to ignore the reset history
3735 * or if the reset history is 0
3737 if (ignore
|| !(diag0val
& MPI_DIAG_RESET_HISTORY
)) {
3738 while ((diag0val
& MPI_DIAG_DRWE
) == 0) {
3739 /* Write magic sequence to WriteSequence register
3740 * Loop until in diagnostic mode
3742 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3743 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3744 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3745 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3746 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3747 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3750 if (sleepFlag
== CAN_SLEEP
) {
3758 printk(MYIOC_s_ERR_FMT
"Enable Diagnostic mode FAILED! (%02xh)\n",
3759 ioc
->name
, diag0val
);
3764 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3766 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Wrote magic DiagWriteEn sequence (%x)\n",
3767 ioc
->name
, diag0val
));
3770 if (ioc
->debug_level
& MPT_DEBUG
) {
3772 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
3773 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG2: diag0=%08x, diag1=%08x\n",
3774 ioc
->name
, diag0val
, diag1val
));
3777 * Disable the ARM (Bug fix)
3780 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_DISABLE_ARM
);
3784 * Now hit the reset bit in the Diagnostic register
3785 * (THE BIG HAMMER!) (Clears DRWE bit).
3787 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_RESET_ADAPTER
);
3788 hard_reset_done
= 1;
3789 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Diagnostic reset performed\n",
3793 * Call each currently registered protocol IOC reset handler
3794 * with pre-reset indication.
3795 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3796 * MptResetHandlers[] registered yet.
3802 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
3803 if (MptResetHandlers
[cb_idx
]) {
3804 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3805 "Calling IOC pre_reset handler #%d\n",
3806 ioc
->name
, cb_idx
));
3807 r
+= mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_PRE_RESET
);
3809 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3810 "Calling alt-%s pre_reset handler #%d\n",
3811 ioc
->name
, ioc
->alt_ioc
->name
, cb_idx
));
3812 r
+= mpt_signal_reset(cb_idx
, ioc
->alt_ioc
, MPT_IOC_PRE_RESET
);
3816 /* FIXME? Examine results here? */
3820 cached_fw
= (MpiFwHeader_t
*)ioc
->cached_fw
;
3821 else if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
)
3822 cached_fw
= (MpiFwHeader_t
*)ioc
->alt_ioc
->cached_fw
;
3826 /* If the DownloadBoot operation fails, the
3827 * IOC will be left unusable. This is a fatal error
3828 * case. _diag_reset will return < 0
3830 for (count
= 0; count
< 30; count
++) {
3831 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3832 if (!(diag0val
& MPI_DIAG_RESET_ADAPTER
)) {
3836 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"cached_fw: diag0val=%x count=%d\n",
3837 ioc
->name
, diag0val
, count
));
3839 if (sleepFlag
== CAN_SLEEP
) {
3845 if ((count
= mpt_downloadboot(ioc
, cached_fw
, sleepFlag
)) < 0) {
3846 printk(MYIOC_s_WARN_FMT
3847 "firmware downloadboot failure (%d)!\n", ioc
->name
, count
);
3851 /* Wait for FW to reload and for board
3852 * to go to the READY state.
3853 * Maximum wait is 60 seconds.
3854 * If fail, no error will check again
3855 * with calling program.
3857 for (count
= 0; count
< 60; count
++) {
3858 doorbell
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
3859 doorbell
&= MPI_IOC_STATE_MASK
;
3861 if (doorbell
== MPI_IOC_STATE_READY
) {
3866 if (sleepFlag
== CAN_SLEEP
) {
3875 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3876 if (ioc
->debug_level
& MPT_DEBUG
) {
3878 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
3879 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG3: diag0=%08x, diag1=%08x\n",
3880 ioc
->name
, diag0val
, diag1val
));
3883 /* Clear RESET_HISTORY bit! Place board in the
3884 * diagnostic mode to update the diag register.
3886 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3888 while ((diag0val
& MPI_DIAG_DRWE
) == 0) {
3889 /* Write magic sequence to WriteSequence register
3890 * Loop until in diagnostic mode
3892 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3893 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3894 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3895 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3896 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3897 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3900 if (sleepFlag
== CAN_SLEEP
) {
3908 printk(MYIOC_s_ERR_FMT
"Enable Diagnostic mode FAILED! (%02xh)\n",
3909 ioc
->name
, diag0val
);
3912 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3914 diag0val
&= ~MPI_DIAG_RESET_HISTORY
;
3915 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
);
3916 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3917 if (diag0val
& MPI_DIAG_RESET_HISTORY
) {
3918 printk(MYIOC_s_WARN_FMT
"ResetHistory bit failed to clear!\n",
3922 /* Disable Diagnostic Mode
3924 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFFFFFFFF);
3926 /* Check FW reload status flags.
3928 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3929 if (diag0val
& (MPI_DIAG_FLASH_BAD_SIG
| MPI_DIAG_RESET_ADAPTER
| MPI_DIAG_DISABLE_ARM
)) {
3930 printk(MYIOC_s_ERR_FMT
"Diagnostic reset FAILED! (%02xh)\n",
3931 ioc
->name
, diag0val
);
3935 if (ioc
->debug_level
& MPT_DEBUG
) {
3937 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
3938 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG4: diag0=%08x, diag1=%08x\n",
3939 ioc
->name
, diag0val
, diag1val
));
3943 * Reset flag that says we've enabled event notification
3945 ioc
->facts
.EventState
= 0;
3948 ioc
->alt_ioc
->facts
.EventState
= 0;
3950 return hard_reset_done
;
3953 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3955 * SendIocReset - Send IOCReset request to MPT adapter.
3956 * @ioc: Pointer to MPT_ADAPTER structure
3957 * @reset_type: reset type, expected values are
3958 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3959 * @sleepFlag: Specifies whether the process can sleep
3961 * Send IOCReset request to the MPT adapter.
3963 * Returns 0 for success, non-zero for failure.
3966 SendIocReset(MPT_ADAPTER
*ioc
, u8 reset_type
, int sleepFlag
)
3972 drsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending IOC reset(0x%02x)!\n",
3973 ioc
->name
, reset_type
));
3974 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, reset_type
<<MPI_DOORBELL_FUNCTION_SHIFT
);
3975 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
3978 /* FW ACK'd request, wait for READY state
3981 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 15; /* 15 seconds */
3983 while ((state
= mpt_GetIocState(ioc
, 1)) != MPI_IOC_STATE_READY
) {
3987 if (sleepFlag
!= CAN_SLEEP
)
3990 printk(MYIOC_s_ERR_FMT
"Wait IOC_READY state timeout(%d)!\n",
3991 ioc
->name
, (int)((count
+5)/HZ
));
3995 if (sleepFlag
== CAN_SLEEP
) {
3998 mdelay (1); /* 1 msec delay */
4003 * Cleanup all event stuff for this IOC; re-issue EventNotification
4004 * request if needed.
4006 if (ioc
->facts
.Function
)
4007 ioc
->facts
.EventState
= 0;
4012 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4014 * initChainBuffers - Allocate memory for and initialize chain buffers
4015 * @ioc: Pointer to MPT_ADAPTER structure
4017 * Allocates memory for and initializes chain buffers,
4018 * chain buffer control arrays and spinlock.
4021 initChainBuffers(MPT_ADAPTER
*ioc
)
4024 int sz
, ii
, num_chain
;
4025 int scale
, num_sge
, numSGE
;
4027 /* ReqToChain size must equal the req_depth
4030 if (ioc
->ReqToChain
== NULL
) {
4031 sz
= ioc
->req_depth
* sizeof(int);
4032 mem
= kmalloc(sz
, GFP_ATOMIC
);
4036 ioc
->ReqToChain
= (int *) mem
;
4037 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReqToChain alloc @ %p, sz=%d bytes\n",
4038 ioc
->name
, mem
, sz
));
4039 mem
= kmalloc(sz
, GFP_ATOMIC
);
4043 ioc
->RequestNB
= (int *) mem
;
4044 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestNB alloc @ %p, sz=%d bytes\n",
4045 ioc
->name
, mem
, sz
));
4047 for (ii
= 0; ii
< ioc
->req_depth
; ii
++) {
4048 ioc
->ReqToChain
[ii
] = MPT_HOST_NO_CHAIN
;
4051 /* ChainToChain size must equal the total number
4052 * of chain buffers to be allocated.
4055 * Calculate the number of chain buffers needed(plus 1) per I/O
4056 * then multiply the maximum number of simultaneous cmds
4058 * num_sge = num sge in request frame + last chain buffer
4059 * scale = num sge per chain buffer if no chain element
4061 scale
= ioc
->req_sz
/(sizeof(dma_addr_t
) + sizeof(u32
));
4062 if (sizeof(dma_addr_t
) == sizeof(u64
))
4063 num_sge
= scale
+ (ioc
->req_sz
- 60) / (sizeof(dma_addr_t
) + sizeof(u32
));
4065 num_sge
= 1+ scale
+ (ioc
->req_sz
- 64) / (sizeof(dma_addr_t
) + sizeof(u32
));
4067 if (sizeof(dma_addr_t
) == sizeof(u64
)) {
4068 numSGE
= (scale
- 1) * (ioc
->facts
.MaxChainDepth
-1) + scale
+
4069 (ioc
->req_sz
- 60) / (sizeof(dma_addr_t
) + sizeof(u32
));
4071 numSGE
= 1 + (scale
- 1) * (ioc
->facts
.MaxChainDepth
-1) + scale
+
4072 (ioc
->req_sz
- 64) / (sizeof(dma_addr_t
) + sizeof(u32
));
4074 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"num_sge=%d numSGE=%d\n",
4075 ioc
->name
, num_sge
, numSGE
));
4077 if ( numSGE
> MPT_SCSI_SG_DEPTH
)
4078 numSGE
= MPT_SCSI_SG_DEPTH
;
4081 while (numSGE
- num_sge
> 0) {
4083 num_sge
+= (scale
- 1);
4087 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Now numSGE=%d num_sge=%d num_chain=%d\n",
4088 ioc
->name
, numSGE
, num_sge
, num_chain
));
4090 if (ioc
->bus_type
== SPI
)
4091 num_chain
*= MPT_SCSI_CAN_QUEUE
;
4093 num_chain
*= MPT_FC_CAN_QUEUE
;
4095 ioc
->num_chain
= num_chain
;
4097 sz
= num_chain
* sizeof(int);
4098 if (ioc
->ChainToChain
== NULL
) {
4099 mem
= kmalloc(sz
, GFP_ATOMIC
);
4103 ioc
->ChainToChain
= (int *) mem
;
4104 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainToChain alloc @ %p, sz=%d bytes\n",
4105 ioc
->name
, mem
, sz
));
4107 mem
= (u8
*) ioc
->ChainToChain
;
4109 memset(mem
, 0xFF, sz
);
4113 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4115 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
4116 * @ioc: Pointer to MPT_ADAPTER structure
4118 * This routine allocates memory for the MPT reply and request frame
4119 * pools (if necessary), and primes the IOC reply FIFO with
4122 * Returns 0 for success, non-zero for failure.
4125 PrimeIocFifos(MPT_ADAPTER
*ioc
)
4128 unsigned long flags
;
4129 dma_addr_t alloc_dma
;
4131 int i
, reply_sz
, sz
, total_size
, num_chain
;
4133 /* Prime reply FIFO... */
4135 if (ioc
->reply_frames
== NULL
) {
4136 if ( (num_chain
= initChainBuffers(ioc
)) < 0)
4139 total_size
= reply_sz
= (ioc
->reply_sz
* ioc
->reply_depth
);
4140 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
4141 ioc
->name
, ioc
->reply_sz
, ioc
->reply_depth
));
4142 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffer sz=%d[%x] bytes\n",
4143 ioc
->name
, reply_sz
, reply_sz
));
4145 sz
= (ioc
->req_sz
* ioc
->req_depth
);
4146 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestBuffer sz=%d bytes, RequestDepth=%d\n",
4147 ioc
->name
, ioc
->req_sz
, ioc
->req_depth
));
4148 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestBuffer sz=%d[%x] bytes\n",
4149 ioc
->name
, sz
, sz
));
4152 sz
= num_chain
* ioc
->req_sz
; /* chain buffer pool size */
4153 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainBuffer sz=%d bytes, ChainDepth=%d\n",
4154 ioc
->name
, ioc
->req_sz
, num_chain
));
4155 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
4156 ioc
->name
, sz
, sz
, num_chain
));
4159 mem
= pci_alloc_consistent(ioc
->pcidev
, total_size
, &alloc_dma
);
4161 printk(MYIOC_s_ERR_FMT
"Unable to allocate Reply, Request, Chain Buffers!\n",
4166 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Total alloc @ %p[%p], sz=%d[%x] bytes\n",
4167 ioc
->name
, mem
, (void *)(ulong
)alloc_dma
, total_size
, total_size
));
4169 memset(mem
, 0, total_size
);
4170 ioc
->alloc_total
+= total_size
;
4172 ioc
->alloc_dma
= alloc_dma
;
4173 ioc
->alloc_sz
= total_size
;
4174 ioc
->reply_frames
= (MPT_FRAME_HDR
*) mem
;
4175 ioc
->reply_frames_low_dma
= (u32
) (alloc_dma
& 0xFFFFFFFF);
4177 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffers @ %p[%p]\n",
4178 ioc
->name
, ioc
->reply_frames
, (void *)(ulong
)alloc_dma
));
4180 alloc_dma
+= reply_sz
;
4183 /* Request FIFO - WE manage this! */
4185 ioc
->req_frames
= (MPT_FRAME_HDR
*) mem
;
4186 ioc
->req_frames_dma
= alloc_dma
;
4188 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestBuffers @ %p[%p]\n",
4189 ioc
->name
, mem
, (void *)(ulong
)alloc_dma
));
4191 ioc
->req_frames_low_dma
= (u32
) (alloc_dma
& 0xFFFFFFFF);
4193 #if defined(CONFIG_MTRR) && 0
4195 * Enable Write Combining MTRR for IOC's memory region.
4196 * (at least as much as we can; "size and base must be
4197 * multiples of 4 kiB"
4199 ioc
->mtrr_reg
= mtrr_add(ioc
->req_frames_dma
,
4201 MTRR_TYPE_WRCOMB
, 1);
4202 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"MTRR region registered (base:size=%08x:%x)\n",
4203 ioc
->name
, ioc
->req_frames_dma
, sz
));
4206 for (i
= 0; i
< ioc
->req_depth
; i
++) {
4207 alloc_dma
+= ioc
->req_sz
;
4211 ioc
->ChainBuffer
= mem
;
4212 ioc
->ChainBufferDMA
= alloc_dma
;
4214 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainBuffers @ %p(%p)\n",
4215 ioc
->name
, ioc
->ChainBuffer
, (void *)(ulong
)ioc
->ChainBufferDMA
));
4217 /* Initialize the free chain Q.
4220 INIT_LIST_HEAD(&ioc
->FreeChainQ
);
4222 /* Post the chain buffers to the FreeChainQ.
4224 mem
= (u8
*)ioc
->ChainBuffer
;
4225 for (i
=0; i
< num_chain
; i
++) {
4226 mf
= (MPT_FRAME_HDR
*) mem
;
4227 list_add_tail(&mf
->u
.frame
.linkage
.list
, &ioc
->FreeChainQ
);
4231 /* Initialize Request frames linked list
4233 alloc_dma
= ioc
->req_frames_dma
;
4234 mem
= (u8
*) ioc
->req_frames
;
4236 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
4237 INIT_LIST_HEAD(&ioc
->FreeQ
);
4238 for (i
= 0; i
< ioc
->req_depth
; i
++) {
4239 mf
= (MPT_FRAME_HDR
*) mem
;
4241 /* Queue REQUESTs *internally*! */
4242 list_add_tail(&mf
->u
.frame
.linkage
.list
, &ioc
->FreeQ
);
4246 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
4248 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
4249 ioc
->sense_buf_pool
=
4250 pci_alloc_consistent(ioc
->pcidev
, sz
, &ioc
->sense_buf_pool_dma
);
4251 if (ioc
->sense_buf_pool
== NULL
) {
4252 printk(MYIOC_s_ERR_FMT
"Unable to allocate Sense Buffers!\n",
4257 ioc
->sense_buf_low_dma
= (u32
) (ioc
->sense_buf_pool_dma
& 0xFFFFFFFF);
4258 ioc
->alloc_total
+= sz
;
4259 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SenseBuffers @ %p[%p]\n",
4260 ioc
->name
, ioc
->sense_buf_pool
, (void *)(ulong
)ioc
->sense_buf_pool_dma
));
4264 /* Post Reply frames to FIFO
4266 alloc_dma
= ioc
->alloc_dma
;
4267 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffers @ %p[%p]\n",
4268 ioc
->name
, ioc
->reply_frames
, (void *)(ulong
)alloc_dma
));
4270 for (i
= 0; i
< ioc
->reply_depth
; i
++) {
4271 /* Write each address to the IOC! */
4272 CHIPREG_WRITE32(&ioc
->chip
->ReplyFifo
, alloc_dma
);
4273 alloc_dma
+= ioc
->reply_sz
;
4279 if (ioc
->alloc
!= NULL
) {
4281 pci_free_consistent(ioc
->pcidev
,
4283 ioc
->alloc
, ioc
->alloc_dma
);
4284 ioc
->reply_frames
= NULL
;
4285 ioc
->req_frames
= NULL
;
4286 ioc
->alloc_total
-= sz
;
4288 if (ioc
->sense_buf_pool
!= NULL
) {
4289 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
4290 pci_free_consistent(ioc
->pcidev
,
4292 ioc
->sense_buf_pool
, ioc
->sense_buf_pool_dma
);
4293 ioc
->sense_buf_pool
= NULL
;
4298 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4300 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4301 * from IOC via doorbell handshake method.
4302 * @ioc: Pointer to MPT_ADAPTER structure
4303 * @reqBytes: Size of the request in bytes
4304 * @req: Pointer to MPT request frame
4305 * @replyBytes: Expected size of the reply in bytes
4306 * @u16reply: Pointer to area where reply should be written
4307 * @maxwait: Max wait time for a reply (in seconds)
4308 * @sleepFlag: Specifies whether the process can sleep
4310 * NOTES: It is the callers responsibility to byte-swap fields in the
4311 * request which are greater than 1 byte in size. It is also the
4312 * callers responsibility to byte-swap response fields which are
4313 * greater than 1 byte in size.
4315 * Returns 0 for success, non-zero for failure.
4318 mpt_handshake_req_reply_wait(MPT_ADAPTER
*ioc
, int reqBytes
, u32
*req
,
4319 int replyBytes
, u16
*u16reply
, int maxwait
, int sleepFlag
)
4321 MPIDefaultReply_t
*mptReply
;
4326 * Get ready to cache a handshake reply
4328 ioc
->hs_reply_idx
= 0;
4329 mptReply
= (MPIDefaultReply_t
*) ioc
->hs_reply
;
4330 mptReply
->MsgLength
= 0;
4333 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4334 * then tell IOC that we want to handshake a request of N words.
4335 * (WRITE u32val to Doorbell reg).
4337 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4338 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
,
4339 ((MPI_FUNCTION_HANDSHAKE
<<MPI_DOORBELL_FUNCTION_SHIFT
) |
4340 ((reqBytes
/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT
)));
4343 * Wait for IOC's doorbell handshake int
4345 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4348 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4349 ioc
->name
, reqBytes
, t
, failcnt
? " - MISSING DOORBELL HANDSHAKE!" : ""));
4351 /* Read doorbell and check for active bit */
4352 if (!(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & MPI_DOORBELL_ACTIVE
))
4356 * Clear doorbell int (WRITE 0 to IntStatus reg),
4357 * then wait for IOC to ACKnowledge that it's ready for
4358 * our handshake request.
4360 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4361 if (!failcnt
&& (t
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
4366 u8
*req_as_bytes
= (u8
*) req
;
4369 * Stuff request words via doorbell handshake,
4370 * with ACK from IOC for each.
4372 for (ii
= 0; !failcnt
&& ii
< reqBytes
/4; ii
++) {
4373 u32 word
= ((req_as_bytes
[(ii
*4) + 0] << 0) |
4374 (req_as_bytes
[(ii
*4) + 1] << 8) |
4375 (req_as_bytes
[(ii
*4) + 2] << 16) |
4376 (req_as_bytes
[(ii
*4) + 3] << 24));
4378 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, word
);
4379 if ((t
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
4383 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Handshake request frame (@%p) header\n", ioc
->name
, req
));
4384 DBG_DUMP_REQUEST_FRAME_HDR(ioc
, (u32
*)req
);
4386 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HandShake request post done, WaitCnt=%d%s\n",
4387 ioc
->name
, t
, failcnt
? " - MISSING DOORBELL ACK!" : ""));
4390 * Wait for completion of doorbell handshake reply from the IOC
4392 if (!failcnt
&& (t
= WaitForDoorbellReply(ioc
, maxwait
, sleepFlag
)) < 0)
4395 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HandShake reply count=%d%s\n",
4396 ioc
->name
, t
, failcnt
? " - MISSING DOORBELL REPLY!" : ""));
4399 * Copy out the cached reply...
4401 for (ii
=0; ii
< min(replyBytes
/2,mptReply
->MsgLength
*2); ii
++)
4402 u16reply
[ii
] = ioc
->hs_reply
[ii
];
4410 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4412 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4413 * @ioc: Pointer to MPT_ADAPTER structure
4414 * @howlong: How long to wait (in seconds)
4415 * @sleepFlag: Specifies whether the process can sleep
4417 * This routine waits (up to ~2 seconds max) for IOC doorbell
4418 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4419 * bit in its IntStatus register being clear.
4421 * Returns a negative value on failure, else wait loop count.
4424 WaitForDoorbellAck(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
4430 cntdn
= 1000 * howlong
;
4432 if (sleepFlag
== CAN_SLEEP
) {
4435 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4436 if (! (intstat
& MPI_HIS_IOP_DOORBELL_STATUS
))
4443 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4444 if (! (intstat
& MPI_HIS_IOP_DOORBELL_STATUS
))
4451 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitForDoorbell ACK (count=%d)\n",
4456 printk(MYIOC_s_ERR_FMT
"Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4457 ioc
->name
, count
, intstat
);
4461 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4463 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4464 * @ioc: Pointer to MPT_ADAPTER structure
4465 * @howlong: How long to wait (in seconds)
4466 * @sleepFlag: Specifies whether the process can sleep
4468 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4469 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4471 * Returns a negative value on failure, else wait loop count.
4474 WaitForDoorbellInt(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
4480 cntdn
= 1000 * howlong
;
4481 if (sleepFlag
== CAN_SLEEP
) {
4483 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4484 if (intstat
& MPI_HIS_DOORBELL_INTERRUPT
)
4491 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4492 if (intstat
& MPI_HIS_DOORBELL_INTERRUPT
)
4500 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4501 ioc
->name
, count
, howlong
));
4505 printk(MYIOC_s_ERR_FMT
"Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4506 ioc
->name
, count
, intstat
);
4510 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4512 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4513 * @ioc: Pointer to MPT_ADAPTER structure
4514 * @howlong: How long to wait (in seconds)
4515 * @sleepFlag: Specifies whether the process can sleep
4517 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4518 * Reply is cached to IOC private area large enough to hold a maximum
4519 * of 128 bytes of reply data.
4521 * Returns a negative value on failure, else size of reply in WORDS.
4524 WaitForDoorbellReply(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
4529 u16
*hs_reply
= ioc
->hs_reply
;
4530 volatile MPIDefaultReply_t
*mptReply
= (MPIDefaultReply_t
*) ioc
->hs_reply
;
4533 hs_reply
[0] = hs_reply
[1] = hs_reply
[7] = 0;
4536 * Get first two u16's so we can look at IOC's intended reply MsgLength
4539 if ((t
= WaitForDoorbellInt(ioc
, howlong
, sleepFlag
)) < 0) {
4542 hs_reply
[u16cnt
++] = le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4543 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4544 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4547 hs_reply
[u16cnt
++] = le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4548 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4552 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitCnt=%d First handshake reply word=%08x%s\n",
4553 ioc
->name
, t
, le32_to_cpu(*(u32
*)hs_reply
),
4554 failcnt
? " - MISSING DOORBELL HANDSHAKE!" : ""));
4557 * If no error (and IOC said MsgLength is > 0), piece together
4558 * reply 16 bits at a time.
4560 for (u16cnt
=2; !failcnt
&& u16cnt
< (2 * mptReply
->MsgLength
); u16cnt
++) {
4561 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4563 hword
= le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4564 /* don't overflow our IOC hs_reply[] buffer! */
4565 if (u16cnt
< sizeof(ioc
->hs_reply
) / sizeof(ioc
->hs_reply
[0]))
4566 hs_reply
[u16cnt
] = hword
;
4567 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4570 if (!failcnt
&& (t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4572 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4575 printk(MYIOC_s_ERR_FMT
"Handshake reply failure!\n",
4580 else if (u16cnt
!= (2 * mptReply
->MsgLength
)) {
4583 else if ((mptReply
->IOCStatus
& MPI_IOCSTATUS_MASK
) != MPI_IOCSTATUS_SUCCESS
) {
4588 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Got Handshake reply:\n", ioc
->name
));
4589 DBG_DUMP_REPLY_FRAME(ioc
, (u32
*)mptReply
);
4591 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4592 ioc
->name
, t
, u16cnt
/2));
4596 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4598 * GetLanConfigPages - Fetch LANConfig pages.
4599 * @ioc: Pointer to MPT_ADAPTER structure
4601 * Return: 0 for success
4602 * -ENOMEM if no memory available
4603 * -EPERM if not allowed due to ISR context
4604 * -EAGAIN if no msg frames currently available
4605 * -EFAULT for non-successful reply or no reply (timeout)
4608 GetLanConfigPages(MPT_ADAPTER
*ioc
)
4610 ConfigPageHeader_t hdr
;
4612 LANPage0_t
*ppage0_alloc
;
4613 dma_addr_t page0_dma
;
4614 LANPage1_t
*ppage1_alloc
;
4615 dma_addr_t page1_dma
;
4620 /* Get LAN Page 0 header */
4621 hdr
.PageVersion
= 0;
4624 hdr
.PageType
= MPI_CONFIG_PAGETYPE_LAN
;
4625 cfg
.cfghdr
.hdr
= &hdr
;
4627 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4632 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
4635 if (hdr
.PageLength
> 0) {
4636 data_sz
= hdr
.PageLength
* 4;
4637 ppage0_alloc
= (LANPage0_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page0_dma
);
4640 memset((u8
*)ppage0_alloc
, 0, data_sz
);
4641 cfg
.physAddr
= page0_dma
;
4642 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4644 if ((rc
= mpt_config(ioc
, &cfg
)) == 0) {
4646 copy_sz
= min_t(int, sizeof(LANPage0_t
), data_sz
);
4647 memcpy(&ioc
->lan_cnfg_page0
, ppage0_alloc
, copy_sz
);
4651 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage0_alloc
, page0_dma
);
4654 * Normalize endianness of structure data,
4655 * by byte-swapping all > 1 byte fields!
4664 /* Get LAN Page 1 header */
4665 hdr
.PageVersion
= 0;
4668 hdr
.PageType
= MPI_CONFIG_PAGETYPE_LAN
;
4669 cfg
.cfghdr
.hdr
= &hdr
;
4671 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4675 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
4678 if (hdr
.PageLength
== 0)
4681 data_sz
= hdr
.PageLength
* 4;
4683 ppage1_alloc
= (LANPage1_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page1_dma
);
4685 memset((u8
*)ppage1_alloc
, 0, data_sz
);
4686 cfg
.physAddr
= page1_dma
;
4687 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4689 if ((rc
= mpt_config(ioc
, &cfg
)) == 0) {
4691 copy_sz
= min_t(int, sizeof(LANPage1_t
), data_sz
);
4692 memcpy(&ioc
->lan_cnfg_page1
, ppage1_alloc
, copy_sz
);
4695 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage1_alloc
, page1_dma
);
4698 * Normalize endianness of structure data,
4699 * by byte-swapping all > 1 byte fields!
4707 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4709 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
4710 * @ioc: Pointer to MPT_ADAPTER structure
4711 * @persist_opcode: see below
4713 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4714 * devices not currently present.
4715 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4717 * NOTE: Don't use not this function during interrupt time.
4719 * Returns 0 for success, non-zero error
4722 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4724 mptbase_sas_persist_operation(MPT_ADAPTER
*ioc
, u8 persist_opcode
)
4726 SasIoUnitControlRequest_t
*sasIoUnitCntrReq
;
4727 SasIoUnitControlReply_t
*sasIoUnitCntrReply
;
4728 MPT_FRAME_HDR
*mf
= NULL
;
4729 MPIHeader_t
*mpi_hdr
;
4732 /* insure garbage is not sent to fw */
4733 switch(persist_opcode
) {
4735 case MPI_SAS_OP_CLEAR_NOT_PRESENT
:
4736 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT
:
4744 printk("%s: persist_opcode=%x\n",__FUNCTION__
, persist_opcode
);
4746 /* Get a MF for this command.
4748 if ((mf
= mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
4749 printk("%s: no msg frames!\n",__FUNCTION__
);
4753 mpi_hdr
= (MPIHeader_t
*) mf
;
4754 sasIoUnitCntrReq
= (SasIoUnitControlRequest_t
*)mf
;
4755 memset(sasIoUnitCntrReq
,0,sizeof(SasIoUnitControlRequest_t
));
4756 sasIoUnitCntrReq
->Function
= MPI_FUNCTION_SAS_IO_UNIT_CONTROL
;
4757 sasIoUnitCntrReq
->MsgContext
= mpi_hdr
->MsgContext
;
4758 sasIoUnitCntrReq
->Operation
= persist_opcode
;
4760 init_timer(&ioc
->persist_timer
);
4761 ioc
->persist_timer
.data
= (unsigned long) ioc
;
4762 ioc
->persist_timer
.function
= mpt_timer_expired
;
4763 ioc
->persist_timer
.expires
= jiffies
+ HZ
*10 /* 10 sec */;
4764 ioc
->persist_wait_done
=0;
4765 add_timer(&ioc
->persist_timer
);
4766 mpt_put_msg_frame(mpt_base_index
, ioc
, mf
);
4767 wait_event(mpt_waitq
, ioc
->persist_wait_done
);
4769 sasIoUnitCntrReply
=
4770 (SasIoUnitControlReply_t
*)ioc
->persist_reply_frame
;
4771 if (le16_to_cpu(sasIoUnitCntrReply
->IOCStatus
) != MPI_IOCSTATUS_SUCCESS
) {
4772 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4774 sasIoUnitCntrReply
->IOCStatus
,
4775 sasIoUnitCntrReply
->IOCLogInfo
);
4779 printk("%s: success\n",__FUNCTION__
);
4783 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4786 mptbase_raid_process_event_data(MPT_ADAPTER
*ioc
,
4787 MpiEventDataRaid_t
* pRaidEventData
)
4796 volume
= pRaidEventData
->VolumeID
;
4797 reason
= pRaidEventData
->ReasonCode
;
4798 disk
= pRaidEventData
->PhysDiskNum
;
4799 status
= le32_to_cpu(pRaidEventData
->SettingsStatus
);
4800 flags
= (status
>> 0) & 0xff;
4801 state
= (status
>> 8) & 0xff;
4803 if (reason
== MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
) {
4807 if ((reason
>= MPI_EVENT_RAID_RC_PHYSDISK_CREATED
&&
4808 reason
<= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
) ||
4809 (reason
== MPI_EVENT_RAID_RC_SMART_DATA
)) {
4810 printk(MYIOC_s_INFO_FMT
"RAID STATUS CHANGE for PhysDisk %d id=%d\n",
4811 ioc
->name
, disk
, volume
);
4813 printk(MYIOC_s_INFO_FMT
"RAID STATUS CHANGE for VolumeID %d\n",
4818 case MPI_EVENT_RAID_RC_VOLUME_CREATED
:
4819 printk(MYIOC_s_INFO_FMT
" volume has been created\n",
4823 case MPI_EVENT_RAID_RC_VOLUME_DELETED
:
4825 printk(MYIOC_s_INFO_FMT
" volume has been deleted\n",
4829 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED
:
4830 printk(MYIOC_s_INFO_FMT
" volume settings have been changed\n",
4834 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED
:
4835 printk(MYIOC_s_INFO_FMT
" volume is now %s%s%s%s\n",
4837 state
== MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
4839 : state
== MPI_RAIDVOL0_STATUS_STATE_DEGRADED
4841 : state
== MPI_RAIDVOL0_STATUS_STATE_FAILED
4844 flags
& MPI_RAIDVOL0_STATUS_FLAG_ENABLED
4846 flags
& MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
4847 ? ", quiesced" : "",
4848 flags
& MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
4849 ? ", resync in progress" : "" );
4852 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED
:
4853 printk(MYIOC_s_INFO_FMT
" volume membership of PhysDisk %d has changed\n",
4857 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED
:
4858 printk(MYIOC_s_INFO_FMT
" PhysDisk has been created\n",
4862 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED
:
4863 printk(MYIOC_s_INFO_FMT
" PhysDisk has been deleted\n",
4867 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED
:
4868 printk(MYIOC_s_INFO_FMT
" PhysDisk settings have been changed\n",
4872 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
:
4873 printk(MYIOC_s_INFO_FMT
" PhysDisk is now %s%s%s\n",
4875 state
== MPI_PHYSDISK0_STATUS_ONLINE
4877 : state
== MPI_PHYSDISK0_STATUS_MISSING
4879 : state
== MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
4881 : state
== MPI_PHYSDISK0_STATUS_FAILED
4883 : state
== MPI_PHYSDISK0_STATUS_INITIALIZING
4885 : state
== MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
4886 ? "offline requested"
4887 : state
== MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
4888 ? "failed requested"
4889 : state
== MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
4892 flags
& MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
4893 ? ", out of sync" : "",
4894 flags
& MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
4895 ? ", quiesced" : "" );
4898 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
:
4899 printk(MYIOC_s_INFO_FMT
" Domain Validation needed for PhysDisk %d\n",
4903 case MPI_EVENT_RAID_RC_SMART_DATA
:
4904 printk(MYIOC_s_INFO_FMT
" SMART data received, ASC/ASCQ = %02xh/%02xh\n",
4905 ioc
->name
, pRaidEventData
->ASC
, pRaidEventData
->ASCQ
);
4908 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED
:
4909 printk(MYIOC_s_INFO_FMT
" replacement of PhysDisk %d has started\n",
4915 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4917 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4918 * @ioc: Pointer to MPT_ADAPTER structure
4920 * Returns: 0 for success
4921 * -ENOMEM if no memory available
4922 * -EPERM if not allowed due to ISR context
4923 * -EAGAIN if no msg frames currently available
4924 * -EFAULT for non-successful reply or no reply (timeout)
4927 GetIoUnitPage2(MPT_ADAPTER
*ioc
)
4929 ConfigPageHeader_t hdr
;
4931 IOUnitPage2_t
*ppage_alloc
;
4932 dma_addr_t page_dma
;
4936 /* Get the page header */
4937 hdr
.PageVersion
= 0;
4940 hdr
.PageType
= MPI_CONFIG_PAGETYPE_IO_UNIT
;
4941 cfg
.cfghdr
.hdr
= &hdr
;
4943 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4948 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
4951 if (hdr
.PageLength
== 0)
4954 /* Read the config page */
4955 data_sz
= hdr
.PageLength
* 4;
4957 ppage_alloc
= (IOUnitPage2_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page_dma
);
4959 memset((u8
*)ppage_alloc
, 0, data_sz
);
4960 cfg
.physAddr
= page_dma
;
4961 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4963 /* If Good, save data */
4964 if ((rc
= mpt_config(ioc
, &cfg
)) == 0)
4965 ioc
->biosVersion
= le32_to_cpu(ppage_alloc
->BiosVersion
);
4967 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage_alloc
, page_dma
);
4973 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4975 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4976 * @ioc: Pointer to a Adapter Strucutre
4977 * @portnum: IOC port number
4979 * Return: -EFAULT if read of config page header fails
4981 * If read of SCSI Port Page 0 fails,
4982 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4983 * Adapter settings: async, narrow
4985 * If read of SCSI Port Page 2 fails,
4986 * Adapter settings valid
4987 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4992 * CHECK - what type of locking mechanisms should be used????
4995 mpt_GetScsiPortSettings(MPT_ADAPTER
*ioc
, int portnum
)
5000 ConfigPageHeader_t header
;
5006 if (!ioc
->spi_data
.nvram
) {
5009 sz
= MPT_MAX_SCSI_DEVICES
* sizeof(int);
5010 mem
= kmalloc(sz
, GFP_ATOMIC
);
5014 ioc
->spi_data
.nvram
= (int *) mem
;
5016 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SCSI device NVRAM settings @ %p, sz=%d\n",
5017 ioc
->name
, ioc
->spi_data
.nvram
, sz
));
5020 /* Invalidate NVRAM information
5022 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
5023 ioc
->spi_data
.nvram
[ii
] = MPT_HOST_NVRAM_INVALID
;
5026 /* Read SPP0 header, allocate memory, then read page.
5028 header
.PageVersion
= 0;
5029 header
.PageLength
= 0;
5030 header
.PageNumber
= 0;
5031 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_PORT
;
5032 cfg
.cfghdr
.hdr
= &header
;
5034 cfg
.pageAddr
= portnum
;
5035 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5037 cfg
.timeout
= 0; /* use default */
5038 if (mpt_config(ioc
, &cfg
) != 0)
5041 if (header
.PageLength
> 0) {
5042 pbuf
= pci_alloc_consistent(ioc
->pcidev
, header
.PageLength
* 4, &buf_dma
);
5044 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5045 cfg
.physAddr
= buf_dma
;
5046 if (mpt_config(ioc
, &cfg
) != 0) {
5047 ioc
->spi_data
.maxBusWidth
= MPT_NARROW
;
5048 ioc
->spi_data
.maxSyncOffset
= 0;
5049 ioc
->spi_data
.minSyncFactor
= MPT_ASYNC
;
5050 ioc
->spi_data
.busType
= MPT_HOST_BUS_UNKNOWN
;
5052 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5053 "Unable to read PortPage0 minSyncFactor=%x\n",
5054 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
5056 /* Save the Port Page 0 data
5058 SCSIPortPage0_t
*pPP0
= (SCSIPortPage0_t
*) pbuf
;
5059 pPP0
->Capabilities
= le32_to_cpu(pPP0
->Capabilities
);
5060 pPP0
->PhysicalInterface
= le32_to_cpu(pPP0
->PhysicalInterface
);
5062 if ( (pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_QAS
) == 0 ) {
5063 ioc
->spi_data
.noQas
|= MPT_TARGET_NO_NEGO_QAS
;
5064 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5065 "noQas due to Capabilities=%x\n",
5066 ioc
->name
, pPP0
->Capabilities
));
5068 ioc
->spi_data
.maxBusWidth
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_WIDE
? 1 : 0;
5069 data
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK
;
5071 ioc
->spi_data
.maxSyncOffset
= (u8
) (data
>> 16);
5072 data
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK
;
5073 ioc
->spi_data
.minSyncFactor
= (u8
) (data
>> 8);
5074 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5075 "PortPage0 minSyncFactor=%x\n",
5076 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
5078 ioc
->spi_data
.maxSyncOffset
= 0;
5079 ioc
->spi_data
.minSyncFactor
= MPT_ASYNC
;
5082 ioc
->spi_data
.busType
= pPP0
->PhysicalInterface
& MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK
;
5084 /* Update the minSyncFactor based on bus type.
5086 if ((ioc
->spi_data
.busType
== MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD
) ||
5087 (ioc
->spi_data
.busType
== MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE
)) {
5089 if (ioc
->spi_data
.minSyncFactor
< MPT_ULTRA
) {
5090 ioc
->spi_data
.minSyncFactor
= MPT_ULTRA
;
5091 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5092 "HVD or SE detected, minSyncFactor=%x\n",
5093 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
5098 pci_free_consistent(ioc
->pcidev
, header
.PageLength
* 4, pbuf
, buf_dma
);
5103 /* SCSI Port Page 2 - Read the header then the page.
5105 header
.PageVersion
= 0;
5106 header
.PageLength
= 0;
5107 header
.PageNumber
= 2;
5108 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_PORT
;
5109 cfg
.cfghdr
.hdr
= &header
;
5111 cfg
.pageAddr
= portnum
;
5112 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5114 if (mpt_config(ioc
, &cfg
) != 0)
5117 if (header
.PageLength
> 0) {
5118 /* Allocate memory and read SCSI Port Page 2
5120 pbuf
= pci_alloc_consistent(ioc
->pcidev
, header
.PageLength
* 4, &buf_dma
);
5122 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_NVRAM
;
5123 cfg
.physAddr
= buf_dma
;
5124 if (mpt_config(ioc
, &cfg
) != 0) {
5125 /* Nvram data is left with INVALID mark
5128 } else if (ioc
->pcidev
->vendor
== PCI_VENDOR_ID_ATTO
) {
5130 /* This is an ATTO adapter, read Page2 accordingly
5132 ATTO_SCSIPortPage2_t
*pPP2
= (ATTO_SCSIPortPage2_t
*) pbuf
;
5133 ATTODeviceInfo_t
*pdevice
= NULL
;
5136 /* Save the Port Page 2 data
5137 * (reformat into a 32bit quantity)
5139 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
5140 pdevice
= &pPP2
->DeviceSettings
[ii
];
5141 ATTOFlags
= le16_to_cpu(pdevice
->ATTOFlags
);
5144 /* Translate ATTO device flags to LSI format
5146 if (ATTOFlags
& ATTOFLAG_DISC
)
5147 data
|= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE
);
5148 if (ATTOFlags
& ATTOFLAG_ID_ENB
)
5149 data
|= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE
);
5150 if (ATTOFlags
& ATTOFLAG_LUN_ENB
)
5151 data
|= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE
);
5152 if (ATTOFlags
& ATTOFLAG_TAGGED
)
5153 data
|= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE
);
5154 if (!(ATTOFlags
& ATTOFLAG_WIDE_ENB
))
5155 data
|= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE
);
5157 data
= (data
<< 16) | (pdevice
->Period
<< 8) | 10;
5158 ioc
->spi_data
.nvram
[ii
] = data
;
5161 SCSIPortPage2_t
*pPP2
= (SCSIPortPage2_t
*) pbuf
;
5162 MpiDeviceInfo_t
*pdevice
= NULL
;
5165 * Save "Set to Avoid SCSI Bus Resets" flag
5167 ioc
->spi_data
.bus_reset
=
5168 (le32_to_cpu(pPP2
->PortFlags
) &
5169 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET
) ?
5172 /* Save the Port Page 2 data
5173 * (reformat into a 32bit quantity)
5175 data
= le32_to_cpu(pPP2
->PortFlags
) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK
;
5176 ioc
->spi_data
.PortFlags
= data
;
5177 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
5178 pdevice
= &pPP2
->DeviceSettings
[ii
];
5179 data
= (le16_to_cpu(pdevice
->DeviceFlags
) << 16) |
5180 (pdevice
->SyncFactor
<< 8) | pdevice
->Timeout
;
5181 ioc
->spi_data
.nvram
[ii
] = data
;
5185 pci_free_consistent(ioc
->pcidev
, header
.PageLength
* 4, pbuf
, buf_dma
);
5189 /* Update Adapter limits with those from NVRAM
5190 * Comment: Don't need to do this. Target performance
5191 * parameters will never exceed the adapters limits.
5197 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5199 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
5200 * @ioc: Pointer to a Adapter Strucutre
5201 * @portnum: IOC port number
5203 * Return: -EFAULT if read of config page header fails
5207 mpt_readScsiDevicePageHeaders(MPT_ADAPTER
*ioc
, int portnum
)
5210 ConfigPageHeader_t header
;
5212 /* Read the SCSI Device Page 1 header
5214 header
.PageVersion
= 0;
5215 header
.PageLength
= 0;
5216 header
.PageNumber
= 1;
5217 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_DEVICE
;
5218 cfg
.cfghdr
.hdr
= &header
;
5220 cfg
.pageAddr
= portnum
;
5221 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5224 if (mpt_config(ioc
, &cfg
) != 0)
5227 ioc
->spi_data
.sdp1version
= cfg
.cfghdr
.hdr
->PageVersion
;
5228 ioc
->spi_data
.sdp1length
= cfg
.cfghdr
.hdr
->PageLength
;
5230 header
.PageVersion
= 0;
5231 header
.PageLength
= 0;
5232 header
.PageNumber
= 0;
5233 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_DEVICE
;
5234 if (mpt_config(ioc
, &cfg
) != 0)
5237 ioc
->spi_data
.sdp0version
= cfg
.cfghdr
.hdr
->PageVersion
;
5238 ioc
->spi_data
.sdp0length
= cfg
.cfghdr
.hdr
->PageLength
;
5240 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Headers: 0: version %d length %d\n",
5241 ioc
->name
, ioc
->spi_data
.sdp0version
, ioc
->spi_data
.sdp0length
));
5243 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Headers: 1: version %d length %d\n",
5244 ioc
->name
, ioc
->spi_data
.sdp1version
, ioc
->spi_data
.sdp1length
));
5249 * mpt_inactive_raid_list_free - This clears this link list.
5250 * @ioc : pointer to per adapter structure
5253 mpt_inactive_raid_list_free(MPT_ADAPTER
*ioc
)
5255 struct inactive_raid_component_info
*component_info
, *pNext
;
5257 if (list_empty(&ioc
->raid_data
.inactive_list
))
5260 mutex_lock(&ioc
->raid_data
.inactive_list_mutex
);
5261 list_for_each_entry_safe(component_info
, pNext
,
5262 &ioc
->raid_data
.inactive_list
, list
) {
5263 list_del(&component_info
->list
);
5264 kfree(component_info
);
5266 mutex_unlock(&ioc
->raid_data
.inactive_list_mutex
);
5270 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5272 * @ioc : pointer to per adapter structure
5273 * @channel : volume channel
5274 * @id : volume target id
5277 mpt_inactive_raid_volumes(MPT_ADAPTER
*ioc
, u8 channel
, u8 id
)
5280 ConfigPageHeader_t hdr
;
5281 dma_addr_t dma_handle
;
5282 pRaidVolumePage0_t buffer
= NULL
;
5284 RaidPhysDiskPage0_t phys_disk
;
5285 struct inactive_raid_component_info
*component_info
;
5286 int handle_inactive_volumes
;
5288 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5289 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5290 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_VOLUME
;
5291 cfg
.pageAddr
= (channel
<< 8) + id
;
5292 cfg
.cfghdr
.hdr
= &hdr
;
5293 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5295 if (mpt_config(ioc
, &cfg
) != 0)
5298 if (!hdr
.PageLength
)
5301 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5307 cfg
.physAddr
= dma_handle
;
5308 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5310 if (mpt_config(ioc
, &cfg
) != 0)
5313 if (!buffer
->NumPhysDisks
)
5316 handle_inactive_volumes
=
5317 (buffer
->VolumeStatus
.Flags
& MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE
||
5318 (buffer
->VolumeStatus
.Flags
& MPI_RAIDVOL0_STATUS_FLAG_ENABLED
) == 0 ||
5319 buffer
->VolumeStatus
.State
== MPI_RAIDVOL0_STATUS_STATE_FAILED
||
5320 buffer
->VolumeStatus
.State
== MPI_RAIDVOL0_STATUS_STATE_MISSING
) ? 1 : 0;
5322 if (!handle_inactive_volumes
)
5325 mutex_lock(&ioc
->raid_data
.inactive_list_mutex
);
5326 for (i
= 0; i
< buffer
->NumPhysDisks
; i
++) {
5327 if(mpt_raid_phys_disk_pg0(ioc
,
5328 buffer
->PhysDisk
[i
].PhysDiskNum
, &phys_disk
) != 0)
5331 if ((component_info
= kmalloc(sizeof (*component_info
),
5332 GFP_KERNEL
)) == NULL
)
5335 component_info
->volumeID
= id
;
5336 component_info
->volumeBus
= channel
;
5337 component_info
->d
.PhysDiskNum
= phys_disk
.PhysDiskNum
;
5338 component_info
->d
.PhysDiskBus
= phys_disk
.PhysDiskBus
;
5339 component_info
->d
.PhysDiskID
= phys_disk
.PhysDiskID
;
5340 component_info
->d
.PhysDiskIOC
= phys_disk
.PhysDiskIOC
;
5342 list_add_tail(&component_info
->list
,
5343 &ioc
->raid_data
.inactive_list
);
5345 mutex_unlock(&ioc
->raid_data
.inactive_list_mutex
);
5349 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5354 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5355 * @ioc: Pointer to a Adapter Structure
5356 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5357 * @phys_disk: requested payload data returned
5361 * -EFAULT if read of config page header fails or data pointer not NULL
5362 * -ENOMEM if pci_alloc failed
5365 mpt_raid_phys_disk_pg0(MPT_ADAPTER
*ioc
, u8 phys_disk_num
, pRaidPhysDiskPage0_t phys_disk
)
5368 ConfigPageHeader_t hdr
;
5369 dma_addr_t dma_handle
;
5370 pRaidPhysDiskPage0_t buffer
= NULL
;
5373 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5374 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5376 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_PHYSDISK
;
5377 cfg
.cfghdr
.hdr
= &hdr
;
5379 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5381 if (mpt_config(ioc
, &cfg
) != 0) {
5386 if (!hdr
.PageLength
) {
5391 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5399 cfg
.physAddr
= dma_handle
;
5400 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5401 cfg
.pageAddr
= phys_disk_num
;
5403 if (mpt_config(ioc
, &cfg
) != 0) {
5409 memcpy(phys_disk
, buffer
, sizeof(*buffer
));
5410 phys_disk
->MaxLBA
= le32_to_cpu(buffer
->MaxLBA
);
5415 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5422 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5423 * @ioc: Pointer to a Adapter Strucutre
5424 * @portnum: IOC port number
5428 * -EFAULT if read of config page header fails or data pointer not NULL
5429 * -ENOMEM if pci_alloc failed
5432 mpt_findImVolumes(MPT_ADAPTER
*ioc
)
5436 dma_addr_t ioc2_dma
;
5438 ConfigPageHeader_t header
;
5443 if (!ioc
->ir_firmware
)
5446 /* Free the old page
5448 kfree(ioc
->raid_data
.pIocPg2
);
5449 ioc
->raid_data
.pIocPg2
= NULL
;
5450 mpt_inactive_raid_list_free(ioc
);
5452 /* Read IOCP2 header then the page.
5454 header
.PageVersion
= 0;
5455 header
.PageLength
= 0;
5456 header
.PageNumber
= 2;
5457 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
5458 cfg
.cfghdr
.hdr
= &header
;
5461 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5464 if (mpt_config(ioc
, &cfg
) != 0)
5467 if (header
.PageLength
== 0)
5470 iocpage2sz
= header
.PageLength
* 4;
5471 pIoc2
= pci_alloc_consistent(ioc
->pcidev
, iocpage2sz
, &ioc2_dma
);
5475 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5476 cfg
.physAddr
= ioc2_dma
;
5477 if (mpt_config(ioc
, &cfg
) != 0)
5480 mem
= kmalloc(iocpage2sz
, GFP_KERNEL
);
5484 memcpy(mem
, (u8
*)pIoc2
, iocpage2sz
);
5485 ioc
->raid_data
.pIocPg2
= (IOCPage2_t
*) mem
;
5487 mpt_read_ioc_pg_3(ioc
);
5489 for (i
= 0; i
< pIoc2
->NumActiveVolumes
; i
++)
5490 mpt_inactive_raid_volumes(ioc
,
5491 pIoc2
->RaidVolume
[i
].VolumeBus
,
5492 pIoc2
->RaidVolume
[i
].VolumeID
);
5495 pci_free_consistent(ioc
->pcidev
, iocpage2sz
, pIoc2
, ioc2_dma
);
5501 mpt_read_ioc_pg_3(MPT_ADAPTER
*ioc
)
5506 ConfigPageHeader_t header
;
5507 dma_addr_t ioc3_dma
;
5510 /* Free the old page
5512 kfree(ioc
->raid_data
.pIocPg3
);
5513 ioc
->raid_data
.pIocPg3
= NULL
;
5515 /* There is at least one physical disk.
5516 * Read and save IOC Page 3
5518 header
.PageVersion
= 0;
5519 header
.PageLength
= 0;
5520 header
.PageNumber
= 3;
5521 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
5522 cfg
.cfghdr
.hdr
= &header
;
5525 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5528 if (mpt_config(ioc
, &cfg
) != 0)
5531 if (header
.PageLength
== 0)
5534 /* Read Header good, alloc memory
5536 iocpage3sz
= header
.PageLength
* 4;
5537 pIoc3
= pci_alloc_consistent(ioc
->pcidev
, iocpage3sz
, &ioc3_dma
);
5541 /* Read the Page and save the data
5542 * into malloc'd memory.
5544 cfg
.physAddr
= ioc3_dma
;
5545 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5546 if (mpt_config(ioc
, &cfg
) == 0) {
5547 mem
= kmalloc(iocpage3sz
, GFP_KERNEL
);
5549 memcpy(mem
, (u8
*)pIoc3
, iocpage3sz
);
5550 ioc
->raid_data
.pIocPg3
= (IOCPage3_t
*) mem
;
5554 pci_free_consistent(ioc
->pcidev
, iocpage3sz
, pIoc3
, ioc3_dma
);
5560 mpt_read_ioc_pg_4(MPT_ADAPTER
*ioc
)
5564 ConfigPageHeader_t header
;
5565 dma_addr_t ioc4_dma
;
5568 /* Read and save IOC Page 4
5570 header
.PageVersion
= 0;
5571 header
.PageLength
= 0;
5572 header
.PageNumber
= 4;
5573 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
5574 cfg
.cfghdr
.hdr
= &header
;
5577 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5580 if (mpt_config(ioc
, &cfg
) != 0)
5583 if (header
.PageLength
== 0)
5586 if ( (pIoc4
= ioc
->spi_data
.pIocPg4
) == NULL
) {
5587 iocpage4sz
= (header
.PageLength
+ 4) * 4; /* Allow 4 additional SEP's */
5588 pIoc4
= pci_alloc_consistent(ioc
->pcidev
, iocpage4sz
, &ioc4_dma
);
5591 ioc
->alloc_total
+= iocpage4sz
;
5593 ioc4_dma
= ioc
->spi_data
.IocPg4_dma
;
5594 iocpage4sz
= ioc
->spi_data
.IocPg4Sz
;
5597 /* Read the Page into dma memory.
5599 cfg
.physAddr
= ioc4_dma
;
5600 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5601 if (mpt_config(ioc
, &cfg
) == 0) {
5602 ioc
->spi_data
.pIocPg4
= (IOCPage4_t
*) pIoc4
;
5603 ioc
->spi_data
.IocPg4_dma
= ioc4_dma
;
5604 ioc
->spi_data
.IocPg4Sz
= iocpage4sz
;
5606 pci_free_consistent(ioc
->pcidev
, iocpage4sz
, pIoc4
, ioc4_dma
);
5607 ioc
->spi_data
.pIocPg4
= NULL
;
5608 ioc
->alloc_total
-= iocpage4sz
;
5613 mpt_read_ioc_pg_1(MPT_ADAPTER
*ioc
)
5617 ConfigPageHeader_t header
;
5618 dma_addr_t ioc1_dma
;
5622 /* Check the Coalescing Timeout in IOC Page 1
5624 header
.PageVersion
= 0;
5625 header
.PageLength
= 0;
5626 header
.PageNumber
= 1;
5627 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
5628 cfg
.cfghdr
.hdr
= &header
;
5631 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5634 if (mpt_config(ioc
, &cfg
) != 0)
5637 if (header
.PageLength
== 0)
5640 /* Read Header good, alloc memory
5642 iocpage1sz
= header
.PageLength
* 4;
5643 pIoc1
= pci_alloc_consistent(ioc
->pcidev
, iocpage1sz
, &ioc1_dma
);
5647 /* Read the Page and check coalescing timeout
5649 cfg
.physAddr
= ioc1_dma
;
5650 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5651 if (mpt_config(ioc
, &cfg
) == 0) {
5653 tmp
= le32_to_cpu(pIoc1
->Flags
) & MPI_IOCPAGE1_REPLY_COALESCING
;
5654 if (tmp
== MPI_IOCPAGE1_REPLY_COALESCING
) {
5655 tmp
= le32_to_cpu(pIoc1
->CoalescingTimeout
);
5657 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Coalescing Enabled Timeout = %d\n",
5660 if (tmp
> MPT_COALESCING_TIMEOUT
) {
5661 pIoc1
->CoalescingTimeout
= cpu_to_le32(MPT_COALESCING_TIMEOUT
);
5663 /* Write NVRAM and current
5666 cfg
.action
= MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT
;
5667 if (mpt_config(ioc
, &cfg
) == 0) {
5668 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Reset Current Coalescing Timeout to = %d\n",
5669 ioc
->name
, MPT_COALESCING_TIMEOUT
));
5671 cfg
.action
= MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM
;
5672 if (mpt_config(ioc
, &cfg
) == 0) {
5673 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5674 "Reset NVRAM Coalescing Timeout to = %d\n",
5675 ioc
->name
, MPT_COALESCING_TIMEOUT
));
5677 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5678 "Reset NVRAM Coalescing Timeout Failed\n",
5683 dprintk(ioc
, printk(MYIOC_s_WARN_FMT
5684 "Reset of Current Coalescing Timeout Failed!\n",
5690 dprintk(ioc
, printk(MYIOC_s_WARN_FMT
"Coalescing Disabled\n", ioc
->name
));
5694 pci_free_consistent(ioc
->pcidev
, iocpage1sz
, pIoc1
, ioc1_dma
);
5700 mpt_get_manufacturing_pg_0(MPT_ADAPTER
*ioc
)
5703 ConfigPageHeader_t hdr
;
5705 ManufacturingPage0_t
*pbuf
= NULL
;
5707 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5708 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5710 hdr
.PageType
= MPI_CONFIG_PAGETYPE_MANUFACTURING
;
5711 cfg
.cfghdr
.hdr
= &hdr
;
5713 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5716 if (mpt_config(ioc
, &cfg
) != 0)
5719 if (!cfg
.cfghdr
.hdr
->PageLength
)
5722 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5723 pbuf
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, &buf_dma
);
5727 cfg
.physAddr
= buf_dma
;
5729 if (mpt_config(ioc
, &cfg
) != 0)
5732 memcpy(ioc
->board_name
, pbuf
->BoardName
, sizeof(ioc
->board_name
));
5733 memcpy(ioc
->board_assembly
, pbuf
->BoardAssembly
, sizeof(ioc
->board_assembly
));
5734 memcpy(ioc
->board_tracer
, pbuf
->BoardTracerNumber
, sizeof(ioc
->board_tracer
));
5739 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, pbuf
, buf_dma
);
5742 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5744 * SendEventNotification - Send EventNotification (on or off) request to adapter
5745 * @ioc: Pointer to MPT_ADAPTER structure
5746 * @EvSwitch: Event switch flags
5749 SendEventNotification(MPT_ADAPTER
*ioc
, u8 EvSwitch
)
5751 EventNotification_t
*evnp
;
5753 evnp
= (EventNotification_t
*) mpt_get_msg_frame(mpt_base_index
, ioc
);
5755 devtverboseprintk(ioc
, printk(MYIOC_s_WARN_FMT
"Unable to allocate event request frame!\n",
5759 memset(evnp
, 0, sizeof(*evnp
));
5761 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending EventNotification (%d) request %p\n", ioc
->name
, EvSwitch
, evnp
));
5763 evnp
->Function
= MPI_FUNCTION_EVENT_NOTIFICATION
;
5764 evnp
->ChainOffset
= 0;
5766 evnp
->Switch
= EvSwitch
;
5768 mpt_put_msg_frame(mpt_base_index
, ioc
, (MPT_FRAME_HDR
*)evnp
);
5773 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5775 * SendEventAck - Send EventAck request to MPT adapter.
5776 * @ioc: Pointer to MPT_ADAPTER structure
5777 * @evnp: Pointer to original EventNotification request
5780 SendEventAck(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*evnp
)
5784 if ((pAck
= (EventAck_t
*) mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
5785 dfailprintk(ioc
, printk(MYIOC_s_WARN_FMT
"%s, no msg frames!!\n",
5786 ioc
->name
,__FUNCTION__
));
5790 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending EventAck\n", ioc
->name
));
5792 pAck
->Function
= MPI_FUNCTION_EVENT_ACK
;
5793 pAck
->ChainOffset
= 0;
5794 pAck
->Reserved
[0] = pAck
->Reserved
[1] = 0;
5796 pAck
->Reserved1
[0] = pAck
->Reserved1
[1] = pAck
->Reserved1
[2] = 0;
5797 pAck
->Event
= evnp
->Event
;
5798 pAck
->EventContext
= evnp
->EventContext
;
5800 mpt_put_msg_frame(mpt_base_index
, ioc
, (MPT_FRAME_HDR
*)pAck
);
5805 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5807 * mpt_config - Generic function to issue config message
5808 * @ioc: Pointer to an adapter structure
5809 * @pCfg: Pointer to a configuration structure. Struct contains
5810 * action, page address, direction, physical address
5811 * and pointer to a configuration page header
5812 * Page header is updated.
5814 * Returns 0 for success
5815 * -EPERM if not allowed due to ISR context
5816 * -EAGAIN if no msg frames currently available
5817 * -EFAULT for non-successful reply or no reply (timeout)
5820 mpt_config(MPT_ADAPTER
*ioc
, CONFIGPARMS
*pCfg
)
5823 ConfigExtendedPageHeader_t
*pExtHdr
= NULL
;
5825 unsigned long flags
;
5830 /* Prevent calling wait_event() (below), if caller happens
5831 * to be in ISR context, because that is fatal!
5833 in_isr
= in_interrupt();
5835 dcprintk(ioc
, printk(MYIOC_s_WARN_FMT
"Config request not allowed in ISR context!\n",
5840 /* Get and Populate a free Frame
5842 if ((mf
= mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
5843 dcprintk(ioc
, printk(MYIOC_s_WARN_FMT
"mpt_config: no msg frames!\n",
5847 pReq
= (Config_t
*)mf
;
5848 pReq
->Action
= pCfg
->action
;
5850 pReq
->ChainOffset
= 0;
5851 pReq
->Function
= MPI_FUNCTION_CONFIG
;
5853 /* Assume page type is not extended and clear "reserved" fields. */
5854 pReq
->ExtPageLength
= 0;
5855 pReq
->ExtPageType
= 0;
5858 for (ii
=0; ii
< 8; ii
++)
5859 pReq
->Reserved2
[ii
] = 0;
5861 pReq
->Header
.PageVersion
= pCfg
->cfghdr
.hdr
->PageVersion
;
5862 pReq
->Header
.PageLength
= pCfg
->cfghdr
.hdr
->PageLength
;
5863 pReq
->Header
.PageNumber
= pCfg
->cfghdr
.hdr
->PageNumber
;
5864 pReq
->Header
.PageType
= (pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
);
5866 if ((pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
) == MPI_CONFIG_PAGETYPE_EXTENDED
) {
5867 pExtHdr
= (ConfigExtendedPageHeader_t
*)pCfg
->cfghdr
.ehdr
;
5868 pReq
->ExtPageLength
= cpu_to_le16(pExtHdr
->ExtPageLength
);
5869 pReq
->ExtPageType
= pExtHdr
->ExtPageType
;
5870 pReq
->Header
.PageType
= MPI_CONFIG_PAGETYPE_EXTENDED
;
5872 /* Page Length must be treated as a reserved field for the extended header. */
5873 pReq
->Header
.PageLength
= 0;
5876 pReq
->PageAddress
= cpu_to_le32(pCfg
->pageAddr
);
5878 /* Add a SGE to the config request.
5881 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_WRITE
;
5883 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_READ
;
5885 if ((pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
) == MPI_CONFIG_PAGETYPE_EXTENDED
) {
5886 flagsLength
|= pExtHdr
->ExtPageLength
* 4;
5888 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending Config request type %d, page %d and action %d\n",
5889 ioc
->name
, pReq
->ExtPageType
, pReq
->Header
.PageNumber
, pReq
->Action
));
5892 flagsLength
|= pCfg
->cfghdr
.hdr
->PageLength
* 4;
5894 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending Config request type %d, page %d and action %d\n",
5895 ioc
->name
, pReq
->Header
.PageType
, pReq
->Header
.PageNumber
, pReq
->Action
));
5898 mpt_add_sge((char *)&pReq
->PageBufferSGE
, flagsLength
, pCfg
->physAddr
);
5900 /* Append pCfg pointer to end of mf
5902 *((void **) (((u8
*) mf
) + (ioc
->req_sz
- sizeof(void *)))) = (void *) pCfg
;
5904 /* Initalize the timer
5906 init_timer(&pCfg
->timer
);
5907 pCfg
->timer
.data
= (unsigned long) ioc
;
5908 pCfg
->timer
.function
= mpt_timer_expired
;
5909 pCfg
->wait_done
= 0;
5911 /* Set the timer; ensure 10 second minimum */
5912 if (pCfg
->timeout
< 10)
5913 pCfg
->timer
.expires
= jiffies
+ HZ
*10;
5915 pCfg
->timer
.expires
= jiffies
+ HZ
*pCfg
->timeout
;
5917 /* Add to end of Q, set timer and then issue this command */
5918 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
5919 list_add_tail(&pCfg
->linkage
, &ioc
->configQ
);
5920 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
5922 add_timer(&pCfg
->timer
);
5923 mpt_put_msg_frame(mpt_base_index
, ioc
, mf
);
5924 wait_event(mpt_waitq
, pCfg
->wait_done
);
5926 /* mf has been freed - do not access */
5933 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5935 * mpt_timer_expired - Callback for timer process.
5936 * Used only internal config functionality.
5937 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5940 mpt_timer_expired(unsigned long data
)
5942 MPT_ADAPTER
*ioc
= (MPT_ADAPTER
*) data
;
5944 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mpt_timer_expired! \n", ioc
->name
));
5946 /* Perform a FW reload */
5947 if (mpt_HardResetHandler(ioc
, NO_SLEEP
) < 0)
5948 printk(MYIOC_s_WARN_FMT
"Firmware Reload FAILED!\n", ioc
->name
);
5950 /* No more processing.
5951 * Hard reset clean-up will wake up
5952 * process and free all resources.
5954 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mpt_timer_expired complete!\n", ioc
->name
));
5959 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5961 * mpt_ioc_reset - Base cleanup for hard reset
5962 * @ioc: Pointer to the adapter structure
5963 * @reset_phase: Indicates pre- or post-reset functionality
5965 * Remark: Frees resources with internally generated commands.
5968 mpt_ioc_reset(MPT_ADAPTER
*ioc
, int reset_phase
)
5971 unsigned long flags
;
5973 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5974 ": IOC %s_reset routed to MPT base driver!\n",
5975 ioc
->name
, reset_phase
==MPT_IOC_SETUP_RESET
? "setup" : (
5976 reset_phase
==MPT_IOC_PRE_RESET
? "pre" : "post")));
5978 if (reset_phase
== MPT_IOC_SETUP_RESET
) {
5980 } else if (reset_phase
== MPT_IOC_PRE_RESET
) {
5981 /* If the internal config Q is not empty -
5982 * delete timer. MF resources will be freed when
5983 * the FIFO's are primed.
5985 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
5986 list_for_each_entry(pCfg
, &ioc
->configQ
, linkage
)
5987 del_timer(&pCfg
->timer
);
5988 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
5993 /* Search the configQ for internal commands.
5994 * Flush the Q, and wake up all suspended threads.
5996 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
5997 list_for_each_entry_safe(pCfg
, pNext
, &ioc
->configQ
, linkage
) {
5998 list_del(&pCfg
->linkage
);
6000 pCfg
->status
= MPT_CONFIG_ERROR
;
6001 pCfg
->wait_done
= 1;
6002 wake_up(&mpt_waitq
);
6004 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
6007 return 1; /* currently means nothing really */
6011 #ifdef CONFIG_PROC_FS /* { */
6012 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6014 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
6016 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6018 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
6020 * Returns 0 for success, non-zero for failure.
6023 procmpt_create(void)
6025 struct proc_dir_entry
*ent
;
6027 mpt_proc_root_dir
= proc_mkdir(MPT_PROCFS_MPTBASEDIR
, NULL
);
6028 if (mpt_proc_root_dir
== NULL
)
6031 ent
= create_proc_entry("summary", S_IFREG
|S_IRUGO
, mpt_proc_root_dir
);
6033 ent
->read_proc
= procmpt_summary_read
;
6035 ent
= create_proc_entry("version", S_IFREG
|S_IRUGO
, mpt_proc_root_dir
);
6037 ent
->read_proc
= procmpt_version_read
;
6042 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6044 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
6046 * Returns 0 for success, non-zero for failure.
6049 procmpt_destroy(void)
6051 remove_proc_entry("version", mpt_proc_root_dir
);
6052 remove_proc_entry("summary", mpt_proc_root_dir
);
6053 remove_proc_entry(MPT_PROCFS_MPTBASEDIR
, NULL
);
6056 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6058 * procmpt_summary_read - Handle read request of a summary file
6059 * @buf: Pointer to area to write information
6060 * @start: Pointer to start pointer
6061 * @offset: Offset to start writing
6062 * @request: Amount of read data requested
6063 * @eof: Pointer to EOF integer
6066 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
6067 * Returns number of characters written to process performing the read.
6070 procmpt_summary_read(char *buf
, char **start
, off_t offset
, int request
, int *eof
, void *data
)
6080 mpt_print_ioc_summary(ioc
, out
, &more
, 0, 1);
6084 list_for_each_entry(ioc
, &ioc_list
, list
) {
6087 mpt_print_ioc_summary(ioc
, out
, &more
, 0, 1);
6090 if ((out
-buf
) >= request
)
6097 MPT_PROC_READ_RETURN(buf
,start
,offset
,request
,eof
,len
);
6100 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6102 * procmpt_version_read - Handle read request from /proc/mpt/version.
6103 * @buf: Pointer to area to write information
6104 * @start: Pointer to start pointer
6105 * @offset: Offset to start writing
6106 * @request: Amount of read data requested
6107 * @eof: Pointer to EOF integer
6110 * Returns number of characters written to process performing the read.
6113 procmpt_version_read(char *buf
, char **start
, off_t offset
, int request
, int *eof
, void *data
)
6116 int scsi
, fc
, sas
, lan
, ctl
, targ
, dmp
;
6120 len
= sprintf(buf
, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON
);
6121 len
+= sprintf(buf
+len
, " Fusion MPT base driver\n");
6123 scsi
= fc
= sas
= lan
= ctl
= targ
= dmp
= 0;
6124 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
6126 if (MptCallbacks
[cb_idx
]) {
6127 switch (MptDriverClass
[cb_idx
]) {
6129 if (!scsi
++) drvname
= "SPI host";
6132 if (!fc
++) drvname
= "FC host";
6135 if (!sas
++) drvname
= "SAS host";
6138 if (!lan
++) drvname
= "LAN";
6141 if (!targ
++) drvname
= "SCSI target";
6144 if (!ctl
++) drvname
= "ioctl";
6149 len
+= sprintf(buf
+len
, " Fusion MPT %s driver\n", drvname
);
6153 MPT_PROC_READ_RETURN(buf
,start
,offset
,request
,eof
,len
);
6156 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6158 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
6159 * @buf: Pointer to area to write information
6160 * @start: Pointer to start pointer
6161 * @offset: Offset to start writing
6162 * @request: Amount of read data requested
6163 * @eof: Pointer to EOF integer
6166 * Returns number of characters written to process performing the read.
6169 procmpt_iocinfo_read(char *buf
, char **start
, off_t offset
, int request
, int *eof
, void *data
)
6171 MPT_ADAPTER
*ioc
= data
;
6177 mpt_get_fw_exp_ver(expVer
, ioc
);
6179 len
= sprintf(buf
, "%s:", ioc
->name
);
6180 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)
6181 len
+= sprintf(buf
+len
, " (f/w download boot flag set)");
6182 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6183 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
6185 len
+= sprintf(buf
+len
, "\n ProductID = 0x%04x (%s)\n",
6186 ioc
->facts
.ProductID
,
6188 len
+= sprintf(buf
+len
, " FWVersion = 0x%08x%s", ioc
->facts
.FWVersion
.Word
, expVer
);
6189 if (ioc
->facts
.FWImageSize
)
6190 len
+= sprintf(buf
+len
, " (fw_size=%d)", ioc
->facts
.FWImageSize
);
6191 len
+= sprintf(buf
+len
, "\n MsgVersion = 0x%04x\n", ioc
->facts
.MsgVersion
);
6192 len
+= sprintf(buf
+len
, " FirstWhoInit = 0x%02x\n", ioc
->FirstWhoInit
);
6193 len
+= sprintf(buf
+len
, " EventState = 0x%02x\n", ioc
->facts
.EventState
);
6195 len
+= sprintf(buf
+len
, " CurrentHostMfaHighAddr = 0x%08x\n",
6196 ioc
->facts
.CurrentHostMfaHighAddr
);
6197 len
+= sprintf(buf
+len
, " CurrentSenseBufferHighAddr = 0x%08x\n",
6198 ioc
->facts
.CurrentSenseBufferHighAddr
);
6200 len
+= sprintf(buf
+len
, " MaxChainDepth = 0x%02x frames\n", ioc
->facts
.MaxChainDepth
);
6201 len
+= sprintf(buf
+len
, " MinBlockSize = 0x%02x bytes\n", 4*ioc
->facts
.BlockSize
);
6203 len
+= sprintf(buf
+len
, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6204 (void *)ioc
->req_frames
, (void *)(ulong
)ioc
->req_frames_dma
);
6206 * Rounding UP to nearest 4-kB boundary here...
6208 sz
= (ioc
->req_sz
* ioc
->req_depth
) + 128;
6209 sz
= ((sz
+ 0x1000UL
- 1UL) / 0x1000) * 0x1000;
6210 len
+= sprintf(buf
+len
, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6211 ioc
->req_sz
, ioc
->req_depth
, ioc
->req_sz
*ioc
->req_depth
, sz
);
6212 len
+= sprintf(buf
+len
, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
6213 4*ioc
->facts
.RequestFrameSize
,
6214 ioc
->facts
.GlobalCredits
);
6216 len
+= sprintf(buf
+len
, " Frames @ 0x%p (Dma @ 0x%p)\n",
6217 (void *)ioc
->alloc
, (void *)(ulong
)ioc
->alloc_dma
);
6218 sz
= (ioc
->reply_sz
* ioc
->reply_depth
) + 128;
6219 len
+= sprintf(buf
+len
, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6220 ioc
->reply_sz
, ioc
->reply_depth
, ioc
->reply_sz
*ioc
->reply_depth
, sz
);
6221 len
+= sprintf(buf
+len
, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
6222 ioc
->facts
.CurReplyFrameSize
,
6223 ioc
->facts
.ReplyQueueDepth
);
6225 len
+= sprintf(buf
+len
, " MaxDevices = %d\n",
6226 (ioc
->facts
.MaxDevices
==0) ? 255 : ioc
->facts
.MaxDevices
);
6227 len
+= sprintf(buf
+len
, " MaxBuses = %d\n", ioc
->facts
.MaxBuses
);
6230 for (p
=0; p
< ioc
->facts
.NumberOfPorts
; p
++) {
6231 len
+= sprintf(buf
+len
, " PortNumber = %d (of %d)\n",
6233 ioc
->facts
.NumberOfPorts
);
6234 if (ioc
->bus_type
== FC
) {
6235 if (ioc
->pfacts
[p
].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
) {
6236 u8
*a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
6237 len
+= sprintf(buf
+len
, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6238 a
[5], a
[4], a
[3], a
[2], a
[1], a
[0]);
6240 len
+= sprintf(buf
+len
, " WWN = %08X%08X:%08X%08X\n",
6241 ioc
->fc_port_page0
[p
].WWNN
.High
,
6242 ioc
->fc_port_page0
[p
].WWNN
.Low
,
6243 ioc
->fc_port_page0
[p
].WWPN
.High
,
6244 ioc
->fc_port_page0
[p
].WWPN
.Low
);
6248 MPT_PROC_READ_RETURN(buf
,start
,offset
,request
,eof
,len
);
6251 #endif /* CONFIG_PROC_FS } */
6253 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6255 mpt_get_fw_exp_ver(char *buf
, MPT_ADAPTER
*ioc
)
6258 if ((ioc
->facts
.FWVersion
.Word
>> 24) == 0x0E) {
6259 sprintf(buf
, " (Exp %02d%02d)",
6260 (ioc
->facts
.FWVersion
.Word
>> 16) & 0x00FF, /* Month */
6261 (ioc
->facts
.FWVersion
.Word
>> 8) & 0x1F); /* Day */
6264 if ((ioc
->facts
.FWVersion
.Word
>> 8) & 0x80)
6265 strcat(buf
, " [MDBG]");
6269 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6271 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6272 * @ioc: Pointer to MPT_ADAPTER structure
6273 * @buffer: Pointer to buffer where IOC summary info should be written
6274 * @size: Pointer to number of bytes we wrote (set by this routine)
6275 * @len: Offset at which to start writing in buffer
6276 * @showlan: Display LAN stuff?
6278 * This routine writes (english readable) ASCII text, which represents
6279 * a summary of IOC information, to a buffer.
6282 mpt_print_ioc_summary(MPT_ADAPTER
*ioc
, char *buffer
, int *size
, int len
, int showlan
)
6287 mpt_get_fw_exp_ver(expVer
, ioc
);
6290 * Shorter summary of attached ioc's...
6292 y
= sprintf(buffer
+len
, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6295 MPT_FW_REV_MAGIC_ID_STRING
, /* "FwRev=" or somesuch */
6296 ioc
->facts
.FWVersion
.Word
,
6298 ioc
->facts
.NumberOfPorts
,
6301 if (showlan
&& (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
)) {
6302 u8
*a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
6303 y
+= sprintf(buffer
+len
+y
, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6304 a
[5], a
[4], a
[3], a
[2], a
[1], a
[0]);
6307 y
+= sprintf(buffer
+len
+y
, ", IRQ=%d", ioc
->pci_irq
);
6310 y
+= sprintf(buffer
+len
+y
, " (disabled)");
6312 y
+= sprintf(buffer
+len
+y
, "\n");
6317 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6321 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6323 * mpt_HardResetHandler - Generic reset handler
6324 * @ioc: Pointer to MPT_ADAPTER structure
6325 * @sleepFlag: Indicates if sleep or schedule must be called.
6327 * Issues SCSI Task Management call based on input arg values.
6328 * If TaskMgmt fails, returns associated SCSI request.
6330 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
6331 * or a non-interrupt thread. In the former, must not call schedule().
6333 * Note: A return of -1 is a FATAL error case, as it means a
6334 * FW reload/initialization failed.
6336 * Returns 0 for SUCCESS or -1 if FAILED.
6339 mpt_HardResetHandler(MPT_ADAPTER
*ioc
, int sleepFlag
)
6342 unsigned long flags
;
6344 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HardResetHandler Entered!\n", ioc
->name
));
6346 printk(MYIOC_s_INFO_FMT
"HardResetHandler Entered!\n", ioc
->name
);
6347 printk("MF count 0x%x !\n", ioc
->mfcnt
);
6350 /* Reset the adapter. Prevent more than 1 call to
6351 * mpt_do_ioc_recovery at any instant in time.
6353 spin_lock_irqsave(&ioc
->diagLock
, flags
);
6354 if ((ioc
->diagPending
) || (ioc
->alt_ioc
&& ioc
->alt_ioc
->diagPending
)){
6355 spin_unlock_irqrestore(&ioc
->diagLock
, flags
);
6358 ioc
->diagPending
= 1;
6360 spin_unlock_irqrestore(&ioc
->diagLock
, flags
);
6362 /* FIXME: If do_ioc_recovery fails, repeat....
6365 /* The SCSI driver needs to adjust timeouts on all current
6366 * commands prior to the diagnostic reset being issued.
6367 * Prevents timeouts occurring during a diagnostic reset...very bad.
6368 * For all other protocol drivers, this is a no-op.
6374 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
6375 if (MptResetHandlers
[cb_idx
]) {
6376 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Calling IOC reset_setup handler #%d\n",
6377 ioc
->name
, cb_idx
));
6378 r
+= mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_SETUP_RESET
);
6380 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Calling alt-%s setup reset handler #%d\n",
6381 ioc
->name
, ioc
->alt_ioc
->name
, cb_idx
));
6382 r
+= mpt_signal_reset(cb_idx
, ioc
->alt_ioc
, MPT_IOC_SETUP_RESET
);
6388 if ((rc
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_RECOVER
, sleepFlag
)) != 0) {
6389 printk(MYIOC_s_WARN_FMT
"Cannot recover rc = %d!\n", ioc
->name
, rc
);
6393 ioc
->alt_ioc
->reload_fw
= 0;
6395 spin_lock_irqsave(&ioc
->diagLock
, flags
);
6396 ioc
->diagPending
= 0;
6398 ioc
->alt_ioc
->diagPending
= 0;
6399 spin_unlock_irqrestore(&ioc
->diagLock
, flags
);
6401 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HardResetHandler rc = %d!\n", ioc
->name
, rc
));
6406 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6408 EventDescriptionStr(u8 event
, u32 evData0
, char *evStr
)
6413 case MPI_EVENT_NONE
:
6416 case MPI_EVENT_LOG_DATA
:
6419 case MPI_EVENT_STATE_CHANGE
:
6420 ds
= "State Change";
6422 case MPI_EVENT_UNIT_ATTENTION
:
6423 ds
= "Unit Attention";
6425 case MPI_EVENT_IOC_BUS_RESET
:
6426 ds
= "IOC Bus Reset";
6428 case MPI_EVENT_EXT_BUS_RESET
:
6429 ds
= "External Bus Reset";
6431 case MPI_EVENT_RESCAN
:
6432 ds
= "Bus Rescan Event";
6434 case MPI_EVENT_LINK_STATUS_CHANGE
:
6435 if (evData0
== MPI_EVENT_LINK_STATUS_FAILURE
)
6436 ds
= "Link Status(FAILURE) Change";
6438 ds
= "Link Status(ACTIVE) Change";
6440 case MPI_EVENT_LOOP_STATE_CHANGE
:
6441 if (evData0
== MPI_EVENT_LOOP_STATE_CHANGE_LIP
)
6442 ds
= "Loop State(LIP) Change";
6443 else if (evData0
== MPI_EVENT_LOOP_STATE_CHANGE_LPE
)
6444 ds
= "Loop State(LPE) Change"; /* ??? */
6446 ds
= "Loop State(LPB) Change"; /* ??? */
6448 case MPI_EVENT_LOGOUT
:
6451 case MPI_EVENT_EVENT_CHANGE
:
6457 case MPI_EVENT_INTEGRATED_RAID
:
6459 u8 ReasonCode
= (u8
)(evData0
>> 16);
6460 switch (ReasonCode
) {
6461 case MPI_EVENT_RAID_RC_VOLUME_CREATED
:
6462 ds
= "Integrated Raid: Volume Created";
6464 case MPI_EVENT_RAID_RC_VOLUME_DELETED
:
6465 ds
= "Integrated Raid: Volume Deleted";
6467 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED
:
6468 ds
= "Integrated Raid: Volume Settings Changed";
6470 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED
:
6471 ds
= "Integrated Raid: Volume Status Changed";
6473 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED
:
6474 ds
= "Integrated Raid: Volume Physdisk Changed";
6476 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED
:
6477 ds
= "Integrated Raid: Physdisk Created";
6479 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED
:
6480 ds
= "Integrated Raid: Physdisk Deleted";
6482 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED
:
6483 ds
= "Integrated Raid: Physdisk Settings Changed";
6485 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
:
6486 ds
= "Integrated Raid: Physdisk Status Changed";
6488 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
:
6489 ds
= "Integrated Raid: Domain Validation Needed";
6491 case MPI_EVENT_RAID_RC_SMART_DATA
:
6492 ds
= "Integrated Raid; Smart Data";
6494 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED
:
6495 ds
= "Integrated Raid: Replace Action Started";
6498 ds
= "Integrated Raid";
6503 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE
:
6504 ds
= "SCSI Device Status Change";
6506 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE
:
6508 u8 id
= (u8
)(evData0
);
6509 u8 channel
= (u8
)(evData0
>> 8);
6510 u8 ReasonCode
= (u8
)(evData0
>> 16);
6511 switch (ReasonCode
) {
6512 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED
:
6513 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6514 "SAS Device Status Change: Added: "
6515 "id=%d channel=%d", id
, channel
);
6517 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING
:
6518 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6519 "SAS Device Status Change: Deleted: "
6520 "id=%d channel=%d", id
, channel
);
6522 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA
:
6523 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6524 "SAS Device Status Change: SMART Data: "
6525 "id=%d channel=%d", id
, channel
);
6527 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED
:
6528 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6529 "SAS Device Status Change: No Persistancy: "
6530 "id=%d channel=%d", id
, channel
);
6532 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED
:
6533 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6534 "SAS Device Status Change: Unsupported Device "
6535 "Discovered : id=%d channel=%d", id
, channel
);
6537 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET
:
6538 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6539 "SAS Device Status Change: Internal Device "
6540 "Reset : id=%d channel=%d", id
, channel
);
6542 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL
:
6543 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6544 "SAS Device Status Change: Internal Task "
6545 "Abort : id=%d channel=%d", id
, channel
);
6547 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL
:
6548 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6549 "SAS Device Status Change: Internal Abort "
6550 "Task Set : id=%d channel=%d", id
, channel
);
6552 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL
:
6553 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6554 "SAS Device Status Change: Internal Clear "
6555 "Task Set : id=%d channel=%d", id
, channel
);
6557 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL
:
6558 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6559 "SAS Device Status Change: Internal Query "
6560 "Task : id=%d channel=%d", id
, channel
);
6563 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6564 "SAS Device Status Change: Unknown: "
6565 "id=%d channel=%d", id
, channel
);
6570 case MPI_EVENT_ON_BUS_TIMER_EXPIRED
:
6571 ds
= "Bus Timer Expired";
6573 case MPI_EVENT_QUEUE_FULL
:
6575 u16 curr_depth
= (u16
)(evData0
>> 16);
6576 u8 channel
= (u8
)(evData0
>> 8);
6577 u8 id
= (u8
)(evData0
);
6579 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6580 "Queue Full: channel=%d id=%d depth=%d",
6581 channel
, id
, curr_depth
);
6584 case MPI_EVENT_SAS_SES
:
6585 ds
= "SAS SES Event";
6587 case MPI_EVENT_PERSISTENT_TABLE_FULL
:
6588 ds
= "Persistent Table Full";
6590 case MPI_EVENT_SAS_PHY_LINK_STATUS
:
6592 u8 LinkRates
= (u8
)(evData0
>> 8);
6593 u8 PhyNumber
= (u8
)(evData0
);
6594 LinkRates
= (LinkRates
& MPI_EVENT_SAS_PLS_LR_CURRENT_MASK
) >>
6595 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT
;
6596 switch (LinkRates
) {
6597 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN
:
6598 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6599 "SAS PHY Link Status: Phy=%d:"
6600 " Rate Unknown",PhyNumber
);
6602 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED
:
6603 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6604 "SAS PHY Link Status: Phy=%d:"
6605 " Phy Disabled",PhyNumber
);
6607 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION
:
6608 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6609 "SAS PHY Link Status: Phy=%d:"
6610 " Failed Speed Nego",PhyNumber
);
6612 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE
:
6613 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6614 "SAS PHY Link Status: Phy=%d:"
6615 " Sata OOB Completed",PhyNumber
);
6617 case MPI_EVENT_SAS_PLS_LR_RATE_1_5
:
6618 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6619 "SAS PHY Link Status: Phy=%d:"
6620 " Rate 1.5 Gbps",PhyNumber
);
6622 case MPI_EVENT_SAS_PLS_LR_RATE_3_0
:
6623 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6624 "SAS PHY Link Status: Phy=%d:"
6625 " Rate 3.0 Gpbs",PhyNumber
);
6628 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6629 "SAS PHY Link Status: Phy=%d", PhyNumber
);
6634 case MPI_EVENT_SAS_DISCOVERY_ERROR
:
6635 ds
= "SAS Discovery Error";
6637 case MPI_EVENT_IR_RESYNC_UPDATE
:
6639 u8 resync_complete
= (u8
)(evData0
>> 16);
6640 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6641 "IR Resync Update: Complete = %d:",resync_complete
);
6646 u8 ReasonCode
= (u8
)(evData0
>> 16);
6647 switch (ReasonCode
) {
6648 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED
:
6649 ds
= "IR2: LD State Changed";
6651 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED
:
6652 ds
= "IR2: PD State Changed";
6654 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL
:
6655 ds
= "IR2: Bad Block Table Full";
6657 case MPI_EVENT_IR2_RC_PD_INSERTED
:
6658 ds
= "IR2: PD Inserted";
6660 case MPI_EVENT_IR2_RC_PD_REMOVED
:
6661 ds
= "IR2: PD Removed";
6663 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED
:
6664 ds
= "IR2: Foreign CFG Detected";
6666 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR
:
6667 ds
= "IR2: Rebuild Medium Error";
6675 case MPI_EVENT_SAS_DISCOVERY
:
6678 ds
= "SAS Discovery: Start";
6680 ds
= "SAS Discovery: Stop";
6683 case MPI_EVENT_LOG_ENTRY_ADDED
:
6684 ds
= "SAS Log Entry Added";
6687 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE
:
6689 u8 phy_num
= (u8
)(evData0
);
6690 u8 port_num
= (u8
)(evData0
>> 8);
6691 u8 port_width
= (u8
)(evData0
>> 16);
6692 u8 primative
= (u8
)(evData0
>> 24);
6693 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6694 "SAS Broadcase Primative: phy=%d port=%d "
6695 "width=%d primative=0x%02x",
6696 phy_num
, port_num
, port_width
, primative
);
6700 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE
:
6702 u8 reason
= (u8
)(evData0
);
6703 u8 port_num
= (u8
)(evData0
>> 8);
6704 u16 handle
= le16_to_cpu(evData0
>> 16);
6706 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6707 "SAS Initiator Device Status Change: reason=0x%02x "
6708 "port=%d handle=0x%04x",
6709 reason
, port_num
, handle
);
6713 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW
:
6715 u8 max_init
= (u8
)(evData0
);
6716 u8 current_init
= (u8
)(evData0
>> 8);
6718 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6719 "SAS Initiator Device Table Overflow: max initiators=%02d "
6720 "current initators=%02d",
6721 max_init
, current_init
);
6724 case MPI_EVENT_SAS_SMP_ERROR
:
6726 u8 status
= (u8
)(evData0
);
6727 u8 port_num
= (u8
)(evData0
>> 8);
6728 u8 result
= (u8
)(evData0
>> 16);
6730 if (status
== MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID
)
6731 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6732 "SAS SMP Error: port=%d result=0x%02x",
6734 else if (status
== MPI_EVENT_SAS_SMP_CRC_ERROR
)
6735 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6736 "SAS SMP Error: port=%d : CRC Error",
6738 else if (status
== MPI_EVENT_SAS_SMP_TIMEOUT
)
6739 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6740 "SAS SMP Error: port=%d : Timeout",
6742 else if (status
== MPI_EVENT_SAS_SMP_NO_DESTINATION
)
6743 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6744 "SAS SMP Error: port=%d : No Destination",
6746 else if (status
== MPI_EVENT_SAS_SMP_BAD_DESTINATION
)
6747 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6748 "SAS SMP Error: port=%d : Bad Destination",
6751 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6752 "SAS SMP Error: port=%d : status=0x%02x",
6758 * MPT base "custom" events may be added here...
6765 strncpy(evStr
, ds
, EVENT_DESCR_STR_SZ
);
6768 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6770 * ProcessEventNotification - Route EventNotificationReply to all event handlers
6771 * @ioc: Pointer to MPT_ADAPTER structure
6772 * @pEventReply: Pointer to EventNotification reply frame
6773 * @evHandlers: Pointer to integer, number of event handlers
6775 * Routes a received EventNotificationReply to all currently registered
6777 * Returns sum of event handlers return values.
6780 ProcessEventNotification(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*pEventReply
, int *evHandlers
)
6789 char evStr
[EVENT_DESCR_STR_SZ
];
6793 * Do platform normalization of values
6795 event
= le32_to_cpu(pEventReply
->Event
) & 0xFF;
6796 // evCtx = le32_to_cpu(pEventReply->EventContext);
6797 evDataLen
= le16_to_cpu(pEventReply
->EventDataLength
);
6799 evData0
= le32_to_cpu(pEventReply
->Data
[0]);
6802 EventDescriptionStr(event
, evData0
, evStr
);
6803 devtprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"MPT event:(%02Xh) : %s\n",
6808 #ifdef CONFIG_FUSION_LOGGING
6809 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6810 ": Event data:\n", ioc
->name
));
6811 for (ii
= 0; ii
< evDataLen
; ii
++)
6812 devtverboseprintk(ioc
, printk(" %08x",
6813 le32_to_cpu(pEventReply
->Data
[ii
])));
6814 devtverboseprintk(ioc
, printk("\n"));
6818 * Do general / base driver event processing
6821 case MPI_EVENT_EVENT_CHANGE
: /* 0A */
6823 u8 evState
= evData0
& 0xFF;
6825 /* CHECKME! What if evState unexpectedly says OFF (0)? */
6827 /* Update EventState field in cached IocFacts */
6828 if (ioc
->facts
.Function
) {
6829 ioc
->facts
.EventState
= evState
;
6833 case MPI_EVENT_INTEGRATED_RAID
:
6834 mptbase_raid_process_event_data(ioc
,
6835 (MpiEventDataRaid_t
*)pEventReply
->Data
);
6842 * Should this event be logged? Events are written sequentially.
6843 * When buffer is full, start again at the top.
6845 if (ioc
->events
&& (ioc
->eventTypes
& ( 1 << event
))) {
6848 idx
= ioc
->eventContext
% MPTCTL_EVENT_LOG_SIZE
;
6850 ioc
->events
[idx
].event
= event
;
6851 ioc
->events
[idx
].eventContext
= ioc
->eventContext
;
6853 for (ii
= 0; ii
< 2; ii
++) {
6855 ioc
->events
[idx
].data
[ii
] = le32_to_cpu(pEventReply
->Data
[ii
]);
6857 ioc
->events
[idx
].data
[ii
] = 0;
6860 ioc
->eventContext
++;
6865 * Call each currently registered protocol event handler.
6867 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
6868 if (MptEvHandlers
[cb_idx
]) {
6869 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Routing Event to event handler #%d\n",
6870 ioc
->name
, cb_idx
));
6871 r
+= (*(MptEvHandlers
[cb_idx
]))(ioc
, pEventReply
);
6875 /* FIXME? Examine results here? */
6878 * If needed, send (a single) EventAck.
6880 if (pEventReply
->AckRequired
== MPI_EVENT_NOTIFICATION_ACK_REQUIRED
) {
6881 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6882 "EventAck required\n",ioc
->name
));
6883 if ((ii
= SendEventAck(ioc
, pEventReply
)) != 0) {
6884 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SendEventAck returned %d\n",
6889 *evHandlers
= handlers
;
6893 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6895 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
6896 * @ioc: Pointer to MPT_ADAPTER structure
6897 * @log_info: U32 LogInfo reply word from the IOC
6899 * Refer to lsi/mpi_log_fc.h.
6902 mpt_fc_log_info(MPT_ADAPTER
*ioc
, u32 log_info
)
6904 char *desc
= "unknown";
6906 switch (log_info
& 0xFF000000) {
6907 case MPI_IOCLOGINFO_FC_INIT_BASE
:
6908 desc
= "FCP Initiator";
6910 case MPI_IOCLOGINFO_FC_TARGET_BASE
:
6911 desc
= "FCP Target";
6913 case MPI_IOCLOGINFO_FC_LAN_BASE
:
6916 case MPI_IOCLOGINFO_FC_MSG_BASE
:
6917 desc
= "MPI Message Layer";
6919 case MPI_IOCLOGINFO_FC_LINK_BASE
:
6922 case MPI_IOCLOGINFO_FC_CTX_BASE
:
6923 desc
= "Context Manager";
6925 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET
:
6926 desc
= "Invalid Field Offset";
6928 case MPI_IOCLOGINFO_FC_STATE_CHANGE
:
6929 desc
= "State Change Info";
6933 printk(MYIOC_s_INFO_FMT
"LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
6934 ioc
->name
, log_info
, desc
, (log_info
& 0xFFFFFF));
6937 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6939 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
6940 * @ioc: Pointer to MPT_ADAPTER structure
6941 * @mr: Pointer to MPT reply frame
6942 * @log_info: U32 LogInfo word from the IOC
6944 * Refer to lsi/sp_log.h.
6947 mpt_spi_log_info(MPT_ADAPTER
*ioc
, u32 log_info
)
6949 u32 info
= log_info
& 0x00FF0000;
6950 char *desc
= "unknown";
6954 desc
= "bug! MID not found";
6955 if (ioc
->reload_fw
== 0)
6960 desc
= "Parity Error";
6964 desc
= "ASYNC Outbound Overrun";
6968 desc
= "SYNC Offset Error";
6976 desc
= "Msg In Overflow";
6984 desc
= "Outbound DMA Overrun";
6988 desc
= "Task Management";
6992 desc
= "Device Problem";
6996 desc
= "Invalid Phase Change";
7000 desc
= "Untagged Table Size";
7005 printk(MYIOC_s_INFO_FMT
"LogInfo(0x%08x): F/W: %s\n", ioc
->name
, log_info
, desc
);
7008 /* strings for sas loginfo */
7009 static char *originator_str
[] = {
7014 static char *iop_code_str
[] = {
7016 "Invalid SAS Address", /* 01h */
7018 "Invalid Page", /* 03h */
7019 "Diag Message Error", /* 04h */
7020 "Task Terminated", /* 05h */
7021 "Enclosure Management", /* 06h */
7022 "Target Mode" /* 07h */
7024 static char *pl_code_str
[] = {
7026 "Open Failure", /* 01h */
7027 "Invalid Scatter Gather List", /* 02h */
7028 "Wrong Relative Offset or Frame Length", /* 03h */
7029 "Frame Transfer Error", /* 04h */
7030 "Transmit Frame Connected Low", /* 05h */
7031 "SATA Non-NCQ RW Error Bit Set", /* 06h */
7032 "SATA Read Log Receive Data Error", /* 07h */
7033 "SATA NCQ Fail All Commands After Error", /* 08h */
7034 "SATA Error in Receive Set Device Bit FIS", /* 09h */
7035 "Receive Frame Invalid Message", /* 0Ah */
7036 "Receive Context Message Valid Error", /* 0Bh */
7037 "Receive Frame Current Frame Error", /* 0Ch */
7038 "SATA Link Down", /* 0Dh */
7039 "Discovery SATA Init W IOS", /* 0Eh */
7040 "Config Invalid Page", /* 0Fh */
7041 "Discovery SATA Init Timeout", /* 10h */
7044 "IO Not Yet Executed", /* 13h */
7045 "IO Executed", /* 14h */
7046 "Persistent Reservation Out Not Affiliation "
7048 "Open Transmit DMA Abort", /* 16h */
7049 "IO Device Missing Delay Retry", /* 17h */
7050 "IO Cancelled Due to Recieve Error", /* 18h */
7058 "Enclosure Management" /* 20h */
7060 static char *ir_code_str
[] = {
7061 "Raid Action Error", /* 00h */
7071 static char *raid_sub_code_str
[] = {
7073 "Volume Creation Failed: Data Passed too "
7075 "Volume Creation Failed: Duplicate Volumes "
7076 "Attempted", /* 02h */
7077 "Volume Creation Failed: Max Number "
7078 "Supported Volumes Exceeded", /* 03h */
7079 "Volume Creation Failed: DMA Error", /* 04h */
7080 "Volume Creation Failed: Invalid Volume Type", /* 05h */
7081 "Volume Creation Failed: Error Reading "
7082 "MFG Page 4", /* 06h */
7083 "Volume Creation Failed: Creating Internal "
7084 "Structures", /* 07h */
7093 "Activation failed: Already Active Volume", /* 10h */
7094 "Activation failed: Unsupported Volume Type", /* 11h */
7095 "Activation failed: Too Many Active Volumes", /* 12h */
7096 "Activation failed: Volume ID in Use", /* 13h */
7097 "Activation failed: Reported Failure", /* 14h */
7098 "Activation failed: Importing a Volume", /* 15h */
7109 "Phys Disk failed: Too Many Phys Disks", /* 20h */
7110 "Phys Disk failed: Data Passed too Large", /* 21h */
7111 "Phys Disk failed: DMA Error", /* 22h */
7112 "Phys Disk failed: Invalid <channel:id>", /* 23h */
7113 "Phys Disk failed: Creating Phys Disk Config "
7126 "Compatibility Error: IR Disabled", /* 30h */
7127 "Compatibility Error: Inquiry Comand Failed", /* 31h */
7128 "Compatibility Error: Device not Direct Access "
7129 "Device ", /* 32h */
7130 "Compatibility Error: Removable Device Found", /* 33h */
7131 "Compatibility Error: Device SCSI Version not "
7132 "2 or Higher", /* 34h */
7133 "Compatibility Error: SATA Device, 48 BIT LBA "
7134 "not Supported", /* 35h */
7135 "Compatibility Error: Device doesn't have "
7136 "512 Byte Block Sizes", /* 36h */
7137 "Compatibility Error: Volume Type Check Failed", /* 37h */
7138 "Compatibility Error: Volume Type is "
7139 "Unsupported by FW", /* 38h */
7140 "Compatibility Error: Disk Drive too Small for "
7141 "use in Volume", /* 39h */
7142 "Compatibility Error: Phys Disk for Create "
7143 "Volume not Found", /* 3Ah */
7144 "Compatibility Error: Too Many or too Few "
7145 "Disks for Volume Type", /* 3Bh */
7146 "Compatibility Error: Disk stripe Sizes "
7147 "Must be 64KB", /* 3Ch */
7148 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
7151 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7153 * mpt_sas_log_info - Log information returned from SAS IOC.
7154 * @ioc: Pointer to MPT_ADAPTER structure
7155 * @log_info: U32 LogInfo reply word from the IOC
7157 * Refer to lsi/mpi_log_sas.h.
7160 mpt_sas_log_info(MPT_ADAPTER
*ioc
, u32 log_info
)
7162 union loginfo_type
{
7171 union loginfo_type sas_loginfo
;
7172 char *originator_desc
= NULL
;
7173 char *code_desc
= NULL
;
7174 char *sub_code_desc
= NULL
;
7176 sas_loginfo
.loginfo
= log_info
;
7177 if ((sas_loginfo
.dw
.bus_type
!= 3 /*SAS*/) &&
7178 (sas_loginfo
.dw
.originator
< sizeof(originator_str
)/sizeof(char*)))
7181 originator_desc
= originator_str
[sas_loginfo
.dw
.originator
];
7183 switch (sas_loginfo
.dw
.originator
) {
7186 if (sas_loginfo
.dw
.code
<
7187 sizeof(iop_code_str
)/sizeof(char*))
7188 code_desc
= iop_code_str
[sas_loginfo
.dw
.code
];
7191 if (sas_loginfo
.dw
.code
<
7192 sizeof(pl_code_str
)/sizeof(char*))
7193 code_desc
= pl_code_str
[sas_loginfo
.dw
.code
];
7196 if (sas_loginfo
.dw
.code
>=
7197 sizeof(ir_code_str
)/sizeof(char*))
7199 code_desc
= ir_code_str
[sas_loginfo
.dw
.code
];
7200 if (sas_loginfo
.dw
.subcode
>=
7201 sizeof(raid_sub_code_str
)/sizeof(char*))
7203 if (sas_loginfo
.dw
.code
== 0)
7205 raid_sub_code_str
[sas_loginfo
.dw
.subcode
];
7211 if (sub_code_desc
!= NULL
)
7212 printk(MYIOC_s_INFO_FMT
7213 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7215 ioc
->name
, log_info
, originator_desc
, code_desc
,
7217 else if (code_desc
!= NULL
)
7218 printk(MYIOC_s_INFO_FMT
7219 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7220 " SubCode(0x%04x)\n",
7221 ioc
->name
, log_info
, originator_desc
, code_desc
,
7222 sas_loginfo
.dw
.subcode
);
7224 printk(MYIOC_s_INFO_FMT
7225 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
7226 " SubCode(0x%04x)\n",
7227 ioc
->name
, log_info
, originator_desc
,
7228 sas_loginfo
.dw
.code
, sas_loginfo
.dw
.subcode
);
7231 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7233 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
7234 * @ioc: Pointer to MPT_ADAPTER structure
7235 * @ioc_status: U32 IOCStatus word from IOC
7236 * @mf: Pointer to MPT request frame
7238 * Refer to lsi/mpi.h.
7241 mpt_iocstatus_info_config(MPT_ADAPTER
*ioc
, u32 ioc_status
, MPT_FRAME_HDR
*mf
)
7243 Config_t
*pReq
= (Config_t
*)mf
;
7244 char extend_desc
[EVENT_DESCR_STR_SZ
];
7249 if (pReq
->Header
.PageType
== MPI_CONFIG_PAGETYPE_EXTENDED
)
7250 page_type
= pReq
->ExtPageType
;
7252 page_type
= pReq
->Header
.PageType
;
7255 * ignore invalid page messages for GET_NEXT_HANDLE
7257 form
= le32_to_cpu(pReq
->PageAddress
);
7258 if (ioc_status
== MPI_IOCSTATUS_CONFIG_INVALID_PAGE
) {
7259 if (page_type
== MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE
||
7260 page_type
== MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER
||
7261 page_type
== MPI_CONFIG_EXTPAGETYPE_ENCLOSURE
) {
7262 if ((form
>> MPI_SAS_DEVICE_PGAD_FORM_SHIFT
) ==
7263 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE
)
7266 if (page_type
== MPI_CONFIG_PAGETYPE_FC_DEVICE
)
7267 if ((form
& MPI_FC_DEVICE_PGAD_FORM_MASK
) ==
7268 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID
)
7272 snprintf(extend_desc
, EVENT_DESCR_STR_SZ
,
7273 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
7274 page_type
, pReq
->Header
.PageNumber
, pReq
->Action
, form
);
7276 switch (ioc_status
) {
7278 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION
: /* 0x0020 */
7279 desc
= "Config Page Invalid Action";
7282 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE
: /* 0x0021 */
7283 desc
= "Config Page Invalid Type";
7286 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE
: /* 0x0022 */
7287 desc
= "Config Page Invalid Page";
7290 case MPI_IOCSTATUS_CONFIG_INVALID_DATA
: /* 0x0023 */
7291 desc
= "Config Page Invalid Data";
7294 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS
: /* 0x0024 */
7295 desc
= "Config Page No Defaults";
7298 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT
: /* 0x0025 */
7299 desc
= "Config Page Can't Commit";
7306 dreplyprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"IOCStatus(0x%04X): %s: %s\n",
7307 ioc
->name
, ioc_status
, desc
, extend_desc
));
7311 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
7312 * @ioc: Pointer to MPT_ADAPTER structure
7313 * @ioc_status: U32 IOCStatus word from IOC
7314 * @mf: Pointer to MPT request frame
7316 * Refer to lsi/mpi.h.
7319 mpt_iocstatus_info(MPT_ADAPTER
*ioc
, u32 ioc_status
, MPT_FRAME_HDR
*mf
)
7321 u32 status
= ioc_status
& MPI_IOCSTATUS_MASK
;
7326 /****************************************************************************/
7327 /* Common IOCStatus values for all replies */
7328 /****************************************************************************/
7330 case MPI_IOCSTATUS_INVALID_FUNCTION
: /* 0x0001 */
7331 desc
= "Invalid Function";
7334 case MPI_IOCSTATUS_BUSY
: /* 0x0002 */
7338 case MPI_IOCSTATUS_INVALID_SGL
: /* 0x0003 */
7339 desc
= "Invalid SGL";
7342 case MPI_IOCSTATUS_INTERNAL_ERROR
: /* 0x0004 */
7343 desc
= "Internal Error";
7346 case MPI_IOCSTATUS_RESERVED
: /* 0x0005 */
7350 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES
: /* 0x0006 */
7351 desc
= "Insufficient Resources";
7354 case MPI_IOCSTATUS_INVALID_FIELD
: /* 0x0007 */
7355 desc
= "Invalid Field";
7358 case MPI_IOCSTATUS_INVALID_STATE
: /* 0x0008 */
7359 desc
= "Invalid State";
7362 /****************************************************************************/
7363 /* Config IOCStatus values */
7364 /****************************************************************************/
7366 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION
: /* 0x0020 */
7367 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE
: /* 0x0021 */
7368 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE
: /* 0x0022 */
7369 case MPI_IOCSTATUS_CONFIG_INVALID_DATA
: /* 0x0023 */
7370 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS
: /* 0x0024 */
7371 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT
: /* 0x0025 */
7372 mpt_iocstatus_info_config(ioc
, status
, mf
);
7375 /****************************************************************************/
7376 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
7378 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
7380 /****************************************************************************/
7382 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR
: /* 0x0040 */
7383 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN
: /* 0x0045 */
7384 case MPI_IOCSTATUS_SCSI_INVALID_BUS
: /* 0x0041 */
7385 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID
: /* 0x0042 */
7386 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE
: /* 0x0043 */
7387 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN
: /* 0x0044 */
7388 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR
: /* 0x0046 */
7389 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR
: /* 0x0047 */
7390 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED
: /* 0x0048 */
7391 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH
: /* 0x0049 */
7392 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED
: /* 0x004A */
7393 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED
: /* 0x004B */
7394 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED
: /* 0x004C */
7397 /****************************************************************************/
7398 /* SCSI Target values */
7399 /****************************************************************************/
7401 case MPI_IOCSTATUS_TARGET_PRIORITY_IO
: /* 0x0060 */
7402 desc
= "Target: Priority IO";
7405 case MPI_IOCSTATUS_TARGET_INVALID_PORT
: /* 0x0061 */
7406 desc
= "Target: Invalid Port";
7409 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX
: /* 0x0062 */
7410 desc
= "Target Invalid IO Index:";
7413 case MPI_IOCSTATUS_TARGET_ABORTED
: /* 0x0063 */
7414 desc
= "Target: Aborted";
7417 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE
: /* 0x0064 */
7418 desc
= "Target: No Conn Retryable";
7421 case MPI_IOCSTATUS_TARGET_NO_CONNECTION
: /* 0x0065 */
7422 desc
= "Target: No Connection";
7425 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH
: /* 0x006A */
7426 desc
= "Target: Transfer Count Mismatch";
7429 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT
: /* 0x006B */
7430 desc
= "Target: STS Data not Sent";
7433 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR
: /* 0x006D */
7434 desc
= "Target: Data Offset Error";
7437 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA
: /* 0x006E */
7438 desc
= "Target: Too Much Write Data";
7441 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT
: /* 0x006F */
7442 desc
= "Target: IU Too Short";
7445 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT
: /* 0x0070 */
7446 desc
= "Target: ACK NAK Timeout";
7449 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED
: /* 0x0071 */
7450 desc
= "Target: Nak Received";
7453 /****************************************************************************/
7454 /* Fibre Channel Direct Access values */
7455 /****************************************************************************/
7457 case MPI_IOCSTATUS_FC_ABORTED
: /* 0x0066 */
7458 desc
= "FC: Aborted";
7461 case MPI_IOCSTATUS_FC_RX_ID_INVALID
: /* 0x0067 */
7462 desc
= "FC: RX ID Invalid";
7465 case MPI_IOCSTATUS_FC_DID_INVALID
: /* 0x0068 */
7466 desc
= "FC: DID Invalid";
7469 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT
: /* 0x0069 */
7470 desc
= "FC: Node Logged Out";
7473 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED
: /* 0x006C */
7474 desc
= "FC: Exchange Canceled";
7477 /****************************************************************************/
7479 /****************************************************************************/
7481 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND
: /* 0x0080 */
7482 desc
= "LAN: Device not Found";
7485 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE
: /* 0x0081 */
7486 desc
= "LAN: Device Failure";
7489 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR
: /* 0x0082 */
7490 desc
= "LAN: Transmit Error";
7493 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED
: /* 0x0083 */
7494 desc
= "LAN: Transmit Aborted";
7497 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR
: /* 0x0084 */
7498 desc
= "LAN: Receive Error";
7501 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED
: /* 0x0085 */
7502 desc
= "LAN: Receive Aborted";
7505 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET
: /* 0x0086 */
7506 desc
= "LAN: Partial Packet";
7509 case MPI_IOCSTATUS_LAN_CANCELED
: /* 0x0087 */
7510 desc
= "LAN: Canceled";
7513 /****************************************************************************/
7514 /* Serial Attached SCSI values */
7515 /****************************************************************************/
7517 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED
: /* 0x0090 */
7518 desc
= "SAS: SMP Request Failed";
7521 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN
: /* 0x0090 */
7522 desc
= "SAS: SMP Data Overrun";
7533 dreplyprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"IOCStatus(0x%04X): %s\n",
7534 ioc
->name
, status
, desc
));
7537 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7538 EXPORT_SYMBOL(mpt_attach
);
7539 EXPORT_SYMBOL(mpt_detach
);
7541 EXPORT_SYMBOL(mpt_resume
);
7542 EXPORT_SYMBOL(mpt_suspend
);
7544 EXPORT_SYMBOL(ioc_list
);
7545 EXPORT_SYMBOL(mpt_register
);
7546 EXPORT_SYMBOL(mpt_deregister
);
7547 EXPORT_SYMBOL(mpt_event_register
);
7548 EXPORT_SYMBOL(mpt_event_deregister
);
7549 EXPORT_SYMBOL(mpt_reset_register
);
7550 EXPORT_SYMBOL(mpt_reset_deregister
);
7551 EXPORT_SYMBOL(mpt_device_driver_register
);
7552 EXPORT_SYMBOL(mpt_device_driver_deregister
);
7553 EXPORT_SYMBOL(mpt_get_msg_frame
);
7554 EXPORT_SYMBOL(mpt_put_msg_frame
);
7555 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri
);
7556 EXPORT_SYMBOL(mpt_free_msg_frame
);
7557 EXPORT_SYMBOL(mpt_add_sge
);
7558 EXPORT_SYMBOL(mpt_send_handshake_request
);
7559 EXPORT_SYMBOL(mpt_verify_adapter
);
7560 EXPORT_SYMBOL(mpt_GetIocState
);
7561 EXPORT_SYMBOL(mpt_print_ioc_summary
);
7562 EXPORT_SYMBOL(mpt_HardResetHandler
);
7563 EXPORT_SYMBOL(mpt_config
);
7564 EXPORT_SYMBOL(mpt_findImVolumes
);
7565 EXPORT_SYMBOL(mpt_alloc_fw_memory
);
7566 EXPORT_SYMBOL(mpt_free_fw_memory
);
7567 EXPORT_SYMBOL(mptbase_sas_persist_operation
);
7568 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0
);
7570 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7572 * fusion_init - Fusion MPT base driver initialization routine.
7574 * Returns 0 for success, non-zero for failure.
7581 show_mptmod_ver(my_NAME
, my_VERSION
);
7582 printk(KERN_INFO COPYRIGHT
"\n");
7584 for (cb_idx
= 0; cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
; cb_idx
++) {
7585 MptCallbacks
[cb_idx
] = NULL
;
7586 MptDriverClass
[cb_idx
] = MPTUNKNOWN_DRIVER
;
7587 MptEvHandlers
[cb_idx
] = NULL
;
7588 MptResetHandlers
[cb_idx
] = NULL
;
7591 /* Register ourselves (mptbase) in order to facilitate
7592 * EventNotification handling.
7594 mpt_base_index
= mpt_register(mpt_base_reply
, MPTBASE_DRIVER
);
7596 /* Register for hard reset handling callbacks.
7598 mpt_reset_register(mpt_base_index
, mpt_ioc_reset
);
7600 #ifdef CONFIG_PROC_FS
7601 (void) procmpt_create();
7606 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7608 * fusion_exit - Perform driver unload cleanup.
7610 * This routine frees all resources associated with each MPT adapter
7611 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
7617 mpt_reset_deregister(mpt_base_index
);
7619 #ifdef CONFIG_PROC_FS
7624 module_init(fusion_init
);
7625 module_exit(fusion_exit
);