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
);
83 static int mpt_msi_enable_spi
;
84 module_param(mpt_msi_enable_spi
, int, 0);
85 MODULE_PARM_DESC(mpt_msi_enable_spi
, " Enable MSI Support for SPI \
86 controllers (default=0)");
88 static int mpt_msi_enable_fc
;
89 module_param(mpt_msi_enable_fc
, int, 0);
90 MODULE_PARM_DESC(mpt_msi_enable_fc
, " Enable MSI Support for FC \
91 controllers (default=0)");
93 static int mpt_msi_enable_sas
;
94 module_param(mpt_msi_enable_sas
, int, 0);
95 MODULE_PARM_DESC(mpt_msi_enable_sas
, " Enable MSI Support for SAS \
96 controllers (default=0)");
99 static int mpt_channel_mapping
;
100 module_param(mpt_channel_mapping
, int, 0);
101 MODULE_PARM_DESC(mpt_channel_mapping
, " Mapping id's to channels (default=0)");
103 static int mpt_debug_level
;
104 static int mpt_set_debug_level(const char *val
, struct kernel_param
*kp
);
105 module_param_call(mpt_debug_level
, mpt_set_debug_level
, param_get_int
,
106 &mpt_debug_level
, 0600);
107 MODULE_PARM_DESC(mpt_debug_level
, " debug level - refer to mptdebug.h \
110 int mpt_fwfault_debug
;
111 EXPORT_SYMBOL(mpt_fwfault_debug
);
112 module_param_call(mpt_fwfault_debug
, param_set_int
, param_get_int
,
113 &mpt_fwfault_debug
, 0600);
114 MODULE_PARM_DESC(mpt_fwfault_debug
, "Enable detection of Firmware fault"
115 " and halt Firmware on fault - (default=0)");
120 static int mfcounter
= 0;
121 #define PRINT_MF_COUNT 20000
124 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
129 #define WHOINIT_UNKNOWN 0xAA
131 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
135 /* Adapter link list */
137 /* Callback lookup table */
138 static MPT_CALLBACK MptCallbacks
[MPT_MAX_PROTOCOL_DRIVERS
];
139 /* Protocol driver class lookup table */
140 static int MptDriverClass
[MPT_MAX_PROTOCOL_DRIVERS
];
141 /* Event handler lookup table */
142 static MPT_EVHANDLER MptEvHandlers
[MPT_MAX_PROTOCOL_DRIVERS
];
143 /* Reset handler lookup table */
144 static MPT_RESETHANDLER MptResetHandlers
[MPT_MAX_PROTOCOL_DRIVERS
];
145 static struct mpt_pci_driver
*MptDeviceDriverHandlers
[MPT_MAX_PROTOCOL_DRIVERS
];
147 #ifdef CONFIG_PROC_FS
148 static struct proc_dir_entry
*mpt_proc_root_dir
;
152 * Driver Callback Index's
154 static u8 mpt_base_index
= MPT_MAX_PROTOCOL_DRIVERS
;
155 static u8 last_drv_idx
;
157 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
161 static irqreturn_t
mpt_interrupt(int irq
, void *bus_id
);
162 static int mptbase_reply(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*req
,
163 MPT_FRAME_HDR
*reply
);
164 static int mpt_handshake_req_reply_wait(MPT_ADAPTER
*ioc
, int reqBytes
,
165 u32
*req
, int replyBytes
, u16
*u16reply
, int maxwait
,
167 static int mpt_do_ioc_recovery(MPT_ADAPTER
*ioc
, u32 reason
, int sleepFlag
);
168 static void mpt_detect_bound_ports(MPT_ADAPTER
*ioc
, struct pci_dev
*pdev
);
169 static void mpt_adapter_disable(MPT_ADAPTER
*ioc
);
170 static void mpt_adapter_dispose(MPT_ADAPTER
*ioc
);
172 static void MptDisplayIocCapabilities(MPT_ADAPTER
*ioc
);
173 static int MakeIocReady(MPT_ADAPTER
*ioc
, int force
, int sleepFlag
);
174 static int GetIocFacts(MPT_ADAPTER
*ioc
, int sleepFlag
, int reason
);
175 static int GetPortFacts(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
);
176 static int SendIocInit(MPT_ADAPTER
*ioc
, int sleepFlag
);
177 static int SendPortEnable(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
);
178 static int mpt_do_upload(MPT_ADAPTER
*ioc
, int sleepFlag
);
179 static int mpt_downloadboot(MPT_ADAPTER
*ioc
, MpiFwHeader_t
*pFwHeader
, int sleepFlag
);
180 static int mpt_diag_reset(MPT_ADAPTER
*ioc
, int ignore
, int sleepFlag
);
181 static int KickStart(MPT_ADAPTER
*ioc
, int ignore
, int sleepFlag
);
182 static int SendIocReset(MPT_ADAPTER
*ioc
, u8 reset_type
, int sleepFlag
);
183 static int PrimeIocFifos(MPT_ADAPTER
*ioc
);
184 static int WaitForDoorbellAck(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
);
185 static int WaitForDoorbellInt(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
);
186 static int WaitForDoorbellReply(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
);
187 static int GetLanConfigPages(MPT_ADAPTER
*ioc
);
188 static int GetIoUnitPage2(MPT_ADAPTER
*ioc
);
189 int mptbase_sas_persist_operation(MPT_ADAPTER
*ioc
, u8 persist_opcode
);
190 static int mpt_GetScsiPortSettings(MPT_ADAPTER
*ioc
, int portnum
);
191 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER
*ioc
, int portnum
);
192 static void mpt_read_ioc_pg_1(MPT_ADAPTER
*ioc
);
193 static void mpt_read_ioc_pg_4(MPT_ADAPTER
*ioc
);
194 static void mpt_get_manufacturing_pg_0(MPT_ADAPTER
*ioc
);
195 static int SendEventNotification(MPT_ADAPTER
*ioc
, u8 EvSwitch
,
197 static int SendEventAck(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*evnp
);
198 static int mpt_host_page_access_control(MPT_ADAPTER
*ioc
, u8 access_control_value
, int sleepFlag
);
199 static int mpt_host_page_alloc(MPT_ADAPTER
*ioc
, pIOCInit_t ioc_init
);
201 #ifdef CONFIG_PROC_FS
202 static int procmpt_summary_read(char *buf
, char **start
, off_t offset
,
203 int request
, int *eof
, void *data
);
204 static int procmpt_version_read(char *buf
, char **start
, off_t offset
,
205 int request
, int *eof
, void *data
);
206 static int procmpt_iocinfo_read(char *buf
, char **start
, off_t offset
,
207 int request
, int *eof
, void *data
);
209 static void mpt_get_fw_exp_ver(char *buf
, MPT_ADAPTER
*ioc
);
211 static int ProcessEventNotification(MPT_ADAPTER
*ioc
,
212 EventNotificationReply_t
*evReply
, int *evHandlers
);
213 static void mpt_iocstatus_info(MPT_ADAPTER
*ioc
, u32 ioc_status
, MPT_FRAME_HDR
*mf
);
214 static void mpt_fc_log_info(MPT_ADAPTER
*ioc
, u32 log_info
);
215 static void mpt_spi_log_info(MPT_ADAPTER
*ioc
, u32 log_info
);
216 static void mpt_sas_log_info(MPT_ADAPTER
*ioc
, u32 log_info
);
217 static int mpt_read_ioc_pg_3(MPT_ADAPTER
*ioc
);
218 static void mpt_inactive_raid_list_free(MPT_ADAPTER
*ioc
);
220 /* module entry point */
221 static int __init
fusion_init (void);
222 static void __exit
fusion_exit (void);
224 #define CHIPREG_READ32(addr) readl_relaxed(addr)
225 #define CHIPREG_READ32_dmasync(addr) readl(addr)
226 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
227 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
228 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
231 pci_disable_io_access(struct pci_dev
*pdev
)
235 pci_read_config_word(pdev
, PCI_COMMAND
, &command_reg
);
237 pci_write_config_word(pdev
, PCI_COMMAND
, command_reg
);
241 pci_enable_io_access(struct pci_dev
*pdev
)
245 pci_read_config_word(pdev
, PCI_COMMAND
, &command_reg
);
247 pci_write_config_word(pdev
, PCI_COMMAND
, command_reg
);
250 static int mpt_set_debug_level(const char *val
, struct kernel_param
*kp
)
252 int ret
= param_set_int(val
, kp
);
258 list_for_each_entry(ioc
, &ioc_list
, list
)
259 ioc
->debug_level
= mpt_debug_level
;
264 * mpt_get_cb_idx - obtain cb_idx for registered driver
265 * @dclass: class driver enum
267 * Returns cb_idx, or zero means it wasn't found
270 mpt_get_cb_idx(MPT_DRIVER_CLASS dclass
)
274 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--)
275 if (MptDriverClass
[cb_idx
] == dclass
)
281 * mpt_is_discovery_complete - determine if discovery has completed
282 * @ioc: per adatper instance
284 * Returns 1 when discovery completed, else zero.
287 mpt_is_discovery_complete(MPT_ADAPTER
*ioc
)
289 ConfigExtendedPageHeader_t hdr
;
291 SasIOUnitPage0_t
*buffer
;
292 dma_addr_t dma_handle
;
295 memset(&hdr
, 0, sizeof(ConfigExtendedPageHeader_t
));
296 memset(&cfg
, 0, sizeof(CONFIGPARMS
));
297 hdr
.PageVersion
= MPI_SASIOUNITPAGE0_PAGEVERSION
;
298 hdr
.PageType
= MPI_CONFIG_PAGETYPE_EXTENDED
;
299 hdr
.ExtPageType
= MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT
;
300 cfg
.cfghdr
.ehdr
= &hdr
;
301 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
303 if ((mpt_config(ioc
, &cfg
)))
305 if (!hdr
.ExtPageLength
)
308 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.ExtPageLength
* 4,
313 cfg
.physAddr
= dma_handle
;
314 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
316 if ((mpt_config(ioc
, &cfg
)))
317 goto out_free_consistent
;
319 if (!(buffer
->PhyData
[0].PortFlags
&
320 MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS
))
324 pci_free_consistent(ioc
->pcidev
, hdr
.ExtPageLength
* 4,
331 * mpt_fault_reset_work - work performed on workq after ioc fault
332 * @work: input argument, used to derive ioc
336 mpt_fault_reset_work(struct work_struct
*work
)
339 container_of(work
, MPT_ADAPTER
, fault_reset_work
.work
);
344 if (ioc
->ioc_reset_in_progress
|| !ioc
->active
)
347 ioc_raw_state
= mpt_GetIocState(ioc
, 0);
348 if ((ioc_raw_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_FAULT
) {
349 printk(MYIOC_s_WARN_FMT
"IOC is in FAULT state (%04xh)!!!\n",
350 ioc
->name
, ioc_raw_state
& MPI_DOORBELL_DATA_MASK
);
351 printk(MYIOC_s_WARN_FMT
"Issuing HardReset from %s!!\n",
352 ioc
->name
, __func__
);
353 rc
= mpt_HardResetHandler(ioc
, CAN_SLEEP
);
354 printk(MYIOC_s_WARN_FMT
"%s: HardReset: %s\n", ioc
->name
,
355 __func__
, (rc
== 0) ? "success" : "failed");
356 ioc_raw_state
= mpt_GetIocState(ioc
, 0);
357 if ((ioc_raw_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_FAULT
)
358 printk(MYIOC_s_WARN_FMT
"IOC is in FAULT state after "
359 "reset (%04xh)\n", ioc
->name
, ioc_raw_state
&
360 MPI_DOORBELL_DATA_MASK
);
361 } else if (ioc
->bus_type
== SAS
&& ioc
->sas_discovery_quiesce_io
) {
362 if ((mpt_is_discovery_complete(ioc
))) {
363 devtprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"clearing "
364 "discovery_quiesce_io flag\n", ioc
->name
));
365 ioc
->sas_discovery_quiesce_io
= 0;
371 * Take turns polling alternate controller
376 /* rearm the timer */
377 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
378 if (ioc
->reset_work_q
)
379 queue_delayed_work(ioc
->reset_work_q
, &ioc
->fault_reset_work
,
380 msecs_to_jiffies(MPT_POLLING_INTERVAL
));
381 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
386 * Process turbo (context) reply...
389 mpt_turbo_reply(MPT_ADAPTER
*ioc
, u32 pa
)
391 MPT_FRAME_HDR
*mf
= NULL
;
392 MPT_FRAME_HDR
*mr
= NULL
;
396 dmfprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Got TURBO reply req_idx=%08x\n",
399 switch (pa
>> MPI_CONTEXT_REPLY_TYPE_SHIFT
) {
400 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT
:
401 req_idx
= pa
& 0x0000FFFF;
402 cb_idx
= (pa
& 0x00FF0000) >> 16;
403 mf
= MPT_INDEX_2_MFPTR(ioc
, req_idx
);
405 case MPI_CONTEXT_REPLY_TYPE_LAN
:
406 cb_idx
= mpt_get_cb_idx(MPTLAN_DRIVER
);
408 * Blind set of mf to NULL here was fatal
409 * after lan_reply says "freeme"
410 * Fix sort of combined with an optimization here;
411 * added explicit check for case where lan_reply
412 * was just returning 1 and doing nothing else.
413 * For this case skip the callback, but set up
414 * proper mf value first here:-)
416 if ((pa
& 0x58000000) == 0x58000000) {
417 req_idx
= pa
& 0x0000FFFF;
418 mf
= MPT_INDEX_2_MFPTR(ioc
, req_idx
);
419 mpt_free_msg_frame(ioc
, mf
);
424 mr
= (MPT_FRAME_HDR
*) CAST_U32_TO_PTR(pa
);
426 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET
:
427 cb_idx
= mpt_get_cb_idx(MPTSTM_DRIVER
);
428 mr
= (MPT_FRAME_HDR
*) CAST_U32_TO_PTR(pa
);
435 /* Check for (valid) IO callback! */
436 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
||
437 MptCallbacks
[cb_idx
] == NULL
) {
438 printk(MYIOC_s_WARN_FMT
"%s: Invalid cb_idx (%d)!\n",
439 __func__
, ioc
->name
, cb_idx
);
443 if (MptCallbacks
[cb_idx
](ioc
, mf
, mr
))
444 mpt_free_msg_frame(ioc
, mf
);
450 mpt_reply(MPT_ADAPTER
*ioc
, u32 pa
)
461 /* non-TURBO reply! Hmmm, something may be up...
462 * Newest turbo reply mechanism; get address
463 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
466 /* Map DMA address of reply header to cpu address.
467 * pa is 32 bits - but the dma address may be 32 or 64 bits
468 * get offset based only only the low addresses
471 reply_dma_low
= (pa
<<= 1);
472 mr
= (MPT_FRAME_HDR
*)((u8
*)ioc
->reply_frames
+
473 (reply_dma_low
- ioc
->reply_frames_low_dma
));
475 req_idx
= le16_to_cpu(mr
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
);
476 cb_idx
= mr
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
;
477 mf
= MPT_INDEX_2_MFPTR(ioc
, req_idx
);
479 dmfprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
480 ioc
->name
, mr
, req_idx
, cb_idx
, mr
->u
.hdr
.Function
));
481 DBG_DUMP_REPLY_FRAME(ioc
, (u32
*)mr
);
483 /* Check/log IOC log info
485 ioc_stat
= le16_to_cpu(mr
->u
.reply
.IOCStatus
);
486 if (ioc_stat
& MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE
) {
487 u32 log_info
= le32_to_cpu(mr
->u
.reply
.IOCLogInfo
);
488 if (ioc
->bus_type
== FC
)
489 mpt_fc_log_info(ioc
, log_info
);
490 else if (ioc
->bus_type
== SPI
)
491 mpt_spi_log_info(ioc
, log_info
);
492 else if (ioc
->bus_type
== SAS
)
493 mpt_sas_log_info(ioc
, log_info
);
496 if (ioc_stat
& MPI_IOCSTATUS_MASK
)
497 mpt_iocstatus_info(ioc
, (u32
)ioc_stat
, mf
);
499 /* Check for (valid) IO callback! */
500 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
||
501 MptCallbacks
[cb_idx
] == NULL
) {
502 printk(MYIOC_s_WARN_FMT
"%s: Invalid cb_idx (%d)!\n",
503 __func__
, ioc
->name
, cb_idx
);
508 freeme
= MptCallbacks
[cb_idx
](ioc
, mf
, mr
);
511 /* Flush (non-TURBO) reply with a WRITE! */
512 CHIPREG_WRITE32(&ioc
->chip
->ReplyFifo
, pa
);
515 mpt_free_msg_frame(ioc
, mf
);
519 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
521 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
522 * @irq: irq number (not used)
523 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
525 * This routine is registered via the request_irq() kernel API call,
526 * and handles all interrupts generated from a specific MPT adapter
527 * (also referred to as a IO Controller or IOC).
528 * This routine must clear the interrupt from the adapter and does
529 * so by reading the reply FIFO. Multiple replies may be processed
530 * per single call to this routine.
532 * This routine handles register-level access of the adapter but
533 * dispatches (calls) a protocol-specific callback routine to handle
534 * the protocol-specific details of the MPT request completion.
537 mpt_interrupt(int irq
, void *bus_id
)
539 MPT_ADAPTER
*ioc
= bus_id
;
540 u32 pa
= CHIPREG_READ32_dmasync(&ioc
->chip
->ReplyFifo
);
542 if (pa
== 0xFFFFFFFF)
546 * Drain the reply FIFO!
549 if (pa
& MPI_ADDRESS_REPLY_A_BIT
)
552 mpt_turbo_reply(ioc
, pa
);
553 pa
= CHIPREG_READ32_dmasync(&ioc
->chip
->ReplyFifo
);
554 } while (pa
!= 0xFFFFFFFF);
559 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
561 * mptbase_reply - MPT base driver's callback routine
562 * @ioc: Pointer to MPT_ADAPTER structure
563 * @req: Pointer to original MPT request frame
564 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
566 * MPT base driver's callback routine; all base driver
567 * "internal" request/reply processing is routed here.
568 * Currently used for EventNotification and EventAck handling.
570 * Returns 1 indicating original alloc'd request frame ptr
571 * should be freed, or 0 if it shouldn't.
574 mptbase_reply(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*req
, MPT_FRAME_HDR
*reply
)
576 EventNotificationReply_t
*pEventReply
;
581 switch (reply
->u
.hdr
.Function
) {
582 case MPI_FUNCTION_EVENT_NOTIFICATION
:
583 pEventReply
= (EventNotificationReply_t
*)reply
;
585 ProcessEventNotification(ioc
, pEventReply
, &evHandlers
);
586 event
= le32_to_cpu(pEventReply
->Event
) & 0xFF;
587 if (pEventReply
->MsgFlags
& MPI_MSGFLAGS_CONTINUATION_REPLY
)
589 if (event
!= MPI_EVENT_EVENT_CHANGE
)
591 case MPI_FUNCTION_CONFIG
:
592 case MPI_FUNCTION_SAS_IO_UNIT_CONTROL
:
593 ioc
->mptbase_cmds
.status
|= MPT_MGMT_STATUS_COMMAND_GOOD
;
595 ioc
->mptbase_cmds
.status
|= MPT_MGMT_STATUS_RF_VALID
;
596 memcpy(ioc
->mptbase_cmds
.reply
, reply
,
597 min(MPT_DEFAULT_FRAME_SIZE
,
598 4 * reply
->u
.reply
.MsgLength
));
600 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_PENDING
) {
601 ioc
->mptbase_cmds
.status
&= ~MPT_MGMT_STATUS_PENDING
;
602 complete(&ioc
->mptbase_cmds
.done
);
605 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_FREE_MF
)
608 case MPI_FUNCTION_EVENT_ACK
:
609 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
610 "EventAck reply received\n", ioc
->name
));
613 printk(MYIOC_s_ERR_FMT
614 "Unexpected msg function (=%02Xh) reply received!\n",
615 ioc
->name
, reply
->u
.hdr
.Function
);
620 * Conditionally tell caller to free the original
621 * EventNotification/EventAck/unexpected request frame!
626 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
628 * mpt_register - Register protocol-specific main callback handler.
629 * @cbfunc: callback function pointer
630 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
632 * This routine is called by a protocol-specific driver (SCSI host,
633 * LAN, SCSI target) to register its reply callback routine. Each
634 * protocol-specific driver must do this before it will be able to
635 * use any IOC resources, such as obtaining request frames.
637 * NOTES: The SCSI protocol driver currently calls this routine thrice
638 * in order to register separate callbacks; one for "normal" SCSI IO;
639 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
641 * Returns u8 valued "handle" in the range (and S.O.D. order)
642 * {N,...,7,6,5,...,1} if successful.
643 * A return value of MPT_MAX_PROTOCOL_DRIVERS (including zero!) should be
644 * considered an error by the caller.
647 mpt_register(MPT_CALLBACK cbfunc
, MPT_DRIVER_CLASS dclass
)
650 last_drv_idx
= MPT_MAX_PROTOCOL_DRIVERS
;
653 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
654 * (slot/handle 0 is reserved!)
656 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
657 if (MptCallbacks
[cb_idx
] == NULL
) {
658 MptCallbacks
[cb_idx
] = cbfunc
;
659 MptDriverClass
[cb_idx
] = dclass
;
660 MptEvHandlers
[cb_idx
] = NULL
;
661 last_drv_idx
= cb_idx
;
669 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
671 * mpt_deregister - Deregister a protocol drivers resources.
672 * @cb_idx: previously registered callback handle
674 * Each protocol-specific driver should call this routine when its
675 * module is unloaded.
678 mpt_deregister(u8 cb_idx
)
680 if (cb_idx
&& (cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
)) {
681 MptCallbacks
[cb_idx
] = NULL
;
682 MptDriverClass
[cb_idx
] = MPTUNKNOWN_DRIVER
;
683 MptEvHandlers
[cb_idx
] = NULL
;
689 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
691 * mpt_event_register - Register protocol-specific event callback handler.
692 * @cb_idx: previously registered (via mpt_register) callback handle
693 * @ev_cbfunc: callback function
695 * This routine can be called by one or more protocol-specific drivers
696 * if/when they choose to be notified of MPT events.
698 * Returns 0 for success.
701 mpt_event_register(u8 cb_idx
, MPT_EVHANDLER ev_cbfunc
)
703 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
706 MptEvHandlers
[cb_idx
] = ev_cbfunc
;
710 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
712 * mpt_event_deregister - Deregister protocol-specific event callback handler
713 * @cb_idx: previously registered callback handle
715 * Each protocol-specific driver should call this routine
716 * when it does not (or can no longer) handle events,
717 * or when its module is unloaded.
720 mpt_event_deregister(u8 cb_idx
)
722 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
725 MptEvHandlers
[cb_idx
] = NULL
;
728 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
730 * mpt_reset_register - Register protocol-specific IOC reset handler.
731 * @cb_idx: previously registered (via mpt_register) callback handle
732 * @reset_func: reset function
734 * This routine can be called by one or more protocol-specific drivers
735 * if/when they choose to be notified of IOC resets.
737 * Returns 0 for success.
740 mpt_reset_register(u8 cb_idx
, MPT_RESETHANDLER reset_func
)
742 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
745 MptResetHandlers
[cb_idx
] = reset_func
;
749 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
751 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
752 * @cb_idx: previously registered callback handle
754 * Each protocol-specific driver should call this routine
755 * when it does not (or can no longer) handle IOC reset handling,
756 * or when its module is unloaded.
759 mpt_reset_deregister(u8 cb_idx
)
761 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
764 MptResetHandlers
[cb_idx
] = NULL
;
767 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
769 * mpt_device_driver_register - Register device driver hooks
770 * @dd_cbfunc: driver callbacks struct
771 * @cb_idx: MPT protocol driver index
774 mpt_device_driver_register(struct mpt_pci_driver
* dd_cbfunc
, u8 cb_idx
)
777 const struct pci_device_id
*id
;
779 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
782 MptDeviceDriverHandlers
[cb_idx
] = dd_cbfunc
;
784 /* call per pci device probe entry point */
785 list_for_each_entry(ioc
, &ioc_list
, list
) {
786 id
= ioc
->pcidev
->driver
?
787 ioc
->pcidev
->driver
->id_table
: NULL
;
788 if (dd_cbfunc
->probe
)
789 dd_cbfunc
->probe(ioc
->pcidev
, id
);
795 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
797 * mpt_device_driver_deregister - DeRegister device driver hooks
798 * @cb_idx: MPT protocol driver index
801 mpt_device_driver_deregister(u8 cb_idx
)
803 struct mpt_pci_driver
*dd_cbfunc
;
806 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
809 dd_cbfunc
= MptDeviceDriverHandlers
[cb_idx
];
811 list_for_each_entry(ioc
, &ioc_list
, list
) {
812 if (dd_cbfunc
->remove
)
813 dd_cbfunc
->remove(ioc
->pcidev
);
816 MptDeviceDriverHandlers
[cb_idx
] = NULL
;
820 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
822 * mpt_get_msg_frame - Obtain an MPT request frame from the pool
823 * @cb_idx: Handle of registered MPT protocol driver
824 * @ioc: Pointer to MPT adapter structure
826 * Obtain an MPT request frame from the pool (of 1024) that are
827 * allocated per MPT adapter.
829 * Returns pointer to a MPT request frame or %NULL if none are available
830 * or IOC is not active.
833 mpt_get_msg_frame(u8 cb_idx
, MPT_ADAPTER
*ioc
)
837 u16 req_idx
; /* Request index */
839 /* validate handle and ioc identifier */
843 printk(MYIOC_s_WARN_FMT
"IOC Not Active! mpt_get_msg_frame "
844 "returning NULL!\n", ioc
->name
);
847 /* If interrupts are not attached, do not return a request frame */
851 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
852 if (!list_empty(&ioc
->FreeQ
)) {
855 mf
= list_entry(ioc
->FreeQ
.next
, MPT_FRAME_HDR
,
856 u
.frame
.linkage
.list
);
857 list_del(&mf
->u
.frame
.linkage
.list
);
858 mf
->u
.frame
.linkage
.arg1
= 0;
859 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= cb_idx
; /* byte */
860 req_offset
= (u8
*)mf
- (u8
*)ioc
->req_frames
;
862 req_idx
= req_offset
/ ioc
->req_sz
;
863 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(req_idx
);
864 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.rsvd
= 0;
865 /* Default, will be changed if necessary in SG generation */
866 ioc
->RequestNB
[req_idx
] = ioc
->NB_for_64_byte_frame
;
873 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
877 printk(MYIOC_s_WARN_FMT
"IOC Active. No free Msg Frames! "
878 "Count 0x%x Max 0x%x\n", ioc
->name
, ioc
->mfcnt
,
881 if (mfcounter
== PRINT_MF_COUNT
)
882 printk(MYIOC_s_INFO_FMT
"MF Count 0x%x Max 0x%x \n", ioc
->name
,
883 ioc
->mfcnt
, ioc
->req_depth
);
886 dmfprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mpt_get_msg_frame(%d,%d), got mf=%p\n",
887 ioc
->name
, cb_idx
, ioc
->id
, mf
));
891 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
893 * mpt_put_msg_frame - Send a protocol-specific MPT request frame to an IOC
894 * @cb_idx: Handle of registered MPT protocol driver
895 * @ioc: Pointer to MPT adapter structure
896 * @mf: Pointer to MPT request frame
898 * This routine posts an MPT request frame to the request post FIFO of a
899 * specific MPT adapter.
902 mpt_put_msg_frame(u8 cb_idx
, MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
)
906 u16 req_idx
; /* Request index */
908 /* ensure values are reset properly! */
909 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= cb_idx
; /* byte */
910 req_offset
= (u8
*)mf
- (u8
*)ioc
->req_frames
;
912 req_idx
= req_offset
/ ioc
->req_sz
;
913 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(req_idx
);
914 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.rsvd
= 0;
916 DBG_DUMP_PUT_MSG_FRAME(ioc
, (u32
*)mf
);
918 mf_dma_addr
= (ioc
->req_frames_low_dma
+ req_offset
) | ioc
->RequestNB
[req_idx
];
919 dsgprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mf_dma_addr=%x req_idx=%d "
920 "RequestNB=%x\n", ioc
->name
, mf_dma_addr
, req_idx
,
921 ioc
->RequestNB
[req_idx
]));
922 CHIPREG_WRITE32(&ioc
->chip
->RequestFifo
, mf_dma_addr
);
926 * mpt_put_msg_frame_hi_pri - Send a hi-pri protocol-specific MPT request frame
927 * @cb_idx: Handle of registered MPT protocol driver
928 * @ioc: Pointer to MPT adapter structure
929 * @mf: Pointer to MPT request frame
931 * Send a protocol-specific MPT request frame to an IOC using
932 * hi-priority request queue.
934 * This routine posts an MPT request frame to the request post FIFO of a
935 * specific MPT adapter.
938 mpt_put_msg_frame_hi_pri(u8 cb_idx
, MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
)
942 u16 req_idx
; /* Request index */
944 /* ensure values are reset properly! */
945 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= cb_idx
;
946 req_offset
= (u8
*)mf
- (u8
*)ioc
->req_frames
;
947 req_idx
= req_offset
/ ioc
->req_sz
;
948 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(req_idx
);
949 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.rsvd
= 0;
951 DBG_DUMP_PUT_MSG_FRAME(ioc
, (u32
*)mf
);
953 mf_dma_addr
= (ioc
->req_frames_low_dma
+ req_offset
);
954 dsgprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mf_dma_addr=%x req_idx=%d\n",
955 ioc
->name
, mf_dma_addr
, req_idx
));
956 CHIPREG_WRITE32(&ioc
->chip
->RequestHiPriFifo
, mf_dma_addr
);
959 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
961 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
962 * @ioc: Pointer to MPT adapter structure
963 * @mf: Pointer to MPT request frame
965 * This routine places a MPT request frame back on the MPT adapter's
969 mpt_free_msg_frame(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
)
973 /* Put Request back on FreeQ! */
974 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
975 if (cpu_to_le32(mf
->u
.frame
.linkage
.arg1
) == 0xdeadbeaf)
977 /* signature to know if this mf is freed */
978 mf
->u
.frame
.linkage
.arg1
= cpu_to_le32(0xdeadbeaf);
979 list_add_tail(&mf
->u
.frame
.linkage
.list
, &ioc
->FreeQ
);
984 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
987 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
989 * mpt_add_sge - Place a simple 32 bit SGE at address pAddr.
990 * @pAddr: virtual address for SGE
991 * @flagslength: SGE flags and data transfer length
992 * @dma_addr: Physical address
994 * This routine places a MPT request frame back on the MPT adapter's
998 mpt_add_sge(void *pAddr
, u32 flagslength
, dma_addr_t dma_addr
)
1000 SGESimple32_t
*pSge
= (SGESimple32_t
*) pAddr
;
1001 pSge
->FlagsLength
= cpu_to_le32(flagslength
);
1002 pSge
->Address
= cpu_to_le32(dma_addr
);
1006 * mpt_add_sge_64bit - Place a simple 64 bit SGE at address pAddr.
1007 * @pAddr: virtual address for SGE
1008 * @flagslength: SGE flags and data transfer length
1009 * @dma_addr: Physical address
1011 * This routine places a MPT request frame back on the MPT adapter's
1015 mpt_add_sge_64bit(void *pAddr
, u32 flagslength
, dma_addr_t dma_addr
)
1017 SGESimple64_t
*pSge
= (SGESimple64_t
*) pAddr
;
1018 pSge
->Address
.Low
= cpu_to_le32
1019 (lower_32_bits(dma_addr
));
1020 pSge
->Address
.High
= cpu_to_le32
1021 (upper_32_bits(dma_addr
));
1022 pSge
->FlagsLength
= cpu_to_le32
1023 ((flagslength
| MPT_SGE_FLAGS_64_BIT_ADDRESSING
));
1027 * mpt_add_sge_64bit_1078 - Place a simple 64 bit SGE at address pAddr (1078 workaround).
1028 * @pAddr: virtual address for SGE
1029 * @flagslength: SGE flags and data transfer length
1030 * @dma_addr: Physical address
1032 * This routine places a MPT request frame back on the MPT adapter's
1036 mpt_add_sge_64bit_1078(void *pAddr
, u32 flagslength
, dma_addr_t dma_addr
)
1038 SGESimple64_t
*pSge
= (SGESimple64_t
*) pAddr
;
1041 pSge
->Address
.Low
= cpu_to_le32
1042 (lower_32_bits(dma_addr
));
1043 tmp
= (u32
)(upper_32_bits(dma_addr
));
1046 * 1078 errata workaround for the 36GB limitation
1048 if ((((u64
)dma_addr
+ MPI_SGE_LENGTH(flagslength
)) >> 32) == 9) {
1050 MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_LOCAL_ADDRESS
);
1052 if (mpt_debug_level
& MPT_DEBUG_36GB_MEM
)
1053 printk(KERN_DEBUG
"1078 P0M2 addressing for "
1054 "addr = 0x%llx len = %d\n",
1055 (unsigned long long)dma_addr
,
1056 MPI_SGE_LENGTH(flagslength
));
1059 pSge
->Address
.High
= cpu_to_le32(tmp
);
1060 pSge
->FlagsLength
= cpu_to_le32(
1061 (flagslength
| MPT_SGE_FLAGS_64_BIT_ADDRESSING
));
1064 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1066 * mpt_add_chain - Place a 32 bit chain SGE at address pAddr.
1067 * @pAddr: virtual address for SGE
1068 * @next: nextChainOffset value (u32's)
1069 * @length: length of next SGL segment
1070 * @dma_addr: Physical address
1074 mpt_add_chain(void *pAddr
, u8 next
, u16 length
, dma_addr_t dma_addr
)
1076 SGEChain32_t
*pChain
= (SGEChain32_t
*) pAddr
;
1077 pChain
->Length
= cpu_to_le16(length
);
1078 pChain
->Flags
= MPI_SGE_FLAGS_CHAIN_ELEMENT
;
1079 pChain
->NextChainOffset
= next
;
1080 pChain
->Address
= cpu_to_le32(dma_addr
);
1083 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1085 * mpt_add_chain_64bit - Place a 64 bit chain SGE at address pAddr.
1086 * @pAddr: virtual address for SGE
1087 * @next: nextChainOffset value (u32's)
1088 * @length: length of next SGL segment
1089 * @dma_addr: Physical address
1093 mpt_add_chain_64bit(void *pAddr
, u8 next
, u16 length
, dma_addr_t dma_addr
)
1095 SGEChain64_t
*pChain
= (SGEChain64_t
*) pAddr
;
1096 u32 tmp
= dma_addr
& 0xFFFFFFFF;
1098 pChain
->Length
= cpu_to_le16(length
);
1099 pChain
->Flags
= (MPI_SGE_FLAGS_CHAIN_ELEMENT
|
1100 MPI_SGE_FLAGS_64_BIT_ADDRESSING
);
1102 pChain
->NextChainOffset
= next
;
1104 pChain
->Address
.Low
= cpu_to_le32(tmp
);
1105 tmp
= (u32
)(upper_32_bits(dma_addr
));
1106 pChain
->Address
.High
= cpu_to_le32(tmp
);
1109 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1111 * mpt_send_handshake_request - Send MPT request via doorbell handshake method.
1112 * @cb_idx: Handle of registered MPT protocol driver
1113 * @ioc: Pointer to MPT adapter structure
1114 * @reqBytes: Size of the request in bytes
1115 * @req: Pointer to MPT request frame
1116 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1118 * This routine is used exclusively to send MptScsiTaskMgmt
1119 * requests since they are required to be sent via doorbell handshake.
1121 * NOTE: It is the callers responsibility to byte-swap fields in the
1122 * request which are greater than 1 byte in size.
1124 * Returns 0 for success, non-zero for failure.
1127 mpt_send_handshake_request(u8 cb_idx
, MPT_ADAPTER
*ioc
, int reqBytes
, u32
*req
, int sleepFlag
)
1133 /* State is known to be good upon entering
1134 * this function so issue the bus reset
1139 * Emulate what mpt_put_msg_frame() does /wrt to sanity
1140 * setting cb_idx/req_idx. But ONLY if this request
1141 * is in proper (pre-alloc'd) request buffer range...
1143 ii
= MFPTR_2_MPT_INDEX(ioc
,(MPT_FRAME_HDR
*)req
);
1144 if (reqBytes
>= 12 && ii
>= 0 && ii
< ioc
->req_depth
) {
1145 MPT_FRAME_HDR
*mf
= (MPT_FRAME_HDR
*)req
;
1146 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(ii
);
1147 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= cb_idx
;
1150 /* Make sure there are no doorbells */
1151 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1153 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
,
1154 ((MPI_FUNCTION_HANDSHAKE
<<MPI_DOORBELL_FUNCTION_SHIFT
) |
1155 ((reqBytes
/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT
)));
1157 /* Wait for IOC doorbell int */
1158 if ((ii
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0) {
1162 /* Read doorbell and check for active bit */
1163 if (!(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & MPI_DOORBELL_ACTIVE
))
1166 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mpt_send_handshake_request start, WaitCnt=%d\n",
1169 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1171 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0) {
1175 /* Send request via doorbell handshake */
1176 req_as_bytes
= (u8
*) req
;
1177 for (ii
= 0; ii
< reqBytes
/4; ii
++) {
1180 word
= ((req_as_bytes
[(ii
*4) + 0] << 0) |
1181 (req_as_bytes
[(ii
*4) + 1] << 8) |
1182 (req_as_bytes
[(ii
*4) + 2] << 16) |
1183 (req_as_bytes
[(ii
*4) + 3] << 24));
1184 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, word
);
1185 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0) {
1191 if (r
>= 0 && WaitForDoorbellInt(ioc
, 10, sleepFlag
) >= 0)
1196 /* Make sure there are no doorbells */
1197 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1202 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1204 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
1205 * @ioc: Pointer to MPT adapter structure
1206 * @access_control_value: define bits below
1207 * @sleepFlag: Specifies whether the process can sleep
1209 * Provides mechanism for the host driver to control the IOC's
1210 * Host Page Buffer access.
1212 * Access Control Value - bits[15:12]
1214 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1215 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1216 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1218 * Returns 0 for success, non-zero for failure.
1222 mpt_host_page_access_control(MPT_ADAPTER
*ioc
, u8 access_control_value
, int sleepFlag
)
1226 /* return if in use */
1227 if (CHIPREG_READ32(&ioc
->chip
->Doorbell
)
1228 & MPI_DOORBELL_ACTIVE
)
1231 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1233 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
,
1234 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1235 <<MPI_DOORBELL_FUNCTION_SHIFT
) |
1236 (access_control_value
<<12)));
1238 /* Wait for IOC to clear Doorbell Status bit */
1239 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0) {
1245 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1247 * mpt_host_page_alloc - allocate system memory for the fw
1248 * @ioc: Pointer to pointer to IOC adapter
1249 * @ioc_init: Pointer to ioc init config page
1251 * If we already allocated memory in past, then resend the same pointer.
1252 * Returns 0 for success, non-zero for failure.
1255 mpt_host_page_alloc(MPT_ADAPTER
*ioc
, pIOCInit_t ioc_init
)
1259 u32 host_page_buffer_sz
=0;
1261 if(!ioc
->HostPageBuffer
) {
1263 host_page_buffer_sz
=
1264 le32_to_cpu(ioc
->facts
.HostPageBufferSGE
.FlagsLength
) & 0xFFFFFF;
1266 if(!host_page_buffer_sz
)
1267 return 0; /* fw doesn't need any host buffers */
1269 /* spin till we get enough memory */
1270 while(host_page_buffer_sz
> 0) {
1272 if((ioc
->HostPageBuffer
= pci_alloc_consistent(
1274 host_page_buffer_sz
,
1275 &ioc
->HostPageBuffer_dma
)) != NULL
) {
1277 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
1278 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1279 ioc
->name
, ioc
->HostPageBuffer
,
1280 (u32
)ioc
->HostPageBuffer_dma
,
1281 host_page_buffer_sz
));
1282 ioc
->alloc_total
+= host_page_buffer_sz
;
1283 ioc
->HostPageBuffer_sz
= host_page_buffer_sz
;
1287 host_page_buffer_sz
-= (4*1024);
1291 if(!ioc
->HostPageBuffer
) {
1292 printk(MYIOC_s_ERR_FMT
1293 "Failed to alloc memory for host_page_buffer!\n",
1298 psge
= (char *)&ioc_init
->HostPageBufferSGE
;
1299 flags_length
= MPI_SGE_FLAGS_SIMPLE_ELEMENT
|
1300 MPI_SGE_FLAGS_SYSTEM_ADDRESS
|
1301 MPI_SGE_FLAGS_HOST_TO_IOC
|
1302 MPI_SGE_FLAGS_END_OF_BUFFER
;
1303 flags_length
= flags_length
<< MPI_SGE_FLAGS_SHIFT
;
1304 flags_length
|= ioc
->HostPageBuffer_sz
;
1305 ioc
->add_sge(psge
, flags_length
, ioc
->HostPageBuffer_dma
);
1306 ioc
->facts
.HostPageBufferSGE
= ioc_init
->HostPageBufferSGE
;
1311 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1313 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1314 * @iocid: IOC unique identifier (integer)
1315 * @iocpp: Pointer to pointer to IOC adapter
1317 * Given a unique IOC identifier, set pointer to the associated MPT
1318 * adapter structure.
1320 * Returns iocid and sets iocpp if iocid is found.
1321 * Returns -1 if iocid is not found.
1324 mpt_verify_adapter(int iocid
, MPT_ADAPTER
**iocpp
)
1328 list_for_each_entry(ioc
,&ioc_list
,list
) {
1329 if (ioc
->id
== iocid
) {
1340 * mpt_get_product_name - returns product string
1341 * @vendor: pci vendor id
1342 * @device: pci device id
1343 * @revision: pci revision id
1344 * @prod_name: string returned
1346 * Returns product string displayed when driver loads,
1347 * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1351 mpt_get_product_name(u16 vendor
, u16 device
, u8 revision
, char *prod_name
)
1353 char *product_str
= NULL
;
1355 if (vendor
== PCI_VENDOR_ID_BROCADE
) {
1358 case MPI_MANUFACTPAGE_DEVICEID_FC949E
:
1362 product_str
= "BRE040 A0";
1365 product_str
= "BRE040 A1";
1368 product_str
= "BRE040";
1378 case MPI_MANUFACTPAGE_DEVICEID_FC909
:
1379 product_str
= "LSIFC909 B1";
1381 case MPI_MANUFACTPAGE_DEVICEID_FC919
:
1382 product_str
= "LSIFC919 B0";
1384 case MPI_MANUFACTPAGE_DEVICEID_FC929
:
1385 product_str
= "LSIFC929 B0";
1387 case MPI_MANUFACTPAGE_DEVICEID_FC919X
:
1388 if (revision
< 0x80)
1389 product_str
= "LSIFC919X A0";
1391 product_str
= "LSIFC919XL A1";
1393 case MPI_MANUFACTPAGE_DEVICEID_FC929X
:
1394 if (revision
< 0x80)
1395 product_str
= "LSIFC929X A0";
1397 product_str
= "LSIFC929XL A1";
1399 case MPI_MANUFACTPAGE_DEVICEID_FC939X
:
1400 product_str
= "LSIFC939X A1";
1402 case MPI_MANUFACTPAGE_DEVICEID_FC949X
:
1403 product_str
= "LSIFC949X A1";
1405 case MPI_MANUFACTPAGE_DEVICEID_FC949E
:
1409 product_str
= "LSIFC949E A0";
1412 product_str
= "LSIFC949E A1";
1415 product_str
= "LSIFC949E";
1419 case MPI_MANUFACTPAGE_DEVID_53C1030
:
1423 product_str
= "LSI53C1030 A0";
1426 product_str
= "LSI53C1030 B0";
1429 product_str
= "LSI53C1030 B1";
1432 product_str
= "LSI53C1030 B2";
1435 product_str
= "LSI53C1030 C0";
1438 product_str
= "LSI53C1030T A0";
1441 product_str
= "LSI53C1030T A2";
1444 product_str
= "LSI53C1030T A3";
1447 product_str
= "LSI53C1020A A1";
1450 product_str
= "LSI53C1030";
1454 case MPI_MANUFACTPAGE_DEVID_1030_53C1035
:
1458 product_str
= "LSI53C1035 A2";
1461 product_str
= "LSI53C1035 B0";
1464 product_str
= "LSI53C1035";
1468 case MPI_MANUFACTPAGE_DEVID_SAS1064
:
1472 product_str
= "LSISAS1064 A1";
1475 product_str
= "LSISAS1064 A2";
1478 product_str
= "LSISAS1064 A3";
1481 product_str
= "LSISAS1064 A4";
1484 product_str
= "LSISAS1064";
1488 case MPI_MANUFACTPAGE_DEVID_SAS1064E
:
1492 product_str
= "LSISAS1064E A0";
1495 product_str
= "LSISAS1064E B0";
1498 product_str
= "LSISAS1064E B1";
1501 product_str
= "LSISAS1064E B2";
1504 product_str
= "LSISAS1064E B3";
1507 product_str
= "LSISAS1064E";
1511 case MPI_MANUFACTPAGE_DEVID_SAS1068
:
1515 product_str
= "LSISAS1068 A0";
1518 product_str
= "LSISAS1068 B0";
1521 product_str
= "LSISAS1068 B1";
1524 product_str
= "LSISAS1068";
1528 case MPI_MANUFACTPAGE_DEVID_SAS1068E
:
1532 product_str
= "LSISAS1068E A0";
1535 product_str
= "LSISAS1068E B0";
1538 product_str
= "LSISAS1068E B1";
1541 product_str
= "LSISAS1068E B2";
1544 product_str
= "LSISAS1068E B3";
1547 product_str
= "LSISAS1068E";
1551 case MPI_MANUFACTPAGE_DEVID_SAS1078
:
1555 product_str
= "LSISAS1078 A0";
1558 product_str
= "LSISAS1078 B0";
1561 product_str
= "LSISAS1078 C0";
1564 product_str
= "LSISAS1078 C1";
1567 product_str
= "LSISAS1078 C2";
1570 product_str
= "LSISAS1078";
1578 sprintf(prod_name
, "%s", product_str
);
1582 * mpt_mapresources - map in memory mapped io
1583 * @ioc: Pointer to pointer to IOC adapter
1587 mpt_mapresources(MPT_ADAPTER
*ioc
)
1591 resource_size_t mem_phys
;
1597 struct pci_dev
*pdev
;
1600 ioc
->bars
= pci_select_bars(pdev
, IORESOURCE_MEM
);
1601 if (pci_enable_device_mem(pdev
)) {
1602 printk(MYIOC_s_ERR_FMT
"pci_enable_device_mem() "
1603 "failed\n", ioc
->name
);
1606 if (pci_request_selected_regions(pdev
, ioc
->bars
, "mpt")) {
1607 printk(MYIOC_s_ERR_FMT
"pci_request_selected_regions() with "
1608 "MEM failed\n", ioc
->name
);
1612 pci_read_config_byte(pdev
, PCI_CLASS_REVISION
, &revision
);
1614 if (sizeof(dma_addr_t
) > 4) {
1615 const uint64_t required_mask
= dma_get_required_mask
1617 if (required_mask
> DMA_BIT_MASK(32)
1618 && !pci_set_dma_mask(pdev
, DMA_BIT_MASK(64))
1619 && !pci_set_consistent_dma_mask(pdev
,
1620 DMA_BIT_MASK(64))) {
1621 ioc
->dma_mask
= DMA_BIT_MASK(64);
1622 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
1623 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1625 } else if (!pci_set_dma_mask(pdev
, DMA_BIT_MASK(32))
1626 && !pci_set_consistent_dma_mask(pdev
,
1627 DMA_BIT_MASK(32))) {
1628 ioc
->dma_mask
= DMA_BIT_MASK(32);
1629 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
1630 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1633 printk(MYIOC_s_WARN_FMT
"no suitable DMA mask for %s\n",
1634 ioc
->name
, pci_name(pdev
));
1638 if (!pci_set_dma_mask(pdev
, DMA_BIT_MASK(32))
1639 && !pci_set_consistent_dma_mask(pdev
,
1640 DMA_BIT_MASK(32))) {
1641 ioc
->dma_mask
= DMA_BIT_MASK(32);
1642 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
1643 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1646 printk(MYIOC_s_WARN_FMT
"no suitable DMA mask for %s\n",
1647 ioc
->name
, pci_name(pdev
));
1652 mem_phys
= msize
= 0;
1654 for (ii
= 0; ii
< DEVICE_COUNT_RESOURCE
; ii
++) {
1655 if (pci_resource_flags(pdev
, ii
) & PCI_BASE_ADDRESS_SPACE_IO
) {
1658 /* Get I/O space! */
1659 port
= pci_resource_start(pdev
, ii
);
1660 psize
= pci_resource_len(pdev
, ii
);
1665 mem_phys
= pci_resource_start(pdev
, ii
);
1666 msize
= pci_resource_len(pdev
, ii
);
1669 ioc
->mem_size
= msize
;
1672 /* Get logical ptr for PciMem0 space */
1673 /*mem = ioremap(mem_phys, msize);*/
1674 mem
= ioremap(mem_phys
, msize
);
1676 printk(MYIOC_s_ERR_FMT
": ERROR - Unable to map adapter"
1677 " memory!\n", ioc
->name
);
1681 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"mem = %p, mem_phys = %llx\n",
1682 ioc
->name
, mem
, (unsigned long long)mem_phys
));
1684 ioc
->mem_phys
= mem_phys
;
1685 ioc
->chip
= (SYSIF_REGS __iomem
*)mem
;
1687 /* Save Port IO values in case we need to do downloadboot */
1688 ioc
->pio_mem_phys
= port
;
1689 ioc
->pio_chip
= (SYSIF_REGS __iomem
*)port
;
1694 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1696 * mpt_attach - Install a PCI intelligent MPT adapter.
1697 * @pdev: Pointer to pci_dev structure
1698 * @id: PCI device ID information
1700 * This routine performs all the steps necessary to bring the IOC of
1701 * a MPT adapter to a OPERATIONAL state. This includes registering
1702 * memory regions, registering the interrupt, and allocating request
1703 * and reply memory pools.
1705 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1708 * Returns 0 for success, non-zero for failure.
1710 * TODO: Add support for polled controllers
1713 mpt_attach(struct pci_dev
*pdev
, const struct pci_device_id
*id
)
1720 static int mpt_ids
= 0;
1721 #ifdef CONFIG_PROC_FS
1722 struct proc_dir_entry
*dent
, *ent
;
1725 ioc
= kzalloc(sizeof(MPT_ADAPTER
), GFP_ATOMIC
);
1727 printk(KERN_ERR MYNAM
": ERROR - Insufficient memory to add adapter!\n");
1731 ioc
->id
= mpt_ids
++;
1732 sprintf(ioc
->name
, "ioc%d", ioc
->id
);
1733 dinitprintk(ioc
, printk(KERN_WARNING MYNAM
": mpt_adapter_install\n"));
1736 * set initial debug level
1737 * (refer to mptdebug.h)
1740 ioc
->debug_level
= mpt_debug_level
;
1741 if (mpt_debug_level
)
1742 printk(KERN_INFO
"mpt_debug_level=%xh\n", mpt_debug_level
);
1744 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
": mpt_adapter_install\n", ioc
->name
));
1747 if (mpt_mapresources(ioc
)) {
1753 * Setting up proper handlers for scatter gather handling
1755 if (ioc
->dma_mask
== DMA_BIT_MASK(64)) {
1756 if (pdev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1078
)
1757 ioc
->add_sge
= &mpt_add_sge_64bit_1078
;
1759 ioc
->add_sge
= &mpt_add_sge_64bit
;
1760 ioc
->add_chain
= &mpt_add_chain_64bit
;
1761 ioc
->sg_addr_size
= 8;
1763 ioc
->add_sge
= &mpt_add_sge
;
1764 ioc
->add_chain
= &mpt_add_chain
;
1765 ioc
->sg_addr_size
= 4;
1767 ioc
->SGE_size
= sizeof(u32
) + ioc
->sg_addr_size
;
1769 ioc
->alloc_total
= sizeof(MPT_ADAPTER
);
1770 ioc
->req_sz
= MPT_DEFAULT_FRAME_SIZE
; /* avoid div by zero! */
1771 ioc
->reply_sz
= MPT_REPLY_FRAME_SIZE
;
1775 spin_lock_init(&ioc
->taskmgmt_lock
);
1776 mutex_init(&ioc
->internal_cmds
.mutex
);
1777 init_completion(&ioc
->internal_cmds
.done
);
1778 mutex_init(&ioc
->mptbase_cmds
.mutex
);
1779 init_completion(&ioc
->mptbase_cmds
.done
);
1780 mutex_init(&ioc
->taskmgmt_cmds
.mutex
);
1781 init_completion(&ioc
->taskmgmt_cmds
.done
);
1783 /* Initialize the event logging.
1785 ioc
->eventTypes
= 0; /* None */
1786 ioc
->eventContext
= 0;
1787 ioc
->eventLogSize
= 0;
1795 ioc
->cached_fw
= NULL
;
1797 /* Initilize SCSI Config Data structure
1799 memset(&ioc
->spi_data
, 0, sizeof(SpiCfgData
));
1801 /* Initialize the fc rport list head.
1803 INIT_LIST_HEAD(&ioc
->fc_rports
);
1805 /* Find lookup slot. */
1806 INIT_LIST_HEAD(&ioc
->list
);
1809 /* Initialize workqueue */
1810 INIT_DELAYED_WORK(&ioc
->fault_reset_work
, mpt_fault_reset_work
);
1812 snprintf(ioc
->reset_work_q_name
, MPT_KOBJ_NAME_LEN
,
1813 "mpt_poll_%d", ioc
->id
);
1815 create_singlethread_workqueue(ioc
->reset_work_q_name
);
1816 if (!ioc
->reset_work_q
) {
1817 printk(MYIOC_s_ERR_FMT
"Insufficient memory to add adapter!\n",
1819 pci_release_selected_regions(pdev
, ioc
->bars
);
1824 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"facts @ %p, pfacts[0] @ %p\n",
1825 ioc
->name
, &ioc
->facts
, &ioc
->pfacts
[0]));
1827 pci_read_config_byte(pdev
, PCI_CLASS_REVISION
, &revision
);
1828 mpt_get_product_name(pdev
->vendor
, pdev
->device
, revision
, ioc
->prod_name
);
1830 switch (pdev
->device
)
1832 case MPI_MANUFACTPAGE_DEVICEID_FC939X
:
1833 case MPI_MANUFACTPAGE_DEVICEID_FC949X
:
1834 ioc
->errata_flag_1064
= 1;
1835 case MPI_MANUFACTPAGE_DEVICEID_FC909
:
1836 case MPI_MANUFACTPAGE_DEVICEID_FC929
:
1837 case MPI_MANUFACTPAGE_DEVICEID_FC919
:
1838 case MPI_MANUFACTPAGE_DEVICEID_FC949E
:
1842 case MPI_MANUFACTPAGE_DEVICEID_FC929X
:
1843 if (revision
< XL_929
) {
1844 /* 929X Chip Fix. Set Split transactions level
1845 * for PCIX. Set MOST bits to zero.
1847 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1849 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1851 /* 929XL Chip Fix. Set MMRBC to 0x08.
1853 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1855 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1860 case MPI_MANUFACTPAGE_DEVICEID_FC919X
:
1861 /* 919X Chip Fix. Set Split transactions level
1862 * for PCIX. Set MOST bits to zero.
1864 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1866 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1870 case MPI_MANUFACTPAGE_DEVID_53C1030
:
1871 /* 1030 Chip Fix. Disable Split transactions
1872 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1874 if (revision
< C0_1030
) {
1875 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1877 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1880 case MPI_MANUFACTPAGE_DEVID_1030_53C1035
:
1881 ioc
->bus_type
= SPI
;
1884 case MPI_MANUFACTPAGE_DEVID_SAS1064
:
1885 case MPI_MANUFACTPAGE_DEVID_SAS1068
:
1886 ioc
->errata_flag_1064
= 1;
1887 ioc
->bus_type
= SAS
;
1890 case MPI_MANUFACTPAGE_DEVID_SAS1064E
:
1891 case MPI_MANUFACTPAGE_DEVID_SAS1068E
:
1892 case MPI_MANUFACTPAGE_DEVID_SAS1078
:
1893 ioc
->bus_type
= SAS
;
1898 switch (ioc
->bus_type
) {
1901 ioc
->msi_enable
= mpt_msi_enable_sas
;
1905 ioc
->msi_enable
= mpt_msi_enable_spi
;
1909 ioc
->msi_enable
= mpt_msi_enable_fc
;
1913 ioc
->msi_enable
= 0;
1917 ioc
->fw_events_off
= 1;
1919 if (ioc
->errata_flag_1064
)
1920 pci_disable_io_access(pdev
);
1922 spin_lock_init(&ioc
->FreeQlock
);
1925 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
1927 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1929 /* Set IOC ptr in the pcidev's driver data. */
1930 pci_set_drvdata(ioc
->pcidev
, ioc
);
1932 /* Set lookup ptr. */
1933 list_add_tail(&ioc
->list
, &ioc_list
);
1935 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1937 mpt_detect_bound_ports(ioc
, pdev
);
1939 INIT_LIST_HEAD(&ioc
->fw_event_list
);
1940 spin_lock_init(&ioc
->fw_event_lock
);
1941 snprintf(ioc
->fw_event_q_name
, MPT_KOBJ_NAME_LEN
, "mpt/%d", ioc
->id
);
1942 ioc
->fw_event_q
= create_singlethread_workqueue(ioc
->fw_event_q_name
);
1944 if ((r
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_BRINGUP
,
1946 printk(MYIOC_s_ERR_FMT
"didn't initialize properly! (%d)\n",
1949 list_del(&ioc
->list
);
1951 ioc
->alt_ioc
->alt_ioc
= NULL
;
1952 iounmap(ioc
->memmap
);
1954 pci_release_selected_regions(pdev
, ioc
->bars
);
1956 destroy_workqueue(ioc
->reset_work_q
);
1957 ioc
->reset_work_q
= NULL
;
1960 pci_set_drvdata(pdev
, NULL
);
1964 /* call per device driver probe entry point */
1965 for(cb_idx
= 0; cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
; cb_idx
++) {
1966 if(MptDeviceDriverHandlers
[cb_idx
] &&
1967 MptDeviceDriverHandlers
[cb_idx
]->probe
) {
1968 MptDeviceDriverHandlers
[cb_idx
]->probe(pdev
,id
);
1972 #ifdef CONFIG_PROC_FS
1974 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1976 dent
= proc_mkdir(ioc
->name
, mpt_proc_root_dir
);
1978 ent
= create_proc_entry("info", S_IFREG
|S_IRUGO
, dent
);
1980 ent
->read_proc
= procmpt_iocinfo_read
;
1983 ent
= create_proc_entry("summary", S_IFREG
|S_IRUGO
, dent
);
1985 ent
->read_proc
= procmpt_summary_read
;
1992 queue_delayed_work(ioc
->reset_work_q
, &ioc
->fault_reset_work
,
1993 msecs_to_jiffies(MPT_POLLING_INTERVAL
));
1998 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2000 * mpt_detach - Remove a PCI intelligent MPT adapter.
2001 * @pdev: Pointer to pci_dev structure
2005 mpt_detach(struct pci_dev
*pdev
)
2007 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
2010 unsigned long flags
;
2011 struct workqueue_struct
*wq
;
2014 * Stop polling ioc for fault condition
2016 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
2017 wq
= ioc
->reset_work_q
;
2018 ioc
->reset_work_q
= NULL
;
2019 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
2020 cancel_delayed_work(&ioc
->fault_reset_work
);
2021 destroy_workqueue(wq
);
2023 spin_lock_irqsave(&ioc
->fw_event_lock
, flags
);
2024 wq
= ioc
->fw_event_q
;
2025 ioc
->fw_event_q
= NULL
;
2026 spin_unlock_irqrestore(&ioc
->fw_event_lock
, flags
);
2027 destroy_workqueue(wq
);
2029 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s/summary", ioc
->name
);
2030 remove_proc_entry(pname
, NULL
);
2031 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s/info", ioc
->name
);
2032 remove_proc_entry(pname
, NULL
);
2033 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s", ioc
->name
);
2034 remove_proc_entry(pname
, NULL
);
2036 /* call per device driver remove entry point */
2037 for(cb_idx
= 0; cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
; cb_idx
++) {
2038 if(MptDeviceDriverHandlers
[cb_idx
] &&
2039 MptDeviceDriverHandlers
[cb_idx
]->remove
) {
2040 MptDeviceDriverHandlers
[cb_idx
]->remove(pdev
);
2044 /* Disable interrupts! */
2045 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2048 synchronize_irq(pdev
->irq
);
2050 /* Clear any lingering interrupt */
2051 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
2053 CHIPREG_READ32(&ioc
->chip
->IntStatus
);
2055 mpt_adapter_dispose(ioc
);
2057 pci_set_drvdata(pdev
, NULL
);
2060 /**************************************************************************
2064 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2066 * mpt_suspend - Fusion MPT base driver suspend routine.
2067 * @pdev: Pointer to pci_dev structure
2068 * @state: new state to enter
2071 mpt_suspend(struct pci_dev
*pdev
, pm_message_t state
)
2074 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
2076 device_state
= pci_choose_state(pdev
, state
);
2077 printk(MYIOC_s_INFO_FMT
"pci-suspend: pdev=0x%p, slot=%s, Entering "
2078 "operating state [D%d]\n", ioc
->name
, pdev
, pci_name(pdev
),
2081 /* put ioc into READY_STATE */
2082 if(SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, CAN_SLEEP
)) {
2083 printk(MYIOC_s_ERR_FMT
2084 "pci-suspend: IOC msg unit reset failed!\n", ioc
->name
);
2087 /* disable interrupts */
2088 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2091 /* Clear any lingering interrupt */
2092 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
2094 free_irq(ioc
->pci_irq
, ioc
);
2095 if (ioc
->msi_enable
)
2096 pci_disable_msi(ioc
->pcidev
);
2098 pci_save_state(pdev
);
2099 pci_disable_device(pdev
);
2100 pci_release_selected_regions(pdev
, ioc
->bars
);
2101 pci_set_power_state(pdev
, device_state
);
2105 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2107 * mpt_resume - Fusion MPT base driver resume routine.
2108 * @pdev: Pointer to pci_dev structure
2111 mpt_resume(struct pci_dev
*pdev
)
2113 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
2114 u32 device_state
= pdev
->current_state
;
2118 printk(MYIOC_s_INFO_FMT
"pci-resume: pdev=0x%p, slot=%s, Previous "
2119 "operating state [D%d]\n", ioc
->name
, pdev
, pci_name(pdev
),
2122 pci_set_power_state(pdev
, PCI_D0
);
2123 pci_enable_wake(pdev
, PCI_D0
, 0);
2124 pci_restore_state(pdev
);
2126 err
= mpt_mapresources(ioc
);
2130 if (ioc
->dma_mask
== DMA_BIT_MASK(64)) {
2131 if (pdev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1078
)
2132 ioc
->add_sge
= &mpt_add_sge_64bit_1078
;
2134 ioc
->add_sge
= &mpt_add_sge_64bit
;
2135 ioc
->add_chain
= &mpt_add_chain_64bit
;
2136 ioc
->sg_addr_size
= 8;
2139 ioc
->add_sge
= &mpt_add_sge
;
2140 ioc
->add_chain
= &mpt_add_chain
;
2141 ioc
->sg_addr_size
= 4;
2143 ioc
->SGE_size
= sizeof(u32
) + ioc
->sg_addr_size
;
2145 printk(MYIOC_s_INFO_FMT
"pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
2146 ioc
->name
, (mpt_GetIocState(ioc
, 1) >> MPI_IOC_STATE_SHIFT
),
2147 CHIPREG_READ32(&ioc
->chip
->Doorbell
));
2150 * Errata workaround for SAS pci express:
2151 * Upon returning to the D0 state, the contents of the doorbell will be
2152 * stale data, and this will incorrectly signal to the host driver that
2153 * the firmware is ready to process mpt commands. The workaround is
2154 * to issue a diagnostic reset.
2156 if (ioc
->bus_type
== SAS
&& (pdev
->device
==
2157 MPI_MANUFACTPAGE_DEVID_SAS1068E
|| pdev
->device
==
2158 MPI_MANUFACTPAGE_DEVID_SAS1064E
)) {
2159 if (KickStart(ioc
, 1, CAN_SLEEP
) < 0) {
2160 printk(MYIOC_s_WARN_FMT
"pci-resume: Cannot recover\n",
2166 /* bring ioc to operational state */
2167 printk(MYIOC_s_INFO_FMT
"Sending mpt_do_ioc_recovery\n", ioc
->name
);
2168 recovery_state
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_BRINGUP
,
2170 if (recovery_state
!= 0)
2171 printk(MYIOC_s_WARN_FMT
"pci-resume: Cannot recover, "
2172 "error:[%x]\n", ioc
->name
, recovery_state
);
2174 printk(MYIOC_s_INFO_FMT
2175 "pci-resume: success\n", ioc
->name
);
2183 mpt_signal_reset(u8 index
, MPT_ADAPTER
*ioc
, int reset_phase
)
2185 if ((MptDriverClass
[index
] == MPTSPI_DRIVER
&&
2186 ioc
->bus_type
!= SPI
) ||
2187 (MptDriverClass
[index
] == MPTFC_DRIVER
&&
2188 ioc
->bus_type
!= FC
) ||
2189 (MptDriverClass
[index
] == MPTSAS_DRIVER
&&
2190 ioc
->bus_type
!= SAS
))
2191 /* make sure we only call the relevant reset handler
2194 return (MptResetHandlers
[index
])(ioc
, reset_phase
);
2197 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2199 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
2200 * @ioc: Pointer to MPT adapter structure
2201 * @reason: Event word / reason
2202 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
2204 * This routine performs all the steps necessary to bring the IOC
2205 * to a OPERATIONAL state.
2207 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
2212 * -1 if failed to get board READY
2213 * -2 if READY but IOCFacts Failed
2214 * -3 if READY but PrimeIOCFifos Failed
2215 * -4 if READY but IOCInit Failed
2216 * -5 if failed to enable_device and/or request_selected_regions
2217 * -6 if failed to upload firmware
2220 mpt_do_ioc_recovery(MPT_ADAPTER
*ioc
, u32 reason
, int sleepFlag
)
2222 int hard_reset_done
= 0;
2223 int alt_ioc_ready
= 0;
2228 int reset_alt_ioc_active
= 0;
2229 int irq_allocated
= 0;
2232 printk(MYIOC_s_INFO_FMT
"Initiating %s\n", ioc
->name
,
2233 reason
== MPT_HOSTEVENT_IOC_BRINGUP
? "bringup" : "recovery");
2235 /* Disable reply interrupts (also blocks FreeQ) */
2236 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2240 if (ioc
->alt_ioc
->active
||
2241 reason
== MPT_HOSTEVENT_IOC_RECOVER
) {
2242 reset_alt_ioc_active
= 1;
2243 /* Disable alt-IOC's reply interrupts
2244 * (and FreeQ) for a bit
2246 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
,
2248 ioc
->alt_ioc
->active
= 0;
2253 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)
2256 if ((hard_reset_done
= MakeIocReady(ioc
, hard
, sleepFlag
)) < 0) {
2257 if (hard_reset_done
== -4) {
2258 printk(MYIOC_s_WARN_FMT
"Owned by PEER..skipping!\n",
2261 if (reset_alt_ioc_active
&& ioc
->alt_ioc
) {
2262 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
2263 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
2264 "alt_ioc reply irq re-enabled\n", ioc
->alt_ioc
->name
));
2265 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
, MPI_HIM_DIM
);
2266 ioc
->alt_ioc
->active
= 1;
2270 printk(MYIOC_s_WARN_FMT
2271 "NOT READY WARNING!\n", ioc
->name
);
2277 /* hard_reset_done = 0 if a soft reset was performed
2278 * and 1 if a hard reset was performed.
2280 if (hard_reset_done
&& reset_alt_ioc_active
&& ioc
->alt_ioc
) {
2281 if ((rc
= MakeIocReady(ioc
->alt_ioc
, 0, sleepFlag
)) == 0)
2284 printk(MYIOC_s_WARN_FMT
2285 ": alt-ioc Not ready WARNING!\n",
2286 ioc
->alt_ioc
->name
);
2289 for (ii
=0; ii
<5; ii
++) {
2290 /* Get IOC facts! Allow 5 retries */
2291 if ((rc
= GetIocFacts(ioc
, sleepFlag
, reason
)) == 0)
2297 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2298 "Retry IocFacts failed rc=%x\n", ioc
->name
, rc
));
2300 } else if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
2301 MptDisplayIocCapabilities(ioc
);
2304 if (alt_ioc_ready
) {
2305 if ((rc
= GetIocFacts(ioc
->alt_ioc
, sleepFlag
, reason
)) != 0) {
2306 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2307 "Initial Alt IocFacts failed rc=%x\n",
2309 /* Retry - alt IOC was initialized once
2311 rc
= GetIocFacts(ioc
->alt_ioc
, sleepFlag
, reason
);
2314 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2315 "Retry Alt IocFacts failed rc=%x\n", ioc
->name
, rc
));
2317 reset_alt_ioc_active
= 0;
2318 } else if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
2319 MptDisplayIocCapabilities(ioc
->alt_ioc
);
2323 if ((ret
== 0) && (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) &&
2324 (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)) {
2325 pci_release_selected_regions(ioc
->pcidev
, ioc
->bars
);
2326 ioc
->bars
= pci_select_bars(ioc
->pcidev
, IORESOURCE_MEM
|
2328 if (pci_enable_device(ioc
->pcidev
))
2330 if (pci_request_selected_regions(ioc
->pcidev
, ioc
->bars
,
2336 * Device is reset now. It must have de-asserted the interrupt line
2337 * (if it was asserted) and it should be safe to register for the
2340 if ((ret
== 0) && (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)) {
2342 if (ioc
->pcidev
->irq
) {
2343 if (ioc
->msi_enable
&& !pci_enable_msi(ioc
->pcidev
))
2344 printk(MYIOC_s_INFO_FMT
"PCI-MSI enabled\n",
2347 ioc
->msi_enable
= 0;
2348 rc
= request_irq(ioc
->pcidev
->irq
, mpt_interrupt
,
2349 IRQF_SHARED
, ioc
->name
, ioc
);
2351 printk(MYIOC_s_ERR_FMT
"Unable to allocate "
2353 ioc
->name
, ioc
->pcidev
->irq
);
2354 if (ioc
->msi_enable
)
2355 pci_disable_msi(ioc
->pcidev
);
2360 ioc
->pci_irq
= ioc
->pcidev
->irq
;
2361 pci_set_master(ioc
->pcidev
); /* ?? */
2362 pci_set_drvdata(ioc
->pcidev
, ioc
);
2363 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
2364 "installed at interrupt %d\n", ioc
->name
,
2369 /* Prime reply & request queues!
2370 * (mucho alloc's) Must be done prior to
2371 * init as upper addresses are needed for init.
2372 * If fails, continue with alt-ioc processing
2374 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"PrimeIocFifos\n",
2376 if ((ret
== 0) && ((rc
= PrimeIocFifos(ioc
)) != 0))
2379 /* May need to check/upload firmware & data here!
2380 * If fails, continue with alt-ioc processing
2382 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"SendIocInit\n",
2384 if ((ret
== 0) && ((rc
= SendIocInit(ioc
, sleepFlag
)) != 0))
2387 if (alt_ioc_ready
&& ((rc
= PrimeIocFifos(ioc
->alt_ioc
)) != 0)) {
2388 printk(MYIOC_s_WARN_FMT
2389 ": alt-ioc (%d) FIFO mgmt alloc WARNING!\n",
2390 ioc
->alt_ioc
->name
, rc
);
2392 reset_alt_ioc_active
= 0;
2395 if (alt_ioc_ready
) {
2396 if ((rc
= SendIocInit(ioc
->alt_ioc
, sleepFlag
)) != 0) {
2398 reset_alt_ioc_active
= 0;
2399 printk(MYIOC_s_WARN_FMT
2400 ": alt-ioc: (%d) init failure WARNING!\n",
2401 ioc
->alt_ioc
->name
, rc
);
2405 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
){
2406 if (ioc
->upload_fw
) {
2407 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2408 "firmware upload required!\n", ioc
->name
));
2410 /* Controller is not operational, cannot do upload
2413 rc
= mpt_do_upload(ioc
, sleepFlag
);
2415 if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
) {
2417 * Maintain only one pointer to FW memory
2418 * so there will not be two attempt to
2419 * downloadboot onboard dual function
2420 * chips (mpt_adapter_disable,
2423 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2424 "mpt_upload: alt_%s has cached_fw=%p \n",
2425 ioc
->name
, ioc
->alt_ioc
->name
, ioc
->alt_ioc
->cached_fw
));
2426 ioc
->cached_fw
= NULL
;
2429 printk(MYIOC_s_WARN_FMT
2430 "firmware upload failure!\n", ioc
->name
);
2437 /* Enable MPT base driver management of EventNotification
2438 * and EventAck handling.
2440 if ((ret
== 0) && (!ioc
->facts
.EventState
)) {
2441 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
2442 "SendEventNotification\n",
2444 ret
= SendEventNotification(ioc
, 1, sleepFlag
); /* 1=Enable */
2447 if (ioc
->alt_ioc
&& alt_ioc_ready
&& !ioc
->alt_ioc
->facts
.EventState
)
2448 rc
= SendEventNotification(ioc
->alt_ioc
, 1, sleepFlag
);
2451 /* Enable! (reply interrupt) */
2452 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, MPI_HIM_DIM
);
2455 if (rc
== 0) { /* alt ioc */
2456 if (reset_alt_ioc_active
&& ioc
->alt_ioc
) {
2457 /* (re)Enable alt-IOC! (reply interrupt) */
2458 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"alt-ioc"
2459 "reply irq re-enabled\n",
2460 ioc
->alt_ioc
->name
));
2461 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
,
2463 ioc
->alt_ioc
->active
= 1;
2468 /* Add additional "reason" check before call to GetLanConfigPages
2469 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2470 * recursive scenario; GetLanConfigPages times out, timer expired
2471 * routine calls HardResetHandler, which calls into here again,
2472 * and we try GetLanConfigPages again...
2474 if ((ret
== 0) && (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)) {
2477 * Initalize link list for inactive raid volumes.
2479 mutex_init(&ioc
->raid_data
.inactive_list_mutex
);
2480 INIT_LIST_HEAD(&ioc
->raid_data
.inactive_list
);
2482 switch (ioc
->bus_type
) {
2485 /* clear persistency table */
2486 if(ioc
->facts
.IOCExceptions
&
2487 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL
) {
2488 ret
= mptbase_sas_persist_operation(ioc
,
2489 MPI_SAS_OP_CLEAR_NOT_PRESENT
);
2496 mpt_findImVolumes(ioc
);
2498 /* Check, and possibly reset, the coalescing value
2500 mpt_read_ioc_pg_1(ioc
);
2505 if ((ioc
->pfacts
[0].ProtocolFlags
&
2506 MPI_PORTFACTS_PROTOCOL_LAN
) &&
2507 (ioc
->lan_cnfg_page0
.Header
.PageLength
== 0)) {
2509 * Pre-fetch the ports LAN MAC address!
2510 * (LANPage1_t stuff)
2512 (void) GetLanConfigPages(ioc
);
2513 a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
2514 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2515 "LanAddr = %02X:%02X:%02X"
2516 ":%02X:%02X:%02X\n",
2517 ioc
->name
, a
[5], a
[4],
2518 a
[3], a
[2], a
[1], a
[0]));
2523 /* Get NVRAM and adapter maximums from SPP 0 and 2
2525 mpt_GetScsiPortSettings(ioc
, 0);
2527 /* Get version and length of SDP 1
2529 mpt_readScsiDevicePageHeaders(ioc
, 0);
2533 if (ioc
->facts
.MsgVersion
>= MPI_VERSION_01_02
)
2534 mpt_findImVolumes(ioc
);
2536 /* Check, and possibly reset, the coalescing value
2538 mpt_read_ioc_pg_1(ioc
);
2540 mpt_read_ioc_pg_4(ioc
);
2545 GetIoUnitPage2(ioc
);
2546 mpt_get_manufacturing_pg_0(ioc
);
2550 if ((ret
!= 0) && irq_allocated
) {
2551 free_irq(ioc
->pci_irq
, ioc
);
2552 if (ioc
->msi_enable
)
2553 pci_disable_msi(ioc
->pcidev
);
2558 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2560 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2561 * @ioc: Pointer to MPT adapter structure
2562 * @pdev: Pointer to (struct pci_dev) structure
2564 * Search for PCI bus/dev_function which matches
2565 * PCI bus/dev_function (+/-1) for newly discovered 929,
2566 * 929X, 1030 or 1035.
2568 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2569 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2572 mpt_detect_bound_ports(MPT_ADAPTER
*ioc
, struct pci_dev
*pdev
)
2574 struct pci_dev
*peer
=NULL
;
2575 unsigned int slot
= PCI_SLOT(pdev
->devfn
);
2576 unsigned int func
= PCI_FUNC(pdev
->devfn
);
2577 MPT_ADAPTER
*ioc_srch
;
2579 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"PCI device %s devfn=%x/%x,"
2580 " searching for devfn match on %x or %x\n",
2581 ioc
->name
, pci_name(pdev
), pdev
->bus
->number
,
2582 pdev
->devfn
, func
-1, func
+1));
2584 peer
= pci_get_slot(pdev
->bus
, PCI_DEVFN(slot
,func
-1));
2586 peer
= pci_get_slot(pdev
->bus
, PCI_DEVFN(slot
,func
+1));
2591 list_for_each_entry(ioc_srch
, &ioc_list
, list
) {
2592 struct pci_dev
*_pcidev
= ioc_srch
->pcidev
;
2593 if (_pcidev
== peer
) {
2594 /* Paranoia checks */
2595 if (ioc
->alt_ioc
!= NULL
) {
2596 printk(MYIOC_s_WARN_FMT
2597 "Oops, already bound (%s <==> %s)!\n",
2598 ioc
->name
, ioc
->name
, ioc
->alt_ioc
->name
);
2600 } else if (ioc_srch
->alt_ioc
!= NULL
) {
2601 printk(MYIOC_s_WARN_FMT
2602 "Oops, already bound (%s <==> %s)!\n",
2603 ioc_srch
->name
, ioc_srch
->name
,
2604 ioc_srch
->alt_ioc
->name
);
2607 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2608 "FOUND! binding %s <==> %s\n",
2609 ioc
->name
, ioc
->name
, ioc_srch
->name
));
2610 ioc_srch
->alt_ioc
= ioc
;
2611 ioc
->alt_ioc
= ioc_srch
;
2617 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2619 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2620 * @ioc: Pointer to MPT adapter structure
2623 mpt_adapter_disable(MPT_ADAPTER
*ioc
)
2628 if (ioc
->cached_fw
!= NULL
) {
2629 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2630 "%s: Pushing FW onto adapter\n", __func__
, ioc
->name
));
2631 if ((ret
= mpt_downloadboot(ioc
, (MpiFwHeader_t
*)
2632 ioc
->cached_fw
, CAN_SLEEP
)) < 0) {
2633 printk(MYIOC_s_WARN_FMT
2634 ": firmware downloadboot failure (%d)!\n",
2640 * Put the controller into ready state (if its not already)
2642 if (mpt_GetIocState(ioc
, 1) != MPI_IOC_STATE_READY
) {
2643 if (!SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
,
2645 if (mpt_GetIocState(ioc
, 1) != MPI_IOC_STATE_READY
)
2646 printk(MYIOC_s_ERR_FMT
"%s: IOC msg unit "
2647 "reset failed to put ioc in ready state!\n",
2648 ioc
->name
, __func__
);
2650 printk(MYIOC_s_ERR_FMT
"%s: IOC msg unit reset "
2651 "failed!\n", ioc
->name
, __func__
);
2655 /* Disable adapter interrupts! */
2656 synchronize_irq(ioc
->pcidev
->irq
);
2657 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2660 /* Clear any lingering interrupt */
2661 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
2662 CHIPREG_READ32(&ioc
->chip
->IntStatus
);
2664 if (ioc
->alloc
!= NULL
) {
2666 dexitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"free @ %p, sz=%d bytes\n",
2667 ioc
->name
, ioc
->alloc
, ioc
->alloc_sz
));
2668 pci_free_consistent(ioc
->pcidev
, sz
,
2669 ioc
->alloc
, ioc
->alloc_dma
);
2670 ioc
->reply_frames
= NULL
;
2671 ioc
->req_frames
= NULL
;
2673 ioc
->alloc_total
-= sz
;
2676 if (ioc
->sense_buf_pool
!= NULL
) {
2677 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
2678 pci_free_consistent(ioc
->pcidev
, sz
,
2679 ioc
->sense_buf_pool
, ioc
->sense_buf_pool_dma
);
2680 ioc
->sense_buf_pool
= NULL
;
2681 ioc
->alloc_total
-= sz
;
2684 if (ioc
->events
!= NULL
){
2685 sz
= MPTCTL_EVENT_LOG_SIZE
* sizeof(MPT_IOCTL_EVENTS
);
2688 ioc
->alloc_total
-= sz
;
2691 mpt_free_fw_memory(ioc
);
2693 kfree(ioc
->spi_data
.nvram
);
2694 mpt_inactive_raid_list_free(ioc
);
2695 kfree(ioc
->raid_data
.pIocPg2
);
2696 kfree(ioc
->raid_data
.pIocPg3
);
2697 ioc
->spi_data
.nvram
= NULL
;
2698 ioc
->raid_data
.pIocPg3
= NULL
;
2700 if (ioc
->spi_data
.pIocPg4
!= NULL
) {
2701 sz
= ioc
->spi_data
.IocPg4Sz
;
2702 pci_free_consistent(ioc
->pcidev
, sz
,
2703 ioc
->spi_data
.pIocPg4
,
2704 ioc
->spi_data
.IocPg4_dma
);
2705 ioc
->spi_data
.pIocPg4
= NULL
;
2706 ioc
->alloc_total
-= sz
;
2709 if (ioc
->ReqToChain
!= NULL
) {
2710 kfree(ioc
->ReqToChain
);
2711 kfree(ioc
->RequestNB
);
2712 ioc
->ReqToChain
= NULL
;
2715 kfree(ioc
->ChainToChain
);
2716 ioc
->ChainToChain
= NULL
;
2718 if (ioc
->HostPageBuffer
!= NULL
) {
2719 if((ret
= mpt_host_page_access_control(ioc
,
2720 MPI_DB_HPBAC_FREE_BUFFER
, NO_SLEEP
)) != 0) {
2721 printk(MYIOC_s_ERR_FMT
2722 ": %s: host page buffers free failed (%d)!\n",
2723 ioc
->name
, __func__
, ret
);
2725 dexitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2726 "HostPageBuffer free @ %p, sz=%d bytes\n",
2727 ioc
->name
, ioc
->HostPageBuffer
,
2728 ioc
->HostPageBuffer_sz
));
2729 pci_free_consistent(ioc
->pcidev
, ioc
->HostPageBuffer_sz
,
2730 ioc
->HostPageBuffer
, ioc
->HostPageBuffer_dma
);
2731 ioc
->HostPageBuffer
= NULL
;
2732 ioc
->HostPageBuffer_sz
= 0;
2733 ioc
->alloc_total
-= ioc
->HostPageBuffer_sz
;
2736 pci_set_drvdata(ioc
->pcidev
, NULL
);
2738 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2740 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2741 * @ioc: Pointer to MPT adapter structure
2743 * This routine unregisters h/w resources and frees all alloc'd memory
2744 * associated with a MPT adapter structure.
2747 mpt_adapter_dispose(MPT_ADAPTER
*ioc
)
2749 int sz_first
, sz_last
;
2754 sz_first
= ioc
->alloc_total
;
2756 mpt_adapter_disable(ioc
);
2758 if (ioc
->pci_irq
!= -1) {
2759 free_irq(ioc
->pci_irq
, ioc
);
2760 if (ioc
->msi_enable
)
2761 pci_disable_msi(ioc
->pcidev
);
2765 if (ioc
->memmap
!= NULL
) {
2766 iounmap(ioc
->memmap
);
2770 pci_disable_device(ioc
->pcidev
);
2771 pci_release_selected_regions(ioc
->pcidev
, ioc
->bars
);
2773 #if defined(CONFIG_MTRR) && 0
2774 if (ioc
->mtrr_reg
> 0) {
2775 mtrr_del(ioc
->mtrr_reg
, 0, 0);
2776 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
"MTRR region de-registered\n", ioc
->name
));
2780 /* Zap the adapter lookup ptr! */
2781 list_del(&ioc
->list
);
2783 sz_last
= ioc
->alloc_total
;
2784 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
"free'd %d of %d bytes\n",
2785 ioc
->name
, sz_first
-sz_last
+(int)sizeof(*ioc
), sz_first
));
2788 ioc
->alt_ioc
->alt_ioc
= NULL
;
2793 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2795 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2796 * @ioc: Pointer to MPT adapter structure
2799 MptDisplayIocCapabilities(MPT_ADAPTER
*ioc
)
2803 printk(KERN_INFO
"%s: ", ioc
->name
);
2805 printk("%s: ", ioc
->prod_name
);
2806 printk("Capabilities={");
2808 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_INITIATOR
) {
2809 printk("Initiator");
2813 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_TARGET
) {
2814 printk("%sTarget", i
? "," : "");
2818 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
) {
2819 printk("%sLAN", i
? "," : "");
2825 * This would probably evoke more questions than it's worth
2827 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_TARGET
) {
2828 printk("%sLogBusAddr", i
? "," : "");
2836 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2838 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2839 * @ioc: Pointer to MPT_ADAPTER structure
2840 * @force: Force hard KickStart of IOC
2841 * @sleepFlag: Specifies whether the process can sleep
2844 * 1 - DIAG reset and READY
2845 * 0 - READY initially OR soft reset and READY
2846 * -1 - Any failure on KickStart
2847 * -2 - Msg Unit Reset Failed
2848 * -3 - IO Unit Reset Failed
2849 * -4 - IOC owned by a PEER
2852 MakeIocReady(MPT_ADAPTER
*ioc
, int force
, int sleepFlag
)
2857 int hard_reset_done
= 0;
2862 /* Get current [raw] IOC state */
2863 ioc_state
= mpt_GetIocState(ioc
, 0);
2864 dhsprintk(ioc
, printk(MYIOC_s_INFO_FMT
"MakeIocReady [raw] state=%08x\n", ioc
->name
, ioc_state
));
2867 * Check to see if IOC got left/stuck in doorbell handshake
2868 * grip of death. If so, hard reset the IOC.
2870 if (ioc_state
& MPI_DOORBELL_ACTIVE
) {
2872 printk(MYIOC_s_WARN_FMT
"Unexpected doorbell active!\n",
2876 /* Is it already READY? */
2878 ((ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_READY
)) {
2879 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
2880 "IOC is in READY state\n", ioc
->name
));
2885 * Check to see if IOC is in FAULT state.
2887 if ((ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_FAULT
) {
2889 printk(MYIOC_s_WARN_FMT
"IOC is in FAULT state!!!\n",
2891 printk(MYIOC_s_WARN_FMT
" FAULT code = %04xh\n",
2892 ioc
->name
, ioc_state
& MPI_DOORBELL_DATA_MASK
);
2896 * Hmmm... Did it get left operational?
2898 if ((ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_OPERATIONAL
) {
2899 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"IOC operational unexpected\n",
2903 * If PCI Peer, exit.
2904 * Else, if no fault conditions are present, issue a MessageUnitReset
2905 * Else, fall through to KickStart case
2907 whoinit
= (ioc_state
& MPI_DOORBELL_WHO_INIT_MASK
) >> MPI_DOORBELL_WHO_INIT_SHIFT
;
2908 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
2909 "whoinit 0x%x statefault %d force %d\n",
2910 ioc
->name
, whoinit
, statefault
, force
));
2911 if (whoinit
== MPI_WHOINIT_PCI_PEER
)
2914 if ((statefault
== 0 ) && (force
== 0)) {
2915 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
)) == 0)
2922 hard_reset_done
= KickStart(ioc
, statefault
||force
, sleepFlag
);
2923 if (hard_reset_done
< 0)
2927 * Loop here waiting for IOC to come READY.
2930 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 5; /* 5 seconds */
2932 while ((ioc_state
= mpt_GetIocState(ioc
, 1)) != MPI_IOC_STATE_READY
) {
2933 if (ioc_state
== MPI_IOC_STATE_OPERATIONAL
) {
2935 * BIOS or previous driver load left IOC in OP state.
2936 * Reset messaging FIFOs.
2938 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
)) != 0) {
2939 printk(MYIOC_s_ERR_FMT
"IOC msg unit reset failed!\n", ioc
->name
);
2942 } else if (ioc_state
== MPI_IOC_STATE_RESET
) {
2944 * Something is wrong. Try to get IOC back
2947 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IO_UNIT_RESET
, sleepFlag
)) != 0) {
2948 printk(MYIOC_s_ERR_FMT
"IO unit reset failed!\n", ioc
->name
);
2955 printk(MYIOC_s_ERR_FMT
2956 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
2957 ioc
->name
, ioc_state
, (int)((ii
+5)/HZ
));
2961 if (sleepFlag
== CAN_SLEEP
) {
2964 mdelay (1); /* 1 msec delay */
2969 if (statefault
< 3) {
2970 printk(MYIOC_s_INFO_FMT
"Recovered from %s\n", ioc
->name
,
2971 statefault
== 1 ? "stuck handshake" : "IOC FAULT");
2974 return hard_reset_done
;
2977 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2979 * mpt_GetIocState - Get the current state of a MPT adapter.
2980 * @ioc: Pointer to MPT_ADAPTER structure
2981 * @cooked: Request raw or cooked IOC state
2983 * Returns all IOC Doorbell register bits if cooked==0, else just the
2984 * Doorbell bits in MPI_IOC_STATE_MASK.
2987 mpt_GetIocState(MPT_ADAPTER
*ioc
, int cooked
)
2992 s
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
2993 sc
= s
& MPI_IOC_STATE_MASK
;
2996 ioc
->last_state
= sc
;
2998 return cooked
? sc
: s
;
3001 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3003 * GetIocFacts - Send IOCFacts request to MPT adapter.
3004 * @ioc: Pointer to MPT_ADAPTER structure
3005 * @sleepFlag: Specifies whether the process can sleep
3006 * @reason: If recovery, only update facts.
3008 * Returns 0 for success, non-zero for failure.
3011 GetIocFacts(MPT_ADAPTER
*ioc
, int sleepFlag
, int reason
)
3013 IOCFacts_t get_facts
;
3014 IOCFactsReply_t
*facts
;
3022 /* IOC *must* NOT be in RESET state! */
3023 if (ioc
->last_state
== MPI_IOC_STATE_RESET
) {
3024 printk(KERN_ERR MYNAM
3025 ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
3026 ioc
->name
, ioc
->last_state
);
3030 facts
= &ioc
->facts
;
3032 /* Destination (reply area)... */
3033 reply_sz
= sizeof(*facts
);
3034 memset(facts
, 0, reply_sz
);
3036 /* Request area (get_facts on the stack right now!) */
3037 req_sz
= sizeof(get_facts
);
3038 memset(&get_facts
, 0, req_sz
);
3040 get_facts
.Function
= MPI_FUNCTION_IOC_FACTS
;
3041 /* Assert: All other get_facts fields are zero! */
3043 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3044 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
3045 ioc
->name
, req_sz
, reply_sz
));
3047 /* No non-zero fields in the get_facts request are greater than
3048 * 1 byte in size, so we can just fire it off as is.
3050 r
= mpt_handshake_req_reply_wait(ioc
, req_sz
, (u32
*)&get_facts
,
3051 reply_sz
, (u16
*)facts
, 5 /*seconds*/, sleepFlag
);
3056 * Now byte swap (GRRR) the necessary fields before any further
3057 * inspection of reply contents.
3059 * But need to do some sanity checks on MsgLength (byte) field
3060 * to make sure we don't zero IOC's req_sz!
3062 /* Did we get a valid reply? */
3063 if (facts
->MsgLength
> offsetof(IOCFactsReply_t
, RequestFrameSize
)/sizeof(u32
)) {
3064 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
3066 * If not been here, done that, save off first WhoInit value
3068 if (ioc
->FirstWhoInit
== WHOINIT_UNKNOWN
)
3069 ioc
->FirstWhoInit
= facts
->WhoInit
;
3072 facts
->MsgVersion
= le16_to_cpu(facts
->MsgVersion
);
3073 facts
->MsgContext
= le32_to_cpu(facts
->MsgContext
);
3074 facts
->IOCExceptions
= le16_to_cpu(facts
->IOCExceptions
);
3075 facts
->IOCStatus
= le16_to_cpu(facts
->IOCStatus
);
3076 facts
->IOCLogInfo
= le32_to_cpu(facts
->IOCLogInfo
);
3077 status
= le16_to_cpu(facts
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
3078 /* CHECKME! IOCStatus, IOCLogInfo */
3080 facts
->ReplyQueueDepth
= le16_to_cpu(facts
->ReplyQueueDepth
);
3081 facts
->RequestFrameSize
= le16_to_cpu(facts
->RequestFrameSize
);
3084 * FC f/w version changed between 1.1 and 1.2
3085 * Old: u16{Major(4),Minor(4),SubMinor(8)}
3086 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
3088 if (facts
->MsgVersion
< MPI_VERSION_01_02
) {
3090 * Handle old FC f/w style, convert to new...
3092 u16 oldv
= le16_to_cpu(facts
->Reserved_0101_FWVersion
);
3093 facts
->FWVersion
.Word
=
3094 ((oldv
<<12) & 0xFF000000) |
3095 ((oldv
<<8) & 0x000FFF00);
3097 facts
->FWVersion
.Word
= le32_to_cpu(facts
->FWVersion
.Word
);
3099 facts
->ProductID
= le16_to_cpu(facts
->ProductID
);
3101 if ((ioc
->facts
.ProductID
& MPI_FW_HEADER_PID_PROD_MASK
)
3102 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI
)
3103 ioc
->ir_firmware
= 1;
3105 facts
->CurrentHostMfaHighAddr
=
3106 le32_to_cpu(facts
->CurrentHostMfaHighAddr
);
3107 facts
->GlobalCredits
= le16_to_cpu(facts
->GlobalCredits
);
3108 facts
->CurrentSenseBufferHighAddr
=
3109 le32_to_cpu(facts
->CurrentSenseBufferHighAddr
);
3110 facts
->CurReplyFrameSize
=
3111 le16_to_cpu(facts
->CurReplyFrameSize
);
3112 facts
->IOCCapabilities
= le32_to_cpu(facts
->IOCCapabilities
);
3115 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
3116 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
3117 * to 14 in MPI-1.01.0x.
3119 if (facts
->MsgLength
>= (offsetof(IOCFactsReply_t
,FWImageSize
) + 7)/4 &&
3120 facts
->MsgVersion
> MPI_VERSION_01_00
) {
3121 facts
->FWImageSize
= le32_to_cpu(facts
->FWImageSize
);
3124 sz
= facts
->FWImageSize
;
3129 facts
->FWImageSize
= sz
;
3131 if (!facts
->RequestFrameSize
) {
3132 /* Something is wrong! */
3133 printk(MYIOC_s_ERR_FMT
"IOC reported invalid 0 request size!\n",
3138 r
= sz
= facts
->BlockSize
;
3139 vv
= ((63 / (sz
* 4)) + 1) & 0x03;
3140 ioc
->NB_for_64_byte_frame
= vv
;
3146 ioc
->NBShiftFactor
= shiftFactor
;
3147 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3148 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
3149 ioc
->name
, vv
, shiftFactor
, r
));
3151 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
3153 * Set values for this IOC's request & reply frame sizes,
3154 * and request & reply queue depths...
3156 ioc
->req_sz
= min(MPT_DEFAULT_FRAME_SIZE
, facts
->RequestFrameSize
* 4);
3157 ioc
->req_depth
= min_t(int, MPT_MAX_REQ_DEPTH
, facts
->GlobalCredits
);
3158 ioc
->reply_sz
= MPT_REPLY_FRAME_SIZE
;
3159 ioc
->reply_depth
= min_t(int, MPT_DEFAULT_REPLY_DEPTH
, facts
->ReplyQueueDepth
);
3161 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"reply_sz=%3d, reply_depth=%4d\n",
3162 ioc
->name
, ioc
->reply_sz
, ioc
->reply_depth
));
3163 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"req_sz =%3d, req_depth =%4d\n",
3164 ioc
->name
, ioc
->req_sz
, ioc
->req_depth
));
3166 /* Get port facts! */
3167 if ( (r
= GetPortFacts(ioc
, 0, sleepFlag
)) != 0 )
3171 printk(MYIOC_s_ERR_FMT
3172 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
3173 ioc
->name
, facts
->MsgLength
, (offsetof(IOCFactsReply_t
,
3174 RequestFrameSize
)/sizeof(u32
)));
3181 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3183 * GetPortFacts - Send PortFacts request to MPT adapter.
3184 * @ioc: Pointer to MPT_ADAPTER structure
3185 * @portnum: Port number
3186 * @sleepFlag: Specifies whether the process can sleep
3188 * Returns 0 for success, non-zero for failure.
3191 GetPortFacts(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
)
3193 PortFacts_t get_pfacts
;
3194 PortFactsReply_t
*pfacts
;
3200 /* IOC *must* NOT be in RESET state! */
3201 if (ioc
->last_state
== MPI_IOC_STATE_RESET
) {
3202 printk(MYIOC_s_ERR_FMT
"Can't get PortFacts NOT READY! (%08x)\n",
3203 ioc
->name
, ioc
->last_state
);
3207 pfacts
= &ioc
->pfacts
[portnum
];
3209 /* Destination (reply area)... */
3210 reply_sz
= sizeof(*pfacts
);
3211 memset(pfacts
, 0, reply_sz
);
3213 /* Request area (get_pfacts on the stack right now!) */
3214 req_sz
= sizeof(get_pfacts
);
3215 memset(&get_pfacts
, 0, req_sz
);
3217 get_pfacts
.Function
= MPI_FUNCTION_PORT_FACTS
;
3218 get_pfacts
.PortNumber
= portnum
;
3219 /* Assert: All other get_pfacts fields are zero! */
3221 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending get PortFacts(%d) request\n",
3222 ioc
->name
, portnum
));
3224 /* No non-zero fields in the get_pfacts request are greater than
3225 * 1 byte in size, so we can just fire it off as is.
3227 ii
= mpt_handshake_req_reply_wait(ioc
, req_sz
, (u32
*)&get_pfacts
,
3228 reply_sz
, (u16
*)pfacts
, 5 /*seconds*/, sleepFlag
);
3232 /* Did we get a valid reply? */
3234 /* Now byte swap the necessary fields in the response. */
3235 pfacts
->MsgContext
= le32_to_cpu(pfacts
->MsgContext
);
3236 pfacts
->IOCStatus
= le16_to_cpu(pfacts
->IOCStatus
);
3237 pfacts
->IOCLogInfo
= le32_to_cpu(pfacts
->IOCLogInfo
);
3238 pfacts
->MaxDevices
= le16_to_cpu(pfacts
->MaxDevices
);
3239 pfacts
->PortSCSIID
= le16_to_cpu(pfacts
->PortSCSIID
);
3240 pfacts
->ProtocolFlags
= le16_to_cpu(pfacts
->ProtocolFlags
);
3241 pfacts
->MaxPostedCmdBuffers
= le16_to_cpu(pfacts
->MaxPostedCmdBuffers
);
3242 pfacts
->MaxPersistentIDs
= le16_to_cpu(pfacts
->MaxPersistentIDs
);
3243 pfacts
->MaxLanBuckets
= le16_to_cpu(pfacts
->MaxLanBuckets
);
3245 max_id
= (ioc
->bus_type
== SAS
) ? pfacts
->PortSCSIID
:
3247 ioc
->devices_per_bus
= (max_id
> 255) ? 256 : max_id
;
3248 ioc
->number_of_buses
= (ioc
->devices_per_bus
< 256) ? 1 : max_id
/256;
3251 * Place all the devices on channels
3255 if (mpt_channel_mapping
) {
3256 ioc
->devices_per_bus
= 1;
3257 ioc
->number_of_buses
= (max_id
> 255) ? 255 : max_id
;
3263 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3265 * SendIocInit - Send IOCInit request to MPT adapter.
3266 * @ioc: Pointer to MPT_ADAPTER structure
3267 * @sleepFlag: Specifies whether the process can sleep
3269 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
3271 * Returns 0 for success, non-zero for failure.
3274 SendIocInit(MPT_ADAPTER
*ioc
, int sleepFlag
)
3277 MPIDefaultReply_t init_reply
;
3283 memset(&ioc_init
, 0, sizeof(ioc_init
));
3284 memset(&init_reply
, 0, sizeof(init_reply
));
3286 ioc_init
.WhoInit
= MPI_WHOINIT_HOST_DRIVER
;
3287 ioc_init
.Function
= MPI_FUNCTION_IOC_INIT
;
3289 /* If we are in a recovery mode and we uploaded the FW image,
3290 * then this pointer is not NULL. Skip the upload a second time.
3291 * Set this flag if cached_fw set for either IOC.
3293 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)
3297 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"upload_fw %d facts.Flags=%x\n",
3298 ioc
->name
, ioc
->upload_fw
, ioc
->facts
.Flags
));
3300 ioc_init
.MaxDevices
= (U8
)ioc
->devices_per_bus
;
3301 ioc_init
.MaxBuses
= (U8
)ioc
->number_of_buses
;
3303 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"facts.MsgVersion=%x\n",
3304 ioc
->name
, ioc
->facts
.MsgVersion
));
3305 if (ioc
->facts
.MsgVersion
>= MPI_VERSION_01_05
) {
3306 // set MsgVersion and HeaderVersion host driver was built with
3307 ioc_init
.MsgVersion
= cpu_to_le16(MPI_VERSION
);
3308 ioc_init
.HeaderVersion
= cpu_to_le16(MPI_HEADER_VERSION
);
3310 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT
) {
3311 ioc_init
.HostPageBufferSGE
= ioc
->facts
.HostPageBufferSGE
;
3312 } else if(mpt_host_page_alloc(ioc
, &ioc_init
))
3315 ioc_init
.ReplyFrameSize
= cpu_to_le16(ioc
->reply_sz
); /* in BYTES */
3317 if (ioc
->sg_addr_size
== sizeof(u64
)) {
3318 /* Save the upper 32-bits of the request
3319 * (reply) and sense buffers.
3321 ioc_init
.HostMfaHighAddr
= cpu_to_le32((u32
)((u64
)ioc
->alloc_dma
>> 32));
3322 ioc_init
.SenseBufferHighAddr
= cpu_to_le32((u32
)((u64
)ioc
->sense_buf_pool_dma
>> 32));
3324 /* Force 32-bit addressing */
3325 ioc_init
.HostMfaHighAddr
= cpu_to_le32(0);
3326 ioc_init
.SenseBufferHighAddr
= cpu_to_le32(0);
3329 ioc
->facts
.CurrentHostMfaHighAddr
= ioc_init
.HostMfaHighAddr
;
3330 ioc
->facts
.CurrentSenseBufferHighAddr
= ioc_init
.SenseBufferHighAddr
;
3331 ioc
->facts
.MaxDevices
= ioc_init
.MaxDevices
;
3332 ioc
->facts
.MaxBuses
= ioc_init
.MaxBuses
;
3334 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending IOCInit (req @ %p)\n",
3335 ioc
->name
, &ioc_init
));
3337 r
= mpt_handshake_req_reply_wait(ioc
, sizeof(IOCInit_t
), (u32
*)&ioc_init
,
3338 sizeof(MPIDefaultReply_t
), (u16
*)&init_reply
, 10 /*seconds*/, sleepFlag
);
3340 printk(MYIOC_s_ERR_FMT
"Sending IOCInit failed(%d)!\n",ioc
->name
, r
);
3344 /* No need to byte swap the multibyte fields in the reply
3345 * since we don't even look at its contents.
3348 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending PortEnable (req @ %p)\n",
3349 ioc
->name
, &ioc_init
));
3351 if ((r
= SendPortEnable(ioc
, 0, sleepFlag
)) != 0) {
3352 printk(MYIOC_s_ERR_FMT
"Sending PortEnable failed(%d)!\n",ioc
->name
, r
);
3356 /* YIKES! SUPER IMPORTANT!!!
3357 * Poll IocState until _OPERATIONAL while IOC is doing
3358 * LoopInit and TargetDiscovery!
3361 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 60; /* 60 seconds */
3362 state
= mpt_GetIocState(ioc
, 1);
3363 while (state
!= MPI_IOC_STATE_OPERATIONAL
&& --cntdn
) {
3364 if (sleepFlag
== CAN_SLEEP
) {
3371 printk(MYIOC_s_ERR_FMT
"Wait IOC_OP state timeout(%d)!\n",
3372 ioc
->name
, (int)((count
+5)/HZ
));
3376 state
= mpt_GetIocState(ioc
, 1);
3379 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Wait IOC_OPERATIONAL state (cnt=%d)\n",
3382 ioc
->aen_event_read_flag
=0;
3386 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3388 * SendPortEnable - Send PortEnable request to MPT adapter port.
3389 * @ioc: Pointer to MPT_ADAPTER structure
3390 * @portnum: Port number to enable
3391 * @sleepFlag: Specifies whether the process can sleep
3393 * Send PortEnable to bring IOC to OPERATIONAL state.
3395 * Returns 0 for success, non-zero for failure.
3398 SendPortEnable(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
)
3400 PortEnable_t port_enable
;
3401 MPIDefaultReply_t reply_buf
;
3406 /* Destination... */
3407 reply_sz
= sizeof(MPIDefaultReply_t
);
3408 memset(&reply_buf
, 0, reply_sz
);
3410 req_sz
= sizeof(PortEnable_t
);
3411 memset(&port_enable
, 0, req_sz
);
3413 port_enable
.Function
= MPI_FUNCTION_PORT_ENABLE
;
3414 port_enable
.PortNumber
= portnum
;
3415 /* port_enable.ChainOffset = 0; */
3416 /* port_enable.MsgFlags = 0; */
3417 /* port_enable.MsgContext = 0; */
3419 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending Port(%d)Enable (req @ %p)\n",
3420 ioc
->name
, portnum
, &port_enable
));
3422 /* RAID FW may take a long time to enable
3424 if (ioc
->ir_firmware
|| ioc
->bus_type
== SAS
) {
3425 rc
= mpt_handshake_req_reply_wait(ioc
, req_sz
,
3426 (u32
*)&port_enable
, reply_sz
, (u16
*)&reply_buf
,
3427 300 /*seconds*/, sleepFlag
);
3429 rc
= mpt_handshake_req_reply_wait(ioc
, req_sz
,
3430 (u32
*)&port_enable
, reply_sz
, (u16
*)&reply_buf
,
3431 30 /*seconds*/, sleepFlag
);
3437 * mpt_alloc_fw_memory - allocate firmware memory
3438 * @ioc: Pointer to MPT_ADAPTER structure
3439 * @size: total FW bytes
3441 * If memory has already been allocated, the same (cached) value
3444 * Return 0 if successfull, or non-zero for failure
3447 mpt_alloc_fw_memory(MPT_ADAPTER
*ioc
, int size
)
3451 if (ioc
->cached_fw
) {
3452 rc
= 0; /* use already allocated memory */
3455 else if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
) {
3456 ioc
->cached_fw
= ioc
->alt_ioc
->cached_fw
; /* use alt_ioc's memory */
3457 ioc
->cached_fw_dma
= ioc
->alt_ioc
->cached_fw_dma
;
3461 ioc
->cached_fw
= pci_alloc_consistent(ioc
->pcidev
, size
, &ioc
->cached_fw_dma
);
3462 if (!ioc
->cached_fw
) {
3463 printk(MYIOC_s_ERR_FMT
"Unable to allocate memory for the cached firmware image!\n",
3467 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"FW Image @ %p[%p], sz=%d[%x] bytes\n",
3468 ioc
->name
, ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, size
, size
));
3469 ioc
->alloc_total
+= size
;
3477 * mpt_free_fw_memory - free firmware memory
3478 * @ioc: Pointer to MPT_ADAPTER structure
3480 * If alt_img is NULL, delete from ioc structure.
3481 * Else, delete a secondary image in same format.
3484 mpt_free_fw_memory(MPT_ADAPTER
*ioc
)
3488 if (!ioc
->cached_fw
)
3491 sz
= ioc
->facts
.FWImageSize
;
3492 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3493 ioc
->name
, ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, sz
, sz
));
3494 pci_free_consistent(ioc
->pcidev
, sz
, ioc
->cached_fw
, ioc
->cached_fw_dma
);
3495 ioc
->alloc_total
-= sz
;
3496 ioc
->cached_fw
= NULL
;
3499 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3501 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3502 * @ioc: Pointer to MPT_ADAPTER structure
3503 * @sleepFlag: Specifies whether the process can sleep
3505 * Returns 0 for success, >0 for handshake failure
3506 * <0 for fw upload failure.
3508 * Remark: If bound IOC and a successful FWUpload was performed
3509 * on the bound IOC, the second image is discarded
3510 * and memory is free'd. Both channels must upload to prevent
3511 * IOC from running in degraded mode.
3514 mpt_do_upload(MPT_ADAPTER
*ioc
, int sleepFlag
)
3516 u8 reply
[sizeof(FWUploadReply_t
)];
3517 FWUpload_t
*prequest
;
3518 FWUploadReply_t
*preply
;
3519 FWUploadTCSGE_t
*ptcsge
;
3521 int ii
, sz
, reply_sz
;
3524 /* If the image size is 0, we are done.
3526 if ((sz
= ioc
->facts
.FWImageSize
) == 0)
3529 if (mpt_alloc_fw_memory(ioc
, ioc
->facts
.FWImageSize
) != 0)
3532 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3533 ioc
->name
, ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, sz
, sz
));
3535 prequest
= (sleepFlag
== NO_SLEEP
) ? kzalloc(ioc
->req_sz
, GFP_ATOMIC
) :
3536 kzalloc(ioc
->req_sz
, GFP_KERNEL
);
3538 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"fw upload failed "
3539 "while allocating memory \n", ioc
->name
));
3540 mpt_free_fw_memory(ioc
);
3544 preply
= (FWUploadReply_t
*)&reply
;
3546 reply_sz
= sizeof(reply
);
3547 memset(preply
, 0, reply_sz
);
3549 prequest
->ImageType
= MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM
;
3550 prequest
->Function
= MPI_FUNCTION_FW_UPLOAD
;
3552 ptcsge
= (FWUploadTCSGE_t
*) &prequest
->SGL
;
3553 ptcsge
->DetailsLength
= 12;
3554 ptcsge
->Flags
= MPI_SGE_FLAGS_TRANSACTION_ELEMENT
;
3555 ptcsge
->ImageSize
= cpu_to_le32(sz
);
3558 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_READ
| sz
;
3559 ioc
->add_sge((char *)ptcsge
, flagsLength
, ioc
->cached_fw_dma
);
3560 request_size
= offsetof(FWUpload_t
, SGL
) + sizeof(FWUploadTCSGE_t
) +
3562 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending FW Upload "
3563 " (req @ %p) fw_size=%d mf_request_size=%d\n", ioc
->name
, prequest
,
3564 ioc
->facts
.FWImageSize
, request_size
));
3565 DBG_DUMP_FW_REQUEST_FRAME(ioc
, (u32
*)prequest
);
3567 ii
= mpt_handshake_req_reply_wait(ioc
, request_size
, (u32
*)prequest
,
3568 reply_sz
, (u16
*)preply
, 65 /*seconds*/, sleepFlag
);
3570 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"FW Upload completed "
3571 "rc=%x \n", ioc
->name
, ii
));
3573 cmdStatus
= -EFAULT
;
3575 /* Handshake transfer was complete and successful.
3576 * Check the Reply Frame.
3579 status
= le16_to_cpu(preply
->IOCStatus
) &
3581 if (status
== MPI_IOCSTATUS_SUCCESS
&&
3582 ioc
->facts
.FWImageSize
==
3583 le32_to_cpu(preply
->ActualImageSize
))
3586 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
": do_upload cmdStatus=%d \n",
3587 ioc
->name
, cmdStatus
));
3591 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"fw upload failed, "
3592 "freeing image \n", ioc
->name
));
3593 mpt_free_fw_memory(ioc
);
3600 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3602 * mpt_downloadboot - DownloadBoot code
3603 * @ioc: Pointer to MPT_ADAPTER structure
3604 * @pFwHeader: Pointer to firmware header info
3605 * @sleepFlag: Specifies whether the process can sleep
3607 * FwDownloadBoot requires Programmed IO access.
3609 * Returns 0 for success
3610 * -1 FW Image size is 0
3611 * -2 No valid cached_fw Pointer
3612 * <0 for fw upload failure.
3615 mpt_downloadboot(MPT_ADAPTER
*ioc
, MpiFwHeader_t
*pFwHeader
, int sleepFlag
)
3617 MpiExtImageHeader_t
*pExtImage
;
3627 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3628 ioc
->name
, pFwHeader
->ImageSize
, pFwHeader
->ImageSize
, pFwHeader
));
3630 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3631 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3632 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3633 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3634 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3635 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3637 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, (MPI_DIAG_PREVENT_IOC_BOOT
| MPI_DIAG_DISABLE_ARM
));
3640 if (sleepFlag
== CAN_SLEEP
) {
3646 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3647 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_RESET_ADAPTER
);
3649 for (count
= 0; count
< 30; count
++) {
3650 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3651 if (!(diag0val
& MPI_DIAG_RESET_ADAPTER
)) {
3652 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RESET_ADAPTER cleared, count=%d\n",
3657 if (sleepFlag
== CAN_SLEEP
) {
3664 if ( count
== 30 ) {
3665 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot failed! "
3666 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3667 ioc
->name
, diag0val
));
3671 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3672 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3673 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3674 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3675 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3676 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3678 /* Set the DiagRwEn and Disable ARM bits */
3679 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, (MPI_DIAG_RW_ENABLE
| MPI_DIAG_DISABLE_ARM
));
3681 fwSize
= (pFwHeader
->ImageSize
+ 3)/4;
3682 ptrFw
= (u32
*) pFwHeader
;
3684 /* Write the LoadStartAddress to the DiagRw Address Register
3685 * using Programmed IO
3687 if (ioc
->errata_flag_1064
)
3688 pci_enable_io_access(ioc
->pcidev
);
3690 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, pFwHeader
->LoadStartAddress
);
3691 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"LoadStart addr written 0x%x \n",
3692 ioc
->name
, pFwHeader
->LoadStartAddress
));
3694 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write FW Image: 0x%x bytes @ %p\n",
3695 ioc
->name
, fwSize
*4, ptrFw
));
3697 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, *ptrFw
++);
3700 nextImage
= pFwHeader
->NextImageHeaderOffset
;
3702 pExtImage
= (MpiExtImageHeader_t
*) ((char *)pFwHeader
+ nextImage
);
3704 load_addr
= pExtImage
->LoadStartAddress
;
3706 fwSize
= (pExtImage
->ImageSize
+ 3) >> 2;
3707 ptrFw
= (u32
*)pExtImage
;
3709 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3710 ioc
->name
, fwSize
*4, fwSize
*4, ptrFw
, load_addr
));
3711 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, load_addr
);
3714 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, *ptrFw
++);
3716 nextImage
= pExtImage
->NextImageHeaderOffset
;
3719 /* Write the IopResetVectorRegAddr */
3720 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write IopResetVector Addr=%x! \n", ioc
->name
, pFwHeader
->IopResetRegAddr
));
3721 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, pFwHeader
->IopResetRegAddr
);
3723 /* Write the IopResetVectorValue */
3724 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write IopResetVector Value=%x! \n", ioc
->name
, pFwHeader
->IopResetVectorValue
));
3725 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, pFwHeader
->IopResetVectorValue
);
3727 /* Clear the internal flash bad bit - autoincrementing register,
3728 * so must do two writes.
3730 if (ioc
->bus_type
== SPI
) {
3732 * 1030 and 1035 H/W errata, workaround to access
3733 * the ClearFlashBadSignatureBit
3735 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, 0x3F000000);
3736 diagRwData
= CHIPREG_PIO_READ32(&ioc
->pio_chip
->DiagRwData
);
3737 diagRwData
|= 0x40000000;
3738 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, 0x3F000000);
3739 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, diagRwData
);
3741 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3742 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3743 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
|
3744 MPI_DIAG_CLEAR_FLASH_BAD_SIG
);
3747 if (sleepFlag
== CAN_SLEEP
) {
3754 if (ioc
->errata_flag_1064
)
3755 pci_disable_io_access(ioc
->pcidev
);
3757 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3758 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot diag0val=%x, "
3759 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3760 ioc
->name
, diag0val
));
3761 diag0val
&= ~(MPI_DIAG_PREVENT_IOC_BOOT
| MPI_DIAG_DISABLE_ARM
| MPI_DIAG_RW_ENABLE
);
3762 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot now diag0val=%x\n",
3763 ioc
->name
, diag0val
));
3764 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
);
3766 /* Write 0xFF to reset the sequencer */
3767 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3769 if (ioc
->bus_type
== SAS
) {
3770 ioc_state
= mpt_GetIocState(ioc
, 0);
3771 if ( (GetIocFacts(ioc
, sleepFlag
,
3772 MPT_HOSTEVENT_IOC_BRINGUP
)) != 0 ) {
3773 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"GetIocFacts failed: IocState=%x\n",
3774 ioc
->name
, ioc_state
));
3779 for (count
=0; count
<HZ
*20; count
++) {
3780 if ((ioc_state
= mpt_GetIocState(ioc
, 0)) & MPI_IOC_STATE_READY
) {
3781 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3782 "downloadboot successful! (count=%d) IocState=%x\n",
3783 ioc
->name
, count
, ioc_state
));
3784 if (ioc
->bus_type
== SAS
) {
3787 if ((SendIocInit(ioc
, sleepFlag
)) != 0) {
3788 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3789 "downloadboot: SendIocInit failed\n",
3793 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3794 "downloadboot: SendIocInit successful\n",
3798 if (sleepFlag
== CAN_SLEEP
) {
3804 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3805 "downloadboot failed! IocState=%x\n",ioc
->name
, ioc_state
));
3809 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3811 * KickStart - Perform hard reset of MPT adapter.
3812 * @ioc: Pointer to MPT_ADAPTER structure
3813 * @force: Force hard reset
3814 * @sleepFlag: Specifies whether the process can sleep
3816 * This routine places MPT adapter in diagnostic mode via the
3817 * WriteSequence register, and then performs a hard reset of adapter
3818 * via the Diagnostic register.
3820 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3821 * or NO_SLEEP (interrupt thread, use mdelay)
3822 * force - 1 if doorbell active, board fault state
3823 * board operational, IOC_RECOVERY or
3824 * IOC_BRINGUP and there is an alt_ioc.
3828 * 1 - hard reset, READY
3829 * 0 - no reset due to History bit, READY
3830 * -1 - no reset due to History bit but not READY
3831 * OR reset but failed to come READY
3832 * -2 - no reset, could not enter DIAG mode
3833 * -3 - reset but bad FW bit
3836 KickStart(MPT_ADAPTER
*ioc
, int force
, int sleepFlag
)
3838 int hard_reset_done
= 0;
3842 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"KickStarting!\n", ioc
->name
));
3843 if (ioc
->bus_type
== SPI
) {
3844 /* Always issue a Msg Unit Reset first. This will clear some
3845 * SCSI bus hang conditions.
3847 SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
);
3849 if (sleepFlag
== CAN_SLEEP
) {
3856 hard_reset_done
= mpt_diag_reset(ioc
, force
, sleepFlag
);
3857 if (hard_reset_done
< 0)
3858 return hard_reset_done
;
3860 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Diagnostic reset successful!\n",
3863 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 2; /* 2 seconds */
3864 for (cnt
=0; cnt
<cntdn
; cnt
++) {
3865 ioc_state
= mpt_GetIocState(ioc
, 1);
3866 if ((ioc_state
== MPI_IOC_STATE_READY
) || (ioc_state
== MPI_IOC_STATE_OPERATIONAL
)) {
3867 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"KickStart successful! (cnt=%d)\n",
3869 return hard_reset_done
;
3871 if (sleepFlag
== CAN_SLEEP
) {
3878 dinitprintk(ioc
, printk(MYIOC_s_ERR_FMT
"Failed to come READY after reset! IocState=%x\n",
3879 ioc
->name
, mpt_GetIocState(ioc
, 0)));
3883 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3885 * mpt_diag_reset - Perform hard reset of the adapter.
3886 * @ioc: Pointer to MPT_ADAPTER structure
3887 * @ignore: Set if to honor and clear to ignore
3888 * the reset history bit
3889 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3890 * else set to NO_SLEEP (use mdelay instead)
3892 * This routine places the adapter in diagnostic mode via the
3893 * WriteSequence register and then performs a hard reset of adapter
3894 * via the Diagnostic register. Adapter should be in ready state
3895 * upon successful completion.
3897 * Returns: 1 hard reset successful
3898 * 0 no reset performed because reset history bit set
3899 * -2 enabling diagnostic mode failed
3900 * -3 diagnostic reset failed
3903 mpt_diag_reset(MPT_ADAPTER
*ioc
, int ignore
, int sleepFlag
)
3907 int hard_reset_done
= 0;
3910 MpiFwHeader_t
*cached_fw
; /* Pointer to FW */
3913 /* Clear any existing interrupts */
3914 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
3916 if (ioc
->pcidev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1078
) {
3921 drsprintk(ioc
, printk(MYIOC_s_WARN_FMT
"%s: Doorbell=%p; 1078 reset "
3922 "address=%p\n", ioc
->name
, __func__
,
3923 &ioc
->chip
->Doorbell
, &ioc
->chip
->Reset_1078
));
3924 CHIPREG_WRITE32(&ioc
->chip
->Reset_1078
, 0x07);
3925 if (sleepFlag
== CAN_SLEEP
)
3931 * Call each currently registered protocol IOC reset handler
3932 * with pre-reset indication.
3933 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3934 * MptResetHandlers[] registered yet.
3936 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
3937 if (MptResetHandlers
[cb_idx
])
3938 (*(MptResetHandlers
[cb_idx
]))(ioc
,
3942 for (count
= 0; count
< 60; count
++) {
3943 doorbell
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
3944 doorbell
&= MPI_IOC_STATE_MASK
;
3946 drsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3947 "looking for READY STATE: doorbell=%x"
3949 ioc
->name
, doorbell
, count
));
3951 if (doorbell
== MPI_IOC_STATE_READY
) {
3956 if (sleepFlag
== CAN_SLEEP
)
3964 /* Use "Diagnostic reset" method! (only thing available!) */
3965 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3967 if (ioc
->debug_level
& MPT_DEBUG
) {
3969 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
3970 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG1: diag0=%08x, diag1=%08x\n",
3971 ioc
->name
, diag0val
, diag1val
));
3974 /* Do the reset if we are told to ignore the reset history
3975 * or if the reset history is 0
3977 if (ignore
|| !(diag0val
& MPI_DIAG_RESET_HISTORY
)) {
3978 while ((diag0val
& MPI_DIAG_DRWE
) == 0) {
3979 /* Write magic sequence to WriteSequence register
3980 * Loop until in diagnostic mode
3982 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3983 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3984 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3985 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3986 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3987 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3990 if (sleepFlag
== CAN_SLEEP
) {
3998 printk(MYIOC_s_ERR_FMT
"Enable Diagnostic mode FAILED! (%02xh)\n",
3999 ioc
->name
, diag0val
);
4004 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4006 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Wrote magic DiagWriteEn sequence (%x)\n",
4007 ioc
->name
, diag0val
));
4010 if (ioc
->debug_level
& MPT_DEBUG
) {
4012 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
4013 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG2: diag0=%08x, diag1=%08x\n",
4014 ioc
->name
, diag0val
, diag1val
));
4017 * Disable the ARM (Bug fix)
4020 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_DISABLE_ARM
);
4024 * Now hit the reset bit in the Diagnostic register
4025 * (THE BIG HAMMER!) (Clears DRWE bit).
4027 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_RESET_ADAPTER
);
4028 hard_reset_done
= 1;
4029 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Diagnostic reset performed\n",
4033 * Call each currently registered protocol IOC reset handler
4034 * with pre-reset indication.
4035 * NOTE: If we're doing _IOC_BRINGUP, there can be no
4036 * MptResetHandlers[] registered yet.
4038 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
4039 if (MptResetHandlers
[cb_idx
]) {
4040 mpt_signal_reset(cb_idx
,
4041 ioc
, MPT_IOC_PRE_RESET
);
4043 mpt_signal_reset(cb_idx
,
4044 ioc
->alt_ioc
, MPT_IOC_PRE_RESET
);
4050 cached_fw
= (MpiFwHeader_t
*)ioc
->cached_fw
;
4051 else if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
)
4052 cached_fw
= (MpiFwHeader_t
*)ioc
->alt_ioc
->cached_fw
;
4056 /* If the DownloadBoot operation fails, the
4057 * IOC will be left unusable. This is a fatal error
4058 * case. _diag_reset will return < 0
4060 for (count
= 0; count
< 30; count
++) {
4061 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4062 if (!(diag0val
& MPI_DIAG_RESET_ADAPTER
)) {
4066 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"cached_fw: diag0val=%x count=%d\n",
4067 ioc
->name
, diag0val
, count
));
4069 if (sleepFlag
== CAN_SLEEP
) {
4075 if ((count
= mpt_downloadboot(ioc
, cached_fw
, sleepFlag
)) < 0) {
4076 printk(MYIOC_s_WARN_FMT
4077 "firmware downloadboot failure (%d)!\n", ioc
->name
, count
);
4081 /* Wait for FW to reload and for board
4082 * to go to the READY state.
4083 * Maximum wait is 60 seconds.
4084 * If fail, no error will check again
4085 * with calling program.
4087 for (count
= 0; count
< 60; count
++) {
4088 doorbell
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
4089 doorbell
&= MPI_IOC_STATE_MASK
;
4091 drsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4092 "looking for READY STATE: doorbell=%x"
4093 " count=%d\n", ioc
->name
, doorbell
, count
));
4095 if (doorbell
== MPI_IOC_STATE_READY
) {
4100 if (sleepFlag
== CAN_SLEEP
) {
4107 if (doorbell
!= MPI_IOC_STATE_READY
)
4108 printk(MYIOC_s_ERR_FMT
"Failed to come READY "
4109 "after reset! IocState=%x", ioc
->name
,
4114 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4115 if (ioc
->debug_level
& MPT_DEBUG
) {
4117 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
4118 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG3: diag0=%08x, diag1=%08x\n",
4119 ioc
->name
, diag0val
, diag1val
));
4122 /* Clear RESET_HISTORY bit! Place board in the
4123 * diagnostic mode to update the diag register.
4125 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4127 while ((diag0val
& MPI_DIAG_DRWE
) == 0) {
4128 /* Write magic sequence to WriteSequence register
4129 * Loop until in diagnostic mode
4131 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
4132 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
4133 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
4134 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
4135 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
4136 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
4139 if (sleepFlag
== CAN_SLEEP
) {
4147 printk(MYIOC_s_ERR_FMT
"Enable Diagnostic mode FAILED! (%02xh)\n",
4148 ioc
->name
, diag0val
);
4151 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4153 diag0val
&= ~MPI_DIAG_RESET_HISTORY
;
4154 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
);
4155 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4156 if (diag0val
& MPI_DIAG_RESET_HISTORY
) {
4157 printk(MYIOC_s_WARN_FMT
"ResetHistory bit failed to clear!\n",
4161 /* Disable Diagnostic Mode
4163 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFFFFFFFF);
4165 /* Check FW reload status flags.
4167 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4168 if (diag0val
& (MPI_DIAG_FLASH_BAD_SIG
| MPI_DIAG_RESET_ADAPTER
| MPI_DIAG_DISABLE_ARM
)) {
4169 printk(MYIOC_s_ERR_FMT
"Diagnostic reset FAILED! (%02xh)\n",
4170 ioc
->name
, diag0val
);
4174 if (ioc
->debug_level
& MPT_DEBUG
) {
4176 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
4177 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG4: diag0=%08x, diag1=%08x\n",
4178 ioc
->name
, diag0val
, diag1val
));
4182 * Reset flag that says we've enabled event notification
4184 ioc
->facts
.EventState
= 0;
4187 ioc
->alt_ioc
->facts
.EventState
= 0;
4189 return hard_reset_done
;
4192 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4194 * SendIocReset - Send IOCReset request to MPT adapter.
4195 * @ioc: Pointer to MPT_ADAPTER structure
4196 * @reset_type: reset type, expected values are
4197 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
4198 * @sleepFlag: Specifies whether the process can sleep
4200 * Send IOCReset request to the MPT adapter.
4202 * Returns 0 for success, non-zero for failure.
4205 SendIocReset(MPT_ADAPTER
*ioc
, u8 reset_type
, int sleepFlag
)
4211 drsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending IOC reset(0x%02x)!\n",
4212 ioc
->name
, reset_type
));
4213 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, reset_type
<<MPI_DOORBELL_FUNCTION_SHIFT
);
4214 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
4217 /* FW ACK'd request, wait for READY state
4220 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 15; /* 15 seconds */
4222 while ((state
= mpt_GetIocState(ioc
, 1)) != MPI_IOC_STATE_READY
) {
4226 if (sleepFlag
!= CAN_SLEEP
)
4229 printk(MYIOC_s_ERR_FMT
4230 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
4231 ioc
->name
, state
, (int)((count
+5)/HZ
));
4235 if (sleepFlag
== CAN_SLEEP
) {
4238 mdelay (1); /* 1 msec delay */
4243 * Cleanup all event stuff for this IOC; re-issue EventNotification
4244 * request if needed.
4246 if (ioc
->facts
.Function
)
4247 ioc
->facts
.EventState
= 0;
4252 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4254 * initChainBuffers - Allocate memory for and initialize chain buffers
4255 * @ioc: Pointer to MPT_ADAPTER structure
4257 * Allocates memory for and initializes chain buffers,
4258 * chain buffer control arrays and spinlock.
4261 initChainBuffers(MPT_ADAPTER
*ioc
)
4264 int sz
, ii
, num_chain
;
4265 int scale
, num_sge
, numSGE
;
4267 /* ReqToChain size must equal the req_depth
4270 if (ioc
->ReqToChain
== NULL
) {
4271 sz
= ioc
->req_depth
* sizeof(int);
4272 mem
= kmalloc(sz
, GFP_ATOMIC
);
4276 ioc
->ReqToChain
= (int *) mem
;
4277 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReqToChain alloc @ %p, sz=%d bytes\n",
4278 ioc
->name
, mem
, sz
));
4279 mem
= kmalloc(sz
, GFP_ATOMIC
);
4283 ioc
->RequestNB
= (int *) mem
;
4284 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestNB alloc @ %p, sz=%d bytes\n",
4285 ioc
->name
, mem
, sz
));
4287 for (ii
= 0; ii
< ioc
->req_depth
; ii
++) {
4288 ioc
->ReqToChain
[ii
] = MPT_HOST_NO_CHAIN
;
4291 /* ChainToChain size must equal the total number
4292 * of chain buffers to be allocated.
4295 * Calculate the number of chain buffers needed(plus 1) per I/O
4296 * then multiply the maximum number of simultaneous cmds
4298 * num_sge = num sge in request frame + last chain buffer
4299 * scale = num sge per chain buffer if no chain element
4301 scale
= ioc
->req_sz
/ ioc
->SGE_size
;
4302 if (ioc
->sg_addr_size
== sizeof(u64
))
4303 num_sge
= scale
+ (ioc
->req_sz
- 60) / ioc
->SGE_size
;
4305 num_sge
= 1 + scale
+ (ioc
->req_sz
- 64) / ioc
->SGE_size
;
4307 if (ioc
->sg_addr_size
== sizeof(u64
)) {
4308 numSGE
= (scale
- 1) * (ioc
->facts
.MaxChainDepth
-1) + scale
+
4309 (ioc
->req_sz
- 60) / ioc
->SGE_size
;
4311 numSGE
= 1 + (scale
- 1) * (ioc
->facts
.MaxChainDepth
-1) +
4312 scale
+ (ioc
->req_sz
- 64) / ioc
->SGE_size
;
4314 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"num_sge=%d numSGE=%d\n",
4315 ioc
->name
, num_sge
, numSGE
));
4317 if (ioc
->bus_type
== FC
) {
4318 if (numSGE
> MPT_SCSI_FC_SG_DEPTH
)
4319 numSGE
= MPT_SCSI_FC_SG_DEPTH
;
4321 if (numSGE
> MPT_SCSI_SG_DEPTH
)
4322 numSGE
= MPT_SCSI_SG_DEPTH
;
4326 while (numSGE
- num_sge
> 0) {
4328 num_sge
+= (scale
- 1);
4332 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Now numSGE=%d num_sge=%d num_chain=%d\n",
4333 ioc
->name
, numSGE
, num_sge
, num_chain
));
4335 if (ioc
->bus_type
== SPI
)
4336 num_chain
*= MPT_SCSI_CAN_QUEUE
;
4337 else if (ioc
->bus_type
== SAS
)
4338 num_chain
*= MPT_SAS_CAN_QUEUE
;
4340 num_chain
*= MPT_FC_CAN_QUEUE
;
4342 ioc
->num_chain
= num_chain
;
4344 sz
= num_chain
* sizeof(int);
4345 if (ioc
->ChainToChain
== NULL
) {
4346 mem
= kmalloc(sz
, GFP_ATOMIC
);
4350 ioc
->ChainToChain
= (int *) mem
;
4351 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainToChain alloc @ %p, sz=%d bytes\n",
4352 ioc
->name
, mem
, sz
));
4354 mem
= (u8
*) ioc
->ChainToChain
;
4356 memset(mem
, 0xFF, sz
);
4360 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4362 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
4363 * @ioc: Pointer to MPT_ADAPTER structure
4365 * This routine allocates memory for the MPT reply and request frame
4366 * pools (if necessary), and primes the IOC reply FIFO with
4369 * Returns 0 for success, non-zero for failure.
4372 PrimeIocFifos(MPT_ADAPTER
*ioc
)
4375 unsigned long flags
;
4376 dma_addr_t alloc_dma
;
4378 int i
, reply_sz
, sz
, total_size
, num_chain
;
4383 /* Prime reply FIFO... */
4385 if (ioc
->reply_frames
== NULL
) {
4386 if ( (num_chain
= initChainBuffers(ioc
)) < 0)
4389 * 1078 errata workaround for the 36GB limitation
4391 if (ioc
->pcidev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1078
&&
4392 ioc
->dma_mask
> DMA_BIT_MASK(35)) {
4393 if (!pci_set_dma_mask(ioc
->pcidev
, DMA_BIT_MASK(32))
4394 && !pci_set_consistent_dma_mask(ioc
->pcidev
,
4395 DMA_BIT_MASK(32))) {
4396 dma_mask
= DMA_BIT_MASK(35);
4397 d36memprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4398 "setting 35 bit addressing for "
4399 "Request/Reply/Chain and Sense Buffers\n",
4402 /*Reseting DMA mask to 64 bit*/
4403 pci_set_dma_mask(ioc
->pcidev
,
4405 pci_set_consistent_dma_mask(ioc
->pcidev
,
4408 printk(MYIOC_s_ERR_FMT
4409 "failed setting 35 bit addressing for "
4410 "Request/Reply/Chain and Sense Buffers\n",
4416 total_size
= reply_sz
= (ioc
->reply_sz
* ioc
->reply_depth
);
4417 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
4418 ioc
->name
, ioc
->reply_sz
, ioc
->reply_depth
));
4419 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffer sz=%d[%x] bytes\n",
4420 ioc
->name
, reply_sz
, reply_sz
));
4422 sz
= (ioc
->req_sz
* ioc
->req_depth
);
4423 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestBuffer sz=%d bytes, RequestDepth=%d\n",
4424 ioc
->name
, ioc
->req_sz
, ioc
->req_depth
));
4425 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestBuffer sz=%d[%x] bytes\n",
4426 ioc
->name
, sz
, sz
));
4429 sz
= num_chain
* ioc
->req_sz
; /* chain buffer pool size */
4430 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainBuffer sz=%d bytes, ChainDepth=%d\n",
4431 ioc
->name
, ioc
->req_sz
, num_chain
));
4432 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
4433 ioc
->name
, sz
, sz
, num_chain
));
4436 mem
= pci_alloc_consistent(ioc
->pcidev
, total_size
, &alloc_dma
);
4438 printk(MYIOC_s_ERR_FMT
"Unable to allocate Reply, Request, Chain Buffers!\n",
4443 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Total alloc @ %p[%p], sz=%d[%x] bytes\n",
4444 ioc
->name
, mem
, (void *)(ulong
)alloc_dma
, total_size
, total_size
));
4446 memset(mem
, 0, total_size
);
4447 ioc
->alloc_total
+= total_size
;
4449 ioc
->alloc_dma
= alloc_dma
;
4450 ioc
->alloc_sz
= total_size
;
4451 ioc
->reply_frames
= (MPT_FRAME_HDR
*) mem
;
4452 ioc
->reply_frames_low_dma
= (u32
) (alloc_dma
& 0xFFFFFFFF);
4454 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffers @ %p[%p]\n",
4455 ioc
->name
, ioc
->reply_frames
, (void *)(ulong
)alloc_dma
));
4457 alloc_dma
+= reply_sz
;
4460 /* Request FIFO - WE manage this! */
4462 ioc
->req_frames
= (MPT_FRAME_HDR
*) mem
;
4463 ioc
->req_frames_dma
= alloc_dma
;
4465 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestBuffers @ %p[%p]\n",
4466 ioc
->name
, mem
, (void *)(ulong
)alloc_dma
));
4468 ioc
->req_frames_low_dma
= (u32
) (alloc_dma
& 0xFFFFFFFF);
4470 #if defined(CONFIG_MTRR) && 0
4472 * Enable Write Combining MTRR for IOC's memory region.
4473 * (at least as much as we can; "size and base must be
4474 * multiples of 4 kiB"
4476 ioc
->mtrr_reg
= mtrr_add(ioc
->req_frames_dma
,
4478 MTRR_TYPE_WRCOMB
, 1);
4479 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"MTRR region registered (base:size=%08x:%x)\n",
4480 ioc
->name
, ioc
->req_frames_dma
, sz
));
4483 for (i
= 0; i
< ioc
->req_depth
; i
++) {
4484 alloc_dma
+= ioc
->req_sz
;
4488 ioc
->ChainBuffer
= mem
;
4489 ioc
->ChainBufferDMA
= alloc_dma
;
4491 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainBuffers @ %p(%p)\n",
4492 ioc
->name
, ioc
->ChainBuffer
, (void *)(ulong
)ioc
->ChainBufferDMA
));
4494 /* Initialize the free chain Q.
4497 INIT_LIST_HEAD(&ioc
->FreeChainQ
);
4499 /* Post the chain buffers to the FreeChainQ.
4501 mem
= (u8
*)ioc
->ChainBuffer
;
4502 for (i
=0; i
< num_chain
; i
++) {
4503 mf
= (MPT_FRAME_HDR
*) mem
;
4504 list_add_tail(&mf
->u
.frame
.linkage
.list
, &ioc
->FreeChainQ
);
4508 /* Initialize Request frames linked list
4510 alloc_dma
= ioc
->req_frames_dma
;
4511 mem
= (u8
*) ioc
->req_frames
;
4513 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
4514 INIT_LIST_HEAD(&ioc
->FreeQ
);
4515 for (i
= 0; i
< ioc
->req_depth
; i
++) {
4516 mf
= (MPT_FRAME_HDR
*) mem
;
4518 /* Queue REQUESTs *internally*! */
4519 list_add_tail(&mf
->u
.frame
.linkage
.list
, &ioc
->FreeQ
);
4523 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
4525 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
4526 ioc
->sense_buf_pool
=
4527 pci_alloc_consistent(ioc
->pcidev
, sz
, &ioc
->sense_buf_pool_dma
);
4528 if (ioc
->sense_buf_pool
== NULL
) {
4529 printk(MYIOC_s_ERR_FMT
"Unable to allocate Sense Buffers!\n",
4534 ioc
->sense_buf_low_dma
= (u32
) (ioc
->sense_buf_pool_dma
& 0xFFFFFFFF);
4535 ioc
->alloc_total
+= sz
;
4536 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SenseBuffers @ %p[%p]\n",
4537 ioc
->name
, ioc
->sense_buf_pool
, (void *)(ulong
)ioc
->sense_buf_pool_dma
));
4541 /* Post Reply frames to FIFO
4543 alloc_dma
= ioc
->alloc_dma
;
4544 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffers @ %p[%p]\n",
4545 ioc
->name
, ioc
->reply_frames
, (void *)(ulong
)alloc_dma
));
4547 for (i
= 0; i
< ioc
->reply_depth
; i
++) {
4548 /* Write each address to the IOC! */
4549 CHIPREG_WRITE32(&ioc
->chip
->ReplyFifo
, alloc_dma
);
4550 alloc_dma
+= ioc
->reply_sz
;
4553 if (dma_mask
== DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc
->pcidev
,
4554 ioc
->dma_mask
) && !pci_set_consistent_dma_mask(ioc
->pcidev
,
4556 d36memprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4557 "restoring 64 bit addressing\n", ioc
->name
));
4563 if (ioc
->alloc
!= NULL
) {
4565 pci_free_consistent(ioc
->pcidev
,
4567 ioc
->alloc
, ioc
->alloc_dma
);
4568 ioc
->reply_frames
= NULL
;
4569 ioc
->req_frames
= NULL
;
4570 ioc
->alloc_total
-= sz
;
4572 if (ioc
->sense_buf_pool
!= NULL
) {
4573 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
4574 pci_free_consistent(ioc
->pcidev
,
4576 ioc
->sense_buf_pool
, ioc
->sense_buf_pool_dma
);
4577 ioc
->sense_buf_pool
= NULL
;
4580 if (dma_mask
== DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc
->pcidev
,
4581 DMA_BIT_MASK(64)) && !pci_set_consistent_dma_mask(ioc
->pcidev
,
4583 d36memprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4584 "restoring 64 bit addressing\n", ioc
->name
));
4589 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4591 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4592 * from IOC via doorbell handshake method.
4593 * @ioc: Pointer to MPT_ADAPTER structure
4594 * @reqBytes: Size of the request in bytes
4595 * @req: Pointer to MPT request frame
4596 * @replyBytes: Expected size of the reply in bytes
4597 * @u16reply: Pointer to area where reply should be written
4598 * @maxwait: Max wait time for a reply (in seconds)
4599 * @sleepFlag: Specifies whether the process can sleep
4601 * NOTES: It is the callers responsibility to byte-swap fields in the
4602 * request which are greater than 1 byte in size. It is also the
4603 * callers responsibility to byte-swap response fields which are
4604 * greater than 1 byte in size.
4606 * Returns 0 for success, non-zero for failure.
4609 mpt_handshake_req_reply_wait(MPT_ADAPTER
*ioc
, int reqBytes
, u32
*req
,
4610 int replyBytes
, u16
*u16reply
, int maxwait
, int sleepFlag
)
4612 MPIDefaultReply_t
*mptReply
;
4617 * Get ready to cache a handshake reply
4619 ioc
->hs_reply_idx
= 0;
4620 mptReply
= (MPIDefaultReply_t
*) ioc
->hs_reply
;
4621 mptReply
->MsgLength
= 0;
4624 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4625 * then tell IOC that we want to handshake a request of N words.
4626 * (WRITE u32val to Doorbell reg).
4628 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4629 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
,
4630 ((MPI_FUNCTION_HANDSHAKE
<<MPI_DOORBELL_FUNCTION_SHIFT
) |
4631 ((reqBytes
/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT
)));
4634 * Wait for IOC's doorbell handshake int
4636 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4639 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4640 ioc
->name
, reqBytes
, t
, failcnt
? " - MISSING DOORBELL HANDSHAKE!" : ""));
4642 /* Read doorbell and check for active bit */
4643 if (!(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & MPI_DOORBELL_ACTIVE
))
4647 * Clear doorbell int (WRITE 0 to IntStatus reg),
4648 * then wait for IOC to ACKnowledge that it's ready for
4649 * our handshake request.
4651 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4652 if (!failcnt
&& (t
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
4657 u8
*req_as_bytes
= (u8
*) req
;
4660 * Stuff request words via doorbell handshake,
4661 * with ACK from IOC for each.
4663 for (ii
= 0; !failcnt
&& ii
< reqBytes
/4; ii
++) {
4664 u32 word
= ((req_as_bytes
[(ii
*4) + 0] << 0) |
4665 (req_as_bytes
[(ii
*4) + 1] << 8) |
4666 (req_as_bytes
[(ii
*4) + 2] << 16) |
4667 (req_as_bytes
[(ii
*4) + 3] << 24));
4669 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, word
);
4670 if ((t
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
4674 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Handshake request frame (@%p) header\n", ioc
->name
, req
));
4675 DBG_DUMP_REQUEST_FRAME_HDR(ioc
, (u32
*)req
);
4677 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HandShake request post done, WaitCnt=%d%s\n",
4678 ioc
->name
, t
, failcnt
? " - MISSING DOORBELL ACK!" : ""));
4681 * Wait for completion of doorbell handshake reply from the IOC
4683 if (!failcnt
&& (t
= WaitForDoorbellReply(ioc
, maxwait
, sleepFlag
)) < 0)
4686 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HandShake reply count=%d%s\n",
4687 ioc
->name
, t
, failcnt
? " - MISSING DOORBELL REPLY!" : ""));
4690 * Copy out the cached reply...
4692 for (ii
=0; ii
< min(replyBytes
/2,mptReply
->MsgLength
*2); ii
++)
4693 u16reply
[ii
] = ioc
->hs_reply
[ii
];
4701 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4703 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4704 * @ioc: Pointer to MPT_ADAPTER structure
4705 * @howlong: How long to wait (in seconds)
4706 * @sleepFlag: Specifies whether the process can sleep
4708 * This routine waits (up to ~2 seconds max) for IOC doorbell
4709 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4710 * bit in its IntStatus register being clear.
4712 * Returns a negative value on failure, else wait loop count.
4715 WaitForDoorbellAck(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
4721 cntdn
= 1000 * howlong
;
4723 if (sleepFlag
== CAN_SLEEP
) {
4726 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4727 if (! (intstat
& MPI_HIS_IOP_DOORBELL_STATUS
))
4734 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4735 if (! (intstat
& MPI_HIS_IOP_DOORBELL_STATUS
))
4742 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitForDoorbell ACK (count=%d)\n",
4747 printk(MYIOC_s_ERR_FMT
"Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4748 ioc
->name
, count
, intstat
);
4752 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4754 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4755 * @ioc: Pointer to MPT_ADAPTER structure
4756 * @howlong: How long to wait (in seconds)
4757 * @sleepFlag: Specifies whether the process can sleep
4759 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4760 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4762 * Returns a negative value on failure, else wait loop count.
4765 WaitForDoorbellInt(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
4771 cntdn
= 1000 * howlong
;
4772 if (sleepFlag
== CAN_SLEEP
) {
4774 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4775 if (intstat
& MPI_HIS_DOORBELL_INTERRUPT
)
4782 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4783 if (intstat
& MPI_HIS_DOORBELL_INTERRUPT
)
4791 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4792 ioc
->name
, count
, howlong
));
4796 printk(MYIOC_s_ERR_FMT
"Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4797 ioc
->name
, count
, intstat
);
4801 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4803 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4804 * @ioc: Pointer to MPT_ADAPTER structure
4805 * @howlong: How long to wait (in seconds)
4806 * @sleepFlag: Specifies whether the process can sleep
4808 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4809 * Reply is cached to IOC private area large enough to hold a maximum
4810 * of 128 bytes of reply data.
4812 * Returns a negative value on failure, else size of reply in WORDS.
4815 WaitForDoorbellReply(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
4820 u16
*hs_reply
= ioc
->hs_reply
;
4821 volatile MPIDefaultReply_t
*mptReply
= (MPIDefaultReply_t
*) ioc
->hs_reply
;
4824 hs_reply
[0] = hs_reply
[1] = hs_reply
[7] = 0;
4827 * Get first two u16's so we can look at IOC's intended reply MsgLength
4830 if ((t
= WaitForDoorbellInt(ioc
, howlong
, sleepFlag
)) < 0) {
4833 hs_reply
[u16cnt
++] = le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4834 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4835 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4838 hs_reply
[u16cnt
++] = le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4839 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4843 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitCnt=%d First handshake reply word=%08x%s\n",
4844 ioc
->name
, t
, le32_to_cpu(*(u32
*)hs_reply
),
4845 failcnt
? " - MISSING DOORBELL HANDSHAKE!" : ""));
4848 * If no error (and IOC said MsgLength is > 0), piece together
4849 * reply 16 bits at a time.
4851 for (u16cnt
=2; !failcnt
&& u16cnt
< (2 * mptReply
->MsgLength
); u16cnt
++) {
4852 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4854 hword
= le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4855 /* don't overflow our IOC hs_reply[] buffer! */
4856 if (u16cnt
< ARRAY_SIZE(ioc
->hs_reply
))
4857 hs_reply
[u16cnt
] = hword
;
4858 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4861 if (!failcnt
&& (t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4863 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4866 printk(MYIOC_s_ERR_FMT
"Handshake reply failure!\n",
4871 else if (u16cnt
!= (2 * mptReply
->MsgLength
)) {
4874 else if ((mptReply
->IOCStatus
& MPI_IOCSTATUS_MASK
) != MPI_IOCSTATUS_SUCCESS
) {
4879 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Got Handshake reply:\n", ioc
->name
));
4880 DBG_DUMP_REPLY_FRAME(ioc
, (u32
*)mptReply
);
4882 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4883 ioc
->name
, t
, u16cnt
/2));
4887 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4889 * GetLanConfigPages - Fetch LANConfig pages.
4890 * @ioc: Pointer to MPT_ADAPTER structure
4892 * Return: 0 for success
4893 * -ENOMEM if no memory available
4894 * -EPERM if not allowed due to ISR context
4895 * -EAGAIN if no msg frames currently available
4896 * -EFAULT for non-successful reply or no reply (timeout)
4899 GetLanConfigPages(MPT_ADAPTER
*ioc
)
4901 ConfigPageHeader_t hdr
;
4903 LANPage0_t
*ppage0_alloc
;
4904 dma_addr_t page0_dma
;
4905 LANPage1_t
*ppage1_alloc
;
4906 dma_addr_t page1_dma
;
4911 /* Get LAN Page 0 header */
4912 hdr
.PageVersion
= 0;
4915 hdr
.PageType
= MPI_CONFIG_PAGETYPE_LAN
;
4916 cfg
.cfghdr
.hdr
= &hdr
;
4918 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4923 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
4926 if (hdr
.PageLength
> 0) {
4927 data_sz
= hdr
.PageLength
* 4;
4928 ppage0_alloc
= (LANPage0_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page0_dma
);
4931 memset((u8
*)ppage0_alloc
, 0, data_sz
);
4932 cfg
.physAddr
= page0_dma
;
4933 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4935 if ((rc
= mpt_config(ioc
, &cfg
)) == 0) {
4937 copy_sz
= min_t(int, sizeof(LANPage0_t
), data_sz
);
4938 memcpy(&ioc
->lan_cnfg_page0
, ppage0_alloc
, copy_sz
);
4942 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage0_alloc
, page0_dma
);
4945 * Normalize endianness of structure data,
4946 * by byte-swapping all > 1 byte fields!
4955 /* Get LAN Page 1 header */
4956 hdr
.PageVersion
= 0;
4959 hdr
.PageType
= MPI_CONFIG_PAGETYPE_LAN
;
4960 cfg
.cfghdr
.hdr
= &hdr
;
4962 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4966 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
4969 if (hdr
.PageLength
== 0)
4972 data_sz
= hdr
.PageLength
* 4;
4974 ppage1_alloc
= (LANPage1_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page1_dma
);
4976 memset((u8
*)ppage1_alloc
, 0, data_sz
);
4977 cfg
.physAddr
= page1_dma
;
4978 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4980 if ((rc
= mpt_config(ioc
, &cfg
)) == 0) {
4982 copy_sz
= min_t(int, sizeof(LANPage1_t
), data_sz
);
4983 memcpy(&ioc
->lan_cnfg_page1
, ppage1_alloc
, copy_sz
);
4986 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage1_alloc
, page1_dma
);
4989 * Normalize endianness of structure data,
4990 * by byte-swapping all > 1 byte fields!
4998 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5000 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
5001 * @ioc: Pointer to MPT_ADAPTER structure
5002 * @persist_opcode: see below
5004 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
5005 * devices not currently present.
5006 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
5008 * NOTE: Don't use not this function during interrupt time.
5010 * Returns 0 for success, non-zero error
5013 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5015 mptbase_sas_persist_operation(MPT_ADAPTER
*ioc
, u8 persist_opcode
)
5017 SasIoUnitControlRequest_t
*sasIoUnitCntrReq
;
5018 SasIoUnitControlReply_t
*sasIoUnitCntrReply
;
5019 MPT_FRAME_HDR
*mf
= NULL
;
5020 MPIHeader_t
*mpi_hdr
;
5022 unsigned long timeleft
;
5024 mutex_lock(&ioc
->mptbase_cmds
.mutex
);
5026 /* init the internal cmd struct */
5027 memset(ioc
->mptbase_cmds
.reply
, 0 , MPT_DEFAULT_FRAME_SIZE
);
5028 INITIALIZE_MGMT_STATUS(ioc
->mptbase_cmds
.status
)
5030 /* insure garbage is not sent to fw */
5031 switch(persist_opcode
) {
5033 case MPI_SAS_OP_CLEAR_NOT_PRESENT
:
5034 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT
:
5042 printk(KERN_DEBUG
"%s: persist_opcode=%x\n",
5043 __func__
, persist_opcode
);
5045 /* Get a MF for this command.
5047 if ((mf
= mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
5048 printk(KERN_DEBUG
"%s: no msg frames!\n", __func__
);
5053 mpi_hdr
= (MPIHeader_t
*) mf
;
5054 sasIoUnitCntrReq
= (SasIoUnitControlRequest_t
*)mf
;
5055 memset(sasIoUnitCntrReq
,0,sizeof(SasIoUnitControlRequest_t
));
5056 sasIoUnitCntrReq
->Function
= MPI_FUNCTION_SAS_IO_UNIT_CONTROL
;
5057 sasIoUnitCntrReq
->MsgContext
= mpi_hdr
->MsgContext
;
5058 sasIoUnitCntrReq
->Operation
= persist_opcode
;
5060 mpt_put_msg_frame(mpt_base_index
, ioc
, mf
);
5061 timeleft
= wait_for_completion_timeout(&ioc
->mptbase_cmds
.done
, 10*HZ
);
5062 if (!(ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_COMMAND_GOOD
)) {
5064 printk(KERN_DEBUG
"%s: failed\n", __func__
);
5065 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_DID_IOCRESET
)
5068 printk(KERN_DEBUG
"%s: Issuing Reset from %s!!\n",
5069 ioc
->name
, __func__
);
5070 mpt_Soft_Hard_ResetHandler(ioc
, CAN_SLEEP
);
5071 mpt_free_msg_frame(ioc
, mf
);
5076 if (!(ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_RF_VALID
)) {
5081 sasIoUnitCntrReply
=
5082 (SasIoUnitControlReply_t
*)ioc
->mptbase_cmds
.reply
;
5083 if (le16_to_cpu(sasIoUnitCntrReply
->IOCStatus
) != MPI_IOCSTATUS_SUCCESS
) {
5084 printk(KERN_DEBUG
"%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
5085 __func__
, sasIoUnitCntrReply
->IOCStatus
,
5086 sasIoUnitCntrReply
->IOCLogInfo
);
5087 printk(KERN_DEBUG
"%s: failed\n", __func__
);
5090 printk(KERN_DEBUG
"%s: success\n", __func__
);
5093 CLEAR_MGMT_STATUS(ioc
->mptbase_cmds
.status
)
5094 mutex_unlock(&ioc
->mptbase_cmds
.mutex
);
5098 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5101 mptbase_raid_process_event_data(MPT_ADAPTER
*ioc
,
5102 MpiEventDataRaid_t
* pRaidEventData
)
5111 volume
= pRaidEventData
->VolumeID
;
5112 reason
= pRaidEventData
->ReasonCode
;
5113 disk
= pRaidEventData
->PhysDiskNum
;
5114 status
= le32_to_cpu(pRaidEventData
->SettingsStatus
);
5115 flags
= (status
>> 0) & 0xff;
5116 state
= (status
>> 8) & 0xff;
5118 if (reason
== MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
) {
5122 if ((reason
>= MPI_EVENT_RAID_RC_PHYSDISK_CREATED
&&
5123 reason
<= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
) ||
5124 (reason
== MPI_EVENT_RAID_RC_SMART_DATA
)) {
5125 printk(MYIOC_s_INFO_FMT
"RAID STATUS CHANGE for PhysDisk %d id=%d\n",
5126 ioc
->name
, disk
, volume
);
5128 printk(MYIOC_s_INFO_FMT
"RAID STATUS CHANGE for VolumeID %d\n",
5133 case MPI_EVENT_RAID_RC_VOLUME_CREATED
:
5134 printk(MYIOC_s_INFO_FMT
" volume has been created\n",
5138 case MPI_EVENT_RAID_RC_VOLUME_DELETED
:
5140 printk(MYIOC_s_INFO_FMT
" volume has been deleted\n",
5144 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED
:
5145 printk(MYIOC_s_INFO_FMT
" volume settings have been changed\n",
5149 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED
:
5150 printk(MYIOC_s_INFO_FMT
" volume is now %s%s%s%s\n",
5152 state
== MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
5154 : state
== MPI_RAIDVOL0_STATUS_STATE_DEGRADED
5156 : state
== MPI_RAIDVOL0_STATUS_STATE_FAILED
5159 flags
& MPI_RAIDVOL0_STATUS_FLAG_ENABLED
5161 flags
& MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
5162 ? ", quiesced" : "",
5163 flags
& MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
5164 ? ", resync in progress" : "" );
5167 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED
:
5168 printk(MYIOC_s_INFO_FMT
" volume membership of PhysDisk %d has changed\n",
5172 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED
:
5173 printk(MYIOC_s_INFO_FMT
" PhysDisk has been created\n",
5177 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED
:
5178 printk(MYIOC_s_INFO_FMT
" PhysDisk has been deleted\n",
5182 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED
:
5183 printk(MYIOC_s_INFO_FMT
" PhysDisk settings have been changed\n",
5187 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
:
5188 printk(MYIOC_s_INFO_FMT
" PhysDisk is now %s%s%s\n",
5190 state
== MPI_PHYSDISK0_STATUS_ONLINE
5192 : state
== MPI_PHYSDISK0_STATUS_MISSING
5194 : state
== MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
5196 : state
== MPI_PHYSDISK0_STATUS_FAILED
5198 : state
== MPI_PHYSDISK0_STATUS_INITIALIZING
5200 : state
== MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
5201 ? "offline requested"
5202 : state
== MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
5203 ? "failed requested"
5204 : state
== MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
5207 flags
& MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
5208 ? ", out of sync" : "",
5209 flags
& MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
5210 ? ", quiesced" : "" );
5213 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
:
5214 printk(MYIOC_s_INFO_FMT
" Domain Validation needed for PhysDisk %d\n",
5218 case MPI_EVENT_RAID_RC_SMART_DATA
:
5219 printk(MYIOC_s_INFO_FMT
" SMART data received, ASC/ASCQ = %02xh/%02xh\n",
5220 ioc
->name
, pRaidEventData
->ASC
, pRaidEventData
->ASCQ
);
5223 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED
:
5224 printk(MYIOC_s_INFO_FMT
" replacement of PhysDisk %d has started\n",
5230 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5232 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
5233 * @ioc: Pointer to MPT_ADAPTER structure
5235 * Returns: 0 for success
5236 * -ENOMEM if no memory available
5237 * -EPERM if not allowed due to ISR context
5238 * -EAGAIN if no msg frames currently available
5239 * -EFAULT for non-successful reply or no reply (timeout)
5242 GetIoUnitPage2(MPT_ADAPTER
*ioc
)
5244 ConfigPageHeader_t hdr
;
5246 IOUnitPage2_t
*ppage_alloc
;
5247 dma_addr_t page_dma
;
5251 /* Get the page header */
5252 hdr
.PageVersion
= 0;
5255 hdr
.PageType
= MPI_CONFIG_PAGETYPE_IO_UNIT
;
5256 cfg
.cfghdr
.hdr
= &hdr
;
5258 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5263 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
5266 if (hdr
.PageLength
== 0)
5269 /* Read the config page */
5270 data_sz
= hdr
.PageLength
* 4;
5272 ppage_alloc
= (IOUnitPage2_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page_dma
);
5274 memset((u8
*)ppage_alloc
, 0, data_sz
);
5275 cfg
.physAddr
= page_dma
;
5276 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5278 /* If Good, save data */
5279 if ((rc
= mpt_config(ioc
, &cfg
)) == 0)
5280 ioc
->biosVersion
= le32_to_cpu(ppage_alloc
->BiosVersion
);
5282 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage_alloc
, page_dma
);
5288 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5290 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
5291 * @ioc: Pointer to a Adapter Strucutre
5292 * @portnum: IOC port number
5294 * Return: -EFAULT if read of config page header fails
5296 * If read of SCSI Port Page 0 fails,
5297 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5298 * Adapter settings: async, narrow
5300 * If read of SCSI Port Page 2 fails,
5301 * Adapter settings valid
5302 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5307 * CHECK - what type of locking mechanisms should be used????
5310 mpt_GetScsiPortSettings(MPT_ADAPTER
*ioc
, int portnum
)
5315 ConfigPageHeader_t header
;
5321 if (!ioc
->spi_data
.nvram
) {
5324 sz
= MPT_MAX_SCSI_DEVICES
* sizeof(int);
5325 mem
= kmalloc(sz
, GFP_ATOMIC
);
5329 ioc
->spi_data
.nvram
= (int *) mem
;
5331 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SCSI device NVRAM settings @ %p, sz=%d\n",
5332 ioc
->name
, ioc
->spi_data
.nvram
, sz
));
5335 /* Invalidate NVRAM information
5337 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
5338 ioc
->spi_data
.nvram
[ii
] = MPT_HOST_NVRAM_INVALID
;
5341 /* Read SPP0 header, allocate memory, then read page.
5343 header
.PageVersion
= 0;
5344 header
.PageLength
= 0;
5345 header
.PageNumber
= 0;
5346 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_PORT
;
5347 cfg
.cfghdr
.hdr
= &header
;
5349 cfg
.pageAddr
= portnum
;
5350 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5352 cfg
.timeout
= 0; /* use default */
5353 if (mpt_config(ioc
, &cfg
) != 0)
5356 if (header
.PageLength
> 0) {
5357 pbuf
= pci_alloc_consistent(ioc
->pcidev
, header
.PageLength
* 4, &buf_dma
);
5359 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5360 cfg
.physAddr
= buf_dma
;
5361 if (mpt_config(ioc
, &cfg
) != 0) {
5362 ioc
->spi_data
.maxBusWidth
= MPT_NARROW
;
5363 ioc
->spi_data
.maxSyncOffset
= 0;
5364 ioc
->spi_data
.minSyncFactor
= MPT_ASYNC
;
5365 ioc
->spi_data
.busType
= MPT_HOST_BUS_UNKNOWN
;
5367 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5368 "Unable to read PortPage0 minSyncFactor=%x\n",
5369 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
5371 /* Save the Port Page 0 data
5373 SCSIPortPage0_t
*pPP0
= (SCSIPortPage0_t
*) pbuf
;
5374 pPP0
->Capabilities
= le32_to_cpu(pPP0
->Capabilities
);
5375 pPP0
->PhysicalInterface
= le32_to_cpu(pPP0
->PhysicalInterface
);
5377 if ( (pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_QAS
) == 0 ) {
5378 ioc
->spi_data
.noQas
|= MPT_TARGET_NO_NEGO_QAS
;
5379 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5380 "noQas due to Capabilities=%x\n",
5381 ioc
->name
, pPP0
->Capabilities
));
5383 ioc
->spi_data
.maxBusWidth
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_WIDE
? 1 : 0;
5384 data
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK
;
5386 ioc
->spi_data
.maxSyncOffset
= (u8
) (data
>> 16);
5387 data
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK
;
5388 ioc
->spi_data
.minSyncFactor
= (u8
) (data
>> 8);
5389 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5390 "PortPage0 minSyncFactor=%x\n",
5391 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
5393 ioc
->spi_data
.maxSyncOffset
= 0;
5394 ioc
->spi_data
.minSyncFactor
= MPT_ASYNC
;
5397 ioc
->spi_data
.busType
= pPP0
->PhysicalInterface
& MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK
;
5399 /* Update the minSyncFactor based on bus type.
5401 if ((ioc
->spi_data
.busType
== MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD
) ||
5402 (ioc
->spi_data
.busType
== MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE
)) {
5404 if (ioc
->spi_data
.minSyncFactor
< MPT_ULTRA
) {
5405 ioc
->spi_data
.minSyncFactor
= MPT_ULTRA
;
5406 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5407 "HVD or SE detected, minSyncFactor=%x\n",
5408 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
5413 pci_free_consistent(ioc
->pcidev
, header
.PageLength
* 4, pbuf
, buf_dma
);
5418 /* SCSI Port Page 2 - Read the header then the page.
5420 header
.PageVersion
= 0;
5421 header
.PageLength
= 0;
5422 header
.PageNumber
= 2;
5423 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_PORT
;
5424 cfg
.cfghdr
.hdr
= &header
;
5426 cfg
.pageAddr
= portnum
;
5427 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5429 if (mpt_config(ioc
, &cfg
) != 0)
5432 if (header
.PageLength
> 0) {
5433 /* Allocate memory and read SCSI Port Page 2
5435 pbuf
= pci_alloc_consistent(ioc
->pcidev
, header
.PageLength
* 4, &buf_dma
);
5437 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_NVRAM
;
5438 cfg
.physAddr
= buf_dma
;
5439 if (mpt_config(ioc
, &cfg
) != 0) {
5440 /* Nvram data is left with INVALID mark
5443 } else if (ioc
->pcidev
->vendor
== PCI_VENDOR_ID_ATTO
) {
5445 /* This is an ATTO adapter, read Page2 accordingly
5447 ATTO_SCSIPortPage2_t
*pPP2
= (ATTO_SCSIPortPage2_t
*) pbuf
;
5448 ATTODeviceInfo_t
*pdevice
= NULL
;
5451 /* Save the Port Page 2 data
5452 * (reformat into a 32bit quantity)
5454 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
5455 pdevice
= &pPP2
->DeviceSettings
[ii
];
5456 ATTOFlags
= le16_to_cpu(pdevice
->ATTOFlags
);
5459 /* Translate ATTO device flags to LSI format
5461 if (ATTOFlags
& ATTOFLAG_DISC
)
5462 data
|= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE
);
5463 if (ATTOFlags
& ATTOFLAG_ID_ENB
)
5464 data
|= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE
);
5465 if (ATTOFlags
& ATTOFLAG_LUN_ENB
)
5466 data
|= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE
);
5467 if (ATTOFlags
& ATTOFLAG_TAGGED
)
5468 data
|= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE
);
5469 if (!(ATTOFlags
& ATTOFLAG_WIDE_ENB
))
5470 data
|= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE
);
5472 data
= (data
<< 16) | (pdevice
->Period
<< 8) | 10;
5473 ioc
->spi_data
.nvram
[ii
] = data
;
5476 SCSIPortPage2_t
*pPP2
= (SCSIPortPage2_t
*) pbuf
;
5477 MpiDeviceInfo_t
*pdevice
= NULL
;
5480 * Save "Set to Avoid SCSI Bus Resets" flag
5482 ioc
->spi_data
.bus_reset
=
5483 (le32_to_cpu(pPP2
->PortFlags
) &
5484 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET
) ?
5487 /* Save the Port Page 2 data
5488 * (reformat into a 32bit quantity)
5490 data
= le32_to_cpu(pPP2
->PortFlags
) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK
;
5491 ioc
->spi_data
.PortFlags
= data
;
5492 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
5493 pdevice
= &pPP2
->DeviceSettings
[ii
];
5494 data
= (le16_to_cpu(pdevice
->DeviceFlags
) << 16) |
5495 (pdevice
->SyncFactor
<< 8) | pdevice
->Timeout
;
5496 ioc
->spi_data
.nvram
[ii
] = data
;
5500 pci_free_consistent(ioc
->pcidev
, header
.PageLength
* 4, pbuf
, buf_dma
);
5504 /* Update Adapter limits with those from NVRAM
5505 * Comment: Don't need to do this. Target performance
5506 * parameters will never exceed the adapters limits.
5512 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5514 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
5515 * @ioc: Pointer to a Adapter Strucutre
5516 * @portnum: IOC port number
5518 * Return: -EFAULT if read of config page header fails
5522 mpt_readScsiDevicePageHeaders(MPT_ADAPTER
*ioc
, int portnum
)
5525 ConfigPageHeader_t header
;
5527 /* Read the SCSI Device Page 1 header
5529 header
.PageVersion
= 0;
5530 header
.PageLength
= 0;
5531 header
.PageNumber
= 1;
5532 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_DEVICE
;
5533 cfg
.cfghdr
.hdr
= &header
;
5535 cfg
.pageAddr
= portnum
;
5536 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5539 if (mpt_config(ioc
, &cfg
) != 0)
5542 ioc
->spi_data
.sdp1version
= cfg
.cfghdr
.hdr
->PageVersion
;
5543 ioc
->spi_data
.sdp1length
= cfg
.cfghdr
.hdr
->PageLength
;
5545 header
.PageVersion
= 0;
5546 header
.PageLength
= 0;
5547 header
.PageNumber
= 0;
5548 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_DEVICE
;
5549 if (mpt_config(ioc
, &cfg
) != 0)
5552 ioc
->spi_data
.sdp0version
= cfg
.cfghdr
.hdr
->PageVersion
;
5553 ioc
->spi_data
.sdp0length
= cfg
.cfghdr
.hdr
->PageLength
;
5555 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Headers: 0: version %d length %d\n",
5556 ioc
->name
, ioc
->spi_data
.sdp0version
, ioc
->spi_data
.sdp0length
));
5558 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Headers: 1: version %d length %d\n",
5559 ioc
->name
, ioc
->spi_data
.sdp1version
, ioc
->spi_data
.sdp1length
));
5564 * mpt_inactive_raid_list_free - This clears this link list.
5565 * @ioc : pointer to per adapter structure
5568 mpt_inactive_raid_list_free(MPT_ADAPTER
*ioc
)
5570 struct inactive_raid_component_info
*component_info
, *pNext
;
5572 if (list_empty(&ioc
->raid_data
.inactive_list
))
5575 mutex_lock(&ioc
->raid_data
.inactive_list_mutex
);
5576 list_for_each_entry_safe(component_info
, pNext
,
5577 &ioc
->raid_data
.inactive_list
, list
) {
5578 list_del(&component_info
->list
);
5579 kfree(component_info
);
5581 mutex_unlock(&ioc
->raid_data
.inactive_list_mutex
);
5585 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5587 * @ioc : pointer to per adapter structure
5588 * @channel : volume channel
5589 * @id : volume target id
5592 mpt_inactive_raid_volumes(MPT_ADAPTER
*ioc
, u8 channel
, u8 id
)
5595 ConfigPageHeader_t hdr
;
5596 dma_addr_t dma_handle
;
5597 pRaidVolumePage0_t buffer
= NULL
;
5599 RaidPhysDiskPage0_t phys_disk
;
5600 struct inactive_raid_component_info
*component_info
;
5601 int handle_inactive_volumes
;
5603 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5604 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5605 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_VOLUME
;
5606 cfg
.pageAddr
= (channel
<< 8) + id
;
5607 cfg
.cfghdr
.hdr
= &hdr
;
5608 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5610 if (mpt_config(ioc
, &cfg
) != 0)
5613 if (!hdr
.PageLength
)
5616 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5622 cfg
.physAddr
= dma_handle
;
5623 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5625 if (mpt_config(ioc
, &cfg
) != 0)
5628 if (!buffer
->NumPhysDisks
)
5631 handle_inactive_volumes
=
5632 (buffer
->VolumeStatus
.Flags
& MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE
||
5633 (buffer
->VolumeStatus
.Flags
& MPI_RAIDVOL0_STATUS_FLAG_ENABLED
) == 0 ||
5634 buffer
->VolumeStatus
.State
== MPI_RAIDVOL0_STATUS_STATE_FAILED
||
5635 buffer
->VolumeStatus
.State
== MPI_RAIDVOL0_STATUS_STATE_MISSING
) ? 1 : 0;
5637 if (!handle_inactive_volumes
)
5640 mutex_lock(&ioc
->raid_data
.inactive_list_mutex
);
5641 for (i
= 0; i
< buffer
->NumPhysDisks
; i
++) {
5642 if(mpt_raid_phys_disk_pg0(ioc
,
5643 buffer
->PhysDisk
[i
].PhysDiskNum
, &phys_disk
) != 0)
5646 if ((component_info
= kmalloc(sizeof (*component_info
),
5647 GFP_KERNEL
)) == NULL
)
5650 component_info
->volumeID
= id
;
5651 component_info
->volumeBus
= channel
;
5652 component_info
->d
.PhysDiskNum
= phys_disk
.PhysDiskNum
;
5653 component_info
->d
.PhysDiskBus
= phys_disk
.PhysDiskBus
;
5654 component_info
->d
.PhysDiskID
= phys_disk
.PhysDiskID
;
5655 component_info
->d
.PhysDiskIOC
= phys_disk
.PhysDiskIOC
;
5657 list_add_tail(&component_info
->list
,
5658 &ioc
->raid_data
.inactive_list
);
5660 mutex_unlock(&ioc
->raid_data
.inactive_list_mutex
);
5664 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5669 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5670 * @ioc: Pointer to a Adapter Structure
5671 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5672 * @phys_disk: requested payload data returned
5676 * -EFAULT if read of config page header fails or data pointer not NULL
5677 * -ENOMEM if pci_alloc failed
5680 mpt_raid_phys_disk_pg0(MPT_ADAPTER
*ioc
, u8 phys_disk_num
,
5681 RaidPhysDiskPage0_t
*phys_disk
)
5684 ConfigPageHeader_t hdr
;
5685 dma_addr_t dma_handle
;
5686 pRaidPhysDiskPage0_t buffer
= NULL
;
5689 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5690 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5691 memset(phys_disk
, 0, sizeof(RaidPhysDiskPage0_t
));
5693 hdr
.PageVersion
= MPI_RAIDPHYSDISKPAGE0_PAGEVERSION
;
5694 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_PHYSDISK
;
5695 cfg
.cfghdr
.hdr
= &hdr
;
5697 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5699 if (mpt_config(ioc
, &cfg
) != 0) {
5704 if (!hdr
.PageLength
) {
5709 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5717 cfg
.physAddr
= dma_handle
;
5718 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5719 cfg
.pageAddr
= phys_disk_num
;
5721 if (mpt_config(ioc
, &cfg
) != 0) {
5727 memcpy(phys_disk
, buffer
, sizeof(*buffer
));
5728 phys_disk
->MaxLBA
= le32_to_cpu(buffer
->MaxLBA
);
5733 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5740 * mpt_raid_phys_disk_get_num_paths - returns number paths associated to this phys_num
5741 * @ioc: Pointer to a Adapter Structure
5742 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5745 * returns number paths
5748 mpt_raid_phys_disk_get_num_paths(MPT_ADAPTER
*ioc
, u8 phys_disk_num
)
5751 ConfigPageHeader_t hdr
;
5752 dma_addr_t dma_handle
;
5753 pRaidPhysDiskPage1_t buffer
= NULL
;
5756 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5757 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5759 hdr
.PageVersion
= MPI_RAIDPHYSDISKPAGE1_PAGEVERSION
;
5760 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_PHYSDISK
;
5762 cfg
.cfghdr
.hdr
= &hdr
;
5764 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5766 if (mpt_config(ioc
, &cfg
) != 0) {
5771 if (!hdr
.PageLength
) {
5776 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5784 cfg
.physAddr
= dma_handle
;
5785 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5786 cfg
.pageAddr
= phys_disk_num
;
5788 if (mpt_config(ioc
, &cfg
) != 0) {
5793 rc
= buffer
->NumPhysDiskPaths
;
5797 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5802 EXPORT_SYMBOL(mpt_raid_phys_disk_get_num_paths
);
5805 * mpt_raid_phys_disk_pg1 - returns phys disk page 1
5806 * @ioc: Pointer to a Adapter Structure
5807 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5808 * @phys_disk: requested payload data returned
5812 * -EFAULT if read of config page header fails or data pointer not NULL
5813 * -ENOMEM if pci_alloc failed
5816 mpt_raid_phys_disk_pg1(MPT_ADAPTER
*ioc
, u8 phys_disk_num
,
5817 RaidPhysDiskPage1_t
*phys_disk
)
5820 ConfigPageHeader_t hdr
;
5821 dma_addr_t dma_handle
;
5822 pRaidPhysDiskPage1_t buffer
= NULL
;
5827 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5828 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5831 hdr
.PageVersion
= MPI_RAIDPHYSDISKPAGE1_PAGEVERSION
;
5832 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_PHYSDISK
;
5834 cfg
.cfghdr
.hdr
= &hdr
;
5836 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5838 if (mpt_config(ioc
, &cfg
) != 0) {
5843 if (!hdr
.PageLength
) {
5848 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5856 cfg
.physAddr
= dma_handle
;
5857 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5858 cfg
.pageAddr
= phys_disk_num
;
5860 if (mpt_config(ioc
, &cfg
) != 0) {
5865 phys_disk
->NumPhysDiskPaths
= buffer
->NumPhysDiskPaths
;
5866 phys_disk
->PhysDiskNum
= phys_disk_num
;
5867 for (i
= 0; i
< phys_disk
->NumPhysDiskPaths
; i
++) {
5868 phys_disk
->Path
[i
].PhysDiskID
= buffer
->Path
[i
].PhysDiskID
;
5869 phys_disk
->Path
[i
].PhysDiskBus
= buffer
->Path
[i
].PhysDiskBus
;
5870 phys_disk
->Path
[i
].OwnerIdentifier
=
5871 buffer
->Path
[i
].OwnerIdentifier
;
5872 phys_disk
->Path
[i
].Flags
= le16_to_cpu(buffer
->Path
[i
].Flags
);
5873 memcpy(&sas_address
, &buffer
->Path
[i
].WWID
, sizeof(__le64
));
5874 sas_address
= le64_to_cpu(sas_address
);
5875 memcpy(&phys_disk
->Path
[i
].WWID
, &sas_address
, sizeof(__le64
));
5876 memcpy(&sas_address
,
5877 &buffer
->Path
[i
].OwnerWWID
, sizeof(__le64
));
5878 sas_address
= le64_to_cpu(sas_address
);
5879 memcpy(&phys_disk
->Path
[i
].OwnerWWID
,
5880 &sas_address
, sizeof(__le64
));
5886 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5891 EXPORT_SYMBOL(mpt_raid_phys_disk_pg1
);
5895 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5896 * @ioc: Pointer to a Adapter Strucutre
5900 * -EFAULT if read of config page header fails or data pointer not NULL
5901 * -ENOMEM if pci_alloc failed
5904 mpt_findImVolumes(MPT_ADAPTER
*ioc
)
5908 dma_addr_t ioc2_dma
;
5910 ConfigPageHeader_t header
;
5915 if (!ioc
->ir_firmware
)
5918 /* Free the old page
5920 kfree(ioc
->raid_data
.pIocPg2
);
5921 ioc
->raid_data
.pIocPg2
= NULL
;
5922 mpt_inactive_raid_list_free(ioc
);
5924 /* Read IOCP2 header then the page.
5926 header
.PageVersion
= 0;
5927 header
.PageLength
= 0;
5928 header
.PageNumber
= 2;
5929 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
5930 cfg
.cfghdr
.hdr
= &header
;
5933 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5936 if (mpt_config(ioc
, &cfg
) != 0)
5939 if (header
.PageLength
== 0)
5942 iocpage2sz
= header
.PageLength
* 4;
5943 pIoc2
= pci_alloc_consistent(ioc
->pcidev
, iocpage2sz
, &ioc2_dma
);
5947 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5948 cfg
.physAddr
= ioc2_dma
;
5949 if (mpt_config(ioc
, &cfg
) != 0)
5952 mem
= kmalloc(iocpage2sz
, GFP_KERNEL
);
5956 memcpy(mem
, (u8
*)pIoc2
, iocpage2sz
);
5957 ioc
->raid_data
.pIocPg2
= (IOCPage2_t
*) mem
;
5959 mpt_read_ioc_pg_3(ioc
);
5961 for (i
= 0; i
< pIoc2
->NumActiveVolumes
; i
++)
5962 mpt_inactive_raid_volumes(ioc
,
5963 pIoc2
->RaidVolume
[i
].VolumeBus
,
5964 pIoc2
->RaidVolume
[i
].VolumeID
);
5967 pci_free_consistent(ioc
->pcidev
, iocpage2sz
, pIoc2
, ioc2_dma
);
5973 mpt_read_ioc_pg_3(MPT_ADAPTER
*ioc
)
5978 ConfigPageHeader_t header
;
5979 dma_addr_t ioc3_dma
;
5982 /* Free the old page
5984 kfree(ioc
->raid_data
.pIocPg3
);
5985 ioc
->raid_data
.pIocPg3
= NULL
;
5987 /* There is at least one physical disk.
5988 * Read and save IOC Page 3
5990 header
.PageVersion
= 0;
5991 header
.PageLength
= 0;
5992 header
.PageNumber
= 3;
5993 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
5994 cfg
.cfghdr
.hdr
= &header
;
5997 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
6000 if (mpt_config(ioc
, &cfg
) != 0)
6003 if (header
.PageLength
== 0)
6006 /* Read Header good, alloc memory
6008 iocpage3sz
= header
.PageLength
* 4;
6009 pIoc3
= pci_alloc_consistent(ioc
->pcidev
, iocpage3sz
, &ioc3_dma
);
6013 /* Read the Page and save the data
6014 * into malloc'd memory.
6016 cfg
.physAddr
= ioc3_dma
;
6017 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
6018 if (mpt_config(ioc
, &cfg
) == 0) {
6019 mem
= kmalloc(iocpage3sz
, GFP_KERNEL
);
6021 memcpy(mem
, (u8
*)pIoc3
, iocpage3sz
);
6022 ioc
->raid_data
.pIocPg3
= (IOCPage3_t
*) mem
;
6026 pci_free_consistent(ioc
->pcidev
, iocpage3sz
, pIoc3
, ioc3_dma
);
6032 mpt_read_ioc_pg_4(MPT_ADAPTER
*ioc
)
6036 ConfigPageHeader_t header
;
6037 dma_addr_t ioc4_dma
;
6040 /* Read and save IOC Page 4
6042 header
.PageVersion
= 0;
6043 header
.PageLength
= 0;
6044 header
.PageNumber
= 4;
6045 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
6046 cfg
.cfghdr
.hdr
= &header
;
6049 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
6052 if (mpt_config(ioc
, &cfg
) != 0)
6055 if (header
.PageLength
== 0)
6058 if ( (pIoc4
= ioc
->spi_data
.pIocPg4
) == NULL
) {
6059 iocpage4sz
= (header
.PageLength
+ 4) * 4; /* Allow 4 additional SEP's */
6060 pIoc4
= pci_alloc_consistent(ioc
->pcidev
, iocpage4sz
, &ioc4_dma
);
6063 ioc
->alloc_total
+= iocpage4sz
;
6065 ioc4_dma
= ioc
->spi_data
.IocPg4_dma
;
6066 iocpage4sz
= ioc
->spi_data
.IocPg4Sz
;
6069 /* Read the Page into dma memory.
6071 cfg
.physAddr
= ioc4_dma
;
6072 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
6073 if (mpt_config(ioc
, &cfg
) == 0) {
6074 ioc
->spi_data
.pIocPg4
= (IOCPage4_t
*) pIoc4
;
6075 ioc
->spi_data
.IocPg4_dma
= ioc4_dma
;
6076 ioc
->spi_data
.IocPg4Sz
= iocpage4sz
;
6078 pci_free_consistent(ioc
->pcidev
, iocpage4sz
, pIoc4
, ioc4_dma
);
6079 ioc
->spi_data
.pIocPg4
= NULL
;
6080 ioc
->alloc_total
-= iocpage4sz
;
6085 mpt_read_ioc_pg_1(MPT_ADAPTER
*ioc
)
6089 ConfigPageHeader_t header
;
6090 dma_addr_t ioc1_dma
;
6094 /* Check the Coalescing Timeout in IOC Page 1
6096 header
.PageVersion
= 0;
6097 header
.PageLength
= 0;
6098 header
.PageNumber
= 1;
6099 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
6100 cfg
.cfghdr
.hdr
= &header
;
6103 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
6106 if (mpt_config(ioc
, &cfg
) != 0)
6109 if (header
.PageLength
== 0)
6112 /* Read Header good, alloc memory
6114 iocpage1sz
= header
.PageLength
* 4;
6115 pIoc1
= pci_alloc_consistent(ioc
->pcidev
, iocpage1sz
, &ioc1_dma
);
6119 /* Read the Page and check coalescing timeout
6121 cfg
.physAddr
= ioc1_dma
;
6122 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
6123 if (mpt_config(ioc
, &cfg
) == 0) {
6125 tmp
= le32_to_cpu(pIoc1
->Flags
) & MPI_IOCPAGE1_REPLY_COALESCING
;
6126 if (tmp
== MPI_IOCPAGE1_REPLY_COALESCING
) {
6127 tmp
= le32_to_cpu(pIoc1
->CoalescingTimeout
);
6129 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Coalescing Enabled Timeout = %d\n",
6132 if (tmp
> MPT_COALESCING_TIMEOUT
) {
6133 pIoc1
->CoalescingTimeout
= cpu_to_le32(MPT_COALESCING_TIMEOUT
);
6135 /* Write NVRAM and current
6138 cfg
.action
= MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT
;
6139 if (mpt_config(ioc
, &cfg
) == 0) {
6140 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Reset Current Coalescing Timeout to = %d\n",
6141 ioc
->name
, MPT_COALESCING_TIMEOUT
));
6143 cfg
.action
= MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM
;
6144 if (mpt_config(ioc
, &cfg
) == 0) {
6145 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6146 "Reset NVRAM Coalescing Timeout to = %d\n",
6147 ioc
->name
, MPT_COALESCING_TIMEOUT
));
6149 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6150 "Reset NVRAM Coalescing Timeout Failed\n",
6155 dprintk(ioc
, printk(MYIOC_s_WARN_FMT
6156 "Reset of Current Coalescing Timeout Failed!\n",
6162 dprintk(ioc
, printk(MYIOC_s_WARN_FMT
"Coalescing Disabled\n", ioc
->name
));
6166 pci_free_consistent(ioc
->pcidev
, iocpage1sz
, pIoc1
, ioc1_dma
);
6172 mpt_get_manufacturing_pg_0(MPT_ADAPTER
*ioc
)
6175 ConfigPageHeader_t hdr
;
6177 ManufacturingPage0_t
*pbuf
= NULL
;
6179 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
6180 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
6182 hdr
.PageType
= MPI_CONFIG_PAGETYPE_MANUFACTURING
;
6183 cfg
.cfghdr
.hdr
= &hdr
;
6185 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
6188 if (mpt_config(ioc
, &cfg
) != 0)
6191 if (!cfg
.cfghdr
.hdr
->PageLength
)
6194 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
6195 pbuf
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, &buf_dma
);
6199 cfg
.physAddr
= buf_dma
;
6201 if (mpt_config(ioc
, &cfg
) != 0)
6204 memcpy(ioc
->board_name
, pbuf
->BoardName
, sizeof(ioc
->board_name
));
6205 memcpy(ioc
->board_assembly
, pbuf
->BoardAssembly
, sizeof(ioc
->board_assembly
));
6206 memcpy(ioc
->board_tracer
, pbuf
->BoardTracerNumber
, sizeof(ioc
->board_tracer
));
6211 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, pbuf
, buf_dma
);
6214 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6216 * SendEventNotification - Send EventNotification (on or off) request to adapter
6217 * @ioc: Pointer to MPT_ADAPTER structure
6218 * @EvSwitch: Event switch flags
6219 * @sleepFlag: Specifies whether the process can sleep
6222 SendEventNotification(MPT_ADAPTER
*ioc
, u8 EvSwitch
, int sleepFlag
)
6224 EventNotification_t evn
;
6225 MPIDefaultReply_t reply_buf
;
6227 memset(&evn
, 0, sizeof(EventNotification_t
));
6228 memset(&reply_buf
, 0, sizeof(MPIDefaultReply_t
));
6230 evn
.Function
= MPI_FUNCTION_EVENT_NOTIFICATION
;
6231 evn
.Switch
= EvSwitch
;
6232 evn
.MsgContext
= cpu_to_le32(mpt_base_index
<< 16);
6234 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6235 "Sending EventNotification (%d) request %p\n",
6236 ioc
->name
, EvSwitch
, &evn
));
6238 return mpt_handshake_req_reply_wait(ioc
, sizeof(EventNotification_t
),
6239 (u32
*)&evn
, sizeof(MPIDefaultReply_t
), (u16
*)&reply_buf
, 30,
6243 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6245 * SendEventAck - Send EventAck request to MPT adapter.
6246 * @ioc: Pointer to MPT_ADAPTER structure
6247 * @evnp: Pointer to original EventNotification request
6250 SendEventAck(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*evnp
)
6254 if ((pAck
= (EventAck_t
*) mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
6255 dfailprintk(ioc
, printk(MYIOC_s_WARN_FMT
"%s, no msg frames!!\n",
6256 ioc
->name
, __func__
));
6260 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending EventAck\n", ioc
->name
));
6262 pAck
->Function
= MPI_FUNCTION_EVENT_ACK
;
6263 pAck
->ChainOffset
= 0;
6264 pAck
->Reserved
[0] = pAck
->Reserved
[1] = 0;
6266 pAck
->Reserved1
[0] = pAck
->Reserved1
[1] = pAck
->Reserved1
[2] = 0;
6267 pAck
->Event
= evnp
->Event
;
6268 pAck
->EventContext
= evnp
->EventContext
;
6270 mpt_put_msg_frame(mpt_base_index
, ioc
, (MPT_FRAME_HDR
*)pAck
);
6275 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6277 * mpt_config - Generic function to issue config message
6278 * @ioc: Pointer to an adapter structure
6279 * @pCfg: Pointer to a configuration structure. Struct contains
6280 * action, page address, direction, physical address
6281 * and pointer to a configuration page header
6282 * Page header is updated.
6284 * Returns 0 for success
6285 * -EPERM if not allowed due to ISR context
6286 * -EAGAIN if no msg frames currently available
6287 * -EFAULT for non-successful reply or no reply (timeout)
6290 mpt_config(MPT_ADAPTER
*ioc
, CONFIGPARMS
*pCfg
)
6293 ConfigReply_t
*pReply
;
6294 ConfigExtendedPageHeader_t
*pExtHdr
= NULL
;
6300 u8 page_type
= 0, extend_page
;
6301 unsigned long timeleft
;
6302 unsigned long flags
;
6304 u8 issue_hard_reset
= 0;
6307 /* Prevent calling wait_event() (below), if caller happens
6308 * to be in ISR context, because that is fatal!
6310 in_isr
= in_interrupt();
6312 dcprintk(ioc
, printk(MYIOC_s_WARN_FMT
"Config request not allowed in ISR context!\n",
6317 /* don't send a config page during diag reset */
6318 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
6319 if (ioc
->ioc_reset_in_progress
) {
6320 dfailprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6321 "%s: busy with host reset\n", ioc
->name
, __func__
));
6322 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6325 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6327 /* don't send if no chance of success */
6329 mpt_GetIocState(ioc
, 1) != MPI_IOC_STATE_OPERATIONAL
) {
6330 dfailprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6331 "%s: ioc not operational, %d, %xh\n",
6332 ioc
->name
, __func__
, ioc
->active
,
6333 mpt_GetIocState(ioc
, 0)));
6338 mutex_lock(&ioc
->mptbase_cmds
.mutex
);
6339 /* init the internal cmd struct */
6340 memset(ioc
->mptbase_cmds
.reply
, 0 , MPT_DEFAULT_FRAME_SIZE
);
6341 INITIALIZE_MGMT_STATUS(ioc
->mptbase_cmds
.status
)
6343 /* Get and Populate a free Frame
6345 if ((mf
= mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
6346 dcprintk(ioc
, printk(MYIOC_s_WARN_FMT
6347 "mpt_config: no msg frames!\n", ioc
->name
));
6352 pReq
= (Config_t
*)mf
;
6353 pReq
->Action
= pCfg
->action
;
6355 pReq
->ChainOffset
= 0;
6356 pReq
->Function
= MPI_FUNCTION_CONFIG
;
6358 /* Assume page type is not extended and clear "reserved" fields. */
6359 pReq
->ExtPageLength
= 0;
6360 pReq
->ExtPageType
= 0;
6363 for (ii
=0; ii
< 8; ii
++)
6364 pReq
->Reserved2
[ii
] = 0;
6366 pReq
->Header
.PageVersion
= pCfg
->cfghdr
.hdr
->PageVersion
;
6367 pReq
->Header
.PageLength
= pCfg
->cfghdr
.hdr
->PageLength
;
6368 pReq
->Header
.PageNumber
= pCfg
->cfghdr
.hdr
->PageNumber
;
6369 pReq
->Header
.PageType
= (pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
);
6371 if ((pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
) == MPI_CONFIG_PAGETYPE_EXTENDED
) {
6372 pExtHdr
= (ConfigExtendedPageHeader_t
*)pCfg
->cfghdr
.ehdr
;
6373 pReq
->ExtPageLength
= cpu_to_le16(pExtHdr
->ExtPageLength
);
6374 pReq
->ExtPageType
= pExtHdr
->ExtPageType
;
6375 pReq
->Header
.PageType
= MPI_CONFIG_PAGETYPE_EXTENDED
;
6377 /* Page Length must be treated as a reserved field for the
6380 pReq
->Header
.PageLength
= 0;
6383 pReq
->PageAddress
= cpu_to_le32(pCfg
->pageAddr
);
6385 /* Add a SGE to the config request.
6388 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_WRITE
;
6390 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_READ
;
6392 if ((pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
) ==
6393 MPI_CONFIG_PAGETYPE_EXTENDED
) {
6394 flagsLength
|= pExtHdr
->ExtPageLength
* 4;
6395 page_type
= pReq
->ExtPageType
;
6398 flagsLength
|= pCfg
->cfghdr
.hdr
->PageLength
* 4;
6399 page_type
= pReq
->Header
.PageType
;
6403 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6404 "Sending Config request type 0x%x, page 0x%x and action %d\n",
6405 ioc
->name
, page_type
, pReq
->Header
.PageNumber
, pReq
->Action
));
6407 ioc
->add_sge((char *)&pReq
->PageBufferSGE
, flagsLength
, pCfg
->physAddr
);
6408 timeout
= (pCfg
->timeout
< 15) ? HZ
*15 : HZ
*pCfg
->timeout
;
6409 mpt_put_msg_frame(mpt_base_index
, ioc
, mf
);
6410 timeleft
= wait_for_completion_timeout(&ioc
->mptbase_cmds
.done
,
6412 if (!(ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_COMMAND_GOOD
)) {
6414 dfailprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6415 "Failed Sending Config request type 0x%x, page 0x%x,"
6416 " action %d, status %xh, time left %ld\n\n",
6417 ioc
->name
, page_type
, pReq
->Header
.PageNumber
,
6418 pReq
->Action
, ioc
->mptbase_cmds
.status
, timeleft
));
6419 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_DID_IOCRESET
)
6422 issue_hard_reset
= 1;
6426 if (!(ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_RF_VALID
)) {
6430 pReply
= (ConfigReply_t
*)ioc
->mptbase_cmds
.reply
;
6431 ret
= le16_to_cpu(pReply
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
6432 if (ret
== MPI_IOCSTATUS_SUCCESS
) {
6434 pCfg
->cfghdr
.ehdr
->ExtPageLength
=
6435 le16_to_cpu(pReply
->ExtPageLength
);
6436 pCfg
->cfghdr
.ehdr
->ExtPageType
=
6437 pReply
->ExtPageType
;
6439 pCfg
->cfghdr
.hdr
->PageVersion
= pReply
->Header
.PageVersion
;
6440 pCfg
->cfghdr
.hdr
->PageLength
= pReply
->Header
.PageLength
;
6441 pCfg
->cfghdr
.hdr
->PageNumber
= pReply
->Header
.PageNumber
;
6442 pCfg
->cfghdr
.hdr
->PageType
= pReply
->Header
.PageType
;
6447 printk(MYIOC_s_INFO_FMT
"Retry completed "
6448 "ret=0x%x timeleft=%ld\n",
6449 ioc
->name
, ret
, timeleft
);
6451 dcprintk(ioc
, printk(KERN_DEBUG
"IOCStatus=%04xh, IOCLogInfo=%08xh\n",
6452 ret
, le32_to_cpu(pReply
->IOCLogInfo
)));
6456 CLEAR_MGMT_STATUS(ioc
->mptbase_cmds
.status
)
6457 mutex_unlock(&ioc
->mptbase_cmds
.mutex
);
6458 if (issue_hard_reset
) {
6459 issue_hard_reset
= 0;
6460 printk(MYIOC_s_WARN_FMT
"Issuing Reset from %s!!\n",
6461 ioc
->name
, __func__
);
6462 if (retry_count
== 0) {
6463 if (mpt_Soft_Hard_ResetHandler(ioc
, CAN_SLEEP
) != 0)
6466 mpt_HardResetHandler(ioc
, CAN_SLEEP
);
6468 mpt_free_msg_frame(ioc
, mf
);
6469 /* attempt one retry for a timed out command */
6470 if (retry_count
< 2) {
6471 printk(MYIOC_s_INFO_FMT
6472 "Attempting Retry Config request"
6473 " type 0x%x, page 0x%x,"
6474 " action %d\n", ioc
->name
, page_type
,
6475 pCfg
->cfghdr
.hdr
->PageNumber
, pCfg
->action
);
6484 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6486 * mpt_ioc_reset - Base cleanup for hard reset
6487 * @ioc: Pointer to the adapter structure
6488 * @reset_phase: Indicates pre- or post-reset functionality
6490 * Remark: Frees resources with internally generated commands.
6493 mpt_ioc_reset(MPT_ADAPTER
*ioc
, int reset_phase
)
6495 switch (reset_phase
) {
6496 case MPT_IOC_SETUP_RESET
:
6497 ioc
->taskmgmt_quiesce_io
= 1;
6498 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6499 "%s: MPT_IOC_SETUP_RESET\n", ioc
->name
, __func__
));
6501 case MPT_IOC_PRE_RESET
:
6502 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6503 "%s: MPT_IOC_PRE_RESET\n", ioc
->name
, __func__
));
6505 case MPT_IOC_POST_RESET
:
6506 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6507 "%s: MPT_IOC_POST_RESET\n", ioc
->name
, __func__
));
6508 /* wake up mptbase_cmds */
6509 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_PENDING
) {
6510 ioc
->mptbase_cmds
.status
|=
6511 MPT_MGMT_STATUS_DID_IOCRESET
;
6512 complete(&ioc
->mptbase_cmds
.done
);
6514 /* wake up taskmgmt_cmds */
6515 if (ioc
->taskmgmt_cmds
.status
& MPT_MGMT_STATUS_PENDING
) {
6516 ioc
->taskmgmt_cmds
.status
|=
6517 MPT_MGMT_STATUS_DID_IOCRESET
;
6518 complete(&ioc
->taskmgmt_cmds
.done
);
6525 return 1; /* currently means nothing really */
6529 #ifdef CONFIG_PROC_FS /* { */
6530 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6532 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
6534 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6536 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
6538 * Returns 0 for success, non-zero for failure.
6541 procmpt_create(void)
6543 struct proc_dir_entry
*ent
;
6545 mpt_proc_root_dir
= proc_mkdir(MPT_PROCFS_MPTBASEDIR
, NULL
);
6546 if (mpt_proc_root_dir
== NULL
)
6549 ent
= create_proc_entry("summary", S_IFREG
|S_IRUGO
, mpt_proc_root_dir
);
6551 ent
->read_proc
= procmpt_summary_read
;
6553 ent
= create_proc_entry("version", S_IFREG
|S_IRUGO
, mpt_proc_root_dir
);
6555 ent
->read_proc
= procmpt_version_read
;
6560 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6562 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
6564 * Returns 0 for success, non-zero for failure.
6567 procmpt_destroy(void)
6569 remove_proc_entry("version", mpt_proc_root_dir
);
6570 remove_proc_entry("summary", mpt_proc_root_dir
);
6571 remove_proc_entry(MPT_PROCFS_MPTBASEDIR
, NULL
);
6574 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6576 * procmpt_summary_read - Handle read request of a summary file
6577 * @buf: Pointer to area to write information
6578 * @start: Pointer to start pointer
6579 * @offset: Offset to start writing
6580 * @request: Amount of read data requested
6581 * @eof: Pointer to EOF integer
6584 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
6585 * Returns number of characters written to process performing the read.
6588 procmpt_summary_read(char *buf
, char **start
, off_t offset
, int request
, int *eof
, void *data
)
6598 mpt_print_ioc_summary(ioc
, out
, &more
, 0, 1);
6602 list_for_each_entry(ioc
, &ioc_list
, list
) {
6605 mpt_print_ioc_summary(ioc
, out
, &more
, 0, 1);
6608 if ((out
-buf
) >= request
)
6615 MPT_PROC_READ_RETURN(buf
,start
,offset
,request
,eof
,len
);
6618 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6620 * procmpt_version_read - Handle read request from /proc/mpt/version.
6621 * @buf: Pointer to area to write information
6622 * @start: Pointer to start pointer
6623 * @offset: Offset to start writing
6624 * @request: Amount of read data requested
6625 * @eof: Pointer to EOF integer
6628 * Returns number of characters written to process performing the read.
6631 procmpt_version_read(char *buf
, char **start
, off_t offset
, int request
, int *eof
, void *data
)
6634 int scsi
, fc
, sas
, lan
, ctl
, targ
, dmp
;
6638 len
= sprintf(buf
, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON
);
6639 len
+= sprintf(buf
+len
, " Fusion MPT base driver\n");
6641 scsi
= fc
= sas
= lan
= ctl
= targ
= dmp
= 0;
6642 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
6644 if (MptCallbacks
[cb_idx
]) {
6645 switch (MptDriverClass
[cb_idx
]) {
6647 if (!scsi
++) drvname
= "SPI host";
6650 if (!fc
++) drvname
= "FC host";
6653 if (!sas
++) drvname
= "SAS host";
6656 if (!lan
++) drvname
= "LAN";
6659 if (!targ
++) drvname
= "SCSI target";
6662 if (!ctl
++) drvname
= "ioctl";
6667 len
+= sprintf(buf
+len
, " Fusion MPT %s driver\n", drvname
);
6671 MPT_PROC_READ_RETURN(buf
,start
,offset
,request
,eof
,len
);
6674 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6676 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
6677 * @buf: Pointer to area to write information
6678 * @start: Pointer to start pointer
6679 * @offset: Offset to start writing
6680 * @request: Amount of read data requested
6681 * @eof: Pointer to EOF integer
6684 * Returns number of characters written to process performing the read.
6687 procmpt_iocinfo_read(char *buf
, char **start
, off_t offset
, int request
, int *eof
, void *data
)
6689 MPT_ADAPTER
*ioc
= data
;
6695 mpt_get_fw_exp_ver(expVer
, ioc
);
6697 len
= sprintf(buf
, "%s:", ioc
->name
);
6698 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)
6699 len
+= sprintf(buf
+len
, " (f/w download boot flag set)");
6700 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6701 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
6703 len
+= sprintf(buf
+len
, "\n ProductID = 0x%04x (%s)\n",
6704 ioc
->facts
.ProductID
,
6706 len
+= sprintf(buf
+len
, " FWVersion = 0x%08x%s", ioc
->facts
.FWVersion
.Word
, expVer
);
6707 if (ioc
->facts
.FWImageSize
)
6708 len
+= sprintf(buf
+len
, " (fw_size=%d)", ioc
->facts
.FWImageSize
);
6709 len
+= sprintf(buf
+len
, "\n MsgVersion = 0x%04x\n", ioc
->facts
.MsgVersion
);
6710 len
+= sprintf(buf
+len
, " FirstWhoInit = 0x%02x\n", ioc
->FirstWhoInit
);
6711 len
+= sprintf(buf
+len
, " EventState = 0x%02x\n", ioc
->facts
.EventState
);
6713 len
+= sprintf(buf
+len
, " CurrentHostMfaHighAddr = 0x%08x\n",
6714 ioc
->facts
.CurrentHostMfaHighAddr
);
6715 len
+= sprintf(buf
+len
, " CurrentSenseBufferHighAddr = 0x%08x\n",
6716 ioc
->facts
.CurrentSenseBufferHighAddr
);
6718 len
+= sprintf(buf
+len
, " MaxChainDepth = 0x%02x frames\n", ioc
->facts
.MaxChainDepth
);
6719 len
+= sprintf(buf
+len
, " MinBlockSize = 0x%02x bytes\n", 4*ioc
->facts
.BlockSize
);
6721 len
+= sprintf(buf
+len
, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6722 (void *)ioc
->req_frames
, (void *)(ulong
)ioc
->req_frames_dma
);
6724 * Rounding UP to nearest 4-kB boundary here...
6726 sz
= (ioc
->req_sz
* ioc
->req_depth
) + 128;
6727 sz
= ((sz
+ 0x1000UL
- 1UL) / 0x1000) * 0x1000;
6728 len
+= sprintf(buf
+len
, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6729 ioc
->req_sz
, ioc
->req_depth
, ioc
->req_sz
*ioc
->req_depth
, sz
);
6730 len
+= sprintf(buf
+len
, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
6731 4*ioc
->facts
.RequestFrameSize
,
6732 ioc
->facts
.GlobalCredits
);
6734 len
+= sprintf(buf
+len
, " Frames @ 0x%p (Dma @ 0x%p)\n",
6735 (void *)ioc
->alloc
, (void *)(ulong
)ioc
->alloc_dma
);
6736 sz
= (ioc
->reply_sz
* ioc
->reply_depth
) + 128;
6737 len
+= sprintf(buf
+len
, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6738 ioc
->reply_sz
, ioc
->reply_depth
, ioc
->reply_sz
*ioc
->reply_depth
, sz
);
6739 len
+= sprintf(buf
+len
, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
6740 ioc
->facts
.CurReplyFrameSize
,
6741 ioc
->facts
.ReplyQueueDepth
);
6743 len
+= sprintf(buf
+len
, " MaxDevices = %d\n",
6744 (ioc
->facts
.MaxDevices
==0) ? 255 : ioc
->facts
.MaxDevices
);
6745 len
+= sprintf(buf
+len
, " MaxBuses = %d\n", ioc
->facts
.MaxBuses
);
6748 for (p
=0; p
< ioc
->facts
.NumberOfPorts
; p
++) {
6749 len
+= sprintf(buf
+len
, " PortNumber = %d (of %d)\n",
6751 ioc
->facts
.NumberOfPorts
);
6752 if (ioc
->bus_type
== FC
) {
6753 if (ioc
->pfacts
[p
].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
) {
6754 u8
*a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
6755 len
+= sprintf(buf
+len
, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6756 a
[5], a
[4], a
[3], a
[2], a
[1], a
[0]);
6758 len
+= sprintf(buf
+len
, " WWN = %08X%08X:%08X%08X\n",
6759 ioc
->fc_port_page0
[p
].WWNN
.High
,
6760 ioc
->fc_port_page0
[p
].WWNN
.Low
,
6761 ioc
->fc_port_page0
[p
].WWPN
.High
,
6762 ioc
->fc_port_page0
[p
].WWPN
.Low
);
6766 MPT_PROC_READ_RETURN(buf
,start
,offset
,request
,eof
,len
);
6769 #endif /* CONFIG_PROC_FS } */
6771 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6773 mpt_get_fw_exp_ver(char *buf
, MPT_ADAPTER
*ioc
)
6776 if ((ioc
->facts
.FWVersion
.Word
>> 24) == 0x0E) {
6777 sprintf(buf
, " (Exp %02d%02d)",
6778 (ioc
->facts
.FWVersion
.Word
>> 16) & 0x00FF, /* Month */
6779 (ioc
->facts
.FWVersion
.Word
>> 8) & 0x1F); /* Day */
6782 if ((ioc
->facts
.FWVersion
.Word
>> 8) & 0x80)
6783 strcat(buf
, " [MDBG]");
6787 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6789 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6790 * @ioc: Pointer to MPT_ADAPTER structure
6791 * @buffer: Pointer to buffer where IOC summary info should be written
6792 * @size: Pointer to number of bytes we wrote (set by this routine)
6793 * @len: Offset at which to start writing in buffer
6794 * @showlan: Display LAN stuff?
6796 * This routine writes (english readable) ASCII text, which represents
6797 * a summary of IOC information, to a buffer.
6800 mpt_print_ioc_summary(MPT_ADAPTER
*ioc
, char *buffer
, int *size
, int len
, int showlan
)
6805 mpt_get_fw_exp_ver(expVer
, ioc
);
6808 * Shorter summary of attached ioc's...
6810 y
= sprintf(buffer
+len
, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6813 MPT_FW_REV_MAGIC_ID_STRING
, /* "FwRev=" or somesuch */
6814 ioc
->facts
.FWVersion
.Word
,
6816 ioc
->facts
.NumberOfPorts
,
6819 if (showlan
&& (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
)) {
6820 u8
*a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
6821 y
+= sprintf(buffer
+len
+y
, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6822 a
[5], a
[4], a
[3], a
[2], a
[1], a
[0]);
6825 y
+= sprintf(buffer
+len
+y
, ", IRQ=%d", ioc
->pci_irq
);
6828 y
+= sprintf(buffer
+len
+y
, " (disabled)");
6830 y
+= sprintf(buffer
+len
+y
, "\n");
6835 * mpt_set_taskmgmt_in_progress_flag - set flags associated with task management
6836 * @ioc: Pointer to MPT_ADAPTER structure
6838 * Returns 0 for SUCCESS or -1 if FAILED.
6840 * If -1 is return, then it was not possible to set the flags
6843 mpt_set_taskmgmt_in_progress_flag(MPT_ADAPTER
*ioc
)
6845 unsigned long flags
;
6848 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
6849 if (ioc
->ioc_reset_in_progress
|| ioc
->taskmgmt_in_progress
||
6850 (ioc
->alt_ioc
&& ioc
->alt_ioc
->taskmgmt_in_progress
)) {
6855 ioc
->taskmgmt_in_progress
= 1;
6856 ioc
->taskmgmt_quiesce_io
= 1;
6858 ioc
->alt_ioc
->taskmgmt_in_progress
= 1;
6859 ioc
->alt_ioc
->taskmgmt_quiesce_io
= 1;
6862 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6865 EXPORT_SYMBOL(mpt_set_taskmgmt_in_progress_flag
);
6868 * mpt_clear_taskmgmt_in_progress_flag - clear flags associated with task management
6869 * @ioc: Pointer to MPT_ADAPTER structure
6873 mpt_clear_taskmgmt_in_progress_flag(MPT_ADAPTER
*ioc
)
6875 unsigned long flags
;
6877 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
6878 ioc
->taskmgmt_in_progress
= 0;
6879 ioc
->taskmgmt_quiesce_io
= 0;
6881 ioc
->alt_ioc
->taskmgmt_in_progress
= 0;
6882 ioc
->alt_ioc
->taskmgmt_quiesce_io
= 0;
6884 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6886 EXPORT_SYMBOL(mpt_clear_taskmgmt_in_progress_flag
);
6890 * mpt_halt_firmware - Halts the firmware if it is operational and panic
6892 * @ioc: Pointer to MPT_ADAPTER structure
6896 mpt_halt_firmware(MPT_ADAPTER
*ioc
)
6900 ioc_raw_state
= mpt_GetIocState(ioc
, 0);
6902 if ((ioc_raw_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_FAULT
) {
6903 printk(MYIOC_s_ERR_FMT
"IOC is in FAULT state (%04xh)!!!\n",
6904 ioc
->name
, ioc_raw_state
& MPI_DOORBELL_DATA_MASK
);
6905 panic("%s: IOC Fault (%04xh)!!!\n", ioc
->name
,
6906 ioc_raw_state
& MPI_DOORBELL_DATA_MASK
);
6908 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, 0xC0FFEE00);
6909 panic("%s: Firmware is halted due to command timeout\n",
6913 EXPORT_SYMBOL(mpt_halt_firmware
);
6916 * mpt_SoftResetHandler - Issues a less expensive reset
6917 * @ioc: Pointer to MPT_ADAPTER structure
6918 * @sleepFlag: Indicates if sleep or schedule must be called.
6921 * Returns 0 for SUCCESS or -1 if FAILED.
6923 * Message Unit Reset - instructs the IOC to reset the Reply Post and
6924 * Free FIFO's. All the Message Frames on Reply Free FIFO are discarded.
6925 * All posted buffers are freed, and event notification is turned off.
6926 * IOC doesnt reply to any outstanding request. This will transfer IOC
6930 mpt_SoftResetHandler(MPT_ADAPTER
*ioc
, int sleepFlag
)
6935 unsigned long flags
;
6937 unsigned long time_count
;
6939 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SoftResetHandler Entered!\n",
6942 ioc_state
= mpt_GetIocState(ioc
, 0) & MPI_IOC_STATE_MASK
;
6944 if (mpt_fwfault_debug
)
6945 mpt_halt_firmware(ioc
);
6947 if (ioc_state
== MPI_IOC_STATE_FAULT
||
6948 ioc_state
== MPI_IOC_STATE_RESET
) {
6949 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6950 "skipping, either in FAULT or RESET state!\n", ioc
->name
));
6954 if (ioc
->bus_type
== FC
) {
6955 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6956 "skipping, because the bus type is FC!\n", ioc
->name
));
6960 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
6961 if (ioc
->ioc_reset_in_progress
) {
6962 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6965 ioc
->ioc_reset_in_progress
= 1;
6966 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6970 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
6971 if (MptResetHandlers
[cb_idx
])
6972 mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_SETUP_RESET
);
6975 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
6976 if (ioc
->taskmgmt_in_progress
) {
6977 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6980 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6981 /* Disable reply interrupts (also blocks FreeQ) */
6982 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
6984 time_count
= jiffies
;
6986 rc
= SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
);
6988 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
6989 if (MptResetHandlers
[cb_idx
])
6990 mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_PRE_RESET
);
6996 ioc_state
= mpt_GetIocState(ioc
, 0) & MPI_IOC_STATE_MASK
;
6997 if (ioc_state
!= MPI_IOC_STATE_READY
)
7000 for (ii
= 0; ii
< 5; ii
++) {
7001 /* Get IOC facts! Allow 5 retries */
7002 rc
= GetIocFacts(ioc
, sleepFlag
,
7003 MPT_HOSTEVENT_IOC_RECOVER
);
7006 if (sleepFlag
== CAN_SLEEP
)
7014 rc
= PrimeIocFifos(ioc
);
7018 rc
= SendIocInit(ioc
, sleepFlag
);
7022 rc
= SendEventNotification(ioc
, 1, sleepFlag
);
7026 if (ioc
->hard_resets
< -1)
7030 * At this point, we know soft reset succeeded.
7034 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, MPI_HIM_DIM
);
7037 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
7038 ioc
->ioc_reset_in_progress
= 0;
7039 ioc
->taskmgmt_quiesce_io
= 0;
7040 ioc
->taskmgmt_in_progress
= 0;
7041 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
7043 if (ioc
->active
) { /* otherwise, hard reset coming */
7044 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
7045 if (MptResetHandlers
[cb_idx
])
7046 mpt_signal_reset(cb_idx
, ioc
,
7047 MPT_IOC_POST_RESET
);
7051 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
7052 "SoftResetHandler: completed (%d seconds): %s\n",
7053 ioc
->name
, jiffies_to_msecs(jiffies
- time_count
)/1000,
7054 ((rc
== 0) ? "SUCCESS" : "FAILED")));
7060 * mpt_Soft_Hard_ResetHandler - Try less expensive reset
7061 * @ioc: Pointer to MPT_ADAPTER structure
7062 * @sleepFlag: Indicates if sleep or schedule must be called.
7065 * Returns 0 for SUCCESS or -1 if FAILED.
7066 * Try for softreset first, only if it fails go for expensive
7070 mpt_Soft_Hard_ResetHandler(MPT_ADAPTER
*ioc
, int sleepFlag
) {
7073 ret
= mpt_SoftResetHandler(ioc
, sleepFlag
);
7076 ret
= mpt_HardResetHandler(ioc
, sleepFlag
);
7079 EXPORT_SYMBOL(mpt_Soft_Hard_ResetHandler
);
7081 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7085 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7087 * mpt_HardResetHandler - Generic reset handler
7088 * @ioc: Pointer to MPT_ADAPTER structure
7089 * @sleepFlag: Indicates if sleep or schedule must be called.
7091 * Issues SCSI Task Management call based on input arg values.
7092 * If TaskMgmt fails, returns associated SCSI request.
7094 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
7095 * or a non-interrupt thread. In the former, must not call schedule().
7097 * Note: A return of -1 is a FATAL error case, as it means a
7098 * FW reload/initialization failed.
7100 * Returns 0 for SUCCESS or -1 if FAILED.
7103 mpt_HardResetHandler(MPT_ADAPTER
*ioc
, int sleepFlag
)
7107 unsigned long flags
;
7108 unsigned long time_count
;
7110 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HardResetHandler Entered!\n", ioc
->name
));
7112 printk(MYIOC_s_INFO_FMT
"HardResetHandler Entered!\n", ioc
->name
);
7113 printk("MF count 0x%x !\n", ioc
->mfcnt
);
7115 if (mpt_fwfault_debug
)
7116 mpt_halt_firmware(ioc
);
7118 /* Reset the adapter. Prevent more than 1 call to
7119 * mpt_do_ioc_recovery at any instant in time.
7121 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
7122 if (ioc
->ioc_reset_in_progress
) {
7123 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
7126 ioc
->ioc_reset_in_progress
= 1;
7128 ioc
->alt_ioc
->ioc_reset_in_progress
= 1;
7129 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
7132 /* The SCSI driver needs to adjust timeouts on all current
7133 * commands prior to the diagnostic reset being issued.
7134 * Prevents timeouts occurring during a diagnostic reset...very bad.
7135 * For all other protocol drivers, this is a no-op.
7137 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
7138 if (MptResetHandlers
[cb_idx
]) {
7139 mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_SETUP_RESET
);
7141 mpt_signal_reset(cb_idx
, ioc
->alt_ioc
,
7142 MPT_IOC_SETUP_RESET
);
7146 time_count
= jiffies
;
7147 rc
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_RECOVER
, sleepFlag
);
7149 printk(KERN_WARNING MYNAM
7150 ": WARNING - (%d) Cannot recover %s\n", rc
, ioc
->name
);
7152 if (ioc
->hard_resets
< -1)
7156 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
7157 ioc
->ioc_reset_in_progress
= 0;
7158 ioc
->taskmgmt_quiesce_io
= 0;
7159 ioc
->taskmgmt_in_progress
= 0;
7161 ioc
->alt_ioc
->ioc_reset_in_progress
= 0;
7162 ioc
->alt_ioc
->taskmgmt_quiesce_io
= 0;
7163 ioc
->alt_ioc
->taskmgmt_in_progress
= 0;
7165 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
7167 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
7168 if (MptResetHandlers
[cb_idx
]) {
7169 mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_POST_RESET
);
7171 mpt_signal_reset(cb_idx
,
7172 ioc
->alt_ioc
, MPT_IOC_POST_RESET
);
7177 printk(MYIOC_s_DEBUG_FMT
7178 "HardResetHandler: completed (%d seconds): %s\n", ioc
->name
,
7179 jiffies_to_msecs(jiffies
- time_count
)/1000, ((rc
== 0) ?
7180 "SUCCESS" : "FAILED")));
7185 #ifdef CONFIG_FUSION_LOGGING
7187 mpt_display_event_info(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*pEventReply
)
7193 char *evStr
= ioc
->evStr
;
7195 event
= le32_to_cpu(pEventReply
->Event
) & 0xFF;
7196 evData0
= le32_to_cpu(pEventReply
->Data
[0]);
7199 case MPI_EVENT_NONE
:
7202 case MPI_EVENT_LOG_DATA
:
7205 case MPI_EVENT_STATE_CHANGE
:
7206 ds
= "State Change";
7208 case MPI_EVENT_UNIT_ATTENTION
:
7209 ds
= "Unit Attention";
7211 case MPI_EVENT_IOC_BUS_RESET
:
7212 ds
= "IOC Bus Reset";
7214 case MPI_EVENT_EXT_BUS_RESET
:
7215 ds
= "External Bus Reset";
7217 case MPI_EVENT_RESCAN
:
7218 ds
= "Bus Rescan Event";
7220 case MPI_EVENT_LINK_STATUS_CHANGE
:
7221 if (evData0
== MPI_EVENT_LINK_STATUS_FAILURE
)
7222 ds
= "Link Status(FAILURE) Change";
7224 ds
= "Link Status(ACTIVE) Change";
7226 case MPI_EVENT_LOOP_STATE_CHANGE
:
7227 if (evData0
== MPI_EVENT_LOOP_STATE_CHANGE_LIP
)
7228 ds
= "Loop State(LIP) Change";
7229 else if (evData0
== MPI_EVENT_LOOP_STATE_CHANGE_LPE
)
7230 ds
= "Loop State(LPE) Change";
7232 ds
= "Loop State(LPB) Change";
7234 case MPI_EVENT_LOGOUT
:
7237 case MPI_EVENT_EVENT_CHANGE
:
7243 case MPI_EVENT_INTEGRATED_RAID
:
7245 u8 ReasonCode
= (u8
)(evData0
>> 16);
7246 switch (ReasonCode
) {
7247 case MPI_EVENT_RAID_RC_VOLUME_CREATED
:
7248 ds
= "Integrated Raid: Volume Created";
7250 case MPI_EVENT_RAID_RC_VOLUME_DELETED
:
7251 ds
= "Integrated Raid: Volume Deleted";
7253 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED
:
7254 ds
= "Integrated Raid: Volume Settings Changed";
7256 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED
:
7257 ds
= "Integrated Raid: Volume Status Changed";
7259 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED
:
7260 ds
= "Integrated Raid: Volume Physdisk Changed";
7262 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED
:
7263 ds
= "Integrated Raid: Physdisk Created";
7265 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED
:
7266 ds
= "Integrated Raid: Physdisk Deleted";
7268 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED
:
7269 ds
= "Integrated Raid: Physdisk Settings Changed";
7271 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
:
7272 ds
= "Integrated Raid: Physdisk Status Changed";
7274 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
:
7275 ds
= "Integrated Raid: Domain Validation Needed";
7277 case MPI_EVENT_RAID_RC_SMART_DATA
:
7278 ds
= "Integrated Raid; Smart Data";
7280 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED
:
7281 ds
= "Integrated Raid: Replace Action Started";
7284 ds
= "Integrated Raid";
7289 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE
:
7290 ds
= "SCSI Device Status Change";
7292 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE
:
7294 u8 id
= (u8
)(evData0
);
7295 u8 channel
= (u8
)(evData0
>> 8);
7296 u8 ReasonCode
= (u8
)(evData0
>> 16);
7297 switch (ReasonCode
) {
7298 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED
:
7299 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7300 "SAS Device Status Change: Added: "
7301 "id=%d channel=%d", id
, channel
);
7303 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING
:
7304 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7305 "SAS Device Status Change: Deleted: "
7306 "id=%d channel=%d", id
, channel
);
7308 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA
:
7309 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7310 "SAS Device Status Change: SMART Data: "
7311 "id=%d channel=%d", id
, channel
);
7313 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED
:
7314 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7315 "SAS Device Status Change: No Persistancy: "
7316 "id=%d channel=%d", id
, channel
);
7318 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED
:
7319 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7320 "SAS Device Status Change: Unsupported Device "
7321 "Discovered : id=%d channel=%d", id
, channel
);
7323 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET
:
7324 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7325 "SAS Device Status Change: Internal Device "
7326 "Reset : id=%d channel=%d", id
, channel
);
7328 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL
:
7329 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7330 "SAS Device Status Change: Internal Task "
7331 "Abort : id=%d channel=%d", id
, channel
);
7333 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL
:
7334 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7335 "SAS Device Status Change: Internal Abort "
7336 "Task Set : id=%d channel=%d", id
, channel
);
7338 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL
:
7339 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7340 "SAS Device Status Change: Internal Clear "
7341 "Task Set : id=%d channel=%d", id
, channel
);
7343 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL
:
7344 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7345 "SAS Device Status Change: Internal Query "
7346 "Task : id=%d channel=%d", id
, channel
);
7349 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7350 "SAS Device Status Change: Unknown: "
7351 "id=%d channel=%d", id
, channel
);
7356 case MPI_EVENT_ON_BUS_TIMER_EXPIRED
:
7357 ds
= "Bus Timer Expired";
7359 case MPI_EVENT_QUEUE_FULL
:
7361 u16 curr_depth
= (u16
)(evData0
>> 16);
7362 u8 channel
= (u8
)(evData0
>> 8);
7363 u8 id
= (u8
)(evData0
);
7365 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7366 "Queue Full: channel=%d id=%d depth=%d",
7367 channel
, id
, curr_depth
);
7370 case MPI_EVENT_SAS_SES
:
7371 ds
= "SAS SES Event";
7373 case MPI_EVENT_PERSISTENT_TABLE_FULL
:
7374 ds
= "Persistent Table Full";
7376 case MPI_EVENT_SAS_PHY_LINK_STATUS
:
7378 u8 LinkRates
= (u8
)(evData0
>> 8);
7379 u8 PhyNumber
= (u8
)(evData0
);
7380 LinkRates
= (LinkRates
& MPI_EVENT_SAS_PLS_LR_CURRENT_MASK
) >>
7381 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT
;
7382 switch (LinkRates
) {
7383 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN
:
7384 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7385 "SAS PHY Link Status: Phy=%d:"
7386 " Rate Unknown",PhyNumber
);
7388 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED
:
7389 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7390 "SAS PHY Link Status: Phy=%d:"
7391 " Phy Disabled",PhyNumber
);
7393 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION
:
7394 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7395 "SAS PHY Link Status: Phy=%d:"
7396 " Failed Speed Nego",PhyNumber
);
7398 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE
:
7399 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7400 "SAS PHY Link Status: Phy=%d:"
7401 " Sata OOB Completed",PhyNumber
);
7403 case MPI_EVENT_SAS_PLS_LR_RATE_1_5
:
7404 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7405 "SAS PHY Link Status: Phy=%d:"
7406 " Rate 1.5 Gbps",PhyNumber
);
7408 case MPI_EVENT_SAS_PLS_LR_RATE_3_0
:
7409 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7410 "SAS PHY Link Status: Phy=%d:"
7411 " Rate 3.0 Gpbs",PhyNumber
);
7414 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7415 "SAS PHY Link Status: Phy=%d", PhyNumber
);
7420 case MPI_EVENT_SAS_DISCOVERY_ERROR
:
7421 ds
= "SAS Discovery Error";
7423 case MPI_EVENT_IR_RESYNC_UPDATE
:
7425 u8 resync_complete
= (u8
)(evData0
>> 16);
7426 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7427 "IR Resync Update: Complete = %d:",resync_complete
);
7432 u8 id
= (u8
)(evData0
);
7433 u8 channel
= (u8
)(evData0
>> 8);
7434 u8 phys_num
= (u8
)(evData0
>> 24);
7435 u8 ReasonCode
= (u8
)(evData0
>> 16);
7437 switch (ReasonCode
) {
7438 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED
:
7439 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7440 "IR2: LD State Changed: "
7441 "id=%d channel=%d phys_num=%d",
7442 id
, channel
, phys_num
);
7444 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED
:
7445 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7446 "IR2: PD State Changed "
7447 "id=%d channel=%d phys_num=%d",
7448 id
, channel
, phys_num
);
7450 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL
:
7451 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7452 "IR2: Bad Block Table Full: "
7453 "id=%d channel=%d phys_num=%d",
7454 id
, channel
, phys_num
);
7456 case MPI_EVENT_IR2_RC_PD_INSERTED
:
7457 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7458 "IR2: PD Inserted: "
7459 "id=%d channel=%d phys_num=%d",
7460 id
, channel
, phys_num
);
7462 case MPI_EVENT_IR2_RC_PD_REMOVED
:
7463 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7465 "id=%d channel=%d phys_num=%d",
7466 id
, channel
, phys_num
);
7468 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED
:
7469 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7470 "IR2: Foreign CFG Detected: "
7471 "id=%d channel=%d phys_num=%d",
7472 id
, channel
, phys_num
);
7474 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR
:
7475 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7476 "IR2: Rebuild Medium Error: "
7477 "id=%d channel=%d phys_num=%d",
7478 id
, channel
, phys_num
);
7480 case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED
:
7481 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7482 "IR2: Dual Port Added: "
7483 "id=%d channel=%d phys_num=%d",
7484 id
, channel
, phys_num
);
7486 case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED
:
7487 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7488 "IR2: Dual Port Removed: "
7489 "id=%d channel=%d phys_num=%d",
7490 id
, channel
, phys_num
);
7498 case MPI_EVENT_SAS_DISCOVERY
:
7501 ds
= "SAS Discovery: Start";
7503 ds
= "SAS Discovery: Stop";
7506 case MPI_EVENT_LOG_ENTRY_ADDED
:
7507 ds
= "SAS Log Entry Added";
7510 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE
:
7512 u8 phy_num
= (u8
)(evData0
);
7513 u8 port_num
= (u8
)(evData0
>> 8);
7514 u8 port_width
= (u8
)(evData0
>> 16);
7515 u8 primative
= (u8
)(evData0
>> 24);
7516 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7517 "SAS Broadcase Primative: phy=%d port=%d "
7518 "width=%d primative=0x%02x",
7519 phy_num
, port_num
, port_width
, primative
);
7523 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE
:
7525 u8 reason
= (u8
)(evData0
);
7528 case MPI_EVENT_SAS_INIT_RC_ADDED
:
7529 ds
= "SAS Initiator Status Change: Added";
7531 case MPI_EVENT_SAS_INIT_RC_REMOVED
:
7532 ds
= "SAS Initiator Status Change: Deleted";
7535 ds
= "SAS Initiator Status Change";
7541 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW
:
7543 u8 max_init
= (u8
)(evData0
);
7544 u8 current_init
= (u8
)(evData0
>> 8);
7546 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7547 "SAS Initiator Device Table Overflow: max initiators=%02d "
7548 "current initators=%02d",
7549 max_init
, current_init
);
7552 case MPI_EVENT_SAS_SMP_ERROR
:
7554 u8 status
= (u8
)(evData0
);
7555 u8 port_num
= (u8
)(evData0
>> 8);
7556 u8 result
= (u8
)(evData0
>> 16);
7558 if (status
== MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID
)
7559 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7560 "SAS SMP Error: port=%d result=0x%02x",
7562 else if (status
== MPI_EVENT_SAS_SMP_CRC_ERROR
)
7563 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7564 "SAS SMP Error: port=%d : CRC Error",
7566 else if (status
== MPI_EVENT_SAS_SMP_TIMEOUT
)
7567 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7568 "SAS SMP Error: port=%d : Timeout",
7570 else if (status
== MPI_EVENT_SAS_SMP_NO_DESTINATION
)
7571 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7572 "SAS SMP Error: port=%d : No Destination",
7574 else if (status
== MPI_EVENT_SAS_SMP_BAD_DESTINATION
)
7575 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7576 "SAS SMP Error: port=%d : Bad Destination",
7579 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7580 "SAS SMP Error: port=%d : status=0x%02x",
7585 case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE
:
7587 u8 reason
= (u8
)(evData0
);
7590 case MPI_EVENT_SAS_EXP_RC_ADDED
:
7591 ds
= "Expander Status Change: Added";
7593 case MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING
:
7594 ds
= "Expander Status Change: Deleted";
7597 ds
= "Expander Status Change";
7604 * MPT base "custom" events may be added here...
7611 strncpy(evStr
, ds
, EVENT_DESCR_STR_SZ
);
7614 devtprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
7615 "MPT event:(%02Xh) : %s\n",
7616 ioc
->name
, event
, evStr
));
7618 devtverboseprintk(ioc
, printk(KERN_DEBUG MYNAM
7619 ": Event data:\n"));
7620 for (ii
= 0; ii
< le16_to_cpu(pEventReply
->EventDataLength
); ii
++)
7621 devtverboseprintk(ioc
, printk(" %08x",
7622 le32_to_cpu(pEventReply
->Data
[ii
])));
7623 devtverboseprintk(ioc
, printk(KERN_DEBUG
"\n"));
7626 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7628 * ProcessEventNotification - Route EventNotificationReply to all event handlers
7629 * @ioc: Pointer to MPT_ADAPTER structure
7630 * @pEventReply: Pointer to EventNotification reply frame
7631 * @evHandlers: Pointer to integer, number of event handlers
7633 * Routes a received EventNotificationReply to all currently registered
7635 * Returns sum of event handlers return values.
7638 ProcessEventNotification(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*pEventReply
, int *evHandlers
)
7649 * Do platform normalization of values
7651 event
= le32_to_cpu(pEventReply
->Event
) & 0xFF;
7652 evDataLen
= le16_to_cpu(pEventReply
->EventDataLength
);
7654 evData0
= le32_to_cpu(pEventReply
->Data
[0]);
7657 #ifdef CONFIG_FUSION_LOGGING
7659 mpt_display_event_info(ioc
, pEventReply
);
7663 * Do general / base driver event processing
7666 case MPI_EVENT_EVENT_CHANGE
: /* 0A */
7668 u8 evState
= evData0
& 0xFF;
7670 /* CHECKME! What if evState unexpectedly says OFF (0)? */
7672 /* Update EventState field in cached IocFacts */
7673 if (ioc
->facts
.Function
) {
7674 ioc
->facts
.EventState
= evState
;
7678 case MPI_EVENT_INTEGRATED_RAID
:
7679 mptbase_raid_process_event_data(ioc
,
7680 (MpiEventDataRaid_t
*)pEventReply
->Data
);
7687 * Should this event be logged? Events are written sequentially.
7688 * When buffer is full, start again at the top.
7690 if (ioc
->events
&& (ioc
->eventTypes
& ( 1 << event
))) {
7693 idx
= ioc
->eventContext
% MPTCTL_EVENT_LOG_SIZE
;
7695 ioc
->events
[idx
].event
= event
;
7696 ioc
->events
[idx
].eventContext
= ioc
->eventContext
;
7698 for (ii
= 0; ii
< 2; ii
++) {
7700 ioc
->events
[idx
].data
[ii
] = le32_to_cpu(pEventReply
->Data
[ii
]);
7702 ioc
->events
[idx
].data
[ii
] = 0;
7705 ioc
->eventContext
++;
7710 * Call each currently registered protocol event handler.
7712 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
7713 if (MptEvHandlers
[cb_idx
]) {
7714 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
7715 "Routing Event to event handler #%d\n",
7716 ioc
->name
, cb_idx
));
7717 r
+= (*(MptEvHandlers
[cb_idx
]))(ioc
, pEventReply
);
7721 /* FIXME? Examine results here? */
7724 * If needed, send (a single) EventAck.
7726 if (pEventReply
->AckRequired
== MPI_EVENT_NOTIFICATION_ACK_REQUIRED
) {
7727 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
7728 "EventAck required\n",ioc
->name
));
7729 if ((ii
= SendEventAck(ioc
, pEventReply
)) != 0) {
7730 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SendEventAck returned %d\n",
7735 *evHandlers
= handlers
;
7739 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7741 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
7742 * @ioc: Pointer to MPT_ADAPTER structure
7743 * @log_info: U32 LogInfo reply word from the IOC
7745 * Refer to lsi/mpi_log_fc.h.
7748 mpt_fc_log_info(MPT_ADAPTER
*ioc
, u32 log_info
)
7750 char *desc
= "unknown";
7752 switch (log_info
& 0xFF000000) {
7753 case MPI_IOCLOGINFO_FC_INIT_BASE
:
7754 desc
= "FCP Initiator";
7756 case MPI_IOCLOGINFO_FC_TARGET_BASE
:
7757 desc
= "FCP Target";
7759 case MPI_IOCLOGINFO_FC_LAN_BASE
:
7762 case MPI_IOCLOGINFO_FC_MSG_BASE
:
7763 desc
= "MPI Message Layer";
7765 case MPI_IOCLOGINFO_FC_LINK_BASE
:
7768 case MPI_IOCLOGINFO_FC_CTX_BASE
:
7769 desc
= "Context Manager";
7771 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET
:
7772 desc
= "Invalid Field Offset";
7774 case MPI_IOCLOGINFO_FC_STATE_CHANGE
:
7775 desc
= "State Change Info";
7779 printk(MYIOC_s_INFO_FMT
"LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
7780 ioc
->name
, log_info
, desc
, (log_info
& 0xFFFFFF));
7783 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7785 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
7786 * @ioc: Pointer to MPT_ADAPTER structure
7787 * @log_info: U32 LogInfo word from the IOC
7789 * Refer to lsi/sp_log.h.
7792 mpt_spi_log_info(MPT_ADAPTER
*ioc
, u32 log_info
)
7794 u32 info
= log_info
& 0x00FF0000;
7795 char *desc
= "unknown";
7799 desc
= "bug! MID not found";
7803 desc
= "Parity Error";
7807 desc
= "ASYNC Outbound Overrun";
7811 desc
= "SYNC Offset Error";
7819 desc
= "Msg In Overflow";
7827 desc
= "Outbound DMA Overrun";
7831 desc
= "Task Management";
7835 desc
= "Device Problem";
7839 desc
= "Invalid Phase Change";
7843 desc
= "Untagged Table Size";
7848 printk(MYIOC_s_INFO_FMT
"LogInfo(0x%08x): F/W: %s\n", ioc
->name
, log_info
, desc
);
7851 /* strings for sas loginfo */
7852 static char *originator_str
[] = {
7857 static char *iop_code_str
[] = {
7859 "Invalid SAS Address", /* 01h */
7861 "Invalid Page", /* 03h */
7862 "Diag Message Error", /* 04h */
7863 "Task Terminated", /* 05h */
7864 "Enclosure Management", /* 06h */
7865 "Target Mode" /* 07h */
7867 static char *pl_code_str
[] = {
7869 "Open Failure", /* 01h */
7870 "Invalid Scatter Gather List", /* 02h */
7871 "Wrong Relative Offset or Frame Length", /* 03h */
7872 "Frame Transfer Error", /* 04h */
7873 "Transmit Frame Connected Low", /* 05h */
7874 "SATA Non-NCQ RW Error Bit Set", /* 06h */
7875 "SATA Read Log Receive Data Error", /* 07h */
7876 "SATA NCQ Fail All Commands After Error", /* 08h */
7877 "SATA Error in Receive Set Device Bit FIS", /* 09h */
7878 "Receive Frame Invalid Message", /* 0Ah */
7879 "Receive Context Message Valid Error", /* 0Bh */
7880 "Receive Frame Current Frame Error", /* 0Ch */
7881 "SATA Link Down", /* 0Dh */
7882 "Discovery SATA Init W IOS", /* 0Eh */
7883 "Config Invalid Page", /* 0Fh */
7884 "Discovery SATA Init Timeout", /* 10h */
7887 "IO Not Yet Executed", /* 13h */
7888 "IO Executed", /* 14h */
7889 "Persistent Reservation Out Not Affiliation "
7891 "Open Transmit DMA Abort", /* 16h */
7892 "IO Device Missing Delay Retry", /* 17h */
7893 "IO Cancelled Due to Recieve Error", /* 18h */
7901 "Enclosure Management" /* 20h */
7903 static char *ir_code_str
[] = {
7904 "Raid Action Error", /* 00h */
7914 static char *raid_sub_code_str
[] = {
7916 "Volume Creation Failed: Data Passed too "
7918 "Volume Creation Failed: Duplicate Volumes "
7919 "Attempted", /* 02h */
7920 "Volume Creation Failed: Max Number "
7921 "Supported Volumes Exceeded", /* 03h */
7922 "Volume Creation Failed: DMA Error", /* 04h */
7923 "Volume Creation Failed: Invalid Volume Type", /* 05h */
7924 "Volume Creation Failed: Error Reading "
7925 "MFG Page 4", /* 06h */
7926 "Volume Creation Failed: Creating Internal "
7927 "Structures", /* 07h */
7936 "Activation failed: Already Active Volume", /* 10h */
7937 "Activation failed: Unsupported Volume Type", /* 11h */
7938 "Activation failed: Too Many Active Volumes", /* 12h */
7939 "Activation failed: Volume ID in Use", /* 13h */
7940 "Activation failed: Reported Failure", /* 14h */
7941 "Activation failed: Importing a Volume", /* 15h */
7952 "Phys Disk failed: Too Many Phys Disks", /* 20h */
7953 "Phys Disk failed: Data Passed too Large", /* 21h */
7954 "Phys Disk failed: DMA Error", /* 22h */
7955 "Phys Disk failed: Invalid <channel:id>", /* 23h */
7956 "Phys Disk failed: Creating Phys Disk Config "
7969 "Compatibility Error: IR Disabled", /* 30h */
7970 "Compatibility Error: Inquiry Comand Failed", /* 31h */
7971 "Compatibility Error: Device not Direct Access "
7972 "Device ", /* 32h */
7973 "Compatibility Error: Removable Device Found", /* 33h */
7974 "Compatibility Error: Device SCSI Version not "
7975 "2 or Higher", /* 34h */
7976 "Compatibility Error: SATA Device, 48 BIT LBA "
7977 "not Supported", /* 35h */
7978 "Compatibility Error: Device doesn't have "
7979 "512 Byte Block Sizes", /* 36h */
7980 "Compatibility Error: Volume Type Check Failed", /* 37h */
7981 "Compatibility Error: Volume Type is "
7982 "Unsupported by FW", /* 38h */
7983 "Compatibility Error: Disk Drive too Small for "
7984 "use in Volume", /* 39h */
7985 "Compatibility Error: Phys Disk for Create "
7986 "Volume not Found", /* 3Ah */
7987 "Compatibility Error: Too Many or too Few "
7988 "Disks for Volume Type", /* 3Bh */
7989 "Compatibility Error: Disk stripe Sizes "
7990 "Must be 64KB", /* 3Ch */
7991 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
7994 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7996 * mpt_sas_log_info - Log information returned from SAS IOC.
7997 * @ioc: Pointer to MPT_ADAPTER structure
7998 * @log_info: U32 LogInfo reply word from the IOC
8000 * Refer to lsi/mpi_log_sas.h.
8003 mpt_sas_log_info(MPT_ADAPTER
*ioc
, u32 log_info
)
8005 union loginfo_type
{
8014 union loginfo_type sas_loginfo
;
8015 char *originator_desc
= NULL
;
8016 char *code_desc
= NULL
;
8017 char *sub_code_desc
= NULL
;
8019 sas_loginfo
.loginfo
= log_info
;
8020 if ((sas_loginfo
.dw
.bus_type
!= 3 /*SAS*/) &&
8021 (sas_loginfo
.dw
.originator
< ARRAY_SIZE(originator_str
)))
8024 originator_desc
= originator_str
[sas_loginfo
.dw
.originator
];
8026 switch (sas_loginfo
.dw
.originator
) {
8029 if (sas_loginfo
.dw
.code
<
8030 ARRAY_SIZE(iop_code_str
))
8031 code_desc
= iop_code_str
[sas_loginfo
.dw
.code
];
8034 if (sas_loginfo
.dw
.code
<
8035 ARRAY_SIZE(pl_code_str
))
8036 code_desc
= pl_code_str
[sas_loginfo
.dw
.code
];
8039 if (sas_loginfo
.dw
.code
>=
8040 ARRAY_SIZE(ir_code_str
))
8042 code_desc
= ir_code_str
[sas_loginfo
.dw
.code
];
8043 if (sas_loginfo
.dw
.subcode
>=
8044 ARRAY_SIZE(raid_sub_code_str
))
8046 if (sas_loginfo
.dw
.code
== 0)
8048 raid_sub_code_str
[sas_loginfo
.dw
.subcode
];
8054 if (sub_code_desc
!= NULL
)
8055 printk(MYIOC_s_INFO_FMT
8056 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
8058 ioc
->name
, log_info
, originator_desc
, code_desc
,
8060 else if (code_desc
!= NULL
)
8061 printk(MYIOC_s_INFO_FMT
8062 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
8063 " SubCode(0x%04x)\n",
8064 ioc
->name
, log_info
, originator_desc
, code_desc
,
8065 sas_loginfo
.dw
.subcode
);
8067 printk(MYIOC_s_INFO_FMT
8068 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
8069 " SubCode(0x%04x)\n",
8070 ioc
->name
, log_info
, originator_desc
,
8071 sas_loginfo
.dw
.code
, sas_loginfo
.dw
.subcode
);
8074 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8076 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
8077 * @ioc: Pointer to MPT_ADAPTER structure
8078 * @ioc_status: U32 IOCStatus word from IOC
8079 * @mf: Pointer to MPT request frame
8081 * Refer to lsi/mpi.h.
8084 mpt_iocstatus_info_config(MPT_ADAPTER
*ioc
, u32 ioc_status
, MPT_FRAME_HDR
*mf
)
8086 Config_t
*pReq
= (Config_t
*)mf
;
8087 char extend_desc
[EVENT_DESCR_STR_SZ
];
8092 if (pReq
->Header
.PageType
== MPI_CONFIG_PAGETYPE_EXTENDED
)
8093 page_type
= pReq
->ExtPageType
;
8095 page_type
= pReq
->Header
.PageType
;
8098 * ignore invalid page messages for GET_NEXT_HANDLE
8100 form
= le32_to_cpu(pReq
->PageAddress
);
8101 if (ioc_status
== MPI_IOCSTATUS_CONFIG_INVALID_PAGE
) {
8102 if (page_type
== MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE
||
8103 page_type
== MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER
||
8104 page_type
== MPI_CONFIG_EXTPAGETYPE_ENCLOSURE
) {
8105 if ((form
>> MPI_SAS_DEVICE_PGAD_FORM_SHIFT
) ==
8106 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE
)
8109 if (page_type
== MPI_CONFIG_PAGETYPE_FC_DEVICE
)
8110 if ((form
& MPI_FC_DEVICE_PGAD_FORM_MASK
) ==
8111 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID
)
8115 snprintf(extend_desc
, EVENT_DESCR_STR_SZ
,
8116 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
8117 page_type
, pReq
->Header
.PageNumber
, pReq
->Action
, form
);
8119 switch (ioc_status
) {
8121 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION
: /* 0x0020 */
8122 desc
= "Config Page Invalid Action";
8125 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE
: /* 0x0021 */
8126 desc
= "Config Page Invalid Type";
8129 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE
: /* 0x0022 */
8130 desc
= "Config Page Invalid Page";
8133 case MPI_IOCSTATUS_CONFIG_INVALID_DATA
: /* 0x0023 */
8134 desc
= "Config Page Invalid Data";
8137 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS
: /* 0x0024 */
8138 desc
= "Config Page No Defaults";
8141 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT
: /* 0x0025 */
8142 desc
= "Config Page Can't Commit";
8149 dreplyprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"IOCStatus(0x%04X): %s: %s\n",
8150 ioc
->name
, ioc_status
, desc
, extend_desc
));
8154 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
8155 * @ioc: Pointer to MPT_ADAPTER structure
8156 * @ioc_status: U32 IOCStatus word from IOC
8157 * @mf: Pointer to MPT request frame
8159 * Refer to lsi/mpi.h.
8162 mpt_iocstatus_info(MPT_ADAPTER
*ioc
, u32 ioc_status
, MPT_FRAME_HDR
*mf
)
8164 u32 status
= ioc_status
& MPI_IOCSTATUS_MASK
;
8169 /****************************************************************************/
8170 /* Common IOCStatus values for all replies */
8171 /****************************************************************************/
8173 case MPI_IOCSTATUS_INVALID_FUNCTION
: /* 0x0001 */
8174 desc
= "Invalid Function";
8177 case MPI_IOCSTATUS_BUSY
: /* 0x0002 */
8181 case MPI_IOCSTATUS_INVALID_SGL
: /* 0x0003 */
8182 desc
= "Invalid SGL";
8185 case MPI_IOCSTATUS_INTERNAL_ERROR
: /* 0x0004 */
8186 desc
= "Internal Error";
8189 case MPI_IOCSTATUS_RESERVED
: /* 0x0005 */
8193 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES
: /* 0x0006 */
8194 desc
= "Insufficient Resources";
8197 case MPI_IOCSTATUS_INVALID_FIELD
: /* 0x0007 */
8198 desc
= "Invalid Field";
8201 case MPI_IOCSTATUS_INVALID_STATE
: /* 0x0008 */
8202 desc
= "Invalid State";
8205 /****************************************************************************/
8206 /* Config IOCStatus values */
8207 /****************************************************************************/
8209 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION
: /* 0x0020 */
8210 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE
: /* 0x0021 */
8211 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE
: /* 0x0022 */
8212 case MPI_IOCSTATUS_CONFIG_INVALID_DATA
: /* 0x0023 */
8213 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS
: /* 0x0024 */
8214 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT
: /* 0x0025 */
8215 mpt_iocstatus_info_config(ioc
, status
, mf
);
8218 /****************************************************************************/
8219 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
8221 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
8223 /****************************************************************************/
8225 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR
: /* 0x0040 */
8226 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN
: /* 0x0045 */
8227 case MPI_IOCSTATUS_SCSI_INVALID_BUS
: /* 0x0041 */
8228 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID
: /* 0x0042 */
8229 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE
: /* 0x0043 */
8230 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN
: /* 0x0044 */
8231 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR
: /* 0x0046 */
8232 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR
: /* 0x0047 */
8233 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED
: /* 0x0048 */
8234 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH
: /* 0x0049 */
8235 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED
: /* 0x004A */
8236 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED
: /* 0x004B */
8237 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED
: /* 0x004C */
8240 /****************************************************************************/
8241 /* SCSI Target values */
8242 /****************************************************************************/
8244 case MPI_IOCSTATUS_TARGET_PRIORITY_IO
: /* 0x0060 */
8245 desc
= "Target: Priority IO";
8248 case MPI_IOCSTATUS_TARGET_INVALID_PORT
: /* 0x0061 */
8249 desc
= "Target: Invalid Port";
8252 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX
: /* 0x0062 */
8253 desc
= "Target Invalid IO Index:";
8256 case MPI_IOCSTATUS_TARGET_ABORTED
: /* 0x0063 */
8257 desc
= "Target: Aborted";
8260 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE
: /* 0x0064 */
8261 desc
= "Target: No Conn Retryable";
8264 case MPI_IOCSTATUS_TARGET_NO_CONNECTION
: /* 0x0065 */
8265 desc
= "Target: No Connection";
8268 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH
: /* 0x006A */
8269 desc
= "Target: Transfer Count Mismatch";
8272 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT
: /* 0x006B */
8273 desc
= "Target: STS Data not Sent";
8276 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR
: /* 0x006D */
8277 desc
= "Target: Data Offset Error";
8280 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA
: /* 0x006E */
8281 desc
= "Target: Too Much Write Data";
8284 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT
: /* 0x006F */
8285 desc
= "Target: IU Too Short";
8288 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT
: /* 0x0070 */
8289 desc
= "Target: ACK NAK Timeout";
8292 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED
: /* 0x0071 */
8293 desc
= "Target: Nak Received";
8296 /****************************************************************************/
8297 /* Fibre Channel Direct Access values */
8298 /****************************************************************************/
8300 case MPI_IOCSTATUS_FC_ABORTED
: /* 0x0066 */
8301 desc
= "FC: Aborted";
8304 case MPI_IOCSTATUS_FC_RX_ID_INVALID
: /* 0x0067 */
8305 desc
= "FC: RX ID Invalid";
8308 case MPI_IOCSTATUS_FC_DID_INVALID
: /* 0x0068 */
8309 desc
= "FC: DID Invalid";
8312 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT
: /* 0x0069 */
8313 desc
= "FC: Node Logged Out";
8316 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED
: /* 0x006C */
8317 desc
= "FC: Exchange Canceled";
8320 /****************************************************************************/
8322 /****************************************************************************/
8324 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND
: /* 0x0080 */
8325 desc
= "LAN: Device not Found";
8328 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE
: /* 0x0081 */
8329 desc
= "LAN: Device Failure";
8332 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR
: /* 0x0082 */
8333 desc
= "LAN: Transmit Error";
8336 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED
: /* 0x0083 */
8337 desc
= "LAN: Transmit Aborted";
8340 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR
: /* 0x0084 */
8341 desc
= "LAN: Receive Error";
8344 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED
: /* 0x0085 */
8345 desc
= "LAN: Receive Aborted";
8348 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET
: /* 0x0086 */
8349 desc
= "LAN: Partial Packet";
8352 case MPI_IOCSTATUS_LAN_CANCELED
: /* 0x0087 */
8353 desc
= "LAN: Canceled";
8356 /****************************************************************************/
8357 /* Serial Attached SCSI values */
8358 /****************************************************************************/
8360 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED
: /* 0x0090 */
8361 desc
= "SAS: SMP Request Failed";
8364 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN
: /* 0x0090 */
8365 desc
= "SAS: SMP Data Overrun";
8376 dreplyprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"IOCStatus(0x%04X): %s\n",
8377 ioc
->name
, status
, desc
));
8380 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8381 EXPORT_SYMBOL(mpt_attach
);
8382 EXPORT_SYMBOL(mpt_detach
);
8384 EXPORT_SYMBOL(mpt_resume
);
8385 EXPORT_SYMBOL(mpt_suspend
);
8387 EXPORT_SYMBOL(ioc_list
);
8388 EXPORT_SYMBOL(mpt_register
);
8389 EXPORT_SYMBOL(mpt_deregister
);
8390 EXPORT_SYMBOL(mpt_event_register
);
8391 EXPORT_SYMBOL(mpt_event_deregister
);
8392 EXPORT_SYMBOL(mpt_reset_register
);
8393 EXPORT_SYMBOL(mpt_reset_deregister
);
8394 EXPORT_SYMBOL(mpt_device_driver_register
);
8395 EXPORT_SYMBOL(mpt_device_driver_deregister
);
8396 EXPORT_SYMBOL(mpt_get_msg_frame
);
8397 EXPORT_SYMBOL(mpt_put_msg_frame
);
8398 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri
);
8399 EXPORT_SYMBOL(mpt_free_msg_frame
);
8400 EXPORT_SYMBOL(mpt_send_handshake_request
);
8401 EXPORT_SYMBOL(mpt_verify_adapter
);
8402 EXPORT_SYMBOL(mpt_GetIocState
);
8403 EXPORT_SYMBOL(mpt_print_ioc_summary
);
8404 EXPORT_SYMBOL(mpt_HardResetHandler
);
8405 EXPORT_SYMBOL(mpt_config
);
8406 EXPORT_SYMBOL(mpt_findImVolumes
);
8407 EXPORT_SYMBOL(mpt_alloc_fw_memory
);
8408 EXPORT_SYMBOL(mpt_free_fw_memory
);
8409 EXPORT_SYMBOL(mptbase_sas_persist_operation
);
8410 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0
);
8412 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8414 * fusion_init - Fusion MPT base driver initialization routine.
8416 * Returns 0 for success, non-zero for failure.
8423 show_mptmod_ver(my_NAME
, my_VERSION
);
8424 printk(KERN_INFO COPYRIGHT
"\n");
8426 for (cb_idx
= 0; cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
; cb_idx
++) {
8427 MptCallbacks
[cb_idx
] = NULL
;
8428 MptDriverClass
[cb_idx
] = MPTUNKNOWN_DRIVER
;
8429 MptEvHandlers
[cb_idx
] = NULL
;
8430 MptResetHandlers
[cb_idx
] = NULL
;
8433 /* Register ourselves (mptbase) in order to facilitate
8434 * EventNotification handling.
8436 mpt_base_index
= mpt_register(mptbase_reply
, MPTBASE_DRIVER
);
8438 /* Register for hard reset handling callbacks.
8440 mpt_reset_register(mpt_base_index
, mpt_ioc_reset
);
8442 #ifdef CONFIG_PROC_FS
8443 (void) procmpt_create();
8448 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8450 * fusion_exit - Perform driver unload cleanup.
8452 * This routine frees all resources associated with each MPT adapter
8453 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
8459 mpt_reset_deregister(mpt_base_index
);
8461 #ifdef CONFIG_PROC_FS
8466 module_init(fusion_init
);
8467 module_exit(fusion_exit
);