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)");
118 static char MptCallbacksName
[MPT_MAX_PROTOCOL_DRIVERS
][50];
121 static int mfcounter
= 0;
122 #define PRINT_MF_COUNT 20000
125 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
130 #define WHOINIT_UNKNOWN 0xAA
132 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
136 /* Adapter link list */
138 /* Callback lookup table */
139 static MPT_CALLBACK MptCallbacks
[MPT_MAX_PROTOCOL_DRIVERS
];
140 /* Protocol driver class lookup table */
141 static int MptDriverClass
[MPT_MAX_PROTOCOL_DRIVERS
];
142 /* Event handler lookup table */
143 static MPT_EVHANDLER MptEvHandlers
[MPT_MAX_PROTOCOL_DRIVERS
];
144 /* Reset handler lookup table */
145 static MPT_RESETHANDLER MptResetHandlers
[MPT_MAX_PROTOCOL_DRIVERS
];
146 static struct mpt_pci_driver
*MptDeviceDriverHandlers
[MPT_MAX_PROTOCOL_DRIVERS
];
148 #ifdef CONFIG_PROC_FS
149 static struct proc_dir_entry
*mpt_proc_root_dir
;
153 * Driver Callback Index's
155 static u8 mpt_base_index
= MPT_MAX_PROTOCOL_DRIVERS
;
156 static u8 last_drv_idx
;
158 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
162 static irqreturn_t
mpt_interrupt(int irq
, void *bus_id
);
163 static int mptbase_reply(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*req
,
164 MPT_FRAME_HDR
*reply
);
165 static int mpt_handshake_req_reply_wait(MPT_ADAPTER
*ioc
, int reqBytes
,
166 u32
*req
, int replyBytes
, u16
*u16reply
, int maxwait
,
168 static int mpt_do_ioc_recovery(MPT_ADAPTER
*ioc
, u32 reason
, int sleepFlag
);
169 static void mpt_detect_bound_ports(MPT_ADAPTER
*ioc
, struct pci_dev
*pdev
);
170 static void mpt_adapter_disable(MPT_ADAPTER
*ioc
);
171 static void mpt_adapter_dispose(MPT_ADAPTER
*ioc
);
173 static void MptDisplayIocCapabilities(MPT_ADAPTER
*ioc
);
174 static int MakeIocReady(MPT_ADAPTER
*ioc
, int force
, int sleepFlag
);
175 static int GetIocFacts(MPT_ADAPTER
*ioc
, int sleepFlag
, int reason
);
176 static int GetPortFacts(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
);
177 static int SendIocInit(MPT_ADAPTER
*ioc
, int sleepFlag
);
178 static int SendPortEnable(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
);
179 static int mpt_do_upload(MPT_ADAPTER
*ioc
, int sleepFlag
);
180 static int mpt_downloadboot(MPT_ADAPTER
*ioc
, MpiFwHeader_t
*pFwHeader
, int sleepFlag
);
181 static int mpt_diag_reset(MPT_ADAPTER
*ioc
, int ignore
, int sleepFlag
);
182 static int KickStart(MPT_ADAPTER
*ioc
, int ignore
, int sleepFlag
);
183 static int SendIocReset(MPT_ADAPTER
*ioc
, u8 reset_type
, int sleepFlag
);
184 static int PrimeIocFifos(MPT_ADAPTER
*ioc
);
185 static int WaitForDoorbellAck(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
);
186 static int WaitForDoorbellInt(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
);
187 static int WaitForDoorbellReply(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
);
188 static int GetLanConfigPages(MPT_ADAPTER
*ioc
);
189 static int GetIoUnitPage2(MPT_ADAPTER
*ioc
);
190 int mptbase_sas_persist_operation(MPT_ADAPTER
*ioc
, u8 persist_opcode
);
191 static int mpt_GetScsiPortSettings(MPT_ADAPTER
*ioc
, int portnum
);
192 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER
*ioc
, int portnum
);
193 static void mpt_read_ioc_pg_1(MPT_ADAPTER
*ioc
);
194 static void mpt_read_ioc_pg_4(MPT_ADAPTER
*ioc
);
195 static void mpt_get_manufacturing_pg_0(MPT_ADAPTER
*ioc
);
196 static int SendEventNotification(MPT_ADAPTER
*ioc
, u8 EvSwitch
,
198 static int SendEventAck(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*evnp
);
199 static int mpt_host_page_access_control(MPT_ADAPTER
*ioc
, u8 access_control_value
, int sleepFlag
);
200 static int mpt_host_page_alloc(MPT_ADAPTER
*ioc
, pIOCInit_t ioc_init
);
202 #ifdef CONFIG_PROC_FS
203 static int procmpt_summary_read(char *buf
, char **start
, off_t offset
,
204 int request
, int *eof
, void *data
);
205 static int procmpt_version_read(char *buf
, char **start
, off_t offset
,
206 int request
, int *eof
, void *data
);
207 static int procmpt_iocinfo_read(char *buf
, char **start
, off_t offset
,
208 int request
, int *eof
, void *data
);
210 static void mpt_get_fw_exp_ver(char *buf
, MPT_ADAPTER
*ioc
);
212 static int ProcessEventNotification(MPT_ADAPTER
*ioc
,
213 EventNotificationReply_t
*evReply
, int *evHandlers
);
214 static void mpt_iocstatus_info(MPT_ADAPTER
*ioc
, u32 ioc_status
, MPT_FRAME_HDR
*mf
);
215 static void mpt_fc_log_info(MPT_ADAPTER
*ioc
, u32 log_info
);
216 static void mpt_spi_log_info(MPT_ADAPTER
*ioc
, u32 log_info
);
217 static void mpt_sas_log_info(MPT_ADAPTER
*ioc
, u32 log_info
, u8 cb_idx
);
218 static int mpt_read_ioc_pg_3(MPT_ADAPTER
*ioc
);
219 static void mpt_inactive_raid_list_free(MPT_ADAPTER
*ioc
);
221 /* module entry point */
222 static int __init
fusion_init (void);
223 static void __exit
fusion_exit (void);
225 #define CHIPREG_READ32(addr) readl_relaxed(addr)
226 #define CHIPREG_READ32_dmasync(addr) readl(addr)
227 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
228 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
229 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
232 pci_disable_io_access(struct pci_dev
*pdev
)
236 pci_read_config_word(pdev
, PCI_COMMAND
, &command_reg
);
238 pci_write_config_word(pdev
, PCI_COMMAND
, command_reg
);
242 pci_enable_io_access(struct pci_dev
*pdev
)
246 pci_read_config_word(pdev
, PCI_COMMAND
, &command_reg
);
248 pci_write_config_word(pdev
, PCI_COMMAND
, command_reg
);
251 static int mpt_set_debug_level(const char *val
, struct kernel_param
*kp
)
253 int ret
= param_set_int(val
, kp
);
259 list_for_each_entry(ioc
, &ioc_list
, list
)
260 ioc
->debug_level
= mpt_debug_level
;
265 * mpt_get_cb_idx - obtain cb_idx for registered driver
266 * @dclass: class driver enum
268 * Returns cb_idx, or zero means it wasn't found
271 mpt_get_cb_idx(MPT_DRIVER_CLASS dclass
)
275 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--)
276 if (MptDriverClass
[cb_idx
] == dclass
)
282 * mpt_is_discovery_complete - determine if discovery has completed
283 * @ioc: per adatper instance
285 * Returns 1 when discovery completed, else zero.
288 mpt_is_discovery_complete(MPT_ADAPTER
*ioc
)
290 ConfigExtendedPageHeader_t hdr
;
292 SasIOUnitPage0_t
*buffer
;
293 dma_addr_t dma_handle
;
296 memset(&hdr
, 0, sizeof(ConfigExtendedPageHeader_t
));
297 memset(&cfg
, 0, sizeof(CONFIGPARMS
));
298 hdr
.PageVersion
= MPI_SASIOUNITPAGE0_PAGEVERSION
;
299 hdr
.PageType
= MPI_CONFIG_PAGETYPE_EXTENDED
;
300 hdr
.ExtPageType
= MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT
;
301 cfg
.cfghdr
.ehdr
= &hdr
;
302 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
304 if ((mpt_config(ioc
, &cfg
)))
306 if (!hdr
.ExtPageLength
)
309 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.ExtPageLength
* 4,
314 cfg
.physAddr
= dma_handle
;
315 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
317 if ((mpt_config(ioc
, &cfg
)))
318 goto out_free_consistent
;
320 if (!(buffer
->PhyData
[0].PortFlags
&
321 MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS
))
325 pci_free_consistent(ioc
->pcidev
, hdr
.ExtPageLength
* 4,
332 * mpt_fault_reset_work - work performed on workq after ioc fault
333 * @work: input argument, used to derive ioc
337 mpt_fault_reset_work(struct work_struct
*work
)
340 container_of(work
, MPT_ADAPTER
, fault_reset_work
.work
);
345 if (ioc
->ioc_reset_in_progress
|| !ioc
->active
)
348 ioc_raw_state
= mpt_GetIocState(ioc
, 0);
349 if ((ioc_raw_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_FAULT
) {
350 printk(MYIOC_s_WARN_FMT
"IOC is in FAULT state (%04xh)!!!\n",
351 ioc
->name
, ioc_raw_state
& MPI_DOORBELL_DATA_MASK
);
352 printk(MYIOC_s_WARN_FMT
"Issuing HardReset from %s!!\n",
353 ioc
->name
, __func__
);
354 rc
= mpt_HardResetHandler(ioc
, CAN_SLEEP
);
355 printk(MYIOC_s_WARN_FMT
"%s: HardReset: %s\n", ioc
->name
,
356 __func__
, (rc
== 0) ? "success" : "failed");
357 ioc_raw_state
= mpt_GetIocState(ioc
, 0);
358 if ((ioc_raw_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_FAULT
)
359 printk(MYIOC_s_WARN_FMT
"IOC is in FAULT state after "
360 "reset (%04xh)\n", ioc
->name
, ioc_raw_state
&
361 MPI_DOORBELL_DATA_MASK
);
362 } else if (ioc
->bus_type
== SAS
&& ioc
->sas_discovery_quiesce_io
) {
363 if ((mpt_is_discovery_complete(ioc
))) {
364 devtprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"clearing "
365 "discovery_quiesce_io flag\n", ioc
->name
));
366 ioc
->sas_discovery_quiesce_io
= 0;
372 * Take turns polling alternate controller
377 /* rearm the timer */
378 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
379 if (ioc
->reset_work_q
)
380 queue_delayed_work(ioc
->reset_work_q
, &ioc
->fault_reset_work
,
381 msecs_to_jiffies(MPT_POLLING_INTERVAL
));
382 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
387 * Process turbo (context) reply...
390 mpt_turbo_reply(MPT_ADAPTER
*ioc
, u32 pa
)
392 MPT_FRAME_HDR
*mf
= NULL
;
393 MPT_FRAME_HDR
*mr
= NULL
;
397 dmfprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Got TURBO reply req_idx=%08x\n",
400 switch (pa
>> MPI_CONTEXT_REPLY_TYPE_SHIFT
) {
401 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT
:
402 req_idx
= pa
& 0x0000FFFF;
403 cb_idx
= (pa
& 0x00FF0000) >> 16;
404 mf
= MPT_INDEX_2_MFPTR(ioc
, req_idx
);
406 case MPI_CONTEXT_REPLY_TYPE_LAN
:
407 cb_idx
= mpt_get_cb_idx(MPTLAN_DRIVER
);
409 * Blind set of mf to NULL here was fatal
410 * after lan_reply says "freeme"
411 * Fix sort of combined with an optimization here;
412 * added explicit check for case where lan_reply
413 * was just returning 1 and doing nothing else.
414 * For this case skip the callback, but set up
415 * proper mf value first here:-)
417 if ((pa
& 0x58000000) == 0x58000000) {
418 req_idx
= pa
& 0x0000FFFF;
419 mf
= MPT_INDEX_2_MFPTR(ioc
, req_idx
);
420 mpt_free_msg_frame(ioc
, mf
);
425 mr
= (MPT_FRAME_HDR
*) CAST_U32_TO_PTR(pa
);
427 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET
:
428 cb_idx
= mpt_get_cb_idx(MPTSTM_DRIVER
);
429 mr
= (MPT_FRAME_HDR
*) CAST_U32_TO_PTR(pa
);
436 /* Check for (valid) IO callback! */
437 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
||
438 MptCallbacks
[cb_idx
] == NULL
) {
439 printk(MYIOC_s_WARN_FMT
"%s: Invalid cb_idx (%d)!\n",
440 __func__
, ioc
->name
, cb_idx
);
444 if (MptCallbacks
[cb_idx
](ioc
, mf
, mr
))
445 mpt_free_msg_frame(ioc
, mf
);
451 mpt_reply(MPT_ADAPTER
*ioc
, u32 pa
)
462 /* non-TURBO reply! Hmmm, something may be up...
463 * Newest turbo reply mechanism; get address
464 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
467 /* Map DMA address of reply header to cpu address.
468 * pa is 32 bits - but the dma address may be 32 or 64 bits
469 * get offset based only only the low addresses
472 reply_dma_low
= (pa
<<= 1);
473 mr
= (MPT_FRAME_HDR
*)((u8
*)ioc
->reply_frames
+
474 (reply_dma_low
- ioc
->reply_frames_low_dma
));
476 req_idx
= le16_to_cpu(mr
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
);
477 cb_idx
= mr
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
;
478 mf
= MPT_INDEX_2_MFPTR(ioc
, req_idx
);
480 dmfprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
481 ioc
->name
, mr
, req_idx
, cb_idx
, mr
->u
.hdr
.Function
));
482 DBG_DUMP_REPLY_FRAME(ioc
, (u32
*)mr
);
484 /* Check/log IOC log info
486 ioc_stat
= le16_to_cpu(mr
->u
.reply
.IOCStatus
);
487 if (ioc_stat
& MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE
) {
488 u32 log_info
= le32_to_cpu(mr
->u
.reply
.IOCLogInfo
);
489 if (ioc
->bus_type
== FC
)
490 mpt_fc_log_info(ioc
, log_info
);
491 else if (ioc
->bus_type
== SPI
)
492 mpt_spi_log_info(ioc
, log_info
);
493 else if (ioc
->bus_type
== SAS
)
494 mpt_sas_log_info(ioc
, log_info
, cb_idx
);
497 if (ioc_stat
& MPI_IOCSTATUS_MASK
)
498 mpt_iocstatus_info(ioc
, (u32
)ioc_stat
, mf
);
500 /* Check for (valid) IO callback! */
501 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
||
502 MptCallbacks
[cb_idx
] == NULL
) {
503 printk(MYIOC_s_WARN_FMT
"%s: Invalid cb_idx (%d)!\n",
504 __func__
, ioc
->name
, cb_idx
);
509 freeme
= MptCallbacks
[cb_idx
](ioc
, mf
, mr
);
512 /* Flush (non-TURBO) reply with a WRITE! */
513 CHIPREG_WRITE32(&ioc
->chip
->ReplyFifo
, pa
);
516 mpt_free_msg_frame(ioc
, mf
);
520 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
522 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
523 * @irq: irq number (not used)
524 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
526 * This routine is registered via the request_irq() kernel API call,
527 * and handles all interrupts generated from a specific MPT adapter
528 * (also referred to as a IO Controller or IOC).
529 * This routine must clear the interrupt from the adapter and does
530 * so by reading the reply FIFO. Multiple replies may be processed
531 * per single call to this routine.
533 * This routine handles register-level access of the adapter but
534 * dispatches (calls) a protocol-specific callback routine to handle
535 * the protocol-specific details of the MPT request completion.
538 mpt_interrupt(int irq
, void *bus_id
)
540 MPT_ADAPTER
*ioc
= bus_id
;
541 u32 pa
= CHIPREG_READ32_dmasync(&ioc
->chip
->ReplyFifo
);
543 if (pa
== 0xFFFFFFFF)
547 * Drain the reply FIFO!
550 if (pa
& MPI_ADDRESS_REPLY_A_BIT
)
553 mpt_turbo_reply(ioc
, pa
);
554 pa
= CHIPREG_READ32_dmasync(&ioc
->chip
->ReplyFifo
);
555 } while (pa
!= 0xFFFFFFFF);
560 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
562 * mptbase_reply - MPT base driver's callback routine
563 * @ioc: Pointer to MPT_ADAPTER structure
564 * @req: Pointer to original MPT request frame
565 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
567 * MPT base driver's callback routine; all base driver
568 * "internal" request/reply processing is routed here.
569 * Currently used for EventNotification and EventAck handling.
571 * Returns 1 indicating original alloc'd request frame ptr
572 * should be freed, or 0 if it shouldn't.
575 mptbase_reply(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*req
, MPT_FRAME_HDR
*reply
)
577 EventNotificationReply_t
*pEventReply
;
582 switch (reply
->u
.hdr
.Function
) {
583 case MPI_FUNCTION_EVENT_NOTIFICATION
:
584 pEventReply
= (EventNotificationReply_t
*)reply
;
586 ProcessEventNotification(ioc
, pEventReply
, &evHandlers
);
587 event
= le32_to_cpu(pEventReply
->Event
) & 0xFF;
588 if (pEventReply
->MsgFlags
& MPI_MSGFLAGS_CONTINUATION_REPLY
)
590 if (event
!= MPI_EVENT_EVENT_CHANGE
)
592 case MPI_FUNCTION_CONFIG
:
593 case MPI_FUNCTION_SAS_IO_UNIT_CONTROL
:
594 ioc
->mptbase_cmds
.status
|= MPT_MGMT_STATUS_COMMAND_GOOD
;
596 ioc
->mptbase_cmds
.status
|= MPT_MGMT_STATUS_RF_VALID
;
597 memcpy(ioc
->mptbase_cmds
.reply
, reply
,
598 min(MPT_DEFAULT_FRAME_SIZE
,
599 4 * reply
->u
.reply
.MsgLength
));
601 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_PENDING
) {
602 ioc
->mptbase_cmds
.status
&= ~MPT_MGMT_STATUS_PENDING
;
603 complete(&ioc
->mptbase_cmds
.done
);
606 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_FREE_MF
)
609 case MPI_FUNCTION_EVENT_ACK
:
610 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
611 "EventAck reply received\n", ioc
->name
));
614 printk(MYIOC_s_ERR_FMT
615 "Unexpected msg function (=%02Xh) reply received!\n",
616 ioc
->name
, reply
->u
.hdr
.Function
);
621 * Conditionally tell caller to free the original
622 * EventNotification/EventAck/unexpected request frame!
627 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
629 * mpt_register - Register protocol-specific main callback handler.
630 * @cbfunc: callback function pointer
631 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
633 * This routine is called by a protocol-specific driver (SCSI host,
634 * LAN, SCSI target) to register its reply callback routine. Each
635 * protocol-specific driver must do this before it will be able to
636 * use any IOC resources, such as obtaining request frames.
638 * NOTES: The SCSI protocol driver currently calls this routine thrice
639 * in order to register separate callbacks; one for "normal" SCSI IO;
640 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
642 * Returns u8 valued "handle" in the range (and S.O.D. order)
643 * {N,...,7,6,5,...,1} if successful.
644 * A return value of MPT_MAX_PROTOCOL_DRIVERS (including zero!) should be
645 * considered an error by the caller.
648 mpt_register(MPT_CALLBACK cbfunc
, MPT_DRIVER_CLASS dclass
, char *func_name
)
651 last_drv_idx
= MPT_MAX_PROTOCOL_DRIVERS
;
654 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
655 * (slot/handle 0 is reserved!)
657 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
658 if (MptCallbacks
[cb_idx
] == NULL
) {
659 MptCallbacks
[cb_idx
] = cbfunc
;
660 MptDriverClass
[cb_idx
] = dclass
;
661 MptEvHandlers
[cb_idx
] = NULL
;
662 last_drv_idx
= cb_idx
;
663 memcpy(MptCallbacksName
[cb_idx
], func_name
,
664 strlen(func_name
) > 50 ? 50 : strlen(func_name
));
672 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
674 * mpt_deregister - Deregister a protocol drivers resources.
675 * @cb_idx: previously registered callback handle
677 * Each protocol-specific driver should call this routine when its
678 * module is unloaded.
681 mpt_deregister(u8 cb_idx
)
683 if (cb_idx
&& (cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
)) {
684 MptCallbacks
[cb_idx
] = NULL
;
685 MptDriverClass
[cb_idx
] = MPTUNKNOWN_DRIVER
;
686 MptEvHandlers
[cb_idx
] = NULL
;
692 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
694 * mpt_event_register - Register protocol-specific event callback handler.
695 * @cb_idx: previously registered (via mpt_register) callback handle
696 * @ev_cbfunc: callback function
698 * This routine can be called by one or more protocol-specific drivers
699 * if/when they choose to be notified of MPT events.
701 * Returns 0 for success.
704 mpt_event_register(u8 cb_idx
, MPT_EVHANDLER ev_cbfunc
)
706 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
709 MptEvHandlers
[cb_idx
] = ev_cbfunc
;
713 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
715 * mpt_event_deregister - Deregister protocol-specific event callback handler
716 * @cb_idx: previously registered callback handle
718 * Each protocol-specific driver should call this routine
719 * when it does not (or can no longer) handle events,
720 * or when its module is unloaded.
723 mpt_event_deregister(u8 cb_idx
)
725 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
728 MptEvHandlers
[cb_idx
] = NULL
;
731 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
733 * mpt_reset_register - Register protocol-specific IOC reset handler.
734 * @cb_idx: previously registered (via mpt_register) callback handle
735 * @reset_func: reset function
737 * This routine can be called by one or more protocol-specific drivers
738 * if/when they choose to be notified of IOC resets.
740 * Returns 0 for success.
743 mpt_reset_register(u8 cb_idx
, MPT_RESETHANDLER reset_func
)
745 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
748 MptResetHandlers
[cb_idx
] = reset_func
;
752 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
754 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
755 * @cb_idx: previously registered callback handle
757 * Each protocol-specific driver should call this routine
758 * when it does not (or can no longer) handle IOC reset handling,
759 * or when its module is unloaded.
762 mpt_reset_deregister(u8 cb_idx
)
764 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
767 MptResetHandlers
[cb_idx
] = NULL
;
770 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
772 * mpt_device_driver_register - Register device driver hooks
773 * @dd_cbfunc: driver callbacks struct
774 * @cb_idx: MPT protocol driver index
777 mpt_device_driver_register(struct mpt_pci_driver
* dd_cbfunc
, u8 cb_idx
)
780 const struct pci_device_id
*id
;
782 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
785 MptDeviceDriverHandlers
[cb_idx
] = dd_cbfunc
;
787 /* call per pci device probe entry point */
788 list_for_each_entry(ioc
, &ioc_list
, list
) {
789 id
= ioc
->pcidev
->driver
?
790 ioc
->pcidev
->driver
->id_table
: NULL
;
791 if (dd_cbfunc
->probe
)
792 dd_cbfunc
->probe(ioc
->pcidev
, id
);
798 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
800 * mpt_device_driver_deregister - DeRegister device driver hooks
801 * @cb_idx: MPT protocol driver index
804 mpt_device_driver_deregister(u8 cb_idx
)
806 struct mpt_pci_driver
*dd_cbfunc
;
809 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
812 dd_cbfunc
= MptDeviceDriverHandlers
[cb_idx
];
814 list_for_each_entry(ioc
, &ioc_list
, list
) {
815 if (dd_cbfunc
->remove
)
816 dd_cbfunc
->remove(ioc
->pcidev
);
819 MptDeviceDriverHandlers
[cb_idx
] = NULL
;
823 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
825 * mpt_get_msg_frame - Obtain an MPT request frame from the pool
826 * @cb_idx: Handle of registered MPT protocol driver
827 * @ioc: Pointer to MPT adapter structure
829 * Obtain an MPT request frame from the pool (of 1024) that are
830 * allocated per MPT adapter.
832 * Returns pointer to a MPT request frame or %NULL if none are available
833 * or IOC is not active.
836 mpt_get_msg_frame(u8 cb_idx
, MPT_ADAPTER
*ioc
)
840 u16 req_idx
; /* Request index */
842 /* validate handle and ioc identifier */
846 printk(MYIOC_s_WARN_FMT
"IOC Not Active! mpt_get_msg_frame "
847 "returning NULL!\n", ioc
->name
);
850 /* If interrupts are not attached, do not return a request frame */
854 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
855 if (!list_empty(&ioc
->FreeQ
)) {
858 mf
= list_entry(ioc
->FreeQ
.next
, MPT_FRAME_HDR
,
859 u
.frame
.linkage
.list
);
860 list_del(&mf
->u
.frame
.linkage
.list
);
861 mf
->u
.frame
.linkage
.arg1
= 0;
862 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= cb_idx
; /* byte */
863 req_offset
= (u8
*)mf
- (u8
*)ioc
->req_frames
;
865 req_idx
= req_offset
/ ioc
->req_sz
;
866 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(req_idx
);
867 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.rsvd
= 0;
868 /* Default, will be changed if necessary in SG generation */
869 ioc
->RequestNB
[req_idx
] = ioc
->NB_for_64_byte_frame
;
876 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
880 printk(MYIOC_s_WARN_FMT
"IOC Active. No free Msg Frames! "
881 "Count 0x%x Max 0x%x\n", ioc
->name
, ioc
->mfcnt
,
884 if (mfcounter
== PRINT_MF_COUNT
)
885 printk(MYIOC_s_INFO_FMT
"MF Count 0x%x Max 0x%x \n", ioc
->name
,
886 ioc
->mfcnt
, ioc
->req_depth
);
889 dmfprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mpt_get_msg_frame(%d,%d), got mf=%p\n",
890 ioc
->name
, cb_idx
, ioc
->id
, mf
));
894 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
896 * mpt_put_msg_frame - Send a protocol-specific MPT request frame to an IOC
897 * @cb_idx: Handle of registered MPT protocol driver
898 * @ioc: Pointer to MPT adapter structure
899 * @mf: Pointer to MPT request frame
901 * This routine posts an MPT request frame to the request post FIFO of a
902 * specific MPT adapter.
905 mpt_put_msg_frame(u8 cb_idx
, MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
)
909 u16 req_idx
; /* Request index */
911 /* ensure values are reset properly! */
912 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= cb_idx
; /* byte */
913 req_offset
= (u8
*)mf
- (u8
*)ioc
->req_frames
;
915 req_idx
= req_offset
/ ioc
->req_sz
;
916 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(req_idx
);
917 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.rsvd
= 0;
919 DBG_DUMP_PUT_MSG_FRAME(ioc
, (u32
*)mf
);
921 mf_dma_addr
= (ioc
->req_frames_low_dma
+ req_offset
) | ioc
->RequestNB
[req_idx
];
922 dsgprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mf_dma_addr=%x req_idx=%d "
923 "RequestNB=%x\n", ioc
->name
, mf_dma_addr
, req_idx
,
924 ioc
->RequestNB
[req_idx
]));
925 CHIPREG_WRITE32(&ioc
->chip
->RequestFifo
, mf_dma_addr
);
929 * mpt_put_msg_frame_hi_pri - Send a hi-pri protocol-specific MPT request frame
930 * @cb_idx: Handle of registered MPT protocol driver
931 * @ioc: Pointer to MPT adapter structure
932 * @mf: Pointer to MPT request frame
934 * Send a protocol-specific MPT request frame to an IOC using
935 * hi-priority request queue.
937 * This routine posts an MPT request frame to the request post FIFO of a
938 * specific MPT adapter.
941 mpt_put_msg_frame_hi_pri(u8 cb_idx
, MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
)
945 u16 req_idx
; /* Request index */
947 /* ensure values are reset properly! */
948 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= cb_idx
;
949 req_offset
= (u8
*)mf
- (u8
*)ioc
->req_frames
;
950 req_idx
= req_offset
/ ioc
->req_sz
;
951 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(req_idx
);
952 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.rsvd
= 0;
954 DBG_DUMP_PUT_MSG_FRAME(ioc
, (u32
*)mf
);
956 mf_dma_addr
= (ioc
->req_frames_low_dma
+ req_offset
);
957 dsgprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mf_dma_addr=%x req_idx=%d\n",
958 ioc
->name
, mf_dma_addr
, req_idx
));
959 CHIPREG_WRITE32(&ioc
->chip
->RequestHiPriFifo
, mf_dma_addr
);
962 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
964 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
965 * @ioc: Pointer to MPT adapter structure
966 * @mf: Pointer to MPT request frame
968 * This routine places a MPT request frame back on the MPT adapter's
972 mpt_free_msg_frame(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
)
976 /* Put Request back on FreeQ! */
977 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
978 if (cpu_to_le32(mf
->u
.frame
.linkage
.arg1
) == 0xdeadbeaf)
980 /* signature to know if this mf is freed */
981 mf
->u
.frame
.linkage
.arg1
= cpu_to_le32(0xdeadbeaf);
982 list_add_tail(&mf
->u
.frame
.linkage
.list
, &ioc
->FreeQ
);
987 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
990 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
992 * mpt_add_sge - Place a simple 32 bit SGE at address pAddr.
993 * @pAddr: virtual address for SGE
994 * @flagslength: SGE flags and data transfer length
995 * @dma_addr: Physical address
997 * This routine places a MPT request frame back on the MPT adapter's
1001 mpt_add_sge(void *pAddr
, u32 flagslength
, dma_addr_t dma_addr
)
1003 SGESimple32_t
*pSge
= (SGESimple32_t
*) pAddr
;
1004 pSge
->FlagsLength
= cpu_to_le32(flagslength
);
1005 pSge
->Address
= cpu_to_le32(dma_addr
);
1009 * mpt_add_sge_64bit - Place a simple 64 bit SGE at address pAddr.
1010 * @pAddr: virtual address for SGE
1011 * @flagslength: SGE flags and data transfer length
1012 * @dma_addr: Physical address
1014 * This routine places a MPT request frame back on the MPT adapter's
1018 mpt_add_sge_64bit(void *pAddr
, u32 flagslength
, dma_addr_t dma_addr
)
1020 SGESimple64_t
*pSge
= (SGESimple64_t
*) pAddr
;
1021 pSge
->Address
.Low
= cpu_to_le32
1022 (lower_32_bits(dma_addr
));
1023 pSge
->Address
.High
= cpu_to_le32
1024 (upper_32_bits(dma_addr
));
1025 pSge
->FlagsLength
= cpu_to_le32
1026 ((flagslength
| MPT_SGE_FLAGS_64_BIT_ADDRESSING
));
1030 * mpt_add_sge_64bit_1078 - Place a simple 64 bit SGE at address pAddr (1078 workaround).
1031 * @pAddr: virtual address for SGE
1032 * @flagslength: SGE flags and data transfer length
1033 * @dma_addr: Physical address
1035 * This routine places a MPT request frame back on the MPT adapter's
1039 mpt_add_sge_64bit_1078(void *pAddr
, u32 flagslength
, dma_addr_t dma_addr
)
1041 SGESimple64_t
*pSge
= (SGESimple64_t
*) pAddr
;
1044 pSge
->Address
.Low
= cpu_to_le32
1045 (lower_32_bits(dma_addr
));
1046 tmp
= (u32
)(upper_32_bits(dma_addr
));
1049 * 1078 errata workaround for the 36GB limitation
1051 if ((((u64
)dma_addr
+ MPI_SGE_LENGTH(flagslength
)) >> 32) == 9) {
1053 MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_LOCAL_ADDRESS
);
1055 if (mpt_debug_level
& MPT_DEBUG_36GB_MEM
)
1056 printk(KERN_DEBUG
"1078 P0M2 addressing for "
1057 "addr = 0x%llx len = %d\n",
1058 (unsigned long long)dma_addr
,
1059 MPI_SGE_LENGTH(flagslength
));
1062 pSge
->Address
.High
= cpu_to_le32(tmp
);
1063 pSge
->FlagsLength
= cpu_to_le32(
1064 (flagslength
| MPT_SGE_FLAGS_64_BIT_ADDRESSING
));
1067 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1069 * mpt_add_chain - Place a 32 bit chain SGE at address pAddr.
1070 * @pAddr: virtual address for SGE
1071 * @next: nextChainOffset value (u32's)
1072 * @length: length of next SGL segment
1073 * @dma_addr: Physical address
1077 mpt_add_chain(void *pAddr
, u8 next
, u16 length
, dma_addr_t dma_addr
)
1079 SGEChain32_t
*pChain
= (SGEChain32_t
*) pAddr
;
1080 pChain
->Length
= cpu_to_le16(length
);
1081 pChain
->Flags
= MPI_SGE_FLAGS_CHAIN_ELEMENT
;
1082 pChain
->NextChainOffset
= next
;
1083 pChain
->Address
= cpu_to_le32(dma_addr
);
1086 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1088 * mpt_add_chain_64bit - Place a 64 bit chain SGE at address pAddr.
1089 * @pAddr: virtual address for SGE
1090 * @next: nextChainOffset value (u32's)
1091 * @length: length of next SGL segment
1092 * @dma_addr: Physical address
1096 mpt_add_chain_64bit(void *pAddr
, u8 next
, u16 length
, dma_addr_t dma_addr
)
1098 SGEChain64_t
*pChain
= (SGEChain64_t
*) pAddr
;
1099 u32 tmp
= dma_addr
& 0xFFFFFFFF;
1101 pChain
->Length
= cpu_to_le16(length
);
1102 pChain
->Flags
= (MPI_SGE_FLAGS_CHAIN_ELEMENT
|
1103 MPI_SGE_FLAGS_64_BIT_ADDRESSING
);
1105 pChain
->NextChainOffset
= next
;
1107 pChain
->Address
.Low
= cpu_to_le32(tmp
);
1108 tmp
= (u32
)(upper_32_bits(dma_addr
));
1109 pChain
->Address
.High
= cpu_to_le32(tmp
);
1112 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1114 * mpt_send_handshake_request - Send MPT request via doorbell handshake method.
1115 * @cb_idx: Handle of registered MPT protocol driver
1116 * @ioc: Pointer to MPT adapter structure
1117 * @reqBytes: Size of the request in bytes
1118 * @req: Pointer to MPT request frame
1119 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1121 * This routine is used exclusively to send MptScsiTaskMgmt
1122 * requests since they are required to be sent via doorbell handshake.
1124 * NOTE: It is the callers responsibility to byte-swap fields in the
1125 * request which are greater than 1 byte in size.
1127 * Returns 0 for success, non-zero for failure.
1130 mpt_send_handshake_request(u8 cb_idx
, MPT_ADAPTER
*ioc
, int reqBytes
, u32
*req
, int sleepFlag
)
1136 /* State is known to be good upon entering
1137 * this function so issue the bus reset
1142 * Emulate what mpt_put_msg_frame() does /wrt to sanity
1143 * setting cb_idx/req_idx. But ONLY if this request
1144 * is in proper (pre-alloc'd) request buffer range...
1146 ii
= MFPTR_2_MPT_INDEX(ioc
,(MPT_FRAME_HDR
*)req
);
1147 if (reqBytes
>= 12 && ii
>= 0 && ii
< ioc
->req_depth
) {
1148 MPT_FRAME_HDR
*mf
= (MPT_FRAME_HDR
*)req
;
1149 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(ii
);
1150 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= cb_idx
;
1153 /* Make sure there are no doorbells */
1154 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1156 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
,
1157 ((MPI_FUNCTION_HANDSHAKE
<<MPI_DOORBELL_FUNCTION_SHIFT
) |
1158 ((reqBytes
/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT
)));
1160 /* Wait for IOC doorbell int */
1161 if ((ii
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0) {
1165 /* Read doorbell and check for active bit */
1166 if (!(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & MPI_DOORBELL_ACTIVE
))
1169 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mpt_send_handshake_request start, WaitCnt=%d\n",
1172 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1174 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0) {
1178 /* Send request via doorbell handshake */
1179 req_as_bytes
= (u8
*) req
;
1180 for (ii
= 0; ii
< reqBytes
/4; ii
++) {
1183 word
= ((req_as_bytes
[(ii
*4) + 0] << 0) |
1184 (req_as_bytes
[(ii
*4) + 1] << 8) |
1185 (req_as_bytes
[(ii
*4) + 2] << 16) |
1186 (req_as_bytes
[(ii
*4) + 3] << 24));
1187 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, word
);
1188 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0) {
1194 if (r
>= 0 && WaitForDoorbellInt(ioc
, 10, sleepFlag
) >= 0)
1199 /* Make sure there are no doorbells */
1200 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1205 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1207 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
1208 * @ioc: Pointer to MPT adapter structure
1209 * @access_control_value: define bits below
1210 * @sleepFlag: Specifies whether the process can sleep
1212 * Provides mechanism for the host driver to control the IOC's
1213 * Host Page Buffer access.
1215 * Access Control Value - bits[15:12]
1217 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1218 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1219 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1221 * Returns 0 for success, non-zero for failure.
1225 mpt_host_page_access_control(MPT_ADAPTER
*ioc
, u8 access_control_value
, int sleepFlag
)
1229 /* return if in use */
1230 if (CHIPREG_READ32(&ioc
->chip
->Doorbell
)
1231 & MPI_DOORBELL_ACTIVE
)
1234 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1236 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
,
1237 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1238 <<MPI_DOORBELL_FUNCTION_SHIFT
) |
1239 (access_control_value
<<12)));
1241 /* Wait for IOC to clear Doorbell Status bit */
1242 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0) {
1248 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1250 * mpt_host_page_alloc - allocate system memory for the fw
1251 * @ioc: Pointer to pointer to IOC adapter
1252 * @ioc_init: Pointer to ioc init config page
1254 * If we already allocated memory in past, then resend the same pointer.
1255 * Returns 0 for success, non-zero for failure.
1258 mpt_host_page_alloc(MPT_ADAPTER
*ioc
, pIOCInit_t ioc_init
)
1262 u32 host_page_buffer_sz
=0;
1264 if(!ioc
->HostPageBuffer
) {
1266 host_page_buffer_sz
=
1267 le32_to_cpu(ioc
->facts
.HostPageBufferSGE
.FlagsLength
) & 0xFFFFFF;
1269 if(!host_page_buffer_sz
)
1270 return 0; /* fw doesn't need any host buffers */
1272 /* spin till we get enough memory */
1273 while(host_page_buffer_sz
> 0) {
1275 if((ioc
->HostPageBuffer
= pci_alloc_consistent(
1277 host_page_buffer_sz
,
1278 &ioc
->HostPageBuffer_dma
)) != NULL
) {
1280 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
1281 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1282 ioc
->name
, ioc
->HostPageBuffer
,
1283 (u32
)ioc
->HostPageBuffer_dma
,
1284 host_page_buffer_sz
));
1285 ioc
->alloc_total
+= host_page_buffer_sz
;
1286 ioc
->HostPageBuffer_sz
= host_page_buffer_sz
;
1290 host_page_buffer_sz
-= (4*1024);
1294 if(!ioc
->HostPageBuffer
) {
1295 printk(MYIOC_s_ERR_FMT
1296 "Failed to alloc memory for host_page_buffer!\n",
1301 psge
= (char *)&ioc_init
->HostPageBufferSGE
;
1302 flags_length
= MPI_SGE_FLAGS_SIMPLE_ELEMENT
|
1303 MPI_SGE_FLAGS_SYSTEM_ADDRESS
|
1304 MPI_SGE_FLAGS_HOST_TO_IOC
|
1305 MPI_SGE_FLAGS_END_OF_BUFFER
;
1306 flags_length
= flags_length
<< MPI_SGE_FLAGS_SHIFT
;
1307 flags_length
|= ioc
->HostPageBuffer_sz
;
1308 ioc
->add_sge(psge
, flags_length
, ioc
->HostPageBuffer_dma
);
1309 ioc
->facts
.HostPageBufferSGE
= ioc_init
->HostPageBufferSGE
;
1314 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1316 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1317 * @iocid: IOC unique identifier (integer)
1318 * @iocpp: Pointer to pointer to IOC adapter
1320 * Given a unique IOC identifier, set pointer to the associated MPT
1321 * adapter structure.
1323 * Returns iocid and sets iocpp if iocid is found.
1324 * Returns -1 if iocid is not found.
1327 mpt_verify_adapter(int iocid
, MPT_ADAPTER
**iocpp
)
1331 list_for_each_entry(ioc
,&ioc_list
,list
) {
1332 if (ioc
->id
== iocid
) {
1343 * mpt_get_product_name - returns product string
1344 * @vendor: pci vendor id
1345 * @device: pci device id
1346 * @revision: pci revision id
1347 * @prod_name: string returned
1349 * Returns product string displayed when driver loads,
1350 * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1354 mpt_get_product_name(u16 vendor
, u16 device
, u8 revision
, char *prod_name
)
1356 char *product_str
= NULL
;
1358 if (vendor
== PCI_VENDOR_ID_BROCADE
) {
1361 case MPI_MANUFACTPAGE_DEVICEID_FC949E
:
1365 product_str
= "BRE040 A0";
1368 product_str
= "BRE040 A1";
1371 product_str
= "BRE040";
1381 case MPI_MANUFACTPAGE_DEVICEID_FC909
:
1382 product_str
= "LSIFC909 B1";
1384 case MPI_MANUFACTPAGE_DEVICEID_FC919
:
1385 product_str
= "LSIFC919 B0";
1387 case MPI_MANUFACTPAGE_DEVICEID_FC929
:
1388 product_str
= "LSIFC929 B0";
1390 case MPI_MANUFACTPAGE_DEVICEID_FC919X
:
1391 if (revision
< 0x80)
1392 product_str
= "LSIFC919X A0";
1394 product_str
= "LSIFC919XL A1";
1396 case MPI_MANUFACTPAGE_DEVICEID_FC929X
:
1397 if (revision
< 0x80)
1398 product_str
= "LSIFC929X A0";
1400 product_str
= "LSIFC929XL A1";
1402 case MPI_MANUFACTPAGE_DEVICEID_FC939X
:
1403 product_str
= "LSIFC939X A1";
1405 case MPI_MANUFACTPAGE_DEVICEID_FC949X
:
1406 product_str
= "LSIFC949X A1";
1408 case MPI_MANUFACTPAGE_DEVICEID_FC949E
:
1412 product_str
= "LSIFC949E A0";
1415 product_str
= "LSIFC949E A1";
1418 product_str
= "LSIFC949E";
1422 case MPI_MANUFACTPAGE_DEVID_53C1030
:
1426 product_str
= "LSI53C1030 A0";
1429 product_str
= "LSI53C1030 B0";
1432 product_str
= "LSI53C1030 B1";
1435 product_str
= "LSI53C1030 B2";
1438 product_str
= "LSI53C1030 C0";
1441 product_str
= "LSI53C1030T A0";
1444 product_str
= "LSI53C1030T A2";
1447 product_str
= "LSI53C1030T A3";
1450 product_str
= "LSI53C1020A A1";
1453 product_str
= "LSI53C1030";
1457 case MPI_MANUFACTPAGE_DEVID_1030_53C1035
:
1461 product_str
= "LSI53C1035 A2";
1464 product_str
= "LSI53C1035 B0";
1467 product_str
= "LSI53C1035";
1471 case MPI_MANUFACTPAGE_DEVID_SAS1064
:
1475 product_str
= "LSISAS1064 A1";
1478 product_str
= "LSISAS1064 A2";
1481 product_str
= "LSISAS1064 A3";
1484 product_str
= "LSISAS1064 A4";
1487 product_str
= "LSISAS1064";
1491 case MPI_MANUFACTPAGE_DEVID_SAS1064E
:
1495 product_str
= "LSISAS1064E A0";
1498 product_str
= "LSISAS1064E B0";
1501 product_str
= "LSISAS1064E B1";
1504 product_str
= "LSISAS1064E B2";
1507 product_str
= "LSISAS1064E B3";
1510 product_str
= "LSISAS1064E";
1514 case MPI_MANUFACTPAGE_DEVID_SAS1068
:
1518 product_str
= "LSISAS1068 A0";
1521 product_str
= "LSISAS1068 B0";
1524 product_str
= "LSISAS1068 B1";
1527 product_str
= "LSISAS1068";
1531 case MPI_MANUFACTPAGE_DEVID_SAS1068E
:
1535 product_str
= "LSISAS1068E A0";
1538 product_str
= "LSISAS1068E B0";
1541 product_str
= "LSISAS1068E B1";
1544 product_str
= "LSISAS1068E B2";
1547 product_str
= "LSISAS1068E B3";
1550 product_str
= "LSISAS1068E";
1554 case MPI_MANUFACTPAGE_DEVID_SAS1078
:
1558 product_str
= "LSISAS1078 A0";
1561 product_str
= "LSISAS1078 B0";
1564 product_str
= "LSISAS1078 C0";
1567 product_str
= "LSISAS1078 C1";
1570 product_str
= "LSISAS1078 C2";
1573 product_str
= "LSISAS1078";
1581 sprintf(prod_name
, "%s", product_str
);
1585 * mpt_mapresources - map in memory mapped io
1586 * @ioc: Pointer to pointer to IOC adapter
1590 mpt_mapresources(MPT_ADAPTER
*ioc
)
1594 resource_size_t mem_phys
;
1600 struct pci_dev
*pdev
;
1603 ioc
->bars
= pci_select_bars(pdev
, IORESOURCE_MEM
);
1604 if (pci_enable_device_mem(pdev
)) {
1605 printk(MYIOC_s_ERR_FMT
"pci_enable_device_mem() "
1606 "failed\n", ioc
->name
);
1609 if (pci_request_selected_regions(pdev
, ioc
->bars
, "mpt")) {
1610 printk(MYIOC_s_ERR_FMT
"pci_request_selected_regions() with "
1611 "MEM failed\n", ioc
->name
);
1615 pci_read_config_byte(pdev
, PCI_CLASS_REVISION
, &revision
);
1617 if (sizeof(dma_addr_t
) > 4) {
1618 const uint64_t required_mask
= dma_get_required_mask
1620 if (required_mask
> DMA_BIT_MASK(32)
1621 && !pci_set_dma_mask(pdev
, DMA_BIT_MASK(64))
1622 && !pci_set_consistent_dma_mask(pdev
,
1623 DMA_BIT_MASK(64))) {
1624 ioc
->dma_mask
= DMA_BIT_MASK(64);
1625 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
1626 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1628 } else if (!pci_set_dma_mask(pdev
, DMA_BIT_MASK(32))
1629 && !pci_set_consistent_dma_mask(pdev
,
1630 DMA_BIT_MASK(32))) {
1631 ioc
->dma_mask
= DMA_BIT_MASK(32);
1632 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
1633 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1636 printk(MYIOC_s_WARN_FMT
"no suitable DMA mask for %s\n",
1637 ioc
->name
, pci_name(pdev
));
1641 if (!pci_set_dma_mask(pdev
, DMA_BIT_MASK(32))
1642 && !pci_set_consistent_dma_mask(pdev
,
1643 DMA_BIT_MASK(32))) {
1644 ioc
->dma_mask
= DMA_BIT_MASK(32);
1645 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
1646 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1649 printk(MYIOC_s_WARN_FMT
"no suitable DMA mask for %s\n",
1650 ioc
->name
, pci_name(pdev
));
1655 mem_phys
= msize
= 0;
1657 for (ii
= 0; ii
< DEVICE_COUNT_RESOURCE
; ii
++) {
1658 if (pci_resource_flags(pdev
, ii
) & PCI_BASE_ADDRESS_SPACE_IO
) {
1661 /* Get I/O space! */
1662 port
= pci_resource_start(pdev
, ii
);
1663 psize
= pci_resource_len(pdev
, ii
);
1668 mem_phys
= pci_resource_start(pdev
, ii
);
1669 msize
= pci_resource_len(pdev
, ii
);
1672 ioc
->mem_size
= msize
;
1675 /* Get logical ptr for PciMem0 space */
1676 /*mem = ioremap(mem_phys, msize);*/
1677 mem
= ioremap(mem_phys
, msize
);
1679 printk(MYIOC_s_ERR_FMT
": ERROR - Unable to map adapter"
1680 " memory!\n", ioc
->name
);
1684 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"mem = %p, mem_phys = %llx\n",
1685 ioc
->name
, mem
, (unsigned long long)mem_phys
));
1687 ioc
->mem_phys
= mem_phys
;
1688 ioc
->chip
= (SYSIF_REGS __iomem
*)mem
;
1690 /* Save Port IO values in case we need to do downloadboot */
1691 ioc
->pio_mem_phys
= port
;
1692 ioc
->pio_chip
= (SYSIF_REGS __iomem
*)port
;
1697 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1699 * mpt_attach - Install a PCI intelligent MPT adapter.
1700 * @pdev: Pointer to pci_dev structure
1701 * @id: PCI device ID information
1703 * This routine performs all the steps necessary to bring the IOC of
1704 * a MPT adapter to a OPERATIONAL state. This includes registering
1705 * memory regions, registering the interrupt, and allocating request
1706 * and reply memory pools.
1708 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1711 * Returns 0 for success, non-zero for failure.
1713 * TODO: Add support for polled controllers
1716 mpt_attach(struct pci_dev
*pdev
, const struct pci_device_id
*id
)
1723 static int mpt_ids
= 0;
1724 #ifdef CONFIG_PROC_FS
1725 struct proc_dir_entry
*dent
, *ent
;
1728 ioc
= kzalloc(sizeof(MPT_ADAPTER
), GFP_ATOMIC
);
1730 printk(KERN_ERR MYNAM
": ERROR - Insufficient memory to add adapter!\n");
1734 ioc
->id
= mpt_ids
++;
1735 sprintf(ioc
->name
, "ioc%d", ioc
->id
);
1736 dinitprintk(ioc
, printk(KERN_WARNING MYNAM
": mpt_adapter_install\n"));
1739 * set initial debug level
1740 * (refer to mptdebug.h)
1743 ioc
->debug_level
= mpt_debug_level
;
1744 if (mpt_debug_level
)
1745 printk(KERN_INFO
"mpt_debug_level=%xh\n", mpt_debug_level
);
1747 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
": mpt_adapter_install\n", ioc
->name
));
1750 if (mpt_mapresources(ioc
)) {
1756 * Setting up proper handlers for scatter gather handling
1758 if (ioc
->dma_mask
== DMA_BIT_MASK(64)) {
1759 if (pdev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1078
)
1760 ioc
->add_sge
= &mpt_add_sge_64bit_1078
;
1762 ioc
->add_sge
= &mpt_add_sge_64bit
;
1763 ioc
->add_chain
= &mpt_add_chain_64bit
;
1764 ioc
->sg_addr_size
= 8;
1766 ioc
->add_sge
= &mpt_add_sge
;
1767 ioc
->add_chain
= &mpt_add_chain
;
1768 ioc
->sg_addr_size
= 4;
1770 ioc
->SGE_size
= sizeof(u32
) + ioc
->sg_addr_size
;
1772 ioc
->alloc_total
= sizeof(MPT_ADAPTER
);
1773 ioc
->req_sz
= MPT_DEFAULT_FRAME_SIZE
; /* avoid div by zero! */
1774 ioc
->reply_sz
= MPT_REPLY_FRAME_SIZE
;
1777 spin_lock_init(&ioc
->taskmgmt_lock
);
1778 mutex_init(&ioc
->internal_cmds
.mutex
);
1779 init_completion(&ioc
->internal_cmds
.done
);
1780 mutex_init(&ioc
->mptbase_cmds
.mutex
);
1781 init_completion(&ioc
->mptbase_cmds
.done
);
1782 mutex_init(&ioc
->taskmgmt_cmds
.mutex
);
1783 init_completion(&ioc
->taskmgmt_cmds
.done
);
1785 /* Initialize the event logging.
1787 ioc
->eventTypes
= 0; /* None */
1788 ioc
->eventContext
= 0;
1789 ioc
->eventLogSize
= 0;
1797 ioc
->cached_fw
= NULL
;
1799 /* Initilize SCSI Config Data structure
1801 memset(&ioc
->spi_data
, 0, sizeof(SpiCfgData
));
1803 /* Initialize the fc rport list head.
1805 INIT_LIST_HEAD(&ioc
->fc_rports
);
1807 /* Find lookup slot. */
1808 INIT_LIST_HEAD(&ioc
->list
);
1811 /* Initialize workqueue */
1812 INIT_DELAYED_WORK(&ioc
->fault_reset_work
, mpt_fault_reset_work
);
1814 snprintf(ioc
->reset_work_q_name
, MPT_KOBJ_NAME_LEN
,
1815 "mpt_poll_%d", ioc
->id
);
1817 create_singlethread_workqueue(ioc
->reset_work_q_name
);
1818 if (!ioc
->reset_work_q
) {
1819 printk(MYIOC_s_ERR_FMT
"Insufficient memory to add adapter!\n",
1821 pci_release_selected_regions(pdev
, ioc
->bars
);
1826 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"facts @ %p, pfacts[0] @ %p\n",
1827 ioc
->name
, &ioc
->facts
, &ioc
->pfacts
[0]));
1829 pci_read_config_byte(pdev
, PCI_CLASS_REVISION
, &revision
);
1830 mpt_get_product_name(pdev
->vendor
, pdev
->device
, revision
, ioc
->prod_name
);
1832 switch (pdev
->device
)
1834 case MPI_MANUFACTPAGE_DEVICEID_FC939X
:
1835 case MPI_MANUFACTPAGE_DEVICEID_FC949X
:
1836 ioc
->errata_flag_1064
= 1;
1837 case MPI_MANUFACTPAGE_DEVICEID_FC909
:
1838 case MPI_MANUFACTPAGE_DEVICEID_FC929
:
1839 case MPI_MANUFACTPAGE_DEVICEID_FC919
:
1840 case MPI_MANUFACTPAGE_DEVICEID_FC949E
:
1844 case MPI_MANUFACTPAGE_DEVICEID_FC929X
:
1845 if (revision
< XL_929
) {
1846 /* 929X Chip Fix. Set Split transactions level
1847 * for PCIX. Set MOST bits to zero.
1849 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1851 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1853 /* 929XL Chip Fix. Set MMRBC to 0x08.
1855 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1857 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1862 case MPI_MANUFACTPAGE_DEVICEID_FC919X
:
1863 /* 919X Chip Fix. Set Split transactions level
1864 * for PCIX. Set MOST bits to zero.
1866 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1868 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1872 case MPI_MANUFACTPAGE_DEVID_53C1030
:
1873 /* 1030 Chip Fix. Disable Split transactions
1874 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1876 if (revision
< C0_1030
) {
1877 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1879 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1882 case MPI_MANUFACTPAGE_DEVID_1030_53C1035
:
1883 ioc
->bus_type
= SPI
;
1886 case MPI_MANUFACTPAGE_DEVID_SAS1064
:
1887 case MPI_MANUFACTPAGE_DEVID_SAS1068
:
1888 ioc
->errata_flag_1064
= 1;
1889 ioc
->bus_type
= SAS
;
1892 case MPI_MANUFACTPAGE_DEVID_SAS1064E
:
1893 case MPI_MANUFACTPAGE_DEVID_SAS1068E
:
1894 case MPI_MANUFACTPAGE_DEVID_SAS1078
:
1895 ioc
->bus_type
= SAS
;
1900 switch (ioc
->bus_type
) {
1903 ioc
->msi_enable
= mpt_msi_enable_sas
;
1907 ioc
->msi_enable
= mpt_msi_enable_spi
;
1911 ioc
->msi_enable
= mpt_msi_enable_fc
;
1915 ioc
->msi_enable
= 0;
1919 ioc
->fw_events_off
= 1;
1921 if (ioc
->errata_flag_1064
)
1922 pci_disable_io_access(pdev
);
1924 spin_lock_init(&ioc
->FreeQlock
);
1927 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
1929 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1931 /* Set IOC ptr in the pcidev's driver data. */
1932 pci_set_drvdata(ioc
->pcidev
, ioc
);
1934 /* Set lookup ptr. */
1935 list_add_tail(&ioc
->list
, &ioc_list
);
1937 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1939 mpt_detect_bound_ports(ioc
, pdev
);
1941 INIT_LIST_HEAD(&ioc
->fw_event_list
);
1942 spin_lock_init(&ioc
->fw_event_lock
);
1943 snprintf(ioc
->fw_event_q_name
, MPT_KOBJ_NAME_LEN
, "mpt/%d", ioc
->id
);
1944 ioc
->fw_event_q
= create_singlethread_workqueue(ioc
->fw_event_q_name
);
1946 if ((r
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_BRINGUP
,
1948 printk(MYIOC_s_ERR_FMT
"didn't initialize properly! (%d)\n",
1951 list_del(&ioc
->list
);
1953 ioc
->alt_ioc
->alt_ioc
= NULL
;
1954 iounmap(ioc
->memmap
);
1956 pci_release_selected_regions(pdev
, ioc
->bars
);
1958 destroy_workqueue(ioc
->reset_work_q
);
1959 ioc
->reset_work_q
= NULL
;
1962 pci_set_drvdata(pdev
, NULL
);
1966 /* call per device driver probe entry point */
1967 for(cb_idx
= 0; cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
; cb_idx
++) {
1968 if(MptDeviceDriverHandlers
[cb_idx
] &&
1969 MptDeviceDriverHandlers
[cb_idx
]->probe
) {
1970 MptDeviceDriverHandlers
[cb_idx
]->probe(pdev
,id
);
1974 #ifdef CONFIG_PROC_FS
1976 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1978 dent
= proc_mkdir(ioc
->name
, mpt_proc_root_dir
);
1980 ent
= create_proc_entry("info", S_IFREG
|S_IRUGO
, dent
);
1982 ent
->read_proc
= procmpt_iocinfo_read
;
1985 ent
= create_proc_entry("summary", S_IFREG
|S_IRUGO
, dent
);
1987 ent
->read_proc
= procmpt_summary_read
;
1994 queue_delayed_work(ioc
->reset_work_q
, &ioc
->fault_reset_work
,
1995 msecs_to_jiffies(MPT_POLLING_INTERVAL
));
2000 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2002 * mpt_detach - Remove a PCI intelligent MPT adapter.
2003 * @pdev: Pointer to pci_dev structure
2007 mpt_detach(struct pci_dev
*pdev
)
2009 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
2012 unsigned long flags
;
2013 struct workqueue_struct
*wq
;
2016 * Stop polling ioc for fault condition
2018 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
2019 wq
= ioc
->reset_work_q
;
2020 ioc
->reset_work_q
= NULL
;
2021 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
2022 cancel_delayed_work(&ioc
->fault_reset_work
);
2023 destroy_workqueue(wq
);
2025 spin_lock_irqsave(&ioc
->fw_event_lock
, flags
);
2026 wq
= ioc
->fw_event_q
;
2027 ioc
->fw_event_q
= NULL
;
2028 spin_unlock_irqrestore(&ioc
->fw_event_lock
, flags
);
2029 destroy_workqueue(wq
);
2031 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s/summary", ioc
->name
);
2032 remove_proc_entry(pname
, NULL
);
2033 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s/info", ioc
->name
);
2034 remove_proc_entry(pname
, NULL
);
2035 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s", ioc
->name
);
2036 remove_proc_entry(pname
, NULL
);
2038 /* call per device driver remove entry point */
2039 for(cb_idx
= 0; cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
; cb_idx
++) {
2040 if(MptDeviceDriverHandlers
[cb_idx
] &&
2041 MptDeviceDriverHandlers
[cb_idx
]->remove
) {
2042 MptDeviceDriverHandlers
[cb_idx
]->remove(pdev
);
2046 /* Disable interrupts! */
2047 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2050 synchronize_irq(pdev
->irq
);
2052 /* Clear any lingering interrupt */
2053 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
2055 CHIPREG_READ32(&ioc
->chip
->IntStatus
);
2057 mpt_adapter_dispose(ioc
);
2061 /**************************************************************************
2065 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2067 * mpt_suspend - Fusion MPT base driver suspend routine.
2068 * @pdev: Pointer to pci_dev structure
2069 * @state: new state to enter
2072 mpt_suspend(struct pci_dev
*pdev
, pm_message_t state
)
2075 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
2077 device_state
= pci_choose_state(pdev
, state
);
2078 printk(MYIOC_s_INFO_FMT
"pci-suspend: pdev=0x%p, slot=%s, Entering "
2079 "operating state [D%d]\n", ioc
->name
, pdev
, pci_name(pdev
),
2082 /* put ioc into READY_STATE */
2083 if(SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, CAN_SLEEP
)) {
2084 printk(MYIOC_s_ERR_FMT
2085 "pci-suspend: IOC msg unit reset failed!\n", ioc
->name
);
2088 /* disable interrupts */
2089 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2092 /* Clear any lingering interrupt */
2093 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
2095 free_irq(ioc
->pci_irq
, ioc
);
2096 if (ioc
->msi_enable
)
2097 pci_disable_msi(ioc
->pcidev
);
2099 pci_save_state(pdev
);
2100 pci_disable_device(pdev
);
2101 pci_release_selected_regions(pdev
, ioc
->bars
);
2102 pci_set_power_state(pdev
, device_state
);
2106 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2108 * mpt_resume - Fusion MPT base driver resume routine.
2109 * @pdev: Pointer to pci_dev structure
2112 mpt_resume(struct pci_dev
*pdev
)
2114 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
2115 u32 device_state
= pdev
->current_state
;
2119 printk(MYIOC_s_INFO_FMT
"pci-resume: pdev=0x%p, slot=%s, Previous "
2120 "operating state [D%d]\n", ioc
->name
, pdev
, pci_name(pdev
),
2123 pci_set_power_state(pdev
, PCI_D0
);
2124 pci_enable_wake(pdev
, PCI_D0
, 0);
2125 pci_restore_state(pdev
);
2127 err
= mpt_mapresources(ioc
);
2131 if (ioc
->dma_mask
== DMA_BIT_MASK(64)) {
2132 if (pdev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1078
)
2133 ioc
->add_sge
= &mpt_add_sge_64bit_1078
;
2135 ioc
->add_sge
= &mpt_add_sge_64bit
;
2136 ioc
->add_chain
= &mpt_add_chain_64bit
;
2137 ioc
->sg_addr_size
= 8;
2140 ioc
->add_sge
= &mpt_add_sge
;
2141 ioc
->add_chain
= &mpt_add_chain
;
2142 ioc
->sg_addr_size
= 4;
2144 ioc
->SGE_size
= sizeof(u32
) + ioc
->sg_addr_size
;
2146 printk(MYIOC_s_INFO_FMT
"pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
2147 ioc
->name
, (mpt_GetIocState(ioc
, 1) >> MPI_IOC_STATE_SHIFT
),
2148 CHIPREG_READ32(&ioc
->chip
->Doorbell
));
2151 * Errata workaround for SAS pci express:
2152 * Upon returning to the D0 state, the contents of the doorbell will be
2153 * stale data, and this will incorrectly signal to the host driver that
2154 * the firmware is ready to process mpt commands. The workaround is
2155 * to issue a diagnostic reset.
2157 if (ioc
->bus_type
== SAS
&& (pdev
->device
==
2158 MPI_MANUFACTPAGE_DEVID_SAS1068E
|| pdev
->device
==
2159 MPI_MANUFACTPAGE_DEVID_SAS1064E
)) {
2160 if (KickStart(ioc
, 1, CAN_SLEEP
) < 0) {
2161 printk(MYIOC_s_WARN_FMT
"pci-resume: Cannot recover\n",
2167 /* bring ioc to operational state */
2168 printk(MYIOC_s_INFO_FMT
"Sending mpt_do_ioc_recovery\n", ioc
->name
);
2169 recovery_state
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_BRINGUP
,
2171 if (recovery_state
!= 0)
2172 printk(MYIOC_s_WARN_FMT
"pci-resume: Cannot recover, "
2173 "error:[%x]\n", ioc
->name
, recovery_state
);
2175 printk(MYIOC_s_INFO_FMT
2176 "pci-resume: success\n", ioc
->name
);
2184 mpt_signal_reset(u8 index
, MPT_ADAPTER
*ioc
, int reset_phase
)
2186 if ((MptDriverClass
[index
] == MPTSPI_DRIVER
&&
2187 ioc
->bus_type
!= SPI
) ||
2188 (MptDriverClass
[index
] == MPTFC_DRIVER
&&
2189 ioc
->bus_type
!= FC
) ||
2190 (MptDriverClass
[index
] == MPTSAS_DRIVER
&&
2191 ioc
->bus_type
!= SAS
))
2192 /* make sure we only call the relevant reset handler
2195 return (MptResetHandlers
[index
])(ioc
, reset_phase
);
2198 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2200 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
2201 * @ioc: Pointer to MPT adapter structure
2202 * @reason: Event word / reason
2203 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
2205 * This routine performs all the steps necessary to bring the IOC
2206 * to a OPERATIONAL state.
2208 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
2213 * -1 if failed to get board READY
2214 * -2 if READY but IOCFacts Failed
2215 * -3 if READY but PrimeIOCFifos Failed
2216 * -4 if READY but IOCInit Failed
2217 * -5 if failed to enable_device and/or request_selected_regions
2218 * -6 if failed to upload firmware
2221 mpt_do_ioc_recovery(MPT_ADAPTER
*ioc
, u32 reason
, int sleepFlag
)
2223 int hard_reset_done
= 0;
2224 int alt_ioc_ready
= 0;
2229 int reset_alt_ioc_active
= 0;
2230 int irq_allocated
= 0;
2233 printk(MYIOC_s_INFO_FMT
"Initiating %s\n", ioc
->name
,
2234 reason
== MPT_HOSTEVENT_IOC_BRINGUP
? "bringup" : "recovery");
2236 /* Disable reply interrupts (also blocks FreeQ) */
2237 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2241 if (ioc
->alt_ioc
->active
||
2242 reason
== MPT_HOSTEVENT_IOC_RECOVER
) {
2243 reset_alt_ioc_active
= 1;
2244 /* Disable alt-IOC's reply interrupts
2245 * (and FreeQ) for a bit
2247 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
,
2249 ioc
->alt_ioc
->active
= 0;
2254 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)
2257 if ((hard_reset_done
= MakeIocReady(ioc
, hard
, sleepFlag
)) < 0) {
2258 if (hard_reset_done
== -4) {
2259 printk(MYIOC_s_WARN_FMT
"Owned by PEER..skipping!\n",
2262 if (reset_alt_ioc_active
&& ioc
->alt_ioc
) {
2263 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
2264 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
2265 "alt_ioc reply irq re-enabled\n", ioc
->alt_ioc
->name
));
2266 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
, MPI_HIM_DIM
);
2267 ioc
->alt_ioc
->active
= 1;
2271 printk(MYIOC_s_WARN_FMT
2272 "NOT READY WARNING!\n", ioc
->name
);
2278 /* hard_reset_done = 0 if a soft reset was performed
2279 * and 1 if a hard reset was performed.
2281 if (hard_reset_done
&& reset_alt_ioc_active
&& ioc
->alt_ioc
) {
2282 if ((rc
= MakeIocReady(ioc
->alt_ioc
, 0, sleepFlag
)) == 0)
2285 printk(MYIOC_s_WARN_FMT
2286 ": alt-ioc Not ready WARNING!\n",
2287 ioc
->alt_ioc
->name
);
2290 for (ii
=0; ii
<5; ii
++) {
2291 /* Get IOC facts! Allow 5 retries */
2292 if ((rc
= GetIocFacts(ioc
, sleepFlag
, reason
)) == 0)
2298 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2299 "Retry IocFacts failed rc=%x\n", ioc
->name
, rc
));
2301 } else if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
2302 MptDisplayIocCapabilities(ioc
);
2305 if (alt_ioc_ready
) {
2306 if ((rc
= GetIocFacts(ioc
->alt_ioc
, sleepFlag
, reason
)) != 0) {
2307 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2308 "Initial Alt IocFacts failed rc=%x\n",
2310 /* Retry - alt IOC was initialized once
2312 rc
= GetIocFacts(ioc
->alt_ioc
, sleepFlag
, reason
);
2315 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2316 "Retry Alt IocFacts failed rc=%x\n", ioc
->name
, rc
));
2318 reset_alt_ioc_active
= 0;
2319 } else if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
2320 MptDisplayIocCapabilities(ioc
->alt_ioc
);
2324 if ((ret
== 0) && (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) &&
2325 (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)) {
2326 pci_release_selected_regions(ioc
->pcidev
, ioc
->bars
);
2327 ioc
->bars
= pci_select_bars(ioc
->pcidev
, IORESOURCE_MEM
|
2329 if (pci_enable_device(ioc
->pcidev
))
2331 if (pci_request_selected_regions(ioc
->pcidev
, ioc
->bars
,
2337 * Device is reset now. It must have de-asserted the interrupt line
2338 * (if it was asserted) and it should be safe to register for the
2341 if ((ret
== 0) && (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)) {
2343 if (ioc
->pcidev
->irq
) {
2344 if (ioc
->msi_enable
&& !pci_enable_msi(ioc
->pcidev
))
2345 printk(MYIOC_s_INFO_FMT
"PCI-MSI enabled\n",
2348 ioc
->msi_enable
= 0;
2349 rc
= request_irq(ioc
->pcidev
->irq
, mpt_interrupt
,
2350 IRQF_SHARED
, ioc
->name
, ioc
);
2352 printk(MYIOC_s_ERR_FMT
"Unable to allocate "
2354 ioc
->name
, ioc
->pcidev
->irq
);
2355 if (ioc
->msi_enable
)
2356 pci_disable_msi(ioc
->pcidev
);
2361 ioc
->pci_irq
= ioc
->pcidev
->irq
;
2362 pci_set_master(ioc
->pcidev
); /* ?? */
2363 pci_set_drvdata(ioc
->pcidev
, ioc
);
2364 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
2365 "installed at interrupt %d\n", ioc
->name
,
2370 /* Prime reply & request queues!
2371 * (mucho alloc's) Must be done prior to
2372 * init as upper addresses are needed for init.
2373 * If fails, continue with alt-ioc processing
2375 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"PrimeIocFifos\n",
2377 if ((ret
== 0) && ((rc
= PrimeIocFifos(ioc
)) != 0))
2380 /* May need to check/upload firmware & data here!
2381 * If fails, continue with alt-ioc processing
2383 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"SendIocInit\n",
2385 if ((ret
== 0) && ((rc
= SendIocInit(ioc
, sleepFlag
)) != 0))
2388 if (alt_ioc_ready
&& ((rc
= PrimeIocFifos(ioc
->alt_ioc
)) != 0)) {
2389 printk(MYIOC_s_WARN_FMT
2390 ": alt-ioc (%d) FIFO mgmt alloc WARNING!\n",
2391 ioc
->alt_ioc
->name
, rc
);
2393 reset_alt_ioc_active
= 0;
2396 if (alt_ioc_ready
) {
2397 if ((rc
= SendIocInit(ioc
->alt_ioc
, sleepFlag
)) != 0) {
2399 reset_alt_ioc_active
= 0;
2400 printk(MYIOC_s_WARN_FMT
2401 ": alt-ioc: (%d) init failure WARNING!\n",
2402 ioc
->alt_ioc
->name
, rc
);
2406 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
){
2407 if (ioc
->upload_fw
) {
2408 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2409 "firmware upload required!\n", ioc
->name
));
2411 /* Controller is not operational, cannot do upload
2414 rc
= mpt_do_upload(ioc
, sleepFlag
);
2416 if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
) {
2418 * Maintain only one pointer to FW memory
2419 * so there will not be two attempt to
2420 * downloadboot onboard dual function
2421 * chips (mpt_adapter_disable,
2424 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2425 "mpt_upload: alt_%s has cached_fw=%p \n",
2426 ioc
->name
, ioc
->alt_ioc
->name
, ioc
->alt_ioc
->cached_fw
));
2427 ioc
->cached_fw
= NULL
;
2430 printk(MYIOC_s_WARN_FMT
2431 "firmware upload failure!\n", ioc
->name
);
2438 /* Enable MPT base driver management of EventNotification
2439 * and EventAck handling.
2441 if ((ret
== 0) && (!ioc
->facts
.EventState
)) {
2442 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
2443 "SendEventNotification\n",
2445 ret
= SendEventNotification(ioc
, 1, sleepFlag
); /* 1=Enable */
2448 if (ioc
->alt_ioc
&& alt_ioc_ready
&& !ioc
->alt_ioc
->facts
.EventState
)
2449 rc
= SendEventNotification(ioc
->alt_ioc
, 1, sleepFlag
);
2452 /* Enable! (reply interrupt) */
2453 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, MPI_HIM_DIM
);
2456 if (rc
== 0) { /* alt ioc */
2457 if (reset_alt_ioc_active
&& ioc
->alt_ioc
) {
2458 /* (re)Enable alt-IOC! (reply interrupt) */
2459 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"alt-ioc"
2460 "reply irq re-enabled\n",
2461 ioc
->alt_ioc
->name
));
2462 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
,
2464 ioc
->alt_ioc
->active
= 1;
2469 /* Add additional "reason" check before call to GetLanConfigPages
2470 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2471 * recursive scenario; GetLanConfigPages times out, timer expired
2472 * routine calls HardResetHandler, which calls into here again,
2473 * and we try GetLanConfigPages again...
2475 if ((ret
== 0) && (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)) {
2478 * Initalize link list for inactive raid volumes.
2480 mutex_init(&ioc
->raid_data
.inactive_list_mutex
);
2481 INIT_LIST_HEAD(&ioc
->raid_data
.inactive_list
);
2483 switch (ioc
->bus_type
) {
2486 /* clear persistency table */
2487 if(ioc
->facts
.IOCExceptions
&
2488 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL
) {
2489 ret
= mptbase_sas_persist_operation(ioc
,
2490 MPI_SAS_OP_CLEAR_NOT_PRESENT
);
2497 mpt_findImVolumes(ioc
);
2499 /* Check, and possibly reset, the coalescing value
2501 mpt_read_ioc_pg_1(ioc
);
2506 if ((ioc
->pfacts
[0].ProtocolFlags
&
2507 MPI_PORTFACTS_PROTOCOL_LAN
) &&
2508 (ioc
->lan_cnfg_page0
.Header
.PageLength
== 0)) {
2510 * Pre-fetch the ports LAN MAC address!
2511 * (LANPage1_t stuff)
2513 (void) GetLanConfigPages(ioc
);
2514 a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
2515 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2516 "LanAddr = %02X:%02X:%02X"
2517 ":%02X:%02X:%02X\n",
2518 ioc
->name
, a
[5], a
[4],
2519 a
[3], a
[2], a
[1], a
[0]));
2524 /* Get NVRAM and adapter maximums from SPP 0 and 2
2526 mpt_GetScsiPortSettings(ioc
, 0);
2528 /* Get version and length of SDP 1
2530 mpt_readScsiDevicePageHeaders(ioc
, 0);
2534 if (ioc
->facts
.MsgVersion
>= MPI_VERSION_01_02
)
2535 mpt_findImVolumes(ioc
);
2537 /* Check, and possibly reset, the coalescing value
2539 mpt_read_ioc_pg_1(ioc
);
2541 mpt_read_ioc_pg_4(ioc
);
2546 GetIoUnitPage2(ioc
);
2547 mpt_get_manufacturing_pg_0(ioc
);
2551 if ((ret
!= 0) && irq_allocated
) {
2552 free_irq(ioc
->pci_irq
, ioc
);
2553 if (ioc
->msi_enable
)
2554 pci_disable_msi(ioc
->pcidev
);
2559 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2561 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2562 * @ioc: Pointer to MPT adapter structure
2563 * @pdev: Pointer to (struct pci_dev) structure
2565 * Search for PCI bus/dev_function which matches
2566 * PCI bus/dev_function (+/-1) for newly discovered 929,
2567 * 929X, 1030 or 1035.
2569 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2570 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2573 mpt_detect_bound_ports(MPT_ADAPTER
*ioc
, struct pci_dev
*pdev
)
2575 struct pci_dev
*peer
=NULL
;
2576 unsigned int slot
= PCI_SLOT(pdev
->devfn
);
2577 unsigned int func
= PCI_FUNC(pdev
->devfn
);
2578 MPT_ADAPTER
*ioc_srch
;
2580 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"PCI device %s devfn=%x/%x,"
2581 " searching for devfn match on %x or %x\n",
2582 ioc
->name
, pci_name(pdev
), pdev
->bus
->number
,
2583 pdev
->devfn
, func
-1, func
+1));
2585 peer
= pci_get_slot(pdev
->bus
, PCI_DEVFN(slot
,func
-1));
2587 peer
= pci_get_slot(pdev
->bus
, PCI_DEVFN(slot
,func
+1));
2592 list_for_each_entry(ioc_srch
, &ioc_list
, list
) {
2593 struct pci_dev
*_pcidev
= ioc_srch
->pcidev
;
2594 if (_pcidev
== peer
) {
2595 /* Paranoia checks */
2596 if (ioc
->alt_ioc
!= NULL
) {
2597 printk(MYIOC_s_WARN_FMT
2598 "Oops, already bound (%s <==> %s)!\n",
2599 ioc
->name
, ioc
->name
, ioc
->alt_ioc
->name
);
2601 } else if (ioc_srch
->alt_ioc
!= NULL
) {
2602 printk(MYIOC_s_WARN_FMT
2603 "Oops, already bound (%s <==> %s)!\n",
2604 ioc_srch
->name
, ioc_srch
->name
,
2605 ioc_srch
->alt_ioc
->name
);
2608 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2609 "FOUND! binding %s <==> %s\n",
2610 ioc
->name
, ioc
->name
, ioc_srch
->name
));
2611 ioc_srch
->alt_ioc
= ioc
;
2612 ioc
->alt_ioc
= ioc_srch
;
2618 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2620 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2621 * @ioc: Pointer to MPT adapter structure
2624 mpt_adapter_disable(MPT_ADAPTER
*ioc
)
2629 if (ioc
->cached_fw
!= NULL
) {
2630 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2631 "%s: Pushing FW onto adapter\n", __func__
, ioc
->name
));
2632 if ((ret
= mpt_downloadboot(ioc
, (MpiFwHeader_t
*)
2633 ioc
->cached_fw
, CAN_SLEEP
)) < 0) {
2634 printk(MYIOC_s_WARN_FMT
2635 ": firmware downloadboot failure (%d)!\n",
2641 * Put the controller into ready state (if its not already)
2643 if (mpt_GetIocState(ioc
, 1) != MPI_IOC_STATE_READY
) {
2644 if (!SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
,
2646 if (mpt_GetIocState(ioc
, 1) != MPI_IOC_STATE_READY
)
2647 printk(MYIOC_s_ERR_FMT
"%s: IOC msg unit "
2648 "reset failed to put ioc in ready state!\n",
2649 ioc
->name
, __func__
);
2651 printk(MYIOC_s_ERR_FMT
"%s: IOC msg unit reset "
2652 "failed!\n", ioc
->name
, __func__
);
2656 /* Disable adapter interrupts! */
2657 synchronize_irq(ioc
->pcidev
->irq
);
2658 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2661 /* Clear any lingering interrupt */
2662 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
2663 CHIPREG_READ32(&ioc
->chip
->IntStatus
);
2665 if (ioc
->alloc
!= NULL
) {
2667 dexitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"free @ %p, sz=%d bytes\n",
2668 ioc
->name
, ioc
->alloc
, ioc
->alloc_sz
));
2669 pci_free_consistent(ioc
->pcidev
, sz
,
2670 ioc
->alloc
, ioc
->alloc_dma
);
2671 ioc
->reply_frames
= NULL
;
2672 ioc
->req_frames
= NULL
;
2674 ioc
->alloc_total
-= sz
;
2677 if (ioc
->sense_buf_pool
!= NULL
) {
2678 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
2679 pci_free_consistent(ioc
->pcidev
, sz
,
2680 ioc
->sense_buf_pool
, ioc
->sense_buf_pool_dma
);
2681 ioc
->sense_buf_pool
= NULL
;
2682 ioc
->alloc_total
-= sz
;
2685 if (ioc
->events
!= NULL
){
2686 sz
= MPTCTL_EVENT_LOG_SIZE
* sizeof(MPT_IOCTL_EVENTS
);
2689 ioc
->alloc_total
-= sz
;
2692 mpt_free_fw_memory(ioc
);
2694 kfree(ioc
->spi_data
.nvram
);
2695 mpt_inactive_raid_list_free(ioc
);
2696 kfree(ioc
->raid_data
.pIocPg2
);
2697 kfree(ioc
->raid_data
.pIocPg3
);
2698 ioc
->spi_data
.nvram
= NULL
;
2699 ioc
->raid_data
.pIocPg3
= NULL
;
2701 if (ioc
->spi_data
.pIocPg4
!= NULL
) {
2702 sz
= ioc
->spi_data
.IocPg4Sz
;
2703 pci_free_consistent(ioc
->pcidev
, sz
,
2704 ioc
->spi_data
.pIocPg4
,
2705 ioc
->spi_data
.IocPg4_dma
);
2706 ioc
->spi_data
.pIocPg4
= NULL
;
2707 ioc
->alloc_total
-= sz
;
2710 if (ioc
->ReqToChain
!= NULL
) {
2711 kfree(ioc
->ReqToChain
);
2712 kfree(ioc
->RequestNB
);
2713 ioc
->ReqToChain
= NULL
;
2716 kfree(ioc
->ChainToChain
);
2717 ioc
->ChainToChain
= NULL
;
2719 if (ioc
->HostPageBuffer
!= NULL
) {
2720 if((ret
= mpt_host_page_access_control(ioc
,
2721 MPI_DB_HPBAC_FREE_BUFFER
, NO_SLEEP
)) != 0) {
2722 printk(MYIOC_s_ERR_FMT
2723 ": %s: host page buffers free failed (%d)!\n",
2724 ioc
->name
, __func__
, ret
);
2726 dexitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2727 "HostPageBuffer free @ %p, sz=%d bytes\n",
2728 ioc
->name
, ioc
->HostPageBuffer
,
2729 ioc
->HostPageBuffer_sz
));
2730 pci_free_consistent(ioc
->pcidev
, ioc
->HostPageBuffer_sz
,
2731 ioc
->HostPageBuffer
, ioc
->HostPageBuffer_dma
);
2732 ioc
->HostPageBuffer
= NULL
;
2733 ioc
->HostPageBuffer_sz
= 0;
2734 ioc
->alloc_total
-= ioc
->HostPageBuffer_sz
;
2737 pci_set_drvdata(ioc
->pcidev
, NULL
);
2739 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2741 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2742 * @ioc: Pointer to MPT adapter structure
2744 * This routine unregisters h/w resources and frees all alloc'd memory
2745 * associated with a MPT adapter structure.
2748 mpt_adapter_dispose(MPT_ADAPTER
*ioc
)
2750 int sz_first
, sz_last
;
2755 sz_first
= ioc
->alloc_total
;
2757 mpt_adapter_disable(ioc
);
2759 if (ioc
->pci_irq
!= -1) {
2760 free_irq(ioc
->pci_irq
, ioc
);
2761 if (ioc
->msi_enable
)
2762 pci_disable_msi(ioc
->pcidev
);
2766 if (ioc
->memmap
!= NULL
) {
2767 iounmap(ioc
->memmap
);
2771 pci_disable_device(ioc
->pcidev
);
2772 pci_release_selected_regions(ioc
->pcidev
, ioc
->bars
);
2774 #if defined(CONFIG_MTRR) && 0
2775 if (ioc
->mtrr_reg
> 0) {
2776 mtrr_del(ioc
->mtrr_reg
, 0, 0);
2777 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
"MTRR region de-registered\n", ioc
->name
));
2781 /* Zap the adapter lookup ptr! */
2782 list_del(&ioc
->list
);
2784 sz_last
= ioc
->alloc_total
;
2785 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
"free'd %d of %d bytes\n",
2786 ioc
->name
, sz_first
-sz_last
+(int)sizeof(*ioc
), sz_first
));
2789 ioc
->alt_ioc
->alt_ioc
= NULL
;
2794 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2796 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2797 * @ioc: Pointer to MPT adapter structure
2800 MptDisplayIocCapabilities(MPT_ADAPTER
*ioc
)
2804 printk(KERN_INFO
"%s: ", ioc
->name
);
2806 printk("%s: ", ioc
->prod_name
);
2807 printk("Capabilities={");
2809 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_INITIATOR
) {
2810 printk("Initiator");
2814 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_TARGET
) {
2815 printk("%sTarget", i
? "," : "");
2819 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
) {
2820 printk("%sLAN", i
? "," : "");
2826 * This would probably evoke more questions than it's worth
2828 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_TARGET
) {
2829 printk("%sLogBusAddr", i
? "," : "");
2837 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2839 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2840 * @ioc: Pointer to MPT_ADAPTER structure
2841 * @force: Force hard KickStart of IOC
2842 * @sleepFlag: Specifies whether the process can sleep
2845 * 1 - DIAG reset and READY
2846 * 0 - READY initially OR soft reset and READY
2847 * -1 - Any failure on KickStart
2848 * -2 - Msg Unit Reset Failed
2849 * -3 - IO Unit Reset Failed
2850 * -4 - IOC owned by a PEER
2853 MakeIocReady(MPT_ADAPTER
*ioc
, int force
, int sleepFlag
)
2858 int hard_reset_done
= 0;
2863 /* Get current [raw] IOC state */
2864 ioc_state
= mpt_GetIocState(ioc
, 0);
2865 dhsprintk(ioc
, printk(MYIOC_s_INFO_FMT
"MakeIocReady [raw] state=%08x\n", ioc
->name
, ioc_state
));
2868 * Check to see if IOC got left/stuck in doorbell handshake
2869 * grip of death. If so, hard reset the IOC.
2871 if (ioc_state
& MPI_DOORBELL_ACTIVE
) {
2873 printk(MYIOC_s_WARN_FMT
"Unexpected doorbell active!\n",
2877 /* Is it already READY? */
2879 ((ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_READY
)) {
2880 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
2881 "IOC is in READY state\n", ioc
->name
));
2886 * Check to see if IOC is in FAULT state.
2888 if ((ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_FAULT
) {
2890 printk(MYIOC_s_WARN_FMT
"IOC is in FAULT state!!!\n",
2892 printk(MYIOC_s_WARN_FMT
" FAULT code = %04xh\n",
2893 ioc
->name
, ioc_state
& MPI_DOORBELL_DATA_MASK
);
2897 * Hmmm... Did it get left operational?
2899 if ((ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_OPERATIONAL
) {
2900 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"IOC operational unexpected\n",
2904 * If PCI Peer, exit.
2905 * Else, if no fault conditions are present, issue a MessageUnitReset
2906 * Else, fall through to KickStart case
2908 whoinit
= (ioc_state
& MPI_DOORBELL_WHO_INIT_MASK
) >> MPI_DOORBELL_WHO_INIT_SHIFT
;
2909 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
2910 "whoinit 0x%x statefault %d force %d\n",
2911 ioc
->name
, whoinit
, statefault
, force
));
2912 if (whoinit
== MPI_WHOINIT_PCI_PEER
)
2915 if ((statefault
== 0 ) && (force
== 0)) {
2916 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
)) == 0)
2923 hard_reset_done
= KickStart(ioc
, statefault
||force
, sleepFlag
);
2924 if (hard_reset_done
< 0)
2928 * Loop here waiting for IOC to come READY.
2931 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 5; /* 5 seconds */
2933 while ((ioc_state
= mpt_GetIocState(ioc
, 1)) != MPI_IOC_STATE_READY
) {
2934 if (ioc_state
== MPI_IOC_STATE_OPERATIONAL
) {
2936 * BIOS or previous driver load left IOC in OP state.
2937 * Reset messaging FIFOs.
2939 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
)) != 0) {
2940 printk(MYIOC_s_ERR_FMT
"IOC msg unit reset failed!\n", ioc
->name
);
2943 } else if (ioc_state
== MPI_IOC_STATE_RESET
) {
2945 * Something is wrong. Try to get IOC back
2948 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IO_UNIT_RESET
, sleepFlag
)) != 0) {
2949 printk(MYIOC_s_ERR_FMT
"IO unit reset failed!\n", ioc
->name
);
2956 printk(MYIOC_s_ERR_FMT
2957 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
2958 ioc
->name
, ioc_state
, (int)((ii
+5)/HZ
));
2962 if (sleepFlag
== CAN_SLEEP
) {
2965 mdelay (1); /* 1 msec delay */
2970 if (statefault
< 3) {
2971 printk(MYIOC_s_INFO_FMT
"Recovered from %s\n", ioc
->name
,
2972 statefault
== 1 ? "stuck handshake" : "IOC FAULT");
2975 return hard_reset_done
;
2978 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2980 * mpt_GetIocState - Get the current state of a MPT adapter.
2981 * @ioc: Pointer to MPT_ADAPTER structure
2982 * @cooked: Request raw or cooked IOC state
2984 * Returns all IOC Doorbell register bits if cooked==0, else just the
2985 * Doorbell bits in MPI_IOC_STATE_MASK.
2988 mpt_GetIocState(MPT_ADAPTER
*ioc
, int cooked
)
2993 s
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
2994 sc
= s
& MPI_IOC_STATE_MASK
;
2997 ioc
->last_state
= sc
;
2999 return cooked
? sc
: s
;
3002 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3004 * GetIocFacts - Send IOCFacts request to MPT adapter.
3005 * @ioc: Pointer to MPT_ADAPTER structure
3006 * @sleepFlag: Specifies whether the process can sleep
3007 * @reason: If recovery, only update facts.
3009 * Returns 0 for success, non-zero for failure.
3012 GetIocFacts(MPT_ADAPTER
*ioc
, int sleepFlag
, int reason
)
3014 IOCFacts_t get_facts
;
3015 IOCFactsReply_t
*facts
;
3023 /* IOC *must* NOT be in RESET state! */
3024 if (ioc
->last_state
== MPI_IOC_STATE_RESET
) {
3025 printk(KERN_ERR MYNAM
3026 ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
3027 ioc
->name
, ioc
->last_state
);
3031 facts
= &ioc
->facts
;
3033 /* Destination (reply area)... */
3034 reply_sz
= sizeof(*facts
);
3035 memset(facts
, 0, reply_sz
);
3037 /* Request area (get_facts on the stack right now!) */
3038 req_sz
= sizeof(get_facts
);
3039 memset(&get_facts
, 0, req_sz
);
3041 get_facts
.Function
= MPI_FUNCTION_IOC_FACTS
;
3042 /* Assert: All other get_facts fields are zero! */
3044 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3045 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
3046 ioc
->name
, req_sz
, reply_sz
));
3048 /* No non-zero fields in the get_facts request are greater than
3049 * 1 byte in size, so we can just fire it off as is.
3051 r
= mpt_handshake_req_reply_wait(ioc
, req_sz
, (u32
*)&get_facts
,
3052 reply_sz
, (u16
*)facts
, 5 /*seconds*/, sleepFlag
);
3057 * Now byte swap (GRRR) the necessary fields before any further
3058 * inspection of reply contents.
3060 * But need to do some sanity checks on MsgLength (byte) field
3061 * to make sure we don't zero IOC's req_sz!
3063 /* Did we get a valid reply? */
3064 if (facts
->MsgLength
> offsetof(IOCFactsReply_t
, RequestFrameSize
)/sizeof(u32
)) {
3065 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
3067 * If not been here, done that, save off first WhoInit value
3069 if (ioc
->FirstWhoInit
== WHOINIT_UNKNOWN
)
3070 ioc
->FirstWhoInit
= facts
->WhoInit
;
3073 facts
->MsgVersion
= le16_to_cpu(facts
->MsgVersion
);
3074 facts
->MsgContext
= le32_to_cpu(facts
->MsgContext
);
3075 facts
->IOCExceptions
= le16_to_cpu(facts
->IOCExceptions
);
3076 facts
->IOCStatus
= le16_to_cpu(facts
->IOCStatus
);
3077 facts
->IOCLogInfo
= le32_to_cpu(facts
->IOCLogInfo
);
3078 status
= le16_to_cpu(facts
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
3079 /* CHECKME! IOCStatus, IOCLogInfo */
3081 facts
->ReplyQueueDepth
= le16_to_cpu(facts
->ReplyQueueDepth
);
3082 facts
->RequestFrameSize
= le16_to_cpu(facts
->RequestFrameSize
);
3085 * FC f/w version changed between 1.1 and 1.2
3086 * Old: u16{Major(4),Minor(4),SubMinor(8)}
3087 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
3089 if (facts
->MsgVersion
< MPI_VERSION_01_02
) {
3091 * Handle old FC f/w style, convert to new...
3093 u16 oldv
= le16_to_cpu(facts
->Reserved_0101_FWVersion
);
3094 facts
->FWVersion
.Word
=
3095 ((oldv
<<12) & 0xFF000000) |
3096 ((oldv
<<8) & 0x000FFF00);
3098 facts
->FWVersion
.Word
= le32_to_cpu(facts
->FWVersion
.Word
);
3100 facts
->ProductID
= le16_to_cpu(facts
->ProductID
);
3102 if ((ioc
->facts
.ProductID
& MPI_FW_HEADER_PID_PROD_MASK
)
3103 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI
)
3104 ioc
->ir_firmware
= 1;
3106 facts
->CurrentHostMfaHighAddr
=
3107 le32_to_cpu(facts
->CurrentHostMfaHighAddr
);
3108 facts
->GlobalCredits
= le16_to_cpu(facts
->GlobalCredits
);
3109 facts
->CurrentSenseBufferHighAddr
=
3110 le32_to_cpu(facts
->CurrentSenseBufferHighAddr
);
3111 facts
->CurReplyFrameSize
=
3112 le16_to_cpu(facts
->CurReplyFrameSize
);
3113 facts
->IOCCapabilities
= le32_to_cpu(facts
->IOCCapabilities
);
3116 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
3117 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
3118 * to 14 in MPI-1.01.0x.
3120 if (facts
->MsgLength
>= (offsetof(IOCFactsReply_t
,FWImageSize
) + 7)/4 &&
3121 facts
->MsgVersion
> MPI_VERSION_01_00
) {
3122 facts
->FWImageSize
= le32_to_cpu(facts
->FWImageSize
);
3125 sz
= facts
->FWImageSize
;
3130 facts
->FWImageSize
= sz
;
3132 if (!facts
->RequestFrameSize
) {
3133 /* Something is wrong! */
3134 printk(MYIOC_s_ERR_FMT
"IOC reported invalid 0 request size!\n",
3139 r
= sz
= facts
->BlockSize
;
3140 vv
= ((63 / (sz
* 4)) + 1) & 0x03;
3141 ioc
->NB_for_64_byte_frame
= vv
;
3147 ioc
->NBShiftFactor
= shiftFactor
;
3148 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3149 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
3150 ioc
->name
, vv
, shiftFactor
, r
));
3152 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
3154 * Set values for this IOC's request & reply frame sizes,
3155 * and request & reply queue depths...
3157 ioc
->req_sz
= min(MPT_DEFAULT_FRAME_SIZE
, facts
->RequestFrameSize
* 4);
3158 ioc
->req_depth
= min_t(int, MPT_MAX_REQ_DEPTH
, facts
->GlobalCredits
);
3159 ioc
->reply_sz
= MPT_REPLY_FRAME_SIZE
;
3160 ioc
->reply_depth
= min_t(int, MPT_DEFAULT_REPLY_DEPTH
, facts
->ReplyQueueDepth
);
3162 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"reply_sz=%3d, reply_depth=%4d\n",
3163 ioc
->name
, ioc
->reply_sz
, ioc
->reply_depth
));
3164 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"req_sz =%3d, req_depth =%4d\n",
3165 ioc
->name
, ioc
->req_sz
, ioc
->req_depth
));
3167 /* Get port facts! */
3168 if ( (r
= GetPortFacts(ioc
, 0, sleepFlag
)) != 0 )
3172 printk(MYIOC_s_ERR_FMT
3173 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
3174 ioc
->name
, facts
->MsgLength
, (offsetof(IOCFactsReply_t
,
3175 RequestFrameSize
)/sizeof(u32
)));
3182 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3184 * GetPortFacts - Send PortFacts request to MPT adapter.
3185 * @ioc: Pointer to MPT_ADAPTER structure
3186 * @portnum: Port number
3187 * @sleepFlag: Specifies whether the process can sleep
3189 * Returns 0 for success, non-zero for failure.
3192 GetPortFacts(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
)
3194 PortFacts_t get_pfacts
;
3195 PortFactsReply_t
*pfacts
;
3201 /* IOC *must* NOT be in RESET state! */
3202 if (ioc
->last_state
== MPI_IOC_STATE_RESET
) {
3203 printk(MYIOC_s_ERR_FMT
"Can't get PortFacts NOT READY! (%08x)\n",
3204 ioc
->name
, ioc
->last_state
);
3208 pfacts
= &ioc
->pfacts
[portnum
];
3210 /* Destination (reply area)... */
3211 reply_sz
= sizeof(*pfacts
);
3212 memset(pfacts
, 0, reply_sz
);
3214 /* Request area (get_pfacts on the stack right now!) */
3215 req_sz
= sizeof(get_pfacts
);
3216 memset(&get_pfacts
, 0, req_sz
);
3218 get_pfacts
.Function
= MPI_FUNCTION_PORT_FACTS
;
3219 get_pfacts
.PortNumber
= portnum
;
3220 /* Assert: All other get_pfacts fields are zero! */
3222 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending get PortFacts(%d) request\n",
3223 ioc
->name
, portnum
));
3225 /* No non-zero fields in the get_pfacts request are greater than
3226 * 1 byte in size, so we can just fire it off as is.
3228 ii
= mpt_handshake_req_reply_wait(ioc
, req_sz
, (u32
*)&get_pfacts
,
3229 reply_sz
, (u16
*)pfacts
, 5 /*seconds*/, sleepFlag
);
3233 /* Did we get a valid reply? */
3235 /* Now byte swap the necessary fields in the response. */
3236 pfacts
->MsgContext
= le32_to_cpu(pfacts
->MsgContext
);
3237 pfacts
->IOCStatus
= le16_to_cpu(pfacts
->IOCStatus
);
3238 pfacts
->IOCLogInfo
= le32_to_cpu(pfacts
->IOCLogInfo
);
3239 pfacts
->MaxDevices
= le16_to_cpu(pfacts
->MaxDevices
);
3240 pfacts
->PortSCSIID
= le16_to_cpu(pfacts
->PortSCSIID
);
3241 pfacts
->ProtocolFlags
= le16_to_cpu(pfacts
->ProtocolFlags
);
3242 pfacts
->MaxPostedCmdBuffers
= le16_to_cpu(pfacts
->MaxPostedCmdBuffers
);
3243 pfacts
->MaxPersistentIDs
= le16_to_cpu(pfacts
->MaxPersistentIDs
);
3244 pfacts
->MaxLanBuckets
= le16_to_cpu(pfacts
->MaxLanBuckets
);
3246 max_id
= (ioc
->bus_type
== SAS
) ? pfacts
->PortSCSIID
:
3248 ioc
->devices_per_bus
= (max_id
> 255) ? 256 : max_id
;
3249 ioc
->number_of_buses
= (ioc
->devices_per_bus
< 256) ? 1 : max_id
/256;
3252 * Place all the devices on channels
3256 if (mpt_channel_mapping
) {
3257 ioc
->devices_per_bus
= 1;
3258 ioc
->number_of_buses
= (max_id
> 255) ? 255 : max_id
;
3264 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3266 * SendIocInit - Send IOCInit request to MPT adapter.
3267 * @ioc: Pointer to MPT_ADAPTER structure
3268 * @sleepFlag: Specifies whether the process can sleep
3270 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
3272 * Returns 0 for success, non-zero for failure.
3275 SendIocInit(MPT_ADAPTER
*ioc
, int sleepFlag
)
3278 MPIDefaultReply_t init_reply
;
3284 memset(&ioc_init
, 0, sizeof(ioc_init
));
3285 memset(&init_reply
, 0, sizeof(init_reply
));
3287 ioc_init
.WhoInit
= MPI_WHOINIT_HOST_DRIVER
;
3288 ioc_init
.Function
= MPI_FUNCTION_IOC_INIT
;
3290 /* If we are in a recovery mode and we uploaded the FW image,
3291 * then this pointer is not NULL. Skip the upload a second time.
3292 * Set this flag if cached_fw set for either IOC.
3294 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)
3298 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"upload_fw %d facts.Flags=%x\n",
3299 ioc
->name
, ioc
->upload_fw
, ioc
->facts
.Flags
));
3301 ioc_init
.MaxDevices
= (U8
)ioc
->devices_per_bus
;
3302 ioc_init
.MaxBuses
= (U8
)ioc
->number_of_buses
;
3304 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"facts.MsgVersion=%x\n",
3305 ioc
->name
, ioc
->facts
.MsgVersion
));
3306 if (ioc
->facts
.MsgVersion
>= MPI_VERSION_01_05
) {
3307 // set MsgVersion and HeaderVersion host driver was built with
3308 ioc_init
.MsgVersion
= cpu_to_le16(MPI_VERSION
);
3309 ioc_init
.HeaderVersion
= cpu_to_le16(MPI_HEADER_VERSION
);
3311 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT
) {
3312 ioc_init
.HostPageBufferSGE
= ioc
->facts
.HostPageBufferSGE
;
3313 } else if(mpt_host_page_alloc(ioc
, &ioc_init
))
3316 ioc_init
.ReplyFrameSize
= cpu_to_le16(ioc
->reply_sz
); /* in BYTES */
3318 if (ioc
->sg_addr_size
== sizeof(u64
)) {
3319 /* Save the upper 32-bits of the request
3320 * (reply) and sense buffers.
3322 ioc_init
.HostMfaHighAddr
= cpu_to_le32((u32
)((u64
)ioc
->alloc_dma
>> 32));
3323 ioc_init
.SenseBufferHighAddr
= cpu_to_le32((u32
)((u64
)ioc
->sense_buf_pool_dma
>> 32));
3325 /* Force 32-bit addressing */
3326 ioc_init
.HostMfaHighAddr
= cpu_to_le32(0);
3327 ioc_init
.SenseBufferHighAddr
= cpu_to_le32(0);
3330 ioc
->facts
.CurrentHostMfaHighAddr
= ioc_init
.HostMfaHighAddr
;
3331 ioc
->facts
.CurrentSenseBufferHighAddr
= ioc_init
.SenseBufferHighAddr
;
3332 ioc
->facts
.MaxDevices
= ioc_init
.MaxDevices
;
3333 ioc
->facts
.MaxBuses
= ioc_init
.MaxBuses
;
3335 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending IOCInit (req @ %p)\n",
3336 ioc
->name
, &ioc_init
));
3338 r
= mpt_handshake_req_reply_wait(ioc
, sizeof(IOCInit_t
), (u32
*)&ioc_init
,
3339 sizeof(MPIDefaultReply_t
), (u16
*)&init_reply
, 10 /*seconds*/, sleepFlag
);
3341 printk(MYIOC_s_ERR_FMT
"Sending IOCInit failed(%d)!\n",ioc
->name
, r
);
3345 /* No need to byte swap the multibyte fields in the reply
3346 * since we don't even look at its contents.
3349 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending PortEnable (req @ %p)\n",
3350 ioc
->name
, &ioc_init
));
3352 if ((r
= SendPortEnable(ioc
, 0, sleepFlag
)) != 0) {
3353 printk(MYIOC_s_ERR_FMT
"Sending PortEnable failed(%d)!\n",ioc
->name
, r
);
3357 /* YIKES! SUPER IMPORTANT!!!
3358 * Poll IocState until _OPERATIONAL while IOC is doing
3359 * LoopInit and TargetDiscovery!
3362 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 60; /* 60 seconds */
3363 state
= mpt_GetIocState(ioc
, 1);
3364 while (state
!= MPI_IOC_STATE_OPERATIONAL
&& --cntdn
) {
3365 if (sleepFlag
== CAN_SLEEP
) {
3372 printk(MYIOC_s_ERR_FMT
"Wait IOC_OP state timeout(%d)!\n",
3373 ioc
->name
, (int)((count
+5)/HZ
));
3377 state
= mpt_GetIocState(ioc
, 1);
3380 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Wait IOC_OPERATIONAL state (cnt=%d)\n",
3383 ioc
->aen_event_read_flag
=0;
3387 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3389 * SendPortEnable - Send PortEnable request to MPT adapter port.
3390 * @ioc: Pointer to MPT_ADAPTER structure
3391 * @portnum: Port number to enable
3392 * @sleepFlag: Specifies whether the process can sleep
3394 * Send PortEnable to bring IOC to OPERATIONAL state.
3396 * Returns 0 for success, non-zero for failure.
3399 SendPortEnable(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
)
3401 PortEnable_t port_enable
;
3402 MPIDefaultReply_t reply_buf
;
3407 /* Destination... */
3408 reply_sz
= sizeof(MPIDefaultReply_t
);
3409 memset(&reply_buf
, 0, reply_sz
);
3411 req_sz
= sizeof(PortEnable_t
);
3412 memset(&port_enable
, 0, req_sz
);
3414 port_enable
.Function
= MPI_FUNCTION_PORT_ENABLE
;
3415 port_enable
.PortNumber
= portnum
;
3416 /* port_enable.ChainOffset = 0; */
3417 /* port_enable.MsgFlags = 0; */
3418 /* port_enable.MsgContext = 0; */
3420 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending Port(%d)Enable (req @ %p)\n",
3421 ioc
->name
, portnum
, &port_enable
));
3423 /* RAID FW may take a long time to enable
3425 if (ioc
->ir_firmware
|| ioc
->bus_type
== SAS
) {
3426 rc
= mpt_handshake_req_reply_wait(ioc
, req_sz
,
3427 (u32
*)&port_enable
, reply_sz
, (u16
*)&reply_buf
,
3428 300 /*seconds*/, sleepFlag
);
3430 rc
= mpt_handshake_req_reply_wait(ioc
, req_sz
,
3431 (u32
*)&port_enable
, reply_sz
, (u16
*)&reply_buf
,
3432 30 /*seconds*/, sleepFlag
);
3438 * mpt_alloc_fw_memory - allocate firmware memory
3439 * @ioc: Pointer to MPT_ADAPTER structure
3440 * @size: total FW bytes
3442 * If memory has already been allocated, the same (cached) value
3445 * Return 0 if successfull, or non-zero for failure
3448 mpt_alloc_fw_memory(MPT_ADAPTER
*ioc
, int size
)
3452 if (ioc
->cached_fw
) {
3453 rc
= 0; /* use already allocated memory */
3456 else if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
) {
3457 ioc
->cached_fw
= ioc
->alt_ioc
->cached_fw
; /* use alt_ioc's memory */
3458 ioc
->cached_fw_dma
= ioc
->alt_ioc
->cached_fw_dma
;
3462 ioc
->cached_fw
= pci_alloc_consistent(ioc
->pcidev
, size
, &ioc
->cached_fw_dma
);
3463 if (!ioc
->cached_fw
) {
3464 printk(MYIOC_s_ERR_FMT
"Unable to allocate memory for the cached firmware image!\n",
3468 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"FW Image @ %p[%p], sz=%d[%x] bytes\n",
3469 ioc
->name
, ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, size
, size
));
3470 ioc
->alloc_total
+= size
;
3478 * mpt_free_fw_memory - free firmware memory
3479 * @ioc: Pointer to MPT_ADAPTER structure
3481 * If alt_img is NULL, delete from ioc structure.
3482 * Else, delete a secondary image in same format.
3485 mpt_free_fw_memory(MPT_ADAPTER
*ioc
)
3489 if (!ioc
->cached_fw
)
3492 sz
= ioc
->facts
.FWImageSize
;
3493 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3494 ioc
->name
, ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, sz
, sz
));
3495 pci_free_consistent(ioc
->pcidev
, sz
, ioc
->cached_fw
, ioc
->cached_fw_dma
);
3496 ioc
->alloc_total
-= sz
;
3497 ioc
->cached_fw
= NULL
;
3500 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3502 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3503 * @ioc: Pointer to MPT_ADAPTER structure
3504 * @sleepFlag: Specifies whether the process can sleep
3506 * Returns 0 for success, >0 for handshake failure
3507 * <0 for fw upload failure.
3509 * Remark: If bound IOC and a successful FWUpload was performed
3510 * on the bound IOC, the second image is discarded
3511 * and memory is free'd. Both channels must upload to prevent
3512 * IOC from running in degraded mode.
3515 mpt_do_upload(MPT_ADAPTER
*ioc
, int sleepFlag
)
3517 u8 reply
[sizeof(FWUploadReply_t
)];
3518 FWUpload_t
*prequest
;
3519 FWUploadReply_t
*preply
;
3520 FWUploadTCSGE_t
*ptcsge
;
3522 int ii
, sz
, reply_sz
;
3525 /* If the image size is 0, we are done.
3527 if ((sz
= ioc
->facts
.FWImageSize
) == 0)
3530 if (mpt_alloc_fw_memory(ioc
, ioc
->facts
.FWImageSize
) != 0)
3533 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3534 ioc
->name
, ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, sz
, sz
));
3536 prequest
= (sleepFlag
== NO_SLEEP
) ? kzalloc(ioc
->req_sz
, GFP_ATOMIC
) :
3537 kzalloc(ioc
->req_sz
, GFP_KERNEL
);
3539 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"fw upload failed "
3540 "while allocating memory \n", ioc
->name
));
3541 mpt_free_fw_memory(ioc
);
3545 preply
= (FWUploadReply_t
*)&reply
;
3547 reply_sz
= sizeof(reply
);
3548 memset(preply
, 0, reply_sz
);
3550 prequest
->ImageType
= MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM
;
3551 prequest
->Function
= MPI_FUNCTION_FW_UPLOAD
;
3553 ptcsge
= (FWUploadTCSGE_t
*) &prequest
->SGL
;
3554 ptcsge
->DetailsLength
= 12;
3555 ptcsge
->Flags
= MPI_SGE_FLAGS_TRANSACTION_ELEMENT
;
3556 ptcsge
->ImageSize
= cpu_to_le32(sz
);
3559 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_READ
| sz
;
3560 ioc
->add_sge((char *)ptcsge
, flagsLength
, ioc
->cached_fw_dma
);
3561 request_size
= offsetof(FWUpload_t
, SGL
) + sizeof(FWUploadTCSGE_t
) +
3563 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending FW Upload "
3564 " (req @ %p) fw_size=%d mf_request_size=%d\n", ioc
->name
, prequest
,
3565 ioc
->facts
.FWImageSize
, request_size
));
3566 DBG_DUMP_FW_REQUEST_FRAME(ioc
, (u32
*)prequest
);
3568 ii
= mpt_handshake_req_reply_wait(ioc
, request_size
, (u32
*)prequest
,
3569 reply_sz
, (u16
*)preply
, 65 /*seconds*/, sleepFlag
);
3571 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"FW Upload completed "
3572 "rc=%x \n", ioc
->name
, ii
));
3574 cmdStatus
= -EFAULT
;
3576 /* Handshake transfer was complete and successful.
3577 * Check the Reply Frame.
3580 status
= le16_to_cpu(preply
->IOCStatus
) &
3582 if (status
== MPI_IOCSTATUS_SUCCESS
&&
3583 ioc
->facts
.FWImageSize
==
3584 le32_to_cpu(preply
->ActualImageSize
))
3587 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
": do_upload cmdStatus=%d \n",
3588 ioc
->name
, cmdStatus
));
3592 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"fw upload failed, "
3593 "freeing image \n", ioc
->name
));
3594 mpt_free_fw_memory(ioc
);
3601 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3603 * mpt_downloadboot - DownloadBoot code
3604 * @ioc: Pointer to MPT_ADAPTER structure
3605 * @pFwHeader: Pointer to firmware header info
3606 * @sleepFlag: Specifies whether the process can sleep
3608 * FwDownloadBoot requires Programmed IO access.
3610 * Returns 0 for success
3611 * -1 FW Image size is 0
3612 * -2 No valid cached_fw Pointer
3613 * <0 for fw upload failure.
3616 mpt_downloadboot(MPT_ADAPTER
*ioc
, MpiFwHeader_t
*pFwHeader
, int sleepFlag
)
3618 MpiExtImageHeader_t
*pExtImage
;
3628 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3629 ioc
->name
, pFwHeader
->ImageSize
, pFwHeader
->ImageSize
, pFwHeader
));
3631 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3632 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3633 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3634 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3635 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3636 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3638 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, (MPI_DIAG_PREVENT_IOC_BOOT
| MPI_DIAG_DISABLE_ARM
));
3641 if (sleepFlag
== CAN_SLEEP
) {
3647 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3648 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_RESET_ADAPTER
);
3650 for (count
= 0; count
< 30; count
++) {
3651 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3652 if (!(diag0val
& MPI_DIAG_RESET_ADAPTER
)) {
3653 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RESET_ADAPTER cleared, count=%d\n",
3658 if (sleepFlag
== CAN_SLEEP
) {
3665 if ( count
== 30 ) {
3666 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot failed! "
3667 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3668 ioc
->name
, diag0val
));
3672 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3673 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3674 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3675 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3676 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3677 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3679 /* Set the DiagRwEn and Disable ARM bits */
3680 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, (MPI_DIAG_RW_ENABLE
| MPI_DIAG_DISABLE_ARM
));
3682 fwSize
= (pFwHeader
->ImageSize
+ 3)/4;
3683 ptrFw
= (u32
*) pFwHeader
;
3685 /* Write the LoadStartAddress to the DiagRw Address Register
3686 * using Programmed IO
3688 if (ioc
->errata_flag_1064
)
3689 pci_enable_io_access(ioc
->pcidev
);
3691 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, pFwHeader
->LoadStartAddress
);
3692 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"LoadStart addr written 0x%x \n",
3693 ioc
->name
, pFwHeader
->LoadStartAddress
));
3695 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write FW Image: 0x%x bytes @ %p\n",
3696 ioc
->name
, fwSize
*4, ptrFw
));
3698 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, *ptrFw
++);
3701 nextImage
= pFwHeader
->NextImageHeaderOffset
;
3703 pExtImage
= (MpiExtImageHeader_t
*) ((char *)pFwHeader
+ nextImage
);
3705 load_addr
= pExtImage
->LoadStartAddress
;
3707 fwSize
= (pExtImage
->ImageSize
+ 3) >> 2;
3708 ptrFw
= (u32
*)pExtImage
;
3710 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3711 ioc
->name
, fwSize
*4, fwSize
*4, ptrFw
, load_addr
));
3712 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, load_addr
);
3715 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, *ptrFw
++);
3717 nextImage
= pExtImage
->NextImageHeaderOffset
;
3720 /* Write the IopResetVectorRegAddr */
3721 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write IopResetVector Addr=%x! \n", ioc
->name
, pFwHeader
->IopResetRegAddr
));
3722 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, pFwHeader
->IopResetRegAddr
);
3724 /* Write the IopResetVectorValue */
3725 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write IopResetVector Value=%x! \n", ioc
->name
, pFwHeader
->IopResetVectorValue
));
3726 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, pFwHeader
->IopResetVectorValue
);
3728 /* Clear the internal flash bad bit - autoincrementing register,
3729 * so must do two writes.
3731 if (ioc
->bus_type
== SPI
) {
3733 * 1030 and 1035 H/W errata, workaround to access
3734 * the ClearFlashBadSignatureBit
3736 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, 0x3F000000);
3737 diagRwData
= CHIPREG_PIO_READ32(&ioc
->pio_chip
->DiagRwData
);
3738 diagRwData
|= 0x40000000;
3739 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, 0x3F000000);
3740 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, diagRwData
);
3742 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3743 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3744 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
|
3745 MPI_DIAG_CLEAR_FLASH_BAD_SIG
);
3748 if (sleepFlag
== CAN_SLEEP
) {
3755 if (ioc
->errata_flag_1064
)
3756 pci_disable_io_access(ioc
->pcidev
);
3758 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3759 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot diag0val=%x, "
3760 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3761 ioc
->name
, diag0val
));
3762 diag0val
&= ~(MPI_DIAG_PREVENT_IOC_BOOT
| MPI_DIAG_DISABLE_ARM
| MPI_DIAG_RW_ENABLE
);
3763 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot now diag0val=%x\n",
3764 ioc
->name
, diag0val
));
3765 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
);
3767 /* Write 0xFF to reset the sequencer */
3768 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3770 if (ioc
->bus_type
== SAS
) {
3771 ioc_state
= mpt_GetIocState(ioc
, 0);
3772 if ( (GetIocFacts(ioc
, sleepFlag
,
3773 MPT_HOSTEVENT_IOC_BRINGUP
)) != 0 ) {
3774 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"GetIocFacts failed: IocState=%x\n",
3775 ioc
->name
, ioc_state
));
3780 for (count
=0; count
<HZ
*20; count
++) {
3781 if ((ioc_state
= mpt_GetIocState(ioc
, 0)) & MPI_IOC_STATE_READY
) {
3782 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3783 "downloadboot successful! (count=%d) IocState=%x\n",
3784 ioc
->name
, count
, ioc_state
));
3785 if (ioc
->bus_type
== SAS
) {
3788 if ((SendIocInit(ioc
, sleepFlag
)) != 0) {
3789 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3790 "downloadboot: SendIocInit failed\n",
3794 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3795 "downloadboot: SendIocInit successful\n",
3799 if (sleepFlag
== CAN_SLEEP
) {
3805 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3806 "downloadboot failed! IocState=%x\n",ioc
->name
, ioc_state
));
3810 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3812 * KickStart - Perform hard reset of MPT adapter.
3813 * @ioc: Pointer to MPT_ADAPTER structure
3814 * @force: Force hard reset
3815 * @sleepFlag: Specifies whether the process can sleep
3817 * This routine places MPT adapter in diagnostic mode via the
3818 * WriteSequence register, and then performs a hard reset of adapter
3819 * via the Diagnostic register.
3821 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3822 * or NO_SLEEP (interrupt thread, use mdelay)
3823 * force - 1 if doorbell active, board fault state
3824 * board operational, IOC_RECOVERY or
3825 * IOC_BRINGUP and there is an alt_ioc.
3829 * 1 - hard reset, READY
3830 * 0 - no reset due to History bit, READY
3831 * -1 - no reset due to History bit but not READY
3832 * OR reset but failed to come READY
3833 * -2 - no reset, could not enter DIAG mode
3834 * -3 - reset but bad FW bit
3837 KickStart(MPT_ADAPTER
*ioc
, int force
, int sleepFlag
)
3839 int hard_reset_done
= 0;
3843 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"KickStarting!\n", ioc
->name
));
3844 if (ioc
->bus_type
== SPI
) {
3845 /* Always issue a Msg Unit Reset first. This will clear some
3846 * SCSI bus hang conditions.
3848 SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
);
3850 if (sleepFlag
== CAN_SLEEP
) {
3857 hard_reset_done
= mpt_diag_reset(ioc
, force
, sleepFlag
);
3858 if (hard_reset_done
< 0)
3859 return hard_reset_done
;
3861 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Diagnostic reset successful!\n",
3864 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 2; /* 2 seconds */
3865 for (cnt
=0; cnt
<cntdn
; cnt
++) {
3866 ioc_state
= mpt_GetIocState(ioc
, 1);
3867 if ((ioc_state
== MPI_IOC_STATE_READY
) || (ioc_state
== MPI_IOC_STATE_OPERATIONAL
)) {
3868 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"KickStart successful! (cnt=%d)\n",
3870 return hard_reset_done
;
3872 if (sleepFlag
== CAN_SLEEP
) {
3879 dinitprintk(ioc
, printk(MYIOC_s_ERR_FMT
"Failed to come READY after reset! IocState=%x\n",
3880 ioc
->name
, mpt_GetIocState(ioc
, 0)));
3884 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3886 * mpt_diag_reset - Perform hard reset of the adapter.
3887 * @ioc: Pointer to MPT_ADAPTER structure
3888 * @ignore: Set if to honor and clear to ignore
3889 * the reset history bit
3890 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3891 * else set to NO_SLEEP (use mdelay instead)
3893 * This routine places the adapter in diagnostic mode via the
3894 * WriteSequence register and then performs a hard reset of adapter
3895 * via the Diagnostic register. Adapter should be in ready state
3896 * upon successful completion.
3898 * Returns: 1 hard reset successful
3899 * 0 no reset performed because reset history bit set
3900 * -2 enabling diagnostic mode failed
3901 * -3 diagnostic reset failed
3904 mpt_diag_reset(MPT_ADAPTER
*ioc
, int ignore
, int sleepFlag
)
3908 int hard_reset_done
= 0;
3911 MpiFwHeader_t
*cached_fw
; /* Pointer to FW */
3914 /* Clear any existing interrupts */
3915 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
3917 if (ioc
->pcidev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1078
) {
3922 drsprintk(ioc
, printk(MYIOC_s_WARN_FMT
"%s: Doorbell=%p; 1078 reset "
3923 "address=%p\n", ioc
->name
, __func__
,
3924 &ioc
->chip
->Doorbell
, &ioc
->chip
->Reset_1078
));
3925 CHIPREG_WRITE32(&ioc
->chip
->Reset_1078
, 0x07);
3926 if (sleepFlag
== CAN_SLEEP
)
3932 * Call each currently registered protocol IOC reset handler
3933 * with pre-reset indication.
3934 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3935 * MptResetHandlers[] registered yet.
3937 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
3938 if (MptResetHandlers
[cb_idx
])
3939 (*(MptResetHandlers
[cb_idx
]))(ioc
,
3943 for (count
= 0; count
< 60; count
++) {
3944 doorbell
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
3945 doorbell
&= MPI_IOC_STATE_MASK
;
3947 drsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3948 "looking for READY STATE: doorbell=%x"
3950 ioc
->name
, doorbell
, count
));
3952 if (doorbell
== MPI_IOC_STATE_READY
) {
3957 if (sleepFlag
== CAN_SLEEP
)
3965 /* Use "Diagnostic reset" method! (only thing available!) */
3966 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3968 if (ioc
->debug_level
& MPT_DEBUG
) {
3970 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
3971 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG1: diag0=%08x, diag1=%08x\n",
3972 ioc
->name
, diag0val
, diag1val
));
3975 /* Do the reset if we are told to ignore the reset history
3976 * or if the reset history is 0
3978 if (ignore
|| !(diag0val
& MPI_DIAG_RESET_HISTORY
)) {
3979 while ((diag0val
& MPI_DIAG_DRWE
) == 0) {
3980 /* Write magic sequence to WriteSequence register
3981 * Loop until in diagnostic mode
3983 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3984 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3985 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3986 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3987 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3988 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3991 if (sleepFlag
== CAN_SLEEP
) {
3999 printk(MYIOC_s_ERR_FMT
"Enable Diagnostic mode FAILED! (%02xh)\n",
4000 ioc
->name
, diag0val
);
4005 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4007 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Wrote magic DiagWriteEn sequence (%x)\n",
4008 ioc
->name
, diag0val
));
4011 if (ioc
->debug_level
& MPT_DEBUG
) {
4013 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
4014 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG2: diag0=%08x, diag1=%08x\n",
4015 ioc
->name
, diag0val
, diag1val
));
4018 * Disable the ARM (Bug fix)
4021 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_DISABLE_ARM
);
4025 * Now hit the reset bit in the Diagnostic register
4026 * (THE BIG HAMMER!) (Clears DRWE bit).
4028 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_RESET_ADAPTER
);
4029 hard_reset_done
= 1;
4030 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Diagnostic reset performed\n",
4034 * Call each currently registered protocol IOC reset handler
4035 * with pre-reset indication.
4036 * NOTE: If we're doing _IOC_BRINGUP, there can be no
4037 * MptResetHandlers[] registered yet.
4039 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
4040 if (MptResetHandlers
[cb_idx
]) {
4041 mpt_signal_reset(cb_idx
,
4042 ioc
, MPT_IOC_PRE_RESET
);
4044 mpt_signal_reset(cb_idx
,
4045 ioc
->alt_ioc
, MPT_IOC_PRE_RESET
);
4051 cached_fw
= (MpiFwHeader_t
*)ioc
->cached_fw
;
4052 else if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
)
4053 cached_fw
= (MpiFwHeader_t
*)ioc
->alt_ioc
->cached_fw
;
4057 /* If the DownloadBoot operation fails, the
4058 * IOC will be left unusable. This is a fatal error
4059 * case. _diag_reset will return < 0
4061 for (count
= 0; count
< 30; count
++) {
4062 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4063 if (!(diag0val
& MPI_DIAG_RESET_ADAPTER
)) {
4067 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"cached_fw: diag0val=%x count=%d\n",
4068 ioc
->name
, diag0val
, count
));
4070 if (sleepFlag
== CAN_SLEEP
) {
4076 if ((count
= mpt_downloadboot(ioc
, cached_fw
, sleepFlag
)) < 0) {
4077 printk(MYIOC_s_WARN_FMT
4078 "firmware downloadboot failure (%d)!\n", ioc
->name
, count
);
4082 /* Wait for FW to reload and for board
4083 * to go to the READY state.
4084 * Maximum wait is 60 seconds.
4085 * If fail, no error will check again
4086 * with calling program.
4088 for (count
= 0; count
< 60; count
++) {
4089 doorbell
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
4090 doorbell
&= MPI_IOC_STATE_MASK
;
4092 drsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4093 "looking for READY STATE: doorbell=%x"
4094 " count=%d\n", ioc
->name
, doorbell
, count
));
4096 if (doorbell
== MPI_IOC_STATE_READY
) {
4101 if (sleepFlag
== CAN_SLEEP
) {
4108 if (doorbell
!= MPI_IOC_STATE_READY
)
4109 printk(MYIOC_s_ERR_FMT
"Failed to come READY "
4110 "after reset! IocState=%x", ioc
->name
,
4115 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4116 if (ioc
->debug_level
& MPT_DEBUG
) {
4118 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
4119 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG3: diag0=%08x, diag1=%08x\n",
4120 ioc
->name
, diag0val
, diag1val
));
4123 /* Clear RESET_HISTORY bit! Place board in the
4124 * diagnostic mode to update the diag register.
4126 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4128 while ((diag0val
& MPI_DIAG_DRWE
) == 0) {
4129 /* Write magic sequence to WriteSequence register
4130 * Loop until in diagnostic mode
4132 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
4133 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
4134 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
4135 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
4136 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
4137 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
4140 if (sleepFlag
== CAN_SLEEP
) {
4148 printk(MYIOC_s_ERR_FMT
"Enable Diagnostic mode FAILED! (%02xh)\n",
4149 ioc
->name
, diag0val
);
4152 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4154 diag0val
&= ~MPI_DIAG_RESET_HISTORY
;
4155 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
);
4156 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4157 if (diag0val
& MPI_DIAG_RESET_HISTORY
) {
4158 printk(MYIOC_s_WARN_FMT
"ResetHistory bit failed to clear!\n",
4162 /* Disable Diagnostic Mode
4164 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFFFFFFFF);
4166 /* Check FW reload status flags.
4168 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4169 if (diag0val
& (MPI_DIAG_FLASH_BAD_SIG
| MPI_DIAG_RESET_ADAPTER
| MPI_DIAG_DISABLE_ARM
)) {
4170 printk(MYIOC_s_ERR_FMT
"Diagnostic reset FAILED! (%02xh)\n",
4171 ioc
->name
, diag0val
);
4175 if (ioc
->debug_level
& MPT_DEBUG
) {
4177 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
4178 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG4: diag0=%08x, diag1=%08x\n",
4179 ioc
->name
, diag0val
, diag1val
));
4183 * Reset flag that says we've enabled event notification
4185 ioc
->facts
.EventState
= 0;
4188 ioc
->alt_ioc
->facts
.EventState
= 0;
4190 return hard_reset_done
;
4193 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4195 * SendIocReset - Send IOCReset request to MPT adapter.
4196 * @ioc: Pointer to MPT_ADAPTER structure
4197 * @reset_type: reset type, expected values are
4198 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
4199 * @sleepFlag: Specifies whether the process can sleep
4201 * Send IOCReset request to the MPT adapter.
4203 * Returns 0 for success, non-zero for failure.
4206 SendIocReset(MPT_ADAPTER
*ioc
, u8 reset_type
, int sleepFlag
)
4212 drsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending IOC reset(0x%02x)!\n",
4213 ioc
->name
, reset_type
));
4214 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, reset_type
<<MPI_DOORBELL_FUNCTION_SHIFT
);
4215 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
4218 /* FW ACK'd request, wait for READY state
4221 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 15; /* 15 seconds */
4223 while ((state
= mpt_GetIocState(ioc
, 1)) != MPI_IOC_STATE_READY
) {
4227 if (sleepFlag
!= CAN_SLEEP
)
4230 printk(MYIOC_s_ERR_FMT
4231 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
4232 ioc
->name
, state
, (int)((count
+5)/HZ
));
4236 if (sleepFlag
== CAN_SLEEP
) {
4239 mdelay (1); /* 1 msec delay */
4244 * Cleanup all event stuff for this IOC; re-issue EventNotification
4245 * request if needed.
4247 if (ioc
->facts
.Function
)
4248 ioc
->facts
.EventState
= 0;
4253 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4255 * initChainBuffers - Allocate memory for and initialize chain buffers
4256 * @ioc: Pointer to MPT_ADAPTER structure
4258 * Allocates memory for and initializes chain buffers,
4259 * chain buffer control arrays and spinlock.
4262 initChainBuffers(MPT_ADAPTER
*ioc
)
4265 int sz
, ii
, num_chain
;
4266 int scale
, num_sge
, numSGE
;
4268 /* ReqToChain size must equal the req_depth
4271 if (ioc
->ReqToChain
== NULL
) {
4272 sz
= ioc
->req_depth
* sizeof(int);
4273 mem
= kmalloc(sz
, GFP_ATOMIC
);
4277 ioc
->ReqToChain
= (int *) mem
;
4278 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReqToChain alloc @ %p, sz=%d bytes\n",
4279 ioc
->name
, mem
, sz
));
4280 mem
= kmalloc(sz
, GFP_ATOMIC
);
4284 ioc
->RequestNB
= (int *) mem
;
4285 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestNB alloc @ %p, sz=%d bytes\n",
4286 ioc
->name
, mem
, sz
));
4288 for (ii
= 0; ii
< ioc
->req_depth
; ii
++) {
4289 ioc
->ReqToChain
[ii
] = MPT_HOST_NO_CHAIN
;
4292 /* ChainToChain size must equal the total number
4293 * of chain buffers to be allocated.
4296 * Calculate the number of chain buffers needed(plus 1) per I/O
4297 * then multiply the maximum number of simultaneous cmds
4299 * num_sge = num sge in request frame + last chain buffer
4300 * scale = num sge per chain buffer if no chain element
4302 scale
= ioc
->req_sz
/ ioc
->SGE_size
;
4303 if (ioc
->sg_addr_size
== sizeof(u64
))
4304 num_sge
= scale
+ (ioc
->req_sz
- 60) / ioc
->SGE_size
;
4306 num_sge
= 1 + scale
+ (ioc
->req_sz
- 64) / ioc
->SGE_size
;
4308 if (ioc
->sg_addr_size
== sizeof(u64
)) {
4309 numSGE
= (scale
- 1) * (ioc
->facts
.MaxChainDepth
-1) + scale
+
4310 (ioc
->req_sz
- 60) / ioc
->SGE_size
;
4312 numSGE
= 1 + (scale
- 1) * (ioc
->facts
.MaxChainDepth
-1) +
4313 scale
+ (ioc
->req_sz
- 64) / ioc
->SGE_size
;
4315 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"num_sge=%d numSGE=%d\n",
4316 ioc
->name
, num_sge
, numSGE
));
4318 if (ioc
->bus_type
== FC
) {
4319 if (numSGE
> MPT_SCSI_FC_SG_DEPTH
)
4320 numSGE
= MPT_SCSI_FC_SG_DEPTH
;
4322 if (numSGE
> MPT_SCSI_SG_DEPTH
)
4323 numSGE
= MPT_SCSI_SG_DEPTH
;
4327 while (numSGE
- num_sge
> 0) {
4329 num_sge
+= (scale
- 1);
4333 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Now numSGE=%d num_sge=%d num_chain=%d\n",
4334 ioc
->name
, numSGE
, num_sge
, num_chain
));
4336 if (ioc
->bus_type
== SPI
)
4337 num_chain
*= MPT_SCSI_CAN_QUEUE
;
4338 else if (ioc
->bus_type
== SAS
)
4339 num_chain
*= MPT_SAS_CAN_QUEUE
;
4341 num_chain
*= MPT_FC_CAN_QUEUE
;
4343 ioc
->num_chain
= num_chain
;
4345 sz
= num_chain
* sizeof(int);
4346 if (ioc
->ChainToChain
== NULL
) {
4347 mem
= kmalloc(sz
, GFP_ATOMIC
);
4351 ioc
->ChainToChain
= (int *) mem
;
4352 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainToChain alloc @ %p, sz=%d bytes\n",
4353 ioc
->name
, mem
, sz
));
4355 mem
= (u8
*) ioc
->ChainToChain
;
4357 memset(mem
, 0xFF, sz
);
4361 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4363 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
4364 * @ioc: Pointer to MPT_ADAPTER structure
4366 * This routine allocates memory for the MPT reply and request frame
4367 * pools (if necessary), and primes the IOC reply FIFO with
4370 * Returns 0 for success, non-zero for failure.
4373 PrimeIocFifos(MPT_ADAPTER
*ioc
)
4376 unsigned long flags
;
4377 dma_addr_t alloc_dma
;
4379 int i
, reply_sz
, sz
, total_size
, num_chain
;
4384 /* Prime reply FIFO... */
4386 if (ioc
->reply_frames
== NULL
) {
4387 if ( (num_chain
= initChainBuffers(ioc
)) < 0)
4390 * 1078 errata workaround for the 36GB limitation
4392 if (ioc
->pcidev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1078
&&
4393 ioc
->dma_mask
> DMA_BIT_MASK(35)) {
4394 if (!pci_set_dma_mask(ioc
->pcidev
, DMA_BIT_MASK(32))
4395 && !pci_set_consistent_dma_mask(ioc
->pcidev
,
4396 DMA_BIT_MASK(32))) {
4397 dma_mask
= DMA_BIT_MASK(35);
4398 d36memprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4399 "setting 35 bit addressing for "
4400 "Request/Reply/Chain and Sense Buffers\n",
4403 /*Reseting DMA mask to 64 bit*/
4404 pci_set_dma_mask(ioc
->pcidev
,
4406 pci_set_consistent_dma_mask(ioc
->pcidev
,
4409 printk(MYIOC_s_ERR_FMT
4410 "failed setting 35 bit addressing for "
4411 "Request/Reply/Chain and Sense Buffers\n",
4417 total_size
= reply_sz
= (ioc
->reply_sz
* ioc
->reply_depth
);
4418 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
4419 ioc
->name
, ioc
->reply_sz
, ioc
->reply_depth
));
4420 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffer sz=%d[%x] bytes\n",
4421 ioc
->name
, reply_sz
, reply_sz
));
4423 sz
= (ioc
->req_sz
* ioc
->req_depth
);
4424 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestBuffer sz=%d bytes, RequestDepth=%d\n",
4425 ioc
->name
, ioc
->req_sz
, ioc
->req_depth
));
4426 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestBuffer sz=%d[%x] bytes\n",
4427 ioc
->name
, sz
, sz
));
4430 sz
= num_chain
* ioc
->req_sz
; /* chain buffer pool size */
4431 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainBuffer sz=%d bytes, ChainDepth=%d\n",
4432 ioc
->name
, ioc
->req_sz
, num_chain
));
4433 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
4434 ioc
->name
, sz
, sz
, num_chain
));
4437 mem
= pci_alloc_consistent(ioc
->pcidev
, total_size
, &alloc_dma
);
4439 printk(MYIOC_s_ERR_FMT
"Unable to allocate Reply, Request, Chain Buffers!\n",
4444 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Total alloc @ %p[%p], sz=%d[%x] bytes\n",
4445 ioc
->name
, mem
, (void *)(ulong
)alloc_dma
, total_size
, total_size
));
4447 memset(mem
, 0, total_size
);
4448 ioc
->alloc_total
+= total_size
;
4450 ioc
->alloc_dma
= alloc_dma
;
4451 ioc
->alloc_sz
= total_size
;
4452 ioc
->reply_frames
= (MPT_FRAME_HDR
*) mem
;
4453 ioc
->reply_frames_low_dma
= (u32
) (alloc_dma
& 0xFFFFFFFF);
4455 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffers @ %p[%p]\n",
4456 ioc
->name
, ioc
->reply_frames
, (void *)(ulong
)alloc_dma
));
4458 alloc_dma
+= reply_sz
;
4461 /* Request FIFO - WE manage this! */
4463 ioc
->req_frames
= (MPT_FRAME_HDR
*) mem
;
4464 ioc
->req_frames_dma
= alloc_dma
;
4466 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestBuffers @ %p[%p]\n",
4467 ioc
->name
, mem
, (void *)(ulong
)alloc_dma
));
4469 ioc
->req_frames_low_dma
= (u32
) (alloc_dma
& 0xFFFFFFFF);
4471 #if defined(CONFIG_MTRR) && 0
4473 * Enable Write Combining MTRR for IOC's memory region.
4474 * (at least as much as we can; "size and base must be
4475 * multiples of 4 kiB"
4477 ioc
->mtrr_reg
= mtrr_add(ioc
->req_frames_dma
,
4479 MTRR_TYPE_WRCOMB
, 1);
4480 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"MTRR region registered (base:size=%08x:%x)\n",
4481 ioc
->name
, ioc
->req_frames_dma
, sz
));
4484 for (i
= 0; i
< ioc
->req_depth
; i
++) {
4485 alloc_dma
+= ioc
->req_sz
;
4489 ioc
->ChainBuffer
= mem
;
4490 ioc
->ChainBufferDMA
= alloc_dma
;
4492 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainBuffers @ %p(%p)\n",
4493 ioc
->name
, ioc
->ChainBuffer
, (void *)(ulong
)ioc
->ChainBufferDMA
));
4495 /* Initialize the free chain Q.
4498 INIT_LIST_HEAD(&ioc
->FreeChainQ
);
4500 /* Post the chain buffers to the FreeChainQ.
4502 mem
= (u8
*)ioc
->ChainBuffer
;
4503 for (i
=0; i
< num_chain
; i
++) {
4504 mf
= (MPT_FRAME_HDR
*) mem
;
4505 list_add_tail(&mf
->u
.frame
.linkage
.list
, &ioc
->FreeChainQ
);
4509 /* Initialize Request frames linked list
4511 alloc_dma
= ioc
->req_frames_dma
;
4512 mem
= (u8
*) ioc
->req_frames
;
4514 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
4515 INIT_LIST_HEAD(&ioc
->FreeQ
);
4516 for (i
= 0; i
< ioc
->req_depth
; i
++) {
4517 mf
= (MPT_FRAME_HDR
*) mem
;
4519 /* Queue REQUESTs *internally*! */
4520 list_add_tail(&mf
->u
.frame
.linkage
.list
, &ioc
->FreeQ
);
4524 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
4526 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
4527 ioc
->sense_buf_pool
=
4528 pci_alloc_consistent(ioc
->pcidev
, sz
, &ioc
->sense_buf_pool_dma
);
4529 if (ioc
->sense_buf_pool
== NULL
) {
4530 printk(MYIOC_s_ERR_FMT
"Unable to allocate Sense Buffers!\n",
4535 ioc
->sense_buf_low_dma
= (u32
) (ioc
->sense_buf_pool_dma
& 0xFFFFFFFF);
4536 ioc
->alloc_total
+= sz
;
4537 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SenseBuffers @ %p[%p]\n",
4538 ioc
->name
, ioc
->sense_buf_pool
, (void *)(ulong
)ioc
->sense_buf_pool_dma
));
4542 /* Post Reply frames to FIFO
4544 alloc_dma
= ioc
->alloc_dma
;
4545 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffers @ %p[%p]\n",
4546 ioc
->name
, ioc
->reply_frames
, (void *)(ulong
)alloc_dma
));
4548 for (i
= 0; i
< ioc
->reply_depth
; i
++) {
4549 /* Write each address to the IOC! */
4550 CHIPREG_WRITE32(&ioc
->chip
->ReplyFifo
, alloc_dma
);
4551 alloc_dma
+= ioc
->reply_sz
;
4554 if (dma_mask
== DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc
->pcidev
,
4555 ioc
->dma_mask
) && !pci_set_consistent_dma_mask(ioc
->pcidev
,
4557 d36memprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4558 "restoring 64 bit addressing\n", ioc
->name
));
4564 if (ioc
->alloc
!= NULL
) {
4566 pci_free_consistent(ioc
->pcidev
,
4568 ioc
->alloc
, ioc
->alloc_dma
);
4569 ioc
->reply_frames
= NULL
;
4570 ioc
->req_frames
= NULL
;
4571 ioc
->alloc_total
-= sz
;
4573 if (ioc
->sense_buf_pool
!= NULL
) {
4574 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
4575 pci_free_consistent(ioc
->pcidev
,
4577 ioc
->sense_buf_pool
, ioc
->sense_buf_pool_dma
);
4578 ioc
->sense_buf_pool
= NULL
;
4581 if (dma_mask
== DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc
->pcidev
,
4582 DMA_BIT_MASK(64)) && !pci_set_consistent_dma_mask(ioc
->pcidev
,
4584 d36memprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4585 "restoring 64 bit addressing\n", ioc
->name
));
4590 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4592 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4593 * from IOC via doorbell handshake method.
4594 * @ioc: Pointer to MPT_ADAPTER structure
4595 * @reqBytes: Size of the request in bytes
4596 * @req: Pointer to MPT request frame
4597 * @replyBytes: Expected size of the reply in bytes
4598 * @u16reply: Pointer to area where reply should be written
4599 * @maxwait: Max wait time for a reply (in seconds)
4600 * @sleepFlag: Specifies whether the process can sleep
4602 * NOTES: It is the callers responsibility to byte-swap fields in the
4603 * request which are greater than 1 byte in size. It is also the
4604 * callers responsibility to byte-swap response fields which are
4605 * greater than 1 byte in size.
4607 * Returns 0 for success, non-zero for failure.
4610 mpt_handshake_req_reply_wait(MPT_ADAPTER
*ioc
, int reqBytes
, u32
*req
,
4611 int replyBytes
, u16
*u16reply
, int maxwait
, int sleepFlag
)
4613 MPIDefaultReply_t
*mptReply
;
4618 * Get ready to cache a handshake reply
4620 ioc
->hs_reply_idx
= 0;
4621 mptReply
= (MPIDefaultReply_t
*) ioc
->hs_reply
;
4622 mptReply
->MsgLength
= 0;
4625 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4626 * then tell IOC that we want to handshake a request of N words.
4627 * (WRITE u32val to Doorbell reg).
4629 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4630 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
,
4631 ((MPI_FUNCTION_HANDSHAKE
<<MPI_DOORBELL_FUNCTION_SHIFT
) |
4632 ((reqBytes
/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT
)));
4635 * Wait for IOC's doorbell handshake int
4637 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4640 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4641 ioc
->name
, reqBytes
, t
, failcnt
? " - MISSING DOORBELL HANDSHAKE!" : ""));
4643 /* Read doorbell and check for active bit */
4644 if (!(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & MPI_DOORBELL_ACTIVE
))
4648 * Clear doorbell int (WRITE 0 to IntStatus reg),
4649 * then wait for IOC to ACKnowledge that it's ready for
4650 * our handshake request.
4652 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4653 if (!failcnt
&& (t
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
4658 u8
*req_as_bytes
= (u8
*) req
;
4661 * Stuff request words via doorbell handshake,
4662 * with ACK from IOC for each.
4664 for (ii
= 0; !failcnt
&& ii
< reqBytes
/4; ii
++) {
4665 u32 word
= ((req_as_bytes
[(ii
*4) + 0] << 0) |
4666 (req_as_bytes
[(ii
*4) + 1] << 8) |
4667 (req_as_bytes
[(ii
*4) + 2] << 16) |
4668 (req_as_bytes
[(ii
*4) + 3] << 24));
4670 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, word
);
4671 if ((t
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
4675 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Handshake request frame (@%p) header\n", ioc
->name
, req
));
4676 DBG_DUMP_REQUEST_FRAME_HDR(ioc
, (u32
*)req
);
4678 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HandShake request post done, WaitCnt=%d%s\n",
4679 ioc
->name
, t
, failcnt
? " - MISSING DOORBELL ACK!" : ""));
4682 * Wait for completion of doorbell handshake reply from the IOC
4684 if (!failcnt
&& (t
= WaitForDoorbellReply(ioc
, maxwait
, sleepFlag
)) < 0)
4687 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HandShake reply count=%d%s\n",
4688 ioc
->name
, t
, failcnt
? " - MISSING DOORBELL REPLY!" : ""));
4691 * Copy out the cached reply...
4693 for (ii
=0; ii
< min(replyBytes
/2,mptReply
->MsgLength
*2); ii
++)
4694 u16reply
[ii
] = ioc
->hs_reply
[ii
];
4702 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4704 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4705 * @ioc: Pointer to MPT_ADAPTER structure
4706 * @howlong: How long to wait (in seconds)
4707 * @sleepFlag: Specifies whether the process can sleep
4709 * This routine waits (up to ~2 seconds max) for IOC doorbell
4710 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4711 * bit in its IntStatus register being clear.
4713 * Returns a negative value on failure, else wait loop count.
4716 WaitForDoorbellAck(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
4722 cntdn
= 1000 * howlong
;
4724 if (sleepFlag
== CAN_SLEEP
) {
4727 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4728 if (! (intstat
& MPI_HIS_IOP_DOORBELL_STATUS
))
4735 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4736 if (! (intstat
& MPI_HIS_IOP_DOORBELL_STATUS
))
4743 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitForDoorbell ACK (count=%d)\n",
4748 printk(MYIOC_s_ERR_FMT
"Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4749 ioc
->name
, count
, intstat
);
4753 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4755 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4756 * @ioc: Pointer to MPT_ADAPTER structure
4757 * @howlong: How long to wait (in seconds)
4758 * @sleepFlag: Specifies whether the process can sleep
4760 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4761 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4763 * Returns a negative value on failure, else wait loop count.
4766 WaitForDoorbellInt(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
4772 cntdn
= 1000 * howlong
;
4773 if (sleepFlag
== CAN_SLEEP
) {
4775 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4776 if (intstat
& MPI_HIS_DOORBELL_INTERRUPT
)
4783 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4784 if (intstat
& MPI_HIS_DOORBELL_INTERRUPT
)
4792 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4793 ioc
->name
, count
, howlong
));
4797 printk(MYIOC_s_ERR_FMT
"Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4798 ioc
->name
, count
, intstat
);
4802 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4804 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4805 * @ioc: Pointer to MPT_ADAPTER structure
4806 * @howlong: How long to wait (in seconds)
4807 * @sleepFlag: Specifies whether the process can sleep
4809 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4810 * Reply is cached to IOC private area large enough to hold a maximum
4811 * of 128 bytes of reply data.
4813 * Returns a negative value on failure, else size of reply in WORDS.
4816 WaitForDoorbellReply(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
4821 u16
*hs_reply
= ioc
->hs_reply
;
4822 volatile MPIDefaultReply_t
*mptReply
= (MPIDefaultReply_t
*) ioc
->hs_reply
;
4825 hs_reply
[0] = hs_reply
[1] = hs_reply
[7] = 0;
4828 * Get first two u16's so we can look at IOC's intended reply MsgLength
4831 if ((t
= WaitForDoorbellInt(ioc
, howlong
, sleepFlag
)) < 0) {
4834 hs_reply
[u16cnt
++] = le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4835 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4836 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4839 hs_reply
[u16cnt
++] = le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4840 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4844 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitCnt=%d First handshake reply word=%08x%s\n",
4845 ioc
->name
, t
, le32_to_cpu(*(u32
*)hs_reply
),
4846 failcnt
? " - MISSING DOORBELL HANDSHAKE!" : ""));
4849 * If no error (and IOC said MsgLength is > 0), piece together
4850 * reply 16 bits at a time.
4852 for (u16cnt
=2; !failcnt
&& u16cnt
< (2 * mptReply
->MsgLength
); u16cnt
++) {
4853 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4855 hword
= le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4856 /* don't overflow our IOC hs_reply[] buffer! */
4857 if (u16cnt
< ARRAY_SIZE(ioc
->hs_reply
))
4858 hs_reply
[u16cnt
] = hword
;
4859 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4862 if (!failcnt
&& (t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4864 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4867 printk(MYIOC_s_ERR_FMT
"Handshake reply failure!\n",
4872 else if (u16cnt
!= (2 * mptReply
->MsgLength
)) {
4875 else if ((mptReply
->IOCStatus
& MPI_IOCSTATUS_MASK
) != MPI_IOCSTATUS_SUCCESS
) {
4880 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Got Handshake reply:\n", ioc
->name
));
4881 DBG_DUMP_REPLY_FRAME(ioc
, (u32
*)mptReply
);
4883 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4884 ioc
->name
, t
, u16cnt
/2));
4888 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4890 * GetLanConfigPages - Fetch LANConfig pages.
4891 * @ioc: Pointer to MPT_ADAPTER structure
4893 * Return: 0 for success
4894 * -ENOMEM if no memory available
4895 * -EPERM if not allowed due to ISR context
4896 * -EAGAIN if no msg frames currently available
4897 * -EFAULT for non-successful reply or no reply (timeout)
4900 GetLanConfigPages(MPT_ADAPTER
*ioc
)
4902 ConfigPageHeader_t hdr
;
4904 LANPage0_t
*ppage0_alloc
;
4905 dma_addr_t page0_dma
;
4906 LANPage1_t
*ppage1_alloc
;
4907 dma_addr_t page1_dma
;
4912 /* Get LAN Page 0 header */
4913 hdr
.PageVersion
= 0;
4916 hdr
.PageType
= MPI_CONFIG_PAGETYPE_LAN
;
4917 cfg
.cfghdr
.hdr
= &hdr
;
4919 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4924 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
4927 if (hdr
.PageLength
> 0) {
4928 data_sz
= hdr
.PageLength
* 4;
4929 ppage0_alloc
= (LANPage0_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page0_dma
);
4932 memset((u8
*)ppage0_alloc
, 0, data_sz
);
4933 cfg
.physAddr
= page0_dma
;
4934 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4936 if ((rc
= mpt_config(ioc
, &cfg
)) == 0) {
4938 copy_sz
= min_t(int, sizeof(LANPage0_t
), data_sz
);
4939 memcpy(&ioc
->lan_cnfg_page0
, ppage0_alloc
, copy_sz
);
4943 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage0_alloc
, page0_dma
);
4946 * Normalize endianness of structure data,
4947 * by byte-swapping all > 1 byte fields!
4956 /* Get LAN Page 1 header */
4957 hdr
.PageVersion
= 0;
4960 hdr
.PageType
= MPI_CONFIG_PAGETYPE_LAN
;
4961 cfg
.cfghdr
.hdr
= &hdr
;
4963 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4967 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
4970 if (hdr
.PageLength
== 0)
4973 data_sz
= hdr
.PageLength
* 4;
4975 ppage1_alloc
= (LANPage1_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page1_dma
);
4977 memset((u8
*)ppage1_alloc
, 0, data_sz
);
4978 cfg
.physAddr
= page1_dma
;
4979 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4981 if ((rc
= mpt_config(ioc
, &cfg
)) == 0) {
4983 copy_sz
= min_t(int, sizeof(LANPage1_t
), data_sz
);
4984 memcpy(&ioc
->lan_cnfg_page1
, ppage1_alloc
, copy_sz
);
4987 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage1_alloc
, page1_dma
);
4990 * Normalize endianness of structure data,
4991 * by byte-swapping all > 1 byte fields!
4999 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5001 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
5002 * @ioc: Pointer to MPT_ADAPTER structure
5003 * @persist_opcode: see below
5005 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
5006 * devices not currently present.
5007 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
5009 * NOTE: Don't use not this function during interrupt time.
5011 * Returns 0 for success, non-zero error
5014 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5016 mptbase_sas_persist_operation(MPT_ADAPTER
*ioc
, u8 persist_opcode
)
5018 SasIoUnitControlRequest_t
*sasIoUnitCntrReq
;
5019 SasIoUnitControlReply_t
*sasIoUnitCntrReply
;
5020 MPT_FRAME_HDR
*mf
= NULL
;
5021 MPIHeader_t
*mpi_hdr
;
5023 unsigned long timeleft
;
5025 mutex_lock(&ioc
->mptbase_cmds
.mutex
);
5027 /* init the internal cmd struct */
5028 memset(ioc
->mptbase_cmds
.reply
, 0 , MPT_DEFAULT_FRAME_SIZE
);
5029 INITIALIZE_MGMT_STATUS(ioc
->mptbase_cmds
.status
)
5031 /* insure garbage is not sent to fw */
5032 switch(persist_opcode
) {
5034 case MPI_SAS_OP_CLEAR_NOT_PRESENT
:
5035 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT
:
5043 printk(KERN_DEBUG
"%s: persist_opcode=%x\n",
5044 __func__
, persist_opcode
);
5046 /* Get a MF for this command.
5048 if ((mf
= mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
5049 printk(KERN_DEBUG
"%s: no msg frames!\n", __func__
);
5054 mpi_hdr
= (MPIHeader_t
*) mf
;
5055 sasIoUnitCntrReq
= (SasIoUnitControlRequest_t
*)mf
;
5056 memset(sasIoUnitCntrReq
,0,sizeof(SasIoUnitControlRequest_t
));
5057 sasIoUnitCntrReq
->Function
= MPI_FUNCTION_SAS_IO_UNIT_CONTROL
;
5058 sasIoUnitCntrReq
->MsgContext
= mpi_hdr
->MsgContext
;
5059 sasIoUnitCntrReq
->Operation
= persist_opcode
;
5061 mpt_put_msg_frame(mpt_base_index
, ioc
, mf
);
5062 timeleft
= wait_for_completion_timeout(&ioc
->mptbase_cmds
.done
, 10*HZ
);
5063 if (!(ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_COMMAND_GOOD
)) {
5065 printk(KERN_DEBUG
"%s: failed\n", __func__
);
5066 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_DID_IOCRESET
)
5069 printk(MYIOC_s_WARN_FMT
5070 "Issuing Reset from %s!!, doorbell=0x%08x\n",
5071 ioc
->name
, __func__
, mpt_GetIocState(ioc
, 0));
5072 mpt_Soft_Hard_ResetHandler(ioc
, CAN_SLEEP
);
5073 mpt_free_msg_frame(ioc
, mf
);
5078 if (!(ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_RF_VALID
)) {
5083 sasIoUnitCntrReply
=
5084 (SasIoUnitControlReply_t
*)ioc
->mptbase_cmds
.reply
;
5085 if (le16_to_cpu(sasIoUnitCntrReply
->IOCStatus
) != MPI_IOCSTATUS_SUCCESS
) {
5086 printk(KERN_DEBUG
"%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
5087 __func__
, sasIoUnitCntrReply
->IOCStatus
,
5088 sasIoUnitCntrReply
->IOCLogInfo
);
5089 printk(KERN_DEBUG
"%s: failed\n", __func__
);
5092 printk(KERN_DEBUG
"%s: success\n", __func__
);
5095 CLEAR_MGMT_STATUS(ioc
->mptbase_cmds
.status
)
5096 mutex_unlock(&ioc
->mptbase_cmds
.mutex
);
5100 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5103 mptbase_raid_process_event_data(MPT_ADAPTER
*ioc
,
5104 MpiEventDataRaid_t
* pRaidEventData
)
5113 volume
= pRaidEventData
->VolumeID
;
5114 reason
= pRaidEventData
->ReasonCode
;
5115 disk
= pRaidEventData
->PhysDiskNum
;
5116 status
= le32_to_cpu(pRaidEventData
->SettingsStatus
);
5117 flags
= (status
>> 0) & 0xff;
5118 state
= (status
>> 8) & 0xff;
5120 if (reason
== MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
) {
5124 if ((reason
>= MPI_EVENT_RAID_RC_PHYSDISK_CREATED
&&
5125 reason
<= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
) ||
5126 (reason
== MPI_EVENT_RAID_RC_SMART_DATA
)) {
5127 printk(MYIOC_s_INFO_FMT
"RAID STATUS CHANGE for PhysDisk %d id=%d\n",
5128 ioc
->name
, disk
, volume
);
5130 printk(MYIOC_s_INFO_FMT
"RAID STATUS CHANGE for VolumeID %d\n",
5135 case MPI_EVENT_RAID_RC_VOLUME_CREATED
:
5136 printk(MYIOC_s_INFO_FMT
" volume has been created\n",
5140 case MPI_EVENT_RAID_RC_VOLUME_DELETED
:
5142 printk(MYIOC_s_INFO_FMT
" volume has been deleted\n",
5146 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED
:
5147 printk(MYIOC_s_INFO_FMT
" volume settings have been changed\n",
5151 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED
:
5152 printk(MYIOC_s_INFO_FMT
" volume is now %s%s%s%s\n",
5154 state
== MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
5156 : state
== MPI_RAIDVOL0_STATUS_STATE_DEGRADED
5158 : state
== MPI_RAIDVOL0_STATUS_STATE_FAILED
5161 flags
& MPI_RAIDVOL0_STATUS_FLAG_ENABLED
5163 flags
& MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
5164 ? ", quiesced" : "",
5165 flags
& MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
5166 ? ", resync in progress" : "" );
5169 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED
:
5170 printk(MYIOC_s_INFO_FMT
" volume membership of PhysDisk %d has changed\n",
5174 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED
:
5175 printk(MYIOC_s_INFO_FMT
" PhysDisk has been created\n",
5179 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED
:
5180 printk(MYIOC_s_INFO_FMT
" PhysDisk has been deleted\n",
5184 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED
:
5185 printk(MYIOC_s_INFO_FMT
" PhysDisk settings have been changed\n",
5189 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
:
5190 printk(MYIOC_s_INFO_FMT
" PhysDisk is now %s%s%s\n",
5192 state
== MPI_PHYSDISK0_STATUS_ONLINE
5194 : state
== MPI_PHYSDISK0_STATUS_MISSING
5196 : state
== MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
5198 : state
== MPI_PHYSDISK0_STATUS_FAILED
5200 : state
== MPI_PHYSDISK0_STATUS_INITIALIZING
5202 : state
== MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
5203 ? "offline requested"
5204 : state
== MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
5205 ? "failed requested"
5206 : state
== MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
5209 flags
& MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
5210 ? ", out of sync" : "",
5211 flags
& MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
5212 ? ", quiesced" : "" );
5215 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
:
5216 printk(MYIOC_s_INFO_FMT
" Domain Validation needed for PhysDisk %d\n",
5220 case MPI_EVENT_RAID_RC_SMART_DATA
:
5221 printk(MYIOC_s_INFO_FMT
" SMART data received, ASC/ASCQ = %02xh/%02xh\n",
5222 ioc
->name
, pRaidEventData
->ASC
, pRaidEventData
->ASCQ
);
5225 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED
:
5226 printk(MYIOC_s_INFO_FMT
" replacement of PhysDisk %d has started\n",
5232 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5234 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
5235 * @ioc: Pointer to MPT_ADAPTER structure
5237 * Returns: 0 for success
5238 * -ENOMEM if no memory available
5239 * -EPERM if not allowed due to ISR context
5240 * -EAGAIN if no msg frames currently available
5241 * -EFAULT for non-successful reply or no reply (timeout)
5244 GetIoUnitPage2(MPT_ADAPTER
*ioc
)
5246 ConfigPageHeader_t hdr
;
5248 IOUnitPage2_t
*ppage_alloc
;
5249 dma_addr_t page_dma
;
5253 /* Get the page header */
5254 hdr
.PageVersion
= 0;
5257 hdr
.PageType
= MPI_CONFIG_PAGETYPE_IO_UNIT
;
5258 cfg
.cfghdr
.hdr
= &hdr
;
5260 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5265 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
5268 if (hdr
.PageLength
== 0)
5271 /* Read the config page */
5272 data_sz
= hdr
.PageLength
* 4;
5274 ppage_alloc
= (IOUnitPage2_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page_dma
);
5276 memset((u8
*)ppage_alloc
, 0, data_sz
);
5277 cfg
.physAddr
= page_dma
;
5278 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5280 /* If Good, save data */
5281 if ((rc
= mpt_config(ioc
, &cfg
)) == 0)
5282 ioc
->biosVersion
= le32_to_cpu(ppage_alloc
->BiosVersion
);
5284 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage_alloc
, page_dma
);
5290 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5292 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
5293 * @ioc: Pointer to a Adapter Strucutre
5294 * @portnum: IOC port number
5296 * Return: -EFAULT if read of config page header fails
5298 * If read of SCSI Port Page 0 fails,
5299 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5300 * Adapter settings: async, narrow
5302 * If read of SCSI Port Page 2 fails,
5303 * Adapter settings valid
5304 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5309 * CHECK - what type of locking mechanisms should be used????
5312 mpt_GetScsiPortSettings(MPT_ADAPTER
*ioc
, int portnum
)
5317 ConfigPageHeader_t header
;
5323 if (!ioc
->spi_data
.nvram
) {
5326 sz
= MPT_MAX_SCSI_DEVICES
* sizeof(int);
5327 mem
= kmalloc(sz
, GFP_ATOMIC
);
5331 ioc
->spi_data
.nvram
= (int *) mem
;
5333 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SCSI device NVRAM settings @ %p, sz=%d\n",
5334 ioc
->name
, ioc
->spi_data
.nvram
, sz
));
5337 /* Invalidate NVRAM information
5339 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
5340 ioc
->spi_data
.nvram
[ii
] = MPT_HOST_NVRAM_INVALID
;
5343 /* Read SPP0 header, allocate memory, then read page.
5345 header
.PageVersion
= 0;
5346 header
.PageLength
= 0;
5347 header
.PageNumber
= 0;
5348 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_PORT
;
5349 cfg
.cfghdr
.hdr
= &header
;
5351 cfg
.pageAddr
= portnum
;
5352 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5354 cfg
.timeout
= 0; /* use default */
5355 if (mpt_config(ioc
, &cfg
) != 0)
5358 if (header
.PageLength
> 0) {
5359 pbuf
= pci_alloc_consistent(ioc
->pcidev
, header
.PageLength
* 4, &buf_dma
);
5361 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5362 cfg
.physAddr
= buf_dma
;
5363 if (mpt_config(ioc
, &cfg
) != 0) {
5364 ioc
->spi_data
.maxBusWidth
= MPT_NARROW
;
5365 ioc
->spi_data
.maxSyncOffset
= 0;
5366 ioc
->spi_data
.minSyncFactor
= MPT_ASYNC
;
5367 ioc
->spi_data
.busType
= MPT_HOST_BUS_UNKNOWN
;
5369 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5370 "Unable to read PortPage0 minSyncFactor=%x\n",
5371 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
5373 /* Save the Port Page 0 data
5375 SCSIPortPage0_t
*pPP0
= (SCSIPortPage0_t
*) pbuf
;
5376 pPP0
->Capabilities
= le32_to_cpu(pPP0
->Capabilities
);
5377 pPP0
->PhysicalInterface
= le32_to_cpu(pPP0
->PhysicalInterface
);
5379 if ( (pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_QAS
) == 0 ) {
5380 ioc
->spi_data
.noQas
|= MPT_TARGET_NO_NEGO_QAS
;
5381 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5382 "noQas due to Capabilities=%x\n",
5383 ioc
->name
, pPP0
->Capabilities
));
5385 ioc
->spi_data
.maxBusWidth
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_WIDE
? 1 : 0;
5386 data
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK
;
5388 ioc
->spi_data
.maxSyncOffset
= (u8
) (data
>> 16);
5389 data
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK
;
5390 ioc
->spi_data
.minSyncFactor
= (u8
) (data
>> 8);
5391 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5392 "PortPage0 minSyncFactor=%x\n",
5393 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
5395 ioc
->spi_data
.maxSyncOffset
= 0;
5396 ioc
->spi_data
.minSyncFactor
= MPT_ASYNC
;
5399 ioc
->spi_data
.busType
= pPP0
->PhysicalInterface
& MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK
;
5401 /* Update the minSyncFactor based on bus type.
5403 if ((ioc
->spi_data
.busType
== MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD
) ||
5404 (ioc
->spi_data
.busType
== MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE
)) {
5406 if (ioc
->spi_data
.minSyncFactor
< MPT_ULTRA
) {
5407 ioc
->spi_data
.minSyncFactor
= MPT_ULTRA
;
5408 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5409 "HVD or SE detected, minSyncFactor=%x\n",
5410 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
5415 pci_free_consistent(ioc
->pcidev
, header
.PageLength
* 4, pbuf
, buf_dma
);
5420 /* SCSI Port Page 2 - Read the header then the page.
5422 header
.PageVersion
= 0;
5423 header
.PageLength
= 0;
5424 header
.PageNumber
= 2;
5425 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_PORT
;
5426 cfg
.cfghdr
.hdr
= &header
;
5428 cfg
.pageAddr
= portnum
;
5429 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5431 if (mpt_config(ioc
, &cfg
) != 0)
5434 if (header
.PageLength
> 0) {
5435 /* Allocate memory and read SCSI Port Page 2
5437 pbuf
= pci_alloc_consistent(ioc
->pcidev
, header
.PageLength
* 4, &buf_dma
);
5439 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_NVRAM
;
5440 cfg
.physAddr
= buf_dma
;
5441 if (mpt_config(ioc
, &cfg
) != 0) {
5442 /* Nvram data is left with INVALID mark
5445 } else if (ioc
->pcidev
->vendor
== PCI_VENDOR_ID_ATTO
) {
5447 /* This is an ATTO adapter, read Page2 accordingly
5449 ATTO_SCSIPortPage2_t
*pPP2
= (ATTO_SCSIPortPage2_t
*) pbuf
;
5450 ATTODeviceInfo_t
*pdevice
= NULL
;
5453 /* Save the Port Page 2 data
5454 * (reformat into a 32bit quantity)
5456 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
5457 pdevice
= &pPP2
->DeviceSettings
[ii
];
5458 ATTOFlags
= le16_to_cpu(pdevice
->ATTOFlags
);
5461 /* Translate ATTO device flags to LSI format
5463 if (ATTOFlags
& ATTOFLAG_DISC
)
5464 data
|= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE
);
5465 if (ATTOFlags
& ATTOFLAG_ID_ENB
)
5466 data
|= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE
);
5467 if (ATTOFlags
& ATTOFLAG_LUN_ENB
)
5468 data
|= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE
);
5469 if (ATTOFlags
& ATTOFLAG_TAGGED
)
5470 data
|= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE
);
5471 if (!(ATTOFlags
& ATTOFLAG_WIDE_ENB
))
5472 data
|= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE
);
5474 data
= (data
<< 16) | (pdevice
->Period
<< 8) | 10;
5475 ioc
->spi_data
.nvram
[ii
] = data
;
5478 SCSIPortPage2_t
*pPP2
= (SCSIPortPage2_t
*) pbuf
;
5479 MpiDeviceInfo_t
*pdevice
= NULL
;
5482 * Save "Set to Avoid SCSI Bus Resets" flag
5484 ioc
->spi_data
.bus_reset
=
5485 (le32_to_cpu(pPP2
->PortFlags
) &
5486 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET
) ?
5489 /* Save the Port Page 2 data
5490 * (reformat into a 32bit quantity)
5492 data
= le32_to_cpu(pPP2
->PortFlags
) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK
;
5493 ioc
->spi_data
.PortFlags
= data
;
5494 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
5495 pdevice
= &pPP2
->DeviceSettings
[ii
];
5496 data
= (le16_to_cpu(pdevice
->DeviceFlags
) << 16) |
5497 (pdevice
->SyncFactor
<< 8) | pdevice
->Timeout
;
5498 ioc
->spi_data
.nvram
[ii
] = data
;
5502 pci_free_consistent(ioc
->pcidev
, header
.PageLength
* 4, pbuf
, buf_dma
);
5506 /* Update Adapter limits with those from NVRAM
5507 * Comment: Don't need to do this. Target performance
5508 * parameters will never exceed the adapters limits.
5514 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5516 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
5517 * @ioc: Pointer to a Adapter Strucutre
5518 * @portnum: IOC port number
5520 * Return: -EFAULT if read of config page header fails
5524 mpt_readScsiDevicePageHeaders(MPT_ADAPTER
*ioc
, int portnum
)
5527 ConfigPageHeader_t header
;
5529 /* Read the SCSI Device Page 1 header
5531 header
.PageVersion
= 0;
5532 header
.PageLength
= 0;
5533 header
.PageNumber
= 1;
5534 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_DEVICE
;
5535 cfg
.cfghdr
.hdr
= &header
;
5537 cfg
.pageAddr
= portnum
;
5538 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5541 if (mpt_config(ioc
, &cfg
) != 0)
5544 ioc
->spi_data
.sdp1version
= cfg
.cfghdr
.hdr
->PageVersion
;
5545 ioc
->spi_data
.sdp1length
= cfg
.cfghdr
.hdr
->PageLength
;
5547 header
.PageVersion
= 0;
5548 header
.PageLength
= 0;
5549 header
.PageNumber
= 0;
5550 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_DEVICE
;
5551 if (mpt_config(ioc
, &cfg
) != 0)
5554 ioc
->spi_data
.sdp0version
= cfg
.cfghdr
.hdr
->PageVersion
;
5555 ioc
->spi_data
.sdp0length
= cfg
.cfghdr
.hdr
->PageLength
;
5557 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Headers: 0: version %d length %d\n",
5558 ioc
->name
, ioc
->spi_data
.sdp0version
, ioc
->spi_data
.sdp0length
));
5560 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Headers: 1: version %d length %d\n",
5561 ioc
->name
, ioc
->spi_data
.sdp1version
, ioc
->spi_data
.sdp1length
));
5566 * mpt_inactive_raid_list_free - This clears this link list.
5567 * @ioc : pointer to per adapter structure
5570 mpt_inactive_raid_list_free(MPT_ADAPTER
*ioc
)
5572 struct inactive_raid_component_info
*component_info
, *pNext
;
5574 if (list_empty(&ioc
->raid_data
.inactive_list
))
5577 mutex_lock(&ioc
->raid_data
.inactive_list_mutex
);
5578 list_for_each_entry_safe(component_info
, pNext
,
5579 &ioc
->raid_data
.inactive_list
, list
) {
5580 list_del(&component_info
->list
);
5581 kfree(component_info
);
5583 mutex_unlock(&ioc
->raid_data
.inactive_list_mutex
);
5587 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5589 * @ioc : pointer to per adapter structure
5590 * @channel : volume channel
5591 * @id : volume target id
5594 mpt_inactive_raid_volumes(MPT_ADAPTER
*ioc
, u8 channel
, u8 id
)
5597 ConfigPageHeader_t hdr
;
5598 dma_addr_t dma_handle
;
5599 pRaidVolumePage0_t buffer
= NULL
;
5601 RaidPhysDiskPage0_t phys_disk
;
5602 struct inactive_raid_component_info
*component_info
;
5603 int handle_inactive_volumes
;
5605 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5606 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5607 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_VOLUME
;
5608 cfg
.pageAddr
= (channel
<< 8) + id
;
5609 cfg
.cfghdr
.hdr
= &hdr
;
5610 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5612 if (mpt_config(ioc
, &cfg
) != 0)
5615 if (!hdr
.PageLength
)
5618 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5624 cfg
.physAddr
= dma_handle
;
5625 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5627 if (mpt_config(ioc
, &cfg
) != 0)
5630 if (!buffer
->NumPhysDisks
)
5633 handle_inactive_volumes
=
5634 (buffer
->VolumeStatus
.Flags
& MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE
||
5635 (buffer
->VolumeStatus
.Flags
& MPI_RAIDVOL0_STATUS_FLAG_ENABLED
) == 0 ||
5636 buffer
->VolumeStatus
.State
== MPI_RAIDVOL0_STATUS_STATE_FAILED
||
5637 buffer
->VolumeStatus
.State
== MPI_RAIDVOL0_STATUS_STATE_MISSING
) ? 1 : 0;
5639 if (!handle_inactive_volumes
)
5642 mutex_lock(&ioc
->raid_data
.inactive_list_mutex
);
5643 for (i
= 0; i
< buffer
->NumPhysDisks
; i
++) {
5644 if(mpt_raid_phys_disk_pg0(ioc
,
5645 buffer
->PhysDisk
[i
].PhysDiskNum
, &phys_disk
) != 0)
5648 if ((component_info
= kmalloc(sizeof (*component_info
),
5649 GFP_KERNEL
)) == NULL
)
5652 component_info
->volumeID
= id
;
5653 component_info
->volumeBus
= channel
;
5654 component_info
->d
.PhysDiskNum
= phys_disk
.PhysDiskNum
;
5655 component_info
->d
.PhysDiskBus
= phys_disk
.PhysDiskBus
;
5656 component_info
->d
.PhysDiskID
= phys_disk
.PhysDiskID
;
5657 component_info
->d
.PhysDiskIOC
= phys_disk
.PhysDiskIOC
;
5659 list_add_tail(&component_info
->list
,
5660 &ioc
->raid_data
.inactive_list
);
5662 mutex_unlock(&ioc
->raid_data
.inactive_list_mutex
);
5666 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5671 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5672 * @ioc: Pointer to a Adapter Structure
5673 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5674 * @phys_disk: requested payload data returned
5678 * -EFAULT if read of config page header fails or data pointer not NULL
5679 * -ENOMEM if pci_alloc failed
5682 mpt_raid_phys_disk_pg0(MPT_ADAPTER
*ioc
, u8 phys_disk_num
,
5683 RaidPhysDiskPage0_t
*phys_disk
)
5686 ConfigPageHeader_t hdr
;
5687 dma_addr_t dma_handle
;
5688 pRaidPhysDiskPage0_t buffer
= NULL
;
5691 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5692 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5693 memset(phys_disk
, 0, sizeof(RaidPhysDiskPage0_t
));
5695 hdr
.PageVersion
= MPI_RAIDPHYSDISKPAGE0_PAGEVERSION
;
5696 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_PHYSDISK
;
5697 cfg
.cfghdr
.hdr
= &hdr
;
5699 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5701 if (mpt_config(ioc
, &cfg
) != 0) {
5706 if (!hdr
.PageLength
) {
5711 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5719 cfg
.physAddr
= dma_handle
;
5720 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5721 cfg
.pageAddr
= phys_disk_num
;
5723 if (mpt_config(ioc
, &cfg
) != 0) {
5729 memcpy(phys_disk
, buffer
, sizeof(*buffer
));
5730 phys_disk
->MaxLBA
= le32_to_cpu(buffer
->MaxLBA
);
5735 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5742 * mpt_raid_phys_disk_get_num_paths - returns number paths associated to this phys_num
5743 * @ioc: Pointer to a Adapter Structure
5744 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5747 * returns number paths
5750 mpt_raid_phys_disk_get_num_paths(MPT_ADAPTER
*ioc
, u8 phys_disk_num
)
5753 ConfigPageHeader_t hdr
;
5754 dma_addr_t dma_handle
;
5755 pRaidPhysDiskPage1_t buffer
= NULL
;
5758 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5759 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5761 hdr
.PageVersion
= MPI_RAIDPHYSDISKPAGE1_PAGEVERSION
;
5762 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_PHYSDISK
;
5764 cfg
.cfghdr
.hdr
= &hdr
;
5766 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5768 if (mpt_config(ioc
, &cfg
) != 0) {
5773 if (!hdr
.PageLength
) {
5778 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5786 cfg
.physAddr
= dma_handle
;
5787 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5788 cfg
.pageAddr
= phys_disk_num
;
5790 if (mpt_config(ioc
, &cfg
) != 0) {
5795 rc
= buffer
->NumPhysDiskPaths
;
5799 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5804 EXPORT_SYMBOL(mpt_raid_phys_disk_get_num_paths
);
5807 * mpt_raid_phys_disk_pg1 - returns phys disk page 1
5808 * @ioc: Pointer to a Adapter Structure
5809 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5810 * @phys_disk: requested payload data returned
5814 * -EFAULT if read of config page header fails or data pointer not NULL
5815 * -ENOMEM if pci_alloc failed
5818 mpt_raid_phys_disk_pg1(MPT_ADAPTER
*ioc
, u8 phys_disk_num
,
5819 RaidPhysDiskPage1_t
*phys_disk
)
5822 ConfigPageHeader_t hdr
;
5823 dma_addr_t dma_handle
;
5824 pRaidPhysDiskPage1_t buffer
= NULL
;
5829 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5830 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5833 hdr
.PageVersion
= MPI_RAIDPHYSDISKPAGE1_PAGEVERSION
;
5834 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_PHYSDISK
;
5836 cfg
.cfghdr
.hdr
= &hdr
;
5838 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5840 if (mpt_config(ioc
, &cfg
) != 0) {
5845 if (!hdr
.PageLength
) {
5850 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5858 cfg
.physAddr
= dma_handle
;
5859 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5860 cfg
.pageAddr
= phys_disk_num
;
5862 if (mpt_config(ioc
, &cfg
) != 0) {
5867 phys_disk
->NumPhysDiskPaths
= buffer
->NumPhysDiskPaths
;
5868 phys_disk
->PhysDiskNum
= phys_disk_num
;
5869 for (i
= 0; i
< phys_disk
->NumPhysDiskPaths
; i
++) {
5870 phys_disk
->Path
[i
].PhysDiskID
= buffer
->Path
[i
].PhysDiskID
;
5871 phys_disk
->Path
[i
].PhysDiskBus
= buffer
->Path
[i
].PhysDiskBus
;
5872 phys_disk
->Path
[i
].OwnerIdentifier
=
5873 buffer
->Path
[i
].OwnerIdentifier
;
5874 phys_disk
->Path
[i
].Flags
= le16_to_cpu(buffer
->Path
[i
].Flags
);
5875 memcpy(&sas_address
, &buffer
->Path
[i
].WWID
, sizeof(__le64
));
5876 sas_address
= le64_to_cpu(sas_address
);
5877 memcpy(&phys_disk
->Path
[i
].WWID
, &sas_address
, sizeof(__le64
));
5878 memcpy(&sas_address
,
5879 &buffer
->Path
[i
].OwnerWWID
, sizeof(__le64
));
5880 sas_address
= le64_to_cpu(sas_address
);
5881 memcpy(&phys_disk
->Path
[i
].OwnerWWID
,
5882 &sas_address
, sizeof(__le64
));
5888 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5893 EXPORT_SYMBOL(mpt_raid_phys_disk_pg1
);
5897 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5898 * @ioc: Pointer to a Adapter Strucutre
5902 * -EFAULT if read of config page header fails or data pointer not NULL
5903 * -ENOMEM if pci_alloc failed
5906 mpt_findImVolumes(MPT_ADAPTER
*ioc
)
5910 dma_addr_t ioc2_dma
;
5912 ConfigPageHeader_t header
;
5917 if (!ioc
->ir_firmware
)
5920 /* Free the old page
5922 kfree(ioc
->raid_data
.pIocPg2
);
5923 ioc
->raid_data
.pIocPg2
= NULL
;
5924 mpt_inactive_raid_list_free(ioc
);
5926 /* Read IOCP2 header then the page.
5928 header
.PageVersion
= 0;
5929 header
.PageLength
= 0;
5930 header
.PageNumber
= 2;
5931 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
5932 cfg
.cfghdr
.hdr
= &header
;
5935 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5938 if (mpt_config(ioc
, &cfg
) != 0)
5941 if (header
.PageLength
== 0)
5944 iocpage2sz
= header
.PageLength
* 4;
5945 pIoc2
= pci_alloc_consistent(ioc
->pcidev
, iocpage2sz
, &ioc2_dma
);
5949 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5950 cfg
.physAddr
= ioc2_dma
;
5951 if (mpt_config(ioc
, &cfg
) != 0)
5954 mem
= kmalloc(iocpage2sz
, GFP_KERNEL
);
5958 memcpy(mem
, (u8
*)pIoc2
, iocpage2sz
);
5959 ioc
->raid_data
.pIocPg2
= (IOCPage2_t
*) mem
;
5961 mpt_read_ioc_pg_3(ioc
);
5963 for (i
= 0; i
< pIoc2
->NumActiveVolumes
; i
++)
5964 mpt_inactive_raid_volumes(ioc
,
5965 pIoc2
->RaidVolume
[i
].VolumeBus
,
5966 pIoc2
->RaidVolume
[i
].VolumeID
);
5969 pci_free_consistent(ioc
->pcidev
, iocpage2sz
, pIoc2
, ioc2_dma
);
5975 mpt_read_ioc_pg_3(MPT_ADAPTER
*ioc
)
5980 ConfigPageHeader_t header
;
5981 dma_addr_t ioc3_dma
;
5984 /* Free the old page
5986 kfree(ioc
->raid_data
.pIocPg3
);
5987 ioc
->raid_data
.pIocPg3
= NULL
;
5989 /* There is at least one physical disk.
5990 * Read and save IOC Page 3
5992 header
.PageVersion
= 0;
5993 header
.PageLength
= 0;
5994 header
.PageNumber
= 3;
5995 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
5996 cfg
.cfghdr
.hdr
= &header
;
5999 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
6002 if (mpt_config(ioc
, &cfg
) != 0)
6005 if (header
.PageLength
== 0)
6008 /* Read Header good, alloc memory
6010 iocpage3sz
= header
.PageLength
* 4;
6011 pIoc3
= pci_alloc_consistent(ioc
->pcidev
, iocpage3sz
, &ioc3_dma
);
6015 /* Read the Page and save the data
6016 * into malloc'd memory.
6018 cfg
.physAddr
= ioc3_dma
;
6019 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
6020 if (mpt_config(ioc
, &cfg
) == 0) {
6021 mem
= kmalloc(iocpage3sz
, GFP_KERNEL
);
6023 memcpy(mem
, (u8
*)pIoc3
, iocpage3sz
);
6024 ioc
->raid_data
.pIocPg3
= (IOCPage3_t
*) mem
;
6028 pci_free_consistent(ioc
->pcidev
, iocpage3sz
, pIoc3
, ioc3_dma
);
6034 mpt_read_ioc_pg_4(MPT_ADAPTER
*ioc
)
6038 ConfigPageHeader_t header
;
6039 dma_addr_t ioc4_dma
;
6042 /* Read and save IOC Page 4
6044 header
.PageVersion
= 0;
6045 header
.PageLength
= 0;
6046 header
.PageNumber
= 4;
6047 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
6048 cfg
.cfghdr
.hdr
= &header
;
6051 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
6054 if (mpt_config(ioc
, &cfg
) != 0)
6057 if (header
.PageLength
== 0)
6060 if ( (pIoc4
= ioc
->spi_data
.pIocPg4
) == NULL
) {
6061 iocpage4sz
= (header
.PageLength
+ 4) * 4; /* Allow 4 additional SEP's */
6062 pIoc4
= pci_alloc_consistent(ioc
->pcidev
, iocpage4sz
, &ioc4_dma
);
6065 ioc
->alloc_total
+= iocpage4sz
;
6067 ioc4_dma
= ioc
->spi_data
.IocPg4_dma
;
6068 iocpage4sz
= ioc
->spi_data
.IocPg4Sz
;
6071 /* Read the Page into dma memory.
6073 cfg
.physAddr
= ioc4_dma
;
6074 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
6075 if (mpt_config(ioc
, &cfg
) == 0) {
6076 ioc
->spi_data
.pIocPg4
= (IOCPage4_t
*) pIoc4
;
6077 ioc
->spi_data
.IocPg4_dma
= ioc4_dma
;
6078 ioc
->spi_data
.IocPg4Sz
= iocpage4sz
;
6080 pci_free_consistent(ioc
->pcidev
, iocpage4sz
, pIoc4
, ioc4_dma
);
6081 ioc
->spi_data
.pIocPg4
= NULL
;
6082 ioc
->alloc_total
-= iocpage4sz
;
6087 mpt_read_ioc_pg_1(MPT_ADAPTER
*ioc
)
6091 ConfigPageHeader_t header
;
6092 dma_addr_t ioc1_dma
;
6096 /* Check the Coalescing Timeout in IOC Page 1
6098 header
.PageVersion
= 0;
6099 header
.PageLength
= 0;
6100 header
.PageNumber
= 1;
6101 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
6102 cfg
.cfghdr
.hdr
= &header
;
6105 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
6108 if (mpt_config(ioc
, &cfg
) != 0)
6111 if (header
.PageLength
== 0)
6114 /* Read Header good, alloc memory
6116 iocpage1sz
= header
.PageLength
* 4;
6117 pIoc1
= pci_alloc_consistent(ioc
->pcidev
, iocpage1sz
, &ioc1_dma
);
6121 /* Read the Page and check coalescing timeout
6123 cfg
.physAddr
= ioc1_dma
;
6124 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
6125 if (mpt_config(ioc
, &cfg
) == 0) {
6127 tmp
= le32_to_cpu(pIoc1
->Flags
) & MPI_IOCPAGE1_REPLY_COALESCING
;
6128 if (tmp
== MPI_IOCPAGE1_REPLY_COALESCING
) {
6129 tmp
= le32_to_cpu(pIoc1
->CoalescingTimeout
);
6131 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Coalescing Enabled Timeout = %d\n",
6134 if (tmp
> MPT_COALESCING_TIMEOUT
) {
6135 pIoc1
->CoalescingTimeout
= cpu_to_le32(MPT_COALESCING_TIMEOUT
);
6137 /* Write NVRAM and current
6140 cfg
.action
= MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT
;
6141 if (mpt_config(ioc
, &cfg
) == 0) {
6142 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Reset Current Coalescing Timeout to = %d\n",
6143 ioc
->name
, MPT_COALESCING_TIMEOUT
));
6145 cfg
.action
= MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM
;
6146 if (mpt_config(ioc
, &cfg
) == 0) {
6147 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6148 "Reset NVRAM Coalescing Timeout to = %d\n",
6149 ioc
->name
, MPT_COALESCING_TIMEOUT
));
6151 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6152 "Reset NVRAM Coalescing Timeout Failed\n",
6157 dprintk(ioc
, printk(MYIOC_s_WARN_FMT
6158 "Reset of Current Coalescing Timeout Failed!\n",
6164 dprintk(ioc
, printk(MYIOC_s_WARN_FMT
"Coalescing Disabled\n", ioc
->name
));
6168 pci_free_consistent(ioc
->pcidev
, iocpage1sz
, pIoc1
, ioc1_dma
);
6174 mpt_get_manufacturing_pg_0(MPT_ADAPTER
*ioc
)
6177 ConfigPageHeader_t hdr
;
6179 ManufacturingPage0_t
*pbuf
= NULL
;
6181 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
6182 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
6184 hdr
.PageType
= MPI_CONFIG_PAGETYPE_MANUFACTURING
;
6185 cfg
.cfghdr
.hdr
= &hdr
;
6187 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
6190 if (mpt_config(ioc
, &cfg
) != 0)
6193 if (!cfg
.cfghdr
.hdr
->PageLength
)
6196 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
6197 pbuf
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, &buf_dma
);
6201 cfg
.physAddr
= buf_dma
;
6203 if (mpt_config(ioc
, &cfg
) != 0)
6206 memcpy(ioc
->board_name
, pbuf
->BoardName
, sizeof(ioc
->board_name
));
6207 memcpy(ioc
->board_assembly
, pbuf
->BoardAssembly
, sizeof(ioc
->board_assembly
));
6208 memcpy(ioc
->board_tracer
, pbuf
->BoardTracerNumber
, sizeof(ioc
->board_tracer
));
6213 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, pbuf
, buf_dma
);
6216 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6218 * SendEventNotification - Send EventNotification (on or off) request to adapter
6219 * @ioc: Pointer to MPT_ADAPTER structure
6220 * @EvSwitch: Event switch flags
6221 * @sleepFlag: Specifies whether the process can sleep
6224 SendEventNotification(MPT_ADAPTER
*ioc
, u8 EvSwitch
, int sleepFlag
)
6226 EventNotification_t evn
;
6227 MPIDefaultReply_t reply_buf
;
6229 memset(&evn
, 0, sizeof(EventNotification_t
));
6230 memset(&reply_buf
, 0, sizeof(MPIDefaultReply_t
));
6232 evn
.Function
= MPI_FUNCTION_EVENT_NOTIFICATION
;
6233 evn
.Switch
= EvSwitch
;
6234 evn
.MsgContext
= cpu_to_le32(mpt_base_index
<< 16);
6236 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6237 "Sending EventNotification (%d) request %p\n",
6238 ioc
->name
, EvSwitch
, &evn
));
6240 return mpt_handshake_req_reply_wait(ioc
, sizeof(EventNotification_t
),
6241 (u32
*)&evn
, sizeof(MPIDefaultReply_t
), (u16
*)&reply_buf
, 30,
6245 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6247 * SendEventAck - Send EventAck request to MPT adapter.
6248 * @ioc: Pointer to MPT_ADAPTER structure
6249 * @evnp: Pointer to original EventNotification request
6252 SendEventAck(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*evnp
)
6256 if ((pAck
= (EventAck_t
*) mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
6257 dfailprintk(ioc
, printk(MYIOC_s_WARN_FMT
"%s, no msg frames!!\n",
6258 ioc
->name
, __func__
));
6262 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending EventAck\n", ioc
->name
));
6264 pAck
->Function
= MPI_FUNCTION_EVENT_ACK
;
6265 pAck
->ChainOffset
= 0;
6266 pAck
->Reserved
[0] = pAck
->Reserved
[1] = 0;
6268 pAck
->Reserved1
[0] = pAck
->Reserved1
[1] = pAck
->Reserved1
[2] = 0;
6269 pAck
->Event
= evnp
->Event
;
6270 pAck
->EventContext
= evnp
->EventContext
;
6272 mpt_put_msg_frame(mpt_base_index
, ioc
, (MPT_FRAME_HDR
*)pAck
);
6277 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6279 * mpt_config - Generic function to issue config message
6280 * @ioc: Pointer to an adapter structure
6281 * @pCfg: Pointer to a configuration structure. Struct contains
6282 * action, page address, direction, physical address
6283 * and pointer to a configuration page header
6284 * Page header is updated.
6286 * Returns 0 for success
6287 * -EPERM if not allowed due to ISR context
6288 * -EAGAIN if no msg frames currently available
6289 * -EFAULT for non-successful reply or no reply (timeout)
6292 mpt_config(MPT_ADAPTER
*ioc
, CONFIGPARMS
*pCfg
)
6295 ConfigReply_t
*pReply
;
6296 ConfigExtendedPageHeader_t
*pExtHdr
= NULL
;
6302 u8 page_type
= 0, extend_page
;
6303 unsigned long timeleft
;
6304 unsigned long flags
;
6306 u8 issue_hard_reset
= 0;
6309 /* Prevent calling wait_event() (below), if caller happens
6310 * to be in ISR context, because that is fatal!
6312 in_isr
= in_interrupt();
6314 dcprintk(ioc
, printk(MYIOC_s_WARN_FMT
"Config request not allowed in ISR context!\n",
6319 /* don't send a config page during diag reset */
6320 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
6321 if (ioc
->ioc_reset_in_progress
) {
6322 dfailprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6323 "%s: busy with host reset\n", ioc
->name
, __func__
));
6324 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6327 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6329 /* don't send if no chance of success */
6331 mpt_GetIocState(ioc
, 1) != MPI_IOC_STATE_OPERATIONAL
) {
6332 dfailprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6333 "%s: ioc not operational, %d, %xh\n",
6334 ioc
->name
, __func__
, ioc
->active
,
6335 mpt_GetIocState(ioc
, 0)));
6340 mutex_lock(&ioc
->mptbase_cmds
.mutex
);
6341 /* init the internal cmd struct */
6342 memset(ioc
->mptbase_cmds
.reply
, 0 , MPT_DEFAULT_FRAME_SIZE
);
6343 INITIALIZE_MGMT_STATUS(ioc
->mptbase_cmds
.status
)
6345 /* Get and Populate a free Frame
6347 if ((mf
= mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
6348 dcprintk(ioc
, printk(MYIOC_s_WARN_FMT
6349 "mpt_config: no msg frames!\n", ioc
->name
));
6354 pReq
= (Config_t
*)mf
;
6355 pReq
->Action
= pCfg
->action
;
6357 pReq
->ChainOffset
= 0;
6358 pReq
->Function
= MPI_FUNCTION_CONFIG
;
6360 /* Assume page type is not extended and clear "reserved" fields. */
6361 pReq
->ExtPageLength
= 0;
6362 pReq
->ExtPageType
= 0;
6365 for (ii
=0; ii
< 8; ii
++)
6366 pReq
->Reserved2
[ii
] = 0;
6368 pReq
->Header
.PageVersion
= pCfg
->cfghdr
.hdr
->PageVersion
;
6369 pReq
->Header
.PageLength
= pCfg
->cfghdr
.hdr
->PageLength
;
6370 pReq
->Header
.PageNumber
= pCfg
->cfghdr
.hdr
->PageNumber
;
6371 pReq
->Header
.PageType
= (pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
);
6373 if ((pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
) == MPI_CONFIG_PAGETYPE_EXTENDED
) {
6374 pExtHdr
= (ConfigExtendedPageHeader_t
*)pCfg
->cfghdr
.ehdr
;
6375 pReq
->ExtPageLength
= cpu_to_le16(pExtHdr
->ExtPageLength
);
6376 pReq
->ExtPageType
= pExtHdr
->ExtPageType
;
6377 pReq
->Header
.PageType
= MPI_CONFIG_PAGETYPE_EXTENDED
;
6379 /* Page Length must be treated as a reserved field for the
6382 pReq
->Header
.PageLength
= 0;
6385 pReq
->PageAddress
= cpu_to_le32(pCfg
->pageAddr
);
6387 /* Add a SGE to the config request.
6390 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_WRITE
;
6392 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_READ
;
6394 if ((pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
) ==
6395 MPI_CONFIG_PAGETYPE_EXTENDED
) {
6396 flagsLength
|= pExtHdr
->ExtPageLength
* 4;
6397 page_type
= pReq
->ExtPageType
;
6400 flagsLength
|= pCfg
->cfghdr
.hdr
->PageLength
* 4;
6401 page_type
= pReq
->Header
.PageType
;
6405 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6406 "Sending Config request type 0x%x, page 0x%x and action %d\n",
6407 ioc
->name
, page_type
, pReq
->Header
.PageNumber
, pReq
->Action
));
6409 ioc
->add_sge((char *)&pReq
->PageBufferSGE
, flagsLength
, pCfg
->physAddr
);
6410 timeout
= (pCfg
->timeout
< 15) ? HZ
*15 : HZ
*pCfg
->timeout
;
6411 mpt_put_msg_frame(mpt_base_index
, ioc
, mf
);
6412 timeleft
= wait_for_completion_timeout(&ioc
->mptbase_cmds
.done
,
6414 if (!(ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_COMMAND_GOOD
)) {
6416 dfailprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6417 "Failed Sending Config request type 0x%x, page 0x%x,"
6418 " action %d, status %xh, time left %ld\n\n",
6419 ioc
->name
, page_type
, pReq
->Header
.PageNumber
,
6420 pReq
->Action
, ioc
->mptbase_cmds
.status
, timeleft
));
6421 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_DID_IOCRESET
)
6424 issue_hard_reset
= 1;
6428 if (!(ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_RF_VALID
)) {
6432 pReply
= (ConfigReply_t
*)ioc
->mptbase_cmds
.reply
;
6433 ret
= le16_to_cpu(pReply
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
6434 if (ret
== MPI_IOCSTATUS_SUCCESS
) {
6436 pCfg
->cfghdr
.ehdr
->ExtPageLength
=
6437 le16_to_cpu(pReply
->ExtPageLength
);
6438 pCfg
->cfghdr
.ehdr
->ExtPageType
=
6439 pReply
->ExtPageType
;
6441 pCfg
->cfghdr
.hdr
->PageVersion
= pReply
->Header
.PageVersion
;
6442 pCfg
->cfghdr
.hdr
->PageLength
= pReply
->Header
.PageLength
;
6443 pCfg
->cfghdr
.hdr
->PageNumber
= pReply
->Header
.PageNumber
;
6444 pCfg
->cfghdr
.hdr
->PageType
= pReply
->Header
.PageType
;
6449 printk(MYIOC_s_INFO_FMT
"Retry completed "
6450 "ret=0x%x timeleft=%ld\n",
6451 ioc
->name
, ret
, timeleft
);
6453 dcprintk(ioc
, printk(KERN_DEBUG
"IOCStatus=%04xh, IOCLogInfo=%08xh\n",
6454 ret
, le32_to_cpu(pReply
->IOCLogInfo
)));
6458 CLEAR_MGMT_STATUS(ioc
->mptbase_cmds
.status
)
6459 mutex_unlock(&ioc
->mptbase_cmds
.mutex
);
6460 if (issue_hard_reset
) {
6461 issue_hard_reset
= 0;
6462 printk(MYIOC_s_WARN_FMT
6463 "Issuing Reset from %s!!, doorbell=0x%08x\n",
6464 ioc
->name
, __func__
, mpt_GetIocState(ioc
, 0));
6465 if (retry_count
== 0) {
6466 if (mpt_Soft_Hard_ResetHandler(ioc
, CAN_SLEEP
) != 0)
6469 mpt_HardResetHandler(ioc
, CAN_SLEEP
);
6471 mpt_free_msg_frame(ioc
, mf
);
6472 /* attempt one retry for a timed out command */
6473 if (retry_count
< 2) {
6474 printk(MYIOC_s_INFO_FMT
6475 "Attempting Retry Config request"
6476 " type 0x%x, page 0x%x,"
6477 " action %d\n", ioc
->name
, page_type
,
6478 pCfg
->cfghdr
.hdr
->PageNumber
, pCfg
->action
);
6487 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6489 * mpt_ioc_reset - Base cleanup for hard reset
6490 * @ioc: Pointer to the adapter structure
6491 * @reset_phase: Indicates pre- or post-reset functionality
6493 * Remark: Frees resources with internally generated commands.
6496 mpt_ioc_reset(MPT_ADAPTER
*ioc
, int reset_phase
)
6498 switch (reset_phase
) {
6499 case MPT_IOC_SETUP_RESET
:
6500 ioc
->taskmgmt_quiesce_io
= 1;
6501 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6502 "%s: MPT_IOC_SETUP_RESET\n", ioc
->name
, __func__
));
6504 case MPT_IOC_PRE_RESET
:
6505 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6506 "%s: MPT_IOC_PRE_RESET\n", ioc
->name
, __func__
));
6508 case MPT_IOC_POST_RESET
:
6509 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6510 "%s: MPT_IOC_POST_RESET\n", ioc
->name
, __func__
));
6511 /* wake up mptbase_cmds */
6512 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_PENDING
) {
6513 ioc
->mptbase_cmds
.status
|=
6514 MPT_MGMT_STATUS_DID_IOCRESET
;
6515 complete(&ioc
->mptbase_cmds
.done
);
6517 /* wake up taskmgmt_cmds */
6518 if (ioc
->taskmgmt_cmds
.status
& MPT_MGMT_STATUS_PENDING
) {
6519 ioc
->taskmgmt_cmds
.status
|=
6520 MPT_MGMT_STATUS_DID_IOCRESET
;
6521 complete(&ioc
->taskmgmt_cmds
.done
);
6528 return 1; /* currently means nothing really */
6532 #ifdef CONFIG_PROC_FS /* { */
6533 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6535 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
6537 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6539 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
6541 * Returns 0 for success, non-zero for failure.
6544 procmpt_create(void)
6546 struct proc_dir_entry
*ent
;
6548 mpt_proc_root_dir
= proc_mkdir(MPT_PROCFS_MPTBASEDIR
, NULL
);
6549 if (mpt_proc_root_dir
== NULL
)
6552 ent
= create_proc_entry("summary", S_IFREG
|S_IRUGO
, mpt_proc_root_dir
);
6554 ent
->read_proc
= procmpt_summary_read
;
6556 ent
= create_proc_entry("version", S_IFREG
|S_IRUGO
, mpt_proc_root_dir
);
6558 ent
->read_proc
= procmpt_version_read
;
6563 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6565 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
6567 * Returns 0 for success, non-zero for failure.
6570 procmpt_destroy(void)
6572 remove_proc_entry("version", mpt_proc_root_dir
);
6573 remove_proc_entry("summary", mpt_proc_root_dir
);
6574 remove_proc_entry(MPT_PROCFS_MPTBASEDIR
, NULL
);
6577 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6579 * procmpt_summary_read - Handle read request of a summary file
6580 * @buf: Pointer to area to write information
6581 * @start: Pointer to start pointer
6582 * @offset: Offset to start writing
6583 * @request: Amount of read data requested
6584 * @eof: Pointer to EOF integer
6587 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
6588 * Returns number of characters written to process performing the read.
6591 procmpt_summary_read(char *buf
, char **start
, off_t offset
, int request
, int *eof
, void *data
)
6601 mpt_print_ioc_summary(ioc
, out
, &more
, 0, 1);
6605 list_for_each_entry(ioc
, &ioc_list
, list
) {
6608 mpt_print_ioc_summary(ioc
, out
, &more
, 0, 1);
6611 if ((out
-buf
) >= request
)
6618 MPT_PROC_READ_RETURN(buf
,start
,offset
,request
,eof
,len
);
6621 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6623 * procmpt_version_read - Handle read request from /proc/mpt/version.
6624 * @buf: Pointer to area to write information
6625 * @start: Pointer to start pointer
6626 * @offset: Offset to start writing
6627 * @request: Amount of read data requested
6628 * @eof: Pointer to EOF integer
6631 * Returns number of characters written to process performing the read.
6634 procmpt_version_read(char *buf
, char **start
, off_t offset
, int request
, int *eof
, void *data
)
6637 int scsi
, fc
, sas
, lan
, ctl
, targ
, dmp
;
6641 len
= sprintf(buf
, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON
);
6642 len
+= sprintf(buf
+len
, " Fusion MPT base driver\n");
6644 scsi
= fc
= sas
= lan
= ctl
= targ
= dmp
= 0;
6645 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
6647 if (MptCallbacks
[cb_idx
]) {
6648 switch (MptDriverClass
[cb_idx
]) {
6650 if (!scsi
++) drvname
= "SPI host";
6653 if (!fc
++) drvname
= "FC host";
6656 if (!sas
++) drvname
= "SAS host";
6659 if (!lan
++) drvname
= "LAN";
6662 if (!targ
++) drvname
= "SCSI target";
6665 if (!ctl
++) drvname
= "ioctl";
6670 len
+= sprintf(buf
+len
, " Fusion MPT %s driver\n", drvname
);
6674 MPT_PROC_READ_RETURN(buf
,start
,offset
,request
,eof
,len
);
6677 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6679 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
6680 * @buf: Pointer to area to write information
6681 * @start: Pointer to start pointer
6682 * @offset: Offset to start writing
6683 * @request: Amount of read data requested
6684 * @eof: Pointer to EOF integer
6687 * Returns number of characters written to process performing the read.
6690 procmpt_iocinfo_read(char *buf
, char **start
, off_t offset
, int request
, int *eof
, void *data
)
6692 MPT_ADAPTER
*ioc
= data
;
6698 mpt_get_fw_exp_ver(expVer
, ioc
);
6700 len
= sprintf(buf
, "%s:", ioc
->name
);
6701 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)
6702 len
+= sprintf(buf
+len
, " (f/w download boot flag set)");
6703 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6704 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
6706 len
+= sprintf(buf
+len
, "\n ProductID = 0x%04x (%s)\n",
6707 ioc
->facts
.ProductID
,
6709 len
+= sprintf(buf
+len
, " FWVersion = 0x%08x%s", ioc
->facts
.FWVersion
.Word
, expVer
);
6710 if (ioc
->facts
.FWImageSize
)
6711 len
+= sprintf(buf
+len
, " (fw_size=%d)", ioc
->facts
.FWImageSize
);
6712 len
+= sprintf(buf
+len
, "\n MsgVersion = 0x%04x\n", ioc
->facts
.MsgVersion
);
6713 len
+= sprintf(buf
+len
, " FirstWhoInit = 0x%02x\n", ioc
->FirstWhoInit
);
6714 len
+= sprintf(buf
+len
, " EventState = 0x%02x\n", ioc
->facts
.EventState
);
6716 len
+= sprintf(buf
+len
, " CurrentHostMfaHighAddr = 0x%08x\n",
6717 ioc
->facts
.CurrentHostMfaHighAddr
);
6718 len
+= sprintf(buf
+len
, " CurrentSenseBufferHighAddr = 0x%08x\n",
6719 ioc
->facts
.CurrentSenseBufferHighAddr
);
6721 len
+= sprintf(buf
+len
, " MaxChainDepth = 0x%02x frames\n", ioc
->facts
.MaxChainDepth
);
6722 len
+= sprintf(buf
+len
, " MinBlockSize = 0x%02x bytes\n", 4*ioc
->facts
.BlockSize
);
6724 len
+= sprintf(buf
+len
, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6725 (void *)ioc
->req_frames
, (void *)(ulong
)ioc
->req_frames_dma
);
6727 * Rounding UP to nearest 4-kB boundary here...
6729 sz
= (ioc
->req_sz
* ioc
->req_depth
) + 128;
6730 sz
= ((sz
+ 0x1000UL
- 1UL) / 0x1000) * 0x1000;
6731 len
+= sprintf(buf
+len
, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6732 ioc
->req_sz
, ioc
->req_depth
, ioc
->req_sz
*ioc
->req_depth
, sz
);
6733 len
+= sprintf(buf
+len
, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
6734 4*ioc
->facts
.RequestFrameSize
,
6735 ioc
->facts
.GlobalCredits
);
6737 len
+= sprintf(buf
+len
, " Frames @ 0x%p (Dma @ 0x%p)\n",
6738 (void *)ioc
->alloc
, (void *)(ulong
)ioc
->alloc_dma
);
6739 sz
= (ioc
->reply_sz
* ioc
->reply_depth
) + 128;
6740 len
+= sprintf(buf
+len
, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6741 ioc
->reply_sz
, ioc
->reply_depth
, ioc
->reply_sz
*ioc
->reply_depth
, sz
);
6742 len
+= sprintf(buf
+len
, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
6743 ioc
->facts
.CurReplyFrameSize
,
6744 ioc
->facts
.ReplyQueueDepth
);
6746 len
+= sprintf(buf
+len
, " MaxDevices = %d\n",
6747 (ioc
->facts
.MaxDevices
==0) ? 255 : ioc
->facts
.MaxDevices
);
6748 len
+= sprintf(buf
+len
, " MaxBuses = %d\n", ioc
->facts
.MaxBuses
);
6751 for (p
=0; p
< ioc
->facts
.NumberOfPorts
; p
++) {
6752 len
+= sprintf(buf
+len
, " PortNumber = %d (of %d)\n",
6754 ioc
->facts
.NumberOfPorts
);
6755 if (ioc
->bus_type
== FC
) {
6756 if (ioc
->pfacts
[p
].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
) {
6757 u8
*a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
6758 len
+= sprintf(buf
+len
, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6759 a
[5], a
[4], a
[3], a
[2], a
[1], a
[0]);
6761 len
+= sprintf(buf
+len
, " WWN = %08X%08X:%08X%08X\n",
6762 ioc
->fc_port_page0
[p
].WWNN
.High
,
6763 ioc
->fc_port_page0
[p
].WWNN
.Low
,
6764 ioc
->fc_port_page0
[p
].WWPN
.High
,
6765 ioc
->fc_port_page0
[p
].WWPN
.Low
);
6769 MPT_PROC_READ_RETURN(buf
,start
,offset
,request
,eof
,len
);
6772 #endif /* CONFIG_PROC_FS } */
6774 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6776 mpt_get_fw_exp_ver(char *buf
, MPT_ADAPTER
*ioc
)
6779 if ((ioc
->facts
.FWVersion
.Word
>> 24) == 0x0E) {
6780 sprintf(buf
, " (Exp %02d%02d)",
6781 (ioc
->facts
.FWVersion
.Word
>> 16) & 0x00FF, /* Month */
6782 (ioc
->facts
.FWVersion
.Word
>> 8) & 0x1F); /* Day */
6785 if ((ioc
->facts
.FWVersion
.Word
>> 8) & 0x80)
6786 strcat(buf
, " [MDBG]");
6790 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6792 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6793 * @ioc: Pointer to MPT_ADAPTER structure
6794 * @buffer: Pointer to buffer where IOC summary info should be written
6795 * @size: Pointer to number of bytes we wrote (set by this routine)
6796 * @len: Offset at which to start writing in buffer
6797 * @showlan: Display LAN stuff?
6799 * This routine writes (english readable) ASCII text, which represents
6800 * a summary of IOC information, to a buffer.
6803 mpt_print_ioc_summary(MPT_ADAPTER
*ioc
, char *buffer
, int *size
, int len
, int showlan
)
6808 mpt_get_fw_exp_ver(expVer
, ioc
);
6811 * Shorter summary of attached ioc's...
6813 y
= sprintf(buffer
+len
, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6816 MPT_FW_REV_MAGIC_ID_STRING
, /* "FwRev=" or somesuch */
6817 ioc
->facts
.FWVersion
.Word
,
6819 ioc
->facts
.NumberOfPorts
,
6822 if (showlan
&& (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
)) {
6823 u8
*a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
6824 y
+= sprintf(buffer
+len
+y
, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6825 a
[5], a
[4], a
[3], a
[2], a
[1], a
[0]);
6828 y
+= sprintf(buffer
+len
+y
, ", IRQ=%d", ioc
->pci_irq
);
6831 y
+= sprintf(buffer
+len
+y
, " (disabled)");
6833 y
+= sprintf(buffer
+len
+y
, "\n");
6838 * mpt_set_taskmgmt_in_progress_flag - set flags associated with task management
6839 * @ioc: Pointer to MPT_ADAPTER structure
6841 * Returns 0 for SUCCESS or -1 if FAILED.
6843 * If -1 is return, then it was not possible to set the flags
6846 mpt_set_taskmgmt_in_progress_flag(MPT_ADAPTER
*ioc
)
6848 unsigned long flags
;
6851 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
6852 if (ioc
->ioc_reset_in_progress
|| ioc
->taskmgmt_in_progress
||
6853 (ioc
->alt_ioc
&& ioc
->alt_ioc
->taskmgmt_in_progress
)) {
6858 ioc
->taskmgmt_in_progress
= 1;
6859 ioc
->taskmgmt_quiesce_io
= 1;
6861 ioc
->alt_ioc
->taskmgmt_in_progress
= 1;
6862 ioc
->alt_ioc
->taskmgmt_quiesce_io
= 1;
6865 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6868 EXPORT_SYMBOL(mpt_set_taskmgmt_in_progress_flag
);
6871 * mpt_clear_taskmgmt_in_progress_flag - clear flags associated with task management
6872 * @ioc: Pointer to MPT_ADAPTER structure
6876 mpt_clear_taskmgmt_in_progress_flag(MPT_ADAPTER
*ioc
)
6878 unsigned long flags
;
6880 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
6881 ioc
->taskmgmt_in_progress
= 0;
6882 ioc
->taskmgmt_quiesce_io
= 0;
6884 ioc
->alt_ioc
->taskmgmt_in_progress
= 0;
6885 ioc
->alt_ioc
->taskmgmt_quiesce_io
= 0;
6887 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6889 EXPORT_SYMBOL(mpt_clear_taskmgmt_in_progress_flag
);
6893 * mpt_halt_firmware - Halts the firmware if it is operational and panic
6895 * @ioc: Pointer to MPT_ADAPTER structure
6899 mpt_halt_firmware(MPT_ADAPTER
*ioc
)
6903 ioc_raw_state
= mpt_GetIocState(ioc
, 0);
6905 if ((ioc_raw_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_FAULT
) {
6906 printk(MYIOC_s_ERR_FMT
"IOC is in FAULT state (%04xh)!!!\n",
6907 ioc
->name
, ioc_raw_state
& MPI_DOORBELL_DATA_MASK
);
6908 panic("%s: IOC Fault (%04xh)!!!\n", ioc
->name
,
6909 ioc_raw_state
& MPI_DOORBELL_DATA_MASK
);
6911 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, 0xC0FFEE00);
6912 panic("%s: Firmware is halted due to command timeout\n",
6916 EXPORT_SYMBOL(mpt_halt_firmware
);
6919 * mpt_SoftResetHandler - Issues a less expensive reset
6920 * @ioc: Pointer to MPT_ADAPTER structure
6921 * @sleepFlag: Indicates if sleep or schedule must be called.
6924 * Returns 0 for SUCCESS or -1 if FAILED.
6926 * Message Unit Reset - instructs the IOC to reset the Reply Post and
6927 * Free FIFO's. All the Message Frames on Reply Free FIFO are discarded.
6928 * All posted buffers are freed, and event notification is turned off.
6929 * IOC doesnt reply to any outstanding request. This will transfer IOC
6933 mpt_SoftResetHandler(MPT_ADAPTER
*ioc
, int sleepFlag
)
6938 unsigned long flags
;
6940 unsigned long time_count
;
6942 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SoftResetHandler Entered!\n",
6945 ioc_state
= mpt_GetIocState(ioc
, 0) & MPI_IOC_STATE_MASK
;
6947 if (mpt_fwfault_debug
)
6948 mpt_halt_firmware(ioc
);
6950 if (ioc_state
== MPI_IOC_STATE_FAULT
||
6951 ioc_state
== MPI_IOC_STATE_RESET
) {
6952 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6953 "skipping, either in FAULT or RESET state!\n", ioc
->name
));
6957 if (ioc
->bus_type
== FC
) {
6958 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6959 "skipping, because the bus type is FC!\n", ioc
->name
));
6963 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
6964 if (ioc
->ioc_reset_in_progress
) {
6965 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6968 ioc
->ioc_reset_in_progress
= 1;
6969 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6973 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
6974 if (MptResetHandlers
[cb_idx
])
6975 mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_SETUP_RESET
);
6978 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
6979 if (ioc
->taskmgmt_in_progress
) {
6980 ioc
->ioc_reset_in_progress
= 0;
6981 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6984 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6985 /* Disable reply interrupts (also blocks FreeQ) */
6986 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
6988 time_count
= jiffies
;
6990 rc
= SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
);
6992 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
6993 if (MptResetHandlers
[cb_idx
])
6994 mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_PRE_RESET
);
7000 ioc_state
= mpt_GetIocState(ioc
, 0) & MPI_IOC_STATE_MASK
;
7001 if (ioc_state
!= MPI_IOC_STATE_READY
)
7004 for (ii
= 0; ii
< 5; ii
++) {
7005 /* Get IOC facts! Allow 5 retries */
7006 rc
= GetIocFacts(ioc
, sleepFlag
,
7007 MPT_HOSTEVENT_IOC_RECOVER
);
7010 if (sleepFlag
== CAN_SLEEP
)
7018 rc
= PrimeIocFifos(ioc
);
7022 rc
= SendIocInit(ioc
, sleepFlag
);
7026 rc
= SendEventNotification(ioc
, 1, sleepFlag
);
7030 if (ioc
->hard_resets
< -1)
7034 * At this point, we know soft reset succeeded.
7038 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, MPI_HIM_DIM
);
7041 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
7042 ioc
->ioc_reset_in_progress
= 0;
7043 ioc
->taskmgmt_quiesce_io
= 0;
7044 ioc
->taskmgmt_in_progress
= 0;
7045 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
7047 if (ioc
->active
) { /* otherwise, hard reset coming */
7048 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
7049 if (MptResetHandlers
[cb_idx
])
7050 mpt_signal_reset(cb_idx
, ioc
,
7051 MPT_IOC_POST_RESET
);
7055 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
7056 "SoftResetHandler: completed (%d seconds): %s\n",
7057 ioc
->name
, jiffies_to_msecs(jiffies
- time_count
)/1000,
7058 ((rc
== 0) ? "SUCCESS" : "FAILED")));
7064 * mpt_Soft_Hard_ResetHandler - Try less expensive reset
7065 * @ioc: Pointer to MPT_ADAPTER structure
7066 * @sleepFlag: Indicates if sleep or schedule must be called.
7069 * Returns 0 for SUCCESS or -1 if FAILED.
7070 * Try for softreset first, only if it fails go for expensive
7074 mpt_Soft_Hard_ResetHandler(MPT_ADAPTER
*ioc
, int sleepFlag
) {
7077 ret
= mpt_SoftResetHandler(ioc
, sleepFlag
);
7080 ret
= mpt_HardResetHandler(ioc
, sleepFlag
);
7083 EXPORT_SYMBOL(mpt_Soft_Hard_ResetHandler
);
7085 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7089 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7091 * mpt_HardResetHandler - Generic reset handler
7092 * @ioc: Pointer to MPT_ADAPTER structure
7093 * @sleepFlag: Indicates if sleep or schedule must be called.
7095 * Issues SCSI Task Management call based on input arg values.
7096 * If TaskMgmt fails, returns associated SCSI request.
7098 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
7099 * or a non-interrupt thread. In the former, must not call schedule().
7101 * Note: A return of -1 is a FATAL error case, as it means a
7102 * FW reload/initialization failed.
7104 * Returns 0 for SUCCESS or -1 if FAILED.
7107 mpt_HardResetHandler(MPT_ADAPTER
*ioc
, int sleepFlag
)
7111 unsigned long flags
;
7112 unsigned long time_count
;
7114 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HardResetHandler Entered!\n", ioc
->name
));
7116 printk(MYIOC_s_INFO_FMT
"HardResetHandler Entered!\n", ioc
->name
);
7117 printk("MF count 0x%x !\n", ioc
->mfcnt
);
7119 if (mpt_fwfault_debug
)
7120 mpt_halt_firmware(ioc
);
7122 /* Reset the adapter. Prevent more than 1 call to
7123 * mpt_do_ioc_recovery at any instant in time.
7125 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
7126 if (ioc
->ioc_reset_in_progress
) {
7127 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
7130 ioc
->ioc_reset_in_progress
= 1;
7132 ioc
->alt_ioc
->ioc_reset_in_progress
= 1;
7133 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
7136 /* The SCSI driver needs to adjust timeouts on all current
7137 * commands prior to the diagnostic reset being issued.
7138 * Prevents timeouts occurring during a diagnostic reset...very bad.
7139 * For all other protocol drivers, this is a no-op.
7141 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
7142 if (MptResetHandlers
[cb_idx
]) {
7143 mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_SETUP_RESET
);
7145 mpt_signal_reset(cb_idx
, ioc
->alt_ioc
,
7146 MPT_IOC_SETUP_RESET
);
7150 time_count
= jiffies
;
7151 rc
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_RECOVER
, sleepFlag
);
7153 printk(KERN_WARNING MYNAM
7154 ": WARNING - (%d) Cannot recover %s, doorbell=0x%08x\n",
7155 rc
, ioc
->name
, mpt_GetIocState(ioc
, 0));
7157 if (ioc
->hard_resets
< -1)
7161 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
7162 ioc
->ioc_reset_in_progress
= 0;
7163 ioc
->taskmgmt_quiesce_io
= 0;
7164 ioc
->taskmgmt_in_progress
= 0;
7166 ioc
->alt_ioc
->ioc_reset_in_progress
= 0;
7167 ioc
->alt_ioc
->taskmgmt_quiesce_io
= 0;
7168 ioc
->alt_ioc
->taskmgmt_in_progress
= 0;
7170 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
7172 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
7173 if (MptResetHandlers
[cb_idx
]) {
7174 mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_POST_RESET
);
7176 mpt_signal_reset(cb_idx
,
7177 ioc
->alt_ioc
, MPT_IOC_POST_RESET
);
7182 printk(MYIOC_s_DEBUG_FMT
7183 "HardResetHandler: completed (%d seconds): %s\n", ioc
->name
,
7184 jiffies_to_msecs(jiffies
- time_count
)/1000, ((rc
== 0) ?
7185 "SUCCESS" : "FAILED")));
7190 #ifdef CONFIG_FUSION_LOGGING
7192 mpt_display_event_info(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*pEventReply
)
7198 char *evStr
= ioc
->evStr
;
7200 event
= le32_to_cpu(pEventReply
->Event
) & 0xFF;
7201 evData0
= le32_to_cpu(pEventReply
->Data
[0]);
7204 case MPI_EVENT_NONE
:
7207 case MPI_EVENT_LOG_DATA
:
7210 case MPI_EVENT_STATE_CHANGE
:
7211 ds
= "State Change";
7213 case MPI_EVENT_UNIT_ATTENTION
:
7214 ds
= "Unit Attention";
7216 case MPI_EVENT_IOC_BUS_RESET
:
7217 ds
= "IOC Bus Reset";
7219 case MPI_EVENT_EXT_BUS_RESET
:
7220 ds
= "External Bus Reset";
7222 case MPI_EVENT_RESCAN
:
7223 ds
= "Bus Rescan Event";
7225 case MPI_EVENT_LINK_STATUS_CHANGE
:
7226 if (evData0
== MPI_EVENT_LINK_STATUS_FAILURE
)
7227 ds
= "Link Status(FAILURE) Change";
7229 ds
= "Link Status(ACTIVE) Change";
7231 case MPI_EVENT_LOOP_STATE_CHANGE
:
7232 if (evData0
== MPI_EVENT_LOOP_STATE_CHANGE_LIP
)
7233 ds
= "Loop State(LIP) Change";
7234 else if (evData0
== MPI_EVENT_LOOP_STATE_CHANGE_LPE
)
7235 ds
= "Loop State(LPE) Change";
7237 ds
= "Loop State(LPB) Change";
7239 case MPI_EVENT_LOGOUT
:
7242 case MPI_EVENT_EVENT_CHANGE
:
7248 case MPI_EVENT_INTEGRATED_RAID
:
7250 u8 ReasonCode
= (u8
)(evData0
>> 16);
7251 switch (ReasonCode
) {
7252 case MPI_EVENT_RAID_RC_VOLUME_CREATED
:
7253 ds
= "Integrated Raid: Volume Created";
7255 case MPI_EVENT_RAID_RC_VOLUME_DELETED
:
7256 ds
= "Integrated Raid: Volume Deleted";
7258 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED
:
7259 ds
= "Integrated Raid: Volume Settings Changed";
7261 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED
:
7262 ds
= "Integrated Raid: Volume Status Changed";
7264 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED
:
7265 ds
= "Integrated Raid: Volume Physdisk Changed";
7267 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED
:
7268 ds
= "Integrated Raid: Physdisk Created";
7270 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED
:
7271 ds
= "Integrated Raid: Physdisk Deleted";
7273 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED
:
7274 ds
= "Integrated Raid: Physdisk Settings Changed";
7276 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
:
7277 ds
= "Integrated Raid: Physdisk Status Changed";
7279 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
:
7280 ds
= "Integrated Raid: Domain Validation Needed";
7282 case MPI_EVENT_RAID_RC_SMART_DATA
:
7283 ds
= "Integrated Raid; Smart Data";
7285 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED
:
7286 ds
= "Integrated Raid: Replace Action Started";
7289 ds
= "Integrated Raid";
7294 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE
:
7295 ds
= "SCSI Device Status Change";
7297 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE
:
7299 u8 id
= (u8
)(evData0
);
7300 u8 channel
= (u8
)(evData0
>> 8);
7301 u8 ReasonCode
= (u8
)(evData0
>> 16);
7302 switch (ReasonCode
) {
7303 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED
:
7304 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7305 "SAS Device Status Change: Added: "
7306 "id=%d channel=%d", id
, channel
);
7308 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING
:
7309 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7310 "SAS Device Status Change: Deleted: "
7311 "id=%d channel=%d", id
, channel
);
7313 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA
:
7314 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7315 "SAS Device Status Change: SMART Data: "
7316 "id=%d channel=%d", id
, channel
);
7318 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED
:
7319 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7320 "SAS Device Status Change: No Persistancy: "
7321 "id=%d channel=%d", id
, channel
);
7323 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED
:
7324 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7325 "SAS Device Status Change: Unsupported Device "
7326 "Discovered : id=%d channel=%d", id
, channel
);
7328 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET
:
7329 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7330 "SAS Device Status Change: Internal Device "
7331 "Reset : id=%d channel=%d", id
, channel
);
7333 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL
:
7334 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7335 "SAS Device Status Change: Internal Task "
7336 "Abort : id=%d channel=%d", id
, channel
);
7338 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL
:
7339 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7340 "SAS Device Status Change: Internal Abort "
7341 "Task Set : id=%d channel=%d", id
, channel
);
7343 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL
:
7344 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7345 "SAS Device Status Change: Internal Clear "
7346 "Task Set : id=%d channel=%d", id
, channel
);
7348 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL
:
7349 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7350 "SAS Device Status Change: Internal Query "
7351 "Task : id=%d channel=%d", id
, channel
);
7354 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7355 "SAS Device Status Change: Unknown: "
7356 "id=%d channel=%d", id
, channel
);
7361 case MPI_EVENT_ON_BUS_TIMER_EXPIRED
:
7362 ds
= "Bus Timer Expired";
7364 case MPI_EVENT_QUEUE_FULL
:
7366 u16 curr_depth
= (u16
)(evData0
>> 16);
7367 u8 channel
= (u8
)(evData0
>> 8);
7368 u8 id
= (u8
)(evData0
);
7370 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7371 "Queue Full: channel=%d id=%d depth=%d",
7372 channel
, id
, curr_depth
);
7375 case MPI_EVENT_SAS_SES
:
7376 ds
= "SAS SES Event";
7378 case MPI_EVENT_PERSISTENT_TABLE_FULL
:
7379 ds
= "Persistent Table Full";
7381 case MPI_EVENT_SAS_PHY_LINK_STATUS
:
7383 u8 LinkRates
= (u8
)(evData0
>> 8);
7384 u8 PhyNumber
= (u8
)(evData0
);
7385 LinkRates
= (LinkRates
& MPI_EVENT_SAS_PLS_LR_CURRENT_MASK
) >>
7386 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT
;
7387 switch (LinkRates
) {
7388 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN
:
7389 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7390 "SAS PHY Link Status: Phy=%d:"
7391 " Rate Unknown",PhyNumber
);
7393 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED
:
7394 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7395 "SAS PHY Link Status: Phy=%d:"
7396 " Phy Disabled",PhyNumber
);
7398 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION
:
7399 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7400 "SAS PHY Link Status: Phy=%d:"
7401 " Failed Speed Nego",PhyNumber
);
7403 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE
:
7404 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7405 "SAS PHY Link Status: Phy=%d:"
7406 " Sata OOB Completed",PhyNumber
);
7408 case MPI_EVENT_SAS_PLS_LR_RATE_1_5
:
7409 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7410 "SAS PHY Link Status: Phy=%d:"
7411 " Rate 1.5 Gbps",PhyNumber
);
7413 case MPI_EVENT_SAS_PLS_LR_RATE_3_0
:
7414 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7415 "SAS PHY Link Status: Phy=%d:"
7416 " Rate 3.0 Gpbs",PhyNumber
);
7419 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7420 "SAS PHY Link Status: Phy=%d", PhyNumber
);
7425 case MPI_EVENT_SAS_DISCOVERY_ERROR
:
7426 ds
= "SAS Discovery Error";
7428 case MPI_EVENT_IR_RESYNC_UPDATE
:
7430 u8 resync_complete
= (u8
)(evData0
>> 16);
7431 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7432 "IR Resync Update: Complete = %d:",resync_complete
);
7437 u8 id
= (u8
)(evData0
);
7438 u8 channel
= (u8
)(evData0
>> 8);
7439 u8 phys_num
= (u8
)(evData0
>> 24);
7440 u8 ReasonCode
= (u8
)(evData0
>> 16);
7442 switch (ReasonCode
) {
7443 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED
:
7444 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7445 "IR2: LD State Changed: "
7446 "id=%d channel=%d phys_num=%d",
7447 id
, channel
, phys_num
);
7449 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED
:
7450 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7451 "IR2: PD State Changed "
7452 "id=%d channel=%d phys_num=%d",
7453 id
, channel
, phys_num
);
7455 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL
:
7456 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7457 "IR2: Bad Block Table Full: "
7458 "id=%d channel=%d phys_num=%d",
7459 id
, channel
, phys_num
);
7461 case MPI_EVENT_IR2_RC_PD_INSERTED
:
7462 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7463 "IR2: PD Inserted: "
7464 "id=%d channel=%d phys_num=%d",
7465 id
, channel
, phys_num
);
7467 case MPI_EVENT_IR2_RC_PD_REMOVED
:
7468 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7470 "id=%d channel=%d phys_num=%d",
7471 id
, channel
, phys_num
);
7473 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED
:
7474 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7475 "IR2: Foreign CFG Detected: "
7476 "id=%d channel=%d phys_num=%d",
7477 id
, channel
, phys_num
);
7479 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR
:
7480 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7481 "IR2: Rebuild Medium Error: "
7482 "id=%d channel=%d phys_num=%d",
7483 id
, channel
, phys_num
);
7485 case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED
:
7486 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7487 "IR2: Dual Port Added: "
7488 "id=%d channel=%d phys_num=%d",
7489 id
, channel
, phys_num
);
7491 case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED
:
7492 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7493 "IR2: Dual Port Removed: "
7494 "id=%d channel=%d phys_num=%d",
7495 id
, channel
, phys_num
);
7503 case MPI_EVENT_SAS_DISCOVERY
:
7506 ds
= "SAS Discovery: Start";
7508 ds
= "SAS Discovery: Stop";
7511 case MPI_EVENT_LOG_ENTRY_ADDED
:
7512 ds
= "SAS Log Entry Added";
7515 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE
:
7517 u8 phy_num
= (u8
)(evData0
);
7518 u8 port_num
= (u8
)(evData0
>> 8);
7519 u8 port_width
= (u8
)(evData0
>> 16);
7520 u8 primative
= (u8
)(evData0
>> 24);
7521 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7522 "SAS Broadcase Primative: phy=%d port=%d "
7523 "width=%d primative=0x%02x",
7524 phy_num
, port_num
, port_width
, primative
);
7528 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE
:
7530 u8 reason
= (u8
)(evData0
);
7533 case MPI_EVENT_SAS_INIT_RC_ADDED
:
7534 ds
= "SAS Initiator Status Change: Added";
7536 case MPI_EVENT_SAS_INIT_RC_REMOVED
:
7537 ds
= "SAS Initiator Status Change: Deleted";
7540 ds
= "SAS Initiator Status Change";
7546 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW
:
7548 u8 max_init
= (u8
)(evData0
);
7549 u8 current_init
= (u8
)(evData0
>> 8);
7551 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7552 "SAS Initiator Device Table Overflow: max initiators=%02d "
7553 "current initators=%02d",
7554 max_init
, current_init
);
7557 case MPI_EVENT_SAS_SMP_ERROR
:
7559 u8 status
= (u8
)(evData0
);
7560 u8 port_num
= (u8
)(evData0
>> 8);
7561 u8 result
= (u8
)(evData0
>> 16);
7563 if (status
== MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID
)
7564 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7565 "SAS SMP Error: port=%d result=0x%02x",
7567 else if (status
== MPI_EVENT_SAS_SMP_CRC_ERROR
)
7568 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7569 "SAS SMP Error: port=%d : CRC Error",
7571 else if (status
== MPI_EVENT_SAS_SMP_TIMEOUT
)
7572 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7573 "SAS SMP Error: port=%d : Timeout",
7575 else if (status
== MPI_EVENT_SAS_SMP_NO_DESTINATION
)
7576 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7577 "SAS SMP Error: port=%d : No Destination",
7579 else if (status
== MPI_EVENT_SAS_SMP_BAD_DESTINATION
)
7580 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7581 "SAS SMP Error: port=%d : Bad Destination",
7584 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7585 "SAS SMP Error: port=%d : status=0x%02x",
7590 case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE
:
7592 u8 reason
= (u8
)(evData0
);
7595 case MPI_EVENT_SAS_EXP_RC_ADDED
:
7596 ds
= "Expander Status Change: Added";
7598 case MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING
:
7599 ds
= "Expander Status Change: Deleted";
7602 ds
= "Expander Status Change";
7609 * MPT base "custom" events may be added here...
7616 strncpy(evStr
, ds
, EVENT_DESCR_STR_SZ
);
7619 devtprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
7620 "MPT event:(%02Xh) : %s\n",
7621 ioc
->name
, event
, evStr
));
7623 devtverboseprintk(ioc
, printk(KERN_DEBUG MYNAM
7624 ": Event data:\n"));
7625 for (ii
= 0; ii
< le16_to_cpu(pEventReply
->EventDataLength
); ii
++)
7626 devtverboseprintk(ioc
, printk(" %08x",
7627 le32_to_cpu(pEventReply
->Data
[ii
])));
7628 devtverboseprintk(ioc
, printk(KERN_DEBUG
"\n"));
7631 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7633 * ProcessEventNotification - Route EventNotificationReply to all event handlers
7634 * @ioc: Pointer to MPT_ADAPTER structure
7635 * @pEventReply: Pointer to EventNotification reply frame
7636 * @evHandlers: Pointer to integer, number of event handlers
7638 * Routes a received EventNotificationReply to all currently registered
7640 * Returns sum of event handlers return values.
7643 ProcessEventNotification(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*pEventReply
, int *evHandlers
)
7654 * Do platform normalization of values
7656 event
= le32_to_cpu(pEventReply
->Event
) & 0xFF;
7657 evDataLen
= le16_to_cpu(pEventReply
->EventDataLength
);
7659 evData0
= le32_to_cpu(pEventReply
->Data
[0]);
7662 #ifdef CONFIG_FUSION_LOGGING
7664 mpt_display_event_info(ioc
, pEventReply
);
7668 * Do general / base driver event processing
7671 case MPI_EVENT_EVENT_CHANGE
: /* 0A */
7673 u8 evState
= evData0
& 0xFF;
7675 /* CHECKME! What if evState unexpectedly says OFF (0)? */
7677 /* Update EventState field in cached IocFacts */
7678 if (ioc
->facts
.Function
) {
7679 ioc
->facts
.EventState
= evState
;
7683 case MPI_EVENT_INTEGRATED_RAID
:
7684 mptbase_raid_process_event_data(ioc
,
7685 (MpiEventDataRaid_t
*)pEventReply
->Data
);
7692 * Should this event be logged? Events are written sequentially.
7693 * When buffer is full, start again at the top.
7695 if (ioc
->events
&& (ioc
->eventTypes
& ( 1 << event
))) {
7698 idx
= ioc
->eventContext
% MPTCTL_EVENT_LOG_SIZE
;
7700 ioc
->events
[idx
].event
= event
;
7701 ioc
->events
[idx
].eventContext
= ioc
->eventContext
;
7703 for (ii
= 0; ii
< 2; ii
++) {
7705 ioc
->events
[idx
].data
[ii
] = le32_to_cpu(pEventReply
->Data
[ii
]);
7707 ioc
->events
[idx
].data
[ii
] = 0;
7710 ioc
->eventContext
++;
7715 * Call each currently registered protocol event handler.
7717 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
7718 if (MptEvHandlers
[cb_idx
]) {
7719 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
7720 "Routing Event to event handler #%d\n",
7721 ioc
->name
, cb_idx
));
7722 r
+= (*(MptEvHandlers
[cb_idx
]))(ioc
, pEventReply
);
7726 /* FIXME? Examine results here? */
7729 * If needed, send (a single) EventAck.
7731 if (pEventReply
->AckRequired
== MPI_EVENT_NOTIFICATION_ACK_REQUIRED
) {
7732 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
7733 "EventAck required\n",ioc
->name
));
7734 if ((ii
= SendEventAck(ioc
, pEventReply
)) != 0) {
7735 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SendEventAck returned %d\n",
7740 *evHandlers
= handlers
;
7744 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7746 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
7747 * @ioc: Pointer to MPT_ADAPTER structure
7748 * @log_info: U32 LogInfo reply word from the IOC
7750 * Refer to lsi/mpi_log_fc.h.
7753 mpt_fc_log_info(MPT_ADAPTER
*ioc
, u32 log_info
)
7755 char *desc
= "unknown";
7757 switch (log_info
& 0xFF000000) {
7758 case MPI_IOCLOGINFO_FC_INIT_BASE
:
7759 desc
= "FCP Initiator";
7761 case MPI_IOCLOGINFO_FC_TARGET_BASE
:
7762 desc
= "FCP Target";
7764 case MPI_IOCLOGINFO_FC_LAN_BASE
:
7767 case MPI_IOCLOGINFO_FC_MSG_BASE
:
7768 desc
= "MPI Message Layer";
7770 case MPI_IOCLOGINFO_FC_LINK_BASE
:
7773 case MPI_IOCLOGINFO_FC_CTX_BASE
:
7774 desc
= "Context Manager";
7776 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET
:
7777 desc
= "Invalid Field Offset";
7779 case MPI_IOCLOGINFO_FC_STATE_CHANGE
:
7780 desc
= "State Change Info";
7784 printk(MYIOC_s_INFO_FMT
"LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
7785 ioc
->name
, log_info
, desc
, (log_info
& 0xFFFFFF));
7788 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7790 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
7791 * @ioc: Pointer to MPT_ADAPTER structure
7792 * @log_info: U32 LogInfo word from the IOC
7794 * Refer to lsi/sp_log.h.
7797 mpt_spi_log_info(MPT_ADAPTER
*ioc
, u32 log_info
)
7799 u32 info
= log_info
& 0x00FF0000;
7800 char *desc
= "unknown";
7804 desc
= "bug! MID not found";
7808 desc
= "Parity Error";
7812 desc
= "ASYNC Outbound Overrun";
7816 desc
= "SYNC Offset Error";
7824 desc
= "Msg In Overflow";
7832 desc
= "Outbound DMA Overrun";
7836 desc
= "Task Management";
7840 desc
= "Device Problem";
7844 desc
= "Invalid Phase Change";
7848 desc
= "Untagged Table Size";
7853 printk(MYIOC_s_INFO_FMT
"LogInfo(0x%08x): F/W: %s\n", ioc
->name
, log_info
, desc
);
7856 /* strings for sas loginfo */
7857 static char *originator_str
[] = {
7862 static char *iop_code_str
[] = {
7864 "Invalid SAS Address", /* 01h */
7866 "Invalid Page", /* 03h */
7867 "Diag Message Error", /* 04h */
7868 "Task Terminated", /* 05h */
7869 "Enclosure Management", /* 06h */
7870 "Target Mode" /* 07h */
7872 static char *pl_code_str
[] = {
7874 "Open Failure", /* 01h */
7875 "Invalid Scatter Gather List", /* 02h */
7876 "Wrong Relative Offset or Frame Length", /* 03h */
7877 "Frame Transfer Error", /* 04h */
7878 "Transmit Frame Connected Low", /* 05h */
7879 "SATA Non-NCQ RW Error Bit Set", /* 06h */
7880 "SATA Read Log Receive Data Error", /* 07h */
7881 "SATA NCQ Fail All Commands After Error", /* 08h */
7882 "SATA Error in Receive Set Device Bit FIS", /* 09h */
7883 "Receive Frame Invalid Message", /* 0Ah */
7884 "Receive Context Message Valid Error", /* 0Bh */
7885 "Receive Frame Current Frame Error", /* 0Ch */
7886 "SATA Link Down", /* 0Dh */
7887 "Discovery SATA Init W IOS", /* 0Eh */
7888 "Config Invalid Page", /* 0Fh */
7889 "Discovery SATA Init Timeout", /* 10h */
7892 "IO Not Yet Executed", /* 13h */
7893 "IO Executed", /* 14h */
7894 "Persistent Reservation Out Not Affiliation "
7896 "Open Transmit DMA Abort", /* 16h */
7897 "IO Device Missing Delay Retry", /* 17h */
7898 "IO Cancelled Due to Recieve Error", /* 18h */
7906 "Enclosure Management" /* 20h */
7908 static char *ir_code_str
[] = {
7909 "Raid Action Error", /* 00h */
7919 static char *raid_sub_code_str
[] = {
7921 "Volume Creation Failed: Data Passed too "
7923 "Volume Creation Failed: Duplicate Volumes "
7924 "Attempted", /* 02h */
7925 "Volume Creation Failed: Max Number "
7926 "Supported Volumes Exceeded", /* 03h */
7927 "Volume Creation Failed: DMA Error", /* 04h */
7928 "Volume Creation Failed: Invalid Volume Type", /* 05h */
7929 "Volume Creation Failed: Error Reading "
7930 "MFG Page 4", /* 06h */
7931 "Volume Creation Failed: Creating Internal "
7932 "Structures", /* 07h */
7941 "Activation failed: Already Active Volume", /* 10h */
7942 "Activation failed: Unsupported Volume Type", /* 11h */
7943 "Activation failed: Too Many Active Volumes", /* 12h */
7944 "Activation failed: Volume ID in Use", /* 13h */
7945 "Activation failed: Reported Failure", /* 14h */
7946 "Activation failed: Importing a Volume", /* 15h */
7957 "Phys Disk failed: Too Many Phys Disks", /* 20h */
7958 "Phys Disk failed: Data Passed too Large", /* 21h */
7959 "Phys Disk failed: DMA Error", /* 22h */
7960 "Phys Disk failed: Invalid <channel:id>", /* 23h */
7961 "Phys Disk failed: Creating Phys Disk Config "
7974 "Compatibility Error: IR Disabled", /* 30h */
7975 "Compatibility Error: Inquiry Comand Failed", /* 31h */
7976 "Compatibility Error: Device not Direct Access "
7977 "Device ", /* 32h */
7978 "Compatibility Error: Removable Device Found", /* 33h */
7979 "Compatibility Error: Device SCSI Version not "
7980 "2 or Higher", /* 34h */
7981 "Compatibility Error: SATA Device, 48 BIT LBA "
7982 "not Supported", /* 35h */
7983 "Compatibility Error: Device doesn't have "
7984 "512 Byte Block Sizes", /* 36h */
7985 "Compatibility Error: Volume Type Check Failed", /* 37h */
7986 "Compatibility Error: Volume Type is "
7987 "Unsupported by FW", /* 38h */
7988 "Compatibility Error: Disk Drive too Small for "
7989 "use in Volume", /* 39h */
7990 "Compatibility Error: Phys Disk for Create "
7991 "Volume not Found", /* 3Ah */
7992 "Compatibility Error: Too Many or too Few "
7993 "Disks for Volume Type", /* 3Bh */
7994 "Compatibility Error: Disk stripe Sizes "
7995 "Must be 64KB", /* 3Ch */
7996 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
7999 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8001 * mpt_sas_log_info - Log information returned from SAS IOC.
8002 * @ioc: Pointer to MPT_ADAPTER structure
8003 * @log_info: U32 LogInfo reply word from the IOC
8005 * Refer to lsi/mpi_log_sas.h.
8008 mpt_sas_log_info(MPT_ADAPTER
*ioc
, u32 log_info
, u8 cb_idx
)
8010 union loginfo_type
{
8019 union loginfo_type sas_loginfo
;
8020 char *originator_desc
= NULL
;
8021 char *code_desc
= NULL
;
8022 char *sub_code_desc
= NULL
;
8024 sas_loginfo
.loginfo
= log_info
;
8025 if ((sas_loginfo
.dw
.bus_type
!= 3 /*SAS*/) &&
8026 (sas_loginfo
.dw
.originator
< ARRAY_SIZE(originator_str
)))
8029 originator_desc
= originator_str
[sas_loginfo
.dw
.originator
];
8031 switch (sas_loginfo
.dw
.originator
) {
8034 if (sas_loginfo
.dw
.code
<
8035 ARRAY_SIZE(iop_code_str
))
8036 code_desc
= iop_code_str
[sas_loginfo
.dw
.code
];
8039 if (sas_loginfo
.dw
.code
<
8040 ARRAY_SIZE(pl_code_str
))
8041 code_desc
= pl_code_str
[sas_loginfo
.dw
.code
];
8044 if (sas_loginfo
.dw
.code
>=
8045 ARRAY_SIZE(ir_code_str
))
8047 code_desc
= ir_code_str
[sas_loginfo
.dw
.code
];
8048 if (sas_loginfo
.dw
.subcode
>=
8049 ARRAY_SIZE(raid_sub_code_str
))
8051 if (sas_loginfo
.dw
.code
== 0)
8053 raid_sub_code_str
[sas_loginfo
.dw
.subcode
];
8059 if (sub_code_desc
!= NULL
)
8060 printk(MYIOC_s_INFO_FMT
8061 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
8062 " SubCode={%s} cb_idx %s\n",
8063 ioc
->name
, log_info
, originator_desc
, code_desc
,
8064 sub_code_desc
, MptCallbacksName
[cb_idx
]);
8065 else if (code_desc
!= NULL
)
8066 printk(MYIOC_s_INFO_FMT
8067 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
8068 " SubCode(0x%04x) cb_idx %s\n",
8069 ioc
->name
, log_info
, originator_desc
, code_desc
,
8070 sas_loginfo
.dw
.subcode
, MptCallbacksName
[cb_idx
]);
8072 printk(MYIOC_s_INFO_FMT
8073 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
8074 " SubCode(0x%04x) cb_idx %s\n",
8075 ioc
->name
, log_info
, originator_desc
,
8076 sas_loginfo
.dw
.code
, sas_loginfo
.dw
.subcode
,
8077 MptCallbacksName
[cb_idx
]);
8080 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8082 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
8083 * @ioc: Pointer to MPT_ADAPTER structure
8084 * @ioc_status: U32 IOCStatus word from IOC
8085 * @mf: Pointer to MPT request frame
8087 * Refer to lsi/mpi.h.
8090 mpt_iocstatus_info_config(MPT_ADAPTER
*ioc
, u32 ioc_status
, MPT_FRAME_HDR
*mf
)
8092 Config_t
*pReq
= (Config_t
*)mf
;
8093 char extend_desc
[EVENT_DESCR_STR_SZ
];
8098 if (pReq
->Header
.PageType
== MPI_CONFIG_PAGETYPE_EXTENDED
)
8099 page_type
= pReq
->ExtPageType
;
8101 page_type
= pReq
->Header
.PageType
;
8104 * ignore invalid page messages for GET_NEXT_HANDLE
8106 form
= le32_to_cpu(pReq
->PageAddress
);
8107 if (ioc_status
== MPI_IOCSTATUS_CONFIG_INVALID_PAGE
) {
8108 if (page_type
== MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE
||
8109 page_type
== MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER
||
8110 page_type
== MPI_CONFIG_EXTPAGETYPE_ENCLOSURE
) {
8111 if ((form
>> MPI_SAS_DEVICE_PGAD_FORM_SHIFT
) ==
8112 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE
)
8115 if (page_type
== MPI_CONFIG_PAGETYPE_FC_DEVICE
)
8116 if ((form
& MPI_FC_DEVICE_PGAD_FORM_MASK
) ==
8117 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID
)
8121 snprintf(extend_desc
, EVENT_DESCR_STR_SZ
,
8122 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
8123 page_type
, pReq
->Header
.PageNumber
, pReq
->Action
, form
);
8125 switch (ioc_status
) {
8127 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION
: /* 0x0020 */
8128 desc
= "Config Page Invalid Action";
8131 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE
: /* 0x0021 */
8132 desc
= "Config Page Invalid Type";
8135 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE
: /* 0x0022 */
8136 desc
= "Config Page Invalid Page";
8139 case MPI_IOCSTATUS_CONFIG_INVALID_DATA
: /* 0x0023 */
8140 desc
= "Config Page Invalid Data";
8143 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS
: /* 0x0024 */
8144 desc
= "Config Page No Defaults";
8147 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT
: /* 0x0025 */
8148 desc
= "Config Page Can't Commit";
8155 dreplyprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"IOCStatus(0x%04X): %s: %s\n",
8156 ioc
->name
, ioc_status
, desc
, extend_desc
));
8160 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
8161 * @ioc: Pointer to MPT_ADAPTER structure
8162 * @ioc_status: U32 IOCStatus word from IOC
8163 * @mf: Pointer to MPT request frame
8165 * Refer to lsi/mpi.h.
8168 mpt_iocstatus_info(MPT_ADAPTER
*ioc
, u32 ioc_status
, MPT_FRAME_HDR
*mf
)
8170 u32 status
= ioc_status
& MPI_IOCSTATUS_MASK
;
8175 /****************************************************************************/
8176 /* Common IOCStatus values for all replies */
8177 /****************************************************************************/
8179 case MPI_IOCSTATUS_INVALID_FUNCTION
: /* 0x0001 */
8180 desc
= "Invalid Function";
8183 case MPI_IOCSTATUS_BUSY
: /* 0x0002 */
8187 case MPI_IOCSTATUS_INVALID_SGL
: /* 0x0003 */
8188 desc
= "Invalid SGL";
8191 case MPI_IOCSTATUS_INTERNAL_ERROR
: /* 0x0004 */
8192 desc
= "Internal Error";
8195 case MPI_IOCSTATUS_RESERVED
: /* 0x0005 */
8199 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES
: /* 0x0006 */
8200 desc
= "Insufficient Resources";
8203 case MPI_IOCSTATUS_INVALID_FIELD
: /* 0x0007 */
8204 desc
= "Invalid Field";
8207 case MPI_IOCSTATUS_INVALID_STATE
: /* 0x0008 */
8208 desc
= "Invalid State";
8211 /****************************************************************************/
8212 /* Config IOCStatus values */
8213 /****************************************************************************/
8215 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION
: /* 0x0020 */
8216 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE
: /* 0x0021 */
8217 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE
: /* 0x0022 */
8218 case MPI_IOCSTATUS_CONFIG_INVALID_DATA
: /* 0x0023 */
8219 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS
: /* 0x0024 */
8220 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT
: /* 0x0025 */
8221 mpt_iocstatus_info_config(ioc
, status
, mf
);
8224 /****************************************************************************/
8225 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
8227 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
8229 /****************************************************************************/
8231 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR
: /* 0x0040 */
8232 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN
: /* 0x0045 */
8233 case MPI_IOCSTATUS_SCSI_INVALID_BUS
: /* 0x0041 */
8234 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID
: /* 0x0042 */
8235 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE
: /* 0x0043 */
8236 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN
: /* 0x0044 */
8237 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR
: /* 0x0046 */
8238 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR
: /* 0x0047 */
8239 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED
: /* 0x0048 */
8240 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH
: /* 0x0049 */
8241 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED
: /* 0x004A */
8242 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED
: /* 0x004B */
8243 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED
: /* 0x004C */
8246 /****************************************************************************/
8247 /* SCSI Target values */
8248 /****************************************************************************/
8250 case MPI_IOCSTATUS_TARGET_PRIORITY_IO
: /* 0x0060 */
8251 desc
= "Target: Priority IO";
8254 case MPI_IOCSTATUS_TARGET_INVALID_PORT
: /* 0x0061 */
8255 desc
= "Target: Invalid Port";
8258 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX
: /* 0x0062 */
8259 desc
= "Target Invalid IO Index:";
8262 case MPI_IOCSTATUS_TARGET_ABORTED
: /* 0x0063 */
8263 desc
= "Target: Aborted";
8266 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE
: /* 0x0064 */
8267 desc
= "Target: No Conn Retryable";
8270 case MPI_IOCSTATUS_TARGET_NO_CONNECTION
: /* 0x0065 */
8271 desc
= "Target: No Connection";
8274 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH
: /* 0x006A */
8275 desc
= "Target: Transfer Count Mismatch";
8278 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT
: /* 0x006B */
8279 desc
= "Target: STS Data not Sent";
8282 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR
: /* 0x006D */
8283 desc
= "Target: Data Offset Error";
8286 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA
: /* 0x006E */
8287 desc
= "Target: Too Much Write Data";
8290 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT
: /* 0x006F */
8291 desc
= "Target: IU Too Short";
8294 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT
: /* 0x0070 */
8295 desc
= "Target: ACK NAK Timeout";
8298 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED
: /* 0x0071 */
8299 desc
= "Target: Nak Received";
8302 /****************************************************************************/
8303 /* Fibre Channel Direct Access values */
8304 /****************************************************************************/
8306 case MPI_IOCSTATUS_FC_ABORTED
: /* 0x0066 */
8307 desc
= "FC: Aborted";
8310 case MPI_IOCSTATUS_FC_RX_ID_INVALID
: /* 0x0067 */
8311 desc
= "FC: RX ID Invalid";
8314 case MPI_IOCSTATUS_FC_DID_INVALID
: /* 0x0068 */
8315 desc
= "FC: DID Invalid";
8318 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT
: /* 0x0069 */
8319 desc
= "FC: Node Logged Out";
8322 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED
: /* 0x006C */
8323 desc
= "FC: Exchange Canceled";
8326 /****************************************************************************/
8328 /****************************************************************************/
8330 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND
: /* 0x0080 */
8331 desc
= "LAN: Device not Found";
8334 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE
: /* 0x0081 */
8335 desc
= "LAN: Device Failure";
8338 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR
: /* 0x0082 */
8339 desc
= "LAN: Transmit Error";
8342 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED
: /* 0x0083 */
8343 desc
= "LAN: Transmit Aborted";
8346 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR
: /* 0x0084 */
8347 desc
= "LAN: Receive Error";
8350 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED
: /* 0x0085 */
8351 desc
= "LAN: Receive Aborted";
8354 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET
: /* 0x0086 */
8355 desc
= "LAN: Partial Packet";
8358 case MPI_IOCSTATUS_LAN_CANCELED
: /* 0x0087 */
8359 desc
= "LAN: Canceled";
8362 /****************************************************************************/
8363 /* Serial Attached SCSI values */
8364 /****************************************************************************/
8366 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED
: /* 0x0090 */
8367 desc
= "SAS: SMP Request Failed";
8370 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN
: /* 0x0090 */
8371 desc
= "SAS: SMP Data Overrun";
8382 dreplyprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"IOCStatus(0x%04X): %s\n",
8383 ioc
->name
, status
, desc
));
8386 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8387 EXPORT_SYMBOL(mpt_attach
);
8388 EXPORT_SYMBOL(mpt_detach
);
8390 EXPORT_SYMBOL(mpt_resume
);
8391 EXPORT_SYMBOL(mpt_suspend
);
8393 EXPORT_SYMBOL(ioc_list
);
8394 EXPORT_SYMBOL(mpt_register
);
8395 EXPORT_SYMBOL(mpt_deregister
);
8396 EXPORT_SYMBOL(mpt_event_register
);
8397 EXPORT_SYMBOL(mpt_event_deregister
);
8398 EXPORT_SYMBOL(mpt_reset_register
);
8399 EXPORT_SYMBOL(mpt_reset_deregister
);
8400 EXPORT_SYMBOL(mpt_device_driver_register
);
8401 EXPORT_SYMBOL(mpt_device_driver_deregister
);
8402 EXPORT_SYMBOL(mpt_get_msg_frame
);
8403 EXPORT_SYMBOL(mpt_put_msg_frame
);
8404 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri
);
8405 EXPORT_SYMBOL(mpt_free_msg_frame
);
8406 EXPORT_SYMBOL(mpt_send_handshake_request
);
8407 EXPORT_SYMBOL(mpt_verify_adapter
);
8408 EXPORT_SYMBOL(mpt_GetIocState
);
8409 EXPORT_SYMBOL(mpt_print_ioc_summary
);
8410 EXPORT_SYMBOL(mpt_HardResetHandler
);
8411 EXPORT_SYMBOL(mpt_config
);
8412 EXPORT_SYMBOL(mpt_findImVolumes
);
8413 EXPORT_SYMBOL(mpt_alloc_fw_memory
);
8414 EXPORT_SYMBOL(mpt_free_fw_memory
);
8415 EXPORT_SYMBOL(mptbase_sas_persist_operation
);
8416 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0
);
8418 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8420 * fusion_init - Fusion MPT base driver initialization routine.
8422 * Returns 0 for success, non-zero for failure.
8429 show_mptmod_ver(my_NAME
, my_VERSION
);
8430 printk(KERN_INFO COPYRIGHT
"\n");
8432 for (cb_idx
= 0; cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
; cb_idx
++) {
8433 MptCallbacks
[cb_idx
] = NULL
;
8434 MptDriverClass
[cb_idx
] = MPTUNKNOWN_DRIVER
;
8435 MptEvHandlers
[cb_idx
] = NULL
;
8436 MptResetHandlers
[cb_idx
] = NULL
;
8439 /* Register ourselves (mptbase) in order to facilitate
8440 * EventNotification handling.
8442 mpt_base_index
= mpt_register(mptbase_reply
, MPTBASE_DRIVER
,
8445 /* Register for hard reset handling callbacks.
8447 mpt_reset_register(mpt_base_index
, mpt_ioc_reset
);
8449 #ifdef CONFIG_PROC_FS
8450 (void) procmpt_create();
8455 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8457 * fusion_exit - Perform driver unload cleanup.
8459 * This routine frees all resources associated with each MPT adapter
8460 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
8466 mpt_reset_deregister(mpt_base_index
);
8468 #ifdef CONFIG_PROC_FS
8473 module_init(fusion_init
);
8474 module_exit(fusion_exit
);