2 * linux/drivers/message/fusion/mptbase.c
3 * This is the Fusion MPT base driver which supports multiple
4 * (SCSI + LAN) specialized protocol drivers.
5 * For use with LSI PCI chip/adapter(s)
6 * running LSI Fusion MPT (Message Passing Technology) firmware.
8 * Copyright (c) 1999-2008 LSI Corporation
9 * (mailto:DL-MPTFusionLinux@lsi.com)
12 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; version 2 of the License.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
24 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
25 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
26 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
27 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
28 solely responsible for determining the appropriateness of using and
29 distributing the Program and assumes all risks associated with its
30 exercise of rights under this Agreement, including but not limited to
31 the risks and costs of program errors, damage to or loss of data,
32 programs or equipment, and unavailability or interruption of operations.
34 DISCLAIMER OF LIABILITY
35 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
36 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
38 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
39 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
40 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
41 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
43 You should have received a copy of the GNU General Public License
44 along with this program; if not, write to the Free Software
45 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
47 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
49 #include <linux/kernel.h>
50 #include <linux/module.h>
51 #include <linux/errno.h>
52 #include <linux/init.h>
53 #include <linux/slab.h>
54 #include <linux/types.h>
55 #include <linux/pci.h>
56 #include <linux/kdev_t.h>
57 #include <linux/blkdev.h>
58 #include <linux/delay.h>
59 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
60 #include <linux/dma-mapping.h>
67 #include "lsi/mpi_log_fc.h"
69 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
70 #define my_NAME "Fusion MPT base driver"
71 #define my_VERSION MPT_LINUX_VERSION_COMMON
72 #define MYNAM "mptbase"
74 MODULE_AUTHOR(MODULEAUTHOR
);
75 MODULE_DESCRIPTION(my_NAME
);
76 MODULE_LICENSE("GPL");
77 MODULE_VERSION(my_VERSION
);
83 static int mpt_msi_enable_spi
;
84 module_param(mpt_msi_enable_spi
, int, 0);
85 MODULE_PARM_DESC(mpt_msi_enable_spi
, " Enable MSI Support for SPI \
86 controllers (default=0)");
88 static int mpt_msi_enable_fc
;
89 module_param(mpt_msi_enable_fc
, int, 0);
90 MODULE_PARM_DESC(mpt_msi_enable_fc
, " Enable MSI Support for FC \
91 controllers (default=0)");
93 static int mpt_msi_enable_sas
;
94 module_param(mpt_msi_enable_sas
, int, 0);
95 MODULE_PARM_DESC(mpt_msi_enable_sas
, " Enable MSI Support for SAS \
96 controllers (default=0)");
99 static int mpt_channel_mapping
;
100 module_param(mpt_channel_mapping
, int, 0);
101 MODULE_PARM_DESC(mpt_channel_mapping
, " Mapping id's to channels (default=0)");
103 static int mpt_debug_level
;
104 static int mpt_set_debug_level(const char *val
, struct kernel_param
*kp
);
105 module_param_call(mpt_debug_level
, mpt_set_debug_level
, param_get_int
,
106 &mpt_debug_level
, 0600);
107 MODULE_PARM_DESC(mpt_debug_level
, " debug level - refer to mptdebug.h \
110 int mpt_fwfault_debug
;
111 EXPORT_SYMBOL(mpt_fwfault_debug
);
112 module_param_call(mpt_fwfault_debug
, param_set_int
, param_get_int
,
113 &mpt_fwfault_debug
, 0600);
114 MODULE_PARM_DESC(mpt_fwfault_debug
, "Enable detection of Firmware fault"
115 " and halt Firmware on fault - (default=0)");
120 static int mfcounter
= 0;
121 #define PRINT_MF_COUNT 20000
124 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
129 #define WHOINIT_UNKNOWN 0xAA
131 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
135 /* Adapter link list */
137 /* Callback lookup table */
138 static MPT_CALLBACK MptCallbacks
[MPT_MAX_PROTOCOL_DRIVERS
];
139 /* Protocol driver class lookup table */
140 static int MptDriverClass
[MPT_MAX_PROTOCOL_DRIVERS
];
141 /* Event handler lookup table */
142 static MPT_EVHANDLER MptEvHandlers
[MPT_MAX_PROTOCOL_DRIVERS
];
143 /* Reset handler lookup table */
144 static MPT_RESETHANDLER MptResetHandlers
[MPT_MAX_PROTOCOL_DRIVERS
];
145 static struct mpt_pci_driver
*MptDeviceDriverHandlers
[MPT_MAX_PROTOCOL_DRIVERS
];
147 #ifdef CONFIG_PROC_FS
148 static struct proc_dir_entry
*mpt_proc_root_dir
;
152 * Driver Callback Index's
154 static u8 mpt_base_index
= MPT_MAX_PROTOCOL_DRIVERS
;
155 static u8 last_drv_idx
;
157 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
161 static irqreturn_t
mpt_interrupt(int irq
, void *bus_id
);
162 static int mptbase_reply(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*req
,
163 MPT_FRAME_HDR
*reply
);
164 static int mpt_handshake_req_reply_wait(MPT_ADAPTER
*ioc
, int reqBytes
,
165 u32
*req
, int replyBytes
, u16
*u16reply
, int maxwait
,
167 static int mpt_do_ioc_recovery(MPT_ADAPTER
*ioc
, u32 reason
, int sleepFlag
);
168 static void mpt_detect_bound_ports(MPT_ADAPTER
*ioc
, struct pci_dev
*pdev
);
169 static void mpt_adapter_disable(MPT_ADAPTER
*ioc
);
170 static void mpt_adapter_dispose(MPT_ADAPTER
*ioc
);
172 static void MptDisplayIocCapabilities(MPT_ADAPTER
*ioc
);
173 static int MakeIocReady(MPT_ADAPTER
*ioc
, int force
, int sleepFlag
);
174 static int GetIocFacts(MPT_ADAPTER
*ioc
, int sleepFlag
, int reason
);
175 static int GetPortFacts(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
);
176 static int SendIocInit(MPT_ADAPTER
*ioc
, int sleepFlag
);
177 static int SendPortEnable(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
);
178 static int mpt_do_upload(MPT_ADAPTER
*ioc
, int sleepFlag
);
179 static int mpt_downloadboot(MPT_ADAPTER
*ioc
, MpiFwHeader_t
*pFwHeader
, int sleepFlag
);
180 static int mpt_diag_reset(MPT_ADAPTER
*ioc
, int ignore
, int sleepFlag
);
181 static int KickStart(MPT_ADAPTER
*ioc
, int ignore
, int sleepFlag
);
182 static int SendIocReset(MPT_ADAPTER
*ioc
, u8 reset_type
, int sleepFlag
);
183 static int PrimeIocFifos(MPT_ADAPTER
*ioc
);
184 static int WaitForDoorbellAck(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
);
185 static int WaitForDoorbellInt(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
);
186 static int WaitForDoorbellReply(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
);
187 static int GetLanConfigPages(MPT_ADAPTER
*ioc
);
188 static int GetIoUnitPage2(MPT_ADAPTER
*ioc
);
189 int mptbase_sas_persist_operation(MPT_ADAPTER
*ioc
, u8 persist_opcode
);
190 static int mpt_GetScsiPortSettings(MPT_ADAPTER
*ioc
, int portnum
);
191 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER
*ioc
, int portnum
);
192 static void mpt_read_ioc_pg_1(MPT_ADAPTER
*ioc
);
193 static void mpt_read_ioc_pg_4(MPT_ADAPTER
*ioc
);
194 static void mpt_get_manufacturing_pg_0(MPT_ADAPTER
*ioc
);
195 static int SendEventNotification(MPT_ADAPTER
*ioc
, u8 EvSwitch
,
197 static int SendEventAck(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*evnp
);
198 static int mpt_host_page_access_control(MPT_ADAPTER
*ioc
, u8 access_control_value
, int sleepFlag
);
199 static int mpt_host_page_alloc(MPT_ADAPTER
*ioc
, pIOCInit_t ioc_init
);
201 #ifdef CONFIG_PROC_FS
202 static int procmpt_summary_read(char *buf
, char **start
, off_t offset
,
203 int request
, int *eof
, void *data
);
204 static int procmpt_version_read(char *buf
, char **start
, off_t offset
,
205 int request
, int *eof
, void *data
);
206 static int procmpt_iocinfo_read(char *buf
, char **start
, off_t offset
,
207 int request
, int *eof
, void *data
);
209 static void mpt_get_fw_exp_ver(char *buf
, MPT_ADAPTER
*ioc
);
211 static int ProcessEventNotification(MPT_ADAPTER
*ioc
,
212 EventNotificationReply_t
*evReply
, int *evHandlers
);
213 static void mpt_iocstatus_info(MPT_ADAPTER
*ioc
, u32 ioc_status
, MPT_FRAME_HDR
*mf
);
214 static void mpt_fc_log_info(MPT_ADAPTER
*ioc
, u32 log_info
);
215 static void mpt_spi_log_info(MPT_ADAPTER
*ioc
, u32 log_info
);
216 static void mpt_sas_log_info(MPT_ADAPTER
*ioc
, u32 log_info
);
217 static int mpt_read_ioc_pg_3(MPT_ADAPTER
*ioc
);
218 static void mpt_inactive_raid_list_free(MPT_ADAPTER
*ioc
);
220 /* module entry point */
221 static int __init
fusion_init (void);
222 static void __exit
fusion_exit (void);
224 #define CHIPREG_READ32(addr) readl_relaxed(addr)
225 #define CHIPREG_READ32_dmasync(addr) readl(addr)
226 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
227 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
228 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
231 pci_disable_io_access(struct pci_dev
*pdev
)
235 pci_read_config_word(pdev
, PCI_COMMAND
, &command_reg
);
237 pci_write_config_word(pdev
, PCI_COMMAND
, command_reg
);
241 pci_enable_io_access(struct pci_dev
*pdev
)
245 pci_read_config_word(pdev
, PCI_COMMAND
, &command_reg
);
247 pci_write_config_word(pdev
, PCI_COMMAND
, command_reg
);
250 static int mpt_set_debug_level(const char *val
, struct kernel_param
*kp
)
252 int ret
= param_set_int(val
, kp
);
258 list_for_each_entry(ioc
, &ioc_list
, list
)
259 ioc
->debug_level
= mpt_debug_level
;
264 * mpt_get_cb_idx - obtain cb_idx for registered driver
265 * @dclass: class driver enum
267 * Returns cb_idx, or zero means it wasn't found
270 mpt_get_cb_idx(MPT_DRIVER_CLASS dclass
)
274 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--)
275 if (MptDriverClass
[cb_idx
] == dclass
)
281 * mpt_is_discovery_complete - determine if discovery has completed
282 * @ioc: per adatper instance
284 * Returns 1 when discovery completed, else zero.
287 mpt_is_discovery_complete(MPT_ADAPTER
*ioc
)
289 ConfigExtendedPageHeader_t hdr
;
291 SasIOUnitPage0_t
*buffer
;
292 dma_addr_t dma_handle
;
295 memset(&hdr
, 0, sizeof(ConfigExtendedPageHeader_t
));
296 memset(&cfg
, 0, sizeof(CONFIGPARMS
));
297 hdr
.PageVersion
= MPI_SASIOUNITPAGE0_PAGEVERSION
;
298 hdr
.PageType
= MPI_CONFIG_PAGETYPE_EXTENDED
;
299 hdr
.ExtPageType
= MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT
;
300 cfg
.cfghdr
.ehdr
= &hdr
;
301 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
303 if ((mpt_config(ioc
, &cfg
)))
305 if (!hdr
.ExtPageLength
)
308 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.ExtPageLength
* 4,
313 cfg
.physAddr
= dma_handle
;
314 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
316 if ((mpt_config(ioc
, &cfg
)))
317 goto out_free_consistent
;
319 if (!(buffer
->PhyData
[0].PortFlags
&
320 MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS
))
324 pci_free_consistent(ioc
->pcidev
, hdr
.ExtPageLength
* 4,
331 * mpt_fault_reset_work - work performed on workq after ioc fault
332 * @work: input argument, used to derive ioc
336 mpt_fault_reset_work(struct work_struct
*work
)
339 container_of(work
, MPT_ADAPTER
, fault_reset_work
.work
);
344 if (ioc
->ioc_reset_in_progress
|| !ioc
->active
)
347 ioc_raw_state
= mpt_GetIocState(ioc
, 0);
348 if ((ioc_raw_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_FAULT
) {
349 printk(MYIOC_s_WARN_FMT
"IOC is in FAULT state (%04xh)!!!\n",
350 ioc
->name
, ioc_raw_state
& MPI_DOORBELL_DATA_MASK
);
351 printk(MYIOC_s_WARN_FMT
"Issuing HardReset from %s!!\n",
352 ioc
->name
, __func__
);
353 rc
= mpt_HardResetHandler(ioc
, CAN_SLEEP
);
354 printk(MYIOC_s_WARN_FMT
"%s: HardReset: %s\n", ioc
->name
,
355 __func__
, (rc
== 0) ? "success" : "failed");
356 ioc_raw_state
= mpt_GetIocState(ioc
, 0);
357 if ((ioc_raw_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_FAULT
)
358 printk(MYIOC_s_WARN_FMT
"IOC is in FAULT state after "
359 "reset (%04xh)\n", ioc
->name
, ioc_raw_state
&
360 MPI_DOORBELL_DATA_MASK
);
361 } else if (ioc
->bus_type
== SAS
&& ioc
->sas_discovery_quiesce_io
) {
362 if ((mpt_is_discovery_complete(ioc
))) {
363 devtprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"clearing "
364 "discovery_quiesce_io flag\n", ioc
->name
));
365 ioc
->sas_discovery_quiesce_io
= 0;
371 * Take turns polling alternate controller
376 /* rearm the timer */
377 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
378 if (ioc
->reset_work_q
)
379 queue_delayed_work(ioc
->reset_work_q
, &ioc
->fault_reset_work
,
380 msecs_to_jiffies(MPT_POLLING_INTERVAL
));
381 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
386 * Process turbo (context) reply...
389 mpt_turbo_reply(MPT_ADAPTER
*ioc
, u32 pa
)
391 MPT_FRAME_HDR
*mf
= NULL
;
392 MPT_FRAME_HDR
*mr
= NULL
;
396 dmfprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Got TURBO reply req_idx=%08x\n",
399 switch (pa
>> MPI_CONTEXT_REPLY_TYPE_SHIFT
) {
400 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT
:
401 req_idx
= pa
& 0x0000FFFF;
402 cb_idx
= (pa
& 0x00FF0000) >> 16;
403 mf
= MPT_INDEX_2_MFPTR(ioc
, req_idx
);
405 case MPI_CONTEXT_REPLY_TYPE_LAN
:
406 cb_idx
= mpt_get_cb_idx(MPTLAN_DRIVER
);
408 * Blind set of mf to NULL here was fatal
409 * after lan_reply says "freeme"
410 * Fix sort of combined with an optimization here;
411 * added explicit check for case where lan_reply
412 * was just returning 1 and doing nothing else.
413 * For this case skip the callback, but set up
414 * proper mf value first here:-)
416 if ((pa
& 0x58000000) == 0x58000000) {
417 req_idx
= pa
& 0x0000FFFF;
418 mf
= MPT_INDEX_2_MFPTR(ioc
, req_idx
);
419 mpt_free_msg_frame(ioc
, mf
);
424 mr
= (MPT_FRAME_HDR
*) CAST_U32_TO_PTR(pa
);
426 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET
:
427 cb_idx
= mpt_get_cb_idx(MPTSTM_DRIVER
);
428 mr
= (MPT_FRAME_HDR
*) CAST_U32_TO_PTR(pa
);
435 /* Check for (valid) IO callback! */
436 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
||
437 MptCallbacks
[cb_idx
] == NULL
) {
438 printk(MYIOC_s_WARN_FMT
"%s: Invalid cb_idx (%d)!\n",
439 __func__
, ioc
->name
, cb_idx
);
443 if (MptCallbacks
[cb_idx
](ioc
, mf
, mr
))
444 mpt_free_msg_frame(ioc
, mf
);
450 mpt_reply(MPT_ADAPTER
*ioc
, u32 pa
)
461 /* non-TURBO reply! Hmmm, something may be up...
462 * Newest turbo reply mechanism; get address
463 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
466 /* Map DMA address of reply header to cpu address.
467 * pa is 32 bits - but the dma address may be 32 or 64 bits
468 * get offset based only only the low addresses
471 reply_dma_low
= (pa
<<= 1);
472 mr
= (MPT_FRAME_HDR
*)((u8
*)ioc
->reply_frames
+
473 (reply_dma_low
- ioc
->reply_frames_low_dma
));
475 req_idx
= le16_to_cpu(mr
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
);
476 cb_idx
= mr
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
;
477 mf
= MPT_INDEX_2_MFPTR(ioc
, req_idx
);
479 dmfprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
480 ioc
->name
, mr
, req_idx
, cb_idx
, mr
->u
.hdr
.Function
));
481 DBG_DUMP_REPLY_FRAME(ioc
, (u32
*)mr
);
483 /* Check/log IOC log info
485 ioc_stat
= le16_to_cpu(mr
->u
.reply
.IOCStatus
);
486 if (ioc_stat
& MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE
) {
487 u32 log_info
= le32_to_cpu(mr
->u
.reply
.IOCLogInfo
);
488 if (ioc
->bus_type
== FC
)
489 mpt_fc_log_info(ioc
, log_info
);
490 else if (ioc
->bus_type
== SPI
)
491 mpt_spi_log_info(ioc
, log_info
);
492 else if (ioc
->bus_type
== SAS
)
493 mpt_sas_log_info(ioc
, log_info
);
496 if (ioc_stat
& MPI_IOCSTATUS_MASK
)
497 mpt_iocstatus_info(ioc
, (u32
)ioc_stat
, mf
);
499 /* Check for (valid) IO callback! */
500 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
||
501 MptCallbacks
[cb_idx
] == NULL
) {
502 printk(MYIOC_s_WARN_FMT
"%s: Invalid cb_idx (%d)!\n",
503 __func__
, ioc
->name
, cb_idx
);
508 freeme
= MptCallbacks
[cb_idx
](ioc
, mf
, mr
);
511 /* Flush (non-TURBO) reply with a WRITE! */
512 CHIPREG_WRITE32(&ioc
->chip
->ReplyFifo
, pa
);
515 mpt_free_msg_frame(ioc
, mf
);
519 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
521 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
522 * @irq: irq number (not used)
523 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
525 * This routine is registered via the request_irq() kernel API call,
526 * and handles all interrupts generated from a specific MPT adapter
527 * (also referred to as a IO Controller or IOC).
528 * This routine must clear the interrupt from the adapter and does
529 * so by reading the reply FIFO. Multiple replies may be processed
530 * per single call to this routine.
532 * This routine handles register-level access of the adapter but
533 * dispatches (calls) a protocol-specific callback routine to handle
534 * the protocol-specific details of the MPT request completion.
537 mpt_interrupt(int irq
, void *bus_id
)
539 MPT_ADAPTER
*ioc
= bus_id
;
540 u32 pa
= CHIPREG_READ32_dmasync(&ioc
->chip
->ReplyFifo
);
542 if (pa
== 0xFFFFFFFF)
546 * Drain the reply FIFO!
549 if (pa
& MPI_ADDRESS_REPLY_A_BIT
)
552 mpt_turbo_reply(ioc
, pa
);
553 pa
= CHIPREG_READ32_dmasync(&ioc
->chip
->ReplyFifo
);
554 } while (pa
!= 0xFFFFFFFF);
559 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
561 * mptbase_reply - MPT base driver's callback routine
562 * @ioc: Pointer to MPT_ADAPTER structure
563 * @req: Pointer to original MPT request frame
564 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
566 * MPT base driver's callback routine; all base driver
567 * "internal" request/reply processing is routed here.
568 * Currently used for EventNotification and EventAck handling.
570 * Returns 1 indicating original alloc'd request frame ptr
571 * should be freed, or 0 if it shouldn't.
574 mptbase_reply(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*req
, MPT_FRAME_HDR
*reply
)
576 EventNotificationReply_t
*pEventReply
;
581 switch (reply
->u
.hdr
.Function
) {
582 case MPI_FUNCTION_EVENT_NOTIFICATION
:
583 pEventReply
= (EventNotificationReply_t
*)reply
;
585 ProcessEventNotification(ioc
, pEventReply
, &evHandlers
);
586 event
= le32_to_cpu(pEventReply
->Event
) & 0xFF;
587 if (pEventReply
->MsgFlags
& MPI_MSGFLAGS_CONTINUATION_REPLY
)
589 if (event
!= MPI_EVENT_EVENT_CHANGE
)
591 case MPI_FUNCTION_CONFIG
:
592 case MPI_FUNCTION_SAS_IO_UNIT_CONTROL
:
593 ioc
->mptbase_cmds
.status
|= MPT_MGMT_STATUS_COMMAND_GOOD
;
595 ioc
->mptbase_cmds
.status
|= MPT_MGMT_STATUS_RF_VALID
;
596 memcpy(ioc
->mptbase_cmds
.reply
, reply
,
597 min(MPT_DEFAULT_FRAME_SIZE
,
598 4 * reply
->u
.reply
.MsgLength
));
600 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_PENDING
) {
601 ioc
->mptbase_cmds
.status
&= ~MPT_MGMT_STATUS_PENDING
;
602 complete(&ioc
->mptbase_cmds
.done
);
605 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_FREE_MF
)
608 case MPI_FUNCTION_EVENT_ACK
:
609 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
610 "EventAck reply received\n", ioc
->name
));
613 printk(MYIOC_s_ERR_FMT
614 "Unexpected msg function (=%02Xh) reply received!\n",
615 ioc
->name
, reply
->u
.hdr
.Function
);
620 * Conditionally tell caller to free the original
621 * EventNotification/EventAck/unexpected request frame!
626 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
628 * mpt_register - Register protocol-specific main callback handler.
629 * @cbfunc: callback function pointer
630 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
632 * This routine is called by a protocol-specific driver (SCSI host,
633 * LAN, SCSI target) to register its reply callback routine. Each
634 * protocol-specific driver must do this before it will be able to
635 * use any IOC resources, such as obtaining request frames.
637 * NOTES: The SCSI protocol driver currently calls this routine thrice
638 * in order to register separate callbacks; one for "normal" SCSI IO;
639 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
641 * Returns u8 valued "handle" in the range (and S.O.D. order)
642 * {N,...,7,6,5,...,1} if successful.
643 * A return value of MPT_MAX_PROTOCOL_DRIVERS (including zero!) should be
644 * considered an error by the caller.
647 mpt_register(MPT_CALLBACK cbfunc
, MPT_DRIVER_CLASS dclass
)
650 last_drv_idx
= MPT_MAX_PROTOCOL_DRIVERS
;
653 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
654 * (slot/handle 0 is reserved!)
656 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
657 if (MptCallbacks
[cb_idx
] == NULL
) {
658 MptCallbacks
[cb_idx
] = cbfunc
;
659 MptDriverClass
[cb_idx
] = dclass
;
660 MptEvHandlers
[cb_idx
] = NULL
;
661 last_drv_idx
= cb_idx
;
669 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
671 * mpt_deregister - Deregister a protocol drivers resources.
672 * @cb_idx: previously registered callback handle
674 * Each protocol-specific driver should call this routine when its
675 * module is unloaded.
678 mpt_deregister(u8 cb_idx
)
680 if (cb_idx
&& (cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
)) {
681 MptCallbacks
[cb_idx
] = NULL
;
682 MptDriverClass
[cb_idx
] = MPTUNKNOWN_DRIVER
;
683 MptEvHandlers
[cb_idx
] = NULL
;
689 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
691 * mpt_event_register - Register protocol-specific event callback handler.
692 * @cb_idx: previously registered (via mpt_register) callback handle
693 * @ev_cbfunc: callback function
695 * This routine can be called by one or more protocol-specific drivers
696 * if/when they choose to be notified of MPT events.
698 * Returns 0 for success.
701 mpt_event_register(u8 cb_idx
, MPT_EVHANDLER ev_cbfunc
)
703 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
706 MptEvHandlers
[cb_idx
] = ev_cbfunc
;
710 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
712 * mpt_event_deregister - Deregister protocol-specific event callback handler
713 * @cb_idx: previously registered callback handle
715 * Each protocol-specific driver should call this routine
716 * when it does not (or can no longer) handle events,
717 * or when its module is unloaded.
720 mpt_event_deregister(u8 cb_idx
)
722 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
725 MptEvHandlers
[cb_idx
] = NULL
;
728 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
730 * mpt_reset_register - Register protocol-specific IOC reset handler.
731 * @cb_idx: previously registered (via mpt_register) callback handle
732 * @reset_func: reset function
734 * This routine can be called by one or more protocol-specific drivers
735 * if/when they choose to be notified of IOC resets.
737 * Returns 0 for success.
740 mpt_reset_register(u8 cb_idx
, MPT_RESETHANDLER reset_func
)
742 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
745 MptResetHandlers
[cb_idx
] = reset_func
;
749 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
751 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
752 * @cb_idx: previously registered callback handle
754 * Each protocol-specific driver should call this routine
755 * when it does not (or can no longer) handle IOC reset handling,
756 * or when its module is unloaded.
759 mpt_reset_deregister(u8 cb_idx
)
761 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
764 MptResetHandlers
[cb_idx
] = NULL
;
767 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
769 * mpt_device_driver_register - Register device driver hooks
770 * @dd_cbfunc: driver callbacks struct
771 * @cb_idx: MPT protocol driver index
774 mpt_device_driver_register(struct mpt_pci_driver
* dd_cbfunc
, u8 cb_idx
)
777 const struct pci_device_id
*id
;
779 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
782 MptDeviceDriverHandlers
[cb_idx
] = dd_cbfunc
;
784 /* call per pci device probe entry point */
785 list_for_each_entry(ioc
, &ioc_list
, list
) {
786 id
= ioc
->pcidev
->driver
?
787 ioc
->pcidev
->driver
->id_table
: NULL
;
788 if (dd_cbfunc
->probe
)
789 dd_cbfunc
->probe(ioc
->pcidev
, id
);
795 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
797 * mpt_device_driver_deregister - DeRegister device driver hooks
798 * @cb_idx: MPT protocol driver index
801 mpt_device_driver_deregister(u8 cb_idx
)
803 struct mpt_pci_driver
*dd_cbfunc
;
806 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
809 dd_cbfunc
= MptDeviceDriverHandlers
[cb_idx
];
811 list_for_each_entry(ioc
, &ioc_list
, list
) {
812 if (dd_cbfunc
->remove
)
813 dd_cbfunc
->remove(ioc
->pcidev
);
816 MptDeviceDriverHandlers
[cb_idx
] = NULL
;
820 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
822 * mpt_get_msg_frame - Obtain an MPT request frame from the pool
823 * @cb_idx: Handle of registered MPT protocol driver
824 * @ioc: Pointer to MPT adapter structure
826 * Obtain an MPT request frame from the pool (of 1024) that are
827 * allocated per MPT adapter.
829 * Returns pointer to a MPT request frame or %NULL if none are available
830 * or IOC is not active.
833 mpt_get_msg_frame(u8 cb_idx
, MPT_ADAPTER
*ioc
)
837 u16 req_idx
; /* Request index */
839 /* validate handle and ioc identifier */
843 printk(MYIOC_s_WARN_FMT
"IOC Not Active! mpt_get_msg_frame "
844 "returning NULL!\n", ioc
->name
);
847 /* If interrupts are not attached, do not return a request frame */
851 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
852 if (!list_empty(&ioc
->FreeQ
)) {
855 mf
= list_entry(ioc
->FreeQ
.next
, MPT_FRAME_HDR
,
856 u
.frame
.linkage
.list
);
857 list_del(&mf
->u
.frame
.linkage
.list
);
858 mf
->u
.frame
.linkage
.arg1
= 0;
859 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= cb_idx
; /* byte */
860 req_offset
= (u8
*)mf
- (u8
*)ioc
->req_frames
;
862 req_idx
= req_offset
/ ioc
->req_sz
;
863 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(req_idx
);
864 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.rsvd
= 0;
865 /* Default, will be changed if necessary in SG generation */
866 ioc
->RequestNB
[req_idx
] = ioc
->NB_for_64_byte_frame
;
873 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
877 printk(MYIOC_s_WARN_FMT
"IOC Active. No free Msg Frames! "
878 "Count 0x%x Max 0x%x\n", ioc
->name
, ioc
->mfcnt
,
881 if (mfcounter
== PRINT_MF_COUNT
)
882 printk(MYIOC_s_INFO_FMT
"MF Count 0x%x Max 0x%x \n", ioc
->name
,
883 ioc
->mfcnt
, ioc
->req_depth
);
886 dmfprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mpt_get_msg_frame(%d,%d), got mf=%p\n",
887 ioc
->name
, cb_idx
, ioc
->id
, mf
));
891 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
893 * mpt_put_msg_frame - Send a protocol-specific MPT request frame to an IOC
894 * @cb_idx: Handle of registered MPT protocol driver
895 * @ioc: Pointer to MPT adapter structure
896 * @mf: Pointer to MPT request frame
898 * This routine posts an MPT request frame to the request post FIFO of a
899 * specific MPT adapter.
902 mpt_put_msg_frame(u8 cb_idx
, MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
)
906 u16 req_idx
; /* Request index */
908 /* ensure values are reset properly! */
909 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= cb_idx
; /* byte */
910 req_offset
= (u8
*)mf
- (u8
*)ioc
->req_frames
;
912 req_idx
= req_offset
/ ioc
->req_sz
;
913 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(req_idx
);
914 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.rsvd
= 0;
916 DBG_DUMP_PUT_MSG_FRAME(ioc
, (u32
*)mf
);
918 mf_dma_addr
= (ioc
->req_frames_low_dma
+ req_offset
) | ioc
->RequestNB
[req_idx
];
919 dsgprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mf_dma_addr=%x req_idx=%d "
920 "RequestNB=%x\n", ioc
->name
, mf_dma_addr
, req_idx
,
921 ioc
->RequestNB
[req_idx
]));
922 CHIPREG_WRITE32(&ioc
->chip
->RequestFifo
, mf_dma_addr
);
926 * mpt_put_msg_frame_hi_pri - Send a hi-pri protocol-specific MPT request frame
927 * @cb_idx: Handle of registered MPT protocol driver
928 * @ioc: Pointer to MPT adapter structure
929 * @mf: Pointer to MPT request frame
931 * Send a protocol-specific MPT request frame to an IOC using
932 * hi-priority request queue.
934 * This routine posts an MPT request frame to the request post FIFO of a
935 * specific MPT adapter.
938 mpt_put_msg_frame_hi_pri(u8 cb_idx
, MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
)
942 u16 req_idx
; /* Request index */
944 /* ensure values are reset properly! */
945 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= cb_idx
;
946 req_offset
= (u8
*)mf
- (u8
*)ioc
->req_frames
;
947 req_idx
= req_offset
/ ioc
->req_sz
;
948 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(req_idx
);
949 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.rsvd
= 0;
951 DBG_DUMP_PUT_MSG_FRAME(ioc
, (u32
*)mf
);
953 mf_dma_addr
= (ioc
->req_frames_low_dma
+ req_offset
);
954 dsgprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mf_dma_addr=%x req_idx=%d\n",
955 ioc
->name
, mf_dma_addr
, req_idx
));
956 CHIPREG_WRITE32(&ioc
->chip
->RequestHiPriFifo
, mf_dma_addr
);
959 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
961 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
962 * @ioc: Pointer to MPT adapter structure
963 * @mf: Pointer to MPT request frame
965 * This routine places a MPT request frame back on the MPT adapter's
969 mpt_free_msg_frame(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
)
973 /* Put Request back on FreeQ! */
974 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
975 if (cpu_to_le32(mf
->u
.frame
.linkage
.arg1
) == 0xdeadbeaf)
977 /* signature to know if this mf is freed */
978 mf
->u
.frame
.linkage
.arg1
= cpu_to_le32(0xdeadbeaf);
979 list_add_tail(&mf
->u
.frame
.linkage
.list
, &ioc
->FreeQ
);
984 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
987 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
989 * mpt_add_sge - Place a simple 32 bit SGE at address pAddr.
990 * @pAddr: virtual address for SGE
991 * @flagslength: SGE flags and data transfer length
992 * @dma_addr: Physical address
994 * This routine places a MPT request frame back on the MPT adapter's
998 mpt_add_sge(void *pAddr
, u32 flagslength
, dma_addr_t dma_addr
)
1000 SGESimple32_t
*pSge
= (SGESimple32_t
*) pAddr
;
1001 pSge
->FlagsLength
= cpu_to_le32(flagslength
);
1002 pSge
->Address
= cpu_to_le32(dma_addr
);
1006 * mpt_add_sge_64bit - Place a simple 64 bit SGE at address pAddr.
1007 * @pAddr: virtual address for SGE
1008 * @flagslength: SGE flags and data transfer length
1009 * @dma_addr: Physical address
1011 * This routine places a MPT request frame back on the MPT adapter's
1015 mpt_add_sge_64bit(void *pAddr
, u32 flagslength
, dma_addr_t dma_addr
)
1017 SGESimple64_t
*pSge
= (SGESimple64_t
*) pAddr
;
1018 pSge
->Address
.Low
= cpu_to_le32
1019 (lower_32_bits(dma_addr
));
1020 pSge
->Address
.High
= cpu_to_le32
1021 (upper_32_bits(dma_addr
));
1022 pSge
->FlagsLength
= cpu_to_le32
1023 ((flagslength
| MPT_SGE_FLAGS_64_BIT_ADDRESSING
));
1027 * mpt_add_sge_64bit_1078 - Place a simple 64 bit SGE at address pAddr (1078 workaround).
1028 * @pAddr: virtual address for SGE
1029 * @flagslength: SGE flags and data transfer length
1030 * @dma_addr: Physical address
1032 * This routine places a MPT request frame back on the MPT adapter's
1036 mpt_add_sge_64bit_1078(void *pAddr
, u32 flagslength
, dma_addr_t dma_addr
)
1038 SGESimple64_t
*pSge
= (SGESimple64_t
*) pAddr
;
1041 pSge
->Address
.Low
= cpu_to_le32
1042 (lower_32_bits(dma_addr
));
1043 tmp
= (u32
)(upper_32_bits(dma_addr
));
1046 * 1078 errata workaround for the 36GB limitation
1048 if ((((u64
)dma_addr
+ MPI_SGE_LENGTH(flagslength
)) >> 32) == 9) {
1050 MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_LOCAL_ADDRESS
);
1052 if (mpt_debug_level
& MPT_DEBUG_36GB_MEM
)
1053 printk(KERN_DEBUG
"1078 P0M2 addressing for "
1054 "addr = 0x%llx len = %d\n",
1055 (unsigned long long)dma_addr
,
1056 MPI_SGE_LENGTH(flagslength
));
1059 pSge
->Address
.High
= cpu_to_le32(tmp
);
1060 pSge
->FlagsLength
= cpu_to_le32(
1061 (flagslength
| MPT_SGE_FLAGS_64_BIT_ADDRESSING
));
1064 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1066 * mpt_add_chain - Place a 32 bit chain SGE at address pAddr.
1067 * @pAddr: virtual address for SGE
1068 * @next: nextChainOffset value (u32's)
1069 * @length: length of next SGL segment
1070 * @dma_addr: Physical address
1074 mpt_add_chain(void *pAddr
, u8 next
, u16 length
, dma_addr_t dma_addr
)
1076 SGEChain32_t
*pChain
= (SGEChain32_t
*) pAddr
;
1077 pChain
->Length
= cpu_to_le16(length
);
1078 pChain
->Flags
= MPI_SGE_FLAGS_CHAIN_ELEMENT
;
1079 pChain
->NextChainOffset
= next
;
1080 pChain
->Address
= cpu_to_le32(dma_addr
);
1083 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1085 * mpt_add_chain_64bit - Place a 64 bit chain SGE at address pAddr.
1086 * @pAddr: virtual address for SGE
1087 * @next: nextChainOffset value (u32's)
1088 * @length: length of next SGL segment
1089 * @dma_addr: Physical address
1093 mpt_add_chain_64bit(void *pAddr
, u8 next
, u16 length
, dma_addr_t dma_addr
)
1095 SGEChain64_t
*pChain
= (SGEChain64_t
*) pAddr
;
1096 u32 tmp
= dma_addr
& 0xFFFFFFFF;
1098 pChain
->Length
= cpu_to_le16(length
);
1099 pChain
->Flags
= (MPI_SGE_FLAGS_CHAIN_ELEMENT
|
1100 MPI_SGE_FLAGS_64_BIT_ADDRESSING
);
1102 pChain
->NextChainOffset
= next
;
1104 pChain
->Address
.Low
= cpu_to_le32(tmp
);
1105 tmp
= (u32
)(upper_32_bits(dma_addr
));
1106 pChain
->Address
.High
= cpu_to_le32(tmp
);
1109 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1111 * mpt_send_handshake_request - Send MPT request via doorbell handshake method.
1112 * @cb_idx: Handle of registered MPT protocol driver
1113 * @ioc: Pointer to MPT adapter structure
1114 * @reqBytes: Size of the request in bytes
1115 * @req: Pointer to MPT request frame
1116 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1118 * This routine is used exclusively to send MptScsiTaskMgmt
1119 * requests since they are required to be sent via doorbell handshake.
1121 * NOTE: It is the callers responsibility to byte-swap fields in the
1122 * request which are greater than 1 byte in size.
1124 * Returns 0 for success, non-zero for failure.
1127 mpt_send_handshake_request(u8 cb_idx
, MPT_ADAPTER
*ioc
, int reqBytes
, u32
*req
, int sleepFlag
)
1133 /* State is known to be good upon entering
1134 * this function so issue the bus reset
1139 * Emulate what mpt_put_msg_frame() does /wrt to sanity
1140 * setting cb_idx/req_idx. But ONLY if this request
1141 * is in proper (pre-alloc'd) request buffer range...
1143 ii
= MFPTR_2_MPT_INDEX(ioc
,(MPT_FRAME_HDR
*)req
);
1144 if (reqBytes
>= 12 && ii
>= 0 && ii
< ioc
->req_depth
) {
1145 MPT_FRAME_HDR
*mf
= (MPT_FRAME_HDR
*)req
;
1146 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(ii
);
1147 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= cb_idx
;
1150 /* Make sure there are no doorbells */
1151 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1153 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
,
1154 ((MPI_FUNCTION_HANDSHAKE
<<MPI_DOORBELL_FUNCTION_SHIFT
) |
1155 ((reqBytes
/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT
)));
1157 /* Wait for IOC doorbell int */
1158 if ((ii
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0) {
1162 /* Read doorbell and check for active bit */
1163 if (!(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & MPI_DOORBELL_ACTIVE
))
1166 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mpt_send_handshake_request start, WaitCnt=%d\n",
1169 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1171 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0) {
1175 /* Send request via doorbell handshake */
1176 req_as_bytes
= (u8
*) req
;
1177 for (ii
= 0; ii
< reqBytes
/4; ii
++) {
1180 word
= ((req_as_bytes
[(ii
*4) + 0] << 0) |
1181 (req_as_bytes
[(ii
*4) + 1] << 8) |
1182 (req_as_bytes
[(ii
*4) + 2] << 16) |
1183 (req_as_bytes
[(ii
*4) + 3] << 24));
1184 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, word
);
1185 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0) {
1191 if (r
>= 0 && WaitForDoorbellInt(ioc
, 10, sleepFlag
) >= 0)
1196 /* Make sure there are no doorbells */
1197 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1202 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1204 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
1205 * @ioc: Pointer to MPT adapter structure
1206 * @access_control_value: define bits below
1207 * @sleepFlag: Specifies whether the process can sleep
1209 * Provides mechanism for the host driver to control the IOC's
1210 * Host Page Buffer access.
1212 * Access Control Value - bits[15:12]
1214 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1215 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1216 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1218 * Returns 0 for success, non-zero for failure.
1222 mpt_host_page_access_control(MPT_ADAPTER
*ioc
, u8 access_control_value
, int sleepFlag
)
1226 /* return if in use */
1227 if (CHIPREG_READ32(&ioc
->chip
->Doorbell
)
1228 & MPI_DOORBELL_ACTIVE
)
1231 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1233 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
,
1234 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1235 <<MPI_DOORBELL_FUNCTION_SHIFT
) |
1236 (access_control_value
<<12)));
1238 /* Wait for IOC to clear Doorbell Status bit */
1239 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0) {
1245 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1247 * mpt_host_page_alloc - allocate system memory for the fw
1248 * @ioc: Pointer to pointer to IOC adapter
1249 * @ioc_init: Pointer to ioc init config page
1251 * If we already allocated memory in past, then resend the same pointer.
1252 * Returns 0 for success, non-zero for failure.
1255 mpt_host_page_alloc(MPT_ADAPTER
*ioc
, pIOCInit_t ioc_init
)
1259 u32 host_page_buffer_sz
=0;
1261 if(!ioc
->HostPageBuffer
) {
1263 host_page_buffer_sz
=
1264 le32_to_cpu(ioc
->facts
.HostPageBufferSGE
.FlagsLength
) & 0xFFFFFF;
1266 if(!host_page_buffer_sz
)
1267 return 0; /* fw doesn't need any host buffers */
1269 /* spin till we get enough memory */
1270 while(host_page_buffer_sz
> 0) {
1272 if((ioc
->HostPageBuffer
= pci_alloc_consistent(
1274 host_page_buffer_sz
,
1275 &ioc
->HostPageBuffer_dma
)) != NULL
) {
1277 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
1278 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1279 ioc
->name
, ioc
->HostPageBuffer
,
1280 (u32
)ioc
->HostPageBuffer_dma
,
1281 host_page_buffer_sz
));
1282 ioc
->alloc_total
+= host_page_buffer_sz
;
1283 ioc
->HostPageBuffer_sz
= host_page_buffer_sz
;
1287 host_page_buffer_sz
-= (4*1024);
1291 if(!ioc
->HostPageBuffer
) {
1292 printk(MYIOC_s_ERR_FMT
1293 "Failed to alloc memory for host_page_buffer!\n",
1298 psge
= (char *)&ioc_init
->HostPageBufferSGE
;
1299 flags_length
= MPI_SGE_FLAGS_SIMPLE_ELEMENT
|
1300 MPI_SGE_FLAGS_SYSTEM_ADDRESS
|
1301 MPI_SGE_FLAGS_HOST_TO_IOC
|
1302 MPI_SGE_FLAGS_END_OF_BUFFER
;
1303 flags_length
= flags_length
<< MPI_SGE_FLAGS_SHIFT
;
1304 flags_length
|= ioc
->HostPageBuffer_sz
;
1305 ioc
->add_sge(psge
, flags_length
, ioc
->HostPageBuffer_dma
);
1306 ioc
->facts
.HostPageBufferSGE
= ioc_init
->HostPageBufferSGE
;
1311 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1313 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1314 * @iocid: IOC unique identifier (integer)
1315 * @iocpp: Pointer to pointer to IOC adapter
1317 * Given a unique IOC identifier, set pointer to the associated MPT
1318 * adapter structure.
1320 * Returns iocid and sets iocpp if iocid is found.
1321 * Returns -1 if iocid is not found.
1324 mpt_verify_adapter(int iocid
, MPT_ADAPTER
**iocpp
)
1328 list_for_each_entry(ioc
,&ioc_list
,list
) {
1329 if (ioc
->id
== iocid
) {
1340 * mpt_get_product_name - returns product string
1341 * @vendor: pci vendor id
1342 * @device: pci device id
1343 * @revision: pci revision id
1344 * @prod_name: string returned
1346 * Returns product string displayed when driver loads,
1347 * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1351 mpt_get_product_name(u16 vendor
, u16 device
, u8 revision
, char *prod_name
)
1353 char *product_str
= NULL
;
1355 if (vendor
== PCI_VENDOR_ID_BROCADE
) {
1358 case MPI_MANUFACTPAGE_DEVICEID_FC949E
:
1362 product_str
= "BRE040 A0";
1365 product_str
= "BRE040 A1";
1368 product_str
= "BRE040";
1378 case MPI_MANUFACTPAGE_DEVICEID_FC909
:
1379 product_str
= "LSIFC909 B1";
1381 case MPI_MANUFACTPAGE_DEVICEID_FC919
:
1382 product_str
= "LSIFC919 B0";
1384 case MPI_MANUFACTPAGE_DEVICEID_FC929
:
1385 product_str
= "LSIFC929 B0";
1387 case MPI_MANUFACTPAGE_DEVICEID_FC919X
:
1388 if (revision
< 0x80)
1389 product_str
= "LSIFC919X A0";
1391 product_str
= "LSIFC919XL A1";
1393 case MPI_MANUFACTPAGE_DEVICEID_FC929X
:
1394 if (revision
< 0x80)
1395 product_str
= "LSIFC929X A0";
1397 product_str
= "LSIFC929XL A1";
1399 case MPI_MANUFACTPAGE_DEVICEID_FC939X
:
1400 product_str
= "LSIFC939X A1";
1402 case MPI_MANUFACTPAGE_DEVICEID_FC949X
:
1403 product_str
= "LSIFC949X A1";
1405 case MPI_MANUFACTPAGE_DEVICEID_FC949E
:
1409 product_str
= "LSIFC949E A0";
1412 product_str
= "LSIFC949E A1";
1415 product_str
= "LSIFC949E";
1419 case MPI_MANUFACTPAGE_DEVID_53C1030
:
1423 product_str
= "LSI53C1030 A0";
1426 product_str
= "LSI53C1030 B0";
1429 product_str
= "LSI53C1030 B1";
1432 product_str
= "LSI53C1030 B2";
1435 product_str
= "LSI53C1030 C0";
1438 product_str
= "LSI53C1030T A0";
1441 product_str
= "LSI53C1030T A2";
1444 product_str
= "LSI53C1030T A3";
1447 product_str
= "LSI53C1020A A1";
1450 product_str
= "LSI53C1030";
1454 case MPI_MANUFACTPAGE_DEVID_1030_53C1035
:
1458 product_str
= "LSI53C1035 A2";
1461 product_str
= "LSI53C1035 B0";
1464 product_str
= "LSI53C1035";
1468 case MPI_MANUFACTPAGE_DEVID_SAS1064
:
1472 product_str
= "LSISAS1064 A1";
1475 product_str
= "LSISAS1064 A2";
1478 product_str
= "LSISAS1064 A3";
1481 product_str
= "LSISAS1064 A4";
1484 product_str
= "LSISAS1064";
1488 case MPI_MANUFACTPAGE_DEVID_SAS1064E
:
1492 product_str
= "LSISAS1064E A0";
1495 product_str
= "LSISAS1064E B0";
1498 product_str
= "LSISAS1064E B1";
1501 product_str
= "LSISAS1064E B2";
1504 product_str
= "LSISAS1064E B3";
1507 product_str
= "LSISAS1064E";
1511 case MPI_MANUFACTPAGE_DEVID_SAS1068
:
1515 product_str
= "LSISAS1068 A0";
1518 product_str
= "LSISAS1068 B0";
1521 product_str
= "LSISAS1068 B1";
1524 product_str
= "LSISAS1068";
1528 case MPI_MANUFACTPAGE_DEVID_SAS1068E
:
1532 product_str
= "LSISAS1068E A0";
1535 product_str
= "LSISAS1068E B0";
1538 product_str
= "LSISAS1068E B1";
1541 product_str
= "LSISAS1068E B2";
1544 product_str
= "LSISAS1068E B3";
1547 product_str
= "LSISAS1068E";
1551 case MPI_MANUFACTPAGE_DEVID_SAS1078
:
1555 product_str
= "LSISAS1078 A0";
1558 product_str
= "LSISAS1078 B0";
1561 product_str
= "LSISAS1078 C0";
1564 product_str
= "LSISAS1078 C1";
1567 product_str
= "LSISAS1078 C2";
1570 product_str
= "LSISAS1078";
1578 sprintf(prod_name
, "%s", product_str
);
1582 * mpt_mapresources - map in memory mapped io
1583 * @ioc: Pointer to pointer to IOC adapter
1587 mpt_mapresources(MPT_ADAPTER
*ioc
)
1591 resource_size_t mem_phys
;
1597 struct pci_dev
*pdev
;
1600 ioc
->bars
= pci_select_bars(pdev
, IORESOURCE_MEM
);
1601 if (pci_enable_device_mem(pdev
)) {
1602 printk(MYIOC_s_ERR_FMT
"pci_enable_device_mem() "
1603 "failed\n", ioc
->name
);
1606 if (pci_request_selected_regions(pdev
, ioc
->bars
, "mpt")) {
1607 printk(MYIOC_s_ERR_FMT
"pci_request_selected_regions() with "
1608 "MEM failed\n", ioc
->name
);
1612 pci_read_config_byte(pdev
, PCI_CLASS_REVISION
, &revision
);
1614 if (sizeof(dma_addr_t
) > 4) {
1615 const uint64_t required_mask
= dma_get_required_mask
1617 if (required_mask
> DMA_BIT_MASK(32)
1618 && !pci_set_dma_mask(pdev
, DMA_BIT_MASK(64))
1619 && !pci_set_consistent_dma_mask(pdev
,
1620 DMA_BIT_MASK(64))) {
1621 ioc
->dma_mask
= DMA_BIT_MASK(64);
1622 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
1623 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1625 } else if (!pci_set_dma_mask(pdev
, DMA_BIT_MASK(32))
1626 && !pci_set_consistent_dma_mask(pdev
,
1627 DMA_BIT_MASK(32))) {
1628 ioc
->dma_mask
= DMA_BIT_MASK(32);
1629 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
1630 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1633 printk(MYIOC_s_WARN_FMT
"no suitable DMA mask for %s\n",
1634 ioc
->name
, pci_name(pdev
));
1638 if (!pci_set_dma_mask(pdev
, DMA_BIT_MASK(32))
1639 && !pci_set_consistent_dma_mask(pdev
,
1640 DMA_BIT_MASK(32))) {
1641 ioc
->dma_mask
= DMA_BIT_MASK(32);
1642 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
1643 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1646 printk(MYIOC_s_WARN_FMT
"no suitable DMA mask for %s\n",
1647 ioc
->name
, pci_name(pdev
));
1652 mem_phys
= msize
= 0;
1654 for (ii
= 0; ii
< DEVICE_COUNT_RESOURCE
; ii
++) {
1655 if (pci_resource_flags(pdev
, ii
) & PCI_BASE_ADDRESS_SPACE_IO
) {
1658 /* Get I/O space! */
1659 port
= pci_resource_start(pdev
, ii
);
1660 psize
= pci_resource_len(pdev
, ii
);
1665 mem_phys
= pci_resource_start(pdev
, ii
);
1666 msize
= pci_resource_len(pdev
, ii
);
1669 ioc
->mem_size
= msize
;
1672 /* Get logical ptr for PciMem0 space */
1673 /*mem = ioremap(mem_phys, msize);*/
1674 mem
= ioremap(mem_phys
, msize
);
1676 printk(MYIOC_s_ERR_FMT
": ERROR - Unable to map adapter"
1677 " memory!\n", ioc
->name
);
1681 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"mem = %p, mem_phys = %llx\n",
1682 ioc
->name
, mem
, (unsigned long long)mem_phys
));
1684 ioc
->mem_phys
= mem_phys
;
1685 ioc
->chip
= (SYSIF_REGS __iomem
*)mem
;
1687 /* Save Port IO values in case we need to do downloadboot */
1688 ioc
->pio_mem_phys
= port
;
1689 ioc
->pio_chip
= (SYSIF_REGS __iomem
*)port
;
1694 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1696 * mpt_attach - Install a PCI intelligent MPT adapter.
1697 * @pdev: Pointer to pci_dev structure
1698 * @id: PCI device ID information
1700 * This routine performs all the steps necessary to bring the IOC of
1701 * a MPT adapter to a OPERATIONAL state. This includes registering
1702 * memory regions, registering the interrupt, and allocating request
1703 * and reply memory pools.
1705 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1708 * Returns 0 for success, non-zero for failure.
1710 * TODO: Add support for polled controllers
1713 mpt_attach(struct pci_dev
*pdev
, const struct pci_device_id
*id
)
1720 static int mpt_ids
= 0;
1721 #ifdef CONFIG_PROC_FS
1722 struct proc_dir_entry
*dent
, *ent
;
1725 ioc
= kzalloc(sizeof(MPT_ADAPTER
), GFP_ATOMIC
);
1727 printk(KERN_ERR MYNAM
": ERROR - Insufficient memory to add adapter!\n");
1731 ioc
->id
= mpt_ids
++;
1732 sprintf(ioc
->name
, "ioc%d", ioc
->id
);
1733 dinitprintk(ioc
, printk(KERN_WARNING MYNAM
": mpt_adapter_install\n"));
1736 * set initial debug level
1737 * (refer to mptdebug.h)
1740 ioc
->debug_level
= mpt_debug_level
;
1741 if (mpt_debug_level
)
1742 printk(KERN_INFO
"mpt_debug_level=%xh\n", mpt_debug_level
);
1744 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
": mpt_adapter_install\n", ioc
->name
));
1747 if (mpt_mapresources(ioc
)) {
1753 * Setting up proper handlers for scatter gather handling
1755 if (ioc
->dma_mask
== DMA_BIT_MASK(64)) {
1756 if (pdev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1078
)
1757 ioc
->add_sge
= &mpt_add_sge_64bit_1078
;
1759 ioc
->add_sge
= &mpt_add_sge_64bit
;
1760 ioc
->add_chain
= &mpt_add_chain_64bit
;
1761 ioc
->sg_addr_size
= 8;
1763 ioc
->add_sge
= &mpt_add_sge
;
1764 ioc
->add_chain
= &mpt_add_chain
;
1765 ioc
->sg_addr_size
= 4;
1767 ioc
->SGE_size
= sizeof(u32
) + ioc
->sg_addr_size
;
1769 ioc
->alloc_total
= sizeof(MPT_ADAPTER
);
1770 ioc
->req_sz
= MPT_DEFAULT_FRAME_SIZE
; /* avoid div by zero! */
1771 ioc
->reply_sz
= MPT_REPLY_FRAME_SIZE
;
1775 spin_lock_init(&ioc
->taskmgmt_lock
);
1776 mutex_init(&ioc
->internal_cmds
.mutex
);
1777 init_completion(&ioc
->internal_cmds
.done
);
1778 mutex_init(&ioc
->mptbase_cmds
.mutex
);
1779 init_completion(&ioc
->mptbase_cmds
.done
);
1780 mutex_init(&ioc
->taskmgmt_cmds
.mutex
);
1781 init_completion(&ioc
->taskmgmt_cmds
.done
);
1783 /* Initialize the event logging.
1785 ioc
->eventTypes
= 0; /* None */
1786 ioc
->eventContext
= 0;
1787 ioc
->eventLogSize
= 0;
1795 ioc
->cached_fw
= NULL
;
1797 /* Initilize SCSI Config Data structure
1799 memset(&ioc
->spi_data
, 0, sizeof(SpiCfgData
));
1801 /* Initialize the fc rport list head.
1803 INIT_LIST_HEAD(&ioc
->fc_rports
);
1805 /* Find lookup slot. */
1806 INIT_LIST_HEAD(&ioc
->list
);
1809 /* Initialize workqueue */
1810 INIT_DELAYED_WORK(&ioc
->fault_reset_work
, mpt_fault_reset_work
);
1812 snprintf(ioc
->reset_work_q_name
, MPT_KOBJ_NAME_LEN
,
1813 "mpt_poll_%d", ioc
->id
);
1815 create_singlethread_workqueue(ioc
->reset_work_q_name
);
1816 if (!ioc
->reset_work_q
) {
1817 printk(MYIOC_s_ERR_FMT
"Insufficient memory to add adapter!\n",
1819 pci_release_selected_regions(pdev
, ioc
->bars
);
1824 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"facts @ %p, pfacts[0] @ %p\n",
1825 ioc
->name
, &ioc
->facts
, &ioc
->pfacts
[0]));
1827 pci_read_config_byte(pdev
, PCI_CLASS_REVISION
, &revision
);
1828 mpt_get_product_name(pdev
->vendor
, pdev
->device
, revision
, ioc
->prod_name
);
1830 switch (pdev
->device
)
1832 case MPI_MANUFACTPAGE_DEVICEID_FC939X
:
1833 case MPI_MANUFACTPAGE_DEVICEID_FC949X
:
1834 ioc
->errata_flag_1064
= 1;
1835 case MPI_MANUFACTPAGE_DEVICEID_FC909
:
1836 case MPI_MANUFACTPAGE_DEVICEID_FC929
:
1837 case MPI_MANUFACTPAGE_DEVICEID_FC919
:
1838 case MPI_MANUFACTPAGE_DEVICEID_FC949E
:
1842 case MPI_MANUFACTPAGE_DEVICEID_FC929X
:
1843 if (revision
< XL_929
) {
1844 /* 929X Chip Fix. Set Split transactions level
1845 * for PCIX. Set MOST bits to zero.
1847 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1849 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1851 /* 929XL Chip Fix. Set MMRBC to 0x08.
1853 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1855 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1860 case MPI_MANUFACTPAGE_DEVICEID_FC919X
:
1861 /* 919X Chip Fix. Set Split transactions level
1862 * for PCIX. Set MOST bits to zero.
1864 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1866 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1870 case MPI_MANUFACTPAGE_DEVID_53C1030
:
1871 /* 1030 Chip Fix. Disable Split transactions
1872 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1874 if (revision
< C0_1030
) {
1875 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1877 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1880 case MPI_MANUFACTPAGE_DEVID_1030_53C1035
:
1881 ioc
->bus_type
= SPI
;
1884 case MPI_MANUFACTPAGE_DEVID_SAS1064
:
1885 case MPI_MANUFACTPAGE_DEVID_SAS1068
:
1886 ioc
->errata_flag_1064
= 1;
1887 ioc
->bus_type
= SAS
;
1890 case MPI_MANUFACTPAGE_DEVID_SAS1064E
:
1891 case MPI_MANUFACTPAGE_DEVID_SAS1068E
:
1892 case MPI_MANUFACTPAGE_DEVID_SAS1078
:
1893 ioc
->bus_type
= SAS
;
1898 switch (ioc
->bus_type
) {
1901 ioc
->msi_enable
= mpt_msi_enable_sas
;
1905 ioc
->msi_enable
= mpt_msi_enable_spi
;
1909 ioc
->msi_enable
= mpt_msi_enable_fc
;
1913 ioc
->msi_enable
= 0;
1916 if (ioc
->errata_flag_1064
)
1917 pci_disable_io_access(pdev
);
1919 spin_lock_init(&ioc
->FreeQlock
);
1922 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
1924 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1926 /* Set IOC ptr in the pcidev's driver data. */
1927 pci_set_drvdata(ioc
->pcidev
, ioc
);
1929 /* Set lookup ptr. */
1930 list_add_tail(&ioc
->list
, &ioc_list
);
1932 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1934 mpt_detect_bound_ports(ioc
, pdev
);
1936 INIT_LIST_HEAD(&ioc
->fw_event_list
);
1937 spin_lock_init(&ioc
->fw_event_lock
);
1938 snprintf(ioc
->fw_event_q_name
, MPT_KOBJ_NAME_LEN
, "mpt/%d", ioc
->id
);
1939 ioc
->fw_event_q
= create_singlethread_workqueue(ioc
->fw_event_q_name
);
1941 if ((r
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_BRINGUP
,
1943 printk(MYIOC_s_ERR_FMT
"didn't initialize properly! (%d)\n",
1946 list_del(&ioc
->list
);
1948 ioc
->alt_ioc
->alt_ioc
= NULL
;
1949 iounmap(ioc
->memmap
);
1951 pci_release_selected_regions(pdev
, ioc
->bars
);
1953 destroy_workqueue(ioc
->reset_work_q
);
1954 ioc
->reset_work_q
= NULL
;
1957 pci_set_drvdata(pdev
, NULL
);
1961 /* call per device driver probe entry point */
1962 for(cb_idx
= 0; cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
; cb_idx
++) {
1963 if(MptDeviceDriverHandlers
[cb_idx
] &&
1964 MptDeviceDriverHandlers
[cb_idx
]->probe
) {
1965 MptDeviceDriverHandlers
[cb_idx
]->probe(pdev
,id
);
1969 #ifdef CONFIG_PROC_FS
1971 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1973 dent
= proc_mkdir(ioc
->name
, mpt_proc_root_dir
);
1975 ent
= create_proc_entry("info", S_IFREG
|S_IRUGO
, dent
);
1977 ent
->read_proc
= procmpt_iocinfo_read
;
1980 ent
= create_proc_entry("summary", S_IFREG
|S_IRUGO
, dent
);
1982 ent
->read_proc
= procmpt_summary_read
;
1989 queue_delayed_work(ioc
->reset_work_q
, &ioc
->fault_reset_work
,
1990 msecs_to_jiffies(MPT_POLLING_INTERVAL
));
1995 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1997 * mpt_detach - Remove a PCI intelligent MPT adapter.
1998 * @pdev: Pointer to pci_dev structure
2002 mpt_detach(struct pci_dev
*pdev
)
2004 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
2007 unsigned long flags
;
2008 struct workqueue_struct
*wq
;
2011 * Stop polling ioc for fault condition
2013 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
2014 wq
= ioc
->reset_work_q
;
2015 ioc
->reset_work_q
= NULL
;
2016 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
2017 cancel_delayed_work(&ioc
->fault_reset_work
);
2018 destroy_workqueue(wq
);
2020 spin_lock_irqsave(&ioc
->fw_event_lock
, flags
);
2021 wq
= ioc
->fw_event_q
;
2022 ioc
->fw_event_q
= NULL
;
2023 spin_unlock_irqrestore(&ioc
->fw_event_lock
, flags
);
2024 destroy_workqueue(wq
);
2026 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s/summary", ioc
->name
);
2027 remove_proc_entry(pname
, NULL
);
2028 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s/info", ioc
->name
);
2029 remove_proc_entry(pname
, NULL
);
2030 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s", ioc
->name
);
2031 remove_proc_entry(pname
, NULL
);
2033 /* call per device driver remove entry point */
2034 for(cb_idx
= 0; cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
; cb_idx
++) {
2035 if(MptDeviceDriverHandlers
[cb_idx
] &&
2036 MptDeviceDriverHandlers
[cb_idx
]->remove
) {
2037 MptDeviceDriverHandlers
[cb_idx
]->remove(pdev
);
2041 /* Disable interrupts! */
2042 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2045 synchronize_irq(pdev
->irq
);
2047 /* Clear any lingering interrupt */
2048 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
2050 CHIPREG_READ32(&ioc
->chip
->IntStatus
);
2052 mpt_adapter_dispose(ioc
);
2054 pci_set_drvdata(pdev
, NULL
);
2057 /**************************************************************************
2061 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2063 * mpt_suspend - Fusion MPT base driver suspend routine.
2064 * @pdev: Pointer to pci_dev structure
2065 * @state: new state to enter
2068 mpt_suspend(struct pci_dev
*pdev
, pm_message_t state
)
2071 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
2073 device_state
= pci_choose_state(pdev
, state
);
2074 printk(MYIOC_s_INFO_FMT
"pci-suspend: pdev=0x%p, slot=%s, Entering "
2075 "operating state [D%d]\n", ioc
->name
, pdev
, pci_name(pdev
),
2078 /* put ioc into READY_STATE */
2079 if(SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, CAN_SLEEP
)) {
2080 printk(MYIOC_s_ERR_FMT
2081 "pci-suspend: IOC msg unit reset failed!\n", ioc
->name
);
2084 /* disable interrupts */
2085 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2088 /* Clear any lingering interrupt */
2089 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
2091 free_irq(ioc
->pci_irq
, ioc
);
2092 if (ioc
->msi_enable
)
2093 pci_disable_msi(ioc
->pcidev
);
2095 pci_save_state(pdev
);
2096 pci_disable_device(pdev
);
2097 pci_release_selected_regions(pdev
, ioc
->bars
);
2098 pci_set_power_state(pdev
, device_state
);
2102 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2104 * mpt_resume - Fusion MPT base driver resume routine.
2105 * @pdev: Pointer to pci_dev structure
2108 mpt_resume(struct pci_dev
*pdev
)
2110 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
2111 u32 device_state
= pdev
->current_state
;
2115 printk(MYIOC_s_INFO_FMT
"pci-resume: pdev=0x%p, slot=%s, Previous "
2116 "operating state [D%d]\n", ioc
->name
, pdev
, pci_name(pdev
),
2119 pci_set_power_state(pdev
, PCI_D0
);
2120 pci_enable_wake(pdev
, PCI_D0
, 0);
2121 pci_restore_state(pdev
);
2123 err
= mpt_mapresources(ioc
);
2127 if (ioc
->dma_mask
== DMA_BIT_MASK(64)) {
2128 if (pdev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1078
)
2129 ioc
->add_sge
= &mpt_add_sge_64bit_1078
;
2131 ioc
->add_sge
= &mpt_add_sge_64bit
;
2132 ioc
->add_chain
= &mpt_add_chain_64bit
;
2133 ioc
->sg_addr_size
= 8;
2136 ioc
->add_sge
= &mpt_add_sge
;
2137 ioc
->add_chain
= &mpt_add_chain
;
2138 ioc
->sg_addr_size
= 4;
2140 ioc
->SGE_size
= sizeof(u32
) + ioc
->sg_addr_size
;
2142 printk(MYIOC_s_INFO_FMT
"pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
2143 ioc
->name
, (mpt_GetIocState(ioc
, 1) >> MPI_IOC_STATE_SHIFT
),
2144 CHIPREG_READ32(&ioc
->chip
->Doorbell
));
2147 * Errata workaround for SAS pci express:
2148 * Upon returning to the D0 state, the contents of the doorbell will be
2149 * stale data, and this will incorrectly signal to the host driver that
2150 * the firmware is ready to process mpt commands. The workaround is
2151 * to issue a diagnostic reset.
2153 if (ioc
->bus_type
== SAS
&& (pdev
->device
==
2154 MPI_MANUFACTPAGE_DEVID_SAS1068E
|| pdev
->device
==
2155 MPI_MANUFACTPAGE_DEVID_SAS1064E
)) {
2156 if (KickStart(ioc
, 1, CAN_SLEEP
) < 0) {
2157 printk(MYIOC_s_WARN_FMT
"pci-resume: Cannot recover\n",
2163 /* bring ioc to operational state */
2164 printk(MYIOC_s_INFO_FMT
"Sending mpt_do_ioc_recovery\n", ioc
->name
);
2165 recovery_state
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_BRINGUP
,
2167 if (recovery_state
!= 0)
2168 printk(MYIOC_s_WARN_FMT
"pci-resume: Cannot recover, "
2169 "error:[%x]\n", ioc
->name
, recovery_state
);
2171 printk(MYIOC_s_INFO_FMT
2172 "pci-resume: success\n", ioc
->name
);
2180 mpt_signal_reset(u8 index
, MPT_ADAPTER
*ioc
, int reset_phase
)
2182 if ((MptDriverClass
[index
] == MPTSPI_DRIVER
&&
2183 ioc
->bus_type
!= SPI
) ||
2184 (MptDriverClass
[index
] == MPTFC_DRIVER
&&
2185 ioc
->bus_type
!= FC
) ||
2186 (MptDriverClass
[index
] == MPTSAS_DRIVER
&&
2187 ioc
->bus_type
!= SAS
))
2188 /* make sure we only call the relevant reset handler
2191 return (MptResetHandlers
[index
])(ioc
, reset_phase
);
2194 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2196 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
2197 * @ioc: Pointer to MPT adapter structure
2198 * @reason: Event word / reason
2199 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
2201 * This routine performs all the steps necessary to bring the IOC
2202 * to a OPERATIONAL state.
2204 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
2209 * -1 if failed to get board READY
2210 * -2 if READY but IOCFacts Failed
2211 * -3 if READY but PrimeIOCFifos Failed
2212 * -4 if READY but IOCInit Failed
2213 * -5 if failed to enable_device and/or request_selected_regions
2214 * -6 if failed to upload firmware
2217 mpt_do_ioc_recovery(MPT_ADAPTER
*ioc
, u32 reason
, int sleepFlag
)
2219 int hard_reset_done
= 0;
2220 int alt_ioc_ready
= 0;
2225 int reset_alt_ioc_active
= 0;
2226 int irq_allocated
= 0;
2229 printk(MYIOC_s_INFO_FMT
"Initiating %s\n", ioc
->name
,
2230 reason
== MPT_HOSTEVENT_IOC_BRINGUP
? "bringup" : "recovery");
2232 /* Disable reply interrupts (also blocks FreeQ) */
2233 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2237 if (ioc
->alt_ioc
->active
||
2238 reason
== MPT_HOSTEVENT_IOC_RECOVER
) {
2239 reset_alt_ioc_active
= 1;
2240 /* Disable alt-IOC's reply interrupts
2241 * (and FreeQ) for a bit
2243 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
,
2245 ioc
->alt_ioc
->active
= 0;
2250 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)
2253 if ((hard_reset_done
= MakeIocReady(ioc
, hard
, sleepFlag
)) < 0) {
2254 if (hard_reset_done
== -4) {
2255 printk(MYIOC_s_WARN_FMT
"Owned by PEER..skipping!\n",
2258 if (reset_alt_ioc_active
&& ioc
->alt_ioc
) {
2259 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
2260 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
2261 "alt_ioc reply irq re-enabled\n", ioc
->alt_ioc
->name
));
2262 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
, MPI_HIM_DIM
);
2263 ioc
->alt_ioc
->active
= 1;
2267 printk(MYIOC_s_WARN_FMT
2268 "NOT READY WARNING!\n", ioc
->name
);
2274 /* hard_reset_done = 0 if a soft reset was performed
2275 * and 1 if a hard reset was performed.
2277 if (hard_reset_done
&& reset_alt_ioc_active
&& ioc
->alt_ioc
) {
2278 if ((rc
= MakeIocReady(ioc
->alt_ioc
, 0, sleepFlag
)) == 0)
2281 printk(MYIOC_s_WARN_FMT
2282 ": alt-ioc Not ready WARNING!\n",
2283 ioc
->alt_ioc
->name
);
2286 for (ii
=0; ii
<5; ii
++) {
2287 /* Get IOC facts! Allow 5 retries */
2288 if ((rc
= GetIocFacts(ioc
, sleepFlag
, reason
)) == 0)
2294 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2295 "Retry IocFacts failed rc=%x\n", ioc
->name
, rc
));
2297 } else if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
2298 MptDisplayIocCapabilities(ioc
);
2301 if (alt_ioc_ready
) {
2302 if ((rc
= GetIocFacts(ioc
->alt_ioc
, sleepFlag
, reason
)) != 0) {
2303 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2304 "Initial Alt IocFacts failed rc=%x\n",
2306 /* Retry - alt IOC was initialized once
2308 rc
= GetIocFacts(ioc
->alt_ioc
, sleepFlag
, reason
);
2311 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2312 "Retry Alt IocFacts failed rc=%x\n", ioc
->name
, rc
));
2314 reset_alt_ioc_active
= 0;
2315 } else if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
2316 MptDisplayIocCapabilities(ioc
->alt_ioc
);
2320 if ((ret
== 0) && (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) &&
2321 (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)) {
2322 pci_release_selected_regions(ioc
->pcidev
, ioc
->bars
);
2323 ioc
->bars
= pci_select_bars(ioc
->pcidev
, IORESOURCE_MEM
|
2325 if (pci_enable_device(ioc
->pcidev
))
2327 if (pci_request_selected_regions(ioc
->pcidev
, ioc
->bars
,
2333 * Device is reset now. It must have de-asserted the interrupt line
2334 * (if it was asserted) and it should be safe to register for the
2337 if ((ret
== 0) && (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)) {
2339 if (ioc
->pcidev
->irq
) {
2340 if (ioc
->msi_enable
&& !pci_enable_msi(ioc
->pcidev
))
2341 printk(MYIOC_s_INFO_FMT
"PCI-MSI enabled\n",
2344 ioc
->msi_enable
= 0;
2345 rc
= request_irq(ioc
->pcidev
->irq
, mpt_interrupt
,
2346 IRQF_SHARED
, ioc
->name
, ioc
);
2348 printk(MYIOC_s_ERR_FMT
"Unable to allocate "
2350 ioc
->name
, ioc
->pcidev
->irq
);
2351 if (ioc
->msi_enable
)
2352 pci_disable_msi(ioc
->pcidev
);
2357 ioc
->pci_irq
= ioc
->pcidev
->irq
;
2358 pci_set_master(ioc
->pcidev
); /* ?? */
2359 pci_set_drvdata(ioc
->pcidev
, ioc
);
2360 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
2361 "installed at interrupt %d\n", ioc
->name
,
2366 /* Prime reply & request queues!
2367 * (mucho alloc's) Must be done prior to
2368 * init as upper addresses are needed for init.
2369 * If fails, continue with alt-ioc processing
2371 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"PrimeIocFifos\n",
2373 if ((ret
== 0) && ((rc
= PrimeIocFifos(ioc
)) != 0))
2376 /* May need to check/upload firmware & data here!
2377 * If fails, continue with alt-ioc processing
2379 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"SendIocInit\n",
2381 if ((ret
== 0) && ((rc
= SendIocInit(ioc
, sleepFlag
)) != 0))
2384 if (alt_ioc_ready
&& ((rc
= PrimeIocFifos(ioc
->alt_ioc
)) != 0)) {
2385 printk(MYIOC_s_WARN_FMT
2386 ": alt-ioc (%d) FIFO mgmt alloc WARNING!\n",
2387 ioc
->alt_ioc
->name
, rc
);
2389 reset_alt_ioc_active
= 0;
2392 if (alt_ioc_ready
) {
2393 if ((rc
= SendIocInit(ioc
->alt_ioc
, sleepFlag
)) != 0) {
2395 reset_alt_ioc_active
= 0;
2396 printk(MYIOC_s_WARN_FMT
2397 ": alt-ioc: (%d) init failure WARNING!\n",
2398 ioc
->alt_ioc
->name
, rc
);
2402 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
){
2403 if (ioc
->upload_fw
) {
2404 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2405 "firmware upload required!\n", ioc
->name
));
2407 /* Controller is not operational, cannot do upload
2410 rc
= mpt_do_upload(ioc
, sleepFlag
);
2412 if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
) {
2414 * Maintain only one pointer to FW memory
2415 * so there will not be two attempt to
2416 * downloadboot onboard dual function
2417 * chips (mpt_adapter_disable,
2420 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2421 "mpt_upload: alt_%s has cached_fw=%p \n",
2422 ioc
->name
, ioc
->alt_ioc
->name
, ioc
->alt_ioc
->cached_fw
));
2423 ioc
->cached_fw
= NULL
;
2426 printk(MYIOC_s_WARN_FMT
2427 "firmware upload failure!\n", ioc
->name
);
2434 /* Enable MPT base driver management of EventNotification
2435 * and EventAck handling.
2437 if ((ret
== 0) && (!ioc
->facts
.EventState
)) {
2438 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
2439 "SendEventNotification\n",
2441 ret
= SendEventNotification(ioc
, 1, sleepFlag
); /* 1=Enable */
2444 if (ioc
->alt_ioc
&& alt_ioc_ready
&& !ioc
->alt_ioc
->facts
.EventState
)
2445 rc
= SendEventNotification(ioc
->alt_ioc
, 1, sleepFlag
);
2448 /* Enable! (reply interrupt) */
2449 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, MPI_HIM_DIM
);
2452 if (rc
== 0) { /* alt ioc */
2453 if (reset_alt_ioc_active
&& ioc
->alt_ioc
) {
2454 /* (re)Enable alt-IOC! (reply interrupt) */
2455 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"alt-ioc"
2456 "reply irq re-enabled\n",
2457 ioc
->alt_ioc
->name
));
2458 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
,
2460 ioc
->alt_ioc
->active
= 1;
2465 /* Add additional "reason" check before call to GetLanConfigPages
2466 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2467 * recursive scenario; GetLanConfigPages times out, timer expired
2468 * routine calls HardResetHandler, which calls into here again,
2469 * and we try GetLanConfigPages again...
2471 if ((ret
== 0) && (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)) {
2474 * Initalize link list for inactive raid volumes.
2476 mutex_init(&ioc
->raid_data
.inactive_list_mutex
);
2477 INIT_LIST_HEAD(&ioc
->raid_data
.inactive_list
);
2479 switch (ioc
->bus_type
) {
2482 /* clear persistency table */
2483 if(ioc
->facts
.IOCExceptions
&
2484 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL
) {
2485 ret
= mptbase_sas_persist_operation(ioc
,
2486 MPI_SAS_OP_CLEAR_NOT_PRESENT
);
2493 mpt_findImVolumes(ioc
);
2495 /* Check, and possibly reset, the coalescing value
2497 mpt_read_ioc_pg_1(ioc
);
2502 if ((ioc
->pfacts
[0].ProtocolFlags
&
2503 MPI_PORTFACTS_PROTOCOL_LAN
) &&
2504 (ioc
->lan_cnfg_page0
.Header
.PageLength
== 0)) {
2506 * Pre-fetch the ports LAN MAC address!
2507 * (LANPage1_t stuff)
2509 (void) GetLanConfigPages(ioc
);
2510 a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
2511 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2512 "LanAddr = %02X:%02X:%02X"
2513 ":%02X:%02X:%02X\n",
2514 ioc
->name
, a
[5], a
[4],
2515 a
[3], a
[2], a
[1], a
[0]));
2520 /* Get NVRAM and adapter maximums from SPP 0 and 2
2522 mpt_GetScsiPortSettings(ioc
, 0);
2524 /* Get version and length of SDP 1
2526 mpt_readScsiDevicePageHeaders(ioc
, 0);
2530 if (ioc
->facts
.MsgVersion
>= MPI_VERSION_01_02
)
2531 mpt_findImVolumes(ioc
);
2533 /* Check, and possibly reset, the coalescing value
2535 mpt_read_ioc_pg_1(ioc
);
2537 mpt_read_ioc_pg_4(ioc
);
2542 GetIoUnitPage2(ioc
);
2543 mpt_get_manufacturing_pg_0(ioc
);
2547 if ((ret
!= 0) && irq_allocated
) {
2548 free_irq(ioc
->pci_irq
, ioc
);
2549 if (ioc
->msi_enable
)
2550 pci_disable_msi(ioc
->pcidev
);
2555 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2557 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2558 * @ioc: Pointer to MPT adapter structure
2559 * @pdev: Pointer to (struct pci_dev) structure
2561 * Search for PCI bus/dev_function which matches
2562 * PCI bus/dev_function (+/-1) for newly discovered 929,
2563 * 929X, 1030 or 1035.
2565 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2566 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2569 mpt_detect_bound_ports(MPT_ADAPTER
*ioc
, struct pci_dev
*pdev
)
2571 struct pci_dev
*peer
=NULL
;
2572 unsigned int slot
= PCI_SLOT(pdev
->devfn
);
2573 unsigned int func
= PCI_FUNC(pdev
->devfn
);
2574 MPT_ADAPTER
*ioc_srch
;
2576 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"PCI device %s devfn=%x/%x,"
2577 " searching for devfn match on %x or %x\n",
2578 ioc
->name
, pci_name(pdev
), pdev
->bus
->number
,
2579 pdev
->devfn
, func
-1, func
+1));
2581 peer
= pci_get_slot(pdev
->bus
, PCI_DEVFN(slot
,func
-1));
2583 peer
= pci_get_slot(pdev
->bus
, PCI_DEVFN(slot
,func
+1));
2588 list_for_each_entry(ioc_srch
, &ioc_list
, list
) {
2589 struct pci_dev
*_pcidev
= ioc_srch
->pcidev
;
2590 if (_pcidev
== peer
) {
2591 /* Paranoia checks */
2592 if (ioc
->alt_ioc
!= NULL
) {
2593 printk(MYIOC_s_WARN_FMT
2594 "Oops, already bound (%s <==> %s)!\n",
2595 ioc
->name
, ioc
->name
, ioc
->alt_ioc
->name
);
2597 } else if (ioc_srch
->alt_ioc
!= NULL
) {
2598 printk(MYIOC_s_WARN_FMT
2599 "Oops, already bound (%s <==> %s)!\n",
2600 ioc_srch
->name
, ioc_srch
->name
,
2601 ioc_srch
->alt_ioc
->name
);
2604 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2605 "FOUND! binding %s <==> %s\n",
2606 ioc
->name
, ioc
->name
, ioc_srch
->name
));
2607 ioc_srch
->alt_ioc
= ioc
;
2608 ioc
->alt_ioc
= ioc_srch
;
2614 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2616 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2617 * @ioc: Pointer to MPT adapter structure
2620 mpt_adapter_disable(MPT_ADAPTER
*ioc
)
2625 if (ioc
->cached_fw
!= NULL
) {
2626 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2627 "%s: Pushing FW onto adapter\n", __func__
, ioc
->name
));
2628 if ((ret
= mpt_downloadboot(ioc
, (MpiFwHeader_t
*)
2629 ioc
->cached_fw
, CAN_SLEEP
)) < 0) {
2630 printk(MYIOC_s_WARN_FMT
2631 ": firmware downloadboot failure (%d)!\n",
2637 * Put the controller into ready state (if its not already)
2639 if (mpt_GetIocState(ioc
, 1) != MPI_IOC_STATE_READY
) {
2640 if (!SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
,
2642 if (mpt_GetIocState(ioc
, 1) != MPI_IOC_STATE_READY
)
2643 printk(MYIOC_s_ERR_FMT
"%s: IOC msg unit "
2644 "reset failed to put ioc in ready state!\n",
2645 ioc
->name
, __func__
);
2647 printk(MYIOC_s_ERR_FMT
"%s: IOC msg unit reset "
2648 "failed!\n", ioc
->name
, __func__
);
2652 /* Disable adapter interrupts! */
2653 synchronize_irq(ioc
->pcidev
->irq
);
2654 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2657 /* Clear any lingering interrupt */
2658 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
2659 CHIPREG_READ32(&ioc
->chip
->IntStatus
);
2661 if (ioc
->alloc
!= NULL
) {
2663 dexitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"free @ %p, sz=%d bytes\n",
2664 ioc
->name
, ioc
->alloc
, ioc
->alloc_sz
));
2665 pci_free_consistent(ioc
->pcidev
, sz
,
2666 ioc
->alloc
, ioc
->alloc_dma
);
2667 ioc
->reply_frames
= NULL
;
2668 ioc
->req_frames
= NULL
;
2670 ioc
->alloc_total
-= sz
;
2673 if (ioc
->sense_buf_pool
!= NULL
) {
2674 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
2675 pci_free_consistent(ioc
->pcidev
, sz
,
2676 ioc
->sense_buf_pool
, ioc
->sense_buf_pool_dma
);
2677 ioc
->sense_buf_pool
= NULL
;
2678 ioc
->alloc_total
-= sz
;
2681 if (ioc
->events
!= NULL
){
2682 sz
= MPTCTL_EVENT_LOG_SIZE
* sizeof(MPT_IOCTL_EVENTS
);
2685 ioc
->alloc_total
-= sz
;
2688 mpt_free_fw_memory(ioc
);
2690 kfree(ioc
->spi_data
.nvram
);
2691 mpt_inactive_raid_list_free(ioc
);
2692 kfree(ioc
->raid_data
.pIocPg2
);
2693 kfree(ioc
->raid_data
.pIocPg3
);
2694 ioc
->spi_data
.nvram
= NULL
;
2695 ioc
->raid_data
.pIocPg3
= NULL
;
2697 if (ioc
->spi_data
.pIocPg4
!= NULL
) {
2698 sz
= ioc
->spi_data
.IocPg4Sz
;
2699 pci_free_consistent(ioc
->pcidev
, sz
,
2700 ioc
->spi_data
.pIocPg4
,
2701 ioc
->spi_data
.IocPg4_dma
);
2702 ioc
->spi_data
.pIocPg4
= NULL
;
2703 ioc
->alloc_total
-= sz
;
2706 if (ioc
->ReqToChain
!= NULL
) {
2707 kfree(ioc
->ReqToChain
);
2708 kfree(ioc
->RequestNB
);
2709 ioc
->ReqToChain
= NULL
;
2712 kfree(ioc
->ChainToChain
);
2713 ioc
->ChainToChain
= NULL
;
2715 if (ioc
->HostPageBuffer
!= NULL
) {
2716 if((ret
= mpt_host_page_access_control(ioc
,
2717 MPI_DB_HPBAC_FREE_BUFFER
, NO_SLEEP
)) != 0) {
2718 printk(MYIOC_s_ERR_FMT
2719 ": %s: host page buffers free failed (%d)!\n",
2720 ioc
->name
, __func__
, ret
);
2722 dexitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2723 "HostPageBuffer free @ %p, sz=%d bytes\n",
2724 ioc
->name
, ioc
->HostPageBuffer
,
2725 ioc
->HostPageBuffer_sz
));
2726 pci_free_consistent(ioc
->pcidev
, ioc
->HostPageBuffer_sz
,
2727 ioc
->HostPageBuffer
, ioc
->HostPageBuffer_dma
);
2728 ioc
->HostPageBuffer
= NULL
;
2729 ioc
->HostPageBuffer_sz
= 0;
2730 ioc
->alloc_total
-= ioc
->HostPageBuffer_sz
;
2733 pci_set_drvdata(ioc
->pcidev
, NULL
);
2735 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2737 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2738 * @ioc: Pointer to MPT adapter structure
2740 * This routine unregisters h/w resources and frees all alloc'd memory
2741 * associated with a MPT adapter structure.
2744 mpt_adapter_dispose(MPT_ADAPTER
*ioc
)
2746 int sz_first
, sz_last
;
2751 sz_first
= ioc
->alloc_total
;
2753 mpt_adapter_disable(ioc
);
2755 if (ioc
->pci_irq
!= -1) {
2756 free_irq(ioc
->pci_irq
, ioc
);
2757 if (ioc
->msi_enable
)
2758 pci_disable_msi(ioc
->pcidev
);
2762 if (ioc
->memmap
!= NULL
) {
2763 iounmap(ioc
->memmap
);
2767 pci_disable_device(ioc
->pcidev
);
2768 pci_release_selected_regions(ioc
->pcidev
, ioc
->bars
);
2770 #if defined(CONFIG_MTRR) && 0
2771 if (ioc
->mtrr_reg
> 0) {
2772 mtrr_del(ioc
->mtrr_reg
, 0, 0);
2773 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
"MTRR region de-registered\n", ioc
->name
));
2777 /* Zap the adapter lookup ptr! */
2778 list_del(&ioc
->list
);
2780 sz_last
= ioc
->alloc_total
;
2781 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
"free'd %d of %d bytes\n",
2782 ioc
->name
, sz_first
-sz_last
+(int)sizeof(*ioc
), sz_first
));
2785 ioc
->alt_ioc
->alt_ioc
= NULL
;
2790 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2792 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2793 * @ioc: Pointer to MPT adapter structure
2796 MptDisplayIocCapabilities(MPT_ADAPTER
*ioc
)
2800 printk(KERN_INFO
"%s: ", ioc
->name
);
2802 printk("%s: ", ioc
->prod_name
);
2803 printk("Capabilities={");
2805 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_INITIATOR
) {
2806 printk("Initiator");
2810 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_TARGET
) {
2811 printk("%sTarget", i
? "," : "");
2815 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
) {
2816 printk("%sLAN", i
? "," : "");
2822 * This would probably evoke more questions than it's worth
2824 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_TARGET
) {
2825 printk("%sLogBusAddr", i
? "," : "");
2833 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2835 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2836 * @ioc: Pointer to MPT_ADAPTER structure
2837 * @force: Force hard KickStart of IOC
2838 * @sleepFlag: Specifies whether the process can sleep
2841 * 1 - DIAG reset and READY
2842 * 0 - READY initially OR soft reset and READY
2843 * -1 - Any failure on KickStart
2844 * -2 - Msg Unit Reset Failed
2845 * -3 - IO Unit Reset Failed
2846 * -4 - IOC owned by a PEER
2849 MakeIocReady(MPT_ADAPTER
*ioc
, int force
, int sleepFlag
)
2854 int hard_reset_done
= 0;
2859 /* Get current [raw] IOC state */
2860 ioc_state
= mpt_GetIocState(ioc
, 0);
2861 dhsprintk(ioc
, printk(MYIOC_s_INFO_FMT
"MakeIocReady [raw] state=%08x\n", ioc
->name
, ioc_state
));
2864 * Check to see if IOC got left/stuck in doorbell handshake
2865 * grip of death. If so, hard reset the IOC.
2867 if (ioc_state
& MPI_DOORBELL_ACTIVE
) {
2869 printk(MYIOC_s_WARN_FMT
"Unexpected doorbell active!\n",
2873 /* Is it already READY? */
2875 ((ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_READY
)) {
2876 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
2877 "IOC is in READY state\n", ioc
->name
));
2882 * Check to see if IOC is in FAULT state.
2884 if ((ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_FAULT
) {
2886 printk(MYIOC_s_WARN_FMT
"IOC is in FAULT state!!!\n",
2888 printk(MYIOC_s_WARN_FMT
" FAULT code = %04xh\n",
2889 ioc
->name
, ioc_state
& MPI_DOORBELL_DATA_MASK
);
2893 * Hmmm... Did it get left operational?
2895 if ((ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_OPERATIONAL
) {
2896 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"IOC operational unexpected\n",
2900 * If PCI Peer, exit.
2901 * Else, if no fault conditions are present, issue a MessageUnitReset
2902 * Else, fall through to KickStart case
2904 whoinit
= (ioc_state
& MPI_DOORBELL_WHO_INIT_MASK
) >> MPI_DOORBELL_WHO_INIT_SHIFT
;
2905 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
2906 "whoinit 0x%x statefault %d force %d\n",
2907 ioc
->name
, whoinit
, statefault
, force
));
2908 if (whoinit
== MPI_WHOINIT_PCI_PEER
)
2911 if ((statefault
== 0 ) && (force
== 0)) {
2912 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
)) == 0)
2919 hard_reset_done
= KickStart(ioc
, statefault
||force
, sleepFlag
);
2920 if (hard_reset_done
< 0)
2924 * Loop here waiting for IOC to come READY.
2927 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 5; /* 5 seconds */
2929 while ((ioc_state
= mpt_GetIocState(ioc
, 1)) != MPI_IOC_STATE_READY
) {
2930 if (ioc_state
== MPI_IOC_STATE_OPERATIONAL
) {
2932 * BIOS or previous driver load left IOC in OP state.
2933 * Reset messaging FIFOs.
2935 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
)) != 0) {
2936 printk(MYIOC_s_ERR_FMT
"IOC msg unit reset failed!\n", ioc
->name
);
2939 } else if (ioc_state
== MPI_IOC_STATE_RESET
) {
2941 * Something is wrong. Try to get IOC back
2944 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IO_UNIT_RESET
, sleepFlag
)) != 0) {
2945 printk(MYIOC_s_ERR_FMT
"IO unit reset failed!\n", ioc
->name
);
2952 printk(MYIOC_s_ERR_FMT
2953 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
2954 ioc
->name
, ioc_state
, (int)((ii
+5)/HZ
));
2958 if (sleepFlag
== CAN_SLEEP
) {
2961 mdelay (1); /* 1 msec delay */
2966 if (statefault
< 3) {
2967 printk(MYIOC_s_INFO_FMT
"Recovered from %s\n", ioc
->name
,
2968 statefault
== 1 ? "stuck handshake" : "IOC FAULT");
2971 return hard_reset_done
;
2974 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2976 * mpt_GetIocState - Get the current state of a MPT adapter.
2977 * @ioc: Pointer to MPT_ADAPTER structure
2978 * @cooked: Request raw or cooked IOC state
2980 * Returns all IOC Doorbell register bits if cooked==0, else just the
2981 * Doorbell bits in MPI_IOC_STATE_MASK.
2984 mpt_GetIocState(MPT_ADAPTER
*ioc
, int cooked
)
2989 s
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
2990 sc
= s
& MPI_IOC_STATE_MASK
;
2993 ioc
->last_state
= sc
;
2995 return cooked
? sc
: s
;
2998 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3000 * GetIocFacts - Send IOCFacts request to MPT adapter.
3001 * @ioc: Pointer to MPT_ADAPTER structure
3002 * @sleepFlag: Specifies whether the process can sleep
3003 * @reason: If recovery, only update facts.
3005 * Returns 0 for success, non-zero for failure.
3008 GetIocFacts(MPT_ADAPTER
*ioc
, int sleepFlag
, int reason
)
3010 IOCFacts_t get_facts
;
3011 IOCFactsReply_t
*facts
;
3019 /* IOC *must* NOT be in RESET state! */
3020 if (ioc
->last_state
== MPI_IOC_STATE_RESET
) {
3021 printk(KERN_ERR MYNAM
3022 ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
3023 ioc
->name
, ioc
->last_state
);
3027 facts
= &ioc
->facts
;
3029 /* Destination (reply area)... */
3030 reply_sz
= sizeof(*facts
);
3031 memset(facts
, 0, reply_sz
);
3033 /* Request area (get_facts on the stack right now!) */
3034 req_sz
= sizeof(get_facts
);
3035 memset(&get_facts
, 0, req_sz
);
3037 get_facts
.Function
= MPI_FUNCTION_IOC_FACTS
;
3038 /* Assert: All other get_facts fields are zero! */
3040 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3041 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
3042 ioc
->name
, req_sz
, reply_sz
));
3044 /* No non-zero fields in the get_facts request are greater than
3045 * 1 byte in size, so we can just fire it off as is.
3047 r
= mpt_handshake_req_reply_wait(ioc
, req_sz
, (u32
*)&get_facts
,
3048 reply_sz
, (u16
*)facts
, 5 /*seconds*/, sleepFlag
);
3053 * Now byte swap (GRRR) the necessary fields before any further
3054 * inspection of reply contents.
3056 * But need to do some sanity checks on MsgLength (byte) field
3057 * to make sure we don't zero IOC's req_sz!
3059 /* Did we get a valid reply? */
3060 if (facts
->MsgLength
> offsetof(IOCFactsReply_t
, RequestFrameSize
)/sizeof(u32
)) {
3061 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
3063 * If not been here, done that, save off first WhoInit value
3065 if (ioc
->FirstWhoInit
== WHOINIT_UNKNOWN
)
3066 ioc
->FirstWhoInit
= facts
->WhoInit
;
3069 facts
->MsgVersion
= le16_to_cpu(facts
->MsgVersion
);
3070 facts
->MsgContext
= le32_to_cpu(facts
->MsgContext
);
3071 facts
->IOCExceptions
= le16_to_cpu(facts
->IOCExceptions
);
3072 facts
->IOCStatus
= le16_to_cpu(facts
->IOCStatus
);
3073 facts
->IOCLogInfo
= le32_to_cpu(facts
->IOCLogInfo
);
3074 status
= le16_to_cpu(facts
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
3075 /* CHECKME! IOCStatus, IOCLogInfo */
3077 facts
->ReplyQueueDepth
= le16_to_cpu(facts
->ReplyQueueDepth
);
3078 facts
->RequestFrameSize
= le16_to_cpu(facts
->RequestFrameSize
);
3081 * FC f/w version changed between 1.1 and 1.2
3082 * Old: u16{Major(4),Minor(4),SubMinor(8)}
3083 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
3085 if (facts
->MsgVersion
< MPI_VERSION_01_02
) {
3087 * Handle old FC f/w style, convert to new...
3089 u16 oldv
= le16_to_cpu(facts
->Reserved_0101_FWVersion
);
3090 facts
->FWVersion
.Word
=
3091 ((oldv
<<12) & 0xFF000000) |
3092 ((oldv
<<8) & 0x000FFF00);
3094 facts
->FWVersion
.Word
= le32_to_cpu(facts
->FWVersion
.Word
);
3096 facts
->ProductID
= le16_to_cpu(facts
->ProductID
);
3098 if ((ioc
->facts
.ProductID
& MPI_FW_HEADER_PID_PROD_MASK
)
3099 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI
)
3100 ioc
->ir_firmware
= 1;
3102 facts
->CurrentHostMfaHighAddr
=
3103 le32_to_cpu(facts
->CurrentHostMfaHighAddr
);
3104 facts
->GlobalCredits
= le16_to_cpu(facts
->GlobalCredits
);
3105 facts
->CurrentSenseBufferHighAddr
=
3106 le32_to_cpu(facts
->CurrentSenseBufferHighAddr
);
3107 facts
->CurReplyFrameSize
=
3108 le16_to_cpu(facts
->CurReplyFrameSize
);
3109 facts
->IOCCapabilities
= le32_to_cpu(facts
->IOCCapabilities
);
3112 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
3113 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
3114 * to 14 in MPI-1.01.0x.
3116 if (facts
->MsgLength
>= (offsetof(IOCFactsReply_t
,FWImageSize
) + 7)/4 &&
3117 facts
->MsgVersion
> MPI_VERSION_01_00
) {
3118 facts
->FWImageSize
= le32_to_cpu(facts
->FWImageSize
);
3121 sz
= facts
->FWImageSize
;
3126 facts
->FWImageSize
= sz
;
3128 if (!facts
->RequestFrameSize
) {
3129 /* Something is wrong! */
3130 printk(MYIOC_s_ERR_FMT
"IOC reported invalid 0 request size!\n",
3135 r
= sz
= facts
->BlockSize
;
3136 vv
= ((63 / (sz
* 4)) + 1) & 0x03;
3137 ioc
->NB_for_64_byte_frame
= vv
;
3143 ioc
->NBShiftFactor
= shiftFactor
;
3144 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3145 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
3146 ioc
->name
, vv
, shiftFactor
, r
));
3148 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
3150 * Set values for this IOC's request & reply frame sizes,
3151 * and request & reply queue depths...
3153 ioc
->req_sz
= min(MPT_DEFAULT_FRAME_SIZE
, facts
->RequestFrameSize
* 4);
3154 ioc
->req_depth
= min_t(int, MPT_MAX_REQ_DEPTH
, facts
->GlobalCredits
);
3155 ioc
->reply_sz
= MPT_REPLY_FRAME_SIZE
;
3156 ioc
->reply_depth
= min_t(int, MPT_DEFAULT_REPLY_DEPTH
, facts
->ReplyQueueDepth
);
3158 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"reply_sz=%3d, reply_depth=%4d\n",
3159 ioc
->name
, ioc
->reply_sz
, ioc
->reply_depth
));
3160 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"req_sz =%3d, req_depth =%4d\n",
3161 ioc
->name
, ioc
->req_sz
, ioc
->req_depth
));
3163 /* Get port facts! */
3164 if ( (r
= GetPortFacts(ioc
, 0, sleepFlag
)) != 0 )
3168 printk(MYIOC_s_ERR_FMT
3169 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
3170 ioc
->name
, facts
->MsgLength
, (offsetof(IOCFactsReply_t
,
3171 RequestFrameSize
)/sizeof(u32
)));
3178 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3180 * GetPortFacts - Send PortFacts request to MPT adapter.
3181 * @ioc: Pointer to MPT_ADAPTER structure
3182 * @portnum: Port number
3183 * @sleepFlag: Specifies whether the process can sleep
3185 * Returns 0 for success, non-zero for failure.
3188 GetPortFacts(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
)
3190 PortFacts_t get_pfacts
;
3191 PortFactsReply_t
*pfacts
;
3197 /* IOC *must* NOT be in RESET state! */
3198 if (ioc
->last_state
== MPI_IOC_STATE_RESET
) {
3199 printk(MYIOC_s_ERR_FMT
"Can't get PortFacts NOT READY! (%08x)\n",
3200 ioc
->name
, ioc
->last_state
);
3204 pfacts
= &ioc
->pfacts
[portnum
];
3206 /* Destination (reply area)... */
3207 reply_sz
= sizeof(*pfacts
);
3208 memset(pfacts
, 0, reply_sz
);
3210 /* Request area (get_pfacts on the stack right now!) */
3211 req_sz
= sizeof(get_pfacts
);
3212 memset(&get_pfacts
, 0, req_sz
);
3214 get_pfacts
.Function
= MPI_FUNCTION_PORT_FACTS
;
3215 get_pfacts
.PortNumber
= portnum
;
3216 /* Assert: All other get_pfacts fields are zero! */
3218 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending get PortFacts(%d) request\n",
3219 ioc
->name
, portnum
));
3221 /* No non-zero fields in the get_pfacts request are greater than
3222 * 1 byte in size, so we can just fire it off as is.
3224 ii
= mpt_handshake_req_reply_wait(ioc
, req_sz
, (u32
*)&get_pfacts
,
3225 reply_sz
, (u16
*)pfacts
, 5 /*seconds*/, sleepFlag
);
3229 /* Did we get a valid reply? */
3231 /* Now byte swap the necessary fields in the response. */
3232 pfacts
->MsgContext
= le32_to_cpu(pfacts
->MsgContext
);
3233 pfacts
->IOCStatus
= le16_to_cpu(pfacts
->IOCStatus
);
3234 pfacts
->IOCLogInfo
= le32_to_cpu(pfacts
->IOCLogInfo
);
3235 pfacts
->MaxDevices
= le16_to_cpu(pfacts
->MaxDevices
);
3236 pfacts
->PortSCSIID
= le16_to_cpu(pfacts
->PortSCSIID
);
3237 pfacts
->ProtocolFlags
= le16_to_cpu(pfacts
->ProtocolFlags
);
3238 pfacts
->MaxPostedCmdBuffers
= le16_to_cpu(pfacts
->MaxPostedCmdBuffers
);
3239 pfacts
->MaxPersistentIDs
= le16_to_cpu(pfacts
->MaxPersistentIDs
);
3240 pfacts
->MaxLanBuckets
= le16_to_cpu(pfacts
->MaxLanBuckets
);
3242 max_id
= (ioc
->bus_type
== SAS
) ? pfacts
->PortSCSIID
:
3244 ioc
->devices_per_bus
= (max_id
> 255) ? 256 : max_id
;
3245 ioc
->number_of_buses
= (ioc
->devices_per_bus
< 256) ? 1 : max_id
/256;
3248 * Place all the devices on channels
3252 if (mpt_channel_mapping
) {
3253 ioc
->devices_per_bus
= 1;
3254 ioc
->number_of_buses
= (max_id
> 255) ? 255 : max_id
;
3260 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3262 * SendIocInit - Send IOCInit request to MPT adapter.
3263 * @ioc: Pointer to MPT_ADAPTER structure
3264 * @sleepFlag: Specifies whether the process can sleep
3266 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
3268 * Returns 0 for success, non-zero for failure.
3271 SendIocInit(MPT_ADAPTER
*ioc
, int sleepFlag
)
3274 MPIDefaultReply_t init_reply
;
3280 memset(&ioc_init
, 0, sizeof(ioc_init
));
3281 memset(&init_reply
, 0, sizeof(init_reply
));
3283 ioc_init
.WhoInit
= MPI_WHOINIT_HOST_DRIVER
;
3284 ioc_init
.Function
= MPI_FUNCTION_IOC_INIT
;
3286 /* If we are in a recovery mode and we uploaded the FW image,
3287 * then this pointer is not NULL. Skip the upload a second time.
3288 * Set this flag if cached_fw set for either IOC.
3290 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)
3294 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"upload_fw %d facts.Flags=%x\n",
3295 ioc
->name
, ioc
->upload_fw
, ioc
->facts
.Flags
));
3297 ioc_init
.MaxDevices
= (U8
)ioc
->devices_per_bus
;
3298 ioc_init
.MaxBuses
= (U8
)ioc
->number_of_buses
;
3300 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"facts.MsgVersion=%x\n",
3301 ioc
->name
, ioc
->facts
.MsgVersion
));
3302 if (ioc
->facts
.MsgVersion
>= MPI_VERSION_01_05
) {
3303 // set MsgVersion and HeaderVersion host driver was built with
3304 ioc_init
.MsgVersion
= cpu_to_le16(MPI_VERSION
);
3305 ioc_init
.HeaderVersion
= cpu_to_le16(MPI_HEADER_VERSION
);
3307 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT
) {
3308 ioc_init
.HostPageBufferSGE
= ioc
->facts
.HostPageBufferSGE
;
3309 } else if(mpt_host_page_alloc(ioc
, &ioc_init
))
3312 ioc_init
.ReplyFrameSize
= cpu_to_le16(ioc
->reply_sz
); /* in BYTES */
3314 if (ioc
->sg_addr_size
== sizeof(u64
)) {
3315 /* Save the upper 32-bits of the request
3316 * (reply) and sense buffers.
3318 ioc_init
.HostMfaHighAddr
= cpu_to_le32((u32
)((u64
)ioc
->alloc_dma
>> 32));
3319 ioc_init
.SenseBufferHighAddr
= cpu_to_le32((u32
)((u64
)ioc
->sense_buf_pool_dma
>> 32));
3321 /* Force 32-bit addressing */
3322 ioc_init
.HostMfaHighAddr
= cpu_to_le32(0);
3323 ioc_init
.SenseBufferHighAddr
= cpu_to_le32(0);
3326 ioc
->facts
.CurrentHostMfaHighAddr
= ioc_init
.HostMfaHighAddr
;
3327 ioc
->facts
.CurrentSenseBufferHighAddr
= ioc_init
.SenseBufferHighAddr
;
3328 ioc
->facts
.MaxDevices
= ioc_init
.MaxDevices
;
3329 ioc
->facts
.MaxBuses
= ioc_init
.MaxBuses
;
3331 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending IOCInit (req @ %p)\n",
3332 ioc
->name
, &ioc_init
));
3334 r
= mpt_handshake_req_reply_wait(ioc
, sizeof(IOCInit_t
), (u32
*)&ioc_init
,
3335 sizeof(MPIDefaultReply_t
), (u16
*)&init_reply
, 10 /*seconds*/, sleepFlag
);
3337 printk(MYIOC_s_ERR_FMT
"Sending IOCInit failed(%d)!\n",ioc
->name
, r
);
3341 /* No need to byte swap the multibyte fields in the reply
3342 * since we don't even look at its contents.
3345 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending PortEnable (req @ %p)\n",
3346 ioc
->name
, &ioc_init
));
3348 if ((r
= SendPortEnable(ioc
, 0, sleepFlag
)) != 0) {
3349 printk(MYIOC_s_ERR_FMT
"Sending PortEnable failed(%d)!\n",ioc
->name
, r
);
3353 /* YIKES! SUPER IMPORTANT!!!
3354 * Poll IocState until _OPERATIONAL while IOC is doing
3355 * LoopInit and TargetDiscovery!
3358 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 60; /* 60 seconds */
3359 state
= mpt_GetIocState(ioc
, 1);
3360 while (state
!= MPI_IOC_STATE_OPERATIONAL
&& --cntdn
) {
3361 if (sleepFlag
== CAN_SLEEP
) {
3368 printk(MYIOC_s_ERR_FMT
"Wait IOC_OP state timeout(%d)!\n",
3369 ioc
->name
, (int)((count
+5)/HZ
));
3373 state
= mpt_GetIocState(ioc
, 1);
3376 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Wait IOC_OPERATIONAL state (cnt=%d)\n",
3379 ioc
->aen_event_read_flag
=0;
3383 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3385 * SendPortEnable - Send PortEnable request to MPT adapter port.
3386 * @ioc: Pointer to MPT_ADAPTER structure
3387 * @portnum: Port number to enable
3388 * @sleepFlag: Specifies whether the process can sleep
3390 * Send PortEnable to bring IOC to OPERATIONAL state.
3392 * Returns 0 for success, non-zero for failure.
3395 SendPortEnable(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
)
3397 PortEnable_t port_enable
;
3398 MPIDefaultReply_t reply_buf
;
3403 /* Destination... */
3404 reply_sz
= sizeof(MPIDefaultReply_t
);
3405 memset(&reply_buf
, 0, reply_sz
);
3407 req_sz
= sizeof(PortEnable_t
);
3408 memset(&port_enable
, 0, req_sz
);
3410 port_enable
.Function
= MPI_FUNCTION_PORT_ENABLE
;
3411 port_enable
.PortNumber
= portnum
;
3412 /* port_enable.ChainOffset = 0; */
3413 /* port_enable.MsgFlags = 0; */
3414 /* port_enable.MsgContext = 0; */
3416 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending Port(%d)Enable (req @ %p)\n",
3417 ioc
->name
, portnum
, &port_enable
));
3419 /* RAID FW may take a long time to enable
3421 if (ioc
->ir_firmware
|| ioc
->bus_type
== SAS
) {
3422 rc
= mpt_handshake_req_reply_wait(ioc
, req_sz
,
3423 (u32
*)&port_enable
, reply_sz
, (u16
*)&reply_buf
,
3424 300 /*seconds*/, sleepFlag
);
3426 rc
= mpt_handshake_req_reply_wait(ioc
, req_sz
,
3427 (u32
*)&port_enable
, reply_sz
, (u16
*)&reply_buf
,
3428 30 /*seconds*/, sleepFlag
);
3434 * mpt_alloc_fw_memory - allocate firmware memory
3435 * @ioc: Pointer to MPT_ADAPTER structure
3436 * @size: total FW bytes
3438 * If memory has already been allocated, the same (cached) value
3441 * Return 0 if successfull, or non-zero for failure
3444 mpt_alloc_fw_memory(MPT_ADAPTER
*ioc
, int size
)
3448 if (ioc
->cached_fw
) {
3449 rc
= 0; /* use already allocated memory */
3452 else if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
) {
3453 ioc
->cached_fw
= ioc
->alt_ioc
->cached_fw
; /* use alt_ioc's memory */
3454 ioc
->cached_fw_dma
= ioc
->alt_ioc
->cached_fw_dma
;
3458 ioc
->cached_fw
= pci_alloc_consistent(ioc
->pcidev
, size
, &ioc
->cached_fw_dma
);
3459 if (!ioc
->cached_fw
) {
3460 printk(MYIOC_s_ERR_FMT
"Unable to allocate memory for the cached firmware image!\n",
3464 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"FW Image @ %p[%p], sz=%d[%x] bytes\n",
3465 ioc
->name
, ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, size
, size
));
3466 ioc
->alloc_total
+= size
;
3474 * mpt_free_fw_memory - free firmware memory
3475 * @ioc: Pointer to MPT_ADAPTER structure
3477 * If alt_img is NULL, delete from ioc structure.
3478 * Else, delete a secondary image in same format.
3481 mpt_free_fw_memory(MPT_ADAPTER
*ioc
)
3485 if (!ioc
->cached_fw
)
3488 sz
= ioc
->facts
.FWImageSize
;
3489 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3490 ioc
->name
, ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, sz
, sz
));
3491 pci_free_consistent(ioc
->pcidev
, sz
, ioc
->cached_fw
, ioc
->cached_fw_dma
);
3492 ioc
->alloc_total
-= sz
;
3493 ioc
->cached_fw
= NULL
;
3496 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3498 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3499 * @ioc: Pointer to MPT_ADAPTER structure
3500 * @sleepFlag: Specifies whether the process can sleep
3502 * Returns 0 for success, >0 for handshake failure
3503 * <0 for fw upload failure.
3505 * Remark: If bound IOC and a successful FWUpload was performed
3506 * on the bound IOC, the second image is discarded
3507 * and memory is free'd. Both channels must upload to prevent
3508 * IOC from running in degraded mode.
3511 mpt_do_upload(MPT_ADAPTER
*ioc
, int sleepFlag
)
3513 u8 reply
[sizeof(FWUploadReply_t
)];
3514 FWUpload_t
*prequest
;
3515 FWUploadReply_t
*preply
;
3516 FWUploadTCSGE_t
*ptcsge
;
3518 int ii
, sz
, reply_sz
;
3521 /* If the image size is 0, we are done.
3523 if ((sz
= ioc
->facts
.FWImageSize
) == 0)
3526 if (mpt_alloc_fw_memory(ioc
, ioc
->facts
.FWImageSize
) != 0)
3529 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3530 ioc
->name
, ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, sz
, sz
));
3532 prequest
= (sleepFlag
== NO_SLEEP
) ? kzalloc(ioc
->req_sz
, GFP_ATOMIC
) :
3533 kzalloc(ioc
->req_sz
, GFP_KERNEL
);
3535 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"fw upload failed "
3536 "while allocating memory \n", ioc
->name
));
3537 mpt_free_fw_memory(ioc
);
3541 preply
= (FWUploadReply_t
*)&reply
;
3543 reply_sz
= sizeof(reply
);
3544 memset(preply
, 0, reply_sz
);
3546 prequest
->ImageType
= MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM
;
3547 prequest
->Function
= MPI_FUNCTION_FW_UPLOAD
;
3549 ptcsge
= (FWUploadTCSGE_t
*) &prequest
->SGL
;
3550 ptcsge
->DetailsLength
= 12;
3551 ptcsge
->Flags
= MPI_SGE_FLAGS_TRANSACTION_ELEMENT
;
3552 ptcsge
->ImageSize
= cpu_to_le32(sz
);
3555 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_READ
| sz
;
3556 ioc
->add_sge((char *)ptcsge
, flagsLength
, ioc
->cached_fw_dma
);
3557 request_size
= offsetof(FWUpload_t
, SGL
) + sizeof(FWUploadTCSGE_t
) +
3559 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending FW Upload "
3560 " (req @ %p) fw_size=%d mf_request_size=%d\n", ioc
->name
, prequest
,
3561 ioc
->facts
.FWImageSize
, request_size
));
3562 DBG_DUMP_FW_REQUEST_FRAME(ioc
, (u32
*)prequest
);
3564 ii
= mpt_handshake_req_reply_wait(ioc
, request_size
, (u32
*)prequest
,
3565 reply_sz
, (u16
*)preply
, 65 /*seconds*/, sleepFlag
);
3567 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"FW Upload completed "
3568 "rc=%x \n", ioc
->name
, ii
));
3570 cmdStatus
= -EFAULT
;
3572 /* Handshake transfer was complete and successful.
3573 * Check the Reply Frame.
3576 status
= le16_to_cpu(preply
->IOCStatus
) &
3578 if (status
== MPI_IOCSTATUS_SUCCESS
&&
3579 ioc
->facts
.FWImageSize
==
3580 le32_to_cpu(preply
->ActualImageSize
))
3583 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
": do_upload cmdStatus=%d \n",
3584 ioc
->name
, cmdStatus
));
3588 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"fw upload failed, "
3589 "freeing image \n", ioc
->name
));
3590 mpt_free_fw_memory(ioc
);
3597 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3599 * mpt_downloadboot - DownloadBoot code
3600 * @ioc: Pointer to MPT_ADAPTER structure
3601 * @pFwHeader: Pointer to firmware header info
3602 * @sleepFlag: Specifies whether the process can sleep
3604 * FwDownloadBoot requires Programmed IO access.
3606 * Returns 0 for success
3607 * -1 FW Image size is 0
3608 * -2 No valid cached_fw Pointer
3609 * <0 for fw upload failure.
3612 mpt_downloadboot(MPT_ADAPTER
*ioc
, MpiFwHeader_t
*pFwHeader
, int sleepFlag
)
3614 MpiExtImageHeader_t
*pExtImage
;
3624 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3625 ioc
->name
, pFwHeader
->ImageSize
, pFwHeader
->ImageSize
, pFwHeader
));
3627 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3628 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3629 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3630 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3631 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3632 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3634 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, (MPI_DIAG_PREVENT_IOC_BOOT
| MPI_DIAG_DISABLE_ARM
));
3637 if (sleepFlag
== CAN_SLEEP
) {
3643 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3644 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_RESET_ADAPTER
);
3646 for (count
= 0; count
< 30; count
++) {
3647 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3648 if (!(diag0val
& MPI_DIAG_RESET_ADAPTER
)) {
3649 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RESET_ADAPTER cleared, count=%d\n",
3654 if (sleepFlag
== CAN_SLEEP
) {
3661 if ( count
== 30 ) {
3662 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot failed! "
3663 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3664 ioc
->name
, diag0val
));
3668 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3669 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3670 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3671 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3672 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3673 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3675 /* Set the DiagRwEn and Disable ARM bits */
3676 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, (MPI_DIAG_RW_ENABLE
| MPI_DIAG_DISABLE_ARM
));
3678 fwSize
= (pFwHeader
->ImageSize
+ 3)/4;
3679 ptrFw
= (u32
*) pFwHeader
;
3681 /* Write the LoadStartAddress to the DiagRw Address Register
3682 * using Programmed IO
3684 if (ioc
->errata_flag_1064
)
3685 pci_enable_io_access(ioc
->pcidev
);
3687 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, pFwHeader
->LoadStartAddress
);
3688 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"LoadStart addr written 0x%x \n",
3689 ioc
->name
, pFwHeader
->LoadStartAddress
));
3691 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write FW Image: 0x%x bytes @ %p\n",
3692 ioc
->name
, fwSize
*4, ptrFw
));
3694 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, *ptrFw
++);
3697 nextImage
= pFwHeader
->NextImageHeaderOffset
;
3699 pExtImage
= (MpiExtImageHeader_t
*) ((char *)pFwHeader
+ nextImage
);
3701 load_addr
= pExtImage
->LoadStartAddress
;
3703 fwSize
= (pExtImage
->ImageSize
+ 3) >> 2;
3704 ptrFw
= (u32
*)pExtImage
;
3706 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3707 ioc
->name
, fwSize
*4, fwSize
*4, ptrFw
, load_addr
));
3708 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, load_addr
);
3711 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, *ptrFw
++);
3713 nextImage
= pExtImage
->NextImageHeaderOffset
;
3716 /* Write the IopResetVectorRegAddr */
3717 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write IopResetVector Addr=%x! \n", ioc
->name
, pFwHeader
->IopResetRegAddr
));
3718 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, pFwHeader
->IopResetRegAddr
);
3720 /* Write the IopResetVectorValue */
3721 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write IopResetVector Value=%x! \n", ioc
->name
, pFwHeader
->IopResetVectorValue
));
3722 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, pFwHeader
->IopResetVectorValue
);
3724 /* Clear the internal flash bad bit - autoincrementing register,
3725 * so must do two writes.
3727 if (ioc
->bus_type
== SPI
) {
3729 * 1030 and 1035 H/W errata, workaround to access
3730 * the ClearFlashBadSignatureBit
3732 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, 0x3F000000);
3733 diagRwData
= CHIPREG_PIO_READ32(&ioc
->pio_chip
->DiagRwData
);
3734 diagRwData
|= 0x40000000;
3735 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, 0x3F000000);
3736 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, diagRwData
);
3738 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3739 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3740 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
|
3741 MPI_DIAG_CLEAR_FLASH_BAD_SIG
);
3744 if (sleepFlag
== CAN_SLEEP
) {
3751 if (ioc
->errata_flag_1064
)
3752 pci_disable_io_access(ioc
->pcidev
);
3754 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3755 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot diag0val=%x, "
3756 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3757 ioc
->name
, diag0val
));
3758 diag0val
&= ~(MPI_DIAG_PREVENT_IOC_BOOT
| MPI_DIAG_DISABLE_ARM
| MPI_DIAG_RW_ENABLE
);
3759 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot now diag0val=%x\n",
3760 ioc
->name
, diag0val
));
3761 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
);
3763 /* Write 0xFF to reset the sequencer */
3764 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3766 if (ioc
->bus_type
== SAS
) {
3767 ioc_state
= mpt_GetIocState(ioc
, 0);
3768 if ( (GetIocFacts(ioc
, sleepFlag
,
3769 MPT_HOSTEVENT_IOC_BRINGUP
)) != 0 ) {
3770 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"GetIocFacts failed: IocState=%x\n",
3771 ioc
->name
, ioc_state
));
3776 for (count
=0; count
<HZ
*20; count
++) {
3777 if ((ioc_state
= mpt_GetIocState(ioc
, 0)) & MPI_IOC_STATE_READY
) {
3778 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3779 "downloadboot successful! (count=%d) IocState=%x\n",
3780 ioc
->name
, count
, ioc_state
));
3781 if (ioc
->bus_type
== SAS
) {
3784 if ((SendIocInit(ioc
, sleepFlag
)) != 0) {
3785 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3786 "downloadboot: SendIocInit failed\n",
3790 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3791 "downloadboot: SendIocInit successful\n",
3795 if (sleepFlag
== CAN_SLEEP
) {
3801 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3802 "downloadboot failed! IocState=%x\n",ioc
->name
, ioc_state
));
3806 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3808 * KickStart - Perform hard reset of MPT adapter.
3809 * @ioc: Pointer to MPT_ADAPTER structure
3810 * @force: Force hard reset
3811 * @sleepFlag: Specifies whether the process can sleep
3813 * This routine places MPT adapter in diagnostic mode via the
3814 * WriteSequence register, and then performs a hard reset of adapter
3815 * via the Diagnostic register.
3817 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3818 * or NO_SLEEP (interrupt thread, use mdelay)
3819 * force - 1 if doorbell active, board fault state
3820 * board operational, IOC_RECOVERY or
3821 * IOC_BRINGUP and there is an alt_ioc.
3825 * 1 - hard reset, READY
3826 * 0 - no reset due to History bit, READY
3827 * -1 - no reset due to History bit but not READY
3828 * OR reset but failed to come READY
3829 * -2 - no reset, could not enter DIAG mode
3830 * -3 - reset but bad FW bit
3833 KickStart(MPT_ADAPTER
*ioc
, int force
, int sleepFlag
)
3835 int hard_reset_done
= 0;
3839 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"KickStarting!\n", ioc
->name
));
3840 if (ioc
->bus_type
== SPI
) {
3841 /* Always issue a Msg Unit Reset first. This will clear some
3842 * SCSI bus hang conditions.
3844 SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
);
3846 if (sleepFlag
== CAN_SLEEP
) {
3853 hard_reset_done
= mpt_diag_reset(ioc
, force
, sleepFlag
);
3854 if (hard_reset_done
< 0)
3855 return hard_reset_done
;
3857 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Diagnostic reset successful!\n",
3860 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 2; /* 2 seconds */
3861 for (cnt
=0; cnt
<cntdn
; cnt
++) {
3862 ioc_state
= mpt_GetIocState(ioc
, 1);
3863 if ((ioc_state
== MPI_IOC_STATE_READY
) || (ioc_state
== MPI_IOC_STATE_OPERATIONAL
)) {
3864 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"KickStart successful! (cnt=%d)\n",
3866 return hard_reset_done
;
3868 if (sleepFlag
== CAN_SLEEP
) {
3875 dinitprintk(ioc
, printk(MYIOC_s_ERR_FMT
"Failed to come READY after reset! IocState=%x\n",
3876 ioc
->name
, mpt_GetIocState(ioc
, 0)));
3880 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3882 * mpt_diag_reset - Perform hard reset of the adapter.
3883 * @ioc: Pointer to MPT_ADAPTER structure
3884 * @ignore: Set if to honor and clear to ignore
3885 * the reset history bit
3886 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3887 * else set to NO_SLEEP (use mdelay instead)
3889 * This routine places the adapter in diagnostic mode via the
3890 * WriteSequence register and then performs a hard reset of adapter
3891 * via the Diagnostic register. Adapter should be in ready state
3892 * upon successful completion.
3894 * Returns: 1 hard reset successful
3895 * 0 no reset performed because reset history bit set
3896 * -2 enabling diagnostic mode failed
3897 * -3 diagnostic reset failed
3900 mpt_diag_reset(MPT_ADAPTER
*ioc
, int ignore
, int sleepFlag
)
3904 int hard_reset_done
= 0;
3907 MpiFwHeader_t
*cached_fw
; /* Pointer to FW */
3910 /* Clear any existing interrupts */
3911 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
3913 if (ioc
->pcidev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1078
) {
3918 drsprintk(ioc
, printk(MYIOC_s_WARN_FMT
"%s: Doorbell=%p; 1078 reset "
3919 "address=%p\n", ioc
->name
, __func__
,
3920 &ioc
->chip
->Doorbell
, &ioc
->chip
->Reset_1078
));
3921 CHIPREG_WRITE32(&ioc
->chip
->Reset_1078
, 0x07);
3922 if (sleepFlag
== CAN_SLEEP
)
3928 * Call each currently registered protocol IOC reset handler
3929 * with pre-reset indication.
3930 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3931 * MptResetHandlers[] registered yet.
3933 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
3934 if (MptResetHandlers
[cb_idx
])
3935 (*(MptResetHandlers
[cb_idx
]))(ioc
,
3939 for (count
= 0; count
< 60; count
++) {
3940 doorbell
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
3941 doorbell
&= MPI_IOC_STATE_MASK
;
3943 drsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3944 "looking for READY STATE: doorbell=%x"
3946 ioc
->name
, doorbell
, count
));
3948 if (doorbell
== MPI_IOC_STATE_READY
) {
3953 if (sleepFlag
== CAN_SLEEP
)
3961 /* Use "Diagnostic reset" method! (only thing available!) */
3962 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3964 if (ioc
->debug_level
& MPT_DEBUG
) {
3966 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
3967 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG1: diag0=%08x, diag1=%08x\n",
3968 ioc
->name
, diag0val
, diag1val
));
3971 /* Do the reset if we are told to ignore the reset history
3972 * or if the reset history is 0
3974 if (ignore
|| !(diag0val
& MPI_DIAG_RESET_HISTORY
)) {
3975 while ((diag0val
& MPI_DIAG_DRWE
) == 0) {
3976 /* Write magic sequence to WriteSequence register
3977 * Loop until in diagnostic mode
3979 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3980 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3981 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3982 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3983 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3984 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3987 if (sleepFlag
== CAN_SLEEP
) {
3995 printk(MYIOC_s_ERR_FMT
"Enable Diagnostic mode FAILED! (%02xh)\n",
3996 ioc
->name
, diag0val
);
4001 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4003 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Wrote magic DiagWriteEn sequence (%x)\n",
4004 ioc
->name
, diag0val
));
4007 if (ioc
->debug_level
& MPT_DEBUG
) {
4009 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
4010 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG2: diag0=%08x, diag1=%08x\n",
4011 ioc
->name
, diag0val
, diag1val
));
4014 * Disable the ARM (Bug fix)
4017 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_DISABLE_ARM
);
4021 * Now hit the reset bit in the Diagnostic register
4022 * (THE BIG HAMMER!) (Clears DRWE bit).
4024 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_RESET_ADAPTER
);
4025 hard_reset_done
= 1;
4026 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Diagnostic reset performed\n",
4030 * Call each currently registered protocol IOC reset handler
4031 * with pre-reset indication.
4032 * NOTE: If we're doing _IOC_BRINGUP, there can be no
4033 * MptResetHandlers[] registered yet.
4035 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
4036 if (MptResetHandlers
[cb_idx
]) {
4037 mpt_signal_reset(cb_idx
,
4038 ioc
, MPT_IOC_PRE_RESET
);
4040 mpt_signal_reset(cb_idx
,
4041 ioc
->alt_ioc
, MPT_IOC_PRE_RESET
);
4047 cached_fw
= (MpiFwHeader_t
*)ioc
->cached_fw
;
4048 else if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
)
4049 cached_fw
= (MpiFwHeader_t
*)ioc
->alt_ioc
->cached_fw
;
4053 /* If the DownloadBoot operation fails, the
4054 * IOC will be left unusable. This is a fatal error
4055 * case. _diag_reset will return < 0
4057 for (count
= 0; count
< 30; count
++) {
4058 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4059 if (!(diag0val
& MPI_DIAG_RESET_ADAPTER
)) {
4063 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"cached_fw: diag0val=%x count=%d\n",
4064 ioc
->name
, diag0val
, count
));
4066 if (sleepFlag
== CAN_SLEEP
) {
4072 if ((count
= mpt_downloadboot(ioc
, cached_fw
, sleepFlag
)) < 0) {
4073 printk(MYIOC_s_WARN_FMT
4074 "firmware downloadboot failure (%d)!\n", ioc
->name
, count
);
4078 /* Wait for FW to reload and for board
4079 * to go to the READY state.
4080 * Maximum wait is 60 seconds.
4081 * If fail, no error will check again
4082 * with calling program.
4084 for (count
= 0; count
< 60; count
++) {
4085 doorbell
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
4086 doorbell
&= MPI_IOC_STATE_MASK
;
4088 drsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4089 "looking for READY STATE: doorbell=%x"
4090 " count=%d\n", ioc
->name
, doorbell
, count
));
4092 if (doorbell
== MPI_IOC_STATE_READY
) {
4097 if (sleepFlag
== CAN_SLEEP
) {
4104 if (doorbell
!= MPI_IOC_STATE_READY
)
4105 printk(MYIOC_s_ERR_FMT
"Failed to come READY "
4106 "after reset! IocState=%x", ioc
->name
,
4111 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4112 if (ioc
->debug_level
& MPT_DEBUG
) {
4114 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
4115 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG3: diag0=%08x, diag1=%08x\n",
4116 ioc
->name
, diag0val
, diag1val
));
4119 /* Clear RESET_HISTORY bit! Place board in the
4120 * diagnostic mode to update the diag register.
4122 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4124 while ((diag0val
& MPI_DIAG_DRWE
) == 0) {
4125 /* Write magic sequence to WriteSequence register
4126 * Loop until in diagnostic mode
4128 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
4129 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
4130 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
4131 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
4132 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
4133 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
4136 if (sleepFlag
== CAN_SLEEP
) {
4144 printk(MYIOC_s_ERR_FMT
"Enable Diagnostic mode FAILED! (%02xh)\n",
4145 ioc
->name
, diag0val
);
4148 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4150 diag0val
&= ~MPI_DIAG_RESET_HISTORY
;
4151 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
);
4152 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4153 if (diag0val
& MPI_DIAG_RESET_HISTORY
) {
4154 printk(MYIOC_s_WARN_FMT
"ResetHistory bit failed to clear!\n",
4158 /* Disable Diagnostic Mode
4160 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFFFFFFFF);
4162 /* Check FW reload status flags.
4164 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4165 if (diag0val
& (MPI_DIAG_FLASH_BAD_SIG
| MPI_DIAG_RESET_ADAPTER
| MPI_DIAG_DISABLE_ARM
)) {
4166 printk(MYIOC_s_ERR_FMT
"Diagnostic reset FAILED! (%02xh)\n",
4167 ioc
->name
, diag0val
);
4171 if (ioc
->debug_level
& MPT_DEBUG
) {
4173 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
4174 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG4: diag0=%08x, diag1=%08x\n",
4175 ioc
->name
, diag0val
, diag1val
));
4179 * Reset flag that says we've enabled event notification
4181 ioc
->facts
.EventState
= 0;
4184 ioc
->alt_ioc
->facts
.EventState
= 0;
4186 return hard_reset_done
;
4189 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4191 * SendIocReset - Send IOCReset request to MPT adapter.
4192 * @ioc: Pointer to MPT_ADAPTER structure
4193 * @reset_type: reset type, expected values are
4194 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
4195 * @sleepFlag: Specifies whether the process can sleep
4197 * Send IOCReset request to the MPT adapter.
4199 * Returns 0 for success, non-zero for failure.
4202 SendIocReset(MPT_ADAPTER
*ioc
, u8 reset_type
, int sleepFlag
)
4208 drsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending IOC reset(0x%02x)!\n",
4209 ioc
->name
, reset_type
));
4210 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, reset_type
<<MPI_DOORBELL_FUNCTION_SHIFT
);
4211 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
4214 /* FW ACK'd request, wait for READY state
4217 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 15; /* 15 seconds */
4219 while ((state
= mpt_GetIocState(ioc
, 1)) != MPI_IOC_STATE_READY
) {
4223 if (sleepFlag
!= CAN_SLEEP
)
4226 printk(MYIOC_s_ERR_FMT
4227 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
4228 ioc
->name
, state
, (int)((count
+5)/HZ
));
4232 if (sleepFlag
== CAN_SLEEP
) {
4235 mdelay (1); /* 1 msec delay */
4240 * Cleanup all event stuff for this IOC; re-issue EventNotification
4241 * request if needed.
4243 if (ioc
->facts
.Function
)
4244 ioc
->facts
.EventState
= 0;
4249 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4251 * initChainBuffers - Allocate memory for and initialize chain buffers
4252 * @ioc: Pointer to MPT_ADAPTER structure
4254 * Allocates memory for and initializes chain buffers,
4255 * chain buffer control arrays and spinlock.
4258 initChainBuffers(MPT_ADAPTER
*ioc
)
4261 int sz
, ii
, num_chain
;
4262 int scale
, num_sge
, numSGE
;
4264 /* ReqToChain size must equal the req_depth
4267 if (ioc
->ReqToChain
== NULL
) {
4268 sz
= ioc
->req_depth
* sizeof(int);
4269 mem
= kmalloc(sz
, GFP_ATOMIC
);
4273 ioc
->ReqToChain
= (int *) mem
;
4274 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReqToChain alloc @ %p, sz=%d bytes\n",
4275 ioc
->name
, mem
, sz
));
4276 mem
= kmalloc(sz
, GFP_ATOMIC
);
4280 ioc
->RequestNB
= (int *) mem
;
4281 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestNB alloc @ %p, sz=%d bytes\n",
4282 ioc
->name
, mem
, sz
));
4284 for (ii
= 0; ii
< ioc
->req_depth
; ii
++) {
4285 ioc
->ReqToChain
[ii
] = MPT_HOST_NO_CHAIN
;
4288 /* ChainToChain size must equal the total number
4289 * of chain buffers to be allocated.
4292 * Calculate the number of chain buffers needed(plus 1) per I/O
4293 * then multiply the maximum number of simultaneous cmds
4295 * num_sge = num sge in request frame + last chain buffer
4296 * scale = num sge per chain buffer if no chain element
4298 scale
= ioc
->req_sz
/ ioc
->SGE_size
;
4299 if (ioc
->sg_addr_size
== sizeof(u64
))
4300 num_sge
= scale
+ (ioc
->req_sz
- 60) / ioc
->SGE_size
;
4302 num_sge
= 1 + scale
+ (ioc
->req_sz
- 64) / ioc
->SGE_size
;
4304 if (ioc
->sg_addr_size
== sizeof(u64
)) {
4305 numSGE
= (scale
- 1) * (ioc
->facts
.MaxChainDepth
-1) + scale
+
4306 (ioc
->req_sz
- 60) / ioc
->SGE_size
;
4308 numSGE
= 1 + (scale
- 1) * (ioc
->facts
.MaxChainDepth
-1) +
4309 scale
+ (ioc
->req_sz
- 64) / ioc
->SGE_size
;
4311 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"num_sge=%d numSGE=%d\n",
4312 ioc
->name
, num_sge
, numSGE
));
4314 if (ioc
->bus_type
== FC
) {
4315 if (numSGE
> MPT_SCSI_FC_SG_DEPTH
)
4316 numSGE
= MPT_SCSI_FC_SG_DEPTH
;
4318 if (numSGE
> MPT_SCSI_SG_DEPTH
)
4319 numSGE
= MPT_SCSI_SG_DEPTH
;
4323 while (numSGE
- num_sge
> 0) {
4325 num_sge
+= (scale
- 1);
4329 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Now numSGE=%d num_sge=%d num_chain=%d\n",
4330 ioc
->name
, numSGE
, num_sge
, num_chain
));
4332 if (ioc
->bus_type
== SPI
)
4333 num_chain
*= MPT_SCSI_CAN_QUEUE
;
4334 else if (ioc
->bus_type
== SAS
)
4335 num_chain
*= MPT_SAS_CAN_QUEUE
;
4337 num_chain
*= MPT_FC_CAN_QUEUE
;
4339 ioc
->num_chain
= num_chain
;
4341 sz
= num_chain
* sizeof(int);
4342 if (ioc
->ChainToChain
== NULL
) {
4343 mem
= kmalloc(sz
, GFP_ATOMIC
);
4347 ioc
->ChainToChain
= (int *) mem
;
4348 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainToChain alloc @ %p, sz=%d bytes\n",
4349 ioc
->name
, mem
, sz
));
4351 mem
= (u8
*) ioc
->ChainToChain
;
4353 memset(mem
, 0xFF, sz
);
4357 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4359 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
4360 * @ioc: Pointer to MPT_ADAPTER structure
4362 * This routine allocates memory for the MPT reply and request frame
4363 * pools (if necessary), and primes the IOC reply FIFO with
4366 * Returns 0 for success, non-zero for failure.
4369 PrimeIocFifos(MPT_ADAPTER
*ioc
)
4372 unsigned long flags
;
4373 dma_addr_t alloc_dma
;
4375 int i
, reply_sz
, sz
, total_size
, num_chain
;
4380 /* Prime reply FIFO... */
4382 if (ioc
->reply_frames
== NULL
) {
4383 if ( (num_chain
= initChainBuffers(ioc
)) < 0)
4386 * 1078 errata workaround for the 36GB limitation
4388 if (ioc
->pcidev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1078
&&
4389 ioc
->dma_mask
> DMA_BIT_MASK(35)) {
4390 if (!pci_set_dma_mask(ioc
->pcidev
, DMA_BIT_MASK(32))
4391 && !pci_set_consistent_dma_mask(ioc
->pcidev
,
4392 DMA_BIT_MASK(32))) {
4393 dma_mask
= DMA_BIT_MASK(35);
4394 d36memprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4395 "setting 35 bit addressing for "
4396 "Request/Reply/Chain and Sense Buffers\n",
4399 /*Reseting DMA mask to 64 bit*/
4400 pci_set_dma_mask(ioc
->pcidev
,
4402 pci_set_consistent_dma_mask(ioc
->pcidev
,
4405 printk(MYIOC_s_ERR_FMT
4406 "failed setting 35 bit addressing for "
4407 "Request/Reply/Chain and Sense Buffers\n",
4413 total_size
= reply_sz
= (ioc
->reply_sz
* ioc
->reply_depth
);
4414 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
4415 ioc
->name
, ioc
->reply_sz
, ioc
->reply_depth
));
4416 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffer sz=%d[%x] bytes\n",
4417 ioc
->name
, reply_sz
, reply_sz
));
4419 sz
= (ioc
->req_sz
* ioc
->req_depth
);
4420 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestBuffer sz=%d bytes, RequestDepth=%d\n",
4421 ioc
->name
, ioc
->req_sz
, ioc
->req_depth
));
4422 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestBuffer sz=%d[%x] bytes\n",
4423 ioc
->name
, sz
, sz
));
4426 sz
= num_chain
* ioc
->req_sz
; /* chain buffer pool size */
4427 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainBuffer sz=%d bytes, ChainDepth=%d\n",
4428 ioc
->name
, ioc
->req_sz
, num_chain
));
4429 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
4430 ioc
->name
, sz
, sz
, num_chain
));
4433 mem
= pci_alloc_consistent(ioc
->pcidev
, total_size
, &alloc_dma
);
4435 printk(MYIOC_s_ERR_FMT
"Unable to allocate Reply, Request, Chain Buffers!\n",
4440 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Total alloc @ %p[%p], sz=%d[%x] bytes\n",
4441 ioc
->name
, mem
, (void *)(ulong
)alloc_dma
, total_size
, total_size
));
4443 memset(mem
, 0, total_size
);
4444 ioc
->alloc_total
+= total_size
;
4446 ioc
->alloc_dma
= alloc_dma
;
4447 ioc
->alloc_sz
= total_size
;
4448 ioc
->reply_frames
= (MPT_FRAME_HDR
*) mem
;
4449 ioc
->reply_frames_low_dma
= (u32
) (alloc_dma
& 0xFFFFFFFF);
4451 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffers @ %p[%p]\n",
4452 ioc
->name
, ioc
->reply_frames
, (void *)(ulong
)alloc_dma
));
4454 alloc_dma
+= reply_sz
;
4457 /* Request FIFO - WE manage this! */
4459 ioc
->req_frames
= (MPT_FRAME_HDR
*) mem
;
4460 ioc
->req_frames_dma
= alloc_dma
;
4462 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestBuffers @ %p[%p]\n",
4463 ioc
->name
, mem
, (void *)(ulong
)alloc_dma
));
4465 ioc
->req_frames_low_dma
= (u32
) (alloc_dma
& 0xFFFFFFFF);
4467 #if defined(CONFIG_MTRR) && 0
4469 * Enable Write Combining MTRR for IOC's memory region.
4470 * (at least as much as we can; "size and base must be
4471 * multiples of 4 kiB"
4473 ioc
->mtrr_reg
= mtrr_add(ioc
->req_frames_dma
,
4475 MTRR_TYPE_WRCOMB
, 1);
4476 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"MTRR region registered (base:size=%08x:%x)\n",
4477 ioc
->name
, ioc
->req_frames_dma
, sz
));
4480 for (i
= 0; i
< ioc
->req_depth
; i
++) {
4481 alloc_dma
+= ioc
->req_sz
;
4485 ioc
->ChainBuffer
= mem
;
4486 ioc
->ChainBufferDMA
= alloc_dma
;
4488 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainBuffers @ %p(%p)\n",
4489 ioc
->name
, ioc
->ChainBuffer
, (void *)(ulong
)ioc
->ChainBufferDMA
));
4491 /* Initialize the free chain Q.
4494 INIT_LIST_HEAD(&ioc
->FreeChainQ
);
4496 /* Post the chain buffers to the FreeChainQ.
4498 mem
= (u8
*)ioc
->ChainBuffer
;
4499 for (i
=0; i
< num_chain
; i
++) {
4500 mf
= (MPT_FRAME_HDR
*) mem
;
4501 list_add_tail(&mf
->u
.frame
.linkage
.list
, &ioc
->FreeChainQ
);
4505 /* Initialize Request frames linked list
4507 alloc_dma
= ioc
->req_frames_dma
;
4508 mem
= (u8
*) ioc
->req_frames
;
4510 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
4511 INIT_LIST_HEAD(&ioc
->FreeQ
);
4512 for (i
= 0; i
< ioc
->req_depth
; i
++) {
4513 mf
= (MPT_FRAME_HDR
*) mem
;
4515 /* Queue REQUESTs *internally*! */
4516 list_add_tail(&mf
->u
.frame
.linkage
.list
, &ioc
->FreeQ
);
4520 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
4522 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
4523 ioc
->sense_buf_pool
=
4524 pci_alloc_consistent(ioc
->pcidev
, sz
, &ioc
->sense_buf_pool_dma
);
4525 if (ioc
->sense_buf_pool
== NULL
) {
4526 printk(MYIOC_s_ERR_FMT
"Unable to allocate Sense Buffers!\n",
4531 ioc
->sense_buf_low_dma
= (u32
) (ioc
->sense_buf_pool_dma
& 0xFFFFFFFF);
4532 ioc
->alloc_total
+= sz
;
4533 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SenseBuffers @ %p[%p]\n",
4534 ioc
->name
, ioc
->sense_buf_pool
, (void *)(ulong
)ioc
->sense_buf_pool_dma
));
4538 /* Post Reply frames to FIFO
4540 alloc_dma
= ioc
->alloc_dma
;
4541 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffers @ %p[%p]\n",
4542 ioc
->name
, ioc
->reply_frames
, (void *)(ulong
)alloc_dma
));
4544 for (i
= 0; i
< ioc
->reply_depth
; i
++) {
4545 /* Write each address to the IOC! */
4546 CHIPREG_WRITE32(&ioc
->chip
->ReplyFifo
, alloc_dma
);
4547 alloc_dma
+= ioc
->reply_sz
;
4550 if (dma_mask
== DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc
->pcidev
,
4551 ioc
->dma_mask
) && !pci_set_consistent_dma_mask(ioc
->pcidev
,
4553 d36memprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4554 "restoring 64 bit addressing\n", ioc
->name
));
4560 if (ioc
->alloc
!= NULL
) {
4562 pci_free_consistent(ioc
->pcidev
,
4564 ioc
->alloc
, ioc
->alloc_dma
);
4565 ioc
->reply_frames
= NULL
;
4566 ioc
->req_frames
= NULL
;
4567 ioc
->alloc_total
-= sz
;
4569 if (ioc
->sense_buf_pool
!= NULL
) {
4570 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
4571 pci_free_consistent(ioc
->pcidev
,
4573 ioc
->sense_buf_pool
, ioc
->sense_buf_pool_dma
);
4574 ioc
->sense_buf_pool
= NULL
;
4577 if (dma_mask
== DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc
->pcidev
,
4578 DMA_BIT_MASK(64)) && !pci_set_consistent_dma_mask(ioc
->pcidev
,
4580 d36memprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4581 "restoring 64 bit addressing\n", ioc
->name
));
4586 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4588 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4589 * from IOC via doorbell handshake method.
4590 * @ioc: Pointer to MPT_ADAPTER structure
4591 * @reqBytes: Size of the request in bytes
4592 * @req: Pointer to MPT request frame
4593 * @replyBytes: Expected size of the reply in bytes
4594 * @u16reply: Pointer to area where reply should be written
4595 * @maxwait: Max wait time for a reply (in seconds)
4596 * @sleepFlag: Specifies whether the process can sleep
4598 * NOTES: It is the callers responsibility to byte-swap fields in the
4599 * request which are greater than 1 byte in size. It is also the
4600 * callers responsibility to byte-swap response fields which are
4601 * greater than 1 byte in size.
4603 * Returns 0 for success, non-zero for failure.
4606 mpt_handshake_req_reply_wait(MPT_ADAPTER
*ioc
, int reqBytes
, u32
*req
,
4607 int replyBytes
, u16
*u16reply
, int maxwait
, int sleepFlag
)
4609 MPIDefaultReply_t
*mptReply
;
4614 * Get ready to cache a handshake reply
4616 ioc
->hs_reply_idx
= 0;
4617 mptReply
= (MPIDefaultReply_t
*) ioc
->hs_reply
;
4618 mptReply
->MsgLength
= 0;
4621 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4622 * then tell IOC that we want to handshake a request of N words.
4623 * (WRITE u32val to Doorbell reg).
4625 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4626 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
,
4627 ((MPI_FUNCTION_HANDSHAKE
<<MPI_DOORBELL_FUNCTION_SHIFT
) |
4628 ((reqBytes
/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT
)));
4631 * Wait for IOC's doorbell handshake int
4633 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4636 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4637 ioc
->name
, reqBytes
, t
, failcnt
? " - MISSING DOORBELL HANDSHAKE!" : ""));
4639 /* Read doorbell and check for active bit */
4640 if (!(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & MPI_DOORBELL_ACTIVE
))
4644 * Clear doorbell int (WRITE 0 to IntStatus reg),
4645 * then wait for IOC to ACKnowledge that it's ready for
4646 * our handshake request.
4648 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4649 if (!failcnt
&& (t
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
4654 u8
*req_as_bytes
= (u8
*) req
;
4657 * Stuff request words via doorbell handshake,
4658 * with ACK from IOC for each.
4660 for (ii
= 0; !failcnt
&& ii
< reqBytes
/4; ii
++) {
4661 u32 word
= ((req_as_bytes
[(ii
*4) + 0] << 0) |
4662 (req_as_bytes
[(ii
*4) + 1] << 8) |
4663 (req_as_bytes
[(ii
*4) + 2] << 16) |
4664 (req_as_bytes
[(ii
*4) + 3] << 24));
4666 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, word
);
4667 if ((t
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
4671 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Handshake request frame (@%p) header\n", ioc
->name
, req
));
4672 DBG_DUMP_REQUEST_FRAME_HDR(ioc
, (u32
*)req
);
4674 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HandShake request post done, WaitCnt=%d%s\n",
4675 ioc
->name
, t
, failcnt
? " - MISSING DOORBELL ACK!" : ""));
4678 * Wait for completion of doorbell handshake reply from the IOC
4680 if (!failcnt
&& (t
= WaitForDoorbellReply(ioc
, maxwait
, sleepFlag
)) < 0)
4683 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HandShake reply count=%d%s\n",
4684 ioc
->name
, t
, failcnt
? " - MISSING DOORBELL REPLY!" : ""));
4687 * Copy out the cached reply...
4689 for (ii
=0; ii
< min(replyBytes
/2,mptReply
->MsgLength
*2); ii
++)
4690 u16reply
[ii
] = ioc
->hs_reply
[ii
];
4698 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4700 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4701 * @ioc: Pointer to MPT_ADAPTER structure
4702 * @howlong: How long to wait (in seconds)
4703 * @sleepFlag: Specifies whether the process can sleep
4705 * This routine waits (up to ~2 seconds max) for IOC doorbell
4706 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4707 * bit in its IntStatus register being clear.
4709 * Returns a negative value on failure, else wait loop count.
4712 WaitForDoorbellAck(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
4718 cntdn
= 1000 * howlong
;
4720 if (sleepFlag
== CAN_SLEEP
) {
4723 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4724 if (! (intstat
& MPI_HIS_IOP_DOORBELL_STATUS
))
4731 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4732 if (! (intstat
& MPI_HIS_IOP_DOORBELL_STATUS
))
4739 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitForDoorbell ACK (count=%d)\n",
4744 printk(MYIOC_s_ERR_FMT
"Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4745 ioc
->name
, count
, intstat
);
4749 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4751 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4752 * @ioc: Pointer to MPT_ADAPTER structure
4753 * @howlong: How long to wait (in seconds)
4754 * @sleepFlag: Specifies whether the process can sleep
4756 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4757 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4759 * Returns a negative value on failure, else wait loop count.
4762 WaitForDoorbellInt(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
4768 cntdn
= 1000 * howlong
;
4769 if (sleepFlag
== CAN_SLEEP
) {
4771 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4772 if (intstat
& MPI_HIS_DOORBELL_INTERRUPT
)
4779 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4780 if (intstat
& MPI_HIS_DOORBELL_INTERRUPT
)
4788 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4789 ioc
->name
, count
, howlong
));
4793 printk(MYIOC_s_ERR_FMT
"Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4794 ioc
->name
, count
, intstat
);
4798 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4800 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4801 * @ioc: Pointer to MPT_ADAPTER structure
4802 * @howlong: How long to wait (in seconds)
4803 * @sleepFlag: Specifies whether the process can sleep
4805 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4806 * Reply is cached to IOC private area large enough to hold a maximum
4807 * of 128 bytes of reply data.
4809 * Returns a negative value on failure, else size of reply in WORDS.
4812 WaitForDoorbellReply(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
4817 u16
*hs_reply
= ioc
->hs_reply
;
4818 volatile MPIDefaultReply_t
*mptReply
= (MPIDefaultReply_t
*) ioc
->hs_reply
;
4821 hs_reply
[0] = hs_reply
[1] = hs_reply
[7] = 0;
4824 * Get first two u16's so we can look at IOC's intended reply MsgLength
4827 if ((t
= WaitForDoorbellInt(ioc
, howlong
, sleepFlag
)) < 0) {
4830 hs_reply
[u16cnt
++] = le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4831 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4832 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4835 hs_reply
[u16cnt
++] = le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4836 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4840 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitCnt=%d First handshake reply word=%08x%s\n",
4841 ioc
->name
, t
, le32_to_cpu(*(u32
*)hs_reply
),
4842 failcnt
? " - MISSING DOORBELL HANDSHAKE!" : ""));
4845 * If no error (and IOC said MsgLength is > 0), piece together
4846 * reply 16 bits at a time.
4848 for (u16cnt
=2; !failcnt
&& u16cnt
< (2 * mptReply
->MsgLength
); u16cnt
++) {
4849 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4851 hword
= le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4852 /* don't overflow our IOC hs_reply[] buffer! */
4853 if (u16cnt
< ARRAY_SIZE(ioc
->hs_reply
))
4854 hs_reply
[u16cnt
] = hword
;
4855 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4858 if (!failcnt
&& (t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4860 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4863 printk(MYIOC_s_ERR_FMT
"Handshake reply failure!\n",
4868 else if (u16cnt
!= (2 * mptReply
->MsgLength
)) {
4871 else if ((mptReply
->IOCStatus
& MPI_IOCSTATUS_MASK
) != MPI_IOCSTATUS_SUCCESS
) {
4876 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Got Handshake reply:\n", ioc
->name
));
4877 DBG_DUMP_REPLY_FRAME(ioc
, (u32
*)mptReply
);
4879 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4880 ioc
->name
, t
, u16cnt
/2));
4884 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4886 * GetLanConfigPages - Fetch LANConfig pages.
4887 * @ioc: Pointer to MPT_ADAPTER structure
4889 * Return: 0 for success
4890 * -ENOMEM if no memory available
4891 * -EPERM if not allowed due to ISR context
4892 * -EAGAIN if no msg frames currently available
4893 * -EFAULT for non-successful reply or no reply (timeout)
4896 GetLanConfigPages(MPT_ADAPTER
*ioc
)
4898 ConfigPageHeader_t hdr
;
4900 LANPage0_t
*ppage0_alloc
;
4901 dma_addr_t page0_dma
;
4902 LANPage1_t
*ppage1_alloc
;
4903 dma_addr_t page1_dma
;
4908 /* Get LAN Page 0 header */
4909 hdr
.PageVersion
= 0;
4912 hdr
.PageType
= MPI_CONFIG_PAGETYPE_LAN
;
4913 cfg
.cfghdr
.hdr
= &hdr
;
4915 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4920 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
4923 if (hdr
.PageLength
> 0) {
4924 data_sz
= hdr
.PageLength
* 4;
4925 ppage0_alloc
= (LANPage0_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page0_dma
);
4928 memset((u8
*)ppage0_alloc
, 0, data_sz
);
4929 cfg
.physAddr
= page0_dma
;
4930 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4932 if ((rc
= mpt_config(ioc
, &cfg
)) == 0) {
4934 copy_sz
= min_t(int, sizeof(LANPage0_t
), data_sz
);
4935 memcpy(&ioc
->lan_cnfg_page0
, ppage0_alloc
, copy_sz
);
4939 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage0_alloc
, page0_dma
);
4942 * Normalize endianness of structure data,
4943 * by byte-swapping all > 1 byte fields!
4952 /* Get LAN Page 1 header */
4953 hdr
.PageVersion
= 0;
4956 hdr
.PageType
= MPI_CONFIG_PAGETYPE_LAN
;
4957 cfg
.cfghdr
.hdr
= &hdr
;
4959 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4963 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
4966 if (hdr
.PageLength
== 0)
4969 data_sz
= hdr
.PageLength
* 4;
4971 ppage1_alloc
= (LANPage1_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page1_dma
);
4973 memset((u8
*)ppage1_alloc
, 0, data_sz
);
4974 cfg
.physAddr
= page1_dma
;
4975 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4977 if ((rc
= mpt_config(ioc
, &cfg
)) == 0) {
4979 copy_sz
= min_t(int, sizeof(LANPage1_t
), data_sz
);
4980 memcpy(&ioc
->lan_cnfg_page1
, ppage1_alloc
, copy_sz
);
4983 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage1_alloc
, page1_dma
);
4986 * Normalize endianness of structure data,
4987 * by byte-swapping all > 1 byte fields!
4995 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4997 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
4998 * @ioc: Pointer to MPT_ADAPTER structure
4999 * @persist_opcode: see below
5001 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
5002 * devices not currently present.
5003 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
5005 * NOTE: Don't use not this function during interrupt time.
5007 * Returns 0 for success, non-zero error
5010 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5012 mptbase_sas_persist_operation(MPT_ADAPTER
*ioc
, u8 persist_opcode
)
5014 SasIoUnitControlRequest_t
*sasIoUnitCntrReq
;
5015 SasIoUnitControlReply_t
*sasIoUnitCntrReply
;
5016 MPT_FRAME_HDR
*mf
= NULL
;
5017 MPIHeader_t
*mpi_hdr
;
5019 unsigned long timeleft
;
5021 mutex_lock(&ioc
->mptbase_cmds
.mutex
);
5023 /* init the internal cmd struct */
5024 memset(ioc
->mptbase_cmds
.reply
, 0 , MPT_DEFAULT_FRAME_SIZE
);
5025 INITIALIZE_MGMT_STATUS(ioc
->mptbase_cmds
.status
)
5027 /* insure garbage is not sent to fw */
5028 switch(persist_opcode
) {
5030 case MPI_SAS_OP_CLEAR_NOT_PRESENT
:
5031 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT
:
5039 printk(KERN_DEBUG
"%s: persist_opcode=%x\n",
5040 __func__
, persist_opcode
);
5042 /* Get a MF for this command.
5044 if ((mf
= mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
5045 printk(KERN_DEBUG
"%s: no msg frames!\n", __func__
);
5050 mpi_hdr
= (MPIHeader_t
*) mf
;
5051 sasIoUnitCntrReq
= (SasIoUnitControlRequest_t
*)mf
;
5052 memset(sasIoUnitCntrReq
,0,sizeof(SasIoUnitControlRequest_t
));
5053 sasIoUnitCntrReq
->Function
= MPI_FUNCTION_SAS_IO_UNIT_CONTROL
;
5054 sasIoUnitCntrReq
->MsgContext
= mpi_hdr
->MsgContext
;
5055 sasIoUnitCntrReq
->Operation
= persist_opcode
;
5057 mpt_put_msg_frame(mpt_base_index
, ioc
, mf
);
5058 timeleft
= wait_for_completion_timeout(&ioc
->mptbase_cmds
.done
, 10*HZ
);
5059 if (!(ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_COMMAND_GOOD
)) {
5061 printk(KERN_DEBUG
"%s: failed\n", __func__
);
5062 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_DID_IOCRESET
)
5065 printk(KERN_DEBUG
"%s: Issuing Reset from %s!!\n",
5066 ioc
->name
, __func__
);
5067 mpt_Soft_Hard_ResetHandler(ioc
, CAN_SLEEP
);
5068 mpt_free_msg_frame(ioc
, mf
);
5073 if (!(ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_RF_VALID
)) {
5078 sasIoUnitCntrReply
=
5079 (SasIoUnitControlReply_t
*)ioc
->mptbase_cmds
.reply
;
5080 if (le16_to_cpu(sasIoUnitCntrReply
->IOCStatus
) != MPI_IOCSTATUS_SUCCESS
) {
5081 printk(KERN_DEBUG
"%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
5082 __func__
, sasIoUnitCntrReply
->IOCStatus
,
5083 sasIoUnitCntrReply
->IOCLogInfo
);
5084 printk(KERN_DEBUG
"%s: failed\n", __func__
);
5087 printk(KERN_DEBUG
"%s: success\n", __func__
);
5090 CLEAR_MGMT_STATUS(ioc
->mptbase_cmds
.status
)
5091 mutex_unlock(&ioc
->mptbase_cmds
.mutex
);
5095 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5098 mptbase_raid_process_event_data(MPT_ADAPTER
*ioc
,
5099 MpiEventDataRaid_t
* pRaidEventData
)
5108 volume
= pRaidEventData
->VolumeID
;
5109 reason
= pRaidEventData
->ReasonCode
;
5110 disk
= pRaidEventData
->PhysDiskNum
;
5111 status
= le32_to_cpu(pRaidEventData
->SettingsStatus
);
5112 flags
= (status
>> 0) & 0xff;
5113 state
= (status
>> 8) & 0xff;
5115 if (reason
== MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
) {
5119 if ((reason
>= MPI_EVENT_RAID_RC_PHYSDISK_CREATED
&&
5120 reason
<= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
) ||
5121 (reason
== MPI_EVENT_RAID_RC_SMART_DATA
)) {
5122 printk(MYIOC_s_INFO_FMT
"RAID STATUS CHANGE for PhysDisk %d id=%d\n",
5123 ioc
->name
, disk
, volume
);
5125 printk(MYIOC_s_INFO_FMT
"RAID STATUS CHANGE for VolumeID %d\n",
5130 case MPI_EVENT_RAID_RC_VOLUME_CREATED
:
5131 printk(MYIOC_s_INFO_FMT
" volume has been created\n",
5135 case MPI_EVENT_RAID_RC_VOLUME_DELETED
:
5137 printk(MYIOC_s_INFO_FMT
" volume has been deleted\n",
5141 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED
:
5142 printk(MYIOC_s_INFO_FMT
" volume settings have been changed\n",
5146 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED
:
5147 printk(MYIOC_s_INFO_FMT
" volume is now %s%s%s%s\n",
5149 state
== MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
5151 : state
== MPI_RAIDVOL0_STATUS_STATE_DEGRADED
5153 : state
== MPI_RAIDVOL0_STATUS_STATE_FAILED
5156 flags
& MPI_RAIDVOL0_STATUS_FLAG_ENABLED
5158 flags
& MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
5159 ? ", quiesced" : "",
5160 flags
& MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
5161 ? ", resync in progress" : "" );
5164 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED
:
5165 printk(MYIOC_s_INFO_FMT
" volume membership of PhysDisk %d has changed\n",
5169 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED
:
5170 printk(MYIOC_s_INFO_FMT
" PhysDisk has been created\n",
5174 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED
:
5175 printk(MYIOC_s_INFO_FMT
" PhysDisk has been deleted\n",
5179 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED
:
5180 printk(MYIOC_s_INFO_FMT
" PhysDisk settings have been changed\n",
5184 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
:
5185 printk(MYIOC_s_INFO_FMT
" PhysDisk is now %s%s%s\n",
5187 state
== MPI_PHYSDISK0_STATUS_ONLINE
5189 : state
== MPI_PHYSDISK0_STATUS_MISSING
5191 : state
== MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
5193 : state
== MPI_PHYSDISK0_STATUS_FAILED
5195 : state
== MPI_PHYSDISK0_STATUS_INITIALIZING
5197 : state
== MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
5198 ? "offline requested"
5199 : state
== MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
5200 ? "failed requested"
5201 : state
== MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
5204 flags
& MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
5205 ? ", out of sync" : "",
5206 flags
& MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
5207 ? ", quiesced" : "" );
5210 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
:
5211 printk(MYIOC_s_INFO_FMT
" Domain Validation needed for PhysDisk %d\n",
5215 case MPI_EVENT_RAID_RC_SMART_DATA
:
5216 printk(MYIOC_s_INFO_FMT
" SMART data received, ASC/ASCQ = %02xh/%02xh\n",
5217 ioc
->name
, pRaidEventData
->ASC
, pRaidEventData
->ASCQ
);
5220 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED
:
5221 printk(MYIOC_s_INFO_FMT
" replacement of PhysDisk %d has started\n",
5227 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5229 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
5230 * @ioc: Pointer to MPT_ADAPTER structure
5232 * Returns: 0 for success
5233 * -ENOMEM if no memory available
5234 * -EPERM if not allowed due to ISR context
5235 * -EAGAIN if no msg frames currently available
5236 * -EFAULT for non-successful reply or no reply (timeout)
5239 GetIoUnitPage2(MPT_ADAPTER
*ioc
)
5241 ConfigPageHeader_t hdr
;
5243 IOUnitPage2_t
*ppage_alloc
;
5244 dma_addr_t page_dma
;
5248 /* Get the page header */
5249 hdr
.PageVersion
= 0;
5252 hdr
.PageType
= MPI_CONFIG_PAGETYPE_IO_UNIT
;
5253 cfg
.cfghdr
.hdr
= &hdr
;
5255 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5260 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
5263 if (hdr
.PageLength
== 0)
5266 /* Read the config page */
5267 data_sz
= hdr
.PageLength
* 4;
5269 ppage_alloc
= (IOUnitPage2_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page_dma
);
5271 memset((u8
*)ppage_alloc
, 0, data_sz
);
5272 cfg
.physAddr
= page_dma
;
5273 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5275 /* If Good, save data */
5276 if ((rc
= mpt_config(ioc
, &cfg
)) == 0)
5277 ioc
->biosVersion
= le32_to_cpu(ppage_alloc
->BiosVersion
);
5279 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage_alloc
, page_dma
);
5285 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5287 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
5288 * @ioc: Pointer to a Adapter Strucutre
5289 * @portnum: IOC port number
5291 * Return: -EFAULT if read of config page header fails
5293 * If read of SCSI Port Page 0 fails,
5294 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5295 * Adapter settings: async, narrow
5297 * If read of SCSI Port Page 2 fails,
5298 * Adapter settings valid
5299 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5304 * CHECK - what type of locking mechanisms should be used????
5307 mpt_GetScsiPortSettings(MPT_ADAPTER
*ioc
, int portnum
)
5312 ConfigPageHeader_t header
;
5318 if (!ioc
->spi_data
.nvram
) {
5321 sz
= MPT_MAX_SCSI_DEVICES
* sizeof(int);
5322 mem
= kmalloc(sz
, GFP_ATOMIC
);
5326 ioc
->spi_data
.nvram
= (int *) mem
;
5328 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SCSI device NVRAM settings @ %p, sz=%d\n",
5329 ioc
->name
, ioc
->spi_data
.nvram
, sz
));
5332 /* Invalidate NVRAM information
5334 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
5335 ioc
->spi_data
.nvram
[ii
] = MPT_HOST_NVRAM_INVALID
;
5338 /* Read SPP0 header, allocate memory, then read page.
5340 header
.PageVersion
= 0;
5341 header
.PageLength
= 0;
5342 header
.PageNumber
= 0;
5343 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_PORT
;
5344 cfg
.cfghdr
.hdr
= &header
;
5346 cfg
.pageAddr
= portnum
;
5347 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5349 cfg
.timeout
= 0; /* use default */
5350 if (mpt_config(ioc
, &cfg
) != 0)
5353 if (header
.PageLength
> 0) {
5354 pbuf
= pci_alloc_consistent(ioc
->pcidev
, header
.PageLength
* 4, &buf_dma
);
5356 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5357 cfg
.physAddr
= buf_dma
;
5358 if (mpt_config(ioc
, &cfg
) != 0) {
5359 ioc
->spi_data
.maxBusWidth
= MPT_NARROW
;
5360 ioc
->spi_data
.maxSyncOffset
= 0;
5361 ioc
->spi_data
.minSyncFactor
= MPT_ASYNC
;
5362 ioc
->spi_data
.busType
= MPT_HOST_BUS_UNKNOWN
;
5364 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5365 "Unable to read PortPage0 minSyncFactor=%x\n",
5366 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
5368 /* Save the Port Page 0 data
5370 SCSIPortPage0_t
*pPP0
= (SCSIPortPage0_t
*) pbuf
;
5371 pPP0
->Capabilities
= le32_to_cpu(pPP0
->Capabilities
);
5372 pPP0
->PhysicalInterface
= le32_to_cpu(pPP0
->PhysicalInterface
);
5374 if ( (pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_QAS
) == 0 ) {
5375 ioc
->spi_data
.noQas
|= MPT_TARGET_NO_NEGO_QAS
;
5376 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5377 "noQas due to Capabilities=%x\n",
5378 ioc
->name
, pPP0
->Capabilities
));
5380 ioc
->spi_data
.maxBusWidth
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_WIDE
? 1 : 0;
5381 data
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK
;
5383 ioc
->spi_data
.maxSyncOffset
= (u8
) (data
>> 16);
5384 data
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK
;
5385 ioc
->spi_data
.minSyncFactor
= (u8
) (data
>> 8);
5386 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5387 "PortPage0 minSyncFactor=%x\n",
5388 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
5390 ioc
->spi_data
.maxSyncOffset
= 0;
5391 ioc
->spi_data
.minSyncFactor
= MPT_ASYNC
;
5394 ioc
->spi_data
.busType
= pPP0
->PhysicalInterface
& MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK
;
5396 /* Update the minSyncFactor based on bus type.
5398 if ((ioc
->spi_data
.busType
== MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD
) ||
5399 (ioc
->spi_data
.busType
== MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE
)) {
5401 if (ioc
->spi_data
.minSyncFactor
< MPT_ULTRA
) {
5402 ioc
->spi_data
.minSyncFactor
= MPT_ULTRA
;
5403 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5404 "HVD or SE detected, minSyncFactor=%x\n",
5405 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
5410 pci_free_consistent(ioc
->pcidev
, header
.PageLength
* 4, pbuf
, buf_dma
);
5415 /* SCSI Port Page 2 - Read the header then the page.
5417 header
.PageVersion
= 0;
5418 header
.PageLength
= 0;
5419 header
.PageNumber
= 2;
5420 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_PORT
;
5421 cfg
.cfghdr
.hdr
= &header
;
5423 cfg
.pageAddr
= portnum
;
5424 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5426 if (mpt_config(ioc
, &cfg
) != 0)
5429 if (header
.PageLength
> 0) {
5430 /* Allocate memory and read SCSI Port Page 2
5432 pbuf
= pci_alloc_consistent(ioc
->pcidev
, header
.PageLength
* 4, &buf_dma
);
5434 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_NVRAM
;
5435 cfg
.physAddr
= buf_dma
;
5436 if (mpt_config(ioc
, &cfg
) != 0) {
5437 /* Nvram data is left with INVALID mark
5440 } else if (ioc
->pcidev
->vendor
== PCI_VENDOR_ID_ATTO
) {
5442 /* This is an ATTO adapter, read Page2 accordingly
5444 ATTO_SCSIPortPage2_t
*pPP2
= (ATTO_SCSIPortPage2_t
*) pbuf
;
5445 ATTODeviceInfo_t
*pdevice
= NULL
;
5448 /* Save the Port Page 2 data
5449 * (reformat into a 32bit quantity)
5451 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
5452 pdevice
= &pPP2
->DeviceSettings
[ii
];
5453 ATTOFlags
= le16_to_cpu(pdevice
->ATTOFlags
);
5456 /* Translate ATTO device flags to LSI format
5458 if (ATTOFlags
& ATTOFLAG_DISC
)
5459 data
|= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE
);
5460 if (ATTOFlags
& ATTOFLAG_ID_ENB
)
5461 data
|= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE
);
5462 if (ATTOFlags
& ATTOFLAG_LUN_ENB
)
5463 data
|= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE
);
5464 if (ATTOFlags
& ATTOFLAG_TAGGED
)
5465 data
|= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE
);
5466 if (!(ATTOFlags
& ATTOFLAG_WIDE_ENB
))
5467 data
|= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE
);
5469 data
= (data
<< 16) | (pdevice
->Period
<< 8) | 10;
5470 ioc
->spi_data
.nvram
[ii
] = data
;
5473 SCSIPortPage2_t
*pPP2
= (SCSIPortPage2_t
*) pbuf
;
5474 MpiDeviceInfo_t
*pdevice
= NULL
;
5477 * Save "Set to Avoid SCSI Bus Resets" flag
5479 ioc
->spi_data
.bus_reset
=
5480 (le32_to_cpu(pPP2
->PortFlags
) &
5481 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET
) ?
5484 /* Save the Port Page 2 data
5485 * (reformat into a 32bit quantity)
5487 data
= le32_to_cpu(pPP2
->PortFlags
) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK
;
5488 ioc
->spi_data
.PortFlags
= data
;
5489 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
5490 pdevice
= &pPP2
->DeviceSettings
[ii
];
5491 data
= (le16_to_cpu(pdevice
->DeviceFlags
) << 16) |
5492 (pdevice
->SyncFactor
<< 8) | pdevice
->Timeout
;
5493 ioc
->spi_data
.nvram
[ii
] = data
;
5497 pci_free_consistent(ioc
->pcidev
, header
.PageLength
* 4, pbuf
, buf_dma
);
5501 /* Update Adapter limits with those from NVRAM
5502 * Comment: Don't need to do this. Target performance
5503 * parameters will never exceed the adapters limits.
5509 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5511 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
5512 * @ioc: Pointer to a Adapter Strucutre
5513 * @portnum: IOC port number
5515 * Return: -EFAULT if read of config page header fails
5519 mpt_readScsiDevicePageHeaders(MPT_ADAPTER
*ioc
, int portnum
)
5522 ConfigPageHeader_t header
;
5524 /* Read the SCSI Device Page 1 header
5526 header
.PageVersion
= 0;
5527 header
.PageLength
= 0;
5528 header
.PageNumber
= 1;
5529 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_DEVICE
;
5530 cfg
.cfghdr
.hdr
= &header
;
5532 cfg
.pageAddr
= portnum
;
5533 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5536 if (mpt_config(ioc
, &cfg
) != 0)
5539 ioc
->spi_data
.sdp1version
= cfg
.cfghdr
.hdr
->PageVersion
;
5540 ioc
->spi_data
.sdp1length
= cfg
.cfghdr
.hdr
->PageLength
;
5542 header
.PageVersion
= 0;
5543 header
.PageLength
= 0;
5544 header
.PageNumber
= 0;
5545 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_DEVICE
;
5546 if (mpt_config(ioc
, &cfg
) != 0)
5549 ioc
->spi_data
.sdp0version
= cfg
.cfghdr
.hdr
->PageVersion
;
5550 ioc
->spi_data
.sdp0length
= cfg
.cfghdr
.hdr
->PageLength
;
5552 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Headers: 0: version %d length %d\n",
5553 ioc
->name
, ioc
->spi_data
.sdp0version
, ioc
->spi_data
.sdp0length
));
5555 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Headers: 1: version %d length %d\n",
5556 ioc
->name
, ioc
->spi_data
.sdp1version
, ioc
->spi_data
.sdp1length
));
5561 * mpt_inactive_raid_list_free - This clears this link list.
5562 * @ioc : pointer to per adapter structure
5565 mpt_inactive_raid_list_free(MPT_ADAPTER
*ioc
)
5567 struct inactive_raid_component_info
*component_info
, *pNext
;
5569 if (list_empty(&ioc
->raid_data
.inactive_list
))
5572 mutex_lock(&ioc
->raid_data
.inactive_list_mutex
);
5573 list_for_each_entry_safe(component_info
, pNext
,
5574 &ioc
->raid_data
.inactive_list
, list
) {
5575 list_del(&component_info
->list
);
5576 kfree(component_info
);
5578 mutex_unlock(&ioc
->raid_data
.inactive_list_mutex
);
5582 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5584 * @ioc : pointer to per adapter structure
5585 * @channel : volume channel
5586 * @id : volume target id
5589 mpt_inactive_raid_volumes(MPT_ADAPTER
*ioc
, u8 channel
, u8 id
)
5592 ConfigPageHeader_t hdr
;
5593 dma_addr_t dma_handle
;
5594 pRaidVolumePage0_t buffer
= NULL
;
5596 RaidPhysDiskPage0_t phys_disk
;
5597 struct inactive_raid_component_info
*component_info
;
5598 int handle_inactive_volumes
;
5600 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5601 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5602 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_VOLUME
;
5603 cfg
.pageAddr
= (channel
<< 8) + id
;
5604 cfg
.cfghdr
.hdr
= &hdr
;
5605 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5607 if (mpt_config(ioc
, &cfg
) != 0)
5610 if (!hdr
.PageLength
)
5613 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5619 cfg
.physAddr
= dma_handle
;
5620 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5622 if (mpt_config(ioc
, &cfg
) != 0)
5625 if (!buffer
->NumPhysDisks
)
5628 handle_inactive_volumes
=
5629 (buffer
->VolumeStatus
.Flags
& MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE
||
5630 (buffer
->VolumeStatus
.Flags
& MPI_RAIDVOL0_STATUS_FLAG_ENABLED
) == 0 ||
5631 buffer
->VolumeStatus
.State
== MPI_RAIDVOL0_STATUS_STATE_FAILED
||
5632 buffer
->VolumeStatus
.State
== MPI_RAIDVOL0_STATUS_STATE_MISSING
) ? 1 : 0;
5634 if (!handle_inactive_volumes
)
5637 mutex_lock(&ioc
->raid_data
.inactive_list_mutex
);
5638 for (i
= 0; i
< buffer
->NumPhysDisks
; i
++) {
5639 if(mpt_raid_phys_disk_pg0(ioc
,
5640 buffer
->PhysDisk
[i
].PhysDiskNum
, &phys_disk
) != 0)
5643 if ((component_info
= kmalloc(sizeof (*component_info
),
5644 GFP_KERNEL
)) == NULL
)
5647 component_info
->volumeID
= id
;
5648 component_info
->volumeBus
= channel
;
5649 component_info
->d
.PhysDiskNum
= phys_disk
.PhysDiskNum
;
5650 component_info
->d
.PhysDiskBus
= phys_disk
.PhysDiskBus
;
5651 component_info
->d
.PhysDiskID
= phys_disk
.PhysDiskID
;
5652 component_info
->d
.PhysDiskIOC
= phys_disk
.PhysDiskIOC
;
5654 list_add_tail(&component_info
->list
,
5655 &ioc
->raid_data
.inactive_list
);
5657 mutex_unlock(&ioc
->raid_data
.inactive_list_mutex
);
5661 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5666 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5667 * @ioc: Pointer to a Adapter Structure
5668 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5669 * @phys_disk: requested payload data returned
5673 * -EFAULT if read of config page header fails or data pointer not NULL
5674 * -ENOMEM if pci_alloc failed
5677 mpt_raid_phys_disk_pg0(MPT_ADAPTER
*ioc
, u8 phys_disk_num
,
5678 RaidPhysDiskPage0_t
*phys_disk
)
5681 ConfigPageHeader_t hdr
;
5682 dma_addr_t dma_handle
;
5683 pRaidPhysDiskPage0_t buffer
= NULL
;
5686 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5687 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5688 memset(phys_disk
, 0, sizeof(RaidPhysDiskPage0_t
));
5690 hdr
.PageVersion
= MPI_RAIDPHYSDISKPAGE0_PAGEVERSION
;
5691 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_PHYSDISK
;
5692 cfg
.cfghdr
.hdr
= &hdr
;
5694 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5696 if (mpt_config(ioc
, &cfg
) != 0) {
5701 if (!hdr
.PageLength
) {
5706 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5714 cfg
.physAddr
= dma_handle
;
5715 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5716 cfg
.pageAddr
= phys_disk_num
;
5718 if (mpt_config(ioc
, &cfg
) != 0) {
5724 memcpy(phys_disk
, buffer
, sizeof(*buffer
));
5725 phys_disk
->MaxLBA
= le32_to_cpu(buffer
->MaxLBA
);
5730 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5737 * mpt_raid_phys_disk_get_num_paths - returns number paths associated to this phys_num
5738 * @ioc: Pointer to a Adapter Structure
5739 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5742 * returns number paths
5745 mpt_raid_phys_disk_get_num_paths(MPT_ADAPTER
*ioc
, u8 phys_disk_num
)
5748 ConfigPageHeader_t hdr
;
5749 dma_addr_t dma_handle
;
5750 pRaidPhysDiskPage1_t buffer
= NULL
;
5753 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5754 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5756 hdr
.PageVersion
= MPI_RAIDPHYSDISKPAGE1_PAGEVERSION
;
5757 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_PHYSDISK
;
5759 cfg
.cfghdr
.hdr
= &hdr
;
5761 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5763 if (mpt_config(ioc
, &cfg
) != 0) {
5768 if (!hdr
.PageLength
) {
5773 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5781 cfg
.physAddr
= dma_handle
;
5782 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5783 cfg
.pageAddr
= phys_disk_num
;
5785 if (mpt_config(ioc
, &cfg
) != 0) {
5790 rc
= buffer
->NumPhysDiskPaths
;
5794 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5799 EXPORT_SYMBOL(mpt_raid_phys_disk_get_num_paths
);
5802 * mpt_raid_phys_disk_pg1 - returns phys disk page 1
5803 * @ioc: Pointer to a Adapter Structure
5804 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5805 * @phys_disk: requested payload data returned
5809 * -EFAULT if read of config page header fails or data pointer not NULL
5810 * -ENOMEM if pci_alloc failed
5813 mpt_raid_phys_disk_pg1(MPT_ADAPTER
*ioc
, u8 phys_disk_num
,
5814 RaidPhysDiskPage1_t
*phys_disk
)
5817 ConfigPageHeader_t hdr
;
5818 dma_addr_t dma_handle
;
5819 pRaidPhysDiskPage1_t buffer
= NULL
;
5824 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5825 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5828 hdr
.PageVersion
= MPI_RAIDPHYSDISKPAGE1_PAGEVERSION
;
5829 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_PHYSDISK
;
5831 cfg
.cfghdr
.hdr
= &hdr
;
5833 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5835 if (mpt_config(ioc
, &cfg
) != 0) {
5840 if (!hdr
.PageLength
) {
5845 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5853 cfg
.physAddr
= dma_handle
;
5854 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5855 cfg
.pageAddr
= phys_disk_num
;
5857 if (mpt_config(ioc
, &cfg
) != 0) {
5862 phys_disk
->NumPhysDiskPaths
= buffer
->NumPhysDiskPaths
;
5863 phys_disk
->PhysDiskNum
= phys_disk_num
;
5864 for (i
= 0; i
< phys_disk
->NumPhysDiskPaths
; i
++) {
5865 phys_disk
->Path
[i
].PhysDiskID
= buffer
->Path
[i
].PhysDiskID
;
5866 phys_disk
->Path
[i
].PhysDiskBus
= buffer
->Path
[i
].PhysDiskBus
;
5867 phys_disk
->Path
[i
].OwnerIdentifier
=
5868 buffer
->Path
[i
].OwnerIdentifier
;
5869 phys_disk
->Path
[i
].Flags
= le16_to_cpu(buffer
->Path
[i
].Flags
);
5870 memcpy(&sas_address
, &buffer
->Path
[i
].WWID
, sizeof(__le64
));
5871 sas_address
= le64_to_cpu(sas_address
);
5872 memcpy(&phys_disk
->Path
[i
].WWID
, &sas_address
, sizeof(__le64
));
5873 memcpy(&sas_address
,
5874 &buffer
->Path
[i
].OwnerWWID
, sizeof(__le64
));
5875 sas_address
= le64_to_cpu(sas_address
);
5876 memcpy(&phys_disk
->Path
[i
].OwnerWWID
,
5877 &sas_address
, sizeof(__le64
));
5883 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5888 EXPORT_SYMBOL(mpt_raid_phys_disk_pg1
);
5892 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5893 * @ioc: Pointer to a Adapter Strucutre
5897 * -EFAULT if read of config page header fails or data pointer not NULL
5898 * -ENOMEM if pci_alloc failed
5901 mpt_findImVolumes(MPT_ADAPTER
*ioc
)
5905 dma_addr_t ioc2_dma
;
5907 ConfigPageHeader_t header
;
5912 if (!ioc
->ir_firmware
)
5915 /* Free the old page
5917 kfree(ioc
->raid_data
.pIocPg2
);
5918 ioc
->raid_data
.pIocPg2
= NULL
;
5919 mpt_inactive_raid_list_free(ioc
);
5921 /* Read IOCP2 header then the page.
5923 header
.PageVersion
= 0;
5924 header
.PageLength
= 0;
5925 header
.PageNumber
= 2;
5926 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
5927 cfg
.cfghdr
.hdr
= &header
;
5930 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5933 if (mpt_config(ioc
, &cfg
) != 0)
5936 if (header
.PageLength
== 0)
5939 iocpage2sz
= header
.PageLength
* 4;
5940 pIoc2
= pci_alloc_consistent(ioc
->pcidev
, iocpage2sz
, &ioc2_dma
);
5944 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5945 cfg
.physAddr
= ioc2_dma
;
5946 if (mpt_config(ioc
, &cfg
) != 0)
5949 mem
= kmalloc(iocpage2sz
, GFP_KERNEL
);
5953 memcpy(mem
, (u8
*)pIoc2
, iocpage2sz
);
5954 ioc
->raid_data
.pIocPg2
= (IOCPage2_t
*) mem
;
5956 mpt_read_ioc_pg_3(ioc
);
5958 for (i
= 0; i
< pIoc2
->NumActiveVolumes
; i
++)
5959 mpt_inactive_raid_volumes(ioc
,
5960 pIoc2
->RaidVolume
[i
].VolumeBus
,
5961 pIoc2
->RaidVolume
[i
].VolumeID
);
5964 pci_free_consistent(ioc
->pcidev
, iocpage2sz
, pIoc2
, ioc2_dma
);
5970 mpt_read_ioc_pg_3(MPT_ADAPTER
*ioc
)
5975 ConfigPageHeader_t header
;
5976 dma_addr_t ioc3_dma
;
5979 /* Free the old page
5981 kfree(ioc
->raid_data
.pIocPg3
);
5982 ioc
->raid_data
.pIocPg3
= NULL
;
5984 /* There is at least one physical disk.
5985 * Read and save IOC Page 3
5987 header
.PageVersion
= 0;
5988 header
.PageLength
= 0;
5989 header
.PageNumber
= 3;
5990 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
5991 cfg
.cfghdr
.hdr
= &header
;
5994 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5997 if (mpt_config(ioc
, &cfg
) != 0)
6000 if (header
.PageLength
== 0)
6003 /* Read Header good, alloc memory
6005 iocpage3sz
= header
.PageLength
* 4;
6006 pIoc3
= pci_alloc_consistent(ioc
->pcidev
, iocpage3sz
, &ioc3_dma
);
6010 /* Read the Page and save the data
6011 * into malloc'd memory.
6013 cfg
.physAddr
= ioc3_dma
;
6014 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
6015 if (mpt_config(ioc
, &cfg
) == 0) {
6016 mem
= kmalloc(iocpage3sz
, GFP_KERNEL
);
6018 memcpy(mem
, (u8
*)pIoc3
, iocpage3sz
);
6019 ioc
->raid_data
.pIocPg3
= (IOCPage3_t
*) mem
;
6023 pci_free_consistent(ioc
->pcidev
, iocpage3sz
, pIoc3
, ioc3_dma
);
6029 mpt_read_ioc_pg_4(MPT_ADAPTER
*ioc
)
6033 ConfigPageHeader_t header
;
6034 dma_addr_t ioc4_dma
;
6037 /* Read and save IOC Page 4
6039 header
.PageVersion
= 0;
6040 header
.PageLength
= 0;
6041 header
.PageNumber
= 4;
6042 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
6043 cfg
.cfghdr
.hdr
= &header
;
6046 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
6049 if (mpt_config(ioc
, &cfg
) != 0)
6052 if (header
.PageLength
== 0)
6055 if ( (pIoc4
= ioc
->spi_data
.pIocPg4
) == NULL
) {
6056 iocpage4sz
= (header
.PageLength
+ 4) * 4; /* Allow 4 additional SEP's */
6057 pIoc4
= pci_alloc_consistent(ioc
->pcidev
, iocpage4sz
, &ioc4_dma
);
6060 ioc
->alloc_total
+= iocpage4sz
;
6062 ioc4_dma
= ioc
->spi_data
.IocPg4_dma
;
6063 iocpage4sz
= ioc
->spi_data
.IocPg4Sz
;
6066 /* Read the Page into dma memory.
6068 cfg
.physAddr
= ioc4_dma
;
6069 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
6070 if (mpt_config(ioc
, &cfg
) == 0) {
6071 ioc
->spi_data
.pIocPg4
= (IOCPage4_t
*) pIoc4
;
6072 ioc
->spi_data
.IocPg4_dma
= ioc4_dma
;
6073 ioc
->spi_data
.IocPg4Sz
= iocpage4sz
;
6075 pci_free_consistent(ioc
->pcidev
, iocpage4sz
, pIoc4
, ioc4_dma
);
6076 ioc
->spi_data
.pIocPg4
= NULL
;
6077 ioc
->alloc_total
-= iocpage4sz
;
6082 mpt_read_ioc_pg_1(MPT_ADAPTER
*ioc
)
6086 ConfigPageHeader_t header
;
6087 dma_addr_t ioc1_dma
;
6091 /* Check the Coalescing Timeout in IOC Page 1
6093 header
.PageVersion
= 0;
6094 header
.PageLength
= 0;
6095 header
.PageNumber
= 1;
6096 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
6097 cfg
.cfghdr
.hdr
= &header
;
6100 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
6103 if (mpt_config(ioc
, &cfg
) != 0)
6106 if (header
.PageLength
== 0)
6109 /* Read Header good, alloc memory
6111 iocpage1sz
= header
.PageLength
* 4;
6112 pIoc1
= pci_alloc_consistent(ioc
->pcidev
, iocpage1sz
, &ioc1_dma
);
6116 /* Read the Page and check coalescing timeout
6118 cfg
.physAddr
= ioc1_dma
;
6119 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
6120 if (mpt_config(ioc
, &cfg
) == 0) {
6122 tmp
= le32_to_cpu(pIoc1
->Flags
) & MPI_IOCPAGE1_REPLY_COALESCING
;
6123 if (tmp
== MPI_IOCPAGE1_REPLY_COALESCING
) {
6124 tmp
= le32_to_cpu(pIoc1
->CoalescingTimeout
);
6126 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Coalescing Enabled Timeout = %d\n",
6129 if (tmp
> MPT_COALESCING_TIMEOUT
) {
6130 pIoc1
->CoalescingTimeout
= cpu_to_le32(MPT_COALESCING_TIMEOUT
);
6132 /* Write NVRAM and current
6135 cfg
.action
= MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT
;
6136 if (mpt_config(ioc
, &cfg
) == 0) {
6137 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Reset Current Coalescing Timeout to = %d\n",
6138 ioc
->name
, MPT_COALESCING_TIMEOUT
));
6140 cfg
.action
= MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM
;
6141 if (mpt_config(ioc
, &cfg
) == 0) {
6142 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6143 "Reset NVRAM Coalescing Timeout to = %d\n",
6144 ioc
->name
, MPT_COALESCING_TIMEOUT
));
6146 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6147 "Reset NVRAM Coalescing Timeout Failed\n",
6152 dprintk(ioc
, printk(MYIOC_s_WARN_FMT
6153 "Reset of Current Coalescing Timeout Failed!\n",
6159 dprintk(ioc
, printk(MYIOC_s_WARN_FMT
"Coalescing Disabled\n", ioc
->name
));
6163 pci_free_consistent(ioc
->pcidev
, iocpage1sz
, pIoc1
, ioc1_dma
);
6169 mpt_get_manufacturing_pg_0(MPT_ADAPTER
*ioc
)
6172 ConfigPageHeader_t hdr
;
6174 ManufacturingPage0_t
*pbuf
= NULL
;
6176 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
6177 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
6179 hdr
.PageType
= MPI_CONFIG_PAGETYPE_MANUFACTURING
;
6180 cfg
.cfghdr
.hdr
= &hdr
;
6182 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
6185 if (mpt_config(ioc
, &cfg
) != 0)
6188 if (!cfg
.cfghdr
.hdr
->PageLength
)
6191 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
6192 pbuf
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, &buf_dma
);
6196 cfg
.physAddr
= buf_dma
;
6198 if (mpt_config(ioc
, &cfg
) != 0)
6201 memcpy(ioc
->board_name
, pbuf
->BoardName
, sizeof(ioc
->board_name
));
6202 memcpy(ioc
->board_assembly
, pbuf
->BoardAssembly
, sizeof(ioc
->board_assembly
));
6203 memcpy(ioc
->board_tracer
, pbuf
->BoardTracerNumber
, sizeof(ioc
->board_tracer
));
6208 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, pbuf
, buf_dma
);
6211 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6213 * SendEventNotification - Send EventNotification (on or off) request to adapter
6214 * @ioc: Pointer to MPT_ADAPTER structure
6215 * @EvSwitch: Event switch flags
6216 * @sleepFlag: Specifies whether the process can sleep
6219 SendEventNotification(MPT_ADAPTER
*ioc
, u8 EvSwitch
, int sleepFlag
)
6221 EventNotification_t evn
;
6222 MPIDefaultReply_t reply_buf
;
6224 memset(&evn
, 0, sizeof(EventNotification_t
));
6225 memset(&reply_buf
, 0, sizeof(MPIDefaultReply_t
));
6227 evn
.Function
= MPI_FUNCTION_EVENT_NOTIFICATION
;
6228 evn
.Switch
= EvSwitch
;
6229 evn
.MsgContext
= cpu_to_le32(mpt_base_index
<< 16);
6231 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6232 "Sending EventNotification (%d) request %p\n",
6233 ioc
->name
, EvSwitch
, &evn
));
6235 return mpt_handshake_req_reply_wait(ioc
, sizeof(EventNotification_t
),
6236 (u32
*)&evn
, sizeof(MPIDefaultReply_t
), (u16
*)&reply_buf
, 30,
6240 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6242 * SendEventAck - Send EventAck request to MPT adapter.
6243 * @ioc: Pointer to MPT_ADAPTER structure
6244 * @evnp: Pointer to original EventNotification request
6247 SendEventAck(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*evnp
)
6251 if ((pAck
= (EventAck_t
*) mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
6252 dfailprintk(ioc
, printk(MYIOC_s_WARN_FMT
"%s, no msg frames!!\n",
6253 ioc
->name
, __func__
));
6257 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending EventAck\n", ioc
->name
));
6259 pAck
->Function
= MPI_FUNCTION_EVENT_ACK
;
6260 pAck
->ChainOffset
= 0;
6261 pAck
->Reserved
[0] = pAck
->Reserved
[1] = 0;
6263 pAck
->Reserved1
[0] = pAck
->Reserved1
[1] = pAck
->Reserved1
[2] = 0;
6264 pAck
->Event
= evnp
->Event
;
6265 pAck
->EventContext
= evnp
->EventContext
;
6267 mpt_put_msg_frame(mpt_base_index
, ioc
, (MPT_FRAME_HDR
*)pAck
);
6272 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6274 * mpt_config - Generic function to issue config message
6275 * @ioc: Pointer to an adapter structure
6276 * @pCfg: Pointer to a configuration structure. Struct contains
6277 * action, page address, direction, physical address
6278 * and pointer to a configuration page header
6279 * Page header is updated.
6281 * Returns 0 for success
6282 * -EPERM if not allowed due to ISR context
6283 * -EAGAIN if no msg frames currently available
6284 * -EFAULT for non-successful reply or no reply (timeout)
6287 mpt_config(MPT_ADAPTER
*ioc
, CONFIGPARMS
*pCfg
)
6290 ConfigReply_t
*pReply
;
6291 ConfigExtendedPageHeader_t
*pExtHdr
= NULL
;
6297 u8 page_type
= 0, extend_page
;
6298 unsigned long timeleft
;
6299 unsigned long flags
;
6301 u8 issue_hard_reset
= 0;
6304 /* Prevent calling wait_event() (below), if caller happens
6305 * to be in ISR context, because that is fatal!
6307 in_isr
= in_interrupt();
6309 dcprintk(ioc
, printk(MYIOC_s_WARN_FMT
"Config request not allowed in ISR context!\n",
6314 /* don't send a config page during diag reset */
6315 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
6316 if (ioc
->ioc_reset_in_progress
) {
6317 dfailprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6318 "%s: busy with host reset\n", ioc
->name
, __func__
));
6319 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6322 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6324 /* don't send if no chance of success */
6326 mpt_GetIocState(ioc
, 1) != MPI_IOC_STATE_OPERATIONAL
) {
6327 dfailprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6328 "%s: ioc not operational, %d, %xh\n",
6329 ioc
->name
, __func__
, ioc
->active
,
6330 mpt_GetIocState(ioc
, 0)));
6335 mutex_lock(&ioc
->mptbase_cmds
.mutex
);
6336 /* init the internal cmd struct */
6337 memset(ioc
->mptbase_cmds
.reply
, 0 , MPT_DEFAULT_FRAME_SIZE
);
6338 INITIALIZE_MGMT_STATUS(ioc
->mptbase_cmds
.status
)
6340 /* Get and Populate a free Frame
6342 if ((mf
= mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
6343 dcprintk(ioc
, printk(MYIOC_s_WARN_FMT
6344 "mpt_config: no msg frames!\n", ioc
->name
));
6349 pReq
= (Config_t
*)mf
;
6350 pReq
->Action
= pCfg
->action
;
6352 pReq
->ChainOffset
= 0;
6353 pReq
->Function
= MPI_FUNCTION_CONFIG
;
6355 /* Assume page type is not extended and clear "reserved" fields. */
6356 pReq
->ExtPageLength
= 0;
6357 pReq
->ExtPageType
= 0;
6360 for (ii
=0; ii
< 8; ii
++)
6361 pReq
->Reserved2
[ii
] = 0;
6363 pReq
->Header
.PageVersion
= pCfg
->cfghdr
.hdr
->PageVersion
;
6364 pReq
->Header
.PageLength
= pCfg
->cfghdr
.hdr
->PageLength
;
6365 pReq
->Header
.PageNumber
= pCfg
->cfghdr
.hdr
->PageNumber
;
6366 pReq
->Header
.PageType
= (pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
);
6368 if ((pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
) == MPI_CONFIG_PAGETYPE_EXTENDED
) {
6369 pExtHdr
= (ConfigExtendedPageHeader_t
*)pCfg
->cfghdr
.ehdr
;
6370 pReq
->ExtPageLength
= cpu_to_le16(pExtHdr
->ExtPageLength
);
6371 pReq
->ExtPageType
= pExtHdr
->ExtPageType
;
6372 pReq
->Header
.PageType
= MPI_CONFIG_PAGETYPE_EXTENDED
;
6374 /* Page Length must be treated as a reserved field for the
6377 pReq
->Header
.PageLength
= 0;
6380 pReq
->PageAddress
= cpu_to_le32(pCfg
->pageAddr
);
6382 /* Add a SGE to the config request.
6385 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_WRITE
;
6387 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_READ
;
6389 if ((pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
) ==
6390 MPI_CONFIG_PAGETYPE_EXTENDED
) {
6391 flagsLength
|= pExtHdr
->ExtPageLength
* 4;
6392 page_type
= pReq
->ExtPageType
;
6395 flagsLength
|= pCfg
->cfghdr
.hdr
->PageLength
* 4;
6396 page_type
= pReq
->Header
.PageType
;
6400 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6401 "Sending Config request type 0x%x, page 0x%x and action %d\n",
6402 ioc
->name
, page_type
, pReq
->Header
.PageNumber
, pReq
->Action
));
6404 ioc
->add_sge((char *)&pReq
->PageBufferSGE
, flagsLength
, pCfg
->physAddr
);
6405 timeout
= (pCfg
->timeout
< 15) ? HZ
*15 : HZ
*pCfg
->timeout
;
6406 mpt_put_msg_frame(mpt_base_index
, ioc
, mf
);
6407 timeleft
= wait_for_completion_timeout(&ioc
->mptbase_cmds
.done
,
6409 if (!(ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_COMMAND_GOOD
)) {
6411 dfailprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6412 "Failed Sending Config request type 0x%x, page 0x%x,"
6413 " action %d, status %xh, time left %ld\n\n",
6414 ioc
->name
, page_type
, pReq
->Header
.PageNumber
,
6415 pReq
->Action
, ioc
->mptbase_cmds
.status
, timeleft
));
6416 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_DID_IOCRESET
)
6419 issue_hard_reset
= 1;
6423 if (!(ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_RF_VALID
)) {
6427 pReply
= (ConfigReply_t
*)ioc
->mptbase_cmds
.reply
;
6428 ret
= le16_to_cpu(pReply
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
6429 if (ret
== MPI_IOCSTATUS_SUCCESS
) {
6431 pCfg
->cfghdr
.ehdr
->ExtPageLength
=
6432 le16_to_cpu(pReply
->ExtPageLength
);
6433 pCfg
->cfghdr
.ehdr
->ExtPageType
=
6434 pReply
->ExtPageType
;
6436 pCfg
->cfghdr
.hdr
->PageVersion
= pReply
->Header
.PageVersion
;
6437 pCfg
->cfghdr
.hdr
->PageLength
= pReply
->Header
.PageLength
;
6438 pCfg
->cfghdr
.hdr
->PageNumber
= pReply
->Header
.PageNumber
;
6439 pCfg
->cfghdr
.hdr
->PageType
= pReply
->Header
.PageType
;
6444 printk(MYIOC_s_INFO_FMT
"Retry completed "
6445 "ret=0x%x timeleft=%ld\n",
6446 ioc
->name
, ret
, timeleft
);
6448 dcprintk(ioc
, printk(KERN_DEBUG
"IOCStatus=%04xh, IOCLogInfo=%08xh\n",
6449 ret
, le32_to_cpu(pReply
->IOCLogInfo
)));
6453 CLEAR_MGMT_STATUS(ioc
->mptbase_cmds
.status
)
6454 mutex_unlock(&ioc
->mptbase_cmds
.mutex
);
6455 if (issue_hard_reset
) {
6456 issue_hard_reset
= 0;
6457 printk(MYIOC_s_WARN_FMT
"Issuing Reset from %s!!\n",
6458 ioc
->name
, __func__
);
6459 if (retry_count
== 0) {
6460 if (mpt_Soft_Hard_ResetHandler(ioc
, CAN_SLEEP
) != 0)
6463 mpt_HardResetHandler(ioc
, CAN_SLEEP
);
6465 mpt_free_msg_frame(ioc
, mf
);
6466 /* attempt one retry for a timed out command */
6467 if (retry_count
< 2) {
6468 printk(MYIOC_s_INFO_FMT
6469 "Attempting Retry Config request"
6470 " type 0x%x, page 0x%x,"
6471 " action %d\n", ioc
->name
, page_type
,
6472 pCfg
->cfghdr
.hdr
->PageNumber
, pCfg
->action
);
6481 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6483 * mpt_ioc_reset - Base cleanup for hard reset
6484 * @ioc: Pointer to the adapter structure
6485 * @reset_phase: Indicates pre- or post-reset functionality
6487 * Remark: Frees resources with internally generated commands.
6490 mpt_ioc_reset(MPT_ADAPTER
*ioc
, int reset_phase
)
6492 switch (reset_phase
) {
6493 case MPT_IOC_SETUP_RESET
:
6494 ioc
->taskmgmt_quiesce_io
= 1;
6495 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6496 "%s: MPT_IOC_SETUP_RESET\n", ioc
->name
, __func__
));
6498 case MPT_IOC_PRE_RESET
:
6499 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6500 "%s: MPT_IOC_PRE_RESET\n", ioc
->name
, __func__
));
6502 case MPT_IOC_POST_RESET
:
6503 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6504 "%s: MPT_IOC_POST_RESET\n", ioc
->name
, __func__
));
6505 /* wake up mptbase_cmds */
6506 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_PENDING
) {
6507 ioc
->mptbase_cmds
.status
|=
6508 MPT_MGMT_STATUS_DID_IOCRESET
;
6509 complete(&ioc
->mptbase_cmds
.done
);
6511 /* wake up taskmgmt_cmds */
6512 if (ioc
->taskmgmt_cmds
.status
& MPT_MGMT_STATUS_PENDING
) {
6513 ioc
->taskmgmt_cmds
.status
|=
6514 MPT_MGMT_STATUS_DID_IOCRESET
;
6515 complete(&ioc
->taskmgmt_cmds
.done
);
6522 return 1; /* currently means nothing really */
6526 #ifdef CONFIG_PROC_FS /* { */
6527 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6529 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
6531 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6533 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
6535 * Returns 0 for success, non-zero for failure.
6538 procmpt_create(void)
6540 struct proc_dir_entry
*ent
;
6542 mpt_proc_root_dir
= proc_mkdir(MPT_PROCFS_MPTBASEDIR
, NULL
);
6543 if (mpt_proc_root_dir
== NULL
)
6546 ent
= create_proc_entry("summary", S_IFREG
|S_IRUGO
, mpt_proc_root_dir
);
6548 ent
->read_proc
= procmpt_summary_read
;
6550 ent
= create_proc_entry("version", S_IFREG
|S_IRUGO
, mpt_proc_root_dir
);
6552 ent
->read_proc
= procmpt_version_read
;
6557 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6559 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
6561 * Returns 0 for success, non-zero for failure.
6564 procmpt_destroy(void)
6566 remove_proc_entry("version", mpt_proc_root_dir
);
6567 remove_proc_entry("summary", mpt_proc_root_dir
);
6568 remove_proc_entry(MPT_PROCFS_MPTBASEDIR
, NULL
);
6571 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6573 * procmpt_summary_read - Handle read request of a summary file
6574 * @buf: Pointer to area to write information
6575 * @start: Pointer to start pointer
6576 * @offset: Offset to start writing
6577 * @request: Amount of read data requested
6578 * @eof: Pointer to EOF integer
6581 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
6582 * Returns number of characters written to process performing the read.
6585 procmpt_summary_read(char *buf
, char **start
, off_t offset
, int request
, int *eof
, void *data
)
6595 mpt_print_ioc_summary(ioc
, out
, &more
, 0, 1);
6599 list_for_each_entry(ioc
, &ioc_list
, list
) {
6602 mpt_print_ioc_summary(ioc
, out
, &more
, 0, 1);
6605 if ((out
-buf
) >= request
)
6612 MPT_PROC_READ_RETURN(buf
,start
,offset
,request
,eof
,len
);
6615 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6617 * procmpt_version_read - Handle read request from /proc/mpt/version.
6618 * @buf: Pointer to area to write information
6619 * @start: Pointer to start pointer
6620 * @offset: Offset to start writing
6621 * @request: Amount of read data requested
6622 * @eof: Pointer to EOF integer
6625 * Returns number of characters written to process performing the read.
6628 procmpt_version_read(char *buf
, char **start
, off_t offset
, int request
, int *eof
, void *data
)
6631 int scsi
, fc
, sas
, lan
, ctl
, targ
, dmp
;
6635 len
= sprintf(buf
, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON
);
6636 len
+= sprintf(buf
+len
, " Fusion MPT base driver\n");
6638 scsi
= fc
= sas
= lan
= ctl
= targ
= dmp
= 0;
6639 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
6641 if (MptCallbacks
[cb_idx
]) {
6642 switch (MptDriverClass
[cb_idx
]) {
6644 if (!scsi
++) drvname
= "SPI host";
6647 if (!fc
++) drvname
= "FC host";
6650 if (!sas
++) drvname
= "SAS host";
6653 if (!lan
++) drvname
= "LAN";
6656 if (!targ
++) drvname
= "SCSI target";
6659 if (!ctl
++) drvname
= "ioctl";
6664 len
+= sprintf(buf
+len
, " Fusion MPT %s driver\n", drvname
);
6668 MPT_PROC_READ_RETURN(buf
,start
,offset
,request
,eof
,len
);
6671 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6673 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
6674 * @buf: Pointer to area to write information
6675 * @start: Pointer to start pointer
6676 * @offset: Offset to start writing
6677 * @request: Amount of read data requested
6678 * @eof: Pointer to EOF integer
6681 * Returns number of characters written to process performing the read.
6684 procmpt_iocinfo_read(char *buf
, char **start
, off_t offset
, int request
, int *eof
, void *data
)
6686 MPT_ADAPTER
*ioc
= data
;
6692 mpt_get_fw_exp_ver(expVer
, ioc
);
6694 len
= sprintf(buf
, "%s:", ioc
->name
);
6695 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)
6696 len
+= sprintf(buf
+len
, " (f/w download boot flag set)");
6697 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6698 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
6700 len
+= sprintf(buf
+len
, "\n ProductID = 0x%04x (%s)\n",
6701 ioc
->facts
.ProductID
,
6703 len
+= sprintf(buf
+len
, " FWVersion = 0x%08x%s", ioc
->facts
.FWVersion
.Word
, expVer
);
6704 if (ioc
->facts
.FWImageSize
)
6705 len
+= sprintf(buf
+len
, " (fw_size=%d)", ioc
->facts
.FWImageSize
);
6706 len
+= sprintf(buf
+len
, "\n MsgVersion = 0x%04x\n", ioc
->facts
.MsgVersion
);
6707 len
+= sprintf(buf
+len
, " FirstWhoInit = 0x%02x\n", ioc
->FirstWhoInit
);
6708 len
+= sprintf(buf
+len
, " EventState = 0x%02x\n", ioc
->facts
.EventState
);
6710 len
+= sprintf(buf
+len
, " CurrentHostMfaHighAddr = 0x%08x\n",
6711 ioc
->facts
.CurrentHostMfaHighAddr
);
6712 len
+= sprintf(buf
+len
, " CurrentSenseBufferHighAddr = 0x%08x\n",
6713 ioc
->facts
.CurrentSenseBufferHighAddr
);
6715 len
+= sprintf(buf
+len
, " MaxChainDepth = 0x%02x frames\n", ioc
->facts
.MaxChainDepth
);
6716 len
+= sprintf(buf
+len
, " MinBlockSize = 0x%02x bytes\n", 4*ioc
->facts
.BlockSize
);
6718 len
+= sprintf(buf
+len
, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6719 (void *)ioc
->req_frames
, (void *)(ulong
)ioc
->req_frames_dma
);
6721 * Rounding UP to nearest 4-kB boundary here...
6723 sz
= (ioc
->req_sz
* ioc
->req_depth
) + 128;
6724 sz
= ((sz
+ 0x1000UL
- 1UL) / 0x1000) * 0x1000;
6725 len
+= sprintf(buf
+len
, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6726 ioc
->req_sz
, ioc
->req_depth
, ioc
->req_sz
*ioc
->req_depth
, sz
);
6727 len
+= sprintf(buf
+len
, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
6728 4*ioc
->facts
.RequestFrameSize
,
6729 ioc
->facts
.GlobalCredits
);
6731 len
+= sprintf(buf
+len
, " Frames @ 0x%p (Dma @ 0x%p)\n",
6732 (void *)ioc
->alloc
, (void *)(ulong
)ioc
->alloc_dma
);
6733 sz
= (ioc
->reply_sz
* ioc
->reply_depth
) + 128;
6734 len
+= sprintf(buf
+len
, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6735 ioc
->reply_sz
, ioc
->reply_depth
, ioc
->reply_sz
*ioc
->reply_depth
, sz
);
6736 len
+= sprintf(buf
+len
, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
6737 ioc
->facts
.CurReplyFrameSize
,
6738 ioc
->facts
.ReplyQueueDepth
);
6740 len
+= sprintf(buf
+len
, " MaxDevices = %d\n",
6741 (ioc
->facts
.MaxDevices
==0) ? 255 : ioc
->facts
.MaxDevices
);
6742 len
+= sprintf(buf
+len
, " MaxBuses = %d\n", ioc
->facts
.MaxBuses
);
6745 for (p
=0; p
< ioc
->facts
.NumberOfPorts
; p
++) {
6746 len
+= sprintf(buf
+len
, " PortNumber = %d (of %d)\n",
6748 ioc
->facts
.NumberOfPorts
);
6749 if (ioc
->bus_type
== FC
) {
6750 if (ioc
->pfacts
[p
].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
) {
6751 u8
*a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
6752 len
+= sprintf(buf
+len
, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6753 a
[5], a
[4], a
[3], a
[2], a
[1], a
[0]);
6755 len
+= sprintf(buf
+len
, " WWN = %08X%08X:%08X%08X\n",
6756 ioc
->fc_port_page0
[p
].WWNN
.High
,
6757 ioc
->fc_port_page0
[p
].WWNN
.Low
,
6758 ioc
->fc_port_page0
[p
].WWPN
.High
,
6759 ioc
->fc_port_page0
[p
].WWPN
.Low
);
6763 MPT_PROC_READ_RETURN(buf
,start
,offset
,request
,eof
,len
);
6766 #endif /* CONFIG_PROC_FS } */
6768 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6770 mpt_get_fw_exp_ver(char *buf
, MPT_ADAPTER
*ioc
)
6773 if ((ioc
->facts
.FWVersion
.Word
>> 24) == 0x0E) {
6774 sprintf(buf
, " (Exp %02d%02d)",
6775 (ioc
->facts
.FWVersion
.Word
>> 16) & 0x00FF, /* Month */
6776 (ioc
->facts
.FWVersion
.Word
>> 8) & 0x1F); /* Day */
6779 if ((ioc
->facts
.FWVersion
.Word
>> 8) & 0x80)
6780 strcat(buf
, " [MDBG]");
6784 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6786 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6787 * @ioc: Pointer to MPT_ADAPTER structure
6788 * @buffer: Pointer to buffer where IOC summary info should be written
6789 * @size: Pointer to number of bytes we wrote (set by this routine)
6790 * @len: Offset at which to start writing in buffer
6791 * @showlan: Display LAN stuff?
6793 * This routine writes (english readable) ASCII text, which represents
6794 * a summary of IOC information, to a buffer.
6797 mpt_print_ioc_summary(MPT_ADAPTER
*ioc
, char *buffer
, int *size
, int len
, int showlan
)
6802 mpt_get_fw_exp_ver(expVer
, ioc
);
6805 * Shorter summary of attached ioc's...
6807 y
= sprintf(buffer
+len
, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6810 MPT_FW_REV_MAGIC_ID_STRING
, /* "FwRev=" or somesuch */
6811 ioc
->facts
.FWVersion
.Word
,
6813 ioc
->facts
.NumberOfPorts
,
6816 if (showlan
&& (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
)) {
6817 u8
*a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
6818 y
+= sprintf(buffer
+len
+y
, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6819 a
[5], a
[4], a
[3], a
[2], a
[1], a
[0]);
6822 y
+= sprintf(buffer
+len
+y
, ", IRQ=%d", ioc
->pci_irq
);
6825 y
+= sprintf(buffer
+len
+y
, " (disabled)");
6827 y
+= sprintf(buffer
+len
+y
, "\n");
6832 * mpt_set_taskmgmt_in_progress_flag - set flags associated with task management
6833 * @ioc: Pointer to MPT_ADAPTER structure
6835 * Returns 0 for SUCCESS or -1 if FAILED.
6837 * If -1 is return, then it was not possible to set the flags
6840 mpt_set_taskmgmt_in_progress_flag(MPT_ADAPTER
*ioc
)
6842 unsigned long flags
;
6845 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
6846 if (ioc
->ioc_reset_in_progress
|| ioc
->taskmgmt_in_progress
||
6847 (ioc
->alt_ioc
&& ioc
->alt_ioc
->taskmgmt_in_progress
)) {
6852 ioc
->taskmgmt_in_progress
= 1;
6853 ioc
->taskmgmt_quiesce_io
= 1;
6855 ioc
->alt_ioc
->taskmgmt_in_progress
= 1;
6856 ioc
->alt_ioc
->taskmgmt_quiesce_io
= 1;
6859 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6862 EXPORT_SYMBOL(mpt_set_taskmgmt_in_progress_flag
);
6865 * mpt_clear_taskmgmt_in_progress_flag - clear flags associated with task management
6866 * @ioc: Pointer to MPT_ADAPTER structure
6870 mpt_clear_taskmgmt_in_progress_flag(MPT_ADAPTER
*ioc
)
6872 unsigned long flags
;
6874 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
6875 ioc
->taskmgmt_in_progress
= 0;
6876 ioc
->taskmgmt_quiesce_io
= 0;
6878 ioc
->alt_ioc
->taskmgmt_in_progress
= 0;
6879 ioc
->alt_ioc
->taskmgmt_quiesce_io
= 0;
6881 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6883 EXPORT_SYMBOL(mpt_clear_taskmgmt_in_progress_flag
);
6887 * mpt_halt_firmware - Halts the firmware if it is operational and panic
6889 * @ioc: Pointer to MPT_ADAPTER structure
6893 mpt_halt_firmware(MPT_ADAPTER
*ioc
)
6897 ioc_raw_state
= mpt_GetIocState(ioc
, 0);
6899 if ((ioc_raw_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_FAULT
) {
6900 printk(MYIOC_s_ERR_FMT
"IOC is in FAULT state (%04xh)!!!\n",
6901 ioc
->name
, ioc_raw_state
& MPI_DOORBELL_DATA_MASK
);
6902 panic("%s: IOC Fault (%04xh)!!!\n", ioc
->name
,
6903 ioc_raw_state
& MPI_DOORBELL_DATA_MASK
);
6905 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, 0xC0FFEE00);
6906 panic("%s: Firmware is halted due to command timeout\n",
6910 EXPORT_SYMBOL(mpt_halt_firmware
);
6913 * mpt_SoftResetHandler - Issues a less expensive reset
6914 * @ioc: Pointer to MPT_ADAPTER structure
6915 * @sleepFlag: Indicates if sleep or schedule must be called.
6918 * Returns 0 for SUCCESS or -1 if FAILED.
6920 * Message Unit Reset - instructs the IOC to reset the Reply Post and
6921 * Free FIFO's. All the Message Frames on Reply Free FIFO are discarded.
6922 * All posted buffers are freed, and event notification is turned off.
6923 * IOC doesnt reply to any outstanding request. This will transfer IOC
6927 mpt_SoftResetHandler(MPT_ADAPTER
*ioc
, int sleepFlag
)
6932 unsigned long flags
;
6934 unsigned long time_count
;
6936 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SoftResetHandler Entered!\n",
6939 ioc_state
= mpt_GetIocState(ioc
, 0) & MPI_IOC_STATE_MASK
;
6941 if (mpt_fwfault_debug
)
6942 mpt_halt_firmware(ioc
);
6944 if (ioc_state
== MPI_IOC_STATE_FAULT
||
6945 ioc_state
== MPI_IOC_STATE_RESET
) {
6946 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6947 "skipping, either in FAULT or RESET state!\n", ioc
->name
));
6951 if (ioc
->bus_type
== FC
) {
6952 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6953 "skipping, because the bus type is FC!\n", ioc
->name
));
6957 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
6958 if (ioc
->ioc_reset_in_progress
) {
6959 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6962 ioc
->ioc_reset_in_progress
= 1;
6963 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6967 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
6968 if (MptResetHandlers
[cb_idx
])
6969 mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_SETUP_RESET
);
6972 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
6973 if (ioc
->taskmgmt_in_progress
) {
6974 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6977 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6978 /* Disable reply interrupts (also blocks FreeQ) */
6979 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
6981 time_count
= jiffies
;
6983 rc
= SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
);
6985 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
6986 if (MptResetHandlers
[cb_idx
])
6987 mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_PRE_RESET
);
6993 ioc_state
= mpt_GetIocState(ioc
, 0) & MPI_IOC_STATE_MASK
;
6994 if (ioc_state
!= MPI_IOC_STATE_READY
)
6997 for (ii
= 0; ii
< 5; ii
++) {
6998 /* Get IOC facts! Allow 5 retries */
6999 rc
= GetIocFacts(ioc
, sleepFlag
,
7000 MPT_HOSTEVENT_IOC_RECOVER
);
7003 if (sleepFlag
== CAN_SLEEP
)
7011 rc
= PrimeIocFifos(ioc
);
7015 rc
= SendIocInit(ioc
, sleepFlag
);
7019 rc
= SendEventNotification(ioc
, 1, sleepFlag
);
7023 if (ioc
->hard_resets
< -1)
7027 * At this point, we know soft reset succeeded.
7031 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, MPI_HIM_DIM
);
7034 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
7035 ioc
->ioc_reset_in_progress
= 0;
7036 ioc
->taskmgmt_quiesce_io
= 0;
7037 ioc
->taskmgmt_in_progress
= 0;
7038 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
7040 if (ioc
->active
) { /* otherwise, hard reset coming */
7041 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
7042 if (MptResetHandlers
[cb_idx
])
7043 mpt_signal_reset(cb_idx
, ioc
,
7044 MPT_IOC_POST_RESET
);
7048 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
7049 "SoftResetHandler: completed (%d seconds): %s\n",
7050 ioc
->name
, jiffies_to_msecs(jiffies
- time_count
)/1000,
7051 ((rc
== 0) ? "SUCCESS" : "FAILED")));
7057 * mpt_Soft_Hard_ResetHandler - Try less expensive reset
7058 * @ioc: Pointer to MPT_ADAPTER structure
7059 * @sleepFlag: Indicates if sleep or schedule must be called.
7062 * Returns 0 for SUCCESS or -1 if FAILED.
7063 * Try for softreset first, only if it fails go for expensive
7067 mpt_Soft_Hard_ResetHandler(MPT_ADAPTER
*ioc
, int sleepFlag
) {
7070 ret
= mpt_SoftResetHandler(ioc
, sleepFlag
);
7073 ret
= mpt_HardResetHandler(ioc
, sleepFlag
);
7076 EXPORT_SYMBOL(mpt_Soft_Hard_ResetHandler
);
7078 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7082 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7084 * mpt_HardResetHandler - Generic reset handler
7085 * @ioc: Pointer to MPT_ADAPTER structure
7086 * @sleepFlag: Indicates if sleep or schedule must be called.
7088 * Issues SCSI Task Management call based on input arg values.
7089 * If TaskMgmt fails, returns associated SCSI request.
7091 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
7092 * or a non-interrupt thread. In the former, must not call schedule().
7094 * Note: A return of -1 is a FATAL error case, as it means a
7095 * FW reload/initialization failed.
7097 * Returns 0 for SUCCESS or -1 if FAILED.
7100 mpt_HardResetHandler(MPT_ADAPTER
*ioc
, int sleepFlag
)
7104 unsigned long flags
;
7105 unsigned long time_count
;
7107 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HardResetHandler Entered!\n", ioc
->name
));
7109 printk(MYIOC_s_INFO_FMT
"HardResetHandler Entered!\n", ioc
->name
);
7110 printk("MF count 0x%x !\n", ioc
->mfcnt
);
7112 if (mpt_fwfault_debug
)
7113 mpt_halt_firmware(ioc
);
7115 /* Reset the adapter. Prevent more than 1 call to
7116 * mpt_do_ioc_recovery at any instant in time.
7118 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
7119 if (ioc
->ioc_reset_in_progress
) {
7120 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
7123 ioc
->ioc_reset_in_progress
= 1;
7125 ioc
->alt_ioc
->ioc_reset_in_progress
= 1;
7126 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
7129 /* The SCSI driver needs to adjust timeouts on all current
7130 * commands prior to the diagnostic reset being issued.
7131 * Prevents timeouts occurring during a diagnostic reset...very bad.
7132 * For all other protocol drivers, this is a no-op.
7134 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
7135 if (MptResetHandlers
[cb_idx
]) {
7136 mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_SETUP_RESET
);
7138 mpt_signal_reset(cb_idx
, ioc
->alt_ioc
,
7139 MPT_IOC_SETUP_RESET
);
7143 time_count
= jiffies
;
7144 rc
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_RECOVER
, sleepFlag
);
7146 printk(KERN_WARNING MYNAM
7147 ": WARNING - (%d) Cannot recover %s\n", rc
, ioc
->name
);
7149 if (ioc
->hard_resets
< -1)
7153 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
7154 ioc
->ioc_reset_in_progress
= 0;
7155 ioc
->taskmgmt_quiesce_io
= 0;
7156 ioc
->taskmgmt_in_progress
= 0;
7158 ioc
->alt_ioc
->ioc_reset_in_progress
= 0;
7159 ioc
->alt_ioc
->taskmgmt_quiesce_io
= 0;
7160 ioc
->alt_ioc
->taskmgmt_in_progress
= 0;
7162 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
7164 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
7165 if (MptResetHandlers
[cb_idx
]) {
7166 mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_POST_RESET
);
7168 mpt_signal_reset(cb_idx
,
7169 ioc
->alt_ioc
, MPT_IOC_POST_RESET
);
7174 printk(MYIOC_s_DEBUG_FMT
7175 "HardResetHandler: completed (%d seconds): %s\n", ioc
->name
,
7176 jiffies_to_msecs(jiffies
- time_count
)/1000, ((rc
== 0) ?
7177 "SUCCESS" : "FAILED")));
7182 #ifdef CONFIG_FUSION_LOGGING
7184 mpt_display_event_info(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*pEventReply
)
7190 char *evStr
= ioc
->evStr
;
7192 event
= le32_to_cpu(pEventReply
->Event
) & 0xFF;
7193 evData0
= le32_to_cpu(pEventReply
->Data
[0]);
7196 case MPI_EVENT_NONE
:
7199 case MPI_EVENT_LOG_DATA
:
7202 case MPI_EVENT_STATE_CHANGE
:
7203 ds
= "State Change";
7205 case MPI_EVENT_UNIT_ATTENTION
:
7206 ds
= "Unit Attention";
7208 case MPI_EVENT_IOC_BUS_RESET
:
7209 ds
= "IOC Bus Reset";
7211 case MPI_EVENT_EXT_BUS_RESET
:
7212 ds
= "External Bus Reset";
7214 case MPI_EVENT_RESCAN
:
7215 ds
= "Bus Rescan Event";
7217 case MPI_EVENT_LINK_STATUS_CHANGE
:
7218 if (evData0
== MPI_EVENT_LINK_STATUS_FAILURE
)
7219 ds
= "Link Status(FAILURE) Change";
7221 ds
= "Link Status(ACTIVE) Change";
7223 case MPI_EVENT_LOOP_STATE_CHANGE
:
7224 if (evData0
== MPI_EVENT_LOOP_STATE_CHANGE_LIP
)
7225 ds
= "Loop State(LIP) Change";
7226 else if (evData0
== MPI_EVENT_LOOP_STATE_CHANGE_LPE
)
7227 ds
= "Loop State(LPE) Change";
7229 ds
= "Loop State(LPB) Change";
7231 case MPI_EVENT_LOGOUT
:
7234 case MPI_EVENT_EVENT_CHANGE
:
7240 case MPI_EVENT_INTEGRATED_RAID
:
7242 u8 ReasonCode
= (u8
)(evData0
>> 16);
7243 switch (ReasonCode
) {
7244 case MPI_EVENT_RAID_RC_VOLUME_CREATED
:
7245 ds
= "Integrated Raid: Volume Created";
7247 case MPI_EVENT_RAID_RC_VOLUME_DELETED
:
7248 ds
= "Integrated Raid: Volume Deleted";
7250 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED
:
7251 ds
= "Integrated Raid: Volume Settings Changed";
7253 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED
:
7254 ds
= "Integrated Raid: Volume Status Changed";
7256 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED
:
7257 ds
= "Integrated Raid: Volume Physdisk Changed";
7259 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED
:
7260 ds
= "Integrated Raid: Physdisk Created";
7262 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED
:
7263 ds
= "Integrated Raid: Physdisk Deleted";
7265 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED
:
7266 ds
= "Integrated Raid: Physdisk Settings Changed";
7268 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
:
7269 ds
= "Integrated Raid: Physdisk Status Changed";
7271 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
:
7272 ds
= "Integrated Raid: Domain Validation Needed";
7274 case MPI_EVENT_RAID_RC_SMART_DATA
:
7275 ds
= "Integrated Raid; Smart Data";
7277 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED
:
7278 ds
= "Integrated Raid: Replace Action Started";
7281 ds
= "Integrated Raid";
7286 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE
:
7287 ds
= "SCSI Device Status Change";
7289 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE
:
7291 u8 id
= (u8
)(evData0
);
7292 u8 channel
= (u8
)(evData0
>> 8);
7293 u8 ReasonCode
= (u8
)(evData0
>> 16);
7294 switch (ReasonCode
) {
7295 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED
:
7296 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7297 "SAS Device Status Change: Added: "
7298 "id=%d channel=%d", id
, channel
);
7300 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING
:
7301 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7302 "SAS Device Status Change: Deleted: "
7303 "id=%d channel=%d", id
, channel
);
7305 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA
:
7306 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7307 "SAS Device Status Change: SMART Data: "
7308 "id=%d channel=%d", id
, channel
);
7310 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED
:
7311 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7312 "SAS Device Status Change: No Persistancy: "
7313 "id=%d channel=%d", id
, channel
);
7315 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED
:
7316 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7317 "SAS Device Status Change: Unsupported Device "
7318 "Discovered : id=%d channel=%d", id
, channel
);
7320 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET
:
7321 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7322 "SAS Device Status Change: Internal Device "
7323 "Reset : id=%d channel=%d", id
, channel
);
7325 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL
:
7326 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7327 "SAS Device Status Change: Internal Task "
7328 "Abort : id=%d channel=%d", id
, channel
);
7330 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL
:
7331 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7332 "SAS Device Status Change: Internal Abort "
7333 "Task Set : id=%d channel=%d", id
, channel
);
7335 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL
:
7336 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7337 "SAS Device Status Change: Internal Clear "
7338 "Task Set : id=%d channel=%d", id
, channel
);
7340 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL
:
7341 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7342 "SAS Device Status Change: Internal Query "
7343 "Task : id=%d channel=%d", id
, channel
);
7346 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7347 "SAS Device Status Change: Unknown: "
7348 "id=%d channel=%d", id
, channel
);
7353 case MPI_EVENT_ON_BUS_TIMER_EXPIRED
:
7354 ds
= "Bus Timer Expired";
7356 case MPI_EVENT_QUEUE_FULL
:
7358 u16 curr_depth
= (u16
)(evData0
>> 16);
7359 u8 channel
= (u8
)(evData0
>> 8);
7360 u8 id
= (u8
)(evData0
);
7362 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7363 "Queue Full: channel=%d id=%d depth=%d",
7364 channel
, id
, curr_depth
);
7367 case MPI_EVENT_SAS_SES
:
7368 ds
= "SAS SES Event";
7370 case MPI_EVENT_PERSISTENT_TABLE_FULL
:
7371 ds
= "Persistent Table Full";
7373 case MPI_EVENT_SAS_PHY_LINK_STATUS
:
7375 u8 LinkRates
= (u8
)(evData0
>> 8);
7376 u8 PhyNumber
= (u8
)(evData0
);
7377 LinkRates
= (LinkRates
& MPI_EVENT_SAS_PLS_LR_CURRENT_MASK
) >>
7378 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT
;
7379 switch (LinkRates
) {
7380 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN
:
7381 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7382 "SAS PHY Link Status: Phy=%d:"
7383 " Rate Unknown",PhyNumber
);
7385 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED
:
7386 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7387 "SAS PHY Link Status: Phy=%d:"
7388 " Phy Disabled",PhyNumber
);
7390 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION
:
7391 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7392 "SAS PHY Link Status: Phy=%d:"
7393 " Failed Speed Nego",PhyNumber
);
7395 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE
:
7396 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7397 "SAS PHY Link Status: Phy=%d:"
7398 " Sata OOB Completed",PhyNumber
);
7400 case MPI_EVENT_SAS_PLS_LR_RATE_1_5
:
7401 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7402 "SAS PHY Link Status: Phy=%d:"
7403 " Rate 1.5 Gbps",PhyNumber
);
7405 case MPI_EVENT_SAS_PLS_LR_RATE_3_0
:
7406 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7407 "SAS PHY Link Status: Phy=%d:"
7408 " Rate 3.0 Gpbs",PhyNumber
);
7411 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7412 "SAS PHY Link Status: Phy=%d", PhyNumber
);
7417 case MPI_EVENT_SAS_DISCOVERY_ERROR
:
7418 ds
= "SAS Discovery Error";
7420 case MPI_EVENT_IR_RESYNC_UPDATE
:
7422 u8 resync_complete
= (u8
)(evData0
>> 16);
7423 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7424 "IR Resync Update: Complete = %d:",resync_complete
);
7429 u8 id
= (u8
)(evData0
);
7430 u8 channel
= (u8
)(evData0
>> 8);
7431 u8 phys_num
= (u8
)(evData0
>> 24);
7432 u8 ReasonCode
= (u8
)(evData0
>> 16);
7434 switch (ReasonCode
) {
7435 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED
:
7436 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7437 "IR2: LD State Changed: "
7438 "id=%d channel=%d phys_num=%d",
7439 id
, channel
, phys_num
);
7441 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED
:
7442 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7443 "IR2: PD State Changed "
7444 "id=%d channel=%d phys_num=%d",
7445 id
, channel
, phys_num
);
7447 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL
:
7448 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7449 "IR2: Bad Block Table Full: "
7450 "id=%d channel=%d phys_num=%d",
7451 id
, channel
, phys_num
);
7453 case MPI_EVENT_IR2_RC_PD_INSERTED
:
7454 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7455 "IR2: PD Inserted: "
7456 "id=%d channel=%d phys_num=%d",
7457 id
, channel
, phys_num
);
7459 case MPI_EVENT_IR2_RC_PD_REMOVED
:
7460 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7462 "id=%d channel=%d phys_num=%d",
7463 id
, channel
, phys_num
);
7465 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED
:
7466 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7467 "IR2: Foreign CFG Detected: "
7468 "id=%d channel=%d phys_num=%d",
7469 id
, channel
, phys_num
);
7471 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR
:
7472 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7473 "IR2: Rebuild Medium Error: "
7474 "id=%d channel=%d phys_num=%d",
7475 id
, channel
, phys_num
);
7477 case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED
:
7478 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7479 "IR2: Dual Port Added: "
7480 "id=%d channel=%d phys_num=%d",
7481 id
, channel
, phys_num
);
7483 case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED
:
7484 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7485 "IR2: Dual Port Removed: "
7486 "id=%d channel=%d phys_num=%d",
7487 id
, channel
, phys_num
);
7495 case MPI_EVENT_SAS_DISCOVERY
:
7498 ds
= "SAS Discovery: Start";
7500 ds
= "SAS Discovery: Stop";
7503 case MPI_EVENT_LOG_ENTRY_ADDED
:
7504 ds
= "SAS Log Entry Added";
7507 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE
:
7509 u8 phy_num
= (u8
)(evData0
);
7510 u8 port_num
= (u8
)(evData0
>> 8);
7511 u8 port_width
= (u8
)(evData0
>> 16);
7512 u8 primative
= (u8
)(evData0
>> 24);
7513 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7514 "SAS Broadcase Primative: phy=%d port=%d "
7515 "width=%d primative=0x%02x",
7516 phy_num
, port_num
, port_width
, primative
);
7520 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE
:
7522 u8 reason
= (u8
)(evData0
);
7525 case MPI_EVENT_SAS_INIT_RC_ADDED
:
7526 ds
= "SAS Initiator Status Change: Added";
7528 case MPI_EVENT_SAS_INIT_RC_REMOVED
:
7529 ds
= "SAS Initiator Status Change: Deleted";
7532 ds
= "SAS Initiator Status Change";
7538 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW
:
7540 u8 max_init
= (u8
)(evData0
);
7541 u8 current_init
= (u8
)(evData0
>> 8);
7543 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7544 "SAS Initiator Device Table Overflow: max initiators=%02d "
7545 "current initators=%02d",
7546 max_init
, current_init
);
7549 case MPI_EVENT_SAS_SMP_ERROR
:
7551 u8 status
= (u8
)(evData0
);
7552 u8 port_num
= (u8
)(evData0
>> 8);
7553 u8 result
= (u8
)(evData0
>> 16);
7555 if (status
== MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID
)
7556 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7557 "SAS SMP Error: port=%d result=0x%02x",
7559 else if (status
== MPI_EVENT_SAS_SMP_CRC_ERROR
)
7560 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7561 "SAS SMP Error: port=%d : CRC Error",
7563 else if (status
== MPI_EVENT_SAS_SMP_TIMEOUT
)
7564 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7565 "SAS SMP Error: port=%d : Timeout",
7567 else if (status
== MPI_EVENT_SAS_SMP_NO_DESTINATION
)
7568 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7569 "SAS SMP Error: port=%d : No Destination",
7571 else if (status
== MPI_EVENT_SAS_SMP_BAD_DESTINATION
)
7572 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7573 "SAS SMP Error: port=%d : Bad Destination",
7576 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7577 "SAS SMP Error: port=%d : status=0x%02x",
7582 case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE
:
7584 u8 reason
= (u8
)(evData0
);
7587 case MPI_EVENT_SAS_EXP_RC_ADDED
:
7588 ds
= "Expander Status Change: Added";
7590 case MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING
:
7591 ds
= "Expander Status Change: Deleted";
7594 ds
= "Expander Status Change";
7601 * MPT base "custom" events may be added here...
7608 strncpy(evStr
, ds
, EVENT_DESCR_STR_SZ
);
7611 devtprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
7612 "MPT event:(%02Xh) : %s\n",
7613 ioc
->name
, event
, evStr
));
7615 devtverboseprintk(ioc
, printk(KERN_DEBUG MYNAM
7616 ": Event data:\n"));
7617 for (ii
= 0; ii
< le16_to_cpu(pEventReply
->EventDataLength
); ii
++)
7618 devtverboseprintk(ioc
, printk(" %08x",
7619 le32_to_cpu(pEventReply
->Data
[ii
])));
7620 devtverboseprintk(ioc
, printk(KERN_DEBUG
"\n"));
7623 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7625 * ProcessEventNotification - Route EventNotificationReply to all event handlers
7626 * @ioc: Pointer to MPT_ADAPTER structure
7627 * @pEventReply: Pointer to EventNotification reply frame
7628 * @evHandlers: Pointer to integer, number of event handlers
7630 * Routes a received EventNotificationReply to all currently registered
7632 * Returns sum of event handlers return values.
7635 ProcessEventNotification(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*pEventReply
, int *evHandlers
)
7646 * Do platform normalization of values
7648 event
= le32_to_cpu(pEventReply
->Event
) & 0xFF;
7649 evDataLen
= le16_to_cpu(pEventReply
->EventDataLength
);
7651 evData0
= le32_to_cpu(pEventReply
->Data
[0]);
7654 #ifdef CONFIG_FUSION_LOGGING
7656 mpt_display_event_info(ioc
, pEventReply
);
7660 * Do general / base driver event processing
7663 case MPI_EVENT_EVENT_CHANGE
: /* 0A */
7665 u8 evState
= evData0
& 0xFF;
7667 /* CHECKME! What if evState unexpectedly says OFF (0)? */
7669 /* Update EventState field in cached IocFacts */
7670 if (ioc
->facts
.Function
) {
7671 ioc
->facts
.EventState
= evState
;
7675 case MPI_EVENT_INTEGRATED_RAID
:
7676 mptbase_raid_process_event_data(ioc
,
7677 (MpiEventDataRaid_t
*)pEventReply
->Data
);
7684 * Should this event be logged? Events are written sequentially.
7685 * When buffer is full, start again at the top.
7687 if (ioc
->events
&& (ioc
->eventTypes
& ( 1 << event
))) {
7690 idx
= ioc
->eventContext
% MPTCTL_EVENT_LOG_SIZE
;
7692 ioc
->events
[idx
].event
= event
;
7693 ioc
->events
[idx
].eventContext
= ioc
->eventContext
;
7695 for (ii
= 0; ii
< 2; ii
++) {
7697 ioc
->events
[idx
].data
[ii
] = le32_to_cpu(pEventReply
->Data
[ii
]);
7699 ioc
->events
[idx
].data
[ii
] = 0;
7702 ioc
->eventContext
++;
7707 * Call each currently registered protocol event handler.
7709 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
7710 if (MptEvHandlers
[cb_idx
]) {
7711 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
7712 "Routing Event to event handler #%d\n",
7713 ioc
->name
, cb_idx
));
7714 r
+= (*(MptEvHandlers
[cb_idx
]))(ioc
, pEventReply
);
7718 /* FIXME? Examine results here? */
7721 * If needed, send (a single) EventAck.
7723 if (pEventReply
->AckRequired
== MPI_EVENT_NOTIFICATION_ACK_REQUIRED
) {
7724 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
7725 "EventAck required\n",ioc
->name
));
7726 if ((ii
= SendEventAck(ioc
, pEventReply
)) != 0) {
7727 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SendEventAck returned %d\n",
7732 *evHandlers
= handlers
;
7736 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7738 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
7739 * @ioc: Pointer to MPT_ADAPTER structure
7740 * @log_info: U32 LogInfo reply word from the IOC
7742 * Refer to lsi/mpi_log_fc.h.
7745 mpt_fc_log_info(MPT_ADAPTER
*ioc
, u32 log_info
)
7747 char *desc
= "unknown";
7749 switch (log_info
& 0xFF000000) {
7750 case MPI_IOCLOGINFO_FC_INIT_BASE
:
7751 desc
= "FCP Initiator";
7753 case MPI_IOCLOGINFO_FC_TARGET_BASE
:
7754 desc
= "FCP Target";
7756 case MPI_IOCLOGINFO_FC_LAN_BASE
:
7759 case MPI_IOCLOGINFO_FC_MSG_BASE
:
7760 desc
= "MPI Message Layer";
7762 case MPI_IOCLOGINFO_FC_LINK_BASE
:
7765 case MPI_IOCLOGINFO_FC_CTX_BASE
:
7766 desc
= "Context Manager";
7768 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET
:
7769 desc
= "Invalid Field Offset";
7771 case MPI_IOCLOGINFO_FC_STATE_CHANGE
:
7772 desc
= "State Change Info";
7776 printk(MYIOC_s_INFO_FMT
"LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
7777 ioc
->name
, log_info
, desc
, (log_info
& 0xFFFFFF));
7780 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7782 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
7783 * @ioc: Pointer to MPT_ADAPTER structure
7784 * @log_info: U32 LogInfo word from the IOC
7786 * Refer to lsi/sp_log.h.
7789 mpt_spi_log_info(MPT_ADAPTER
*ioc
, u32 log_info
)
7791 u32 info
= log_info
& 0x00FF0000;
7792 char *desc
= "unknown";
7796 desc
= "bug! MID not found";
7800 desc
= "Parity Error";
7804 desc
= "ASYNC Outbound Overrun";
7808 desc
= "SYNC Offset Error";
7816 desc
= "Msg In Overflow";
7824 desc
= "Outbound DMA Overrun";
7828 desc
= "Task Management";
7832 desc
= "Device Problem";
7836 desc
= "Invalid Phase Change";
7840 desc
= "Untagged Table Size";
7845 printk(MYIOC_s_INFO_FMT
"LogInfo(0x%08x): F/W: %s\n", ioc
->name
, log_info
, desc
);
7848 /* strings for sas loginfo */
7849 static char *originator_str
[] = {
7854 static char *iop_code_str
[] = {
7856 "Invalid SAS Address", /* 01h */
7858 "Invalid Page", /* 03h */
7859 "Diag Message Error", /* 04h */
7860 "Task Terminated", /* 05h */
7861 "Enclosure Management", /* 06h */
7862 "Target Mode" /* 07h */
7864 static char *pl_code_str
[] = {
7866 "Open Failure", /* 01h */
7867 "Invalid Scatter Gather List", /* 02h */
7868 "Wrong Relative Offset or Frame Length", /* 03h */
7869 "Frame Transfer Error", /* 04h */
7870 "Transmit Frame Connected Low", /* 05h */
7871 "SATA Non-NCQ RW Error Bit Set", /* 06h */
7872 "SATA Read Log Receive Data Error", /* 07h */
7873 "SATA NCQ Fail All Commands After Error", /* 08h */
7874 "SATA Error in Receive Set Device Bit FIS", /* 09h */
7875 "Receive Frame Invalid Message", /* 0Ah */
7876 "Receive Context Message Valid Error", /* 0Bh */
7877 "Receive Frame Current Frame Error", /* 0Ch */
7878 "SATA Link Down", /* 0Dh */
7879 "Discovery SATA Init W IOS", /* 0Eh */
7880 "Config Invalid Page", /* 0Fh */
7881 "Discovery SATA Init Timeout", /* 10h */
7884 "IO Not Yet Executed", /* 13h */
7885 "IO Executed", /* 14h */
7886 "Persistent Reservation Out Not Affiliation "
7888 "Open Transmit DMA Abort", /* 16h */
7889 "IO Device Missing Delay Retry", /* 17h */
7890 "IO Cancelled Due to Recieve Error", /* 18h */
7898 "Enclosure Management" /* 20h */
7900 static char *ir_code_str
[] = {
7901 "Raid Action Error", /* 00h */
7911 static char *raid_sub_code_str
[] = {
7913 "Volume Creation Failed: Data Passed too "
7915 "Volume Creation Failed: Duplicate Volumes "
7916 "Attempted", /* 02h */
7917 "Volume Creation Failed: Max Number "
7918 "Supported Volumes Exceeded", /* 03h */
7919 "Volume Creation Failed: DMA Error", /* 04h */
7920 "Volume Creation Failed: Invalid Volume Type", /* 05h */
7921 "Volume Creation Failed: Error Reading "
7922 "MFG Page 4", /* 06h */
7923 "Volume Creation Failed: Creating Internal "
7924 "Structures", /* 07h */
7933 "Activation failed: Already Active Volume", /* 10h */
7934 "Activation failed: Unsupported Volume Type", /* 11h */
7935 "Activation failed: Too Many Active Volumes", /* 12h */
7936 "Activation failed: Volume ID in Use", /* 13h */
7937 "Activation failed: Reported Failure", /* 14h */
7938 "Activation failed: Importing a Volume", /* 15h */
7949 "Phys Disk failed: Too Many Phys Disks", /* 20h */
7950 "Phys Disk failed: Data Passed too Large", /* 21h */
7951 "Phys Disk failed: DMA Error", /* 22h */
7952 "Phys Disk failed: Invalid <channel:id>", /* 23h */
7953 "Phys Disk failed: Creating Phys Disk Config "
7966 "Compatibility Error: IR Disabled", /* 30h */
7967 "Compatibility Error: Inquiry Comand Failed", /* 31h */
7968 "Compatibility Error: Device not Direct Access "
7969 "Device ", /* 32h */
7970 "Compatibility Error: Removable Device Found", /* 33h */
7971 "Compatibility Error: Device SCSI Version not "
7972 "2 or Higher", /* 34h */
7973 "Compatibility Error: SATA Device, 48 BIT LBA "
7974 "not Supported", /* 35h */
7975 "Compatibility Error: Device doesn't have "
7976 "512 Byte Block Sizes", /* 36h */
7977 "Compatibility Error: Volume Type Check Failed", /* 37h */
7978 "Compatibility Error: Volume Type is "
7979 "Unsupported by FW", /* 38h */
7980 "Compatibility Error: Disk Drive too Small for "
7981 "use in Volume", /* 39h */
7982 "Compatibility Error: Phys Disk for Create "
7983 "Volume not Found", /* 3Ah */
7984 "Compatibility Error: Too Many or too Few "
7985 "Disks for Volume Type", /* 3Bh */
7986 "Compatibility Error: Disk stripe Sizes "
7987 "Must be 64KB", /* 3Ch */
7988 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
7991 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7993 * mpt_sas_log_info - Log information returned from SAS IOC.
7994 * @ioc: Pointer to MPT_ADAPTER structure
7995 * @log_info: U32 LogInfo reply word from the IOC
7997 * Refer to lsi/mpi_log_sas.h.
8000 mpt_sas_log_info(MPT_ADAPTER
*ioc
, u32 log_info
)
8002 union loginfo_type
{
8011 union loginfo_type sas_loginfo
;
8012 char *originator_desc
= NULL
;
8013 char *code_desc
= NULL
;
8014 char *sub_code_desc
= NULL
;
8016 sas_loginfo
.loginfo
= log_info
;
8017 if ((sas_loginfo
.dw
.bus_type
!= 3 /*SAS*/) &&
8018 (sas_loginfo
.dw
.originator
< ARRAY_SIZE(originator_str
)))
8021 originator_desc
= originator_str
[sas_loginfo
.dw
.originator
];
8023 switch (sas_loginfo
.dw
.originator
) {
8026 if (sas_loginfo
.dw
.code
<
8027 ARRAY_SIZE(iop_code_str
))
8028 code_desc
= iop_code_str
[sas_loginfo
.dw
.code
];
8031 if (sas_loginfo
.dw
.code
<
8032 ARRAY_SIZE(pl_code_str
))
8033 code_desc
= pl_code_str
[sas_loginfo
.dw
.code
];
8036 if (sas_loginfo
.dw
.code
>=
8037 ARRAY_SIZE(ir_code_str
))
8039 code_desc
= ir_code_str
[sas_loginfo
.dw
.code
];
8040 if (sas_loginfo
.dw
.subcode
>=
8041 ARRAY_SIZE(raid_sub_code_str
))
8043 if (sas_loginfo
.dw
.code
== 0)
8045 raid_sub_code_str
[sas_loginfo
.dw
.subcode
];
8051 if (sub_code_desc
!= NULL
)
8052 printk(MYIOC_s_INFO_FMT
8053 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
8055 ioc
->name
, log_info
, originator_desc
, code_desc
,
8057 else if (code_desc
!= NULL
)
8058 printk(MYIOC_s_INFO_FMT
8059 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
8060 " SubCode(0x%04x)\n",
8061 ioc
->name
, log_info
, originator_desc
, code_desc
,
8062 sas_loginfo
.dw
.subcode
);
8064 printk(MYIOC_s_INFO_FMT
8065 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
8066 " SubCode(0x%04x)\n",
8067 ioc
->name
, log_info
, originator_desc
,
8068 sas_loginfo
.dw
.code
, sas_loginfo
.dw
.subcode
);
8071 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8073 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
8074 * @ioc: Pointer to MPT_ADAPTER structure
8075 * @ioc_status: U32 IOCStatus word from IOC
8076 * @mf: Pointer to MPT request frame
8078 * Refer to lsi/mpi.h.
8081 mpt_iocstatus_info_config(MPT_ADAPTER
*ioc
, u32 ioc_status
, MPT_FRAME_HDR
*mf
)
8083 Config_t
*pReq
= (Config_t
*)mf
;
8084 char extend_desc
[EVENT_DESCR_STR_SZ
];
8089 if (pReq
->Header
.PageType
== MPI_CONFIG_PAGETYPE_EXTENDED
)
8090 page_type
= pReq
->ExtPageType
;
8092 page_type
= pReq
->Header
.PageType
;
8095 * ignore invalid page messages for GET_NEXT_HANDLE
8097 form
= le32_to_cpu(pReq
->PageAddress
);
8098 if (ioc_status
== MPI_IOCSTATUS_CONFIG_INVALID_PAGE
) {
8099 if (page_type
== MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE
||
8100 page_type
== MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER
||
8101 page_type
== MPI_CONFIG_EXTPAGETYPE_ENCLOSURE
) {
8102 if ((form
>> MPI_SAS_DEVICE_PGAD_FORM_SHIFT
) ==
8103 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE
)
8106 if (page_type
== MPI_CONFIG_PAGETYPE_FC_DEVICE
)
8107 if ((form
& MPI_FC_DEVICE_PGAD_FORM_MASK
) ==
8108 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID
)
8112 snprintf(extend_desc
, EVENT_DESCR_STR_SZ
,
8113 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
8114 page_type
, pReq
->Header
.PageNumber
, pReq
->Action
, form
);
8116 switch (ioc_status
) {
8118 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION
: /* 0x0020 */
8119 desc
= "Config Page Invalid Action";
8122 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE
: /* 0x0021 */
8123 desc
= "Config Page Invalid Type";
8126 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE
: /* 0x0022 */
8127 desc
= "Config Page Invalid Page";
8130 case MPI_IOCSTATUS_CONFIG_INVALID_DATA
: /* 0x0023 */
8131 desc
= "Config Page Invalid Data";
8134 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS
: /* 0x0024 */
8135 desc
= "Config Page No Defaults";
8138 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT
: /* 0x0025 */
8139 desc
= "Config Page Can't Commit";
8146 dreplyprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"IOCStatus(0x%04X): %s: %s\n",
8147 ioc
->name
, ioc_status
, desc
, extend_desc
));
8151 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
8152 * @ioc: Pointer to MPT_ADAPTER structure
8153 * @ioc_status: U32 IOCStatus word from IOC
8154 * @mf: Pointer to MPT request frame
8156 * Refer to lsi/mpi.h.
8159 mpt_iocstatus_info(MPT_ADAPTER
*ioc
, u32 ioc_status
, MPT_FRAME_HDR
*mf
)
8161 u32 status
= ioc_status
& MPI_IOCSTATUS_MASK
;
8166 /****************************************************************************/
8167 /* Common IOCStatus values for all replies */
8168 /****************************************************************************/
8170 case MPI_IOCSTATUS_INVALID_FUNCTION
: /* 0x0001 */
8171 desc
= "Invalid Function";
8174 case MPI_IOCSTATUS_BUSY
: /* 0x0002 */
8178 case MPI_IOCSTATUS_INVALID_SGL
: /* 0x0003 */
8179 desc
= "Invalid SGL";
8182 case MPI_IOCSTATUS_INTERNAL_ERROR
: /* 0x0004 */
8183 desc
= "Internal Error";
8186 case MPI_IOCSTATUS_RESERVED
: /* 0x0005 */
8190 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES
: /* 0x0006 */
8191 desc
= "Insufficient Resources";
8194 case MPI_IOCSTATUS_INVALID_FIELD
: /* 0x0007 */
8195 desc
= "Invalid Field";
8198 case MPI_IOCSTATUS_INVALID_STATE
: /* 0x0008 */
8199 desc
= "Invalid State";
8202 /****************************************************************************/
8203 /* Config IOCStatus values */
8204 /****************************************************************************/
8206 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION
: /* 0x0020 */
8207 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE
: /* 0x0021 */
8208 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE
: /* 0x0022 */
8209 case MPI_IOCSTATUS_CONFIG_INVALID_DATA
: /* 0x0023 */
8210 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS
: /* 0x0024 */
8211 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT
: /* 0x0025 */
8212 mpt_iocstatus_info_config(ioc
, status
, mf
);
8215 /****************************************************************************/
8216 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
8218 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
8220 /****************************************************************************/
8222 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR
: /* 0x0040 */
8223 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN
: /* 0x0045 */
8224 case MPI_IOCSTATUS_SCSI_INVALID_BUS
: /* 0x0041 */
8225 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID
: /* 0x0042 */
8226 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE
: /* 0x0043 */
8227 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN
: /* 0x0044 */
8228 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR
: /* 0x0046 */
8229 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR
: /* 0x0047 */
8230 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED
: /* 0x0048 */
8231 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH
: /* 0x0049 */
8232 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED
: /* 0x004A */
8233 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED
: /* 0x004B */
8234 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED
: /* 0x004C */
8237 /****************************************************************************/
8238 /* SCSI Target values */
8239 /****************************************************************************/
8241 case MPI_IOCSTATUS_TARGET_PRIORITY_IO
: /* 0x0060 */
8242 desc
= "Target: Priority IO";
8245 case MPI_IOCSTATUS_TARGET_INVALID_PORT
: /* 0x0061 */
8246 desc
= "Target: Invalid Port";
8249 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX
: /* 0x0062 */
8250 desc
= "Target Invalid IO Index:";
8253 case MPI_IOCSTATUS_TARGET_ABORTED
: /* 0x0063 */
8254 desc
= "Target: Aborted";
8257 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE
: /* 0x0064 */
8258 desc
= "Target: No Conn Retryable";
8261 case MPI_IOCSTATUS_TARGET_NO_CONNECTION
: /* 0x0065 */
8262 desc
= "Target: No Connection";
8265 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH
: /* 0x006A */
8266 desc
= "Target: Transfer Count Mismatch";
8269 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT
: /* 0x006B */
8270 desc
= "Target: STS Data not Sent";
8273 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR
: /* 0x006D */
8274 desc
= "Target: Data Offset Error";
8277 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA
: /* 0x006E */
8278 desc
= "Target: Too Much Write Data";
8281 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT
: /* 0x006F */
8282 desc
= "Target: IU Too Short";
8285 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT
: /* 0x0070 */
8286 desc
= "Target: ACK NAK Timeout";
8289 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED
: /* 0x0071 */
8290 desc
= "Target: Nak Received";
8293 /****************************************************************************/
8294 /* Fibre Channel Direct Access values */
8295 /****************************************************************************/
8297 case MPI_IOCSTATUS_FC_ABORTED
: /* 0x0066 */
8298 desc
= "FC: Aborted";
8301 case MPI_IOCSTATUS_FC_RX_ID_INVALID
: /* 0x0067 */
8302 desc
= "FC: RX ID Invalid";
8305 case MPI_IOCSTATUS_FC_DID_INVALID
: /* 0x0068 */
8306 desc
= "FC: DID Invalid";
8309 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT
: /* 0x0069 */
8310 desc
= "FC: Node Logged Out";
8313 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED
: /* 0x006C */
8314 desc
= "FC: Exchange Canceled";
8317 /****************************************************************************/
8319 /****************************************************************************/
8321 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND
: /* 0x0080 */
8322 desc
= "LAN: Device not Found";
8325 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE
: /* 0x0081 */
8326 desc
= "LAN: Device Failure";
8329 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR
: /* 0x0082 */
8330 desc
= "LAN: Transmit Error";
8333 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED
: /* 0x0083 */
8334 desc
= "LAN: Transmit Aborted";
8337 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR
: /* 0x0084 */
8338 desc
= "LAN: Receive Error";
8341 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED
: /* 0x0085 */
8342 desc
= "LAN: Receive Aborted";
8345 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET
: /* 0x0086 */
8346 desc
= "LAN: Partial Packet";
8349 case MPI_IOCSTATUS_LAN_CANCELED
: /* 0x0087 */
8350 desc
= "LAN: Canceled";
8353 /****************************************************************************/
8354 /* Serial Attached SCSI values */
8355 /****************************************************************************/
8357 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED
: /* 0x0090 */
8358 desc
= "SAS: SMP Request Failed";
8361 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN
: /* 0x0090 */
8362 desc
= "SAS: SMP Data Overrun";
8373 dreplyprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"IOCStatus(0x%04X): %s\n",
8374 ioc
->name
, status
, desc
));
8377 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8378 EXPORT_SYMBOL(mpt_attach
);
8379 EXPORT_SYMBOL(mpt_detach
);
8381 EXPORT_SYMBOL(mpt_resume
);
8382 EXPORT_SYMBOL(mpt_suspend
);
8384 EXPORT_SYMBOL(ioc_list
);
8385 EXPORT_SYMBOL(mpt_register
);
8386 EXPORT_SYMBOL(mpt_deregister
);
8387 EXPORT_SYMBOL(mpt_event_register
);
8388 EXPORT_SYMBOL(mpt_event_deregister
);
8389 EXPORT_SYMBOL(mpt_reset_register
);
8390 EXPORT_SYMBOL(mpt_reset_deregister
);
8391 EXPORT_SYMBOL(mpt_device_driver_register
);
8392 EXPORT_SYMBOL(mpt_device_driver_deregister
);
8393 EXPORT_SYMBOL(mpt_get_msg_frame
);
8394 EXPORT_SYMBOL(mpt_put_msg_frame
);
8395 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri
);
8396 EXPORT_SYMBOL(mpt_free_msg_frame
);
8397 EXPORT_SYMBOL(mpt_send_handshake_request
);
8398 EXPORT_SYMBOL(mpt_verify_adapter
);
8399 EXPORT_SYMBOL(mpt_GetIocState
);
8400 EXPORT_SYMBOL(mpt_print_ioc_summary
);
8401 EXPORT_SYMBOL(mpt_HardResetHandler
);
8402 EXPORT_SYMBOL(mpt_config
);
8403 EXPORT_SYMBOL(mpt_findImVolumes
);
8404 EXPORT_SYMBOL(mpt_alloc_fw_memory
);
8405 EXPORT_SYMBOL(mpt_free_fw_memory
);
8406 EXPORT_SYMBOL(mptbase_sas_persist_operation
);
8407 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0
);
8409 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8411 * fusion_init - Fusion MPT base driver initialization routine.
8413 * Returns 0 for success, non-zero for failure.
8420 show_mptmod_ver(my_NAME
, my_VERSION
);
8421 printk(KERN_INFO COPYRIGHT
"\n");
8423 for (cb_idx
= 0; cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
; cb_idx
++) {
8424 MptCallbacks
[cb_idx
] = NULL
;
8425 MptDriverClass
[cb_idx
] = MPTUNKNOWN_DRIVER
;
8426 MptEvHandlers
[cb_idx
] = NULL
;
8427 MptResetHandlers
[cb_idx
] = NULL
;
8430 /* Register ourselves (mptbase) in order to facilitate
8431 * EventNotification handling.
8433 mpt_base_index
= mpt_register(mptbase_reply
, MPTBASE_DRIVER
);
8435 /* Register for hard reset handling callbacks.
8437 mpt_reset_register(mpt_base_index
, mpt_ioc_reset
);
8439 #ifdef CONFIG_PROC_FS
8440 (void) procmpt_create();
8445 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8447 * fusion_exit - Perform driver unload cleanup.
8449 * This routine frees all resources associated with each MPT adapter
8450 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
8456 mpt_reset_deregister(mpt_base_index
);
8458 #ifdef CONFIG_PROC_FS
8463 module_init(fusion_init
);
8464 module_exit(fusion_exit
);