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 static struct proc_dir_entry
*mpt_proc_root_dir
;
131 #define WHOINIT_UNKNOWN 0xAA
133 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
137 /* Adapter link list */
139 /* Callback lookup table */
140 static MPT_CALLBACK MptCallbacks
[MPT_MAX_PROTOCOL_DRIVERS
];
141 /* Protocol driver class lookup table */
142 static int MptDriverClass
[MPT_MAX_PROTOCOL_DRIVERS
];
143 /* Event handler lookup table */
144 static MPT_EVHANDLER MptEvHandlers
[MPT_MAX_PROTOCOL_DRIVERS
];
145 /* Reset handler lookup table */
146 static MPT_RESETHANDLER MptResetHandlers
[MPT_MAX_PROTOCOL_DRIVERS
];
147 static struct mpt_pci_driver
*MptDeviceDriverHandlers
[MPT_MAX_PROTOCOL_DRIVERS
];
151 * Driver Callback Index's
153 static u8 mpt_base_index
= MPT_MAX_PROTOCOL_DRIVERS
;
154 static u8 last_drv_idx
;
156 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
160 static irqreturn_t
mpt_interrupt(int irq
, void *bus_id
);
161 static int mptbase_reply(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*req
,
162 MPT_FRAME_HDR
*reply
);
163 static int mpt_handshake_req_reply_wait(MPT_ADAPTER
*ioc
, int reqBytes
,
164 u32
*req
, int replyBytes
, u16
*u16reply
, int maxwait
,
166 static int mpt_do_ioc_recovery(MPT_ADAPTER
*ioc
, u32 reason
, int sleepFlag
);
167 static void mpt_detect_bound_ports(MPT_ADAPTER
*ioc
, struct pci_dev
*pdev
);
168 static void mpt_adapter_disable(MPT_ADAPTER
*ioc
);
169 static void mpt_adapter_dispose(MPT_ADAPTER
*ioc
);
171 static void MptDisplayIocCapabilities(MPT_ADAPTER
*ioc
);
172 static int MakeIocReady(MPT_ADAPTER
*ioc
, int force
, int sleepFlag
);
173 static int GetIocFacts(MPT_ADAPTER
*ioc
, int sleepFlag
, int reason
);
174 static int GetPortFacts(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
);
175 static int SendIocInit(MPT_ADAPTER
*ioc
, int sleepFlag
);
176 static int SendPortEnable(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
);
177 static int mpt_do_upload(MPT_ADAPTER
*ioc
, int sleepFlag
);
178 static int mpt_downloadboot(MPT_ADAPTER
*ioc
, MpiFwHeader_t
*pFwHeader
, int sleepFlag
);
179 static int mpt_diag_reset(MPT_ADAPTER
*ioc
, int ignore
, int sleepFlag
);
180 static int KickStart(MPT_ADAPTER
*ioc
, int ignore
, int sleepFlag
);
181 static int SendIocReset(MPT_ADAPTER
*ioc
, u8 reset_type
, int sleepFlag
);
182 static int PrimeIocFifos(MPT_ADAPTER
*ioc
);
183 static int WaitForDoorbellAck(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
);
184 static int WaitForDoorbellInt(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
);
185 static int WaitForDoorbellReply(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
);
186 static int GetLanConfigPages(MPT_ADAPTER
*ioc
);
187 static int GetIoUnitPage2(MPT_ADAPTER
*ioc
);
188 int mptbase_sas_persist_operation(MPT_ADAPTER
*ioc
, u8 persist_opcode
);
189 static int mpt_GetScsiPortSettings(MPT_ADAPTER
*ioc
, int portnum
);
190 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER
*ioc
, int portnum
);
191 static void mpt_read_ioc_pg_1(MPT_ADAPTER
*ioc
);
192 static void mpt_read_ioc_pg_4(MPT_ADAPTER
*ioc
);
193 static void mpt_get_manufacturing_pg_0(MPT_ADAPTER
*ioc
);
194 static int SendEventNotification(MPT_ADAPTER
*ioc
, u8 EvSwitch
,
196 static int SendEventAck(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*evnp
);
197 static int mpt_host_page_access_control(MPT_ADAPTER
*ioc
, u8 access_control_value
, int sleepFlag
);
198 static int mpt_host_page_alloc(MPT_ADAPTER
*ioc
, pIOCInit_t ioc_init
);
200 #ifdef CONFIG_PROC_FS
201 static int procmpt_summary_read(char *buf
, char **start
, off_t offset
,
202 int request
, int *eof
, void *data
);
203 static int procmpt_version_read(char *buf
, char **start
, off_t offset
,
204 int request
, int *eof
, void *data
);
205 static int procmpt_iocinfo_read(char *buf
, char **start
, off_t offset
,
206 int request
, int *eof
, void *data
);
208 static void mpt_get_fw_exp_ver(char *buf
, MPT_ADAPTER
*ioc
);
210 //int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
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
->diagPending
|| !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
->fault_reset_work_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
->fault_reset_work_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 mf
->u
.frame
.linkage
.arg1
= 0xdeadbeaf; /* signature to know if this mf is freed */
976 list_add_tail(&mf
->u
.frame
.linkage
.list
, &ioc
->FreeQ
);
980 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
983 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
985 * mpt_add_sge - Place a simple 32 bit SGE at address pAddr.
986 * @pAddr: virtual address for SGE
987 * @flagslength: SGE flags and data transfer length
988 * @dma_addr: Physical address
990 * This routine places a MPT request frame back on the MPT adapter's
994 mpt_add_sge(void *pAddr
, u32 flagslength
, dma_addr_t dma_addr
)
996 SGESimple32_t
*pSge
= (SGESimple32_t
*) pAddr
;
997 pSge
->FlagsLength
= cpu_to_le32(flagslength
);
998 pSge
->Address
= cpu_to_le32(dma_addr
);
1002 * mpt_add_sge_64bit - Place a simple 64 bit SGE at address pAddr.
1003 * @pAddr: virtual address for SGE
1004 * @flagslength: SGE flags and data transfer length
1005 * @dma_addr: Physical address
1007 * This routine places a MPT request frame back on the MPT adapter's
1011 mpt_add_sge_64bit(void *pAddr
, u32 flagslength
, dma_addr_t dma_addr
)
1013 SGESimple64_t
*pSge
= (SGESimple64_t
*) pAddr
;
1014 pSge
->Address
.Low
= cpu_to_le32
1015 (lower_32_bits((unsigned long)(dma_addr
)));
1016 pSge
->Address
.High
= cpu_to_le32
1017 (upper_32_bits((unsigned long)dma_addr
));
1018 pSge
->FlagsLength
= cpu_to_le32
1019 ((flagslength
| MPT_SGE_FLAGS_64_BIT_ADDRESSING
));
1023 * mpt_add_sge_64bit_1078 - Place a simple 64 bit SGE at address pAddr
1024 * (1078 workaround).
1025 * @pAddr: virtual address for SGE
1026 * @flagslength: SGE flags and data transfer length
1027 * @dma_addr: Physical address
1029 * This routine places a MPT request frame back on the MPT adapter's
1033 mpt_add_sge_64bit_1078(void *pAddr
, u32 flagslength
, dma_addr_t dma_addr
)
1035 SGESimple64_t
*pSge
= (SGESimple64_t
*) pAddr
;
1038 pSge
->Address
.Low
= cpu_to_le32
1039 (lower_32_bits((unsigned long)(dma_addr
)));
1040 tmp
= (u32
)(upper_32_bits((unsigned long)dma_addr
));
1043 * 1078 errata workaround for the 36GB limitation
1045 if ((((u64
)dma_addr
+ MPI_SGE_LENGTH(flagslength
)) >> 32) == 9) {
1047 MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_LOCAL_ADDRESS
);
1049 if (mpt_debug_level
& MPT_DEBUG_36GB_MEM
)
1050 printk(KERN_DEBUG
"1078 P0M2 addressing for "
1051 "addr = 0x%llx len = %d\n",
1052 (unsigned long long)dma_addr
,
1053 MPI_SGE_LENGTH(flagslength
));
1056 pSge
->Address
.High
= cpu_to_le32(tmp
);
1057 pSge
->FlagsLength
= cpu_to_le32(
1058 (flagslength
| MPT_SGE_FLAGS_64_BIT_ADDRESSING
));
1061 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1063 * mpt_add_chain - Place a 32 bit chain SGE at address pAddr.
1064 * @pAddr: virtual address for SGE
1065 * @next: nextChainOffset value (u32's)
1066 * @length: length of next SGL segment
1067 * @dma_addr: Physical address
1071 mpt_add_chain(void *pAddr
, u8 next
, u16 length
, dma_addr_t dma_addr
)
1073 SGEChain32_t
*pChain
= (SGEChain32_t
*) pAddr
;
1074 pChain
->Length
= cpu_to_le16(length
);
1075 pChain
->Flags
= MPI_SGE_FLAGS_CHAIN_ELEMENT
;
1076 pChain
->NextChainOffset
= next
;
1077 pChain
->Address
= cpu_to_le32(dma_addr
);
1080 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1082 * mpt_add_chain_64bit - Place a 64 bit chain SGE at address pAddr.
1083 * @pAddr: virtual address for SGE
1084 * @next: nextChainOffset value (u32's)
1085 * @length: length of next SGL segment
1086 * @dma_addr: Physical address
1090 mpt_add_chain_64bit(void *pAddr
, u8 next
, u16 length
, dma_addr_t dma_addr
)
1092 SGEChain64_t
*pChain
= (SGEChain64_t
*) pAddr
;
1093 u32 tmp
= dma_addr
& 0xFFFFFFFF;
1095 pChain
->Length
= cpu_to_le16(length
);
1096 pChain
->Flags
= (MPI_SGE_FLAGS_CHAIN_ELEMENT
|
1097 MPI_SGE_FLAGS_64_BIT_ADDRESSING
);
1099 pChain
->NextChainOffset
= next
;
1101 pChain
->Address
.Low
= cpu_to_le32(tmp
);
1102 tmp
= (u32
)(upper_32_bits((unsigned long)dma_addr
));
1103 pChain
->Address
.High
= cpu_to_le32(tmp
);
1106 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1108 * mpt_send_handshake_request - Send MPT request via doorbell handshake method.
1109 * @cb_idx: Handle of registered MPT protocol driver
1110 * @ioc: Pointer to MPT adapter structure
1111 * @reqBytes: Size of the request in bytes
1112 * @req: Pointer to MPT request frame
1113 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1115 * This routine is used exclusively to send MptScsiTaskMgmt
1116 * requests since they are required to be sent via doorbell handshake.
1118 * NOTE: It is the callers responsibility to byte-swap fields in the
1119 * request which are greater than 1 byte in size.
1121 * Returns 0 for success, non-zero for failure.
1124 mpt_send_handshake_request(u8 cb_idx
, MPT_ADAPTER
*ioc
, int reqBytes
, u32
*req
, int sleepFlag
)
1130 /* State is known to be good upon entering
1131 * this function so issue the bus reset
1136 * Emulate what mpt_put_msg_frame() does /wrt to sanity
1137 * setting cb_idx/req_idx. But ONLY if this request
1138 * is in proper (pre-alloc'd) request buffer range...
1140 ii
= MFPTR_2_MPT_INDEX(ioc
,(MPT_FRAME_HDR
*)req
);
1141 if (reqBytes
>= 12 && ii
>= 0 && ii
< ioc
->req_depth
) {
1142 MPT_FRAME_HDR
*mf
= (MPT_FRAME_HDR
*)req
;
1143 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(ii
);
1144 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= cb_idx
;
1147 /* Make sure there are no doorbells */
1148 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1150 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
,
1151 ((MPI_FUNCTION_HANDSHAKE
<<MPI_DOORBELL_FUNCTION_SHIFT
) |
1152 ((reqBytes
/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT
)));
1154 /* Wait for IOC doorbell int */
1155 if ((ii
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0) {
1159 /* Read doorbell and check for active bit */
1160 if (!(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & MPI_DOORBELL_ACTIVE
))
1163 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mpt_send_handshake_request start, WaitCnt=%d\n",
1166 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1168 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0) {
1172 /* Send request via doorbell handshake */
1173 req_as_bytes
= (u8
*) req
;
1174 for (ii
= 0; ii
< reqBytes
/4; ii
++) {
1177 word
= ((req_as_bytes
[(ii
*4) + 0] << 0) |
1178 (req_as_bytes
[(ii
*4) + 1] << 8) |
1179 (req_as_bytes
[(ii
*4) + 2] << 16) |
1180 (req_as_bytes
[(ii
*4) + 3] << 24));
1181 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, word
);
1182 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0) {
1188 if (r
>= 0 && WaitForDoorbellInt(ioc
, 10, sleepFlag
) >= 0)
1193 /* Make sure there are no doorbells */
1194 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1199 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1201 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
1202 * @ioc: Pointer to MPT adapter structure
1203 * @access_control_value: define bits below
1204 * @sleepFlag: Specifies whether the process can sleep
1206 * Provides mechanism for the host driver to control the IOC's
1207 * Host Page Buffer access.
1209 * Access Control Value - bits[15:12]
1211 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1212 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1213 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1215 * Returns 0 for success, non-zero for failure.
1219 mpt_host_page_access_control(MPT_ADAPTER
*ioc
, u8 access_control_value
, int sleepFlag
)
1223 /* return if in use */
1224 if (CHIPREG_READ32(&ioc
->chip
->Doorbell
)
1225 & MPI_DOORBELL_ACTIVE
)
1228 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1230 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
,
1231 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1232 <<MPI_DOORBELL_FUNCTION_SHIFT
) |
1233 (access_control_value
<<12)));
1235 /* Wait for IOC to clear Doorbell Status bit */
1236 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0) {
1242 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1244 * mpt_host_page_alloc - allocate system memory for the fw
1245 * @ioc: Pointer to pointer to IOC adapter
1246 * @ioc_init: Pointer to ioc init config page
1248 * If we already allocated memory in past, then resend the same pointer.
1249 * Returns 0 for success, non-zero for failure.
1252 mpt_host_page_alloc(MPT_ADAPTER
*ioc
, pIOCInit_t ioc_init
)
1256 u32 host_page_buffer_sz
=0;
1258 if(!ioc
->HostPageBuffer
) {
1260 host_page_buffer_sz
=
1261 le32_to_cpu(ioc
->facts
.HostPageBufferSGE
.FlagsLength
) & 0xFFFFFF;
1263 if(!host_page_buffer_sz
)
1264 return 0; /* fw doesn't need any host buffers */
1266 /* spin till we get enough memory */
1267 while(host_page_buffer_sz
> 0) {
1269 if((ioc
->HostPageBuffer
= pci_alloc_consistent(
1271 host_page_buffer_sz
,
1272 &ioc
->HostPageBuffer_dma
)) != NULL
) {
1274 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
1275 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1276 ioc
->name
, ioc
->HostPageBuffer
,
1277 (u32
)ioc
->HostPageBuffer_dma
,
1278 host_page_buffer_sz
));
1279 ioc
->alloc_total
+= host_page_buffer_sz
;
1280 ioc
->HostPageBuffer_sz
= host_page_buffer_sz
;
1284 host_page_buffer_sz
-= (4*1024);
1288 if(!ioc
->HostPageBuffer
) {
1289 printk(MYIOC_s_ERR_FMT
1290 "Failed to alloc memory for host_page_buffer!\n",
1295 psge
= (char *)&ioc_init
->HostPageBufferSGE
;
1296 flags_length
= MPI_SGE_FLAGS_SIMPLE_ELEMENT
|
1297 MPI_SGE_FLAGS_SYSTEM_ADDRESS
|
1298 MPI_SGE_FLAGS_32_BIT_ADDRESSING
|
1299 MPI_SGE_FLAGS_HOST_TO_IOC
|
1300 MPI_SGE_FLAGS_END_OF_BUFFER
;
1301 if (sizeof(dma_addr_t
) == sizeof(u64
)) {
1302 flags_length
|= MPI_SGE_FLAGS_64_BIT_ADDRESSING
;
1304 flags_length
= flags_length
<< MPI_SGE_FLAGS_SHIFT
;
1305 flags_length
|= ioc
->HostPageBuffer_sz
;
1306 ioc
->add_sge(psge
, flags_length
, ioc
->HostPageBuffer_dma
);
1307 ioc
->facts
.HostPageBufferSGE
= ioc_init
->HostPageBufferSGE
;
1312 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1314 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1315 * @iocid: IOC unique identifier (integer)
1316 * @iocpp: Pointer to pointer to IOC adapter
1318 * Given a unique IOC identifier, set pointer to the associated MPT
1319 * adapter structure.
1321 * Returns iocid and sets iocpp if iocid is found.
1322 * Returns -1 if iocid is not found.
1325 mpt_verify_adapter(int iocid
, MPT_ADAPTER
**iocpp
)
1329 list_for_each_entry(ioc
,&ioc_list
,list
) {
1330 if (ioc
->id
== iocid
) {
1341 * mpt_get_product_name - returns product string
1342 * @vendor: pci vendor id
1343 * @device: pci device id
1344 * @revision: pci revision id
1345 * @prod_name: string returned
1347 * Returns product string displayed when driver loads,
1348 * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1352 mpt_get_product_name(u16 vendor
, u16 device
, u8 revision
, char *prod_name
)
1354 char *product_str
= NULL
;
1356 if (vendor
== PCI_VENDOR_ID_BROCADE
) {
1359 case MPI_MANUFACTPAGE_DEVICEID_FC949E
:
1363 product_str
= "BRE040 A0";
1366 product_str
= "BRE040 A1";
1369 product_str
= "BRE040";
1379 case MPI_MANUFACTPAGE_DEVICEID_FC909
:
1380 product_str
= "LSIFC909 B1";
1382 case MPI_MANUFACTPAGE_DEVICEID_FC919
:
1383 product_str
= "LSIFC919 B0";
1385 case MPI_MANUFACTPAGE_DEVICEID_FC929
:
1386 product_str
= "LSIFC929 B0";
1388 case MPI_MANUFACTPAGE_DEVICEID_FC919X
:
1389 if (revision
< 0x80)
1390 product_str
= "LSIFC919X A0";
1392 product_str
= "LSIFC919XL A1";
1394 case MPI_MANUFACTPAGE_DEVICEID_FC929X
:
1395 if (revision
< 0x80)
1396 product_str
= "LSIFC929X A0";
1398 product_str
= "LSIFC929XL A1";
1400 case MPI_MANUFACTPAGE_DEVICEID_FC939X
:
1401 product_str
= "LSIFC939X A1";
1403 case MPI_MANUFACTPAGE_DEVICEID_FC949X
:
1404 product_str
= "LSIFC949X A1";
1406 case MPI_MANUFACTPAGE_DEVICEID_FC949E
:
1410 product_str
= "LSIFC949E A0";
1413 product_str
= "LSIFC949E A1";
1416 product_str
= "LSIFC949E";
1420 case MPI_MANUFACTPAGE_DEVID_53C1030
:
1424 product_str
= "LSI53C1030 A0";
1427 product_str
= "LSI53C1030 B0";
1430 product_str
= "LSI53C1030 B1";
1433 product_str
= "LSI53C1030 B2";
1436 product_str
= "LSI53C1030 C0";
1439 product_str
= "LSI53C1030T A0";
1442 product_str
= "LSI53C1030T A2";
1445 product_str
= "LSI53C1030T A3";
1448 product_str
= "LSI53C1020A A1";
1451 product_str
= "LSI53C1030";
1455 case MPI_MANUFACTPAGE_DEVID_1030_53C1035
:
1459 product_str
= "LSI53C1035 A2";
1462 product_str
= "LSI53C1035 B0";
1465 product_str
= "LSI53C1035";
1469 case MPI_MANUFACTPAGE_DEVID_SAS1064
:
1473 product_str
= "LSISAS1064 A1";
1476 product_str
= "LSISAS1064 A2";
1479 product_str
= "LSISAS1064 A3";
1482 product_str
= "LSISAS1064 A4";
1485 product_str
= "LSISAS1064";
1489 case MPI_MANUFACTPAGE_DEVID_SAS1064E
:
1493 product_str
= "LSISAS1064E A0";
1496 product_str
= "LSISAS1064E B0";
1499 product_str
= "LSISAS1064E B1";
1502 product_str
= "LSISAS1064E B2";
1505 product_str
= "LSISAS1064E B3";
1508 product_str
= "LSISAS1064E";
1512 case MPI_MANUFACTPAGE_DEVID_SAS1068
:
1516 product_str
= "LSISAS1068 A0";
1519 product_str
= "LSISAS1068 B0";
1522 product_str
= "LSISAS1068 B1";
1525 product_str
= "LSISAS1068";
1529 case MPI_MANUFACTPAGE_DEVID_SAS1068E
:
1533 product_str
= "LSISAS1068E A0";
1536 product_str
= "LSISAS1068E B0";
1539 product_str
= "LSISAS1068E B1";
1542 product_str
= "LSISAS1068E B2";
1545 product_str
= "LSISAS1068E B3";
1548 product_str
= "LSISAS1068E";
1552 case MPI_MANUFACTPAGE_DEVID_SAS1078
:
1556 product_str
= "LSISAS1078 A0";
1559 product_str
= "LSISAS1078 B0";
1562 product_str
= "LSISAS1078 C0";
1565 product_str
= "LSISAS1078 C1";
1568 product_str
= "LSISAS1078 C2";
1571 product_str
= "LSISAS1078";
1579 sprintf(prod_name
, "%s", product_str
);
1583 * mpt_mapresources - map in memory mapped io
1584 * @ioc: Pointer to pointer to IOC adapter
1588 mpt_mapresources(MPT_ADAPTER
*ioc
)
1592 unsigned long mem_phys
;
1598 struct pci_dev
*pdev
;
1601 ioc
->bars
= pci_select_bars(pdev
, IORESOURCE_MEM
);
1602 if (pci_enable_device_mem(pdev
)) {
1603 printk(MYIOC_s_ERR_FMT
"pci_enable_device_mem() "
1604 "failed\n", ioc
->name
);
1607 if (pci_request_selected_regions(pdev
, ioc
->bars
, "mpt")) {
1608 printk(MYIOC_s_ERR_FMT
"pci_request_selected_regions() with "
1609 "MEM failed\n", ioc
->name
);
1613 pci_read_config_byte(pdev
, PCI_CLASS_REVISION
, &revision
);
1615 if (sizeof(dma_addr_t
) > 4) {
1616 const uint64_t required_mask
= dma_get_required_mask
1618 if (required_mask
> DMA_BIT_MASK(32)
1619 && !pci_set_dma_mask(pdev
, DMA_BIT_MASK(64))
1620 && !pci_set_consistent_dma_mask(pdev
,
1621 DMA_BIT_MASK(64))) {
1622 ioc
->dma_mask
= DMA_BIT_MASK(64);
1623 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
1624 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1626 } else if (!pci_set_dma_mask(pdev
, DMA_BIT_MASK(32))
1627 && !pci_set_consistent_dma_mask(pdev
,
1628 DMA_BIT_MASK(32))) {
1629 ioc
->dma_mask
= DMA_BIT_MASK(32);
1630 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
1631 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1634 printk(MYIOC_s_WARN_FMT
"no suitable DMA mask for %s\n",
1635 ioc
->name
, pci_name(pdev
));
1639 if (!pci_set_dma_mask(pdev
, DMA_BIT_MASK(32))
1640 && !pci_set_consistent_dma_mask(pdev
,
1641 DMA_BIT_MASK(32))) {
1642 ioc
->dma_mask
= DMA_BIT_MASK(32);
1643 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
1644 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1647 printk(MYIOC_s_WARN_FMT
"no suitable DMA mask for %s\n",
1648 ioc
->name
, pci_name(pdev
));
1653 mem_phys
= msize
= 0;
1655 for (ii
= 0; ii
< DEVICE_COUNT_RESOURCE
; ii
++) {
1656 if (pci_resource_flags(pdev
, ii
) & PCI_BASE_ADDRESS_SPACE_IO
) {
1659 /* Get I/O space! */
1660 port
= pci_resource_start(pdev
, ii
);
1661 psize
= pci_resource_len(pdev
, ii
);
1666 mem_phys
= pci_resource_start(pdev
, ii
);
1667 msize
= pci_resource_len(pdev
, ii
);
1670 ioc
->mem_size
= msize
;
1673 /* Get logical ptr for PciMem0 space */
1674 /*mem = ioremap(mem_phys, msize);*/
1675 mem
= ioremap(mem_phys
, msize
);
1677 printk(MYIOC_s_ERR_FMT
": ERROR - Unable to map adapter"
1678 " memory!\n", ioc
->name
);
1682 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"mem = %p, mem_phys = %lx\n",
1683 ioc
->name
, mem
, mem_phys
));
1685 ioc
->mem_phys
= mem_phys
;
1686 ioc
->chip
= (SYSIF_REGS __iomem
*)mem
;
1688 /* Save Port IO values in case we need to do downloadboot */
1689 ioc
->pio_mem_phys
= port
;
1690 ioc
->pio_chip
= (SYSIF_REGS __iomem
*)port
;
1695 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1697 * mpt_attach - Install a PCI intelligent MPT adapter.
1698 * @pdev: Pointer to pci_dev structure
1699 * @id: PCI device ID information
1701 * This routine performs all the steps necessary to bring the IOC of
1702 * a MPT adapter to a OPERATIONAL state. This includes registering
1703 * memory regions, registering the interrupt, and allocating request
1704 * and reply memory pools.
1706 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1709 * Returns 0 for success, non-zero for failure.
1711 * TODO: Add support for polled controllers
1714 mpt_attach(struct pci_dev
*pdev
, const struct pci_device_id
*id
)
1721 static int mpt_ids
= 0;
1722 #ifdef CONFIG_PROC_FS
1723 struct proc_dir_entry
*dent
, *ent
;
1726 ioc
= kzalloc(sizeof(MPT_ADAPTER
), GFP_ATOMIC
);
1728 printk(KERN_ERR MYNAM
": ERROR - Insufficient memory to add adapter!\n");
1732 ioc
->id
= mpt_ids
++;
1733 sprintf(ioc
->name
, "ioc%d", ioc
->id
);
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
;
1774 ioc
->diagPending
= 0;
1775 spin_lock_init(&ioc
->diagLock
);
1776 spin_lock_init(&ioc
->initializing_hba_lock
);
1778 mutex_init(&ioc
->mptbase_cmds
.mutex
);
1779 init_completion(&ioc
->mptbase_cmds
.done
);
1781 /* Initialize the event logging.
1783 ioc
->eventTypes
= 0; /* None */
1784 ioc
->eventContext
= 0;
1785 ioc
->eventLogSize
= 0;
1792 ioc
->cached_fw
= NULL
;
1794 /* Initilize SCSI Config Data structure
1796 memset(&ioc
->spi_data
, 0, sizeof(SpiCfgData
));
1798 /* Initialize the fc rport list head.
1800 INIT_LIST_HEAD(&ioc
->fc_rports
);
1802 /* Find lookup slot. */
1803 INIT_LIST_HEAD(&ioc
->list
);
1806 /* Initialize workqueue */
1807 INIT_DELAYED_WORK(&ioc
->fault_reset_work
, mpt_fault_reset_work
);
1808 spin_lock_init(&ioc
->fault_reset_work_lock
);
1810 snprintf(ioc
->reset_work_q_name
, sizeof(ioc
->reset_work_q_name
),
1811 "mpt_poll_%d", ioc
->id
);
1813 create_singlethread_workqueue(ioc
->reset_work_q_name
);
1814 if (!ioc
->reset_work_q
) {
1815 printk(MYIOC_s_ERR_FMT
"Insufficient memory to add adapter!\n",
1817 pci_release_selected_regions(pdev
, ioc
->bars
);
1822 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"facts @ %p, pfacts[0] @ %p\n",
1823 ioc
->name
, &ioc
->facts
, &ioc
->pfacts
[0]));
1825 pci_read_config_byte(pdev
, PCI_CLASS_REVISION
, &revision
);
1826 mpt_get_product_name(pdev
->vendor
, pdev
->device
, revision
, ioc
->prod_name
);
1828 switch (pdev
->device
)
1830 case MPI_MANUFACTPAGE_DEVICEID_FC939X
:
1831 case MPI_MANUFACTPAGE_DEVICEID_FC949X
:
1832 ioc
->errata_flag_1064
= 1;
1833 case MPI_MANUFACTPAGE_DEVICEID_FC909
:
1834 case MPI_MANUFACTPAGE_DEVICEID_FC929
:
1835 case MPI_MANUFACTPAGE_DEVICEID_FC919
:
1836 case MPI_MANUFACTPAGE_DEVICEID_FC949E
:
1840 case MPI_MANUFACTPAGE_DEVICEID_FC929X
:
1841 if (revision
< XL_929
) {
1842 /* 929X Chip Fix. Set Split transactions level
1843 * for PCIX. Set MOST bits to zero.
1845 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1847 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1849 /* 929XL Chip Fix. Set MMRBC to 0x08.
1851 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1853 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1858 case MPI_MANUFACTPAGE_DEVICEID_FC919X
:
1859 /* 919X Chip Fix. Set Split transactions level
1860 * for PCIX. Set MOST bits to zero.
1862 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1864 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1868 case MPI_MANUFACTPAGE_DEVID_53C1030
:
1869 /* 1030 Chip Fix. Disable Split transactions
1870 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1872 if (revision
< C0_1030
) {
1873 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1875 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1878 case MPI_MANUFACTPAGE_DEVID_1030_53C1035
:
1879 ioc
->bus_type
= SPI
;
1882 case MPI_MANUFACTPAGE_DEVID_SAS1064
:
1883 case MPI_MANUFACTPAGE_DEVID_SAS1068
:
1884 ioc
->errata_flag_1064
= 1;
1886 case MPI_MANUFACTPAGE_DEVID_SAS1064E
:
1887 case MPI_MANUFACTPAGE_DEVID_SAS1068E
:
1888 case MPI_MANUFACTPAGE_DEVID_SAS1078
:
1889 ioc
->bus_type
= SAS
;
1893 switch (ioc
->bus_type
) {
1896 ioc
->msi_enable
= mpt_msi_enable_sas
;
1900 ioc
->msi_enable
= mpt_msi_enable_spi
;
1904 ioc
->msi_enable
= mpt_msi_enable_fc
;
1908 ioc
->msi_enable
= 0;
1911 if (ioc
->errata_flag_1064
)
1912 pci_disable_io_access(pdev
);
1914 spin_lock_init(&ioc
->FreeQlock
);
1917 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
1919 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1921 /* Set IOC ptr in the pcidev's driver data. */
1922 pci_set_drvdata(ioc
->pcidev
, ioc
);
1924 /* Set lookup ptr. */
1925 list_add_tail(&ioc
->list
, &ioc_list
);
1927 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1929 mpt_detect_bound_ports(ioc
, pdev
);
1931 if ((r
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_BRINGUP
,
1933 printk(MYIOC_s_ERR_FMT
"didn't initialize properly! (%d)\n",
1936 list_del(&ioc
->list
);
1938 ioc
->alt_ioc
->alt_ioc
= NULL
;
1939 iounmap(ioc
->memmap
);
1941 pci_release_selected_regions(pdev
, ioc
->bars
);
1943 destroy_workqueue(ioc
->reset_work_q
);
1944 ioc
->reset_work_q
= NULL
;
1947 pci_set_drvdata(pdev
, NULL
);
1951 /* call per device driver probe entry point */
1952 for(cb_idx
= 0; cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
; cb_idx
++) {
1953 if(MptDeviceDriverHandlers
[cb_idx
] &&
1954 MptDeviceDriverHandlers
[cb_idx
]->probe
) {
1955 MptDeviceDriverHandlers
[cb_idx
]->probe(pdev
,id
);
1959 #ifdef CONFIG_PROC_FS
1961 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1963 dent
= proc_mkdir(ioc
->name
, mpt_proc_root_dir
);
1965 ent
= create_proc_entry("info", S_IFREG
|S_IRUGO
, dent
);
1967 ent
->read_proc
= procmpt_iocinfo_read
;
1970 ent
= create_proc_entry("summary", S_IFREG
|S_IRUGO
, dent
);
1972 ent
->read_proc
= procmpt_summary_read
;
1979 queue_delayed_work(ioc
->reset_work_q
, &ioc
->fault_reset_work
,
1980 msecs_to_jiffies(MPT_POLLING_INTERVAL
));
1985 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1987 * mpt_detach - Remove a PCI intelligent MPT adapter.
1988 * @pdev: Pointer to pci_dev structure
1992 mpt_detach(struct pci_dev
*pdev
)
1994 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
1997 unsigned long flags
;
1998 struct workqueue_struct
*wq
;
2001 * Stop polling ioc for fault condition
2003 spin_lock_irqsave(&ioc
->fault_reset_work_lock
, flags
);
2004 wq
= ioc
->reset_work_q
;
2005 ioc
->reset_work_q
= NULL
;
2006 spin_unlock_irqrestore(&ioc
->fault_reset_work_lock
, flags
);
2007 cancel_delayed_work(&ioc
->fault_reset_work
);
2008 destroy_workqueue(wq
);
2011 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s/summary", ioc
->name
);
2012 remove_proc_entry(pname
, NULL
);
2013 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s/info", ioc
->name
);
2014 remove_proc_entry(pname
, NULL
);
2015 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s", ioc
->name
);
2016 remove_proc_entry(pname
, NULL
);
2018 /* call per device driver remove entry point */
2019 for(cb_idx
= 0; cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
; cb_idx
++) {
2020 if(MptDeviceDriverHandlers
[cb_idx
] &&
2021 MptDeviceDriverHandlers
[cb_idx
]->remove
) {
2022 MptDeviceDriverHandlers
[cb_idx
]->remove(pdev
);
2026 /* Disable interrupts! */
2027 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2030 synchronize_irq(pdev
->irq
);
2032 /* Clear any lingering interrupt */
2033 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
2035 CHIPREG_READ32(&ioc
->chip
->IntStatus
);
2037 mpt_adapter_dispose(ioc
);
2039 pci_set_drvdata(pdev
, NULL
);
2042 /**************************************************************************
2046 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2048 * mpt_suspend - Fusion MPT base driver suspend routine.
2049 * @pdev: Pointer to pci_dev structure
2050 * @state: new state to enter
2053 mpt_suspend(struct pci_dev
*pdev
, pm_message_t state
)
2056 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
2058 device_state
= pci_choose_state(pdev
, state
);
2059 printk(MYIOC_s_INFO_FMT
"pci-suspend: pdev=0x%p, slot=%s, Entering "
2060 "operating state [D%d]\n", ioc
->name
, pdev
, pci_name(pdev
),
2063 /* put ioc into READY_STATE */
2064 if(SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, CAN_SLEEP
)) {
2065 printk(MYIOC_s_ERR_FMT
2066 "pci-suspend: IOC msg unit reset failed!\n", ioc
->name
);
2069 /* disable interrupts */
2070 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2073 /* Clear any lingering interrupt */
2074 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
2076 free_irq(ioc
->pci_irq
, ioc
);
2077 if (ioc
->msi_enable
)
2078 pci_disable_msi(ioc
->pcidev
);
2080 pci_save_state(pdev
);
2081 pci_disable_device(pdev
);
2082 pci_release_selected_regions(pdev
, ioc
->bars
);
2083 pci_set_power_state(pdev
, device_state
);
2087 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2089 * mpt_resume - Fusion MPT base driver resume routine.
2090 * @pdev: Pointer to pci_dev structure
2093 mpt_resume(struct pci_dev
*pdev
)
2095 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
2096 u32 device_state
= pdev
->current_state
;
2100 printk(MYIOC_s_INFO_FMT
"pci-resume: pdev=0x%p, slot=%s, Previous "
2101 "operating state [D%d]\n", ioc
->name
, pdev
, pci_name(pdev
),
2104 pci_set_power_state(pdev
, PCI_D0
);
2105 pci_enable_wake(pdev
, PCI_D0
, 0);
2106 pci_restore_state(pdev
);
2108 err
= mpt_mapresources(ioc
);
2112 if (ioc
->dma_mask
== DMA_BIT_MASK(64)) {
2113 if (pdev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1078
)
2114 ioc
->add_sge
= &mpt_add_sge_64bit_1078
;
2116 ioc
->add_sge
= &mpt_add_sge_64bit
;
2117 ioc
->add_chain
= &mpt_add_chain_64bit
;
2118 ioc
->sg_addr_size
= 8;
2121 ioc
->add_sge
= &mpt_add_sge
;
2122 ioc
->add_chain
= &mpt_add_chain
;
2123 ioc
->sg_addr_size
= 4;
2125 ioc
->SGE_size
= sizeof(u32
) + ioc
->sg_addr_size
;
2127 printk(MYIOC_s_INFO_FMT
"pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
2128 ioc
->name
, (mpt_GetIocState(ioc
, 1) >> MPI_IOC_STATE_SHIFT
),
2129 CHIPREG_READ32(&ioc
->chip
->Doorbell
));
2132 * Errata workaround for SAS pci express:
2133 * Upon returning to the D0 state, the contents of the doorbell will be
2134 * stale data, and this will incorrectly signal to the host driver that
2135 * the firmware is ready to process mpt commands. The workaround is
2136 * to issue a diagnostic reset.
2138 if (ioc
->bus_type
== SAS
&& (pdev
->device
==
2139 MPI_MANUFACTPAGE_DEVID_SAS1068E
|| pdev
->device
==
2140 MPI_MANUFACTPAGE_DEVID_SAS1064E
)) {
2141 if (KickStart(ioc
, 1, CAN_SLEEP
) < 0) {
2142 printk(MYIOC_s_WARN_FMT
"pci-resume: Cannot recover\n",
2148 /* bring ioc to operational state */
2149 printk(MYIOC_s_INFO_FMT
"Sending mpt_do_ioc_recovery\n", ioc
->name
);
2150 recovery_state
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_BRINGUP
,
2152 if (recovery_state
!= 0)
2153 printk(MYIOC_s_WARN_FMT
"pci-resume: Cannot recover, "
2154 "error:[%x]\n", ioc
->name
, recovery_state
);
2156 printk(MYIOC_s_INFO_FMT
2157 "pci-resume: success\n", ioc
->name
);
2165 mpt_signal_reset(u8 index
, MPT_ADAPTER
*ioc
, int reset_phase
)
2167 if ((MptDriverClass
[index
] == MPTSPI_DRIVER
&&
2168 ioc
->bus_type
!= SPI
) ||
2169 (MptDriverClass
[index
] == MPTFC_DRIVER
&&
2170 ioc
->bus_type
!= FC
) ||
2171 (MptDriverClass
[index
] == MPTSAS_DRIVER
&&
2172 ioc
->bus_type
!= SAS
))
2173 /* make sure we only call the relevant reset handler
2176 return (MptResetHandlers
[index
])(ioc
, reset_phase
);
2179 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2181 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
2182 * @ioc: Pointer to MPT adapter structure
2183 * @reason: Event word / reason
2184 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
2186 * This routine performs all the steps necessary to bring the IOC
2187 * to a OPERATIONAL state.
2189 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
2194 * -1 if failed to get board READY
2195 * -2 if READY but IOCFacts Failed
2196 * -3 if READY but PrimeIOCFifos Failed
2197 * -4 if READY but IOCInit Failed
2198 * -5 if failed to enable_device and/or request_selected_regions
2199 * -6 if failed to upload firmware
2202 mpt_do_ioc_recovery(MPT_ADAPTER
*ioc
, u32 reason
, int sleepFlag
)
2204 int hard_reset_done
= 0;
2205 int alt_ioc_ready
= 0;
2212 int reset_alt_ioc_active
= 0;
2213 int irq_allocated
= 0;
2216 printk(MYIOC_s_INFO_FMT
"Initiating %s\n", ioc
->name
,
2217 reason
== MPT_HOSTEVENT_IOC_BRINGUP
? "bringup" : "recovery");
2219 /* Disable reply interrupts (also blocks FreeQ) */
2220 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2224 if (ioc
->alt_ioc
->active
)
2225 reset_alt_ioc_active
= 1;
2227 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
2228 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
, 0xFFFFFFFF);
2229 ioc
->alt_ioc
->active
= 0;
2233 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)
2236 if ((hard_reset_done
= MakeIocReady(ioc
, hard
, sleepFlag
)) < 0) {
2237 if (hard_reset_done
== -4) {
2238 printk(MYIOC_s_WARN_FMT
"Owned by PEER..skipping!\n",
2241 if (reset_alt_ioc_active
&& ioc
->alt_ioc
) {
2242 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
2243 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
2244 "alt_ioc reply irq re-enabled\n", ioc
->alt_ioc
->name
));
2245 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
, MPI_HIM_DIM
);
2246 ioc
->alt_ioc
->active
= 1;
2250 printk(MYIOC_s_WARN_FMT
"NOT READY!\n", ioc
->name
);
2255 /* hard_reset_done = 0 if a soft reset was performed
2256 * and 1 if a hard reset was performed.
2258 if (hard_reset_done
&& reset_alt_ioc_active
&& ioc
->alt_ioc
) {
2259 if ((rc
= MakeIocReady(ioc
->alt_ioc
, 0, sleepFlag
)) == 0)
2262 printk(MYIOC_s_WARN_FMT
"alt_ioc not ready!\n", ioc
->alt_ioc
->name
);
2265 for (ii
=0; ii
<5; ii
++) {
2266 /* Get IOC facts! Allow 5 retries */
2267 if ((rc
= GetIocFacts(ioc
, sleepFlag
, reason
)) == 0)
2273 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2274 "Retry IocFacts failed rc=%x\n", ioc
->name
, rc
));
2276 } else if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
2277 MptDisplayIocCapabilities(ioc
);
2280 if (alt_ioc_ready
) {
2281 if ((rc
= GetIocFacts(ioc
->alt_ioc
, sleepFlag
, reason
)) != 0) {
2282 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2283 "Initial Alt IocFacts failed rc=%x\n", ioc
->name
, rc
));
2284 /* Retry - alt IOC was initialized once
2286 rc
= GetIocFacts(ioc
->alt_ioc
, sleepFlag
, reason
);
2289 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2290 "Retry Alt IocFacts failed rc=%x\n", ioc
->name
, rc
));
2292 reset_alt_ioc_active
= 0;
2293 } else if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
2294 MptDisplayIocCapabilities(ioc
->alt_ioc
);
2298 if ((ret
== 0) && (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) &&
2299 (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)) {
2300 pci_release_selected_regions(ioc
->pcidev
, ioc
->bars
);
2301 ioc
->bars
= pci_select_bars(ioc
->pcidev
, IORESOURCE_MEM
|
2303 if (pci_enable_device(ioc
->pcidev
))
2305 if (pci_request_selected_regions(ioc
->pcidev
, ioc
->bars
,
2311 * Device is reset now. It must have de-asserted the interrupt line
2312 * (if it was asserted) and it should be safe to register for the
2315 if ((ret
== 0) && (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)) {
2317 if (ioc
->pcidev
->irq
) {
2318 if (ioc
->msi_enable
&& !pci_enable_msi(ioc
->pcidev
))
2319 printk(MYIOC_s_INFO_FMT
"PCI-MSI enabled\n",
2322 ioc
->msi_enable
= 0;
2323 rc
= request_irq(ioc
->pcidev
->irq
, mpt_interrupt
,
2324 IRQF_SHARED
, ioc
->name
, ioc
);
2326 printk(MYIOC_s_ERR_FMT
"Unable to allocate "
2327 "interrupt %d!\n", ioc
->name
, ioc
->pcidev
->irq
);
2328 if (ioc
->msi_enable
)
2329 pci_disable_msi(ioc
->pcidev
);
2333 ioc
->pci_irq
= ioc
->pcidev
->irq
;
2334 pci_set_master(ioc
->pcidev
); /* ?? */
2335 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
"installed at interrupt "
2336 "%d\n", ioc
->name
, ioc
->pcidev
->irq
));
2340 /* Prime reply & request queues!
2341 * (mucho alloc's) Must be done prior to
2342 * init as upper addresses are needed for init.
2343 * If fails, continue with alt-ioc processing
2345 if ((ret
== 0) && ((rc
= PrimeIocFifos(ioc
)) != 0))
2348 /* May need to check/upload firmware & data here!
2349 * If fails, continue with alt-ioc processing
2351 if ((ret
== 0) && ((rc
= SendIocInit(ioc
, sleepFlag
)) != 0))
2354 if (alt_ioc_ready
&& ((rc
= PrimeIocFifos(ioc
->alt_ioc
)) != 0)) {
2355 printk(MYIOC_s_WARN_FMT
": alt_ioc (%d) FIFO mgmt alloc!\n",
2356 ioc
->alt_ioc
->name
, rc
);
2358 reset_alt_ioc_active
= 0;
2361 if (alt_ioc_ready
) {
2362 if ((rc
= SendIocInit(ioc
->alt_ioc
, sleepFlag
)) != 0) {
2364 reset_alt_ioc_active
= 0;
2365 printk(MYIOC_s_WARN_FMT
"alt_ioc (%d) init failure!\n",
2366 ioc
->alt_ioc
->name
, rc
);
2370 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
){
2371 if (ioc
->upload_fw
) {
2372 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2373 "firmware upload required!\n", ioc
->name
));
2375 /* Controller is not operational, cannot do upload
2378 rc
= mpt_do_upload(ioc
, sleepFlag
);
2380 if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
) {
2382 * Maintain only one pointer to FW memory
2383 * so there will not be two attempt to
2384 * downloadboot onboard dual function
2385 * chips (mpt_adapter_disable,
2388 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2389 "mpt_upload: alt_%s has cached_fw=%p \n",
2390 ioc
->name
, ioc
->alt_ioc
->name
, ioc
->alt_ioc
->cached_fw
));
2391 ioc
->cached_fw
= NULL
;
2394 printk(MYIOC_s_WARN_FMT
2395 "firmware upload failure!\n", ioc
->name
);
2402 /* Enable MPT base driver management of EventNotification
2403 * and EventAck handling.
2405 if ((ret
== 0) && (!ioc
->facts
.EventState
)) {
2406 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
2407 "SendEventNotification\n",
2409 ret
= SendEventNotification(ioc
, 1, sleepFlag
); /* 1=Enable */
2412 if (ioc
->alt_ioc
&& alt_ioc_ready
&& !ioc
->alt_ioc
->facts
.EventState
)
2413 rc
= SendEventNotification(ioc
->alt_ioc
, 1, sleepFlag
);
2416 /* Enable! (reply interrupt) */
2417 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, MPI_HIM_DIM
);
2420 if (rc
== 0) { /* alt ioc */
2421 if (reset_alt_ioc_active
&& ioc
->alt_ioc
) {
2422 /* (re)Enable alt-IOC! (reply interrupt) */
2423 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"alt-ioc"
2424 "reply irq re-enabled\n",
2425 ioc
->alt_ioc
->name
));
2426 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
,
2428 ioc
->alt_ioc
->active
= 1;
2433 /* Add additional "reason" check before call to GetLanConfigPages
2434 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2435 * recursive scenario; GetLanConfigPages times out, timer expired
2436 * routine calls HardResetHandler, which calls into here again,
2437 * and we try GetLanConfigPages again...
2439 if ((ret
== 0) && (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)) {
2442 * Initalize link list for inactive raid volumes.
2444 mutex_init(&ioc
->raid_data
.inactive_list_mutex
);
2445 INIT_LIST_HEAD(&ioc
->raid_data
.inactive_list
);
2447 if (ioc
->bus_type
== SAS
) {
2449 /* clear persistency table */
2450 if(ioc
->facts
.IOCExceptions
&
2451 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL
) {
2452 ret
= mptbase_sas_persist_operation(ioc
,
2453 MPI_SAS_OP_CLEAR_NOT_PRESENT
);
2460 mpt_findImVolumes(ioc
);
2462 } else if (ioc
->bus_type
== FC
) {
2463 if ((ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
) &&
2464 (ioc
->lan_cnfg_page0
.Header
.PageLength
== 0)) {
2466 * Pre-fetch the ports LAN MAC address!
2467 * (LANPage1_t stuff)
2469 (void) GetLanConfigPages(ioc
);
2470 a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
2471 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2472 "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
2473 ioc
->name
, a
[5], a
[4], a
[3], a
[2], a
[1], a
[0]));
2477 /* Get NVRAM and adapter maximums from SPP 0 and 2
2479 mpt_GetScsiPortSettings(ioc
, 0);
2481 /* Get version and length of SDP 1
2483 mpt_readScsiDevicePageHeaders(ioc
, 0);
2487 if (ioc
->facts
.MsgVersion
>= MPI_VERSION_01_02
)
2488 mpt_findImVolumes(ioc
);
2490 /* Check, and possibly reset, the coalescing value
2492 mpt_read_ioc_pg_1(ioc
);
2494 mpt_read_ioc_pg_4(ioc
);
2497 GetIoUnitPage2(ioc
);
2498 mpt_get_manufacturing_pg_0(ioc
);
2502 * Call each currently registered protocol IOC reset handler
2503 * with post-reset indication.
2504 * NOTE: If we're doing _IOC_BRINGUP, there can be no
2505 * MptResetHandlers[] registered yet.
2507 if (hard_reset_done
) {
2509 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
2510 if ((ret
== 0) && MptResetHandlers
[cb_idx
]) {
2511 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2512 "Calling IOC post_reset handler #%d\n",
2513 ioc
->name
, cb_idx
));
2514 rc
+= mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_POST_RESET
);
2518 if (alt_ioc_ready
&& MptResetHandlers
[cb_idx
]) {
2519 drsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2520 "Calling IOC post_reset handler #%d\n",
2521 ioc
->alt_ioc
->name
, cb_idx
));
2522 rc
+= mpt_signal_reset(cb_idx
, ioc
->alt_ioc
, MPT_IOC_POST_RESET
);
2526 /* FIXME? Examine results here? */
2530 if ((ret
!= 0) && irq_allocated
) {
2531 free_irq(ioc
->pci_irq
, ioc
);
2532 if (ioc
->msi_enable
)
2533 pci_disable_msi(ioc
->pcidev
);
2538 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2540 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2541 * @ioc: Pointer to MPT adapter structure
2542 * @pdev: Pointer to (struct pci_dev) structure
2544 * Search for PCI bus/dev_function which matches
2545 * PCI bus/dev_function (+/-1) for newly discovered 929,
2546 * 929X, 1030 or 1035.
2548 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2549 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2552 mpt_detect_bound_ports(MPT_ADAPTER
*ioc
, struct pci_dev
*pdev
)
2554 struct pci_dev
*peer
=NULL
;
2555 unsigned int slot
= PCI_SLOT(pdev
->devfn
);
2556 unsigned int func
= PCI_FUNC(pdev
->devfn
);
2557 MPT_ADAPTER
*ioc_srch
;
2559 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"PCI device %s devfn=%x/%x,"
2560 " searching for devfn match on %x or %x\n",
2561 ioc
->name
, pci_name(pdev
), pdev
->bus
->number
,
2562 pdev
->devfn
, func
-1, func
+1));
2564 peer
= pci_get_slot(pdev
->bus
, PCI_DEVFN(slot
,func
-1));
2566 peer
= pci_get_slot(pdev
->bus
, PCI_DEVFN(slot
,func
+1));
2571 list_for_each_entry(ioc_srch
, &ioc_list
, list
) {
2572 struct pci_dev
*_pcidev
= ioc_srch
->pcidev
;
2573 if (_pcidev
== peer
) {
2574 /* Paranoia checks */
2575 if (ioc
->alt_ioc
!= NULL
) {
2576 printk(MYIOC_s_WARN_FMT
"Oops, already bound to %s!\n",
2577 ioc
->name
, ioc
->alt_ioc
->name
);
2579 } else if (ioc_srch
->alt_ioc
!= NULL
) {
2580 printk(MYIOC_s_WARN_FMT
"Oops, already bound to %s!\n",
2581 ioc_srch
->name
, ioc_srch
->alt_ioc
->name
);
2584 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
"FOUND! binding to %s\n",
2585 ioc
->name
, ioc_srch
->name
));
2586 ioc_srch
->alt_ioc
= ioc
;
2587 ioc
->alt_ioc
= ioc_srch
;
2593 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2595 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2596 * @ioc: Pointer to MPT adapter structure
2599 mpt_adapter_disable(MPT_ADAPTER
*ioc
)
2604 if (ioc
->cached_fw
!= NULL
) {
2605 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"%s: Pushing FW onto "
2606 "adapter\n", __func__
, ioc
->name
));
2607 if ((ret
= mpt_downloadboot(ioc
, (MpiFwHeader_t
*)
2608 ioc
->cached_fw
, CAN_SLEEP
)) < 0) {
2609 printk(MYIOC_s_WARN_FMT
2610 ": firmware downloadboot failure (%d)!\n",
2615 /* Disable adapter interrupts! */
2616 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2618 /* Clear any lingering interrupt */
2619 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
2621 if (ioc
->alloc
!= NULL
) {
2623 dexitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"free @ %p, sz=%d bytes\n",
2624 ioc
->name
, ioc
->alloc
, ioc
->alloc_sz
));
2625 pci_free_consistent(ioc
->pcidev
, sz
,
2626 ioc
->alloc
, ioc
->alloc_dma
);
2627 ioc
->reply_frames
= NULL
;
2628 ioc
->req_frames
= NULL
;
2630 ioc
->alloc_total
-= sz
;
2633 if (ioc
->sense_buf_pool
!= NULL
) {
2634 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
2635 pci_free_consistent(ioc
->pcidev
, sz
,
2636 ioc
->sense_buf_pool
, ioc
->sense_buf_pool_dma
);
2637 ioc
->sense_buf_pool
= NULL
;
2638 ioc
->alloc_total
-= sz
;
2641 if (ioc
->events
!= NULL
){
2642 sz
= MPTCTL_EVENT_LOG_SIZE
* sizeof(MPT_IOCTL_EVENTS
);
2645 ioc
->alloc_total
-= sz
;
2648 mpt_free_fw_memory(ioc
);
2650 kfree(ioc
->spi_data
.nvram
);
2651 mpt_inactive_raid_list_free(ioc
);
2652 kfree(ioc
->raid_data
.pIocPg2
);
2653 kfree(ioc
->raid_data
.pIocPg3
);
2654 ioc
->spi_data
.nvram
= NULL
;
2655 ioc
->raid_data
.pIocPg3
= NULL
;
2657 if (ioc
->spi_data
.pIocPg4
!= NULL
) {
2658 sz
= ioc
->spi_data
.IocPg4Sz
;
2659 pci_free_consistent(ioc
->pcidev
, sz
,
2660 ioc
->spi_data
.pIocPg4
,
2661 ioc
->spi_data
.IocPg4_dma
);
2662 ioc
->spi_data
.pIocPg4
= NULL
;
2663 ioc
->alloc_total
-= sz
;
2666 if (ioc
->ReqToChain
!= NULL
) {
2667 kfree(ioc
->ReqToChain
);
2668 kfree(ioc
->RequestNB
);
2669 ioc
->ReqToChain
= NULL
;
2672 kfree(ioc
->ChainToChain
);
2673 ioc
->ChainToChain
= NULL
;
2675 if (ioc
->HostPageBuffer
!= NULL
) {
2676 if((ret
= mpt_host_page_access_control(ioc
,
2677 MPI_DB_HPBAC_FREE_BUFFER
, NO_SLEEP
)) != 0) {
2678 printk(MYIOC_s_ERR_FMT
2679 "host page buffers free failed (%d)!\n",
2682 dexitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"HostPageBuffer free @ %p, sz=%d bytes\n",
2683 ioc
->name
, ioc
->HostPageBuffer
, ioc
->HostPageBuffer_sz
));
2684 pci_free_consistent(ioc
->pcidev
, ioc
->HostPageBuffer_sz
,
2685 ioc
->HostPageBuffer
, ioc
->HostPageBuffer_dma
);
2686 ioc
->HostPageBuffer
= NULL
;
2687 ioc
->HostPageBuffer_sz
= 0;
2688 ioc
->alloc_total
-= ioc
->HostPageBuffer_sz
;
2692 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2694 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2695 * @ioc: Pointer to MPT adapter structure
2697 * This routine unregisters h/w resources and frees all alloc'd memory
2698 * associated with a MPT adapter structure.
2701 mpt_adapter_dispose(MPT_ADAPTER
*ioc
)
2703 int sz_first
, sz_last
;
2708 sz_first
= ioc
->alloc_total
;
2710 mpt_adapter_disable(ioc
);
2712 if (ioc
->pci_irq
!= -1) {
2713 free_irq(ioc
->pci_irq
, ioc
);
2714 if (ioc
->msi_enable
)
2715 pci_disable_msi(ioc
->pcidev
);
2719 if (ioc
->memmap
!= NULL
) {
2720 iounmap(ioc
->memmap
);
2724 pci_disable_device(ioc
->pcidev
);
2725 pci_release_selected_regions(ioc
->pcidev
, ioc
->bars
);
2727 #if defined(CONFIG_MTRR) && 0
2728 if (ioc
->mtrr_reg
> 0) {
2729 mtrr_del(ioc
->mtrr_reg
, 0, 0);
2730 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
"MTRR region de-registered\n", ioc
->name
));
2734 /* Zap the adapter lookup ptr! */
2735 list_del(&ioc
->list
);
2737 sz_last
= ioc
->alloc_total
;
2738 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
"free'd %d of %d bytes\n",
2739 ioc
->name
, sz_first
-sz_last
+(int)sizeof(*ioc
), sz_first
));
2742 ioc
->alt_ioc
->alt_ioc
= NULL
;
2747 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2749 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2750 * @ioc: Pointer to MPT adapter structure
2753 MptDisplayIocCapabilities(MPT_ADAPTER
*ioc
)
2757 printk(KERN_INFO
"%s: ", ioc
->name
);
2759 printk("%s: ", ioc
->prod_name
);
2760 printk("Capabilities={");
2762 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_INITIATOR
) {
2763 printk("Initiator");
2767 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_TARGET
) {
2768 printk("%sTarget", i
? "," : "");
2772 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
) {
2773 printk("%sLAN", i
? "," : "");
2779 * This would probably evoke more questions than it's worth
2781 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_TARGET
) {
2782 printk("%sLogBusAddr", i
? "," : "");
2790 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2792 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2793 * @ioc: Pointer to MPT_ADAPTER structure
2794 * @force: Force hard KickStart of IOC
2795 * @sleepFlag: Specifies whether the process can sleep
2798 * 1 - DIAG reset and READY
2799 * 0 - READY initially OR soft reset and READY
2800 * -1 - Any failure on KickStart
2801 * -2 - Msg Unit Reset Failed
2802 * -3 - IO Unit Reset Failed
2803 * -4 - IOC owned by a PEER
2806 MakeIocReady(MPT_ADAPTER
*ioc
, int force
, int sleepFlag
)
2811 int hard_reset_done
= 0;
2816 /* Get current [raw] IOC state */
2817 ioc_state
= mpt_GetIocState(ioc
, 0);
2818 dhsprintk(ioc
, printk(MYIOC_s_INFO_FMT
"MakeIocReady [raw] state=%08x\n", ioc
->name
, ioc_state
));
2821 * Check to see if IOC got left/stuck in doorbell handshake
2822 * grip of death. If so, hard reset the IOC.
2824 if (ioc_state
& MPI_DOORBELL_ACTIVE
) {
2826 printk(MYIOC_s_WARN_FMT
"Unexpected doorbell active!\n",
2830 /* Is it already READY? */
2831 if (!statefault
&& (ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_READY
)
2835 * Check to see if IOC is in FAULT state.
2837 if ((ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_FAULT
) {
2839 printk(MYIOC_s_WARN_FMT
"IOC is in FAULT state!!!\n",
2841 printk(MYIOC_s_WARN_FMT
" FAULT code = %04xh\n",
2842 ioc
->name
, ioc_state
& MPI_DOORBELL_DATA_MASK
);
2846 * Hmmm... Did it get left operational?
2848 if ((ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_OPERATIONAL
) {
2849 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"IOC operational unexpected\n",
2853 * If PCI Peer, exit.
2854 * Else, if no fault conditions are present, issue a MessageUnitReset
2855 * Else, fall through to KickStart case
2857 whoinit
= (ioc_state
& MPI_DOORBELL_WHO_INIT_MASK
) >> MPI_DOORBELL_WHO_INIT_SHIFT
;
2858 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
2859 "whoinit 0x%x statefault %d force %d\n",
2860 ioc
->name
, whoinit
, statefault
, force
));
2861 if (whoinit
== MPI_WHOINIT_PCI_PEER
)
2864 if ((statefault
== 0 ) && (force
== 0)) {
2865 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
)) == 0)
2872 hard_reset_done
= KickStart(ioc
, statefault
||force
, sleepFlag
);
2873 if (hard_reset_done
< 0)
2877 * Loop here waiting for IOC to come READY.
2880 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 5; /* 5 seconds */
2882 while ((ioc_state
= mpt_GetIocState(ioc
, 1)) != MPI_IOC_STATE_READY
) {
2883 if (ioc_state
== MPI_IOC_STATE_OPERATIONAL
) {
2885 * BIOS or previous driver load left IOC in OP state.
2886 * Reset messaging FIFOs.
2888 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
)) != 0) {
2889 printk(MYIOC_s_ERR_FMT
"IOC msg unit reset failed!\n", ioc
->name
);
2892 } else if (ioc_state
== MPI_IOC_STATE_RESET
) {
2894 * Something is wrong. Try to get IOC back
2897 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IO_UNIT_RESET
, sleepFlag
)) != 0) {
2898 printk(MYIOC_s_ERR_FMT
"IO unit reset failed!\n", ioc
->name
);
2905 printk(MYIOC_s_ERR_FMT
"Wait IOC_READY state timeout(%d)!\n",
2906 ioc
->name
, (int)((ii
+5)/HZ
));
2910 if (sleepFlag
== CAN_SLEEP
) {
2913 mdelay (1); /* 1 msec delay */
2918 if (statefault
< 3) {
2919 printk(MYIOC_s_INFO_FMT
"Recovered from %s\n",
2921 statefault
==1 ? "stuck handshake" : "IOC FAULT");
2924 return hard_reset_done
;
2927 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2929 * mpt_GetIocState - Get the current state of a MPT adapter.
2930 * @ioc: Pointer to MPT_ADAPTER structure
2931 * @cooked: Request raw or cooked IOC state
2933 * Returns all IOC Doorbell register bits if cooked==0, else just the
2934 * Doorbell bits in MPI_IOC_STATE_MASK.
2937 mpt_GetIocState(MPT_ADAPTER
*ioc
, int cooked
)
2942 s
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
2943 sc
= s
& MPI_IOC_STATE_MASK
;
2946 ioc
->last_state
= sc
;
2948 return cooked
? sc
: s
;
2951 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2953 * GetIocFacts - Send IOCFacts request to MPT adapter.
2954 * @ioc: Pointer to MPT_ADAPTER structure
2955 * @sleepFlag: Specifies whether the process can sleep
2956 * @reason: If recovery, only update facts.
2958 * Returns 0 for success, non-zero for failure.
2961 GetIocFacts(MPT_ADAPTER
*ioc
, int sleepFlag
, int reason
)
2963 IOCFacts_t get_facts
;
2964 IOCFactsReply_t
*facts
;
2972 /* IOC *must* NOT be in RESET state! */
2973 if (ioc
->last_state
== MPI_IOC_STATE_RESET
) {
2974 printk(MYIOC_s_ERR_FMT
"Can't get IOCFacts NOT READY! (%08x)\n",
2975 ioc
->name
, ioc
->last_state
);
2979 facts
= &ioc
->facts
;
2981 /* Destination (reply area)... */
2982 reply_sz
= sizeof(*facts
);
2983 memset(facts
, 0, reply_sz
);
2985 /* Request area (get_facts on the stack right now!) */
2986 req_sz
= sizeof(get_facts
);
2987 memset(&get_facts
, 0, req_sz
);
2989 get_facts
.Function
= MPI_FUNCTION_IOC_FACTS
;
2990 /* Assert: All other get_facts fields are zero! */
2992 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2993 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2994 ioc
->name
, req_sz
, reply_sz
));
2996 /* No non-zero fields in the get_facts request are greater than
2997 * 1 byte in size, so we can just fire it off as is.
2999 r
= mpt_handshake_req_reply_wait(ioc
, req_sz
, (u32
*)&get_facts
,
3000 reply_sz
, (u16
*)facts
, 5 /*seconds*/, sleepFlag
);
3005 * Now byte swap (GRRR) the necessary fields before any further
3006 * inspection of reply contents.
3008 * But need to do some sanity checks on MsgLength (byte) field
3009 * to make sure we don't zero IOC's req_sz!
3011 /* Did we get a valid reply? */
3012 if (facts
->MsgLength
> offsetof(IOCFactsReply_t
, RequestFrameSize
)/sizeof(u32
)) {
3013 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
3015 * If not been here, done that, save off first WhoInit value
3017 if (ioc
->FirstWhoInit
== WHOINIT_UNKNOWN
)
3018 ioc
->FirstWhoInit
= facts
->WhoInit
;
3021 facts
->MsgVersion
= le16_to_cpu(facts
->MsgVersion
);
3022 facts
->MsgContext
= le32_to_cpu(facts
->MsgContext
);
3023 facts
->IOCExceptions
= le16_to_cpu(facts
->IOCExceptions
);
3024 facts
->IOCStatus
= le16_to_cpu(facts
->IOCStatus
);
3025 facts
->IOCLogInfo
= le32_to_cpu(facts
->IOCLogInfo
);
3026 status
= le16_to_cpu(facts
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
3027 /* CHECKME! IOCStatus, IOCLogInfo */
3029 facts
->ReplyQueueDepth
= le16_to_cpu(facts
->ReplyQueueDepth
);
3030 facts
->RequestFrameSize
= le16_to_cpu(facts
->RequestFrameSize
);
3033 * FC f/w version changed between 1.1 and 1.2
3034 * Old: u16{Major(4),Minor(4),SubMinor(8)}
3035 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
3037 if (facts
->MsgVersion
< 0x0102) {
3039 * Handle old FC f/w style, convert to new...
3041 u16 oldv
= le16_to_cpu(facts
->Reserved_0101_FWVersion
);
3042 facts
->FWVersion
.Word
=
3043 ((oldv
<<12) & 0xFF000000) |
3044 ((oldv
<<8) & 0x000FFF00);
3046 facts
->FWVersion
.Word
= le32_to_cpu(facts
->FWVersion
.Word
);
3048 facts
->ProductID
= le16_to_cpu(facts
->ProductID
);
3049 if ((ioc
->facts
.ProductID
& MPI_FW_HEADER_PID_PROD_MASK
)
3050 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI
)
3051 ioc
->ir_firmware
= 1;
3052 facts
->CurrentHostMfaHighAddr
=
3053 le32_to_cpu(facts
->CurrentHostMfaHighAddr
);
3054 facts
->GlobalCredits
= le16_to_cpu(facts
->GlobalCredits
);
3055 facts
->CurrentSenseBufferHighAddr
=
3056 le32_to_cpu(facts
->CurrentSenseBufferHighAddr
);
3057 facts
->CurReplyFrameSize
=
3058 le16_to_cpu(facts
->CurReplyFrameSize
);
3059 facts
->IOCCapabilities
= le32_to_cpu(facts
->IOCCapabilities
);
3062 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
3063 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
3064 * to 14 in MPI-1.01.0x.
3066 if (facts
->MsgLength
>= (offsetof(IOCFactsReply_t
,FWImageSize
) + 7)/4 &&
3067 facts
->MsgVersion
> 0x0100) {
3068 facts
->FWImageSize
= le32_to_cpu(facts
->FWImageSize
);
3071 sz
= facts
->FWImageSize
;
3076 facts
->FWImageSize
= sz
;
3078 if (!facts
->RequestFrameSize
) {
3079 /* Something is wrong! */
3080 printk(MYIOC_s_ERR_FMT
"IOC reported invalid 0 request size!\n",
3085 r
= sz
= facts
->BlockSize
;
3086 vv
= ((63 / (sz
* 4)) + 1) & 0x03;
3087 ioc
->NB_for_64_byte_frame
= vv
;
3093 ioc
->NBShiftFactor
= shiftFactor
;
3094 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3095 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
3096 ioc
->name
, vv
, shiftFactor
, r
));
3098 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
3100 * Set values for this IOC's request & reply frame sizes,
3101 * and request & reply queue depths...
3103 ioc
->req_sz
= min(MPT_DEFAULT_FRAME_SIZE
, facts
->RequestFrameSize
* 4);
3104 ioc
->req_depth
= min_t(int, MPT_MAX_REQ_DEPTH
, facts
->GlobalCredits
);
3105 ioc
->reply_sz
= MPT_REPLY_FRAME_SIZE
;
3106 ioc
->reply_depth
= min_t(int, MPT_DEFAULT_REPLY_DEPTH
, facts
->ReplyQueueDepth
);
3108 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"reply_sz=%3d, reply_depth=%4d\n",
3109 ioc
->name
, ioc
->reply_sz
, ioc
->reply_depth
));
3110 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"req_sz =%3d, req_depth =%4d\n",
3111 ioc
->name
, ioc
->req_sz
, ioc
->req_depth
));
3113 /* Get port facts! */
3114 if ( (r
= GetPortFacts(ioc
, 0, sleepFlag
)) != 0 )
3118 printk(MYIOC_s_ERR_FMT
3119 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
3120 ioc
->name
, facts
->MsgLength
, (offsetof(IOCFactsReply_t
,
3121 RequestFrameSize
)/sizeof(u32
)));
3128 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3130 * GetPortFacts - Send PortFacts request to MPT adapter.
3131 * @ioc: Pointer to MPT_ADAPTER structure
3132 * @portnum: Port number
3133 * @sleepFlag: Specifies whether the process can sleep
3135 * Returns 0 for success, non-zero for failure.
3138 GetPortFacts(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
)
3140 PortFacts_t get_pfacts
;
3141 PortFactsReply_t
*pfacts
;
3147 /* IOC *must* NOT be in RESET state! */
3148 if (ioc
->last_state
== MPI_IOC_STATE_RESET
) {
3149 printk(MYIOC_s_ERR_FMT
"Can't get PortFacts NOT READY! (%08x)\n",
3150 ioc
->name
, ioc
->last_state
);
3154 pfacts
= &ioc
->pfacts
[portnum
];
3156 /* Destination (reply area)... */
3157 reply_sz
= sizeof(*pfacts
);
3158 memset(pfacts
, 0, reply_sz
);
3160 /* Request area (get_pfacts on the stack right now!) */
3161 req_sz
= sizeof(get_pfacts
);
3162 memset(&get_pfacts
, 0, req_sz
);
3164 get_pfacts
.Function
= MPI_FUNCTION_PORT_FACTS
;
3165 get_pfacts
.PortNumber
= portnum
;
3166 /* Assert: All other get_pfacts fields are zero! */
3168 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending get PortFacts(%d) request\n",
3169 ioc
->name
, portnum
));
3171 /* No non-zero fields in the get_pfacts request are greater than
3172 * 1 byte in size, so we can just fire it off as is.
3174 ii
= mpt_handshake_req_reply_wait(ioc
, req_sz
, (u32
*)&get_pfacts
,
3175 reply_sz
, (u16
*)pfacts
, 5 /*seconds*/, sleepFlag
);
3179 /* Did we get a valid reply? */
3181 /* Now byte swap the necessary fields in the response. */
3182 pfacts
->MsgContext
= le32_to_cpu(pfacts
->MsgContext
);
3183 pfacts
->IOCStatus
= le16_to_cpu(pfacts
->IOCStatus
);
3184 pfacts
->IOCLogInfo
= le32_to_cpu(pfacts
->IOCLogInfo
);
3185 pfacts
->MaxDevices
= le16_to_cpu(pfacts
->MaxDevices
);
3186 pfacts
->PortSCSIID
= le16_to_cpu(pfacts
->PortSCSIID
);
3187 pfacts
->ProtocolFlags
= le16_to_cpu(pfacts
->ProtocolFlags
);
3188 pfacts
->MaxPostedCmdBuffers
= le16_to_cpu(pfacts
->MaxPostedCmdBuffers
);
3189 pfacts
->MaxPersistentIDs
= le16_to_cpu(pfacts
->MaxPersistentIDs
);
3190 pfacts
->MaxLanBuckets
= le16_to_cpu(pfacts
->MaxLanBuckets
);
3192 max_id
= (ioc
->bus_type
== SAS
) ? pfacts
->PortSCSIID
:
3194 ioc
->devices_per_bus
= (max_id
> 255) ? 256 : max_id
;
3195 ioc
->number_of_buses
= (ioc
->devices_per_bus
< 256) ? 1 : max_id
/256;
3198 * Place all the devices on channels
3202 if (mpt_channel_mapping
) {
3203 ioc
->devices_per_bus
= 1;
3204 ioc
->number_of_buses
= (max_id
> 255) ? 255 : max_id
;
3210 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3212 * SendIocInit - Send IOCInit request to MPT adapter.
3213 * @ioc: Pointer to MPT_ADAPTER structure
3214 * @sleepFlag: Specifies whether the process can sleep
3216 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
3218 * Returns 0 for success, non-zero for failure.
3221 SendIocInit(MPT_ADAPTER
*ioc
, int sleepFlag
)
3224 MPIDefaultReply_t init_reply
;
3230 memset(&ioc_init
, 0, sizeof(ioc_init
));
3231 memset(&init_reply
, 0, sizeof(init_reply
));
3233 ioc_init
.WhoInit
= MPI_WHOINIT_HOST_DRIVER
;
3234 ioc_init
.Function
= MPI_FUNCTION_IOC_INIT
;
3236 /* If we are in a recovery mode and we uploaded the FW image,
3237 * then this pointer is not NULL. Skip the upload a second time.
3238 * Set this flag if cached_fw set for either IOC.
3240 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)
3244 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"upload_fw %d facts.Flags=%x\n",
3245 ioc
->name
, ioc
->upload_fw
, ioc
->facts
.Flags
));
3247 ioc_init
.MaxDevices
= (U8
)ioc
->devices_per_bus
;
3248 ioc_init
.MaxBuses
= (U8
)ioc
->number_of_buses
;
3249 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"facts.MsgVersion=%x\n",
3250 ioc
->name
, ioc
->facts
.MsgVersion
));
3251 if (ioc
->facts
.MsgVersion
>= MPI_VERSION_01_05
) {
3252 // set MsgVersion and HeaderVersion host driver was built with
3253 ioc_init
.MsgVersion
= cpu_to_le16(MPI_VERSION
);
3254 ioc_init
.HeaderVersion
= cpu_to_le16(MPI_HEADER_VERSION
);
3256 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT
) {
3257 ioc_init
.HostPageBufferSGE
= ioc
->facts
.HostPageBufferSGE
;
3258 } else if(mpt_host_page_alloc(ioc
, &ioc_init
))
3261 ioc_init
.ReplyFrameSize
= cpu_to_le16(ioc
->reply_sz
); /* in BYTES */
3263 if (sizeof(dma_addr_t
) == sizeof(u64
)) {
3264 /* Save the upper 32-bits of the request
3265 * (reply) and sense buffers.
3267 ioc_init
.HostMfaHighAddr
= cpu_to_le32((u32
)((u64
)ioc
->alloc_dma
>> 32));
3268 ioc_init
.SenseBufferHighAddr
= cpu_to_le32((u32
)((u64
)ioc
->sense_buf_pool_dma
>> 32));
3270 /* Force 32-bit addressing */
3271 ioc_init
.HostMfaHighAddr
= cpu_to_le32(0);
3272 ioc_init
.SenseBufferHighAddr
= cpu_to_le32(0);
3275 ioc
->facts
.CurrentHostMfaHighAddr
= ioc_init
.HostMfaHighAddr
;
3276 ioc
->facts
.CurrentSenseBufferHighAddr
= ioc_init
.SenseBufferHighAddr
;
3277 ioc
->facts
.MaxDevices
= ioc_init
.MaxDevices
;
3278 ioc
->facts
.MaxBuses
= ioc_init
.MaxBuses
;
3280 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending IOCInit (req @ %p)\n",
3281 ioc
->name
, &ioc_init
));
3283 r
= mpt_handshake_req_reply_wait(ioc
, sizeof(IOCInit_t
), (u32
*)&ioc_init
,
3284 sizeof(MPIDefaultReply_t
), (u16
*)&init_reply
, 10 /*seconds*/, sleepFlag
);
3286 printk(MYIOC_s_ERR_FMT
"Sending IOCInit failed(%d)!\n",ioc
->name
, r
);
3290 /* No need to byte swap the multibyte fields in the reply
3291 * since we don't even look at its contents.
3294 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending PortEnable (req @ %p)\n",
3295 ioc
->name
, &ioc_init
));
3297 if ((r
= SendPortEnable(ioc
, 0, sleepFlag
)) != 0) {
3298 printk(MYIOC_s_ERR_FMT
"Sending PortEnable failed(%d)!\n",ioc
->name
, r
);
3302 /* YIKES! SUPER IMPORTANT!!!
3303 * Poll IocState until _OPERATIONAL while IOC is doing
3304 * LoopInit and TargetDiscovery!
3307 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 60; /* 60 seconds */
3308 state
= mpt_GetIocState(ioc
, 1);
3309 while (state
!= MPI_IOC_STATE_OPERATIONAL
&& --cntdn
) {
3310 if (sleepFlag
== CAN_SLEEP
) {
3317 printk(MYIOC_s_ERR_FMT
"Wait IOC_OP state timeout(%d)!\n",
3318 ioc
->name
, (int)((count
+5)/HZ
));
3322 state
= mpt_GetIocState(ioc
, 1);
3325 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Wait IOC_OPERATIONAL state (cnt=%d)\n",
3328 ioc
->aen_event_read_flag
=0;
3332 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3334 * SendPortEnable - Send PortEnable request to MPT adapter port.
3335 * @ioc: Pointer to MPT_ADAPTER structure
3336 * @portnum: Port number to enable
3337 * @sleepFlag: Specifies whether the process can sleep
3339 * Send PortEnable to bring IOC to OPERATIONAL state.
3341 * Returns 0 for success, non-zero for failure.
3344 SendPortEnable(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
)
3346 PortEnable_t port_enable
;
3347 MPIDefaultReply_t reply_buf
;
3352 /* Destination... */
3353 reply_sz
= sizeof(MPIDefaultReply_t
);
3354 memset(&reply_buf
, 0, reply_sz
);
3356 req_sz
= sizeof(PortEnable_t
);
3357 memset(&port_enable
, 0, req_sz
);
3359 port_enable
.Function
= MPI_FUNCTION_PORT_ENABLE
;
3360 port_enable
.PortNumber
= portnum
;
3361 /* port_enable.ChainOffset = 0; */
3362 /* port_enable.MsgFlags = 0; */
3363 /* port_enable.MsgContext = 0; */
3365 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending Port(%d)Enable (req @ %p)\n",
3366 ioc
->name
, portnum
, &port_enable
));
3368 /* RAID FW may take a long time to enable
3370 if (ioc
->ir_firmware
|| ioc
->bus_type
== SAS
) {
3371 rc
= mpt_handshake_req_reply_wait(ioc
, req_sz
,
3372 (u32
*)&port_enable
, reply_sz
, (u16
*)&reply_buf
,
3373 300 /*seconds*/, sleepFlag
);
3375 rc
= mpt_handshake_req_reply_wait(ioc
, req_sz
,
3376 (u32
*)&port_enable
, reply_sz
, (u16
*)&reply_buf
,
3377 30 /*seconds*/, sleepFlag
);
3383 * mpt_alloc_fw_memory - allocate firmware memory
3384 * @ioc: Pointer to MPT_ADAPTER structure
3385 * @size: total FW bytes
3387 * If memory has already been allocated, the same (cached) value
3390 * Return 0 if successfull, or non-zero for failure
3393 mpt_alloc_fw_memory(MPT_ADAPTER
*ioc
, int size
)
3397 if (ioc
->cached_fw
) {
3398 rc
= 0; /* use already allocated memory */
3401 else if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
) {
3402 ioc
->cached_fw
= ioc
->alt_ioc
->cached_fw
; /* use alt_ioc's memory */
3403 ioc
->cached_fw_dma
= ioc
->alt_ioc
->cached_fw_dma
;
3407 ioc
->cached_fw
= pci_alloc_consistent(ioc
->pcidev
, size
, &ioc
->cached_fw_dma
);
3408 if (!ioc
->cached_fw
) {
3409 printk(MYIOC_s_ERR_FMT
"Unable to allocate memory for the cached firmware image!\n",
3413 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"FW Image @ %p[%p], sz=%d[%x] bytes\n",
3414 ioc
->name
, ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, size
, size
));
3415 ioc
->alloc_total
+= size
;
3423 * mpt_free_fw_memory - free firmware memory
3424 * @ioc: Pointer to MPT_ADAPTER structure
3426 * If alt_img is NULL, delete from ioc structure.
3427 * Else, delete a secondary image in same format.
3430 mpt_free_fw_memory(MPT_ADAPTER
*ioc
)
3434 if (!ioc
->cached_fw
)
3437 sz
= ioc
->facts
.FWImageSize
;
3438 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3439 ioc
->name
, ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, sz
, sz
));
3440 pci_free_consistent(ioc
->pcidev
, sz
, ioc
->cached_fw
, ioc
->cached_fw_dma
);
3441 ioc
->alloc_total
-= sz
;
3442 ioc
->cached_fw
= NULL
;
3445 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3447 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3448 * @ioc: Pointer to MPT_ADAPTER structure
3449 * @sleepFlag: Specifies whether the process can sleep
3451 * Returns 0 for success, >0 for handshake failure
3452 * <0 for fw upload failure.
3454 * Remark: If bound IOC and a successful FWUpload was performed
3455 * on the bound IOC, the second image is discarded
3456 * and memory is free'd. Both channels must upload to prevent
3457 * IOC from running in degraded mode.
3460 mpt_do_upload(MPT_ADAPTER
*ioc
, int sleepFlag
)
3462 u8 reply
[sizeof(FWUploadReply_t
)];
3463 FWUpload_t
*prequest
;
3464 FWUploadReply_t
*preply
;
3465 FWUploadTCSGE_t
*ptcsge
;
3467 int ii
, sz
, reply_sz
;
3470 /* If the image size is 0, we are done.
3472 if ((sz
= ioc
->facts
.FWImageSize
) == 0)
3475 if (mpt_alloc_fw_memory(ioc
, ioc
->facts
.FWImageSize
) != 0)
3478 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3479 ioc
->name
, ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, sz
, sz
));
3481 prequest
= (sleepFlag
== NO_SLEEP
) ? kzalloc(ioc
->req_sz
, GFP_ATOMIC
) :
3482 kzalloc(ioc
->req_sz
, GFP_KERNEL
);
3484 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"fw upload failed "
3485 "while allocating memory \n", ioc
->name
));
3486 mpt_free_fw_memory(ioc
);
3490 preply
= (FWUploadReply_t
*)&reply
;
3492 reply_sz
= sizeof(reply
);
3493 memset(preply
, 0, reply_sz
);
3495 prequest
->ImageType
= MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM
;
3496 prequest
->Function
= MPI_FUNCTION_FW_UPLOAD
;
3498 ptcsge
= (FWUploadTCSGE_t
*) &prequest
->SGL
;
3499 ptcsge
->DetailsLength
= 12;
3500 ptcsge
->Flags
= MPI_SGE_FLAGS_TRANSACTION_ELEMENT
;
3501 ptcsge
->ImageSize
= cpu_to_le32(sz
);
3504 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_READ
| sz
;
3505 ioc
->add_sge((char *)ptcsge
, flagsLength
, ioc
->cached_fw_dma
);
3506 request_size
= offsetof(FWUpload_t
, SGL
) + sizeof(FWUploadTCSGE_t
) +
3508 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending FW Upload "
3509 " (req @ %p) fw_size=%d mf_request_size=%d\n", ioc
->name
, prequest
,
3510 ioc
->facts
.FWImageSize
, request_size
));
3511 DBG_DUMP_FW_REQUEST_FRAME(ioc
, (u32
*)prequest
);
3513 ii
= mpt_handshake_req_reply_wait(ioc
, request_size
, (u32
*)prequest
,
3514 reply_sz
, (u16
*)preply
, 65 /*seconds*/, sleepFlag
);
3516 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
": FW Upload completed rc=%x \n", ioc
->name
, ii
));
3518 cmdStatus
= -EFAULT
;
3520 /* Handshake transfer was complete and successful.
3521 * Check the Reply Frame.
3523 int status
, transfer_sz
;
3524 status
= le16_to_cpu(preply
->IOCStatus
);
3525 if (status
== MPI_IOCSTATUS_SUCCESS
) {
3526 transfer_sz
= le32_to_cpu(preply
->ActualImageSize
);
3527 if (transfer_sz
== sz
)
3531 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
": do_upload cmdStatus=%d \n",
3532 ioc
->name
, cmdStatus
));
3537 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
": fw upload failed, freeing image \n",
3539 mpt_free_fw_memory(ioc
);
3546 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3548 * mpt_downloadboot - DownloadBoot code
3549 * @ioc: Pointer to MPT_ADAPTER structure
3550 * @pFwHeader: Pointer to firmware header info
3551 * @sleepFlag: Specifies whether the process can sleep
3553 * FwDownloadBoot requires Programmed IO access.
3555 * Returns 0 for success
3556 * -1 FW Image size is 0
3557 * -2 No valid cached_fw Pointer
3558 * <0 for fw upload failure.
3561 mpt_downloadboot(MPT_ADAPTER
*ioc
, MpiFwHeader_t
*pFwHeader
, int sleepFlag
)
3563 MpiExtImageHeader_t
*pExtImage
;
3573 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3574 ioc
->name
, pFwHeader
->ImageSize
, pFwHeader
->ImageSize
, pFwHeader
));
3576 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3577 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3578 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3579 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3580 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3581 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3583 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, (MPI_DIAG_PREVENT_IOC_BOOT
| MPI_DIAG_DISABLE_ARM
));
3586 if (sleepFlag
== CAN_SLEEP
) {
3592 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3593 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_RESET_ADAPTER
);
3595 for (count
= 0; count
< 30; count
++) {
3596 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3597 if (!(diag0val
& MPI_DIAG_RESET_ADAPTER
)) {
3598 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RESET_ADAPTER cleared, count=%d\n",
3603 if (sleepFlag
== CAN_SLEEP
) {
3610 if ( count
== 30 ) {
3611 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot failed! "
3612 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3613 ioc
->name
, diag0val
));
3617 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3618 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3619 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3620 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3621 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3622 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3624 /* Set the DiagRwEn and Disable ARM bits */
3625 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, (MPI_DIAG_RW_ENABLE
| MPI_DIAG_DISABLE_ARM
));
3627 fwSize
= (pFwHeader
->ImageSize
+ 3)/4;
3628 ptrFw
= (u32
*) pFwHeader
;
3630 /* Write the LoadStartAddress to the DiagRw Address Register
3631 * using Programmed IO
3633 if (ioc
->errata_flag_1064
)
3634 pci_enable_io_access(ioc
->pcidev
);
3636 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, pFwHeader
->LoadStartAddress
);
3637 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"LoadStart addr written 0x%x \n",
3638 ioc
->name
, pFwHeader
->LoadStartAddress
));
3640 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write FW Image: 0x%x bytes @ %p\n",
3641 ioc
->name
, fwSize
*4, ptrFw
));
3643 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, *ptrFw
++);
3646 nextImage
= pFwHeader
->NextImageHeaderOffset
;
3648 pExtImage
= (MpiExtImageHeader_t
*) ((char *)pFwHeader
+ nextImage
);
3650 load_addr
= pExtImage
->LoadStartAddress
;
3652 fwSize
= (pExtImage
->ImageSize
+ 3) >> 2;
3653 ptrFw
= (u32
*)pExtImage
;
3655 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3656 ioc
->name
, fwSize
*4, fwSize
*4, ptrFw
, load_addr
));
3657 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, load_addr
);
3660 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, *ptrFw
++);
3662 nextImage
= pExtImage
->NextImageHeaderOffset
;
3665 /* Write the IopResetVectorRegAddr */
3666 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write IopResetVector Addr=%x! \n", ioc
->name
, pFwHeader
->IopResetRegAddr
));
3667 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, pFwHeader
->IopResetRegAddr
);
3669 /* Write the IopResetVectorValue */
3670 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write IopResetVector Value=%x! \n", ioc
->name
, pFwHeader
->IopResetVectorValue
));
3671 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, pFwHeader
->IopResetVectorValue
);
3673 /* Clear the internal flash bad bit - autoincrementing register,
3674 * so must do two writes.
3676 if (ioc
->bus_type
== SPI
) {
3678 * 1030 and 1035 H/W errata, workaround to access
3679 * the ClearFlashBadSignatureBit
3681 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, 0x3F000000);
3682 diagRwData
= CHIPREG_PIO_READ32(&ioc
->pio_chip
->DiagRwData
);
3683 diagRwData
|= 0x40000000;
3684 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, 0x3F000000);
3685 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, diagRwData
);
3687 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3688 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3689 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
|
3690 MPI_DIAG_CLEAR_FLASH_BAD_SIG
);
3693 if (sleepFlag
== CAN_SLEEP
) {
3700 if (ioc
->errata_flag_1064
)
3701 pci_disable_io_access(ioc
->pcidev
);
3703 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3704 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot diag0val=%x, "
3705 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3706 ioc
->name
, diag0val
));
3707 diag0val
&= ~(MPI_DIAG_PREVENT_IOC_BOOT
| MPI_DIAG_DISABLE_ARM
| MPI_DIAG_RW_ENABLE
);
3708 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot now diag0val=%x\n",
3709 ioc
->name
, diag0val
));
3710 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
);
3712 /* Write 0xFF to reset the sequencer */
3713 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3715 if (ioc
->bus_type
== SAS
) {
3716 ioc_state
= mpt_GetIocState(ioc
, 0);
3717 if ( (GetIocFacts(ioc
, sleepFlag
,
3718 MPT_HOSTEVENT_IOC_BRINGUP
)) != 0 ) {
3719 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"GetIocFacts failed: IocState=%x\n",
3720 ioc
->name
, ioc_state
));
3725 for (count
=0; count
<HZ
*20; count
++) {
3726 if ((ioc_state
= mpt_GetIocState(ioc
, 0)) & MPI_IOC_STATE_READY
) {
3727 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3728 "downloadboot successful! (count=%d) IocState=%x\n",
3729 ioc
->name
, count
, ioc_state
));
3730 if (ioc
->bus_type
== SAS
) {
3733 if ((SendIocInit(ioc
, sleepFlag
)) != 0) {
3734 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3735 "downloadboot: SendIocInit failed\n",
3739 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3740 "downloadboot: SendIocInit successful\n",
3744 if (sleepFlag
== CAN_SLEEP
) {
3750 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3751 "downloadboot failed! IocState=%x\n",ioc
->name
, ioc_state
));
3755 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3757 * KickStart - Perform hard reset of MPT adapter.
3758 * @ioc: Pointer to MPT_ADAPTER structure
3759 * @force: Force hard reset
3760 * @sleepFlag: Specifies whether the process can sleep
3762 * This routine places MPT adapter in diagnostic mode via the
3763 * WriteSequence register, and then performs a hard reset of adapter
3764 * via the Diagnostic register.
3766 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3767 * or NO_SLEEP (interrupt thread, use mdelay)
3768 * force - 1 if doorbell active, board fault state
3769 * board operational, IOC_RECOVERY or
3770 * IOC_BRINGUP and there is an alt_ioc.
3774 * 1 - hard reset, READY
3775 * 0 - no reset due to History bit, READY
3776 * -1 - no reset due to History bit but not READY
3777 * OR reset but failed to come READY
3778 * -2 - no reset, could not enter DIAG mode
3779 * -3 - reset but bad FW bit
3782 KickStart(MPT_ADAPTER
*ioc
, int force
, int sleepFlag
)
3784 int hard_reset_done
= 0;
3788 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"KickStarting!\n", ioc
->name
));
3789 if (ioc
->bus_type
== SPI
) {
3790 /* Always issue a Msg Unit Reset first. This will clear some
3791 * SCSI bus hang conditions.
3793 SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
);
3795 if (sleepFlag
== CAN_SLEEP
) {
3802 hard_reset_done
= mpt_diag_reset(ioc
, force
, sleepFlag
);
3803 if (hard_reset_done
< 0)
3804 return hard_reset_done
;
3806 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Diagnostic reset successful!\n",
3809 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 2; /* 2 seconds */
3810 for (cnt
=0; cnt
<cntdn
; cnt
++) {
3811 ioc_state
= mpt_GetIocState(ioc
, 1);
3812 if ((ioc_state
== MPI_IOC_STATE_READY
) || (ioc_state
== MPI_IOC_STATE_OPERATIONAL
)) {
3813 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"KickStart successful! (cnt=%d)\n",
3815 return hard_reset_done
;
3817 if (sleepFlag
== CAN_SLEEP
) {
3824 dinitprintk(ioc
, printk(MYIOC_s_ERR_FMT
"Failed to come READY after reset! IocState=%x\n",
3825 ioc
->name
, mpt_GetIocState(ioc
, 0)));
3829 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3831 * mpt_diag_reset - Perform hard reset of the adapter.
3832 * @ioc: Pointer to MPT_ADAPTER structure
3833 * @ignore: Set if to honor and clear to ignore
3834 * the reset history bit
3835 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3836 * else set to NO_SLEEP (use mdelay instead)
3838 * This routine places the adapter in diagnostic mode via the
3839 * WriteSequence register and then performs a hard reset of adapter
3840 * via the Diagnostic register. Adapter should be in ready state
3841 * upon successful completion.
3843 * Returns: 1 hard reset successful
3844 * 0 no reset performed because reset history bit set
3845 * -2 enabling diagnostic mode failed
3846 * -3 diagnostic reset failed
3849 mpt_diag_reset(MPT_ADAPTER
*ioc
, int ignore
, int sleepFlag
)
3853 int hard_reset_done
= 0;
3856 MpiFwHeader_t
*cached_fw
; /* Pointer to FW */
3858 /* Clear any existing interrupts */
3859 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
3861 if (ioc
->pcidev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1078
) {
3862 drsprintk(ioc
, printk(MYIOC_s_WARN_FMT
"%s: Doorbell=%p; 1078 reset "
3863 "address=%p\n", ioc
->name
, __func__
,
3864 &ioc
->chip
->Doorbell
, &ioc
->chip
->Reset_1078
));
3865 CHIPREG_WRITE32(&ioc
->chip
->Reset_1078
, 0x07);
3866 if (sleepFlag
== CAN_SLEEP
)
3871 for (count
= 0; count
< 60; count
++) {
3872 doorbell
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
3873 doorbell
&= MPI_IOC_STATE_MASK
;
3875 drsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3876 "looking for READY STATE: doorbell=%x"
3878 ioc
->name
, doorbell
, count
));
3879 if (doorbell
== MPI_IOC_STATE_READY
) {
3884 if (sleepFlag
== CAN_SLEEP
)
3892 /* Use "Diagnostic reset" method! (only thing available!) */
3893 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3895 if (ioc
->debug_level
& MPT_DEBUG
) {
3897 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
3898 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG1: diag0=%08x, diag1=%08x\n",
3899 ioc
->name
, diag0val
, diag1val
));
3902 /* Do the reset if we are told to ignore the reset history
3903 * or if the reset history is 0
3905 if (ignore
|| !(diag0val
& MPI_DIAG_RESET_HISTORY
)) {
3906 while ((diag0val
& MPI_DIAG_DRWE
) == 0) {
3907 /* Write magic sequence to WriteSequence register
3908 * Loop until in diagnostic mode
3910 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3911 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3912 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3913 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3914 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3915 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3918 if (sleepFlag
== CAN_SLEEP
) {
3926 printk(MYIOC_s_ERR_FMT
"Enable Diagnostic mode FAILED! (%02xh)\n",
3927 ioc
->name
, diag0val
);
3932 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3934 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Wrote magic DiagWriteEn sequence (%x)\n",
3935 ioc
->name
, diag0val
));
3938 if (ioc
->debug_level
& MPT_DEBUG
) {
3940 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
3941 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG2: diag0=%08x, diag1=%08x\n",
3942 ioc
->name
, diag0val
, diag1val
));
3945 * Disable the ARM (Bug fix)
3948 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_DISABLE_ARM
);
3952 * Now hit the reset bit in the Diagnostic register
3953 * (THE BIG HAMMER!) (Clears DRWE bit).
3955 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_RESET_ADAPTER
);
3956 hard_reset_done
= 1;
3957 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Diagnostic reset performed\n",
3961 * Call each currently registered protocol IOC reset handler
3962 * with pre-reset indication.
3963 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3964 * MptResetHandlers[] registered yet.
3970 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
3971 if (MptResetHandlers
[cb_idx
]) {
3972 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3973 "Calling IOC pre_reset handler #%d\n",
3974 ioc
->name
, cb_idx
));
3975 r
+= mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_PRE_RESET
);
3977 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3978 "Calling alt-%s pre_reset handler #%d\n",
3979 ioc
->name
, ioc
->alt_ioc
->name
, cb_idx
));
3980 r
+= mpt_signal_reset(cb_idx
, ioc
->alt_ioc
, MPT_IOC_PRE_RESET
);
3984 /* FIXME? Examine results here? */
3988 cached_fw
= (MpiFwHeader_t
*)ioc
->cached_fw
;
3989 else if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
)
3990 cached_fw
= (MpiFwHeader_t
*)ioc
->alt_ioc
->cached_fw
;
3994 /* If the DownloadBoot operation fails, the
3995 * IOC will be left unusable. This is a fatal error
3996 * case. _diag_reset will return < 0
3998 for (count
= 0; count
< 30; count
++) {
3999 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4000 if (!(diag0val
& MPI_DIAG_RESET_ADAPTER
)) {
4004 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"cached_fw: diag0val=%x count=%d\n",
4005 ioc
->name
, diag0val
, count
));
4007 if (sleepFlag
== CAN_SLEEP
) {
4013 if ((count
= mpt_downloadboot(ioc
, cached_fw
, sleepFlag
)) < 0) {
4014 printk(MYIOC_s_WARN_FMT
4015 "firmware downloadboot failure (%d)!\n", ioc
->name
, count
);
4019 /* Wait for FW to reload and for board
4020 * to go to the READY state.
4021 * Maximum wait is 60 seconds.
4022 * If fail, no error will check again
4023 * with calling program.
4025 for (count
= 0; count
< 60; count
++) {
4026 doorbell
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
4027 doorbell
&= MPI_IOC_STATE_MASK
;
4029 if (doorbell
== MPI_IOC_STATE_READY
) {
4034 if (sleepFlag
== CAN_SLEEP
) {
4043 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4044 if (ioc
->debug_level
& MPT_DEBUG
) {
4046 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
4047 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG3: diag0=%08x, diag1=%08x\n",
4048 ioc
->name
, diag0val
, diag1val
));
4051 /* Clear RESET_HISTORY bit! Place board in the
4052 * diagnostic mode to update the diag register.
4054 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4056 while ((diag0val
& MPI_DIAG_DRWE
) == 0) {
4057 /* Write magic sequence to WriteSequence register
4058 * Loop until in diagnostic mode
4060 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
4061 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
4062 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
4063 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
4064 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
4065 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
4068 if (sleepFlag
== CAN_SLEEP
) {
4076 printk(MYIOC_s_ERR_FMT
"Enable Diagnostic mode FAILED! (%02xh)\n",
4077 ioc
->name
, diag0val
);
4080 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4082 diag0val
&= ~MPI_DIAG_RESET_HISTORY
;
4083 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
);
4084 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4085 if (diag0val
& MPI_DIAG_RESET_HISTORY
) {
4086 printk(MYIOC_s_WARN_FMT
"ResetHistory bit failed to clear!\n",
4090 /* Disable Diagnostic Mode
4092 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFFFFFFFF);
4094 /* Check FW reload status flags.
4096 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4097 if (diag0val
& (MPI_DIAG_FLASH_BAD_SIG
| MPI_DIAG_RESET_ADAPTER
| MPI_DIAG_DISABLE_ARM
)) {
4098 printk(MYIOC_s_ERR_FMT
"Diagnostic reset FAILED! (%02xh)\n",
4099 ioc
->name
, diag0val
);
4103 if (ioc
->debug_level
& MPT_DEBUG
) {
4105 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
4106 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG4: diag0=%08x, diag1=%08x\n",
4107 ioc
->name
, diag0val
, diag1val
));
4111 * Reset flag that says we've enabled event notification
4113 ioc
->facts
.EventState
= 0;
4116 ioc
->alt_ioc
->facts
.EventState
= 0;
4118 return hard_reset_done
;
4121 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4123 * SendIocReset - Send IOCReset request to MPT adapter.
4124 * @ioc: Pointer to MPT_ADAPTER structure
4125 * @reset_type: reset type, expected values are
4126 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
4127 * @sleepFlag: Specifies whether the process can sleep
4129 * Send IOCReset request to the MPT adapter.
4131 * Returns 0 for success, non-zero for failure.
4134 SendIocReset(MPT_ADAPTER
*ioc
, u8 reset_type
, int sleepFlag
)
4140 drsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending IOC reset(0x%02x)!\n",
4141 ioc
->name
, reset_type
));
4142 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, reset_type
<<MPI_DOORBELL_FUNCTION_SHIFT
);
4143 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
4146 /* FW ACK'd request, wait for READY state
4149 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 15; /* 15 seconds */
4151 while ((state
= mpt_GetIocState(ioc
, 1)) != MPI_IOC_STATE_READY
) {
4155 if (sleepFlag
!= CAN_SLEEP
)
4158 printk(MYIOC_s_ERR_FMT
"Wait IOC_READY state timeout(%d)!\n",
4159 ioc
->name
, (int)((count
+5)/HZ
));
4163 if (sleepFlag
== CAN_SLEEP
) {
4166 mdelay (1); /* 1 msec delay */
4171 * Cleanup all event stuff for this IOC; re-issue EventNotification
4172 * request if needed.
4174 if (ioc
->facts
.Function
)
4175 ioc
->facts
.EventState
= 0;
4180 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4182 * initChainBuffers - Allocate memory for and initialize chain buffers
4183 * @ioc: Pointer to MPT_ADAPTER structure
4185 * Allocates memory for and initializes chain buffers,
4186 * chain buffer control arrays and spinlock.
4189 initChainBuffers(MPT_ADAPTER
*ioc
)
4192 int sz
, ii
, num_chain
;
4193 int scale
, num_sge
, numSGE
;
4195 /* ReqToChain size must equal the req_depth
4198 if (ioc
->ReqToChain
== NULL
) {
4199 sz
= ioc
->req_depth
* sizeof(int);
4200 mem
= kmalloc(sz
, GFP_ATOMIC
);
4204 ioc
->ReqToChain
= (int *) mem
;
4205 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReqToChain alloc @ %p, sz=%d bytes\n",
4206 ioc
->name
, mem
, sz
));
4207 mem
= kmalloc(sz
, GFP_ATOMIC
);
4211 ioc
->RequestNB
= (int *) mem
;
4212 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestNB alloc @ %p, sz=%d bytes\n",
4213 ioc
->name
, mem
, sz
));
4215 for (ii
= 0; ii
< ioc
->req_depth
; ii
++) {
4216 ioc
->ReqToChain
[ii
] = MPT_HOST_NO_CHAIN
;
4219 /* ChainToChain size must equal the total number
4220 * of chain buffers to be allocated.
4223 * Calculate the number of chain buffers needed(plus 1) per I/O
4224 * then multiply the maximum number of simultaneous cmds
4226 * num_sge = num sge in request frame + last chain buffer
4227 * scale = num sge per chain buffer if no chain element
4229 scale
= ioc
->req_sz
/ ioc
->SGE_size
;
4230 if (ioc
->sg_addr_size
== sizeof(u64
))
4231 num_sge
= scale
+ (ioc
->req_sz
- 60) / ioc
->SGE_size
;
4233 num_sge
= 1 + scale
+ (ioc
->req_sz
- 64) / ioc
->SGE_size
;
4235 if (ioc
->sg_addr_size
== sizeof(u64
)) {
4236 numSGE
= (scale
- 1) * (ioc
->facts
.MaxChainDepth
-1) + scale
+
4237 (ioc
->req_sz
- 60) / ioc
->SGE_size
;
4239 numSGE
= 1 + (scale
- 1) * (ioc
->facts
.MaxChainDepth
-1) +
4240 scale
+ (ioc
->req_sz
- 64) / ioc
->SGE_size
;
4242 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"num_sge=%d numSGE=%d\n",
4243 ioc
->name
, num_sge
, numSGE
));
4245 if ( numSGE
> MPT_SCSI_SG_DEPTH
)
4246 numSGE
= MPT_SCSI_SG_DEPTH
;
4249 while (numSGE
- num_sge
> 0) {
4251 num_sge
+= (scale
- 1);
4255 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Now numSGE=%d num_sge=%d num_chain=%d\n",
4256 ioc
->name
, numSGE
, num_sge
, num_chain
));
4258 if (ioc
->bus_type
== SPI
)
4259 num_chain
*= MPT_SCSI_CAN_QUEUE
;
4261 num_chain
*= MPT_FC_CAN_QUEUE
;
4263 ioc
->num_chain
= num_chain
;
4265 sz
= num_chain
* sizeof(int);
4266 if (ioc
->ChainToChain
== NULL
) {
4267 mem
= kmalloc(sz
, GFP_ATOMIC
);
4271 ioc
->ChainToChain
= (int *) mem
;
4272 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainToChain alloc @ %p, sz=%d bytes\n",
4273 ioc
->name
, mem
, sz
));
4275 mem
= (u8
*) ioc
->ChainToChain
;
4277 memset(mem
, 0xFF, sz
);
4281 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4283 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
4284 * @ioc: Pointer to MPT_ADAPTER structure
4286 * This routine allocates memory for the MPT reply and request frame
4287 * pools (if necessary), and primes the IOC reply FIFO with
4290 * Returns 0 for success, non-zero for failure.
4293 PrimeIocFifos(MPT_ADAPTER
*ioc
)
4296 unsigned long flags
;
4297 dma_addr_t alloc_dma
;
4299 int i
, reply_sz
, sz
, total_size
, num_chain
;
4304 /* Prime reply FIFO... */
4306 if (ioc
->reply_frames
== NULL
) {
4307 if ( (num_chain
= initChainBuffers(ioc
)) < 0)
4310 * 1078 errata workaround for the 36GB limitation
4312 if (ioc
->pcidev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1078
&&
4313 ioc
->dma_mask
> DMA_35BIT_MASK
) {
4314 if (!pci_set_dma_mask(ioc
->pcidev
, DMA_BIT_MASK(32))
4315 && !pci_set_consistent_dma_mask(ioc
->pcidev
,
4316 DMA_BIT_MASK(32))) {
4317 dma_mask
= DMA_35BIT_MASK
;
4318 d36memprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4319 "setting 35 bit addressing for "
4320 "Request/Reply/Chain and Sense Buffers\n",
4323 /*Reseting DMA mask to 64 bit*/
4324 pci_set_dma_mask(ioc
->pcidev
,
4326 pci_set_consistent_dma_mask(ioc
->pcidev
,
4329 printk(MYIOC_s_ERR_FMT
4330 "failed setting 35 bit addressing for "
4331 "Request/Reply/Chain and Sense Buffers\n",
4337 total_size
= reply_sz
= (ioc
->reply_sz
* ioc
->reply_depth
);
4338 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
4339 ioc
->name
, ioc
->reply_sz
, ioc
->reply_depth
));
4340 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffer sz=%d[%x] bytes\n",
4341 ioc
->name
, reply_sz
, reply_sz
));
4343 sz
= (ioc
->req_sz
* ioc
->req_depth
);
4344 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestBuffer sz=%d bytes, RequestDepth=%d\n",
4345 ioc
->name
, ioc
->req_sz
, ioc
->req_depth
));
4346 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestBuffer sz=%d[%x] bytes\n",
4347 ioc
->name
, sz
, sz
));
4350 sz
= num_chain
* ioc
->req_sz
; /* chain buffer pool size */
4351 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainBuffer sz=%d bytes, ChainDepth=%d\n",
4352 ioc
->name
, ioc
->req_sz
, num_chain
));
4353 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
4354 ioc
->name
, sz
, sz
, num_chain
));
4357 mem
= pci_alloc_consistent(ioc
->pcidev
, total_size
, &alloc_dma
);
4359 printk(MYIOC_s_ERR_FMT
"Unable to allocate Reply, Request, Chain Buffers!\n",
4364 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Total alloc @ %p[%p], sz=%d[%x] bytes\n",
4365 ioc
->name
, mem
, (void *)(ulong
)alloc_dma
, total_size
, total_size
));
4367 memset(mem
, 0, total_size
);
4368 ioc
->alloc_total
+= total_size
;
4370 ioc
->alloc_dma
= alloc_dma
;
4371 ioc
->alloc_sz
= total_size
;
4372 ioc
->reply_frames
= (MPT_FRAME_HDR
*) mem
;
4373 ioc
->reply_frames_low_dma
= (u32
) (alloc_dma
& 0xFFFFFFFF);
4375 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffers @ %p[%p]\n",
4376 ioc
->name
, ioc
->reply_frames
, (void *)(ulong
)alloc_dma
));
4378 alloc_dma
+= reply_sz
;
4381 /* Request FIFO - WE manage this! */
4383 ioc
->req_frames
= (MPT_FRAME_HDR
*) mem
;
4384 ioc
->req_frames_dma
= alloc_dma
;
4386 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestBuffers @ %p[%p]\n",
4387 ioc
->name
, mem
, (void *)(ulong
)alloc_dma
));
4389 ioc
->req_frames_low_dma
= (u32
) (alloc_dma
& 0xFFFFFFFF);
4391 #if defined(CONFIG_MTRR) && 0
4393 * Enable Write Combining MTRR for IOC's memory region.
4394 * (at least as much as we can; "size and base must be
4395 * multiples of 4 kiB"
4397 ioc
->mtrr_reg
= mtrr_add(ioc
->req_frames_dma
,
4399 MTRR_TYPE_WRCOMB
, 1);
4400 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"MTRR region registered (base:size=%08x:%x)\n",
4401 ioc
->name
, ioc
->req_frames_dma
, sz
));
4404 for (i
= 0; i
< ioc
->req_depth
; i
++) {
4405 alloc_dma
+= ioc
->req_sz
;
4409 ioc
->ChainBuffer
= mem
;
4410 ioc
->ChainBufferDMA
= alloc_dma
;
4412 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainBuffers @ %p(%p)\n",
4413 ioc
->name
, ioc
->ChainBuffer
, (void *)(ulong
)ioc
->ChainBufferDMA
));
4415 /* Initialize the free chain Q.
4418 INIT_LIST_HEAD(&ioc
->FreeChainQ
);
4420 /* Post the chain buffers to the FreeChainQ.
4422 mem
= (u8
*)ioc
->ChainBuffer
;
4423 for (i
=0; i
< num_chain
; i
++) {
4424 mf
= (MPT_FRAME_HDR
*) mem
;
4425 list_add_tail(&mf
->u
.frame
.linkage
.list
, &ioc
->FreeChainQ
);
4429 /* Initialize Request frames linked list
4431 alloc_dma
= ioc
->req_frames_dma
;
4432 mem
= (u8
*) ioc
->req_frames
;
4434 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
4435 INIT_LIST_HEAD(&ioc
->FreeQ
);
4436 for (i
= 0; i
< ioc
->req_depth
; i
++) {
4437 mf
= (MPT_FRAME_HDR
*) mem
;
4439 /* Queue REQUESTs *internally*! */
4440 list_add_tail(&mf
->u
.frame
.linkage
.list
, &ioc
->FreeQ
);
4444 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
4446 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
4447 ioc
->sense_buf_pool
=
4448 pci_alloc_consistent(ioc
->pcidev
, sz
, &ioc
->sense_buf_pool_dma
);
4449 if (ioc
->sense_buf_pool
== NULL
) {
4450 printk(MYIOC_s_ERR_FMT
"Unable to allocate Sense Buffers!\n",
4455 ioc
->sense_buf_low_dma
= (u32
) (ioc
->sense_buf_pool_dma
& 0xFFFFFFFF);
4456 ioc
->alloc_total
+= sz
;
4457 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SenseBuffers @ %p[%p]\n",
4458 ioc
->name
, ioc
->sense_buf_pool
, (void *)(ulong
)ioc
->sense_buf_pool_dma
));
4462 /* Post Reply frames to FIFO
4464 alloc_dma
= ioc
->alloc_dma
;
4465 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffers @ %p[%p]\n",
4466 ioc
->name
, ioc
->reply_frames
, (void *)(ulong
)alloc_dma
));
4468 for (i
= 0; i
< ioc
->reply_depth
; i
++) {
4469 /* Write each address to the IOC! */
4470 CHIPREG_WRITE32(&ioc
->chip
->ReplyFifo
, alloc_dma
);
4471 alloc_dma
+= ioc
->reply_sz
;
4474 if (dma_mask
== DMA_35BIT_MASK
&& !pci_set_dma_mask(ioc
->pcidev
,
4475 ioc
->dma_mask
) && !pci_set_consistent_dma_mask(ioc
->pcidev
,
4477 d36memprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4478 "restoring 64 bit addressing\n", ioc
->name
));
4483 if (ioc
->alloc
!= NULL
) {
4485 pci_free_consistent(ioc
->pcidev
,
4487 ioc
->alloc
, ioc
->alloc_dma
);
4488 ioc
->reply_frames
= NULL
;
4489 ioc
->req_frames
= NULL
;
4490 ioc
->alloc_total
-= sz
;
4492 if (ioc
->sense_buf_pool
!= NULL
) {
4493 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
4494 pci_free_consistent(ioc
->pcidev
,
4496 ioc
->sense_buf_pool
, ioc
->sense_buf_pool_dma
);
4497 ioc
->sense_buf_pool
= NULL
;
4500 if (dma_mask
== DMA_35BIT_MASK
&& !pci_set_dma_mask(ioc
->pcidev
,
4501 DMA_BIT_MASK(64)) && !pci_set_consistent_dma_mask(ioc
->pcidev
,
4503 d36memprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4504 "restoring 64 bit addressing\n", ioc
->name
));
4509 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4511 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4512 * from IOC via doorbell handshake method.
4513 * @ioc: Pointer to MPT_ADAPTER structure
4514 * @reqBytes: Size of the request in bytes
4515 * @req: Pointer to MPT request frame
4516 * @replyBytes: Expected size of the reply in bytes
4517 * @u16reply: Pointer to area where reply should be written
4518 * @maxwait: Max wait time for a reply (in seconds)
4519 * @sleepFlag: Specifies whether the process can sleep
4521 * NOTES: It is the callers responsibility to byte-swap fields in the
4522 * request which are greater than 1 byte in size. It is also the
4523 * callers responsibility to byte-swap response fields which are
4524 * greater than 1 byte in size.
4526 * Returns 0 for success, non-zero for failure.
4529 mpt_handshake_req_reply_wait(MPT_ADAPTER
*ioc
, int reqBytes
, u32
*req
,
4530 int replyBytes
, u16
*u16reply
, int maxwait
, int sleepFlag
)
4532 MPIDefaultReply_t
*mptReply
;
4537 * Get ready to cache a handshake reply
4539 ioc
->hs_reply_idx
= 0;
4540 mptReply
= (MPIDefaultReply_t
*) ioc
->hs_reply
;
4541 mptReply
->MsgLength
= 0;
4544 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4545 * then tell IOC that we want to handshake a request of N words.
4546 * (WRITE u32val to Doorbell reg).
4548 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4549 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
,
4550 ((MPI_FUNCTION_HANDSHAKE
<<MPI_DOORBELL_FUNCTION_SHIFT
) |
4551 ((reqBytes
/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT
)));
4554 * Wait for IOC's doorbell handshake int
4556 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4559 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4560 ioc
->name
, reqBytes
, t
, failcnt
? " - MISSING DOORBELL HANDSHAKE!" : ""));
4562 /* Read doorbell and check for active bit */
4563 if (!(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & MPI_DOORBELL_ACTIVE
))
4567 * Clear doorbell int (WRITE 0 to IntStatus reg),
4568 * then wait for IOC to ACKnowledge that it's ready for
4569 * our handshake request.
4571 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4572 if (!failcnt
&& (t
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
4577 u8
*req_as_bytes
= (u8
*) req
;
4580 * Stuff request words via doorbell handshake,
4581 * with ACK from IOC for each.
4583 for (ii
= 0; !failcnt
&& ii
< reqBytes
/4; ii
++) {
4584 u32 word
= ((req_as_bytes
[(ii
*4) + 0] << 0) |
4585 (req_as_bytes
[(ii
*4) + 1] << 8) |
4586 (req_as_bytes
[(ii
*4) + 2] << 16) |
4587 (req_as_bytes
[(ii
*4) + 3] << 24));
4589 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, word
);
4590 if ((t
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
4594 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Handshake request frame (@%p) header\n", ioc
->name
, req
));
4595 DBG_DUMP_REQUEST_FRAME_HDR(ioc
, (u32
*)req
);
4597 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HandShake request post done, WaitCnt=%d%s\n",
4598 ioc
->name
, t
, failcnt
? " - MISSING DOORBELL ACK!" : ""));
4601 * Wait for completion of doorbell handshake reply from the IOC
4603 if (!failcnt
&& (t
= WaitForDoorbellReply(ioc
, maxwait
, sleepFlag
)) < 0)
4606 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HandShake reply count=%d%s\n",
4607 ioc
->name
, t
, failcnt
? " - MISSING DOORBELL REPLY!" : ""));
4610 * Copy out the cached reply...
4612 for (ii
=0; ii
< min(replyBytes
/2,mptReply
->MsgLength
*2); ii
++)
4613 u16reply
[ii
] = ioc
->hs_reply
[ii
];
4621 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4623 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4624 * @ioc: Pointer to MPT_ADAPTER structure
4625 * @howlong: How long to wait (in seconds)
4626 * @sleepFlag: Specifies whether the process can sleep
4628 * This routine waits (up to ~2 seconds max) for IOC doorbell
4629 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4630 * bit in its IntStatus register being clear.
4632 * Returns a negative value on failure, else wait loop count.
4635 WaitForDoorbellAck(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
4641 cntdn
= 1000 * howlong
;
4643 if (sleepFlag
== CAN_SLEEP
) {
4646 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4647 if (! (intstat
& MPI_HIS_IOP_DOORBELL_STATUS
))
4654 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4655 if (! (intstat
& MPI_HIS_IOP_DOORBELL_STATUS
))
4662 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitForDoorbell ACK (count=%d)\n",
4667 printk(MYIOC_s_ERR_FMT
"Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4668 ioc
->name
, count
, intstat
);
4672 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4674 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4675 * @ioc: Pointer to MPT_ADAPTER structure
4676 * @howlong: How long to wait (in seconds)
4677 * @sleepFlag: Specifies whether the process can sleep
4679 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4680 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4682 * Returns a negative value on failure, else wait loop count.
4685 WaitForDoorbellInt(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
4691 cntdn
= 1000 * howlong
;
4692 if (sleepFlag
== CAN_SLEEP
) {
4694 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4695 if (intstat
& MPI_HIS_DOORBELL_INTERRUPT
)
4702 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4703 if (intstat
& MPI_HIS_DOORBELL_INTERRUPT
)
4711 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4712 ioc
->name
, count
, howlong
));
4716 printk(MYIOC_s_ERR_FMT
"Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4717 ioc
->name
, count
, intstat
);
4721 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4723 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4724 * @ioc: Pointer to MPT_ADAPTER structure
4725 * @howlong: How long to wait (in seconds)
4726 * @sleepFlag: Specifies whether the process can sleep
4728 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4729 * Reply is cached to IOC private area large enough to hold a maximum
4730 * of 128 bytes of reply data.
4732 * Returns a negative value on failure, else size of reply in WORDS.
4735 WaitForDoorbellReply(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
4740 u16
*hs_reply
= ioc
->hs_reply
;
4741 volatile MPIDefaultReply_t
*mptReply
= (MPIDefaultReply_t
*) ioc
->hs_reply
;
4744 hs_reply
[0] = hs_reply
[1] = hs_reply
[7] = 0;
4747 * Get first two u16's so we can look at IOC's intended reply MsgLength
4750 if ((t
= WaitForDoorbellInt(ioc
, howlong
, sleepFlag
)) < 0) {
4753 hs_reply
[u16cnt
++] = le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4754 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4755 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4758 hs_reply
[u16cnt
++] = le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4759 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4763 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitCnt=%d First handshake reply word=%08x%s\n",
4764 ioc
->name
, t
, le32_to_cpu(*(u32
*)hs_reply
),
4765 failcnt
? " - MISSING DOORBELL HANDSHAKE!" : ""));
4768 * If no error (and IOC said MsgLength is > 0), piece together
4769 * reply 16 bits at a time.
4771 for (u16cnt
=2; !failcnt
&& u16cnt
< (2 * mptReply
->MsgLength
); u16cnt
++) {
4772 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4774 hword
= le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4775 /* don't overflow our IOC hs_reply[] buffer! */
4776 if (u16cnt
< ARRAY_SIZE(ioc
->hs_reply
))
4777 hs_reply
[u16cnt
] = hword
;
4778 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4781 if (!failcnt
&& (t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4783 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4786 printk(MYIOC_s_ERR_FMT
"Handshake reply failure!\n",
4791 else if (u16cnt
!= (2 * mptReply
->MsgLength
)) {
4794 else if ((mptReply
->IOCStatus
& MPI_IOCSTATUS_MASK
) != MPI_IOCSTATUS_SUCCESS
) {
4799 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Got Handshake reply:\n", ioc
->name
));
4800 DBG_DUMP_REPLY_FRAME(ioc
, (u32
*)mptReply
);
4802 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4803 ioc
->name
, t
, u16cnt
/2));
4807 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4809 * GetLanConfigPages - Fetch LANConfig pages.
4810 * @ioc: Pointer to MPT_ADAPTER structure
4812 * Return: 0 for success
4813 * -ENOMEM if no memory available
4814 * -EPERM if not allowed due to ISR context
4815 * -EAGAIN if no msg frames currently available
4816 * -EFAULT for non-successful reply or no reply (timeout)
4819 GetLanConfigPages(MPT_ADAPTER
*ioc
)
4821 ConfigPageHeader_t hdr
;
4823 LANPage0_t
*ppage0_alloc
;
4824 dma_addr_t page0_dma
;
4825 LANPage1_t
*ppage1_alloc
;
4826 dma_addr_t page1_dma
;
4831 /* Get LAN Page 0 header */
4832 hdr
.PageVersion
= 0;
4835 hdr
.PageType
= MPI_CONFIG_PAGETYPE_LAN
;
4836 cfg
.cfghdr
.hdr
= &hdr
;
4838 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4843 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
4846 if (hdr
.PageLength
> 0) {
4847 data_sz
= hdr
.PageLength
* 4;
4848 ppage0_alloc
= (LANPage0_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page0_dma
);
4851 memset((u8
*)ppage0_alloc
, 0, data_sz
);
4852 cfg
.physAddr
= page0_dma
;
4853 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4855 if ((rc
= mpt_config(ioc
, &cfg
)) == 0) {
4857 copy_sz
= min_t(int, sizeof(LANPage0_t
), data_sz
);
4858 memcpy(&ioc
->lan_cnfg_page0
, ppage0_alloc
, copy_sz
);
4862 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage0_alloc
, page0_dma
);
4865 * Normalize endianness of structure data,
4866 * by byte-swapping all > 1 byte fields!
4875 /* Get LAN Page 1 header */
4876 hdr
.PageVersion
= 0;
4879 hdr
.PageType
= MPI_CONFIG_PAGETYPE_LAN
;
4880 cfg
.cfghdr
.hdr
= &hdr
;
4882 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4886 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
4889 if (hdr
.PageLength
== 0)
4892 data_sz
= hdr
.PageLength
* 4;
4894 ppage1_alloc
= (LANPage1_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page1_dma
);
4896 memset((u8
*)ppage1_alloc
, 0, data_sz
);
4897 cfg
.physAddr
= page1_dma
;
4898 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4900 if ((rc
= mpt_config(ioc
, &cfg
)) == 0) {
4902 copy_sz
= min_t(int, sizeof(LANPage1_t
), data_sz
);
4903 memcpy(&ioc
->lan_cnfg_page1
, ppage1_alloc
, copy_sz
);
4906 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage1_alloc
, page1_dma
);
4909 * Normalize endianness of structure data,
4910 * by byte-swapping all > 1 byte fields!
4918 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4920 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
4921 * @ioc: Pointer to MPT_ADAPTER structure
4922 * @persist_opcode: see below
4924 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4925 * devices not currently present.
4926 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4928 * NOTE: Don't use not this function during interrupt time.
4930 * Returns 0 for success, non-zero error
4933 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4935 mptbase_sas_persist_operation(MPT_ADAPTER
*ioc
, u8 persist_opcode
)
4937 SasIoUnitControlRequest_t
*sasIoUnitCntrReq
;
4938 SasIoUnitControlReply_t
*sasIoUnitCntrReply
;
4939 MPT_FRAME_HDR
*mf
= NULL
;
4940 MPIHeader_t
*mpi_hdr
;
4942 unsigned long timeleft
;
4944 mutex_lock(&ioc
->mptbase_cmds
.mutex
);
4946 /* init the internal cmd struct */
4947 memset(ioc
->mptbase_cmds
.reply
, 0 , MPT_DEFAULT_FRAME_SIZE
);
4948 INITIALIZE_MGMT_STATUS(ioc
->mptbase_cmds
.status
)
4950 /* insure garbage is not sent to fw */
4951 switch(persist_opcode
) {
4953 case MPI_SAS_OP_CLEAR_NOT_PRESENT
:
4954 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT
:
4962 printk(KERN_DEBUG
"%s: persist_opcode=%x\n",
4963 __func__
, persist_opcode
);
4965 /* Get a MF for this command.
4967 if ((mf
= mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
4968 printk(KERN_DEBUG
"%s: no msg frames!\n", __func__
);
4973 mpi_hdr
= (MPIHeader_t
*) mf
;
4974 sasIoUnitCntrReq
= (SasIoUnitControlRequest_t
*)mf
;
4975 memset(sasIoUnitCntrReq
,0,sizeof(SasIoUnitControlRequest_t
));
4976 sasIoUnitCntrReq
->Function
= MPI_FUNCTION_SAS_IO_UNIT_CONTROL
;
4977 sasIoUnitCntrReq
->MsgContext
= mpi_hdr
->MsgContext
;
4978 sasIoUnitCntrReq
->Operation
= persist_opcode
;
4980 mpt_put_msg_frame(mpt_base_index
, ioc
, mf
);
4981 timeleft
= wait_for_completion_timeout(&ioc
->mptbase_cmds
.done
, 10*HZ
);
4982 if (!(ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_COMMAND_GOOD
)) {
4984 printk(KERN_DEBUG
"%s: failed\n", __func__
);
4985 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_DID_IOCRESET
)
4988 printk(KERN_DEBUG
"%s: Issuing Reset from %s!!\n",
4989 ioc
->name
, __func__
);
4990 mpt_HardResetHandler(ioc
, CAN_SLEEP
);
4991 mpt_free_msg_frame(ioc
, mf
);
4996 if (!(ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_RF_VALID
)) {
5001 sasIoUnitCntrReply
=
5002 (SasIoUnitControlReply_t
*)ioc
->mptbase_cmds
.reply
;
5003 if (le16_to_cpu(sasIoUnitCntrReply
->IOCStatus
) != MPI_IOCSTATUS_SUCCESS
) {
5004 printk(KERN_DEBUG
"%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
5005 __func__
, sasIoUnitCntrReply
->IOCStatus
,
5006 sasIoUnitCntrReply
->IOCLogInfo
);
5007 printk(KERN_DEBUG
"%s: failed\n", __func__
);
5010 printk(KERN_DEBUG
"%s: success\n", __func__
);
5013 CLEAR_MGMT_STATUS(ioc
->mptbase_cmds
.status
)
5014 mutex_unlock(&ioc
->mptbase_cmds
.mutex
);
5018 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5021 mptbase_raid_process_event_data(MPT_ADAPTER
*ioc
,
5022 MpiEventDataRaid_t
* pRaidEventData
)
5031 volume
= pRaidEventData
->VolumeID
;
5032 reason
= pRaidEventData
->ReasonCode
;
5033 disk
= pRaidEventData
->PhysDiskNum
;
5034 status
= le32_to_cpu(pRaidEventData
->SettingsStatus
);
5035 flags
= (status
>> 0) & 0xff;
5036 state
= (status
>> 8) & 0xff;
5038 if (reason
== MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
) {
5042 if ((reason
>= MPI_EVENT_RAID_RC_PHYSDISK_CREATED
&&
5043 reason
<= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
) ||
5044 (reason
== MPI_EVENT_RAID_RC_SMART_DATA
)) {
5045 printk(MYIOC_s_INFO_FMT
"RAID STATUS CHANGE for PhysDisk %d id=%d\n",
5046 ioc
->name
, disk
, volume
);
5048 printk(MYIOC_s_INFO_FMT
"RAID STATUS CHANGE for VolumeID %d\n",
5053 case MPI_EVENT_RAID_RC_VOLUME_CREATED
:
5054 printk(MYIOC_s_INFO_FMT
" volume has been created\n",
5058 case MPI_EVENT_RAID_RC_VOLUME_DELETED
:
5060 printk(MYIOC_s_INFO_FMT
" volume has been deleted\n",
5064 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED
:
5065 printk(MYIOC_s_INFO_FMT
" volume settings have been changed\n",
5069 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED
:
5070 printk(MYIOC_s_INFO_FMT
" volume is now %s%s%s%s\n",
5072 state
== MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
5074 : state
== MPI_RAIDVOL0_STATUS_STATE_DEGRADED
5076 : state
== MPI_RAIDVOL0_STATUS_STATE_FAILED
5079 flags
& MPI_RAIDVOL0_STATUS_FLAG_ENABLED
5081 flags
& MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
5082 ? ", quiesced" : "",
5083 flags
& MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
5084 ? ", resync in progress" : "" );
5087 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED
:
5088 printk(MYIOC_s_INFO_FMT
" volume membership of PhysDisk %d has changed\n",
5092 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED
:
5093 printk(MYIOC_s_INFO_FMT
" PhysDisk has been created\n",
5097 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED
:
5098 printk(MYIOC_s_INFO_FMT
" PhysDisk has been deleted\n",
5102 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED
:
5103 printk(MYIOC_s_INFO_FMT
" PhysDisk settings have been changed\n",
5107 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
:
5108 printk(MYIOC_s_INFO_FMT
" PhysDisk is now %s%s%s\n",
5110 state
== MPI_PHYSDISK0_STATUS_ONLINE
5112 : state
== MPI_PHYSDISK0_STATUS_MISSING
5114 : state
== MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
5116 : state
== MPI_PHYSDISK0_STATUS_FAILED
5118 : state
== MPI_PHYSDISK0_STATUS_INITIALIZING
5120 : state
== MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
5121 ? "offline requested"
5122 : state
== MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
5123 ? "failed requested"
5124 : state
== MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
5127 flags
& MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
5128 ? ", out of sync" : "",
5129 flags
& MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
5130 ? ", quiesced" : "" );
5133 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
:
5134 printk(MYIOC_s_INFO_FMT
" Domain Validation needed for PhysDisk %d\n",
5138 case MPI_EVENT_RAID_RC_SMART_DATA
:
5139 printk(MYIOC_s_INFO_FMT
" SMART data received, ASC/ASCQ = %02xh/%02xh\n",
5140 ioc
->name
, pRaidEventData
->ASC
, pRaidEventData
->ASCQ
);
5143 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED
:
5144 printk(MYIOC_s_INFO_FMT
" replacement of PhysDisk %d has started\n",
5150 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5152 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
5153 * @ioc: Pointer to MPT_ADAPTER structure
5155 * Returns: 0 for success
5156 * -ENOMEM if no memory available
5157 * -EPERM if not allowed due to ISR context
5158 * -EAGAIN if no msg frames currently available
5159 * -EFAULT for non-successful reply or no reply (timeout)
5162 GetIoUnitPage2(MPT_ADAPTER
*ioc
)
5164 ConfigPageHeader_t hdr
;
5166 IOUnitPage2_t
*ppage_alloc
;
5167 dma_addr_t page_dma
;
5171 /* Get the page header */
5172 hdr
.PageVersion
= 0;
5175 hdr
.PageType
= MPI_CONFIG_PAGETYPE_IO_UNIT
;
5176 cfg
.cfghdr
.hdr
= &hdr
;
5178 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5183 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
5186 if (hdr
.PageLength
== 0)
5189 /* Read the config page */
5190 data_sz
= hdr
.PageLength
* 4;
5192 ppage_alloc
= (IOUnitPage2_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page_dma
);
5194 memset((u8
*)ppage_alloc
, 0, data_sz
);
5195 cfg
.physAddr
= page_dma
;
5196 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5198 /* If Good, save data */
5199 if ((rc
= mpt_config(ioc
, &cfg
)) == 0)
5200 ioc
->biosVersion
= le32_to_cpu(ppage_alloc
->BiosVersion
);
5202 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage_alloc
, page_dma
);
5208 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5210 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
5211 * @ioc: Pointer to a Adapter Strucutre
5212 * @portnum: IOC port number
5214 * Return: -EFAULT if read of config page header fails
5216 * If read of SCSI Port Page 0 fails,
5217 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5218 * Adapter settings: async, narrow
5220 * If read of SCSI Port Page 2 fails,
5221 * Adapter settings valid
5222 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5227 * CHECK - what type of locking mechanisms should be used????
5230 mpt_GetScsiPortSettings(MPT_ADAPTER
*ioc
, int portnum
)
5235 ConfigPageHeader_t header
;
5241 if (!ioc
->spi_data
.nvram
) {
5244 sz
= MPT_MAX_SCSI_DEVICES
* sizeof(int);
5245 mem
= kmalloc(sz
, GFP_ATOMIC
);
5249 ioc
->spi_data
.nvram
= (int *) mem
;
5251 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SCSI device NVRAM settings @ %p, sz=%d\n",
5252 ioc
->name
, ioc
->spi_data
.nvram
, sz
));
5255 /* Invalidate NVRAM information
5257 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
5258 ioc
->spi_data
.nvram
[ii
] = MPT_HOST_NVRAM_INVALID
;
5261 /* Read SPP0 header, allocate memory, then read page.
5263 header
.PageVersion
= 0;
5264 header
.PageLength
= 0;
5265 header
.PageNumber
= 0;
5266 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_PORT
;
5267 cfg
.cfghdr
.hdr
= &header
;
5269 cfg
.pageAddr
= portnum
;
5270 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5272 cfg
.timeout
= 0; /* use default */
5273 if (mpt_config(ioc
, &cfg
) != 0)
5276 if (header
.PageLength
> 0) {
5277 pbuf
= pci_alloc_consistent(ioc
->pcidev
, header
.PageLength
* 4, &buf_dma
);
5279 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5280 cfg
.physAddr
= buf_dma
;
5281 if (mpt_config(ioc
, &cfg
) != 0) {
5282 ioc
->spi_data
.maxBusWidth
= MPT_NARROW
;
5283 ioc
->spi_data
.maxSyncOffset
= 0;
5284 ioc
->spi_data
.minSyncFactor
= MPT_ASYNC
;
5285 ioc
->spi_data
.busType
= MPT_HOST_BUS_UNKNOWN
;
5287 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5288 "Unable to read PortPage0 minSyncFactor=%x\n",
5289 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
5291 /* Save the Port Page 0 data
5293 SCSIPortPage0_t
*pPP0
= (SCSIPortPage0_t
*) pbuf
;
5294 pPP0
->Capabilities
= le32_to_cpu(pPP0
->Capabilities
);
5295 pPP0
->PhysicalInterface
= le32_to_cpu(pPP0
->PhysicalInterface
);
5297 if ( (pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_QAS
) == 0 ) {
5298 ioc
->spi_data
.noQas
|= MPT_TARGET_NO_NEGO_QAS
;
5299 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5300 "noQas due to Capabilities=%x\n",
5301 ioc
->name
, pPP0
->Capabilities
));
5303 ioc
->spi_data
.maxBusWidth
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_WIDE
? 1 : 0;
5304 data
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK
;
5306 ioc
->spi_data
.maxSyncOffset
= (u8
) (data
>> 16);
5307 data
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK
;
5308 ioc
->spi_data
.minSyncFactor
= (u8
) (data
>> 8);
5309 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5310 "PortPage0 minSyncFactor=%x\n",
5311 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
5313 ioc
->spi_data
.maxSyncOffset
= 0;
5314 ioc
->spi_data
.minSyncFactor
= MPT_ASYNC
;
5317 ioc
->spi_data
.busType
= pPP0
->PhysicalInterface
& MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK
;
5319 /* Update the minSyncFactor based on bus type.
5321 if ((ioc
->spi_data
.busType
== MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD
) ||
5322 (ioc
->spi_data
.busType
== MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE
)) {
5324 if (ioc
->spi_data
.minSyncFactor
< MPT_ULTRA
) {
5325 ioc
->spi_data
.minSyncFactor
= MPT_ULTRA
;
5326 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5327 "HVD or SE detected, minSyncFactor=%x\n",
5328 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
5333 pci_free_consistent(ioc
->pcidev
, header
.PageLength
* 4, pbuf
, buf_dma
);
5338 /* SCSI Port Page 2 - Read the header then the page.
5340 header
.PageVersion
= 0;
5341 header
.PageLength
= 0;
5342 header
.PageNumber
= 2;
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 if (mpt_config(ioc
, &cfg
) != 0)
5352 if (header
.PageLength
> 0) {
5353 /* Allocate memory and read SCSI Port Page 2
5355 pbuf
= pci_alloc_consistent(ioc
->pcidev
, header
.PageLength
* 4, &buf_dma
);
5357 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_NVRAM
;
5358 cfg
.physAddr
= buf_dma
;
5359 if (mpt_config(ioc
, &cfg
) != 0) {
5360 /* Nvram data is left with INVALID mark
5363 } else if (ioc
->pcidev
->vendor
== PCI_VENDOR_ID_ATTO
) {
5365 /* This is an ATTO adapter, read Page2 accordingly
5367 ATTO_SCSIPortPage2_t
*pPP2
= (ATTO_SCSIPortPage2_t
*) pbuf
;
5368 ATTODeviceInfo_t
*pdevice
= NULL
;
5371 /* Save the Port Page 2 data
5372 * (reformat into a 32bit quantity)
5374 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
5375 pdevice
= &pPP2
->DeviceSettings
[ii
];
5376 ATTOFlags
= le16_to_cpu(pdevice
->ATTOFlags
);
5379 /* Translate ATTO device flags to LSI format
5381 if (ATTOFlags
& ATTOFLAG_DISC
)
5382 data
|= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE
);
5383 if (ATTOFlags
& ATTOFLAG_ID_ENB
)
5384 data
|= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE
);
5385 if (ATTOFlags
& ATTOFLAG_LUN_ENB
)
5386 data
|= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE
);
5387 if (ATTOFlags
& ATTOFLAG_TAGGED
)
5388 data
|= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE
);
5389 if (!(ATTOFlags
& ATTOFLAG_WIDE_ENB
))
5390 data
|= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE
);
5392 data
= (data
<< 16) | (pdevice
->Period
<< 8) | 10;
5393 ioc
->spi_data
.nvram
[ii
] = data
;
5396 SCSIPortPage2_t
*pPP2
= (SCSIPortPage2_t
*) pbuf
;
5397 MpiDeviceInfo_t
*pdevice
= NULL
;
5400 * Save "Set to Avoid SCSI Bus Resets" flag
5402 ioc
->spi_data
.bus_reset
=
5403 (le32_to_cpu(pPP2
->PortFlags
) &
5404 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET
) ?
5407 /* Save the Port Page 2 data
5408 * (reformat into a 32bit quantity)
5410 data
= le32_to_cpu(pPP2
->PortFlags
) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK
;
5411 ioc
->spi_data
.PortFlags
= data
;
5412 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
5413 pdevice
= &pPP2
->DeviceSettings
[ii
];
5414 data
= (le16_to_cpu(pdevice
->DeviceFlags
) << 16) |
5415 (pdevice
->SyncFactor
<< 8) | pdevice
->Timeout
;
5416 ioc
->spi_data
.nvram
[ii
] = data
;
5420 pci_free_consistent(ioc
->pcidev
, header
.PageLength
* 4, pbuf
, buf_dma
);
5424 /* Update Adapter limits with those from NVRAM
5425 * Comment: Don't need to do this. Target performance
5426 * parameters will never exceed the adapters limits.
5432 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5434 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
5435 * @ioc: Pointer to a Adapter Strucutre
5436 * @portnum: IOC port number
5438 * Return: -EFAULT if read of config page header fails
5442 mpt_readScsiDevicePageHeaders(MPT_ADAPTER
*ioc
, int portnum
)
5445 ConfigPageHeader_t header
;
5447 /* Read the SCSI Device Page 1 header
5449 header
.PageVersion
= 0;
5450 header
.PageLength
= 0;
5451 header
.PageNumber
= 1;
5452 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_DEVICE
;
5453 cfg
.cfghdr
.hdr
= &header
;
5455 cfg
.pageAddr
= portnum
;
5456 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5459 if (mpt_config(ioc
, &cfg
) != 0)
5462 ioc
->spi_data
.sdp1version
= cfg
.cfghdr
.hdr
->PageVersion
;
5463 ioc
->spi_data
.sdp1length
= cfg
.cfghdr
.hdr
->PageLength
;
5465 header
.PageVersion
= 0;
5466 header
.PageLength
= 0;
5467 header
.PageNumber
= 0;
5468 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_DEVICE
;
5469 if (mpt_config(ioc
, &cfg
) != 0)
5472 ioc
->spi_data
.sdp0version
= cfg
.cfghdr
.hdr
->PageVersion
;
5473 ioc
->spi_data
.sdp0length
= cfg
.cfghdr
.hdr
->PageLength
;
5475 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Headers: 0: version %d length %d\n",
5476 ioc
->name
, ioc
->spi_data
.sdp0version
, ioc
->spi_data
.sdp0length
));
5478 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Headers: 1: version %d length %d\n",
5479 ioc
->name
, ioc
->spi_data
.sdp1version
, ioc
->spi_data
.sdp1length
));
5484 * mpt_inactive_raid_list_free - This clears this link list.
5485 * @ioc : pointer to per adapter structure
5488 mpt_inactive_raid_list_free(MPT_ADAPTER
*ioc
)
5490 struct inactive_raid_component_info
*component_info
, *pNext
;
5492 if (list_empty(&ioc
->raid_data
.inactive_list
))
5495 mutex_lock(&ioc
->raid_data
.inactive_list_mutex
);
5496 list_for_each_entry_safe(component_info
, pNext
,
5497 &ioc
->raid_data
.inactive_list
, list
) {
5498 list_del(&component_info
->list
);
5499 kfree(component_info
);
5501 mutex_unlock(&ioc
->raid_data
.inactive_list_mutex
);
5505 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5507 * @ioc : pointer to per adapter structure
5508 * @channel : volume channel
5509 * @id : volume target id
5512 mpt_inactive_raid_volumes(MPT_ADAPTER
*ioc
, u8 channel
, u8 id
)
5515 ConfigPageHeader_t hdr
;
5516 dma_addr_t dma_handle
;
5517 pRaidVolumePage0_t buffer
= NULL
;
5519 RaidPhysDiskPage0_t phys_disk
;
5520 struct inactive_raid_component_info
*component_info
;
5521 int handle_inactive_volumes
;
5523 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5524 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5525 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_VOLUME
;
5526 cfg
.pageAddr
= (channel
<< 8) + id
;
5527 cfg
.cfghdr
.hdr
= &hdr
;
5528 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5530 if (mpt_config(ioc
, &cfg
) != 0)
5533 if (!hdr
.PageLength
)
5536 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5542 cfg
.physAddr
= dma_handle
;
5543 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5545 if (mpt_config(ioc
, &cfg
) != 0)
5548 if (!buffer
->NumPhysDisks
)
5551 handle_inactive_volumes
=
5552 (buffer
->VolumeStatus
.Flags
& MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE
||
5553 (buffer
->VolumeStatus
.Flags
& MPI_RAIDVOL0_STATUS_FLAG_ENABLED
) == 0 ||
5554 buffer
->VolumeStatus
.State
== MPI_RAIDVOL0_STATUS_STATE_FAILED
||
5555 buffer
->VolumeStatus
.State
== MPI_RAIDVOL0_STATUS_STATE_MISSING
) ? 1 : 0;
5557 if (!handle_inactive_volumes
)
5560 mutex_lock(&ioc
->raid_data
.inactive_list_mutex
);
5561 for (i
= 0; i
< buffer
->NumPhysDisks
; i
++) {
5562 if(mpt_raid_phys_disk_pg0(ioc
,
5563 buffer
->PhysDisk
[i
].PhysDiskNum
, &phys_disk
) != 0)
5566 if ((component_info
= kmalloc(sizeof (*component_info
),
5567 GFP_KERNEL
)) == NULL
)
5570 component_info
->volumeID
= id
;
5571 component_info
->volumeBus
= channel
;
5572 component_info
->d
.PhysDiskNum
= phys_disk
.PhysDiskNum
;
5573 component_info
->d
.PhysDiskBus
= phys_disk
.PhysDiskBus
;
5574 component_info
->d
.PhysDiskID
= phys_disk
.PhysDiskID
;
5575 component_info
->d
.PhysDiskIOC
= phys_disk
.PhysDiskIOC
;
5577 list_add_tail(&component_info
->list
,
5578 &ioc
->raid_data
.inactive_list
);
5580 mutex_unlock(&ioc
->raid_data
.inactive_list_mutex
);
5584 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5589 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5590 * @ioc: Pointer to a Adapter Structure
5591 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5592 * @phys_disk: requested payload data returned
5596 * -EFAULT if read of config page header fails or data pointer not NULL
5597 * -ENOMEM if pci_alloc failed
5600 mpt_raid_phys_disk_pg0(MPT_ADAPTER
*ioc
, u8 phys_disk_num
, pRaidPhysDiskPage0_t phys_disk
)
5603 ConfigPageHeader_t hdr
;
5604 dma_addr_t dma_handle
;
5605 pRaidPhysDiskPage0_t buffer
= NULL
;
5608 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5609 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5611 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_PHYSDISK
;
5612 cfg
.cfghdr
.hdr
= &hdr
;
5614 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5616 if (mpt_config(ioc
, &cfg
) != 0) {
5621 if (!hdr
.PageLength
) {
5626 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5634 cfg
.physAddr
= dma_handle
;
5635 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5636 cfg
.pageAddr
= phys_disk_num
;
5638 if (mpt_config(ioc
, &cfg
) != 0) {
5644 memcpy(phys_disk
, buffer
, sizeof(*buffer
));
5645 phys_disk
->MaxLBA
= le32_to_cpu(buffer
->MaxLBA
);
5650 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5657 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5658 * @ioc: Pointer to a Adapter Strucutre
5662 * -EFAULT if read of config page header fails or data pointer not NULL
5663 * -ENOMEM if pci_alloc failed
5666 mpt_findImVolumes(MPT_ADAPTER
*ioc
)
5670 dma_addr_t ioc2_dma
;
5672 ConfigPageHeader_t header
;
5677 if (!ioc
->ir_firmware
)
5680 /* Free the old page
5682 kfree(ioc
->raid_data
.pIocPg2
);
5683 ioc
->raid_data
.pIocPg2
= NULL
;
5684 mpt_inactive_raid_list_free(ioc
);
5686 /* Read IOCP2 header then the page.
5688 header
.PageVersion
= 0;
5689 header
.PageLength
= 0;
5690 header
.PageNumber
= 2;
5691 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
5692 cfg
.cfghdr
.hdr
= &header
;
5695 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5698 if (mpt_config(ioc
, &cfg
) != 0)
5701 if (header
.PageLength
== 0)
5704 iocpage2sz
= header
.PageLength
* 4;
5705 pIoc2
= pci_alloc_consistent(ioc
->pcidev
, iocpage2sz
, &ioc2_dma
);
5709 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5710 cfg
.physAddr
= ioc2_dma
;
5711 if (mpt_config(ioc
, &cfg
) != 0)
5714 mem
= kmalloc(iocpage2sz
, GFP_KERNEL
);
5718 memcpy(mem
, (u8
*)pIoc2
, iocpage2sz
);
5719 ioc
->raid_data
.pIocPg2
= (IOCPage2_t
*) mem
;
5721 mpt_read_ioc_pg_3(ioc
);
5723 for (i
= 0; i
< pIoc2
->NumActiveVolumes
; i
++)
5724 mpt_inactive_raid_volumes(ioc
,
5725 pIoc2
->RaidVolume
[i
].VolumeBus
,
5726 pIoc2
->RaidVolume
[i
].VolumeID
);
5729 pci_free_consistent(ioc
->pcidev
, iocpage2sz
, pIoc2
, ioc2_dma
);
5735 mpt_read_ioc_pg_3(MPT_ADAPTER
*ioc
)
5740 ConfigPageHeader_t header
;
5741 dma_addr_t ioc3_dma
;
5744 /* Free the old page
5746 kfree(ioc
->raid_data
.pIocPg3
);
5747 ioc
->raid_data
.pIocPg3
= NULL
;
5749 /* There is at least one physical disk.
5750 * Read and save IOC Page 3
5752 header
.PageVersion
= 0;
5753 header
.PageLength
= 0;
5754 header
.PageNumber
= 3;
5755 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
5756 cfg
.cfghdr
.hdr
= &header
;
5759 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5762 if (mpt_config(ioc
, &cfg
) != 0)
5765 if (header
.PageLength
== 0)
5768 /* Read Header good, alloc memory
5770 iocpage3sz
= header
.PageLength
* 4;
5771 pIoc3
= pci_alloc_consistent(ioc
->pcidev
, iocpage3sz
, &ioc3_dma
);
5775 /* Read the Page and save the data
5776 * into malloc'd memory.
5778 cfg
.physAddr
= ioc3_dma
;
5779 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5780 if (mpt_config(ioc
, &cfg
) == 0) {
5781 mem
= kmalloc(iocpage3sz
, GFP_KERNEL
);
5783 memcpy(mem
, (u8
*)pIoc3
, iocpage3sz
);
5784 ioc
->raid_data
.pIocPg3
= (IOCPage3_t
*) mem
;
5788 pci_free_consistent(ioc
->pcidev
, iocpage3sz
, pIoc3
, ioc3_dma
);
5794 mpt_read_ioc_pg_4(MPT_ADAPTER
*ioc
)
5798 ConfigPageHeader_t header
;
5799 dma_addr_t ioc4_dma
;
5802 /* Read and save IOC Page 4
5804 header
.PageVersion
= 0;
5805 header
.PageLength
= 0;
5806 header
.PageNumber
= 4;
5807 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
5808 cfg
.cfghdr
.hdr
= &header
;
5811 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5814 if (mpt_config(ioc
, &cfg
) != 0)
5817 if (header
.PageLength
== 0)
5820 if ( (pIoc4
= ioc
->spi_data
.pIocPg4
) == NULL
) {
5821 iocpage4sz
= (header
.PageLength
+ 4) * 4; /* Allow 4 additional SEP's */
5822 pIoc4
= pci_alloc_consistent(ioc
->pcidev
, iocpage4sz
, &ioc4_dma
);
5825 ioc
->alloc_total
+= iocpage4sz
;
5827 ioc4_dma
= ioc
->spi_data
.IocPg4_dma
;
5828 iocpage4sz
= ioc
->spi_data
.IocPg4Sz
;
5831 /* Read the Page into dma memory.
5833 cfg
.physAddr
= ioc4_dma
;
5834 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5835 if (mpt_config(ioc
, &cfg
) == 0) {
5836 ioc
->spi_data
.pIocPg4
= (IOCPage4_t
*) pIoc4
;
5837 ioc
->spi_data
.IocPg4_dma
= ioc4_dma
;
5838 ioc
->spi_data
.IocPg4Sz
= iocpage4sz
;
5840 pci_free_consistent(ioc
->pcidev
, iocpage4sz
, pIoc4
, ioc4_dma
);
5841 ioc
->spi_data
.pIocPg4
= NULL
;
5842 ioc
->alloc_total
-= iocpage4sz
;
5847 mpt_read_ioc_pg_1(MPT_ADAPTER
*ioc
)
5851 ConfigPageHeader_t header
;
5852 dma_addr_t ioc1_dma
;
5856 /* Check the Coalescing Timeout in IOC Page 1
5858 header
.PageVersion
= 0;
5859 header
.PageLength
= 0;
5860 header
.PageNumber
= 1;
5861 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
5862 cfg
.cfghdr
.hdr
= &header
;
5865 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5868 if (mpt_config(ioc
, &cfg
) != 0)
5871 if (header
.PageLength
== 0)
5874 /* Read Header good, alloc memory
5876 iocpage1sz
= header
.PageLength
* 4;
5877 pIoc1
= pci_alloc_consistent(ioc
->pcidev
, iocpage1sz
, &ioc1_dma
);
5881 /* Read the Page and check coalescing timeout
5883 cfg
.physAddr
= ioc1_dma
;
5884 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5885 if (mpt_config(ioc
, &cfg
) == 0) {
5887 tmp
= le32_to_cpu(pIoc1
->Flags
) & MPI_IOCPAGE1_REPLY_COALESCING
;
5888 if (tmp
== MPI_IOCPAGE1_REPLY_COALESCING
) {
5889 tmp
= le32_to_cpu(pIoc1
->CoalescingTimeout
);
5891 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Coalescing Enabled Timeout = %d\n",
5894 if (tmp
> MPT_COALESCING_TIMEOUT
) {
5895 pIoc1
->CoalescingTimeout
= cpu_to_le32(MPT_COALESCING_TIMEOUT
);
5897 /* Write NVRAM and current
5900 cfg
.action
= MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT
;
5901 if (mpt_config(ioc
, &cfg
) == 0) {
5902 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Reset Current Coalescing Timeout to = %d\n",
5903 ioc
->name
, MPT_COALESCING_TIMEOUT
));
5905 cfg
.action
= MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM
;
5906 if (mpt_config(ioc
, &cfg
) == 0) {
5907 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5908 "Reset NVRAM Coalescing Timeout to = %d\n",
5909 ioc
->name
, MPT_COALESCING_TIMEOUT
));
5911 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5912 "Reset NVRAM Coalescing Timeout Failed\n",
5917 dprintk(ioc
, printk(MYIOC_s_WARN_FMT
5918 "Reset of Current Coalescing Timeout Failed!\n",
5924 dprintk(ioc
, printk(MYIOC_s_WARN_FMT
"Coalescing Disabled\n", ioc
->name
));
5928 pci_free_consistent(ioc
->pcidev
, iocpage1sz
, pIoc1
, ioc1_dma
);
5934 mpt_get_manufacturing_pg_0(MPT_ADAPTER
*ioc
)
5937 ConfigPageHeader_t hdr
;
5939 ManufacturingPage0_t
*pbuf
= NULL
;
5941 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5942 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5944 hdr
.PageType
= MPI_CONFIG_PAGETYPE_MANUFACTURING
;
5945 cfg
.cfghdr
.hdr
= &hdr
;
5947 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5950 if (mpt_config(ioc
, &cfg
) != 0)
5953 if (!cfg
.cfghdr
.hdr
->PageLength
)
5956 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5957 pbuf
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, &buf_dma
);
5961 cfg
.physAddr
= buf_dma
;
5963 if (mpt_config(ioc
, &cfg
) != 0)
5966 memcpy(ioc
->board_name
, pbuf
->BoardName
, sizeof(ioc
->board_name
));
5967 memcpy(ioc
->board_assembly
, pbuf
->BoardAssembly
, sizeof(ioc
->board_assembly
));
5968 memcpy(ioc
->board_tracer
, pbuf
->BoardTracerNumber
, sizeof(ioc
->board_tracer
));
5973 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, pbuf
, buf_dma
);
5976 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5978 * SendEventNotification - Send EventNotification (on or off) request to adapter
5979 * @ioc: Pointer to MPT_ADAPTER structure
5980 * @EvSwitch: Event switch flags
5981 * @sleepFlag: Specifies whether the process can sleep
5984 SendEventNotification(MPT_ADAPTER
*ioc
, u8 EvSwitch
, int sleepFlag
)
5986 EventNotification_t evn
;
5987 MPIDefaultReply_t reply_buf
;
5989 memset(&evn
, 0, sizeof(EventNotification_t
));
5990 memset(&reply_buf
, 0, sizeof(MPIDefaultReply_t
));
5992 evn
.Function
= MPI_FUNCTION_EVENT_NOTIFICATION
;
5993 evn
.Switch
= EvSwitch
;
5994 evn
.MsgContext
= cpu_to_le32(mpt_base_index
<< 16);
5996 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5997 "Sending EventNotification (%d) request %p\n",
5998 ioc
->name
, EvSwitch
, &evn
));
6000 return mpt_handshake_req_reply_wait(ioc
, sizeof(EventNotification_t
),
6001 (u32
*)&evn
, sizeof(MPIDefaultReply_t
), (u16
*)&reply_buf
, 30,
6005 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6007 * SendEventAck - Send EventAck request to MPT adapter.
6008 * @ioc: Pointer to MPT_ADAPTER structure
6009 * @evnp: Pointer to original EventNotification request
6012 SendEventAck(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*evnp
)
6016 if ((pAck
= (EventAck_t
*) mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
6017 dfailprintk(ioc
, printk(MYIOC_s_WARN_FMT
"%s, no msg frames!!\n",
6018 ioc
->name
, __func__
));
6022 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending EventAck\n", ioc
->name
));
6024 pAck
->Function
= MPI_FUNCTION_EVENT_ACK
;
6025 pAck
->ChainOffset
= 0;
6026 pAck
->Reserved
[0] = pAck
->Reserved
[1] = 0;
6028 pAck
->Reserved1
[0] = pAck
->Reserved1
[1] = pAck
->Reserved1
[2] = 0;
6029 pAck
->Event
= evnp
->Event
;
6030 pAck
->EventContext
= evnp
->EventContext
;
6032 mpt_put_msg_frame(mpt_base_index
, ioc
, (MPT_FRAME_HDR
*)pAck
);
6037 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6039 * mpt_config - Generic function to issue config message
6040 * @ioc: Pointer to an adapter structure
6041 * @pCfg: Pointer to a configuration structure. Struct contains
6042 * action, page address, direction, physical address
6043 * and pointer to a configuration page header
6044 * Page header is updated.
6046 * Returns 0 for success
6047 * -EPERM if not allowed due to ISR context
6048 * -EAGAIN if no msg frames currently available
6049 * -EFAULT for non-successful reply or no reply (timeout)
6052 mpt_config(MPT_ADAPTER
*ioc
, CONFIGPARMS
*pCfg
)
6055 ConfigReply_t
*pReply
;
6056 ConfigExtendedPageHeader_t
*pExtHdr
= NULL
;
6062 u8 page_type
= 0, extend_page
;
6063 unsigned long timeleft
;
6065 u8 issue_hard_reset
= 0;
6068 /* Prevent calling wait_event() (below), if caller happens
6069 * to be in ISR context, because that is fatal!
6071 in_isr
= in_interrupt();
6073 dcprintk(ioc
, printk(MYIOC_s_WARN_FMT
"Config request not allowed in ISR context!\n",
6078 /* don't send if no chance of success */
6080 mpt_GetIocState(ioc
, 1) != MPI_IOC_STATE_OPERATIONAL
) {
6081 dfailprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6082 "%s: ioc not operational, %d, %xh\n",
6083 ioc
->name
, __func__
, ioc
->active
,
6084 mpt_GetIocState(ioc
, 0)));
6089 mutex_lock(&ioc
->mptbase_cmds
.mutex
);
6090 /* init the internal cmd struct */
6091 memset(ioc
->mptbase_cmds
.reply
, 0 , MPT_DEFAULT_FRAME_SIZE
);
6092 INITIALIZE_MGMT_STATUS(ioc
->mptbase_cmds
.status
)
6094 /* Get and Populate a free Frame
6096 if ((mf
= mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
6097 dcprintk(ioc
, printk(MYIOC_s_WARN_FMT
6098 "mpt_config: no msg frames!\n", ioc
->name
));
6103 pReq
= (Config_t
*)mf
;
6104 pReq
->Action
= pCfg
->action
;
6106 pReq
->ChainOffset
= 0;
6107 pReq
->Function
= MPI_FUNCTION_CONFIG
;
6109 /* Assume page type is not extended and clear "reserved" fields. */
6110 pReq
->ExtPageLength
= 0;
6111 pReq
->ExtPageType
= 0;
6114 for (ii
=0; ii
< 8; ii
++)
6115 pReq
->Reserved2
[ii
] = 0;
6117 pReq
->Header
.PageVersion
= pCfg
->cfghdr
.hdr
->PageVersion
;
6118 pReq
->Header
.PageLength
= pCfg
->cfghdr
.hdr
->PageLength
;
6119 pReq
->Header
.PageNumber
= pCfg
->cfghdr
.hdr
->PageNumber
;
6120 pReq
->Header
.PageType
= (pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
);
6122 if ((pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
) == MPI_CONFIG_PAGETYPE_EXTENDED
) {
6123 pExtHdr
= (ConfigExtendedPageHeader_t
*)pCfg
->cfghdr
.ehdr
;
6124 pReq
->ExtPageLength
= cpu_to_le16(pExtHdr
->ExtPageLength
);
6125 pReq
->ExtPageType
= pExtHdr
->ExtPageType
;
6126 pReq
->Header
.PageType
= MPI_CONFIG_PAGETYPE_EXTENDED
;
6128 /* Page Length must be treated as a reserved field for the
6131 pReq
->Header
.PageLength
= 0;
6134 pReq
->PageAddress
= cpu_to_le32(pCfg
->pageAddr
);
6136 /* Add a SGE to the config request.
6139 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_WRITE
;
6141 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_READ
;
6143 if ((pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
) ==
6144 MPI_CONFIG_PAGETYPE_EXTENDED
) {
6145 flagsLength
|= pExtHdr
->ExtPageLength
* 4;
6146 page_type
= pReq
->ExtPageType
;
6149 flagsLength
|= pCfg
->cfghdr
.hdr
->PageLength
* 4;
6150 page_type
= pReq
->Header
.PageType
;
6154 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6155 "Sending Config request type 0x%x, page 0x%x and action %d\n",
6156 ioc
->name
, page_type
, pReq
->Header
.PageNumber
, pReq
->Action
));
6158 ioc
->add_sge((char *)&pReq
->PageBufferSGE
, flagsLength
, pCfg
->physAddr
);
6159 timeout
= (pCfg
->timeout
< 15) ? HZ
*15 : HZ
*pCfg
->timeout
;
6160 mpt_put_msg_frame(mpt_base_index
, ioc
, mf
);
6161 timeleft
= wait_for_completion_timeout(&ioc
->mptbase_cmds
.done
,
6163 if (!(ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_COMMAND_GOOD
)) {
6165 dfailprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6166 "Failed Sending Config request type 0x%x, page 0x%x,"
6167 " action %d, status %xh, time left %ld\n\n",
6168 ioc
->name
, page_type
, pReq
->Header
.PageNumber
,
6169 pReq
->Action
, ioc
->mptbase_cmds
.status
, timeleft
));
6170 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_DID_IOCRESET
)
6173 issue_hard_reset
= 1;
6177 if (!(ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_RF_VALID
)) {
6181 pReply
= (ConfigReply_t
*)ioc
->mptbase_cmds
.reply
;
6182 ret
= le16_to_cpu(pReply
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
6183 if (ret
== MPI_IOCSTATUS_SUCCESS
) {
6185 pCfg
->cfghdr
.ehdr
->ExtPageLength
=
6186 le16_to_cpu(pReply
->ExtPageLength
);
6187 pCfg
->cfghdr
.ehdr
->ExtPageType
=
6188 pReply
->ExtPageType
;
6190 pCfg
->cfghdr
.hdr
->PageVersion
= pReply
->Header
.PageVersion
;
6191 pCfg
->cfghdr
.hdr
->PageLength
= pReply
->Header
.PageLength
;
6192 pCfg
->cfghdr
.hdr
->PageNumber
= pReply
->Header
.PageNumber
;
6193 pCfg
->cfghdr
.hdr
->PageType
= pReply
->Header
.PageType
;
6198 printk(MYIOC_s_INFO_FMT
"Retry completed "
6199 "ret=0x%x timeleft=%ld\n",
6200 ioc
->name
, ret
, timeleft
);
6202 dcprintk(ioc
, printk(KERN_DEBUG
"IOCStatus=%04xh, IOCLogInfo=%08xh\n",
6203 ret
, le32_to_cpu(pReply
->IOCLogInfo
)));
6207 CLEAR_MGMT_STATUS(ioc
->mptbase_cmds
.status
)
6208 mutex_unlock(&ioc
->mptbase_cmds
.mutex
);
6209 if (issue_hard_reset
) {
6210 issue_hard_reset
= 0;
6211 printk(MYIOC_s_WARN_FMT
"Issuing Reset from %s!!\n",
6212 ioc
->name
, __func__
);
6213 mpt_HardResetHandler(ioc
, CAN_SLEEP
);
6214 mpt_free_msg_frame(ioc
, mf
);
6215 /* attempt one retry for a timed out command */
6217 printk(MYIOC_s_INFO_FMT
6218 "Attempting Retry Config request"
6219 " type 0x%x, page 0x%x,"
6220 " action %d\n", ioc
->name
, page_type
,
6221 pCfg
->cfghdr
.hdr
->PageNumber
, pCfg
->action
);
6230 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6232 * mpt_ioc_reset - Base cleanup for hard reset
6233 * @ioc: Pointer to the adapter structure
6234 * @reset_phase: Indicates pre- or post-reset functionality
6236 * Remark: Frees resources with internally generated commands.
6239 mpt_ioc_reset(MPT_ADAPTER
*ioc
, int reset_phase
)
6241 switch (reset_phase
) {
6242 case MPT_IOC_SETUP_RESET
:
6243 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6244 "%s: MPT_IOC_SETUP_RESET\n", ioc
->name
, __func__
));
6246 case MPT_IOC_PRE_RESET
:
6247 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6248 "%s: MPT_IOC_PRE_RESET\n", ioc
->name
, __func__
));
6250 case MPT_IOC_POST_RESET
:
6251 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6252 "%s: MPT_IOC_POST_RESET\n", ioc
->name
, __func__
));
6253 /* wake up mptbase_cmds */
6254 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_PENDING
) {
6255 ioc
->mptbase_cmds
.status
|=
6256 MPT_MGMT_STATUS_DID_IOCRESET
;
6257 complete(&ioc
->mptbase_cmds
.done
);
6264 return 1; /* currently means nothing really */
6268 #ifdef CONFIG_PROC_FS /* { */
6269 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6271 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
6273 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6275 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
6277 * Returns 0 for success, non-zero for failure.
6280 procmpt_create(void)
6282 struct proc_dir_entry
*ent
;
6284 mpt_proc_root_dir
= proc_mkdir(MPT_PROCFS_MPTBASEDIR
, NULL
);
6285 if (mpt_proc_root_dir
== NULL
)
6288 ent
= create_proc_entry("summary", S_IFREG
|S_IRUGO
, mpt_proc_root_dir
);
6290 ent
->read_proc
= procmpt_summary_read
;
6292 ent
= create_proc_entry("version", S_IFREG
|S_IRUGO
, mpt_proc_root_dir
);
6294 ent
->read_proc
= procmpt_version_read
;
6299 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6301 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
6303 * Returns 0 for success, non-zero for failure.
6306 procmpt_destroy(void)
6308 remove_proc_entry("version", mpt_proc_root_dir
);
6309 remove_proc_entry("summary", mpt_proc_root_dir
);
6310 remove_proc_entry(MPT_PROCFS_MPTBASEDIR
, NULL
);
6313 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6315 * procmpt_summary_read - Handle read request of a summary file
6316 * @buf: Pointer to area to write information
6317 * @start: Pointer to start pointer
6318 * @offset: Offset to start writing
6319 * @request: Amount of read data requested
6320 * @eof: Pointer to EOF integer
6323 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
6324 * Returns number of characters written to process performing the read.
6327 procmpt_summary_read(char *buf
, char **start
, off_t offset
, int request
, int *eof
, void *data
)
6337 mpt_print_ioc_summary(ioc
, out
, &more
, 0, 1);
6341 list_for_each_entry(ioc
, &ioc_list
, list
) {
6344 mpt_print_ioc_summary(ioc
, out
, &more
, 0, 1);
6347 if ((out
-buf
) >= request
)
6354 MPT_PROC_READ_RETURN(buf
,start
,offset
,request
,eof
,len
);
6357 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6359 * procmpt_version_read - Handle read request from /proc/mpt/version.
6360 * @buf: Pointer to area to write information
6361 * @start: Pointer to start pointer
6362 * @offset: Offset to start writing
6363 * @request: Amount of read data requested
6364 * @eof: Pointer to EOF integer
6367 * Returns number of characters written to process performing the read.
6370 procmpt_version_read(char *buf
, char **start
, off_t offset
, int request
, int *eof
, void *data
)
6373 int scsi
, fc
, sas
, lan
, ctl
, targ
, dmp
;
6377 len
= sprintf(buf
, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON
);
6378 len
+= sprintf(buf
+len
, " Fusion MPT base driver\n");
6380 scsi
= fc
= sas
= lan
= ctl
= targ
= dmp
= 0;
6381 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
6383 if (MptCallbacks
[cb_idx
]) {
6384 switch (MptDriverClass
[cb_idx
]) {
6386 if (!scsi
++) drvname
= "SPI host";
6389 if (!fc
++) drvname
= "FC host";
6392 if (!sas
++) drvname
= "SAS host";
6395 if (!lan
++) drvname
= "LAN";
6398 if (!targ
++) drvname
= "SCSI target";
6401 if (!ctl
++) drvname
= "ioctl";
6406 len
+= sprintf(buf
+len
, " Fusion MPT %s driver\n", drvname
);
6410 MPT_PROC_READ_RETURN(buf
,start
,offset
,request
,eof
,len
);
6413 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6415 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
6416 * @buf: Pointer to area to write information
6417 * @start: Pointer to start pointer
6418 * @offset: Offset to start writing
6419 * @request: Amount of read data requested
6420 * @eof: Pointer to EOF integer
6423 * Returns number of characters written to process performing the read.
6426 procmpt_iocinfo_read(char *buf
, char **start
, off_t offset
, int request
, int *eof
, void *data
)
6428 MPT_ADAPTER
*ioc
= data
;
6434 mpt_get_fw_exp_ver(expVer
, ioc
);
6436 len
= sprintf(buf
, "%s:", ioc
->name
);
6437 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)
6438 len
+= sprintf(buf
+len
, " (f/w download boot flag set)");
6439 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6440 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
6442 len
+= sprintf(buf
+len
, "\n ProductID = 0x%04x (%s)\n",
6443 ioc
->facts
.ProductID
,
6445 len
+= sprintf(buf
+len
, " FWVersion = 0x%08x%s", ioc
->facts
.FWVersion
.Word
, expVer
);
6446 if (ioc
->facts
.FWImageSize
)
6447 len
+= sprintf(buf
+len
, " (fw_size=%d)", ioc
->facts
.FWImageSize
);
6448 len
+= sprintf(buf
+len
, "\n MsgVersion = 0x%04x\n", ioc
->facts
.MsgVersion
);
6449 len
+= sprintf(buf
+len
, " FirstWhoInit = 0x%02x\n", ioc
->FirstWhoInit
);
6450 len
+= sprintf(buf
+len
, " EventState = 0x%02x\n", ioc
->facts
.EventState
);
6452 len
+= sprintf(buf
+len
, " CurrentHostMfaHighAddr = 0x%08x\n",
6453 ioc
->facts
.CurrentHostMfaHighAddr
);
6454 len
+= sprintf(buf
+len
, " CurrentSenseBufferHighAddr = 0x%08x\n",
6455 ioc
->facts
.CurrentSenseBufferHighAddr
);
6457 len
+= sprintf(buf
+len
, " MaxChainDepth = 0x%02x frames\n", ioc
->facts
.MaxChainDepth
);
6458 len
+= sprintf(buf
+len
, " MinBlockSize = 0x%02x bytes\n", 4*ioc
->facts
.BlockSize
);
6460 len
+= sprintf(buf
+len
, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6461 (void *)ioc
->req_frames
, (void *)(ulong
)ioc
->req_frames_dma
);
6463 * Rounding UP to nearest 4-kB boundary here...
6465 sz
= (ioc
->req_sz
* ioc
->req_depth
) + 128;
6466 sz
= ((sz
+ 0x1000UL
- 1UL) / 0x1000) * 0x1000;
6467 len
+= sprintf(buf
+len
, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6468 ioc
->req_sz
, ioc
->req_depth
, ioc
->req_sz
*ioc
->req_depth
, sz
);
6469 len
+= sprintf(buf
+len
, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
6470 4*ioc
->facts
.RequestFrameSize
,
6471 ioc
->facts
.GlobalCredits
);
6473 len
+= sprintf(buf
+len
, " Frames @ 0x%p (Dma @ 0x%p)\n",
6474 (void *)ioc
->alloc
, (void *)(ulong
)ioc
->alloc_dma
);
6475 sz
= (ioc
->reply_sz
* ioc
->reply_depth
) + 128;
6476 len
+= sprintf(buf
+len
, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6477 ioc
->reply_sz
, ioc
->reply_depth
, ioc
->reply_sz
*ioc
->reply_depth
, sz
);
6478 len
+= sprintf(buf
+len
, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
6479 ioc
->facts
.CurReplyFrameSize
,
6480 ioc
->facts
.ReplyQueueDepth
);
6482 len
+= sprintf(buf
+len
, " MaxDevices = %d\n",
6483 (ioc
->facts
.MaxDevices
==0) ? 255 : ioc
->facts
.MaxDevices
);
6484 len
+= sprintf(buf
+len
, " MaxBuses = %d\n", ioc
->facts
.MaxBuses
);
6487 for (p
=0; p
< ioc
->facts
.NumberOfPorts
; p
++) {
6488 len
+= sprintf(buf
+len
, " PortNumber = %d (of %d)\n",
6490 ioc
->facts
.NumberOfPorts
);
6491 if (ioc
->bus_type
== FC
) {
6492 if (ioc
->pfacts
[p
].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
) {
6493 u8
*a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
6494 len
+= sprintf(buf
+len
, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6495 a
[5], a
[4], a
[3], a
[2], a
[1], a
[0]);
6497 len
+= sprintf(buf
+len
, " WWN = %08X%08X:%08X%08X\n",
6498 ioc
->fc_port_page0
[p
].WWNN
.High
,
6499 ioc
->fc_port_page0
[p
].WWNN
.Low
,
6500 ioc
->fc_port_page0
[p
].WWPN
.High
,
6501 ioc
->fc_port_page0
[p
].WWPN
.Low
);
6505 MPT_PROC_READ_RETURN(buf
,start
,offset
,request
,eof
,len
);
6508 #endif /* CONFIG_PROC_FS } */
6510 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6512 mpt_get_fw_exp_ver(char *buf
, MPT_ADAPTER
*ioc
)
6515 if ((ioc
->facts
.FWVersion
.Word
>> 24) == 0x0E) {
6516 sprintf(buf
, " (Exp %02d%02d)",
6517 (ioc
->facts
.FWVersion
.Word
>> 16) & 0x00FF, /* Month */
6518 (ioc
->facts
.FWVersion
.Word
>> 8) & 0x1F); /* Day */
6521 if ((ioc
->facts
.FWVersion
.Word
>> 8) & 0x80)
6522 strcat(buf
, " [MDBG]");
6526 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6528 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6529 * @ioc: Pointer to MPT_ADAPTER structure
6530 * @buffer: Pointer to buffer where IOC summary info should be written
6531 * @size: Pointer to number of bytes we wrote (set by this routine)
6532 * @len: Offset at which to start writing in buffer
6533 * @showlan: Display LAN stuff?
6535 * This routine writes (english readable) ASCII text, which represents
6536 * a summary of IOC information, to a buffer.
6539 mpt_print_ioc_summary(MPT_ADAPTER
*ioc
, char *buffer
, int *size
, int len
, int showlan
)
6544 mpt_get_fw_exp_ver(expVer
, ioc
);
6547 * Shorter summary of attached ioc's...
6549 y
= sprintf(buffer
+len
, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6552 MPT_FW_REV_MAGIC_ID_STRING
, /* "FwRev=" or somesuch */
6553 ioc
->facts
.FWVersion
.Word
,
6555 ioc
->facts
.NumberOfPorts
,
6558 if (showlan
&& (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
)) {
6559 u8
*a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
6560 y
+= sprintf(buffer
+len
+y
, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6561 a
[5], a
[4], a
[3], a
[2], a
[1], a
[0]);
6564 y
+= sprintf(buffer
+len
+y
, ", IRQ=%d", ioc
->pci_irq
);
6567 y
+= sprintf(buffer
+len
+y
, " (disabled)");
6569 y
+= sprintf(buffer
+len
+y
, "\n");
6576 * mpt_halt_firmware - Halts the firmware if it is operational and panic
6578 * @ioc: Pointer to MPT_ADAPTER structure
6582 mpt_halt_firmware(MPT_ADAPTER
*ioc
)
6586 ioc_raw_state
= mpt_GetIocState(ioc
, 0);
6588 if ((ioc_raw_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_FAULT
) {
6589 printk(MYIOC_s_ERR_FMT
"IOC is in FAULT state (%04xh)!!!\n",
6590 ioc
->name
, ioc_raw_state
& MPI_DOORBELL_DATA_MASK
);
6591 panic("%s: IOC Fault (%04xh)!!!\n", ioc
->name
,
6592 ioc_raw_state
& MPI_DOORBELL_DATA_MASK
);
6594 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, 0xC0FFEE00);
6595 panic("%s: Firmware is halted due to command timeout\n",
6599 EXPORT_SYMBOL(mpt_halt_firmware
);
6601 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6605 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6607 * mpt_HardResetHandler - Generic reset handler
6608 * @ioc: Pointer to MPT_ADAPTER structure
6609 * @sleepFlag: Indicates if sleep or schedule must be called.
6611 * Issues SCSI Task Management call based on input arg values.
6612 * If TaskMgmt fails, returns associated SCSI request.
6614 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
6615 * or a non-interrupt thread. In the former, must not call schedule().
6617 * Note: A return of -1 is a FATAL error case, as it means a
6618 * FW reload/initialization failed.
6620 * Returns 0 for SUCCESS or -1 if FAILED.
6623 mpt_HardResetHandler(MPT_ADAPTER
*ioc
, int sleepFlag
)
6626 unsigned long flags
;
6628 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HardResetHandler Entered!\n", ioc
->name
));
6630 printk(MYIOC_s_INFO_FMT
"HardResetHandler Entered!\n", ioc
->name
);
6631 printk("MF count 0x%x !\n", ioc
->mfcnt
);
6633 if (mpt_fwfault_debug
)
6634 mpt_halt_firmware(ioc
);
6636 /* Reset the adapter. Prevent more than 1 call to
6637 * mpt_do_ioc_recovery at any instant in time.
6639 spin_lock_irqsave(&ioc
->diagLock
, flags
);
6640 if ((ioc
->diagPending
) || (ioc
->alt_ioc
&& ioc
->alt_ioc
->diagPending
)){
6641 spin_unlock_irqrestore(&ioc
->diagLock
, flags
);
6644 ioc
->diagPending
= 1;
6646 spin_unlock_irqrestore(&ioc
->diagLock
, flags
);
6648 /* FIXME: If do_ioc_recovery fails, repeat....
6651 /* The SCSI driver needs to adjust timeouts on all current
6652 * commands prior to the diagnostic reset being issued.
6653 * Prevents timeouts occurring during a diagnostic reset...very bad.
6654 * For all other protocol drivers, this is a no-op.
6660 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
6661 if (MptResetHandlers
[cb_idx
]) {
6662 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Calling IOC reset_setup handler #%d\n",
6663 ioc
->name
, cb_idx
));
6664 r
+= mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_SETUP_RESET
);
6666 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Calling alt-%s setup reset handler #%d\n",
6667 ioc
->name
, ioc
->alt_ioc
->name
, cb_idx
));
6668 r
+= mpt_signal_reset(cb_idx
, ioc
->alt_ioc
, MPT_IOC_SETUP_RESET
);
6674 if ((rc
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_RECOVER
, sleepFlag
)) != 0) {
6675 printk(MYIOC_s_WARN_FMT
"Cannot recover rc = %d!\n", ioc
->name
, rc
);
6679 ioc
->alt_ioc
->reload_fw
= 0;
6681 spin_lock_irqsave(&ioc
->diagLock
, flags
);
6682 ioc
->diagPending
= 0;
6684 ioc
->alt_ioc
->diagPending
= 0;
6685 spin_unlock_irqrestore(&ioc
->diagLock
, flags
);
6687 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HardResetHandler rc = %d!\n", ioc
->name
, rc
));
6692 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6694 EventDescriptionStr(u8 event
, u32 evData0
, char *evStr
)
6699 case MPI_EVENT_NONE
:
6702 case MPI_EVENT_LOG_DATA
:
6705 case MPI_EVENT_STATE_CHANGE
:
6706 ds
= "State Change";
6708 case MPI_EVENT_UNIT_ATTENTION
:
6709 ds
= "Unit Attention";
6711 case MPI_EVENT_IOC_BUS_RESET
:
6712 ds
= "IOC Bus Reset";
6714 case MPI_EVENT_EXT_BUS_RESET
:
6715 ds
= "External Bus Reset";
6717 case MPI_EVENT_RESCAN
:
6718 ds
= "Bus Rescan Event";
6720 case MPI_EVENT_LINK_STATUS_CHANGE
:
6721 if (evData0
== MPI_EVENT_LINK_STATUS_FAILURE
)
6722 ds
= "Link Status(FAILURE) Change";
6724 ds
= "Link Status(ACTIVE) Change";
6726 case MPI_EVENT_LOOP_STATE_CHANGE
:
6727 if (evData0
== MPI_EVENT_LOOP_STATE_CHANGE_LIP
)
6728 ds
= "Loop State(LIP) Change";
6729 else if (evData0
== MPI_EVENT_LOOP_STATE_CHANGE_LPE
)
6730 ds
= "Loop State(LPE) Change"; /* ??? */
6732 ds
= "Loop State(LPB) Change"; /* ??? */
6734 case MPI_EVENT_LOGOUT
:
6737 case MPI_EVENT_EVENT_CHANGE
:
6743 case MPI_EVENT_INTEGRATED_RAID
:
6745 u8 ReasonCode
= (u8
)(evData0
>> 16);
6746 switch (ReasonCode
) {
6747 case MPI_EVENT_RAID_RC_VOLUME_CREATED
:
6748 ds
= "Integrated Raid: Volume Created";
6750 case MPI_EVENT_RAID_RC_VOLUME_DELETED
:
6751 ds
= "Integrated Raid: Volume Deleted";
6753 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED
:
6754 ds
= "Integrated Raid: Volume Settings Changed";
6756 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED
:
6757 ds
= "Integrated Raid: Volume Status Changed";
6759 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED
:
6760 ds
= "Integrated Raid: Volume Physdisk Changed";
6762 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED
:
6763 ds
= "Integrated Raid: Physdisk Created";
6765 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED
:
6766 ds
= "Integrated Raid: Physdisk Deleted";
6768 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED
:
6769 ds
= "Integrated Raid: Physdisk Settings Changed";
6771 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
:
6772 ds
= "Integrated Raid: Physdisk Status Changed";
6774 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
:
6775 ds
= "Integrated Raid: Domain Validation Needed";
6777 case MPI_EVENT_RAID_RC_SMART_DATA
:
6778 ds
= "Integrated Raid; Smart Data";
6780 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED
:
6781 ds
= "Integrated Raid: Replace Action Started";
6784 ds
= "Integrated Raid";
6789 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE
:
6790 ds
= "SCSI Device Status Change";
6792 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE
:
6794 u8 id
= (u8
)(evData0
);
6795 u8 channel
= (u8
)(evData0
>> 8);
6796 u8 ReasonCode
= (u8
)(evData0
>> 16);
6797 switch (ReasonCode
) {
6798 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED
:
6799 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6800 "SAS Device Status Change: Added: "
6801 "id=%d channel=%d", id
, channel
);
6803 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING
:
6804 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6805 "SAS Device Status Change: Deleted: "
6806 "id=%d channel=%d", id
, channel
);
6808 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA
:
6809 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6810 "SAS Device Status Change: SMART Data: "
6811 "id=%d channel=%d", id
, channel
);
6813 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED
:
6814 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6815 "SAS Device Status Change: No Persistancy: "
6816 "id=%d channel=%d", id
, channel
);
6818 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED
:
6819 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6820 "SAS Device Status Change: Unsupported Device "
6821 "Discovered : id=%d channel=%d", id
, channel
);
6823 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET
:
6824 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6825 "SAS Device Status Change: Internal Device "
6826 "Reset : id=%d channel=%d", id
, channel
);
6828 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL
:
6829 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6830 "SAS Device Status Change: Internal Task "
6831 "Abort : id=%d channel=%d", id
, channel
);
6833 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL
:
6834 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6835 "SAS Device Status Change: Internal Abort "
6836 "Task Set : id=%d channel=%d", id
, channel
);
6838 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL
:
6839 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6840 "SAS Device Status Change: Internal Clear "
6841 "Task Set : id=%d channel=%d", id
, channel
);
6843 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL
:
6844 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6845 "SAS Device Status Change: Internal Query "
6846 "Task : id=%d channel=%d", id
, channel
);
6849 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6850 "SAS Device Status Change: Unknown: "
6851 "id=%d channel=%d", id
, channel
);
6856 case MPI_EVENT_ON_BUS_TIMER_EXPIRED
:
6857 ds
= "Bus Timer Expired";
6859 case MPI_EVENT_QUEUE_FULL
:
6861 u16 curr_depth
= (u16
)(evData0
>> 16);
6862 u8 channel
= (u8
)(evData0
>> 8);
6863 u8 id
= (u8
)(evData0
);
6865 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6866 "Queue Full: channel=%d id=%d depth=%d",
6867 channel
, id
, curr_depth
);
6870 case MPI_EVENT_SAS_SES
:
6871 ds
= "SAS SES Event";
6873 case MPI_EVENT_PERSISTENT_TABLE_FULL
:
6874 ds
= "Persistent Table Full";
6876 case MPI_EVENT_SAS_PHY_LINK_STATUS
:
6878 u8 LinkRates
= (u8
)(evData0
>> 8);
6879 u8 PhyNumber
= (u8
)(evData0
);
6880 LinkRates
= (LinkRates
& MPI_EVENT_SAS_PLS_LR_CURRENT_MASK
) >>
6881 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT
;
6882 switch (LinkRates
) {
6883 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN
:
6884 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6885 "SAS PHY Link Status: Phy=%d:"
6886 " Rate Unknown",PhyNumber
);
6888 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED
:
6889 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6890 "SAS PHY Link Status: Phy=%d:"
6891 " Phy Disabled",PhyNumber
);
6893 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION
:
6894 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6895 "SAS PHY Link Status: Phy=%d:"
6896 " Failed Speed Nego",PhyNumber
);
6898 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE
:
6899 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6900 "SAS PHY Link Status: Phy=%d:"
6901 " Sata OOB Completed",PhyNumber
);
6903 case MPI_EVENT_SAS_PLS_LR_RATE_1_5
:
6904 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6905 "SAS PHY Link Status: Phy=%d:"
6906 " Rate 1.5 Gbps",PhyNumber
);
6908 case MPI_EVENT_SAS_PLS_LR_RATE_3_0
:
6909 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6910 "SAS PHY Link Status: Phy=%d:"
6911 " Rate 3.0 Gpbs",PhyNumber
);
6914 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6915 "SAS PHY Link Status: Phy=%d", PhyNumber
);
6920 case MPI_EVENT_SAS_DISCOVERY_ERROR
:
6921 ds
= "SAS Discovery Error";
6923 case MPI_EVENT_IR_RESYNC_UPDATE
:
6925 u8 resync_complete
= (u8
)(evData0
>> 16);
6926 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6927 "IR Resync Update: Complete = %d:",resync_complete
);
6932 u8 ReasonCode
= (u8
)(evData0
>> 16);
6933 switch (ReasonCode
) {
6934 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED
:
6935 ds
= "IR2: LD State Changed";
6937 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED
:
6938 ds
= "IR2: PD State Changed";
6940 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL
:
6941 ds
= "IR2: Bad Block Table Full";
6943 case MPI_EVENT_IR2_RC_PD_INSERTED
:
6944 ds
= "IR2: PD Inserted";
6946 case MPI_EVENT_IR2_RC_PD_REMOVED
:
6947 ds
= "IR2: PD Removed";
6949 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED
:
6950 ds
= "IR2: Foreign CFG Detected";
6952 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR
:
6953 ds
= "IR2: Rebuild Medium Error";
6961 case MPI_EVENT_SAS_DISCOVERY
:
6964 ds
= "SAS Discovery: Start";
6966 ds
= "SAS Discovery: Stop";
6969 case MPI_EVENT_LOG_ENTRY_ADDED
:
6970 ds
= "SAS Log Entry Added";
6973 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE
:
6975 u8 phy_num
= (u8
)(evData0
);
6976 u8 port_num
= (u8
)(evData0
>> 8);
6977 u8 port_width
= (u8
)(evData0
>> 16);
6978 u8 primative
= (u8
)(evData0
>> 24);
6979 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6980 "SAS Broadcase Primative: phy=%d port=%d "
6981 "width=%d primative=0x%02x",
6982 phy_num
, port_num
, port_width
, primative
);
6986 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE
:
6988 u8 reason
= (u8
)(evData0
);
6989 u8 port_num
= (u8
)(evData0
>> 8);
6990 u16 handle
= le16_to_cpu(evData0
>> 16);
6992 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
6993 "SAS Initiator Device Status Change: reason=0x%02x "
6994 "port=%d handle=0x%04x",
6995 reason
, port_num
, handle
);
6999 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW
:
7001 u8 max_init
= (u8
)(evData0
);
7002 u8 current_init
= (u8
)(evData0
>> 8);
7004 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7005 "SAS Initiator Device Table Overflow: max initiators=%02d "
7006 "current initators=%02d",
7007 max_init
, current_init
);
7010 case MPI_EVENT_SAS_SMP_ERROR
:
7012 u8 status
= (u8
)(evData0
);
7013 u8 port_num
= (u8
)(evData0
>> 8);
7014 u8 result
= (u8
)(evData0
>> 16);
7016 if (status
== MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID
)
7017 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7018 "SAS SMP Error: port=%d result=0x%02x",
7020 else if (status
== MPI_EVENT_SAS_SMP_CRC_ERROR
)
7021 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7022 "SAS SMP Error: port=%d : CRC Error",
7024 else if (status
== MPI_EVENT_SAS_SMP_TIMEOUT
)
7025 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7026 "SAS SMP Error: port=%d : Timeout",
7028 else if (status
== MPI_EVENT_SAS_SMP_NO_DESTINATION
)
7029 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7030 "SAS SMP Error: port=%d : No Destination",
7032 else if (status
== MPI_EVENT_SAS_SMP_BAD_DESTINATION
)
7033 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7034 "SAS SMP Error: port=%d : Bad Destination",
7037 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7038 "SAS SMP Error: port=%d : status=0x%02x",
7044 * MPT base "custom" events may be added here...
7051 strncpy(evStr
, ds
, EVENT_DESCR_STR_SZ
);
7054 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7056 * ProcessEventNotification - Route EventNotificationReply to all event handlers
7057 * @ioc: Pointer to MPT_ADAPTER structure
7058 * @pEventReply: Pointer to EventNotification reply frame
7059 * @evHandlers: Pointer to integer, number of event handlers
7061 * Routes a received EventNotificationReply to all currently registered
7063 * Returns sum of event handlers return values.
7066 ProcessEventNotification(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*pEventReply
, int *evHandlers
)
7075 char evStr
[EVENT_DESCR_STR_SZ
];
7079 * Do platform normalization of values
7081 event
= le32_to_cpu(pEventReply
->Event
) & 0xFF;
7082 // evCtx = le32_to_cpu(pEventReply->EventContext);
7083 evDataLen
= le16_to_cpu(pEventReply
->EventDataLength
);
7085 evData0
= le32_to_cpu(pEventReply
->Data
[0]);
7088 EventDescriptionStr(event
, evData0
, evStr
);
7089 devtprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"MPT event:(%02Xh) : %s\n",
7094 #ifdef CONFIG_FUSION_LOGGING
7095 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
7096 ": Event data:\n", ioc
->name
));
7097 for (ii
= 0; ii
< evDataLen
; ii
++)
7098 devtverboseprintk(ioc
, printk(" %08x",
7099 le32_to_cpu(pEventReply
->Data
[ii
])));
7100 devtverboseprintk(ioc
, printk("\n"));
7104 * Do general / base driver event processing
7107 case MPI_EVENT_EVENT_CHANGE
: /* 0A */
7109 u8 evState
= evData0
& 0xFF;
7111 /* CHECKME! What if evState unexpectedly says OFF (0)? */
7113 /* Update EventState field in cached IocFacts */
7114 if (ioc
->facts
.Function
) {
7115 ioc
->facts
.EventState
= evState
;
7119 case MPI_EVENT_INTEGRATED_RAID
:
7120 mptbase_raid_process_event_data(ioc
,
7121 (MpiEventDataRaid_t
*)pEventReply
->Data
);
7128 * Should this event be logged? Events are written sequentially.
7129 * When buffer is full, start again at the top.
7131 if (ioc
->events
&& (ioc
->eventTypes
& ( 1 << event
))) {
7134 idx
= ioc
->eventContext
% MPTCTL_EVENT_LOG_SIZE
;
7136 ioc
->events
[idx
].event
= event
;
7137 ioc
->events
[idx
].eventContext
= ioc
->eventContext
;
7139 for (ii
= 0; ii
< 2; ii
++) {
7141 ioc
->events
[idx
].data
[ii
] = le32_to_cpu(pEventReply
->Data
[ii
]);
7143 ioc
->events
[idx
].data
[ii
] = 0;
7146 ioc
->eventContext
++;
7151 * Call each currently registered protocol event handler.
7153 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
7154 if (MptEvHandlers
[cb_idx
]) {
7155 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Routing Event to event handler #%d\n",
7156 ioc
->name
, cb_idx
));
7157 r
+= (*(MptEvHandlers
[cb_idx
]))(ioc
, pEventReply
);
7161 /* FIXME? Examine results here? */
7164 * If needed, send (a single) EventAck.
7166 if (pEventReply
->AckRequired
== MPI_EVENT_NOTIFICATION_ACK_REQUIRED
) {
7167 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
7168 "EventAck required\n",ioc
->name
));
7169 if ((ii
= SendEventAck(ioc
, pEventReply
)) != 0) {
7170 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SendEventAck returned %d\n",
7175 *evHandlers
= handlers
;
7179 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7181 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
7182 * @ioc: Pointer to MPT_ADAPTER structure
7183 * @log_info: U32 LogInfo reply word from the IOC
7185 * Refer to lsi/mpi_log_fc.h.
7188 mpt_fc_log_info(MPT_ADAPTER
*ioc
, u32 log_info
)
7190 char *desc
= "unknown";
7192 switch (log_info
& 0xFF000000) {
7193 case MPI_IOCLOGINFO_FC_INIT_BASE
:
7194 desc
= "FCP Initiator";
7196 case MPI_IOCLOGINFO_FC_TARGET_BASE
:
7197 desc
= "FCP Target";
7199 case MPI_IOCLOGINFO_FC_LAN_BASE
:
7202 case MPI_IOCLOGINFO_FC_MSG_BASE
:
7203 desc
= "MPI Message Layer";
7205 case MPI_IOCLOGINFO_FC_LINK_BASE
:
7208 case MPI_IOCLOGINFO_FC_CTX_BASE
:
7209 desc
= "Context Manager";
7211 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET
:
7212 desc
= "Invalid Field Offset";
7214 case MPI_IOCLOGINFO_FC_STATE_CHANGE
:
7215 desc
= "State Change Info";
7219 printk(MYIOC_s_INFO_FMT
"LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
7220 ioc
->name
, log_info
, desc
, (log_info
& 0xFFFFFF));
7223 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7225 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
7226 * @ioc: Pointer to MPT_ADAPTER structure
7227 * @log_info: U32 LogInfo word from the IOC
7229 * Refer to lsi/sp_log.h.
7232 mpt_spi_log_info(MPT_ADAPTER
*ioc
, u32 log_info
)
7234 u32 info
= log_info
& 0x00FF0000;
7235 char *desc
= "unknown";
7239 desc
= "bug! MID not found";
7240 if (ioc
->reload_fw
== 0)
7245 desc
= "Parity Error";
7249 desc
= "ASYNC Outbound Overrun";
7253 desc
= "SYNC Offset Error";
7261 desc
= "Msg In Overflow";
7269 desc
= "Outbound DMA Overrun";
7273 desc
= "Task Management";
7277 desc
= "Device Problem";
7281 desc
= "Invalid Phase Change";
7285 desc
= "Untagged Table Size";
7290 printk(MYIOC_s_INFO_FMT
"LogInfo(0x%08x): F/W: %s\n", ioc
->name
, log_info
, desc
);
7293 /* strings for sas loginfo */
7294 static char *originator_str
[] = {
7299 static char *iop_code_str
[] = {
7301 "Invalid SAS Address", /* 01h */
7303 "Invalid Page", /* 03h */
7304 "Diag Message Error", /* 04h */
7305 "Task Terminated", /* 05h */
7306 "Enclosure Management", /* 06h */
7307 "Target Mode" /* 07h */
7309 static char *pl_code_str
[] = {
7311 "Open Failure", /* 01h */
7312 "Invalid Scatter Gather List", /* 02h */
7313 "Wrong Relative Offset or Frame Length", /* 03h */
7314 "Frame Transfer Error", /* 04h */
7315 "Transmit Frame Connected Low", /* 05h */
7316 "SATA Non-NCQ RW Error Bit Set", /* 06h */
7317 "SATA Read Log Receive Data Error", /* 07h */
7318 "SATA NCQ Fail All Commands After Error", /* 08h */
7319 "SATA Error in Receive Set Device Bit FIS", /* 09h */
7320 "Receive Frame Invalid Message", /* 0Ah */
7321 "Receive Context Message Valid Error", /* 0Bh */
7322 "Receive Frame Current Frame Error", /* 0Ch */
7323 "SATA Link Down", /* 0Dh */
7324 "Discovery SATA Init W IOS", /* 0Eh */
7325 "Config Invalid Page", /* 0Fh */
7326 "Discovery SATA Init Timeout", /* 10h */
7329 "IO Not Yet Executed", /* 13h */
7330 "IO Executed", /* 14h */
7331 "Persistent Reservation Out Not Affiliation "
7333 "Open Transmit DMA Abort", /* 16h */
7334 "IO Device Missing Delay Retry", /* 17h */
7335 "IO Cancelled Due to Recieve Error", /* 18h */
7343 "Enclosure Management" /* 20h */
7345 static char *ir_code_str
[] = {
7346 "Raid Action Error", /* 00h */
7356 static char *raid_sub_code_str
[] = {
7358 "Volume Creation Failed: Data Passed too "
7360 "Volume Creation Failed: Duplicate Volumes "
7361 "Attempted", /* 02h */
7362 "Volume Creation Failed: Max Number "
7363 "Supported Volumes Exceeded", /* 03h */
7364 "Volume Creation Failed: DMA Error", /* 04h */
7365 "Volume Creation Failed: Invalid Volume Type", /* 05h */
7366 "Volume Creation Failed: Error Reading "
7367 "MFG Page 4", /* 06h */
7368 "Volume Creation Failed: Creating Internal "
7369 "Structures", /* 07h */
7378 "Activation failed: Already Active Volume", /* 10h */
7379 "Activation failed: Unsupported Volume Type", /* 11h */
7380 "Activation failed: Too Many Active Volumes", /* 12h */
7381 "Activation failed: Volume ID in Use", /* 13h */
7382 "Activation failed: Reported Failure", /* 14h */
7383 "Activation failed: Importing a Volume", /* 15h */
7394 "Phys Disk failed: Too Many Phys Disks", /* 20h */
7395 "Phys Disk failed: Data Passed too Large", /* 21h */
7396 "Phys Disk failed: DMA Error", /* 22h */
7397 "Phys Disk failed: Invalid <channel:id>", /* 23h */
7398 "Phys Disk failed: Creating Phys Disk Config "
7411 "Compatibility Error: IR Disabled", /* 30h */
7412 "Compatibility Error: Inquiry Comand Failed", /* 31h */
7413 "Compatibility Error: Device not Direct Access "
7414 "Device ", /* 32h */
7415 "Compatibility Error: Removable Device Found", /* 33h */
7416 "Compatibility Error: Device SCSI Version not "
7417 "2 or Higher", /* 34h */
7418 "Compatibility Error: SATA Device, 48 BIT LBA "
7419 "not Supported", /* 35h */
7420 "Compatibility Error: Device doesn't have "
7421 "512 Byte Block Sizes", /* 36h */
7422 "Compatibility Error: Volume Type Check Failed", /* 37h */
7423 "Compatibility Error: Volume Type is "
7424 "Unsupported by FW", /* 38h */
7425 "Compatibility Error: Disk Drive too Small for "
7426 "use in Volume", /* 39h */
7427 "Compatibility Error: Phys Disk for Create "
7428 "Volume not Found", /* 3Ah */
7429 "Compatibility Error: Too Many or too Few "
7430 "Disks for Volume Type", /* 3Bh */
7431 "Compatibility Error: Disk stripe Sizes "
7432 "Must be 64KB", /* 3Ch */
7433 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
7436 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7438 * mpt_sas_log_info - Log information returned from SAS IOC.
7439 * @ioc: Pointer to MPT_ADAPTER structure
7440 * @log_info: U32 LogInfo reply word from the IOC
7442 * Refer to lsi/mpi_log_sas.h.
7445 mpt_sas_log_info(MPT_ADAPTER
*ioc
, u32 log_info
)
7447 union loginfo_type
{
7456 union loginfo_type sas_loginfo
;
7457 char *originator_desc
= NULL
;
7458 char *code_desc
= NULL
;
7459 char *sub_code_desc
= NULL
;
7461 sas_loginfo
.loginfo
= log_info
;
7462 if ((sas_loginfo
.dw
.bus_type
!= 3 /*SAS*/) &&
7463 (sas_loginfo
.dw
.originator
< ARRAY_SIZE(originator_str
)))
7466 originator_desc
= originator_str
[sas_loginfo
.dw
.originator
];
7468 switch (sas_loginfo
.dw
.originator
) {
7471 if (sas_loginfo
.dw
.code
<
7472 ARRAY_SIZE(iop_code_str
))
7473 code_desc
= iop_code_str
[sas_loginfo
.dw
.code
];
7476 if (sas_loginfo
.dw
.code
<
7477 ARRAY_SIZE(pl_code_str
))
7478 code_desc
= pl_code_str
[sas_loginfo
.dw
.code
];
7481 if (sas_loginfo
.dw
.code
>=
7482 ARRAY_SIZE(ir_code_str
))
7484 code_desc
= ir_code_str
[sas_loginfo
.dw
.code
];
7485 if (sas_loginfo
.dw
.subcode
>=
7486 ARRAY_SIZE(raid_sub_code_str
))
7488 if (sas_loginfo
.dw
.code
== 0)
7490 raid_sub_code_str
[sas_loginfo
.dw
.subcode
];
7496 if (sub_code_desc
!= NULL
)
7497 printk(MYIOC_s_INFO_FMT
7498 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7500 ioc
->name
, log_info
, originator_desc
, code_desc
,
7502 else if (code_desc
!= NULL
)
7503 printk(MYIOC_s_INFO_FMT
7504 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7505 " SubCode(0x%04x)\n",
7506 ioc
->name
, log_info
, originator_desc
, code_desc
,
7507 sas_loginfo
.dw
.subcode
);
7509 printk(MYIOC_s_INFO_FMT
7510 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
7511 " SubCode(0x%04x)\n",
7512 ioc
->name
, log_info
, originator_desc
,
7513 sas_loginfo
.dw
.code
, sas_loginfo
.dw
.subcode
);
7516 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7518 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
7519 * @ioc: Pointer to MPT_ADAPTER structure
7520 * @ioc_status: U32 IOCStatus word from IOC
7521 * @mf: Pointer to MPT request frame
7523 * Refer to lsi/mpi.h.
7526 mpt_iocstatus_info_config(MPT_ADAPTER
*ioc
, u32 ioc_status
, MPT_FRAME_HDR
*mf
)
7528 Config_t
*pReq
= (Config_t
*)mf
;
7529 char extend_desc
[EVENT_DESCR_STR_SZ
];
7534 if (pReq
->Header
.PageType
== MPI_CONFIG_PAGETYPE_EXTENDED
)
7535 page_type
= pReq
->ExtPageType
;
7537 page_type
= pReq
->Header
.PageType
;
7540 * ignore invalid page messages for GET_NEXT_HANDLE
7542 form
= le32_to_cpu(pReq
->PageAddress
);
7543 if (ioc_status
== MPI_IOCSTATUS_CONFIG_INVALID_PAGE
) {
7544 if (page_type
== MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE
||
7545 page_type
== MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER
||
7546 page_type
== MPI_CONFIG_EXTPAGETYPE_ENCLOSURE
) {
7547 if ((form
>> MPI_SAS_DEVICE_PGAD_FORM_SHIFT
) ==
7548 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE
)
7551 if (page_type
== MPI_CONFIG_PAGETYPE_FC_DEVICE
)
7552 if ((form
& MPI_FC_DEVICE_PGAD_FORM_MASK
) ==
7553 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID
)
7557 snprintf(extend_desc
, EVENT_DESCR_STR_SZ
,
7558 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
7559 page_type
, pReq
->Header
.PageNumber
, pReq
->Action
, form
);
7561 switch (ioc_status
) {
7563 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION
: /* 0x0020 */
7564 desc
= "Config Page Invalid Action";
7567 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE
: /* 0x0021 */
7568 desc
= "Config Page Invalid Type";
7571 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE
: /* 0x0022 */
7572 desc
= "Config Page Invalid Page";
7575 case MPI_IOCSTATUS_CONFIG_INVALID_DATA
: /* 0x0023 */
7576 desc
= "Config Page Invalid Data";
7579 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS
: /* 0x0024 */
7580 desc
= "Config Page No Defaults";
7583 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT
: /* 0x0025 */
7584 desc
= "Config Page Can't Commit";
7591 dreplyprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"IOCStatus(0x%04X): %s: %s\n",
7592 ioc
->name
, ioc_status
, desc
, extend_desc
));
7596 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
7597 * @ioc: Pointer to MPT_ADAPTER structure
7598 * @ioc_status: U32 IOCStatus word from IOC
7599 * @mf: Pointer to MPT request frame
7601 * Refer to lsi/mpi.h.
7604 mpt_iocstatus_info(MPT_ADAPTER
*ioc
, u32 ioc_status
, MPT_FRAME_HDR
*mf
)
7606 u32 status
= ioc_status
& MPI_IOCSTATUS_MASK
;
7611 /****************************************************************************/
7612 /* Common IOCStatus values for all replies */
7613 /****************************************************************************/
7615 case MPI_IOCSTATUS_INVALID_FUNCTION
: /* 0x0001 */
7616 desc
= "Invalid Function";
7619 case MPI_IOCSTATUS_BUSY
: /* 0x0002 */
7623 case MPI_IOCSTATUS_INVALID_SGL
: /* 0x0003 */
7624 desc
= "Invalid SGL";
7627 case MPI_IOCSTATUS_INTERNAL_ERROR
: /* 0x0004 */
7628 desc
= "Internal Error";
7631 case MPI_IOCSTATUS_RESERVED
: /* 0x0005 */
7635 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES
: /* 0x0006 */
7636 desc
= "Insufficient Resources";
7639 case MPI_IOCSTATUS_INVALID_FIELD
: /* 0x0007 */
7640 desc
= "Invalid Field";
7643 case MPI_IOCSTATUS_INVALID_STATE
: /* 0x0008 */
7644 desc
= "Invalid State";
7647 /****************************************************************************/
7648 /* Config IOCStatus values */
7649 /****************************************************************************/
7651 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION
: /* 0x0020 */
7652 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE
: /* 0x0021 */
7653 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE
: /* 0x0022 */
7654 case MPI_IOCSTATUS_CONFIG_INVALID_DATA
: /* 0x0023 */
7655 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS
: /* 0x0024 */
7656 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT
: /* 0x0025 */
7657 mpt_iocstatus_info_config(ioc
, status
, mf
);
7660 /****************************************************************************/
7661 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
7663 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
7665 /****************************************************************************/
7667 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR
: /* 0x0040 */
7668 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN
: /* 0x0045 */
7669 case MPI_IOCSTATUS_SCSI_INVALID_BUS
: /* 0x0041 */
7670 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID
: /* 0x0042 */
7671 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE
: /* 0x0043 */
7672 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN
: /* 0x0044 */
7673 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR
: /* 0x0046 */
7674 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR
: /* 0x0047 */
7675 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED
: /* 0x0048 */
7676 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH
: /* 0x0049 */
7677 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED
: /* 0x004A */
7678 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED
: /* 0x004B */
7679 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED
: /* 0x004C */
7682 /****************************************************************************/
7683 /* SCSI Target values */
7684 /****************************************************************************/
7686 case MPI_IOCSTATUS_TARGET_PRIORITY_IO
: /* 0x0060 */
7687 desc
= "Target: Priority IO";
7690 case MPI_IOCSTATUS_TARGET_INVALID_PORT
: /* 0x0061 */
7691 desc
= "Target: Invalid Port";
7694 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX
: /* 0x0062 */
7695 desc
= "Target Invalid IO Index:";
7698 case MPI_IOCSTATUS_TARGET_ABORTED
: /* 0x0063 */
7699 desc
= "Target: Aborted";
7702 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE
: /* 0x0064 */
7703 desc
= "Target: No Conn Retryable";
7706 case MPI_IOCSTATUS_TARGET_NO_CONNECTION
: /* 0x0065 */
7707 desc
= "Target: No Connection";
7710 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH
: /* 0x006A */
7711 desc
= "Target: Transfer Count Mismatch";
7714 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT
: /* 0x006B */
7715 desc
= "Target: STS Data not Sent";
7718 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR
: /* 0x006D */
7719 desc
= "Target: Data Offset Error";
7722 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA
: /* 0x006E */
7723 desc
= "Target: Too Much Write Data";
7726 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT
: /* 0x006F */
7727 desc
= "Target: IU Too Short";
7730 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT
: /* 0x0070 */
7731 desc
= "Target: ACK NAK Timeout";
7734 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED
: /* 0x0071 */
7735 desc
= "Target: Nak Received";
7738 /****************************************************************************/
7739 /* Fibre Channel Direct Access values */
7740 /****************************************************************************/
7742 case MPI_IOCSTATUS_FC_ABORTED
: /* 0x0066 */
7743 desc
= "FC: Aborted";
7746 case MPI_IOCSTATUS_FC_RX_ID_INVALID
: /* 0x0067 */
7747 desc
= "FC: RX ID Invalid";
7750 case MPI_IOCSTATUS_FC_DID_INVALID
: /* 0x0068 */
7751 desc
= "FC: DID Invalid";
7754 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT
: /* 0x0069 */
7755 desc
= "FC: Node Logged Out";
7758 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED
: /* 0x006C */
7759 desc
= "FC: Exchange Canceled";
7762 /****************************************************************************/
7764 /****************************************************************************/
7766 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND
: /* 0x0080 */
7767 desc
= "LAN: Device not Found";
7770 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE
: /* 0x0081 */
7771 desc
= "LAN: Device Failure";
7774 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR
: /* 0x0082 */
7775 desc
= "LAN: Transmit Error";
7778 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED
: /* 0x0083 */
7779 desc
= "LAN: Transmit Aborted";
7782 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR
: /* 0x0084 */
7783 desc
= "LAN: Receive Error";
7786 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED
: /* 0x0085 */
7787 desc
= "LAN: Receive Aborted";
7790 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET
: /* 0x0086 */
7791 desc
= "LAN: Partial Packet";
7794 case MPI_IOCSTATUS_LAN_CANCELED
: /* 0x0087 */
7795 desc
= "LAN: Canceled";
7798 /****************************************************************************/
7799 /* Serial Attached SCSI values */
7800 /****************************************************************************/
7802 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED
: /* 0x0090 */
7803 desc
= "SAS: SMP Request Failed";
7806 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN
: /* 0x0090 */
7807 desc
= "SAS: SMP Data Overrun";
7818 dreplyprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"IOCStatus(0x%04X): %s\n",
7819 ioc
->name
, status
, desc
));
7822 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7823 EXPORT_SYMBOL(mpt_attach
);
7824 EXPORT_SYMBOL(mpt_detach
);
7826 EXPORT_SYMBOL(mpt_resume
);
7827 EXPORT_SYMBOL(mpt_suspend
);
7829 EXPORT_SYMBOL(ioc_list
);
7830 EXPORT_SYMBOL(mpt_register
);
7831 EXPORT_SYMBOL(mpt_deregister
);
7832 EXPORT_SYMBOL(mpt_event_register
);
7833 EXPORT_SYMBOL(mpt_event_deregister
);
7834 EXPORT_SYMBOL(mpt_reset_register
);
7835 EXPORT_SYMBOL(mpt_reset_deregister
);
7836 EXPORT_SYMBOL(mpt_device_driver_register
);
7837 EXPORT_SYMBOL(mpt_device_driver_deregister
);
7838 EXPORT_SYMBOL(mpt_get_msg_frame
);
7839 EXPORT_SYMBOL(mpt_put_msg_frame
);
7840 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri
);
7841 EXPORT_SYMBOL(mpt_free_msg_frame
);
7842 EXPORT_SYMBOL(mpt_send_handshake_request
);
7843 EXPORT_SYMBOL(mpt_verify_adapter
);
7844 EXPORT_SYMBOL(mpt_GetIocState
);
7845 EXPORT_SYMBOL(mpt_print_ioc_summary
);
7846 EXPORT_SYMBOL(mpt_HardResetHandler
);
7847 EXPORT_SYMBOL(mpt_config
);
7848 EXPORT_SYMBOL(mpt_findImVolumes
);
7849 EXPORT_SYMBOL(mpt_alloc_fw_memory
);
7850 EXPORT_SYMBOL(mpt_free_fw_memory
);
7851 EXPORT_SYMBOL(mptbase_sas_persist_operation
);
7852 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0
);
7854 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7856 * fusion_init - Fusion MPT base driver initialization routine.
7858 * Returns 0 for success, non-zero for failure.
7865 show_mptmod_ver(my_NAME
, my_VERSION
);
7866 printk(KERN_INFO COPYRIGHT
"\n");
7868 for (cb_idx
= 0; cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
; cb_idx
++) {
7869 MptCallbacks
[cb_idx
] = NULL
;
7870 MptDriverClass
[cb_idx
] = MPTUNKNOWN_DRIVER
;
7871 MptEvHandlers
[cb_idx
] = NULL
;
7872 MptResetHandlers
[cb_idx
] = NULL
;
7875 /* Register ourselves (mptbase) in order to facilitate
7876 * EventNotification handling.
7878 mpt_base_index
= mpt_register(mptbase_reply
, MPTBASE_DRIVER
);
7880 /* Register for hard reset handling callbacks.
7882 mpt_reset_register(mpt_base_index
, mpt_ioc_reset
);
7884 #ifdef CONFIG_PROC_FS
7885 (void) procmpt_create();
7890 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7892 * fusion_exit - Perform driver unload cleanup.
7894 * This routine frees all resources associated with each MPT adapter
7895 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
7901 mpt_reset_deregister(mpt_base_index
);
7903 #ifdef CONFIG_PROC_FS
7908 module_init(fusion_init
);
7909 module_exit(fusion_exit
);