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/seq_file.h>
54 #include <linux/slab.h>
55 #include <linux/types.h>
56 #include <linux/pci.h>
57 #include <linux/kdev_t.h>
58 #include <linux/blkdev.h>
59 #include <linux/delay.h>
60 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
61 #include <linux/dma-mapping.h>
62 #include <linux/kthread.h>
63 #include <scsi/scsi_host.h>
66 #include "lsi/mpi_log_fc.h"
68 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
69 #define my_NAME "Fusion MPT base driver"
70 #define my_VERSION MPT_LINUX_VERSION_COMMON
71 #define MYNAM "mptbase"
73 MODULE_AUTHOR(MODULEAUTHOR
);
74 MODULE_DESCRIPTION(my_NAME
);
75 MODULE_LICENSE("GPL");
76 MODULE_VERSION(my_VERSION
);
82 static int mpt_msi_enable_spi
;
83 module_param(mpt_msi_enable_spi
, int, 0);
84 MODULE_PARM_DESC(mpt_msi_enable_spi
,
85 " Enable MSI Support for SPI controllers (default=0)");
87 static int mpt_msi_enable_fc
;
88 module_param(mpt_msi_enable_fc
, int, 0);
89 MODULE_PARM_DESC(mpt_msi_enable_fc
,
90 " Enable MSI Support for FC controllers (default=0)");
92 static int mpt_msi_enable_sas
;
93 module_param(mpt_msi_enable_sas
, int, 0);
94 MODULE_PARM_DESC(mpt_msi_enable_sas
,
95 " Enable MSI Support for SAS controllers (default=0)");
97 static int mpt_channel_mapping
;
98 module_param(mpt_channel_mapping
, int, 0);
99 MODULE_PARM_DESC(mpt_channel_mapping
, " Mapping id's to channels (default=0)");
101 static int mpt_debug_level
;
102 static int mpt_set_debug_level(const char *val
, struct kernel_param
*kp
);
103 module_param_call(mpt_debug_level
, mpt_set_debug_level
, param_get_int
,
104 &mpt_debug_level
, 0600);
105 MODULE_PARM_DESC(mpt_debug_level
,
106 " debug level - refer to mptdebug.h - (default=0)");
108 int mpt_fwfault_debug
;
109 EXPORT_SYMBOL(mpt_fwfault_debug
);
110 module_param(mpt_fwfault_debug
, int, 0600);
111 MODULE_PARM_DESC(mpt_fwfault_debug
,
112 "Enable detection of Firmware fault and halt Firmware on fault - (default=0)");
114 static char MptCallbacksName
[MPT_MAX_PROTOCOL_DRIVERS
]
115 [MPT_MAX_CALLBACKNAME_LEN
+1];
118 static int mfcounter
= 0;
119 #define PRINT_MF_COUNT 20000
122 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
127 #define WHOINIT_UNKNOWN 0xAA
129 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
133 /* Adapter link list */
135 /* Callback lookup table */
136 static MPT_CALLBACK MptCallbacks
[MPT_MAX_PROTOCOL_DRIVERS
];
137 /* Protocol driver class lookup table */
138 static int MptDriverClass
[MPT_MAX_PROTOCOL_DRIVERS
];
139 /* Event handler lookup table */
140 static MPT_EVHANDLER MptEvHandlers
[MPT_MAX_PROTOCOL_DRIVERS
];
141 /* Reset handler lookup table */
142 static MPT_RESETHANDLER MptResetHandlers
[MPT_MAX_PROTOCOL_DRIVERS
];
143 static struct mpt_pci_driver
*MptDeviceDriverHandlers
[MPT_MAX_PROTOCOL_DRIVERS
];
145 #ifdef CONFIG_PROC_FS
146 static struct proc_dir_entry
*mpt_proc_root_dir
;
150 * Driver Callback Index's
152 static u8 mpt_base_index
= MPT_MAX_PROTOCOL_DRIVERS
;
153 static u8 last_drv_idx
;
155 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
159 static irqreturn_t
mpt_interrupt(int irq
, void *bus_id
);
160 static int mptbase_reply(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*req
,
161 MPT_FRAME_HDR
*reply
);
162 static int mpt_handshake_req_reply_wait(MPT_ADAPTER
*ioc
, int reqBytes
,
163 u32
*req
, int replyBytes
, u16
*u16reply
, int maxwait
,
165 static int mpt_do_ioc_recovery(MPT_ADAPTER
*ioc
, u32 reason
, int sleepFlag
);
166 static void mpt_detect_bound_ports(MPT_ADAPTER
*ioc
, struct pci_dev
*pdev
);
167 static void mpt_adapter_disable(MPT_ADAPTER
*ioc
);
168 static void mpt_adapter_dispose(MPT_ADAPTER
*ioc
);
170 static void MptDisplayIocCapabilities(MPT_ADAPTER
*ioc
);
171 static int MakeIocReady(MPT_ADAPTER
*ioc
, int force
, int sleepFlag
);
172 static int GetIocFacts(MPT_ADAPTER
*ioc
, int sleepFlag
, int reason
);
173 static int GetPortFacts(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
);
174 static int SendIocInit(MPT_ADAPTER
*ioc
, int sleepFlag
);
175 static int SendPortEnable(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
);
176 static int mpt_do_upload(MPT_ADAPTER
*ioc
, int sleepFlag
);
177 static int mpt_downloadboot(MPT_ADAPTER
*ioc
, MpiFwHeader_t
*pFwHeader
, int sleepFlag
);
178 static int mpt_diag_reset(MPT_ADAPTER
*ioc
, int ignore
, int sleepFlag
);
179 static int KickStart(MPT_ADAPTER
*ioc
, int ignore
, int sleepFlag
);
180 static int SendIocReset(MPT_ADAPTER
*ioc
, u8 reset_type
, int sleepFlag
);
181 static int PrimeIocFifos(MPT_ADAPTER
*ioc
);
182 static int WaitForDoorbellAck(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
);
183 static int WaitForDoorbellInt(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
);
184 static int WaitForDoorbellReply(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
);
185 static int GetLanConfigPages(MPT_ADAPTER
*ioc
);
186 static int GetIoUnitPage2(MPT_ADAPTER
*ioc
);
187 int mptbase_sas_persist_operation(MPT_ADAPTER
*ioc
, u8 persist_opcode
);
188 static int mpt_GetScsiPortSettings(MPT_ADAPTER
*ioc
, int portnum
);
189 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER
*ioc
, int portnum
);
190 static void mpt_read_ioc_pg_1(MPT_ADAPTER
*ioc
);
191 static void mpt_read_ioc_pg_4(MPT_ADAPTER
*ioc
);
192 static void mpt_get_manufacturing_pg_0(MPT_ADAPTER
*ioc
);
193 static int SendEventNotification(MPT_ADAPTER
*ioc
, u8 EvSwitch
,
195 static int SendEventAck(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*evnp
);
196 static int mpt_host_page_access_control(MPT_ADAPTER
*ioc
, u8 access_control_value
, int sleepFlag
);
197 static int mpt_host_page_alloc(MPT_ADAPTER
*ioc
, pIOCInit_t ioc_init
);
199 #ifdef CONFIG_PROC_FS
200 static const struct file_operations mpt_summary_proc_fops
;
201 static const struct file_operations mpt_version_proc_fops
;
202 static const struct file_operations mpt_iocinfo_proc_fops
;
204 static void mpt_get_fw_exp_ver(char *buf
, MPT_ADAPTER
*ioc
);
206 static int ProcessEventNotification(MPT_ADAPTER
*ioc
,
207 EventNotificationReply_t
*evReply
, int *evHandlers
);
208 static void mpt_iocstatus_info(MPT_ADAPTER
*ioc
, u32 ioc_status
, MPT_FRAME_HDR
*mf
);
209 static void mpt_fc_log_info(MPT_ADAPTER
*ioc
, u32 log_info
);
210 static void mpt_spi_log_info(MPT_ADAPTER
*ioc
, u32 log_info
);
211 static void mpt_sas_log_info(MPT_ADAPTER
*ioc
, u32 log_info
, u8 cb_idx
);
212 static int mpt_read_ioc_pg_3(MPT_ADAPTER
*ioc
);
213 static void mpt_inactive_raid_list_free(MPT_ADAPTER
*ioc
);
215 /* module entry point */
216 static int __init
fusion_init (void);
217 static void __exit
fusion_exit (void);
219 #define CHIPREG_READ32(addr) readl_relaxed(addr)
220 #define CHIPREG_READ32_dmasync(addr) readl(addr)
221 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
222 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
223 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
226 pci_disable_io_access(struct pci_dev
*pdev
)
230 pci_read_config_word(pdev
, PCI_COMMAND
, &command_reg
);
232 pci_write_config_word(pdev
, PCI_COMMAND
, command_reg
);
236 pci_enable_io_access(struct pci_dev
*pdev
)
240 pci_read_config_word(pdev
, PCI_COMMAND
, &command_reg
);
242 pci_write_config_word(pdev
, PCI_COMMAND
, command_reg
);
245 static int mpt_set_debug_level(const char *val
, struct kernel_param
*kp
)
247 int ret
= param_set_int(val
, kp
);
253 list_for_each_entry(ioc
, &ioc_list
, list
)
254 ioc
->debug_level
= mpt_debug_level
;
259 * mpt_get_cb_idx - obtain cb_idx for registered driver
260 * @dclass: class driver enum
262 * Returns cb_idx, or zero means it wasn't found
265 mpt_get_cb_idx(MPT_DRIVER_CLASS dclass
)
269 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--)
270 if (MptDriverClass
[cb_idx
] == dclass
)
276 * mpt_is_discovery_complete - determine if discovery has completed
277 * @ioc: per adatper instance
279 * Returns 1 when discovery completed, else zero.
282 mpt_is_discovery_complete(MPT_ADAPTER
*ioc
)
284 ConfigExtendedPageHeader_t hdr
;
286 SasIOUnitPage0_t
*buffer
;
287 dma_addr_t dma_handle
;
290 memset(&hdr
, 0, sizeof(ConfigExtendedPageHeader_t
));
291 memset(&cfg
, 0, sizeof(CONFIGPARMS
));
292 hdr
.PageVersion
= MPI_SASIOUNITPAGE0_PAGEVERSION
;
293 hdr
.PageType
= MPI_CONFIG_PAGETYPE_EXTENDED
;
294 hdr
.ExtPageType
= MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT
;
295 cfg
.cfghdr
.ehdr
= &hdr
;
296 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
298 if ((mpt_config(ioc
, &cfg
)))
300 if (!hdr
.ExtPageLength
)
303 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.ExtPageLength
* 4,
308 cfg
.physAddr
= dma_handle
;
309 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
311 if ((mpt_config(ioc
, &cfg
)))
312 goto out_free_consistent
;
314 if (!(buffer
->PhyData
[0].PortFlags
&
315 MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS
))
319 pci_free_consistent(ioc
->pcidev
, hdr
.ExtPageLength
* 4,
327 * mpt_remove_dead_ioc_func - kthread context to remove dead ioc
328 * @arg: input argument, used to derive ioc
330 * Return 0 if controller is removed from pci subsystem.
331 * Return -1 for other case.
333 static int mpt_remove_dead_ioc_func(void *arg
)
335 MPT_ADAPTER
*ioc
= (MPT_ADAPTER
*)arg
;
336 struct pci_dev
*pdev
;
345 pci_stop_and_remove_bus_device_locked(pdev
);
352 * mpt_fault_reset_work - work performed on workq after ioc fault
353 * @work: input argument, used to derive ioc
357 mpt_fault_reset_work(struct work_struct
*work
)
360 container_of(work
, MPT_ADAPTER
, fault_reset_work
.work
);
365 struct task_struct
*p
;
367 if (ioc
->ioc_reset_in_progress
|| !ioc
->active
)
371 ioc_raw_state
= mpt_GetIocState(ioc
, 0);
372 if ((ioc_raw_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_MASK
) {
373 printk(MYIOC_s_INFO_FMT
"%s: IOC is non-operational !!!!\n",
374 ioc
->name
, __func__
);
377 * Call mptscsih_flush_pending_cmds callback so that we
378 * flush all pending commands back to OS.
379 * This call is required to aovid deadlock at block layer.
380 * Dead IOC will fail to do diag reset,and this call is safe
381 * since dead ioc will never return any command back from HW.
383 hd
= shost_priv(ioc
->sh
);
384 ioc
->schedule_dead_ioc_flush_running_cmds(hd
);
386 /*Remove the Dead Host */
387 p
= kthread_run(mpt_remove_dead_ioc_func
, ioc
,
388 "mpt_dead_ioc_%d", ioc
->id
);
390 printk(MYIOC_s_ERR_FMT
391 "%s: Running mpt_dead_ioc thread failed !\n",
392 ioc
->name
, __func__
);
394 printk(MYIOC_s_WARN_FMT
395 "%s: Running mpt_dead_ioc thread success !\n",
396 ioc
->name
, __func__
);
398 return; /* don't rearm timer */
401 if ((ioc_raw_state
& MPI_IOC_STATE_MASK
)
402 == MPI_IOC_STATE_FAULT
) {
403 printk(MYIOC_s_WARN_FMT
"IOC is in FAULT state (%04xh)!!!\n",
404 ioc
->name
, ioc_raw_state
& MPI_DOORBELL_DATA_MASK
);
405 printk(MYIOC_s_WARN_FMT
"Issuing HardReset from %s!!\n",
406 ioc
->name
, __func__
);
407 rc
= mpt_HardResetHandler(ioc
, CAN_SLEEP
);
408 printk(MYIOC_s_WARN_FMT
"%s: HardReset: %s\n", ioc
->name
,
409 __func__
, (rc
== 0) ? "success" : "failed");
410 ioc_raw_state
= mpt_GetIocState(ioc
, 0);
411 if ((ioc_raw_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_FAULT
)
412 printk(MYIOC_s_WARN_FMT
"IOC is in FAULT state after "
413 "reset (%04xh)\n", ioc
->name
, ioc_raw_state
&
414 MPI_DOORBELL_DATA_MASK
);
415 } else if (ioc
->bus_type
== SAS
&& ioc
->sas_discovery_quiesce_io
) {
416 if ((mpt_is_discovery_complete(ioc
))) {
417 devtprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"clearing "
418 "discovery_quiesce_io flag\n", ioc
->name
));
419 ioc
->sas_discovery_quiesce_io
= 0;
425 * Take turns polling alternate controller
430 /* rearm the timer */
431 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
432 if (ioc
->reset_work_q
)
433 queue_delayed_work(ioc
->reset_work_q
, &ioc
->fault_reset_work
,
434 msecs_to_jiffies(MPT_POLLING_INTERVAL
));
435 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
440 * Process turbo (context) reply...
443 mpt_turbo_reply(MPT_ADAPTER
*ioc
, u32 pa
)
445 MPT_FRAME_HDR
*mf
= NULL
;
446 MPT_FRAME_HDR
*mr
= NULL
;
450 dmfprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Got TURBO reply req_idx=%08x\n",
453 switch (pa
>> MPI_CONTEXT_REPLY_TYPE_SHIFT
) {
454 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT
:
455 req_idx
= pa
& 0x0000FFFF;
456 cb_idx
= (pa
& 0x00FF0000) >> 16;
457 mf
= MPT_INDEX_2_MFPTR(ioc
, req_idx
);
459 case MPI_CONTEXT_REPLY_TYPE_LAN
:
460 cb_idx
= mpt_get_cb_idx(MPTLAN_DRIVER
);
462 * Blind set of mf to NULL here was fatal
463 * after lan_reply says "freeme"
464 * Fix sort of combined with an optimization here;
465 * added explicit check for case where lan_reply
466 * was just returning 1 and doing nothing else.
467 * For this case skip the callback, but set up
468 * proper mf value first here:-)
470 if ((pa
& 0x58000000) == 0x58000000) {
471 req_idx
= pa
& 0x0000FFFF;
472 mf
= MPT_INDEX_2_MFPTR(ioc
, req_idx
);
473 mpt_free_msg_frame(ioc
, mf
);
478 mr
= (MPT_FRAME_HDR
*) CAST_U32_TO_PTR(pa
);
480 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET
:
481 cb_idx
= mpt_get_cb_idx(MPTSTM_DRIVER
);
482 mr
= (MPT_FRAME_HDR
*) CAST_U32_TO_PTR(pa
);
489 /* Check for (valid) IO callback! */
490 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
||
491 MptCallbacks
[cb_idx
] == NULL
) {
492 printk(MYIOC_s_WARN_FMT
"%s: Invalid cb_idx (%d)!\n",
493 __func__
, ioc
->name
, cb_idx
);
497 if (MptCallbacks
[cb_idx
](ioc
, mf
, mr
))
498 mpt_free_msg_frame(ioc
, mf
);
504 mpt_reply(MPT_ADAPTER
*ioc
, u32 pa
)
515 /* non-TURBO reply! Hmmm, something may be up...
516 * Newest turbo reply mechanism; get address
517 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
520 /* Map DMA address of reply header to cpu address.
521 * pa is 32 bits - but the dma address may be 32 or 64 bits
522 * get offset based only only the low addresses
525 reply_dma_low
= (pa
<<= 1);
526 mr
= (MPT_FRAME_HDR
*)((u8
*)ioc
->reply_frames
+
527 (reply_dma_low
- ioc
->reply_frames_low_dma
));
529 req_idx
= le16_to_cpu(mr
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
);
530 cb_idx
= mr
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
;
531 mf
= MPT_INDEX_2_MFPTR(ioc
, req_idx
);
533 dmfprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
534 ioc
->name
, mr
, req_idx
, cb_idx
, mr
->u
.hdr
.Function
));
535 DBG_DUMP_REPLY_FRAME(ioc
, (u32
*)mr
);
537 /* Check/log IOC log info
539 ioc_stat
= le16_to_cpu(mr
->u
.reply
.IOCStatus
);
540 if (ioc_stat
& MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE
) {
541 u32 log_info
= le32_to_cpu(mr
->u
.reply
.IOCLogInfo
);
542 if (ioc
->bus_type
== FC
)
543 mpt_fc_log_info(ioc
, log_info
);
544 else if (ioc
->bus_type
== SPI
)
545 mpt_spi_log_info(ioc
, log_info
);
546 else if (ioc
->bus_type
== SAS
)
547 mpt_sas_log_info(ioc
, log_info
, cb_idx
);
550 if (ioc_stat
& MPI_IOCSTATUS_MASK
)
551 mpt_iocstatus_info(ioc
, (u32
)ioc_stat
, mf
);
553 /* Check for (valid) IO callback! */
554 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
||
555 MptCallbacks
[cb_idx
] == NULL
) {
556 printk(MYIOC_s_WARN_FMT
"%s: Invalid cb_idx (%d)!\n",
557 __func__
, ioc
->name
, cb_idx
);
562 freeme
= MptCallbacks
[cb_idx
](ioc
, mf
, mr
);
565 /* Flush (non-TURBO) reply with a WRITE! */
566 CHIPREG_WRITE32(&ioc
->chip
->ReplyFifo
, pa
);
569 mpt_free_msg_frame(ioc
, mf
);
573 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
575 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
576 * @irq: irq number (not used)
577 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
579 * This routine is registered via the request_irq() kernel API call,
580 * and handles all interrupts generated from a specific MPT adapter
581 * (also referred to as a IO Controller or IOC).
582 * This routine must clear the interrupt from the adapter and does
583 * so by reading the reply FIFO. Multiple replies may be processed
584 * per single call to this routine.
586 * This routine handles register-level access of the adapter but
587 * dispatches (calls) a protocol-specific callback routine to handle
588 * the protocol-specific details of the MPT request completion.
591 mpt_interrupt(int irq
, void *bus_id
)
593 MPT_ADAPTER
*ioc
= bus_id
;
594 u32 pa
= CHIPREG_READ32_dmasync(&ioc
->chip
->ReplyFifo
);
596 if (pa
== 0xFFFFFFFF)
600 * Drain the reply FIFO!
603 if (pa
& MPI_ADDRESS_REPLY_A_BIT
)
606 mpt_turbo_reply(ioc
, pa
);
607 pa
= CHIPREG_READ32_dmasync(&ioc
->chip
->ReplyFifo
);
608 } while (pa
!= 0xFFFFFFFF);
613 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
615 * mptbase_reply - MPT base driver's callback routine
616 * @ioc: Pointer to MPT_ADAPTER structure
617 * @req: Pointer to original MPT request frame
618 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
620 * MPT base driver's callback routine; all base driver
621 * "internal" request/reply processing is routed here.
622 * Currently used for EventNotification and EventAck handling.
624 * Returns 1 indicating original alloc'd request frame ptr
625 * should be freed, or 0 if it shouldn't.
628 mptbase_reply(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*req
, MPT_FRAME_HDR
*reply
)
630 EventNotificationReply_t
*pEventReply
;
635 switch (reply
->u
.hdr
.Function
) {
636 case MPI_FUNCTION_EVENT_NOTIFICATION
:
637 pEventReply
= (EventNotificationReply_t
*)reply
;
639 ProcessEventNotification(ioc
, pEventReply
, &evHandlers
);
640 event
= le32_to_cpu(pEventReply
->Event
) & 0xFF;
641 if (pEventReply
->MsgFlags
& MPI_MSGFLAGS_CONTINUATION_REPLY
)
643 if (event
!= MPI_EVENT_EVENT_CHANGE
)
645 case MPI_FUNCTION_CONFIG
:
646 case MPI_FUNCTION_SAS_IO_UNIT_CONTROL
:
647 ioc
->mptbase_cmds
.status
|= MPT_MGMT_STATUS_COMMAND_GOOD
;
648 ioc
->mptbase_cmds
.status
|= MPT_MGMT_STATUS_RF_VALID
;
649 memcpy(ioc
->mptbase_cmds
.reply
, reply
,
650 min(MPT_DEFAULT_FRAME_SIZE
,
651 4 * reply
->u
.reply
.MsgLength
));
652 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_PENDING
) {
653 ioc
->mptbase_cmds
.status
&= ~MPT_MGMT_STATUS_PENDING
;
654 complete(&ioc
->mptbase_cmds
.done
);
657 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_FREE_MF
)
660 case MPI_FUNCTION_EVENT_ACK
:
661 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
662 "EventAck reply received\n", ioc
->name
));
665 printk(MYIOC_s_ERR_FMT
666 "Unexpected msg function (=%02Xh) reply received!\n",
667 ioc
->name
, reply
->u
.hdr
.Function
);
672 * Conditionally tell caller to free the original
673 * EventNotification/EventAck/unexpected request frame!
678 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
680 * mpt_register - Register protocol-specific main callback handler.
681 * @cbfunc: callback function pointer
682 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
683 * @func_name: call function's name
685 * This routine is called by a protocol-specific driver (SCSI host,
686 * LAN, SCSI target) to register its reply callback routine. Each
687 * protocol-specific driver must do this before it will be able to
688 * use any IOC resources, such as obtaining request frames.
690 * NOTES: The SCSI protocol driver currently calls this routine thrice
691 * in order to register separate callbacks; one for "normal" SCSI IO;
692 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
694 * Returns u8 valued "handle" in the range (and S.O.D. order)
695 * {N,...,7,6,5,...,1} if successful.
696 * A return value of MPT_MAX_PROTOCOL_DRIVERS (including zero!) should be
697 * considered an error by the caller.
700 mpt_register(MPT_CALLBACK cbfunc
, MPT_DRIVER_CLASS dclass
, char *func_name
)
703 last_drv_idx
= MPT_MAX_PROTOCOL_DRIVERS
;
706 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
707 * (slot/handle 0 is reserved!)
709 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
710 if (MptCallbacks
[cb_idx
] == NULL
) {
711 MptCallbacks
[cb_idx
] = cbfunc
;
712 MptDriverClass
[cb_idx
] = dclass
;
713 MptEvHandlers
[cb_idx
] = NULL
;
714 last_drv_idx
= cb_idx
;
715 strlcpy(MptCallbacksName
[cb_idx
], func_name
,
716 MPT_MAX_CALLBACKNAME_LEN
+1);
724 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
726 * mpt_deregister - Deregister a protocol drivers resources.
727 * @cb_idx: previously registered callback handle
729 * Each protocol-specific driver should call this routine when its
730 * module is unloaded.
733 mpt_deregister(u8 cb_idx
)
735 if (cb_idx
&& (cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
)) {
736 MptCallbacks
[cb_idx
] = NULL
;
737 MptDriverClass
[cb_idx
] = MPTUNKNOWN_DRIVER
;
738 MptEvHandlers
[cb_idx
] = NULL
;
744 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
746 * mpt_event_register - Register protocol-specific event callback handler.
747 * @cb_idx: previously registered (via mpt_register) callback handle
748 * @ev_cbfunc: callback function
750 * This routine can be called by one or more protocol-specific drivers
751 * if/when they choose to be notified of MPT events.
753 * Returns 0 for success.
756 mpt_event_register(u8 cb_idx
, MPT_EVHANDLER ev_cbfunc
)
758 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
761 MptEvHandlers
[cb_idx
] = ev_cbfunc
;
765 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
767 * mpt_event_deregister - Deregister protocol-specific event callback handler
768 * @cb_idx: previously registered callback handle
770 * Each protocol-specific driver should call this routine
771 * when it does not (or can no longer) handle events,
772 * or when its module is unloaded.
775 mpt_event_deregister(u8 cb_idx
)
777 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
780 MptEvHandlers
[cb_idx
] = NULL
;
783 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
785 * mpt_reset_register - Register protocol-specific IOC reset handler.
786 * @cb_idx: previously registered (via mpt_register) callback handle
787 * @reset_func: reset function
789 * This routine can be called by one or more protocol-specific drivers
790 * if/when they choose to be notified of IOC resets.
792 * Returns 0 for success.
795 mpt_reset_register(u8 cb_idx
, MPT_RESETHANDLER reset_func
)
797 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
800 MptResetHandlers
[cb_idx
] = reset_func
;
804 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
806 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
807 * @cb_idx: previously registered callback handle
809 * Each protocol-specific driver should call this routine
810 * when it does not (or can no longer) handle IOC reset handling,
811 * or when its module is unloaded.
814 mpt_reset_deregister(u8 cb_idx
)
816 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
819 MptResetHandlers
[cb_idx
] = NULL
;
822 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
824 * mpt_device_driver_register - Register device driver hooks
825 * @dd_cbfunc: driver callbacks struct
826 * @cb_idx: MPT protocol driver index
829 mpt_device_driver_register(struct mpt_pci_driver
* dd_cbfunc
, u8 cb_idx
)
832 const struct pci_device_id
*id
;
834 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
837 MptDeviceDriverHandlers
[cb_idx
] = dd_cbfunc
;
839 /* call per pci device probe entry point */
840 list_for_each_entry(ioc
, &ioc_list
, list
) {
841 id
= ioc
->pcidev
->driver
?
842 ioc
->pcidev
->driver
->id_table
: NULL
;
843 if (dd_cbfunc
->probe
)
844 dd_cbfunc
->probe(ioc
->pcidev
, id
);
850 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
852 * mpt_device_driver_deregister - DeRegister device driver hooks
853 * @cb_idx: MPT protocol driver index
856 mpt_device_driver_deregister(u8 cb_idx
)
858 struct mpt_pci_driver
*dd_cbfunc
;
861 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
864 dd_cbfunc
= MptDeviceDriverHandlers
[cb_idx
];
866 list_for_each_entry(ioc
, &ioc_list
, list
) {
867 if (dd_cbfunc
->remove
)
868 dd_cbfunc
->remove(ioc
->pcidev
);
871 MptDeviceDriverHandlers
[cb_idx
] = NULL
;
875 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
877 * mpt_get_msg_frame - Obtain an MPT request frame from the pool
878 * @cb_idx: Handle of registered MPT protocol driver
879 * @ioc: Pointer to MPT adapter structure
881 * Obtain an MPT request frame from the pool (of 1024) that are
882 * allocated per MPT adapter.
884 * Returns pointer to a MPT request frame or %NULL if none are available
885 * or IOC is not active.
888 mpt_get_msg_frame(u8 cb_idx
, MPT_ADAPTER
*ioc
)
892 u16 req_idx
; /* Request index */
894 /* validate handle and ioc identifier */
898 printk(MYIOC_s_WARN_FMT
"IOC Not Active! mpt_get_msg_frame "
899 "returning NULL!\n", ioc
->name
);
902 /* If interrupts are not attached, do not return a request frame */
906 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
907 if (!list_empty(&ioc
->FreeQ
)) {
910 mf
= list_entry(ioc
->FreeQ
.next
, MPT_FRAME_HDR
,
911 u
.frame
.linkage
.list
);
912 list_del(&mf
->u
.frame
.linkage
.list
);
913 mf
->u
.frame
.linkage
.arg1
= 0;
914 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= cb_idx
; /* byte */
915 req_offset
= (u8
*)mf
- (u8
*)ioc
->req_frames
;
917 req_idx
= req_offset
/ ioc
->req_sz
;
918 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(req_idx
);
919 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.rsvd
= 0;
920 /* Default, will be changed if necessary in SG generation */
921 ioc
->RequestNB
[req_idx
] = ioc
->NB_for_64_byte_frame
;
928 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
932 printk(MYIOC_s_WARN_FMT
"IOC Active. No free Msg Frames! "
933 "Count 0x%x Max 0x%x\n", ioc
->name
, ioc
->mfcnt
,
936 if (mfcounter
== PRINT_MF_COUNT
)
937 printk(MYIOC_s_INFO_FMT
"MF Count 0x%x Max 0x%x \n", ioc
->name
,
938 ioc
->mfcnt
, ioc
->req_depth
);
941 dmfprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mpt_get_msg_frame(%d,%d), got mf=%p\n",
942 ioc
->name
, cb_idx
, ioc
->id
, mf
));
946 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
948 * mpt_put_msg_frame - Send a protocol-specific MPT request frame to an IOC
949 * @cb_idx: Handle of registered MPT protocol driver
950 * @ioc: Pointer to MPT adapter structure
951 * @mf: Pointer to MPT request frame
953 * This routine posts an MPT request frame to the request post FIFO of a
954 * specific MPT adapter.
957 mpt_put_msg_frame(u8 cb_idx
, MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
)
961 u16 req_idx
; /* Request index */
963 /* ensure values are reset properly! */
964 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= cb_idx
; /* byte */
965 req_offset
= (u8
*)mf
- (u8
*)ioc
->req_frames
;
967 req_idx
= req_offset
/ ioc
->req_sz
;
968 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(req_idx
);
969 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.rsvd
= 0;
971 DBG_DUMP_PUT_MSG_FRAME(ioc
, (u32
*)mf
);
973 mf_dma_addr
= (ioc
->req_frames_low_dma
+ req_offset
) | ioc
->RequestNB
[req_idx
];
974 dsgprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mf_dma_addr=%x req_idx=%d "
975 "RequestNB=%x\n", ioc
->name
, mf_dma_addr
, req_idx
,
976 ioc
->RequestNB
[req_idx
]));
977 CHIPREG_WRITE32(&ioc
->chip
->RequestFifo
, mf_dma_addr
);
981 * mpt_put_msg_frame_hi_pri - Send a hi-pri protocol-specific MPT request frame
982 * @cb_idx: Handle of registered MPT protocol driver
983 * @ioc: Pointer to MPT adapter structure
984 * @mf: Pointer to MPT request frame
986 * Send a protocol-specific MPT request frame to an IOC using
987 * hi-priority request queue.
989 * This routine posts an MPT request frame to the request post FIFO of a
990 * specific MPT adapter.
993 mpt_put_msg_frame_hi_pri(u8 cb_idx
, MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
)
997 u16 req_idx
; /* Request index */
999 /* ensure values are reset properly! */
1000 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= cb_idx
;
1001 req_offset
= (u8
*)mf
- (u8
*)ioc
->req_frames
;
1002 req_idx
= req_offset
/ ioc
->req_sz
;
1003 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(req_idx
);
1004 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.rsvd
= 0;
1006 DBG_DUMP_PUT_MSG_FRAME(ioc
, (u32
*)mf
);
1008 mf_dma_addr
= (ioc
->req_frames_low_dma
+ req_offset
);
1009 dsgprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mf_dma_addr=%x req_idx=%d\n",
1010 ioc
->name
, mf_dma_addr
, req_idx
));
1011 CHIPREG_WRITE32(&ioc
->chip
->RequestHiPriFifo
, mf_dma_addr
);
1014 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1016 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
1017 * @ioc: Pointer to MPT adapter structure
1018 * @mf: Pointer to MPT request frame
1020 * This routine places a MPT request frame back on the MPT adapter's
1024 mpt_free_msg_frame(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
)
1026 unsigned long flags
;
1028 /* Put Request back on FreeQ! */
1029 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
1030 if (cpu_to_le32(mf
->u
.frame
.linkage
.arg1
) == 0xdeadbeaf)
1032 /* signature to know if this mf is freed */
1033 mf
->u
.frame
.linkage
.arg1
= cpu_to_le32(0xdeadbeaf);
1034 list_add(&mf
->u
.frame
.linkage
.list
, &ioc
->FreeQ
);
1039 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
1042 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1044 * mpt_add_sge - Place a simple 32 bit SGE at address pAddr.
1045 * @pAddr: virtual address for SGE
1046 * @flagslength: SGE flags and data transfer length
1047 * @dma_addr: Physical address
1049 * This routine places a MPT request frame back on the MPT adapter's
1053 mpt_add_sge(void *pAddr
, u32 flagslength
, dma_addr_t dma_addr
)
1055 SGESimple32_t
*pSge
= (SGESimple32_t
*) pAddr
;
1056 pSge
->FlagsLength
= cpu_to_le32(flagslength
);
1057 pSge
->Address
= cpu_to_le32(dma_addr
);
1061 * mpt_add_sge_64bit - Place a simple 64 bit SGE at address pAddr.
1062 * @pAddr: virtual address for SGE
1063 * @flagslength: SGE flags and data transfer length
1064 * @dma_addr: Physical address
1066 * This routine places a MPT request frame back on the MPT adapter's
1070 mpt_add_sge_64bit(void *pAddr
, u32 flagslength
, dma_addr_t dma_addr
)
1072 SGESimple64_t
*pSge
= (SGESimple64_t
*) pAddr
;
1073 pSge
->Address
.Low
= cpu_to_le32
1074 (lower_32_bits(dma_addr
));
1075 pSge
->Address
.High
= cpu_to_le32
1076 (upper_32_bits(dma_addr
));
1077 pSge
->FlagsLength
= cpu_to_le32
1078 ((flagslength
| MPT_SGE_FLAGS_64_BIT_ADDRESSING
));
1082 * mpt_add_sge_64bit_1078 - Place a simple 64 bit SGE at address pAddr (1078 workaround).
1083 * @pAddr: virtual address for SGE
1084 * @flagslength: SGE flags and data transfer length
1085 * @dma_addr: Physical address
1087 * This routine places a MPT request frame back on the MPT adapter's
1091 mpt_add_sge_64bit_1078(void *pAddr
, u32 flagslength
, dma_addr_t dma_addr
)
1093 SGESimple64_t
*pSge
= (SGESimple64_t
*) pAddr
;
1096 pSge
->Address
.Low
= cpu_to_le32
1097 (lower_32_bits(dma_addr
));
1098 tmp
= (u32
)(upper_32_bits(dma_addr
));
1101 * 1078 errata workaround for the 36GB limitation
1103 if ((((u64
)dma_addr
+ MPI_SGE_LENGTH(flagslength
)) >> 32) == 9) {
1105 MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_LOCAL_ADDRESS
);
1107 if (mpt_debug_level
& MPT_DEBUG_36GB_MEM
)
1108 printk(KERN_DEBUG
"1078 P0M2 addressing for "
1109 "addr = 0x%llx len = %d\n",
1110 (unsigned long long)dma_addr
,
1111 MPI_SGE_LENGTH(flagslength
));
1114 pSge
->Address
.High
= cpu_to_le32(tmp
);
1115 pSge
->FlagsLength
= cpu_to_le32(
1116 (flagslength
| MPT_SGE_FLAGS_64_BIT_ADDRESSING
));
1119 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1121 * mpt_add_chain - Place a 32 bit chain SGE at address pAddr.
1122 * @pAddr: virtual address for SGE
1123 * @next: nextChainOffset value (u32's)
1124 * @length: length of next SGL segment
1125 * @dma_addr: Physical address
1129 mpt_add_chain(void *pAddr
, u8 next
, u16 length
, dma_addr_t dma_addr
)
1131 SGEChain32_t
*pChain
= (SGEChain32_t
*) pAddr
;
1132 pChain
->Length
= cpu_to_le16(length
);
1133 pChain
->Flags
= MPI_SGE_FLAGS_CHAIN_ELEMENT
;
1134 pChain
->NextChainOffset
= next
;
1135 pChain
->Address
= cpu_to_le32(dma_addr
);
1138 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1140 * mpt_add_chain_64bit - Place a 64 bit chain SGE at address pAddr.
1141 * @pAddr: virtual address for SGE
1142 * @next: nextChainOffset value (u32's)
1143 * @length: length of next SGL segment
1144 * @dma_addr: Physical address
1148 mpt_add_chain_64bit(void *pAddr
, u8 next
, u16 length
, dma_addr_t dma_addr
)
1150 SGEChain64_t
*pChain
= (SGEChain64_t
*) pAddr
;
1151 u32 tmp
= dma_addr
& 0xFFFFFFFF;
1153 pChain
->Length
= cpu_to_le16(length
);
1154 pChain
->Flags
= (MPI_SGE_FLAGS_CHAIN_ELEMENT
|
1155 MPI_SGE_FLAGS_64_BIT_ADDRESSING
);
1157 pChain
->NextChainOffset
= next
;
1159 pChain
->Address
.Low
= cpu_to_le32(tmp
);
1160 tmp
= (u32
)(upper_32_bits(dma_addr
));
1161 pChain
->Address
.High
= cpu_to_le32(tmp
);
1164 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1166 * mpt_send_handshake_request - Send MPT request via doorbell handshake method.
1167 * @cb_idx: Handle of registered MPT protocol driver
1168 * @ioc: Pointer to MPT adapter structure
1169 * @reqBytes: Size of the request in bytes
1170 * @req: Pointer to MPT request frame
1171 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1173 * This routine is used exclusively to send MptScsiTaskMgmt
1174 * requests since they are required to be sent via doorbell handshake.
1176 * NOTE: It is the callers responsibility to byte-swap fields in the
1177 * request which are greater than 1 byte in size.
1179 * Returns 0 for success, non-zero for failure.
1182 mpt_send_handshake_request(u8 cb_idx
, MPT_ADAPTER
*ioc
, int reqBytes
, u32
*req
, int sleepFlag
)
1188 /* State is known to be good upon entering
1189 * this function so issue the bus reset
1194 * Emulate what mpt_put_msg_frame() does /wrt to sanity
1195 * setting cb_idx/req_idx. But ONLY if this request
1196 * is in proper (pre-alloc'd) request buffer range...
1198 ii
= MFPTR_2_MPT_INDEX(ioc
,(MPT_FRAME_HDR
*)req
);
1199 if (reqBytes
>= 12 && ii
>= 0 && ii
< ioc
->req_depth
) {
1200 MPT_FRAME_HDR
*mf
= (MPT_FRAME_HDR
*)req
;
1201 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(ii
);
1202 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= cb_idx
;
1205 /* Make sure there are no doorbells */
1206 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1208 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
,
1209 ((MPI_FUNCTION_HANDSHAKE
<<MPI_DOORBELL_FUNCTION_SHIFT
) |
1210 ((reqBytes
/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT
)));
1212 /* Wait for IOC doorbell int */
1213 if ((ii
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0) {
1217 /* Read doorbell and check for active bit */
1218 if (!(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & MPI_DOORBELL_ACTIVE
))
1221 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mpt_send_handshake_request start, WaitCnt=%d\n",
1224 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1226 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0) {
1230 /* Send request via doorbell handshake */
1231 req_as_bytes
= (u8
*) req
;
1232 for (ii
= 0; ii
< reqBytes
/4; ii
++) {
1235 word
= ((req_as_bytes
[(ii
*4) + 0] << 0) |
1236 (req_as_bytes
[(ii
*4) + 1] << 8) |
1237 (req_as_bytes
[(ii
*4) + 2] << 16) |
1238 (req_as_bytes
[(ii
*4) + 3] << 24));
1239 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, word
);
1240 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0) {
1246 if (r
>= 0 && WaitForDoorbellInt(ioc
, 10, sleepFlag
) >= 0)
1251 /* Make sure there are no doorbells */
1252 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1257 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1259 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
1260 * @ioc: Pointer to MPT adapter structure
1261 * @access_control_value: define bits below
1262 * @sleepFlag: Specifies whether the process can sleep
1264 * Provides mechanism for the host driver to control the IOC's
1265 * Host Page Buffer access.
1267 * Access Control Value - bits[15:12]
1269 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1270 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1271 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1273 * Returns 0 for success, non-zero for failure.
1277 mpt_host_page_access_control(MPT_ADAPTER
*ioc
, u8 access_control_value
, int sleepFlag
)
1281 /* return if in use */
1282 if (CHIPREG_READ32(&ioc
->chip
->Doorbell
)
1283 & MPI_DOORBELL_ACTIVE
)
1286 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1288 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
,
1289 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1290 <<MPI_DOORBELL_FUNCTION_SHIFT
) |
1291 (access_control_value
<<12)));
1293 /* Wait for IOC to clear Doorbell Status bit */
1294 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0) {
1300 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1302 * mpt_host_page_alloc - allocate system memory for the fw
1303 * @ioc: Pointer to pointer to IOC adapter
1304 * @ioc_init: Pointer to ioc init config page
1306 * If we already allocated memory in past, then resend the same pointer.
1307 * Returns 0 for success, non-zero for failure.
1310 mpt_host_page_alloc(MPT_ADAPTER
*ioc
, pIOCInit_t ioc_init
)
1314 u32 host_page_buffer_sz
=0;
1316 if(!ioc
->HostPageBuffer
) {
1318 host_page_buffer_sz
=
1319 le32_to_cpu(ioc
->facts
.HostPageBufferSGE
.FlagsLength
) & 0xFFFFFF;
1321 if(!host_page_buffer_sz
)
1322 return 0; /* fw doesn't need any host buffers */
1324 /* spin till we get enough memory */
1325 while(host_page_buffer_sz
> 0) {
1327 if((ioc
->HostPageBuffer
= pci_alloc_consistent(
1329 host_page_buffer_sz
,
1330 &ioc
->HostPageBuffer_dma
)) != NULL
) {
1332 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
1333 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1334 ioc
->name
, ioc
->HostPageBuffer
,
1335 (u32
)ioc
->HostPageBuffer_dma
,
1336 host_page_buffer_sz
));
1337 ioc
->alloc_total
+= host_page_buffer_sz
;
1338 ioc
->HostPageBuffer_sz
= host_page_buffer_sz
;
1342 host_page_buffer_sz
-= (4*1024);
1346 if(!ioc
->HostPageBuffer
) {
1347 printk(MYIOC_s_ERR_FMT
1348 "Failed to alloc memory for host_page_buffer!\n",
1353 psge
= (char *)&ioc_init
->HostPageBufferSGE
;
1354 flags_length
= MPI_SGE_FLAGS_SIMPLE_ELEMENT
|
1355 MPI_SGE_FLAGS_SYSTEM_ADDRESS
|
1356 MPI_SGE_FLAGS_HOST_TO_IOC
|
1357 MPI_SGE_FLAGS_END_OF_BUFFER
;
1358 flags_length
= flags_length
<< MPI_SGE_FLAGS_SHIFT
;
1359 flags_length
|= ioc
->HostPageBuffer_sz
;
1360 ioc
->add_sge(psge
, flags_length
, ioc
->HostPageBuffer_dma
);
1361 ioc
->facts
.HostPageBufferSGE
= ioc_init
->HostPageBufferSGE
;
1366 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1368 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1369 * @iocid: IOC unique identifier (integer)
1370 * @iocpp: Pointer to pointer to IOC adapter
1372 * Given a unique IOC identifier, set pointer to the associated MPT
1373 * adapter structure.
1375 * Returns iocid and sets iocpp if iocid is found.
1376 * Returns -1 if iocid is not found.
1379 mpt_verify_adapter(int iocid
, MPT_ADAPTER
**iocpp
)
1383 list_for_each_entry(ioc
,&ioc_list
,list
) {
1384 if (ioc
->id
== iocid
) {
1395 * mpt_get_product_name - returns product string
1396 * @vendor: pci vendor id
1397 * @device: pci device id
1398 * @revision: pci revision id
1400 * Returns product string displayed when driver loads,
1401 * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1405 mpt_get_product_name(u16 vendor
, u16 device
, u8 revision
)
1407 char *product_str
= NULL
;
1409 if (vendor
== PCI_VENDOR_ID_BROCADE
) {
1412 case MPI_MANUFACTPAGE_DEVICEID_FC949E
:
1416 product_str
= "BRE040 A0";
1419 product_str
= "BRE040 A1";
1422 product_str
= "BRE040";
1432 case MPI_MANUFACTPAGE_DEVICEID_FC909
:
1433 product_str
= "LSIFC909 B1";
1435 case MPI_MANUFACTPAGE_DEVICEID_FC919
:
1436 product_str
= "LSIFC919 B0";
1438 case MPI_MANUFACTPAGE_DEVICEID_FC929
:
1439 product_str
= "LSIFC929 B0";
1441 case MPI_MANUFACTPAGE_DEVICEID_FC919X
:
1442 if (revision
< 0x80)
1443 product_str
= "LSIFC919X A0";
1445 product_str
= "LSIFC919XL A1";
1447 case MPI_MANUFACTPAGE_DEVICEID_FC929X
:
1448 if (revision
< 0x80)
1449 product_str
= "LSIFC929X A0";
1451 product_str
= "LSIFC929XL A1";
1453 case MPI_MANUFACTPAGE_DEVICEID_FC939X
:
1454 product_str
= "LSIFC939X A1";
1456 case MPI_MANUFACTPAGE_DEVICEID_FC949X
:
1457 product_str
= "LSIFC949X A1";
1459 case MPI_MANUFACTPAGE_DEVICEID_FC949E
:
1463 product_str
= "LSIFC949E A0";
1466 product_str
= "LSIFC949E A1";
1469 product_str
= "LSIFC949E";
1473 case MPI_MANUFACTPAGE_DEVID_53C1030
:
1477 product_str
= "LSI53C1030 A0";
1480 product_str
= "LSI53C1030 B0";
1483 product_str
= "LSI53C1030 B1";
1486 product_str
= "LSI53C1030 B2";
1489 product_str
= "LSI53C1030 C0";
1492 product_str
= "LSI53C1030T A0";
1495 product_str
= "LSI53C1030T A2";
1498 product_str
= "LSI53C1030T A3";
1501 product_str
= "LSI53C1020A A1";
1504 product_str
= "LSI53C1030";
1508 case MPI_MANUFACTPAGE_DEVID_1030_53C1035
:
1512 product_str
= "LSI53C1035 A2";
1515 product_str
= "LSI53C1035 B0";
1518 product_str
= "LSI53C1035";
1522 case MPI_MANUFACTPAGE_DEVID_SAS1064
:
1526 product_str
= "LSISAS1064 A1";
1529 product_str
= "LSISAS1064 A2";
1532 product_str
= "LSISAS1064 A3";
1535 product_str
= "LSISAS1064 A4";
1538 product_str
= "LSISAS1064";
1542 case MPI_MANUFACTPAGE_DEVID_SAS1064E
:
1546 product_str
= "LSISAS1064E A0";
1549 product_str
= "LSISAS1064E B0";
1552 product_str
= "LSISAS1064E B1";
1555 product_str
= "LSISAS1064E B2";
1558 product_str
= "LSISAS1064E B3";
1561 product_str
= "LSISAS1064E";
1565 case MPI_MANUFACTPAGE_DEVID_SAS1068
:
1569 product_str
= "LSISAS1068 A0";
1572 product_str
= "LSISAS1068 B0";
1575 product_str
= "LSISAS1068 B1";
1578 product_str
= "LSISAS1068";
1582 case MPI_MANUFACTPAGE_DEVID_SAS1068E
:
1586 product_str
= "LSISAS1068E A0";
1589 product_str
= "LSISAS1068E B0";
1592 product_str
= "LSISAS1068E B1";
1595 product_str
= "LSISAS1068E B2";
1598 product_str
= "LSISAS1068E B3";
1601 product_str
= "LSISAS1068E";
1605 case MPI_MANUFACTPAGE_DEVID_SAS1078
:
1609 product_str
= "LSISAS1078 A0";
1612 product_str
= "LSISAS1078 B0";
1615 product_str
= "LSISAS1078 C0";
1618 product_str
= "LSISAS1078 C1";
1621 product_str
= "LSISAS1078 C2";
1624 product_str
= "LSISAS1078";
1635 * mpt_mapresources - map in memory mapped io
1636 * @ioc: Pointer to pointer to IOC adapter
1640 mpt_mapresources(MPT_ADAPTER
*ioc
)
1644 resource_size_t mem_phys
;
1649 struct pci_dev
*pdev
;
1652 ioc
->bars
= pci_select_bars(pdev
, IORESOURCE_MEM
);
1653 if (pci_enable_device_mem(pdev
)) {
1654 printk(MYIOC_s_ERR_FMT
"pci_enable_device_mem() "
1655 "failed\n", ioc
->name
);
1658 if (pci_request_selected_regions(pdev
, ioc
->bars
, "mpt")) {
1659 printk(MYIOC_s_ERR_FMT
"pci_request_selected_regions() with "
1660 "MEM failed\n", ioc
->name
);
1661 goto out_pci_disable_device
;
1664 if (sizeof(dma_addr_t
) > 4) {
1665 const uint64_t required_mask
= dma_get_required_mask
1667 if (required_mask
> DMA_BIT_MASK(32)
1668 && !pci_set_dma_mask(pdev
, DMA_BIT_MASK(64))
1669 && !pci_set_consistent_dma_mask(pdev
,
1670 DMA_BIT_MASK(64))) {
1671 ioc
->dma_mask
= DMA_BIT_MASK(64);
1672 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
1673 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1675 } else if (!pci_set_dma_mask(pdev
, DMA_BIT_MASK(32))
1676 && !pci_set_consistent_dma_mask(pdev
,
1677 DMA_BIT_MASK(32))) {
1678 ioc
->dma_mask
= DMA_BIT_MASK(32);
1679 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
1680 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1683 printk(MYIOC_s_WARN_FMT
"no suitable DMA mask for %s\n",
1684 ioc
->name
, pci_name(pdev
));
1685 goto out_pci_release_region
;
1688 if (!pci_set_dma_mask(pdev
, DMA_BIT_MASK(32))
1689 && !pci_set_consistent_dma_mask(pdev
,
1690 DMA_BIT_MASK(32))) {
1691 ioc
->dma_mask
= DMA_BIT_MASK(32);
1692 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
1693 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1696 printk(MYIOC_s_WARN_FMT
"no suitable DMA mask for %s\n",
1697 ioc
->name
, pci_name(pdev
));
1698 goto out_pci_release_region
;
1702 mem_phys
= msize
= 0;
1704 for (ii
= 0; ii
< DEVICE_COUNT_RESOURCE
; ii
++) {
1705 if (pci_resource_flags(pdev
, ii
) & PCI_BASE_ADDRESS_SPACE_IO
) {
1708 /* Get I/O space! */
1709 port
= pci_resource_start(pdev
, ii
);
1710 psize
= pci_resource_len(pdev
, ii
);
1715 mem_phys
= pci_resource_start(pdev
, ii
);
1716 msize
= pci_resource_len(pdev
, ii
);
1719 ioc
->mem_size
= msize
;
1722 /* Get logical ptr for PciMem0 space */
1723 /*mem = ioremap(mem_phys, msize);*/
1724 mem
= ioremap(mem_phys
, msize
);
1726 printk(MYIOC_s_ERR_FMT
": ERROR - Unable to map adapter"
1727 " memory!\n", ioc
->name
);
1729 goto out_pci_release_region
;
1732 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"mem = %p, mem_phys = %llx\n",
1733 ioc
->name
, mem
, (unsigned long long)mem_phys
));
1735 ioc
->mem_phys
= mem_phys
;
1736 ioc
->chip
= (SYSIF_REGS __iomem
*)mem
;
1738 /* Save Port IO values in case we need to do downloadboot */
1739 ioc
->pio_mem_phys
= port
;
1740 ioc
->pio_chip
= (SYSIF_REGS __iomem
*)port
;
1744 out_pci_release_region
:
1745 pci_release_selected_regions(pdev
, ioc
->bars
);
1746 out_pci_disable_device
:
1747 pci_disable_device(pdev
);
1751 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1753 * mpt_attach - Install a PCI intelligent MPT adapter.
1754 * @pdev: Pointer to pci_dev structure
1755 * @id: PCI device ID information
1757 * This routine performs all the steps necessary to bring the IOC of
1758 * a MPT adapter to a OPERATIONAL state. This includes registering
1759 * memory regions, registering the interrupt, and allocating request
1760 * and reply memory pools.
1762 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1765 * Returns 0 for success, non-zero for failure.
1767 * TODO: Add support for polled controllers
1770 mpt_attach(struct pci_dev
*pdev
, const struct pci_device_id
*id
)
1776 static int mpt_ids
= 0;
1777 #ifdef CONFIG_PROC_FS
1778 struct proc_dir_entry
*dent
;
1781 ioc
= kzalloc(sizeof(MPT_ADAPTER
), GFP_ATOMIC
);
1783 printk(KERN_ERR MYNAM
": ERROR - Insufficient memory to add adapter!\n");
1787 ioc
->id
= mpt_ids
++;
1788 sprintf(ioc
->name
, "ioc%d", ioc
->id
);
1789 dinitprintk(ioc
, printk(KERN_WARNING MYNAM
": mpt_adapter_install\n"));
1792 * set initial debug level
1793 * (refer to mptdebug.h)
1796 ioc
->debug_level
= mpt_debug_level
;
1797 if (mpt_debug_level
)
1798 printk(KERN_INFO
"mpt_debug_level=%xh\n", mpt_debug_level
);
1800 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
": mpt_adapter_install\n", ioc
->name
));
1803 if (mpt_mapresources(ioc
)) {
1809 * Setting up proper handlers for scatter gather handling
1811 if (ioc
->dma_mask
== DMA_BIT_MASK(64)) {
1812 if (pdev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1078
)
1813 ioc
->add_sge
= &mpt_add_sge_64bit_1078
;
1815 ioc
->add_sge
= &mpt_add_sge_64bit
;
1816 ioc
->add_chain
= &mpt_add_chain_64bit
;
1817 ioc
->sg_addr_size
= 8;
1819 ioc
->add_sge
= &mpt_add_sge
;
1820 ioc
->add_chain
= &mpt_add_chain
;
1821 ioc
->sg_addr_size
= 4;
1823 ioc
->SGE_size
= sizeof(u32
) + ioc
->sg_addr_size
;
1825 ioc
->alloc_total
= sizeof(MPT_ADAPTER
);
1826 ioc
->req_sz
= MPT_DEFAULT_FRAME_SIZE
; /* avoid div by zero! */
1827 ioc
->reply_sz
= MPT_REPLY_FRAME_SIZE
;
1830 spin_lock_init(&ioc
->taskmgmt_lock
);
1831 mutex_init(&ioc
->internal_cmds
.mutex
);
1832 init_completion(&ioc
->internal_cmds
.done
);
1833 mutex_init(&ioc
->mptbase_cmds
.mutex
);
1834 init_completion(&ioc
->mptbase_cmds
.done
);
1835 mutex_init(&ioc
->taskmgmt_cmds
.mutex
);
1836 init_completion(&ioc
->taskmgmt_cmds
.done
);
1838 /* Initialize the event logging.
1840 ioc
->eventTypes
= 0; /* None */
1841 ioc
->eventContext
= 0;
1842 ioc
->eventLogSize
= 0;
1850 ioc
->cached_fw
= NULL
;
1852 /* Initialize SCSI Config Data structure
1854 memset(&ioc
->spi_data
, 0, sizeof(SpiCfgData
));
1856 /* Initialize the fc rport list head.
1858 INIT_LIST_HEAD(&ioc
->fc_rports
);
1860 /* Find lookup slot. */
1861 INIT_LIST_HEAD(&ioc
->list
);
1864 /* Initialize workqueue */
1865 INIT_DELAYED_WORK(&ioc
->fault_reset_work
, mpt_fault_reset_work
);
1867 snprintf(ioc
->reset_work_q_name
, MPT_KOBJ_NAME_LEN
,
1868 "mpt_poll_%d", ioc
->id
);
1870 create_singlethread_workqueue(ioc
->reset_work_q_name
);
1871 if (!ioc
->reset_work_q
) {
1872 printk(MYIOC_s_ERR_FMT
"Insufficient memory to add adapter!\n",
1874 pci_release_selected_regions(pdev
, ioc
->bars
);
1879 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"facts @ %p, pfacts[0] @ %p\n",
1880 ioc
->name
, &ioc
->facts
, &ioc
->pfacts
[0]));
1882 ioc
->prod_name
= mpt_get_product_name(pdev
->vendor
, pdev
->device
,
1885 switch (pdev
->device
)
1887 case MPI_MANUFACTPAGE_DEVICEID_FC939X
:
1888 case MPI_MANUFACTPAGE_DEVICEID_FC949X
:
1889 ioc
->errata_flag_1064
= 1;
1890 case MPI_MANUFACTPAGE_DEVICEID_FC909
:
1891 case MPI_MANUFACTPAGE_DEVICEID_FC929
:
1892 case MPI_MANUFACTPAGE_DEVICEID_FC919
:
1893 case MPI_MANUFACTPAGE_DEVICEID_FC949E
:
1897 case MPI_MANUFACTPAGE_DEVICEID_FC929X
:
1898 if (pdev
->revision
< XL_929
) {
1899 /* 929X Chip Fix. Set Split transactions level
1900 * for PCIX. Set MOST bits to zero.
1902 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1904 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1906 /* 929XL Chip Fix. Set MMRBC to 0x08.
1908 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1910 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1915 case MPI_MANUFACTPAGE_DEVICEID_FC919X
:
1916 /* 919X Chip Fix. Set Split transactions level
1917 * for PCIX. Set MOST bits to zero.
1919 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1921 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1925 case MPI_MANUFACTPAGE_DEVID_53C1030
:
1926 /* 1030 Chip Fix. Disable Split transactions
1927 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1929 if (pdev
->revision
< C0_1030
) {
1930 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1932 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1935 case MPI_MANUFACTPAGE_DEVID_1030_53C1035
:
1936 ioc
->bus_type
= SPI
;
1939 case MPI_MANUFACTPAGE_DEVID_SAS1064
:
1940 case MPI_MANUFACTPAGE_DEVID_SAS1068
:
1941 ioc
->errata_flag_1064
= 1;
1942 ioc
->bus_type
= SAS
;
1945 case MPI_MANUFACTPAGE_DEVID_SAS1064E
:
1946 case MPI_MANUFACTPAGE_DEVID_SAS1068E
:
1947 case MPI_MANUFACTPAGE_DEVID_SAS1078
:
1948 ioc
->bus_type
= SAS
;
1953 switch (ioc
->bus_type
) {
1956 ioc
->msi_enable
= mpt_msi_enable_sas
;
1960 ioc
->msi_enable
= mpt_msi_enable_spi
;
1964 ioc
->msi_enable
= mpt_msi_enable_fc
;
1968 ioc
->msi_enable
= 0;
1972 ioc
->fw_events_off
= 1;
1974 if (ioc
->errata_flag_1064
)
1975 pci_disable_io_access(pdev
);
1977 spin_lock_init(&ioc
->FreeQlock
);
1980 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
1982 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1984 /* Set IOC ptr in the pcidev's driver data. */
1985 pci_set_drvdata(ioc
->pcidev
, ioc
);
1987 /* Set lookup ptr. */
1988 list_add_tail(&ioc
->list
, &ioc_list
);
1990 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1992 mpt_detect_bound_ports(ioc
, pdev
);
1994 INIT_LIST_HEAD(&ioc
->fw_event_list
);
1995 spin_lock_init(&ioc
->fw_event_lock
);
1996 snprintf(ioc
->fw_event_q_name
, MPT_KOBJ_NAME_LEN
, "mpt/%d", ioc
->id
);
1997 ioc
->fw_event_q
= create_singlethread_workqueue(ioc
->fw_event_q_name
);
1999 if ((r
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_BRINGUP
,
2001 printk(MYIOC_s_ERR_FMT
"didn't initialize properly! (%d)\n",
2004 list_del(&ioc
->list
);
2006 ioc
->alt_ioc
->alt_ioc
= NULL
;
2007 iounmap(ioc
->memmap
);
2009 pci_release_selected_regions(pdev
, ioc
->bars
);
2011 destroy_workqueue(ioc
->reset_work_q
);
2012 ioc
->reset_work_q
= NULL
;
2015 pci_set_drvdata(pdev
, NULL
);
2019 /* call per device driver probe entry point */
2020 for(cb_idx
= 0; cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
; cb_idx
++) {
2021 if(MptDeviceDriverHandlers
[cb_idx
] &&
2022 MptDeviceDriverHandlers
[cb_idx
]->probe
) {
2023 MptDeviceDriverHandlers
[cb_idx
]->probe(pdev
,id
);
2027 #ifdef CONFIG_PROC_FS
2029 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
2031 dent
= proc_mkdir(ioc
->name
, mpt_proc_root_dir
);
2033 proc_create_data("info", S_IRUGO
, dent
, &mpt_iocinfo_proc_fops
, ioc
);
2034 proc_create_data("summary", S_IRUGO
, dent
, &mpt_summary_proc_fops
, ioc
);
2039 queue_delayed_work(ioc
->reset_work_q
, &ioc
->fault_reset_work
,
2040 msecs_to_jiffies(MPT_POLLING_INTERVAL
));
2045 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2047 * mpt_detach - Remove a PCI intelligent MPT adapter.
2048 * @pdev: Pointer to pci_dev structure
2052 mpt_detach(struct pci_dev
*pdev
)
2054 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
2057 unsigned long flags
;
2058 struct workqueue_struct
*wq
;
2061 * Stop polling ioc for fault condition
2063 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
2064 wq
= ioc
->reset_work_q
;
2065 ioc
->reset_work_q
= NULL
;
2066 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
2067 cancel_delayed_work(&ioc
->fault_reset_work
);
2068 destroy_workqueue(wq
);
2070 spin_lock_irqsave(&ioc
->fw_event_lock
, flags
);
2071 wq
= ioc
->fw_event_q
;
2072 ioc
->fw_event_q
= NULL
;
2073 spin_unlock_irqrestore(&ioc
->fw_event_lock
, flags
);
2074 destroy_workqueue(wq
);
2076 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s/summary", ioc
->name
);
2077 remove_proc_entry(pname
, NULL
);
2078 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s/info", ioc
->name
);
2079 remove_proc_entry(pname
, NULL
);
2080 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s", ioc
->name
);
2081 remove_proc_entry(pname
, NULL
);
2083 /* call per device driver remove entry point */
2084 for(cb_idx
= 0; cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
; cb_idx
++) {
2085 if(MptDeviceDriverHandlers
[cb_idx
] &&
2086 MptDeviceDriverHandlers
[cb_idx
]->remove
) {
2087 MptDeviceDriverHandlers
[cb_idx
]->remove(pdev
);
2091 /* Disable interrupts! */
2092 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2095 synchronize_irq(pdev
->irq
);
2097 /* Clear any lingering interrupt */
2098 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
2100 CHIPREG_READ32(&ioc
->chip
->IntStatus
);
2102 mpt_adapter_dispose(ioc
);
2106 /**************************************************************************
2110 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2112 * mpt_suspend - Fusion MPT base driver suspend routine.
2113 * @pdev: Pointer to pci_dev structure
2114 * @state: new state to enter
2117 mpt_suspend(struct pci_dev
*pdev
, pm_message_t state
)
2120 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
2122 device_state
= pci_choose_state(pdev
, state
);
2123 printk(MYIOC_s_INFO_FMT
"pci-suspend: pdev=0x%p, slot=%s, Entering "
2124 "operating state [D%d]\n", ioc
->name
, pdev
, pci_name(pdev
),
2127 /* put ioc into READY_STATE */
2128 if(SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, CAN_SLEEP
)) {
2129 printk(MYIOC_s_ERR_FMT
2130 "pci-suspend: IOC msg unit reset failed!\n", ioc
->name
);
2133 /* disable interrupts */
2134 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2137 /* Clear any lingering interrupt */
2138 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
2140 free_irq(ioc
->pci_irq
, ioc
);
2141 if (ioc
->msi_enable
)
2142 pci_disable_msi(ioc
->pcidev
);
2144 pci_save_state(pdev
);
2145 pci_disable_device(pdev
);
2146 pci_release_selected_regions(pdev
, ioc
->bars
);
2147 pci_set_power_state(pdev
, device_state
);
2151 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2153 * mpt_resume - Fusion MPT base driver resume routine.
2154 * @pdev: Pointer to pci_dev structure
2157 mpt_resume(struct pci_dev
*pdev
)
2159 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
2160 u32 device_state
= pdev
->current_state
;
2164 printk(MYIOC_s_INFO_FMT
"pci-resume: pdev=0x%p, slot=%s, Previous "
2165 "operating state [D%d]\n", ioc
->name
, pdev
, pci_name(pdev
),
2168 pci_set_power_state(pdev
, PCI_D0
);
2169 pci_enable_wake(pdev
, PCI_D0
, 0);
2170 pci_restore_state(pdev
);
2172 err
= mpt_mapresources(ioc
);
2176 if (ioc
->dma_mask
== DMA_BIT_MASK(64)) {
2177 if (pdev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1078
)
2178 ioc
->add_sge
= &mpt_add_sge_64bit_1078
;
2180 ioc
->add_sge
= &mpt_add_sge_64bit
;
2181 ioc
->add_chain
= &mpt_add_chain_64bit
;
2182 ioc
->sg_addr_size
= 8;
2185 ioc
->add_sge
= &mpt_add_sge
;
2186 ioc
->add_chain
= &mpt_add_chain
;
2187 ioc
->sg_addr_size
= 4;
2189 ioc
->SGE_size
= sizeof(u32
) + ioc
->sg_addr_size
;
2191 printk(MYIOC_s_INFO_FMT
"pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
2192 ioc
->name
, (mpt_GetIocState(ioc
, 1) >> MPI_IOC_STATE_SHIFT
),
2193 CHIPREG_READ32(&ioc
->chip
->Doorbell
));
2196 * Errata workaround for SAS pci express:
2197 * Upon returning to the D0 state, the contents of the doorbell will be
2198 * stale data, and this will incorrectly signal to the host driver that
2199 * the firmware is ready to process mpt commands. The workaround is
2200 * to issue a diagnostic reset.
2202 if (ioc
->bus_type
== SAS
&& (pdev
->device
==
2203 MPI_MANUFACTPAGE_DEVID_SAS1068E
|| pdev
->device
==
2204 MPI_MANUFACTPAGE_DEVID_SAS1064E
)) {
2205 if (KickStart(ioc
, 1, CAN_SLEEP
) < 0) {
2206 printk(MYIOC_s_WARN_FMT
"pci-resume: Cannot recover\n",
2212 /* bring ioc to operational state */
2213 printk(MYIOC_s_INFO_FMT
"Sending mpt_do_ioc_recovery\n", ioc
->name
);
2214 recovery_state
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_BRINGUP
,
2216 if (recovery_state
!= 0)
2217 printk(MYIOC_s_WARN_FMT
"pci-resume: Cannot recover, "
2218 "error:[%x]\n", ioc
->name
, recovery_state
);
2220 printk(MYIOC_s_INFO_FMT
2221 "pci-resume: success\n", ioc
->name
);
2229 mpt_signal_reset(u8 index
, MPT_ADAPTER
*ioc
, int reset_phase
)
2231 if ((MptDriverClass
[index
] == MPTSPI_DRIVER
&&
2232 ioc
->bus_type
!= SPI
) ||
2233 (MptDriverClass
[index
] == MPTFC_DRIVER
&&
2234 ioc
->bus_type
!= FC
) ||
2235 (MptDriverClass
[index
] == MPTSAS_DRIVER
&&
2236 ioc
->bus_type
!= SAS
))
2237 /* make sure we only call the relevant reset handler
2240 return (MptResetHandlers
[index
])(ioc
, reset_phase
);
2243 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2245 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
2246 * @ioc: Pointer to MPT adapter structure
2247 * @reason: Event word / reason
2248 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
2250 * This routine performs all the steps necessary to bring the IOC
2251 * to a OPERATIONAL state.
2253 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
2258 * -1 if failed to get board READY
2259 * -2 if READY but IOCFacts Failed
2260 * -3 if READY but PrimeIOCFifos Failed
2261 * -4 if READY but IOCInit Failed
2262 * -5 if failed to enable_device and/or request_selected_regions
2263 * -6 if failed to upload firmware
2266 mpt_do_ioc_recovery(MPT_ADAPTER
*ioc
, u32 reason
, int sleepFlag
)
2268 int hard_reset_done
= 0;
2269 int alt_ioc_ready
= 0;
2274 int reset_alt_ioc_active
= 0;
2275 int irq_allocated
= 0;
2278 printk(MYIOC_s_INFO_FMT
"Initiating %s\n", ioc
->name
,
2279 reason
== MPT_HOSTEVENT_IOC_BRINGUP
? "bringup" : "recovery");
2281 /* Disable reply interrupts (also blocks FreeQ) */
2282 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2286 if (ioc
->alt_ioc
->active
||
2287 reason
== MPT_HOSTEVENT_IOC_RECOVER
) {
2288 reset_alt_ioc_active
= 1;
2289 /* Disable alt-IOC's reply interrupts
2290 * (and FreeQ) for a bit
2292 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
,
2294 ioc
->alt_ioc
->active
= 0;
2299 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)
2302 if ((hard_reset_done
= MakeIocReady(ioc
, hard
, sleepFlag
)) < 0) {
2303 if (hard_reset_done
== -4) {
2304 printk(MYIOC_s_WARN_FMT
"Owned by PEER..skipping!\n",
2307 if (reset_alt_ioc_active
&& ioc
->alt_ioc
) {
2308 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
2309 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
2310 "alt_ioc reply irq re-enabled\n", ioc
->alt_ioc
->name
));
2311 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
, MPI_HIM_DIM
);
2312 ioc
->alt_ioc
->active
= 1;
2316 printk(MYIOC_s_WARN_FMT
2317 "NOT READY WARNING!\n", ioc
->name
);
2323 /* hard_reset_done = 0 if a soft reset was performed
2324 * and 1 if a hard reset was performed.
2326 if (hard_reset_done
&& reset_alt_ioc_active
&& ioc
->alt_ioc
) {
2327 if ((rc
= MakeIocReady(ioc
->alt_ioc
, 0, sleepFlag
)) == 0)
2330 printk(MYIOC_s_WARN_FMT
2331 ": alt-ioc Not ready WARNING!\n",
2332 ioc
->alt_ioc
->name
);
2335 for (ii
=0; ii
<5; ii
++) {
2336 /* Get IOC facts! Allow 5 retries */
2337 if ((rc
= GetIocFacts(ioc
, sleepFlag
, reason
)) == 0)
2343 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2344 "Retry IocFacts failed rc=%x\n", ioc
->name
, rc
));
2346 } else if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
2347 MptDisplayIocCapabilities(ioc
);
2350 if (alt_ioc_ready
) {
2351 if ((rc
= GetIocFacts(ioc
->alt_ioc
, sleepFlag
, reason
)) != 0) {
2352 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2353 "Initial Alt IocFacts failed rc=%x\n",
2355 /* Retry - alt IOC was initialized once
2357 rc
= GetIocFacts(ioc
->alt_ioc
, sleepFlag
, reason
);
2360 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2361 "Retry Alt IocFacts failed rc=%x\n", ioc
->name
, rc
));
2363 reset_alt_ioc_active
= 0;
2364 } else if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
2365 MptDisplayIocCapabilities(ioc
->alt_ioc
);
2369 if ((ret
== 0) && (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) &&
2370 (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)) {
2371 pci_release_selected_regions(ioc
->pcidev
, ioc
->bars
);
2372 ioc
->bars
= pci_select_bars(ioc
->pcidev
, IORESOURCE_MEM
|
2374 if (pci_enable_device(ioc
->pcidev
))
2376 if (pci_request_selected_regions(ioc
->pcidev
, ioc
->bars
,
2382 * Device is reset now. It must have de-asserted the interrupt line
2383 * (if it was asserted) and it should be safe to register for the
2386 if ((ret
== 0) && (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)) {
2388 if (ioc
->pcidev
->irq
) {
2389 if (ioc
->msi_enable
&& !pci_enable_msi(ioc
->pcidev
))
2390 printk(MYIOC_s_INFO_FMT
"PCI-MSI enabled\n",
2393 ioc
->msi_enable
= 0;
2394 rc
= request_irq(ioc
->pcidev
->irq
, mpt_interrupt
,
2395 IRQF_SHARED
, ioc
->name
, ioc
);
2397 printk(MYIOC_s_ERR_FMT
"Unable to allocate "
2399 ioc
->name
, ioc
->pcidev
->irq
);
2400 if (ioc
->msi_enable
)
2401 pci_disable_msi(ioc
->pcidev
);
2406 ioc
->pci_irq
= ioc
->pcidev
->irq
;
2407 pci_set_master(ioc
->pcidev
); /* ?? */
2408 pci_set_drvdata(ioc
->pcidev
, ioc
);
2409 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
2410 "installed at interrupt %d\n", ioc
->name
,
2415 /* Prime reply & request queues!
2416 * (mucho alloc's) Must be done prior to
2417 * init as upper addresses are needed for init.
2418 * If fails, continue with alt-ioc processing
2420 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"PrimeIocFifos\n",
2422 if ((ret
== 0) && ((rc
= PrimeIocFifos(ioc
)) != 0))
2425 /* May need to check/upload firmware & data here!
2426 * If fails, continue with alt-ioc processing
2428 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"SendIocInit\n",
2430 if ((ret
== 0) && ((rc
= SendIocInit(ioc
, sleepFlag
)) != 0))
2433 if (alt_ioc_ready
&& ((rc
= PrimeIocFifos(ioc
->alt_ioc
)) != 0)) {
2434 printk(MYIOC_s_WARN_FMT
2435 ": alt-ioc (%d) FIFO mgmt alloc WARNING!\n",
2436 ioc
->alt_ioc
->name
, rc
);
2438 reset_alt_ioc_active
= 0;
2441 if (alt_ioc_ready
) {
2442 if ((rc
= SendIocInit(ioc
->alt_ioc
, sleepFlag
)) != 0) {
2444 reset_alt_ioc_active
= 0;
2445 printk(MYIOC_s_WARN_FMT
2446 ": alt-ioc: (%d) init failure WARNING!\n",
2447 ioc
->alt_ioc
->name
, rc
);
2451 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
){
2452 if (ioc
->upload_fw
) {
2453 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2454 "firmware upload required!\n", ioc
->name
));
2456 /* Controller is not operational, cannot do upload
2459 rc
= mpt_do_upload(ioc
, sleepFlag
);
2461 if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
) {
2463 * Maintain only one pointer to FW memory
2464 * so there will not be two attempt to
2465 * downloadboot onboard dual function
2466 * chips (mpt_adapter_disable,
2469 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2470 "mpt_upload: alt_%s has cached_fw=%p \n",
2471 ioc
->name
, ioc
->alt_ioc
->name
, ioc
->alt_ioc
->cached_fw
));
2472 ioc
->cached_fw
= NULL
;
2475 printk(MYIOC_s_WARN_FMT
2476 "firmware upload failure!\n", ioc
->name
);
2483 /* Enable MPT base driver management of EventNotification
2484 * and EventAck handling.
2486 if ((ret
== 0) && (!ioc
->facts
.EventState
)) {
2487 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
2488 "SendEventNotification\n",
2490 ret
= SendEventNotification(ioc
, 1, sleepFlag
); /* 1=Enable */
2493 if (ioc
->alt_ioc
&& alt_ioc_ready
&& !ioc
->alt_ioc
->facts
.EventState
)
2494 rc
= SendEventNotification(ioc
->alt_ioc
, 1, sleepFlag
);
2497 /* Enable! (reply interrupt) */
2498 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, MPI_HIM_DIM
);
2501 if (rc
== 0) { /* alt ioc */
2502 if (reset_alt_ioc_active
&& ioc
->alt_ioc
) {
2503 /* (re)Enable alt-IOC! (reply interrupt) */
2504 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"alt-ioc"
2505 "reply irq re-enabled\n",
2506 ioc
->alt_ioc
->name
));
2507 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
,
2509 ioc
->alt_ioc
->active
= 1;
2514 /* Add additional "reason" check before call to GetLanConfigPages
2515 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2516 * recursive scenario; GetLanConfigPages times out, timer expired
2517 * routine calls HardResetHandler, which calls into here again,
2518 * and we try GetLanConfigPages again...
2520 if ((ret
== 0) && (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)) {
2523 * Initialize link list for inactive raid volumes.
2525 mutex_init(&ioc
->raid_data
.inactive_list_mutex
);
2526 INIT_LIST_HEAD(&ioc
->raid_data
.inactive_list
);
2528 switch (ioc
->bus_type
) {
2531 /* clear persistency table */
2532 if(ioc
->facts
.IOCExceptions
&
2533 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL
) {
2534 ret
= mptbase_sas_persist_operation(ioc
,
2535 MPI_SAS_OP_CLEAR_NOT_PRESENT
);
2542 mpt_findImVolumes(ioc
);
2544 /* Check, and possibly reset, the coalescing value
2546 mpt_read_ioc_pg_1(ioc
);
2551 if ((ioc
->pfacts
[0].ProtocolFlags
&
2552 MPI_PORTFACTS_PROTOCOL_LAN
) &&
2553 (ioc
->lan_cnfg_page0
.Header
.PageLength
== 0)) {
2555 * Pre-fetch the ports LAN MAC address!
2556 * (LANPage1_t stuff)
2558 (void) GetLanConfigPages(ioc
);
2559 a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
2560 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2561 "LanAddr = %02X:%02X:%02X"
2562 ":%02X:%02X:%02X\n",
2563 ioc
->name
, a
[5], a
[4],
2564 a
[3], a
[2], a
[1], a
[0]));
2569 /* Get NVRAM and adapter maximums from SPP 0 and 2
2571 mpt_GetScsiPortSettings(ioc
, 0);
2573 /* Get version and length of SDP 1
2575 mpt_readScsiDevicePageHeaders(ioc
, 0);
2579 if (ioc
->facts
.MsgVersion
>= MPI_VERSION_01_02
)
2580 mpt_findImVolumes(ioc
);
2582 /* Check, and possibly reset, the coalescing value
2584 mpt_read_ioc_pg_1(ioc
);
2586 mpt_read_ioc_pg_4(ioc
);
2591 GetIoUnitPage2(ioc
);
2592 mpt_get_manufacturing_pg_0(ioc
);
2596 if ((ret
!= 0) && irq_allocated
) {
2597 free_irq(ioc
->pci_irq
, ioc
);
2598 if (ioc
->msi_enable
)
2599 pci_disable_msi(ioc
->pcidev
);
2604 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2606 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2607 * @ioc: Pointer to MPT adapter structure
2608 * @pdev: Pointer to (struct pci_dev) structure
2610 * Search for PCI bus/dev_function which matches
2611 * PCI bus/dev_function (+/-1) for newly discovered 929,
2612 * 929X, 1030 or 1035.
2614 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2615 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2618 mpt_detect_bound_ports(MPT_ADAPTER
*ioc
, struct pci_dev
*pdev
)
2620 struct pci_dev
*peer
=NULL
;
2621 unsigned int slot
= PCI_SLOT(pdev
->devfn
);
2622 unsigned int func
= PCI_FUNC(pdev
->devfn
);
2623 MPT_ADAPTER
*ioc_srch
;
2625 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"PCI device %s devfn=%x/%x,"
2626 " searching for devfn match on %x or %x\n",
2627 ioc
->name
, pci_name(pdev
), pdev
->bus
->number
,
2628 pdev
->devfn
, func
-1, func
+1));
2630 peer
= pci_get_slot(pdev
->bus
, PCI_DEVFN(slot
,func
-1));
2632 peer
= pci_get_slot(pdev
->bus
, PCI_DEVFN(slot
,func
+1));
2637 list_for_each_entry(ioc_srch
, &ioc_list
, list
) {
2638 struct pci_dev
*_pcidev
= ioc_srch
->pcidev
;
2639 if (_pcidev
== peer
) {
2640 /* Paranoia checks */
2641 if (ioc
->alt_ioc
!= NULL
) {
2642 printk(MYIOC_s_WARN_FMT
2643 "Oops, already bound (%s <==> %s)!\n",
2644 ioc
->name
, ioc
->name
, ioc
->alt_ioc
->name
);
2646 } else if (ioc_srch
->alt_ioc
!= NULL
) {
2647 printk(MYIOC_s_WARN_FMT
2648 "Oops, already bound (%s <==> %s)!\n",
2649 ioc_srch
->name
, ioc_srch
->name
,
2650 ioc_srch
->alt_ioc
->name
);
2653 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2654 "FOUND! binding %s <==> %s\n",
2655 ioc
->name
, ioc
->name
, ioc_srch
->name
));
2656 ioc_srch
->alt_ioc
= ioc
;
2657 ioc
->alt_ioc
= ioc_srch
;
2663 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2665 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2666 * @ioc: Pointer to MPT adapter structure
2669 mpt_adapter_disable(MPT_ADAPTER
*ioc
)
2674 if (ioc
->cached_fw
!= NULL
) {
2675 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2676 "%s: Pushing FW onto adapter\n", __func__
, ioc
->name
));
2677 if ((ret
= mpt_downloadboot(ioc
, (MpiFwHeader_t
*)
2678 ioc
->cached_fw
, CAN_SLEEP
)) < 0) {
2679 printk(MYIOC_s_WARN_FMT
2680 ": firmware downloadboot failure (%d)!\n",
2686 * Put the controller into ready state (if its not already)
2688 if (mpt_GetIocState(ioc
, 1) != MPI_IOC_STATE_READY
) {
2689 if (!SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
,
2691 if (mpt_GetIocState(ioc
, 1) != MPI_IOC_STATE_READY
)
2692 printk(MYIOC_s_ERR_FMT
"%s: IOC msg unit "
2693 "reset failed to put ioc in ready state!\n",
2694 ioc
->name
, __func__
);
2696 printk(MYIOC_s_ERR_FMT
"%s: IOC msg unit reset "
2697 "failed!\n", ioc
->name
, __func__
);
2701 /* Disable adapter interrupts! */
2702 synchronize_irq(ioc
->pcidev
->irq
);
2703 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2706 /* Clear any lingering interrupt */
2707 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
2708 CHIPREG_READ32(&ioc
->chip
->IntStatus
);
2710 if (ioc
->alloc
!= NULL
) {
2712 dexitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"free @ %p, sz=%d bytes\n",
2713 ioc
->name
, ioc
->alloc
, ioc
->alloc_sz
));
2714 pci_free_consistent(ioc
->pcidev
, sz
,
2715 ioc
->alloc
, ioc
->alloc_dma
);
2716 ioc
->reply_frames
= NULL
;
2717 ioc
->req_frames
= NULL
;
2719 ioc
->alloc_total
-= sz
;
2722 if (ioc
->sense_buf_pool
!= NULL
) {
2723 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
2724 pci_free_consistent(ioc
->pcidev
, sz
,
2725 ioc
->sense_buf_pool
, ioc
->sense_buf_pool_dma
);
2726 ioc
->sense_buf_pool
= NULL
;
2727 ioc
->alloc_total
-= sz
;
2730 if (ioc
->events
!= NULL
){
2731 sz
= MPTCTL_EVENT_LOG_SIZE
* sizeof(MPT_IOCTL_EVENTS
);
2734 ioc
->alloc_total
-= sz
;
2737 mpt_free_fw_memory(ioc
);
2739 kfree(ioc
->spi_data
.nvram
);
2740 mpt_inactive_raid_list_free(ioc
);
2741 kfree(ioc
->raid_data
.pIocPg2
);
2742 kfree(ioc
->raid_data
.pIocPg3
);
2743 ioc
->spi_data
.nvram
= NULL
;
2744 ioc
->raid_data
.pIocPg3
= NULL
;
2746 if (ioc
->spi_data
.pIocPg4
!= NULL
) {
2747 sz
= ioc
->spi_data
.IocPg4Sz
;
2748 pci_free_consistent(ioc
->pcidev
, sz
,
2749 ioc
->spi_data
.pIocPg4
,
2750 ioc
->spi_data
.IocPg4_dma
);
2751 ioc
->spi_data
.pIocPg4
= NULL
;
2752 ioc
->alloc_total
-= sz
;
2755 if (ioc
->ReqToChain
!= NULL
) {
2756 kfree(ioc
->ReqToChain
);
2757 kfree(ioc
->RequestNB
);
2758 ioc
->ReqToChain
= NULL
;
2761 kfree(ioc
->ChainToChain
);
2762 ioc
->ChainToChain
= NULL
;
2764 if (ioc
->HostPageBuffer
!= NULL
) {
2765 if((ret
= mpt_host_page_access_control(ioc
,
2766 MPI_DB_HPBAC_FREE_BUFFER
, NO_SLEEP
)) != 0) {
2767 printk(MYIOC_s_ERR_FMT
2768 ": %s: host page buffers free failed (%d)!\n",
2769 ioc
->name
, __func__
, ret
);
2771 dexitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2772 "HostPageBuffer free @ %p, sz=%d bytes\n",
2773 ioc
->name
, ioc
->HostPageBuffer
,
2774 ioc
->HostPageBuffer_sz
));
2775 pci_free_consistent(ioc
->pcidev
, ioc
->HostPageBuffer_sz
,
2776 ioc
->HostPageBuffer
, ioc
->HostPageBuffer_dma
);
2777 ioc
->HostPageBuffer
= NULL
;
2778 ioc
->HostPageBuffer_sz
= 0;
2779 ioc
->alloc_total
-= ioc
->HostPageBuffer_sz
;
2782 pci_set_drvdata(ioc
->pcidev
, NULL
);
2784 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2786 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2787 * @ioc: Pointer to MPT adapter structure
2789 * This routine unregisters h/w resources and frees all alloc'd memory
2790 * associated with a MPT adapter structure.
2793 mpt_adapter_dispose(MPT_ADAPTER
*ioc
)
2795 int sz_first
, sz_last
;
2800 sz_first
= ioc
->alloc_total
;
2802 mpt_adapter_disable(ioc
);
2804 if (ioc
->pci_irq
!= -1) {
2805 free_irq(ioc
->pci_irq
, ioc
);
2806 if (ioc
->msi_enable
)
2807 pci_disable_msi(ioc
->pcidev
);
2811 if (ioc
->memmap
!= NULL
) {
2812 iounmap(ioc
->memmap
);
2816 pci_disable_device(ioc
->pcidev
);
2817 pci_release_selected_regions(ioc
->pcidev
, ioc
->bars
);
2819 /* Zap the adapter lookup ptr! */
2820 list_del(&ioc
->list
);
2822 sz_last
= ioc
->alloc_total
;
2823 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
"free'd %d of %d bytes\n",
2824 ioc
->name
, sz_first
-sz_last
+(int)sizeof(*ioc
), sz_first
));
2827 ioc
->alt_ioc
->alt_ioc
= NULL
;
2832 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2834 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2835 * @ioc: Pointer to MPT adapter structure
2838 MptDisplayIocCapabilities(MPT_ADAPTER
*ioc
)
2842 printk(KERN_INFO
"%s: ", ioc
->name
);
2844 printk("%s: ", ioc
->prod_name
);
2845 printk("Capabilities={");
2847 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_INITIATOR
) {
2848 printk("Initiator");
2852 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_TARGET
) {
2853 printk("%sTarget", i
? "," : "");
2857 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
) {
2858 printk("%sLAN", i
? "," : "");
2864 * This would probably evoke more questions than it's worth
2866 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_TARGET
) {
2867 printk("%sLogBusAddr", i
? "," : "");
2875 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2877 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2878 * @ioc: Pointer to MPT_ADAPTER structure
2879 * @force: Force hard KickStart of IOC
2880 * @sleepFlag: Specifies whether the process can sleep
2883 * 1 - DIAG reset and READY
2884 * 0 - READY initially OR soft reset and READY
2885 * -1 - Any failure on KickStart
2886 * -2 - Msg Unit Reset Failed
2887 * -3 - IO Unit Reset Failed
2888 * -4 - IOC owned by a PEER
2891 MakeIocReady(MPT_ADAPTER
*ioc
, int force
, int sleepFlag
)
2896 int hard_reset_done
= 0;
2901 /* Get current [raw] IOC state */
2902 ioc_state
= mpt_GetIocState(ioc
, 0);
2903 dhsprintk(ioc
, printk(MYIOC_s_INFO_FMT
"MakeIocReady [raw] state=%08x\n", ioc
->name
, ioc_state
));
2906 * Check to see if IOC got left/stuck in doorbell handshake
2907 * grip of death. If so, hard reset the IOC.
2909 if (ioc_state
& MPI_DOORBELL_ACTIVE
) {
2911 printk(MYIOC_s_WARN_FMT
"Unexpected doorbell active!\n",
2915 /* Is it already READY? */
2917 ((ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_READY
)) {
2918 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
2919 "IOC is in READY state\n", ioc
->name
));
2924 * Check to see if IOC is in FAULT state.
2926 if ((ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_FAULT
) {
2928 printk(MYIOC_s_WARN_FMT
"IOC is in FAULT state!!!\n",
2930 printk(MYIOC_s_WARN_FMT
" FAULT code = %04xh\n",
2931 ioc
->name
, ioc_state
& MPI_DOORBELL_DATA_MASK
);
2935 * Hmmm... Did it get left operational?
2937 if ((ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_OPERATIONAL
) {
2938 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"IOC operational unexpected\n",
2942 * If PCI Peer, exit.
2943 * Else, if no fault conditions are present, issue a MessageUnitReset
2944 * Else, fall through to KickStart case
2946 whoinit
= (ioc_state
& MPI_DOORBELL_WHO_INIT_MASK
) >> MPI_DOORBELL_WHO_INIT_SHIFT
;
2947 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
2948 "whoinit 0x%x statefault %d force %d\n",
2949 ioc
->name
, whoinit
, statefault
, force
));
2950 if (whoinit
== MPI_WHOINIT_PCI_PEER
)
2953 if ((statefault
== 0 ) && (force
== 0)) {
2954 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
)) == 0)
2961 hard_reset_done
= KickStart(ioc
, statefault
||force
, sleepFlag
);
2962 if (hard_reset_done
< 0)
2966 * Loop here waiting for IOC to come READY.
2969 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 5; /* 5 seconds */
2971 while ((ioc_state
= mpt_GetIocState(ioc
, 1)) != MPI_IOC_STATE_READY
) {
2972 if (ioc_state
== MPI_IOC_STATE_OPERATIONAL
) {
2974 * BIOS or previous driver load left IOC in OP state.
2975 * Reset messaging FIFOs.
2977 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
)) != 0) {
2978 printk(MYIOC_s_ERR_FMT
"IOC msg unit reset failed!\n", ioc
->name
);
2981 } else if (ioc_state
== MPI_IOC_STATE_RESET
) {
2983 * Something is wrong. Try to get IOC back
2986 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IO_UNIT_RESET
, sleepFlag
)) != 0) {
2987 printk(MYIOC_s_ERR_FMT
"IO unit reset failed!\n", ioc
->name
);
2994 printk(MYIOC_s_ERR_FMT
2995 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
2996 ioc
->name
, ioc_state
, (int)((ii
+5)/HZ
));
3000 if (sleepFlag
== CAN_SLEEP
) {
3003 mdelay (1); /* 1 msec delay */
3008 if (statefault
< 3) {
3009 printk(MYIOC_s_INFO_FMT
"Recovered from %s\n", ioc
->name
,
3010 statefault
== 1 ? "stuck handshake" : "IOC FAULT");
3013 return hard_reset_done
;
3016 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3018 * mpt_GetIocState - Get the current state of a MPT adapter.
3019 * @ioc: Pointer to MPT_ADAPTER structure
3020 * @cooked: Request raw or cooked IOC state
3022 * Returns all IOC Doorbell register bits if cooked==0, else just the
3023 * Doorbell bits in MPI_IOC_STATE_MASK.
3026 mpt_GetIocState(MPT_ADAPTER
*ioc
, int cooked
)
3031 s
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
3032 sc
= s
& MPI_IOC_STATE_MASK
;
3035 ioc
->last_state
= sc
;
3037 return cooked
? sc
: s
;
3040 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3042 * GetIocFacts - Send IOCFacts request to MPT adapter.
3043 * @ioc: Pointer to MPT_ADAPTER structure
3044 * @sleepFlag: Specifies whether the process can sleep
3045 * @reason: If recovery, only update facts.
3047 * Returns 0 for success, non-zero for failure.
3050 GetIocFacts(MPT_ADAPTER
*ioc
, int sleepFlag
, int reason
)
3052 IOCFacts_t get_facts
;
3053 IOCFactsReply_t
*facts
;
3061 /* IOC *must* NOT be in RESET state! */
3062 if (ioc
->last_state
== MPI_IOC_STATE_RESET
) {
3063 printk(KERN_ERR MYNAM
3064 ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
3065 ioc
->name
, ioc
->last_state
);
3069 facts
= &ioc
->facts
;
3071 /* Destination (reply area)... */
3072 reply_sz
= sizeof(*facts
);
3073 memset(facts
, 0, reply_sz
);
3075 /* Request area (get_facts on the stack right now!) */
3076 req_sz
= sizeof(get_facts
);
3077 memset(&get_facts
, 0, req_sz
);
3079 get_facts
.Function
= MPI_FUNCTION_IOC_FACTS
;
3080 /* Assert: All other get_facts fields are zero! */
3082 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3083 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
3084 ioc
->name
, req_sz
, reply_sz
));
3086 /* No non-zero fields in the get_facts request are greater than
3087 * 1 byte in size, so we can just fire it off as is.
3089 r
= mpt_handshake_req_reply_wait(ioc
, req_sz
, (u32
*)&get_facts
,
3090 reply_sz
, (u16
*)facts
, 5 /*seconds*/, sleepFlag
);
3095 * Now byte swap (GRRR) the necessary fields before any further
3096 * inspection of reply contents.
3098 * But need to do some sanity checks on MsgLength (byte) field
3099 * to make sure we don't zero IOC's req_sz!
3101 /* Did we get a valid reply? */
3102 if (facts
->MsgLength
> offsetof(IOCFactsReply_t
, RequestFrameSize
)/sizeof(u32
)) {
3103 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
3105 * If not been here, done that, save off first WhoInit value
3107 if (ioc
->FirstWhoInit
== WHOINIT_UNKNOWN
)
3108 ioc
->FirstWhoInit
= facts
->WhoInit
;
3111 facts
->MsgVersion
= le16_to_cpu(facts
->MsgVersion
);
3112 facts
->MsgContext
= le32_to_cpu(facts
->MsgContext
);
3113 facts
->IOCExceptions
= le16_to_cpu(facts
->IOCExceptions
);
3114 facts
->IOCStatus
= le16_to_cpu(facts
->IOCStatus
);
3115 facts
->IOCLogInfo
= le32_to_cpu(facts
->IOCLogInfo
);
3116 status
= le16_to_cpu(facts
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
3117 /* CHECKME! IOCStatus, IOCLogInfo */
3119 facts
->ReplyQueueDepth
= le16_to_cpu(facts
->ReplyQueueDepth
);
3120 facts
->RequestFrameSize
= le16_to_cpu(facts
->RequestFrameSize
);
3123 * FC f/w version changed between 1.1 and 1.2
3124 * Old: u16{Major(4),Minor(4),SubMinor(8)}
3125 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
3127 if (facts
->MsgVersion
< MPI_VERSION_01_02
) {
3129 * Handle old FC f/w style, convert to new...
3131 u16 oldv
= le16_to_cpu(facts
->Reserved_0101_FWVersion
);
3132 facts
->FWVersion
.Word
=
3133 ((oldv
<<12) & 0xFF000000) |
3134 ((oldv
<<8) & 0x000FFF00);
3136 facts
->FWVersion
.Word
= le32_to_cpu(facts
->FWVersion
.Word
);
3138 facts
->ProductID
= le16_to_cpu(facts
->ProductID
);
3140 if ((ioc
->facts
.ProductID
& MPI_FW_HEADER_PID_PROD_MASK
)
3141 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI
)
3142 ioc
->ir_firmware
= 1;
3144 facts
->CurrentHostMfaHighAddr
=
3145 le32_to_cpu(facts
->CurrentHostMfaHighAddr
);
3146 facts
->GlobalCredits
= le16_to_cpu(facts
->GlobalCredits
);
3147 facts
->CurrentSenseBufferHighAddr
=
3148 le32_to_cpu(facts
->CurrentSenseBufferHighAddr
);
3149 facts
->CurReplyFrameSize
=
3150 le16_to_cpu(facts
->CurReplyFrameSize
);
3151 facts
->IOCCapabilities
= le32_to_cpu(facts
->IOCCapabilities
);
3154 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
3155 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
3156 * to 14 in MPI-1.01.0x.
3158 if (facts
->MsgLength
>= (offsetof(IOCFactsReply_t
,FWImageSize
) + 7)/4 &&
3159 facts
->MsgVersion
> MPI_VERSION_01_00
) {
3160 facts
->FWImageSize
= le32_to_cpu(facts
->FWImageSize
);
3163 facts
->FWImageSize
= ALIGN(facts
->FWImageSize
, 4);
3165 if (!facts
->RequestFrameSize
) {
3166 /* Something is wrong! */
3167 printk(MYIOC_s_ERR_FMT
"IOC reported invalid 0 request size!\n",
3172 r
= sz
= facts
->BlockSize
;
3173 vv
= ((63 / (sz
* 4)) + 1) & 0x03;
3174 ioc
->NB_for_64_byte_frame
= vv
;
3180 ioc
->NBShiftFactor
= shiftFactor
;
3181 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3182 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
3183 ioc
->name
, vv
, shiftFactor
, r
));
3185 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
3187 * Set values for this IOC's request & reply frame sizes,
3188 * and request & reply queue depths...
3190 ioc
->req_sz
= min(MPT_DEFAULT_FRAME_SIZE
, facts
->RequestFrameSize
* 4);
3191 ioc
->req_depth
= min_t(int, MPT_MAX_REQ_DEPTH
, facts
->GlobalCredits
);
3192 ioc
->reply_sz
= MPT_REPLY_FRAME_SIZE
;
3193 ioc
->reply_depth
= min_t(int, MPT_DEFAULT_REPLY_DEPTH
, facts
->ReplyQueueDepth
);
3195 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"reply_sz=%3d, reply_depth=%4d\n",
3196 ioc
->name
, ioc
->reply_sz
, ioc
->reply_depth
));
3197 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"req_sz =%3d, req_depth =%4d\n",
3198 ioc
->name
, ioc
->req_sz
, ioc
->req_depth
));
3200 /* Get port facts! */
3201 if ( (r
= GetPortFacts(ioc
, 0, sleepFlag
)) != 0 )
3205 printk(MYIOC_s_ERR_FMT
3206 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
3207 ioc
->name
, facts
->MsgLength
, (offsetof(IOCFactsReply_t
,
3208 RequestFrameSize
)/sizeof(u32
)));
3215 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3217 * GetPortFacts - Send PortFacts request to MPT adapter.
3218 * @ioc: Pointer to MPT_ADAPTER structure
3219 * @portnum: Port number
3220 * @sleepFlag: Specifies whether the process can sleep
3222 * Returns 0 for success, non-zero for failure.
3225 GetPortFacts(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
)
3227 PortFacts_t get_pfacts
;
3228 PortFactsReply_t
*pfacts
;
3234 /* IOC *must* NOT be in RESET state! */
3235 if (ioc
->last_state
== MPI_IOC_STATE_RESET
) {
3236 printk(MYIOC_s_ERR_FMT
"Can't get PortFacts NOT READY! (%08x)\n",
3237 ioc
->name
, ioc
->last_state
);
3241 pfacts
= &ioc
->pfacts
[portnum
];
3243 /* Destination (reply area)... */
3244 reply_sz
= sizeof(*pfacts
);
3245 memset(pfacts
, 0, reply_sz
);
3247 /* Request area (get_pfacts on the stack right now!) */
3248 req_sz
= sizeof(get_pfacts
);
3249 memset(&get_pfacts
, 0, req_sz
);
3251 get_pfacts
.Function
= MPI_FUNCTION_PORT_FACTS
;
3252 get_pfacts
.PortNumber
= portnum
;
3253 /* Assert: All other get_pfacts fields are zero! */
3255 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending get PortFacts(%d) request\n",
3256 ioc
->name
, portnum
));
3258 /* No non-zero fields in the get_pfacts request are greater than
3259 * 1 byte in size, so we can just fire it off as is.
3261 ii
= mpt_handshake_req_reply_wait(ioc
, req_sz
, (u32
*)&get_pfacts
,
3262 reply_sz
, (u16
*)pfacts
, 5 /*seconds*/, sleepFlag
);
3266 /* Did we get a valid reply? */
3268 /* Now byte swap the necessary fields in the response. */
3269 pfacts
->MsgContext
= le32_to_cpu(pfacts
->MsgContext
);
3270 pfacts
->IOCStatus
= le16_to_cpu(pfacts
->IOCStatus
);
3271 pfacts
->IOCLogInfo
= le32_to_cpu(pfacts
->IOCLogInfo
);
3272 pfacts
->MaxDevices
= le16_to_cpu(pfacts
->MaxDevices
);
3273 pfacts
->PortSCSIID
= le16_to_cpu(pfacts
->PortSCSIID
);
3274 pfacts
->ProtocolFlags
= le16_to_cpu(pfacts
->ProtocolFlags
);
3275 pfacts
->MaxPostedCmdBuffers
= le16_to_cpu(pfacts
->MaxPostedCmdBuffers
);
3276 pfacts
->MaxPersistentIDs
= le16_to_cpu(pfacts
->MaxPersistentIDs
);
3277 pfacts
->MaxLanBuckets
= le16_to_cpu(pfacts
->MaxLanBuckets
);
3279 max_id
= (ioc
->bus_type
== SAS
) ? pfacts
->PortSCSIID
:
3281 ioc
->devices_per_bus
= (max_id
> 255) ? 256 : max_id
;
3282 ioc
->number_of_buses
= (ioc
->devices_per_bus
< 256) ? 1 : max_id
/256;
3285 * Place all the devices on channels
3289 if (mpt_channel_mapping
) {
3290 ioc
->devices_per_bus
= 1;
3291 ioc
->number_of_buses
= (max_id
> 255) ? 255 : max_id
;
3297 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3299 * SendIocInit - Send IOCInit request to MPT adapter.
3300 * @ioc: Pointer to MPT_ADAPTER structure
3301 * @sleepFlag: Specifies whether the process can sleep
3303 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
3305 * Returns 0 for success, non-zero for failure.
3308 SendIocInit(MPT_ADAPTER
*ioc
, int sleepFlag
)
3311 MPIDefaultReply_t init_reply
;
3317 memset(&ioc_init
, 0, sizeof(ioc_init
));
3318 memset(&init_reply
, 0, sizeof(init_reply
));
3320 ioc_init
.WhoInit
= MPI_WHOINIT_HOST_DRIVER
;
3321 ioc_init
.Function
= MPI_FUNCTION_IOC_INIT
;
3323 /* If we are in a recovery mode and we uploaded the FW image,
3324 * then this pointer is not NULL. Skip the upload a second time.
3325 * Set this flag if cached_fw set for either IOC.
3327 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)
3331 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"upload_fw %d facts.Flags=%x\n",
3332 ioc
->name
, ioc
->upload_fw
, ioc
->facts
.Flags
));
3334 ioc_init
.MaxDevices
= (U8
)ioc
->devices_per_bus
;
3335 ioc_init
.MaxBuses
= (U8
)ioc
->number_of_buses
;
3337 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"facts.MsgVersion=%x\n",
3338 ioc
->name
, ioc
->facts
.MsgVersion
));
3339 if (ioc
->facts
.MsgVersion
>= MPI_VERSION_01_05
) {
3340 // set MsgVersion and HeaderVersion host driver was built with
3341 ioc_init
.MsgVersion
= cpu_to_le16(MPI_VERSION
);
3342 ioc_init
.HeaderVersion
= cpu_to_le16(MPI_HEADER_VERSION
);
3344 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT
) {
3345 ioc_init
.HostPageBufferSGE
= ioc
->facts
.HostPageBufferSGE
;
3346 } else if(mpt_host_page_alloc(ioc
, &ioc_init
))
3349 ioc_init
.ReplyFrameSize
= cpu_to_le16(ioc
->reply_sz
); /* in BYTES */
3351 if (ioc
->sg_addr_size
== sizeof(u64
)) {
3352 /* Save the upper 32-bits of the request
3353 * (reply) and sense buffers.
3355 ioc_init
.HostMfaHighAddr
= cpu_to_le32((u32
)((u64
)ioc
->alloc_dma
>> 32));
3356 ioc_init
.SenseBufferHighAddr
= cpu_to_le32((u32
)((u64
)ioc
->sense_buf_pool_dma
>> 32));
3358 /* Force 32-bit addressing */
3359 ioc_init
.HostMfaHighAddr
= cpu_to_le32(0);
3360 ioc_init
.SenseBufferHighAddr
= cpu_to_le32(0);
3363 ioc
->facts
.CurrentHostMfaHighAddr
= ioc_init
.HostMfaHighAddr
;
3364 ioc
->facts
.CurrentSenseBufferHighAddr
= ioc_init
.SenseBufferHighAddr
;
3365 ioc
->facts
.MaxDevices
= ioc_init
.MaxDevices
;
3366 ioc
->facts
.MaxBuses
= ioc_init
.MaxBuses
;
3368 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending IOCInit (req @ %p)\n",
3369 ioc
->name
, &ioc_init
));
3371 r
= mpt_handshake_req_reply_wait(ioc
, sizeof(IOCInit_t
), (u32
*)&ioc_init
,
3372 sizeof(MPIDefaultReply_t
), (u16
*)&init_reply
, 10 /*seconds*/, sleepFlag
);
3374 printk(MYIOC_s_ERR_FMT
"Sending IOCInit failed(%d)!\n",ioc
->name
, r
);
3378 /* No need to byte swap the multibyte fields in the reply
3379 * since we don't even look at its contents.
3382 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending PortEnable (req @ %p)\n",
3383 ioc
->name
, &ioc_init
));
3385 if ((r
= SendPortEnable(ioc
, 0, sleepFlag
)) != 0) {
3386 printk(MYIOC_s_ERR_FMT
"Sending PortEnable failed(%d)!\n",ioc
->name
, r
);
3390 /* YIKES! SUPER IMPORTANT!!!
3391 * Poll IocState until _OPERATIONAL while IOC is doing
3392 * LoopInit and TargetDiscovery!
3395 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 60; /* 60 seconds */
3396 state
= mpt_GetIocState(ioc
, 1);
3397 while (state
!= MPI_IOC_STATE_OPERATIONAL
&& --cntdn
) {
3398 if (sleepFlag
== CAN_SLEEP
) {
3405 printk(MYIOC_s_ERR_FMT
"Wait IOC_OP state timeout(%d)!\n",
3406 ioc
->name
, (int)((count
+5)/HZ
));
3410 state
= mpt_GetIocState(ioc
, 1);
3413 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Wait IOC_OPERATIONAL state (cnt=%d)\n",
3416 ioc
->aen_event_read_flag
=0;
3420 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3422 * SendPortEnable - Send PortEnable request to MPT adapter port.
3423 * @ioc: Pointer to MPT_ADAPTER structure
3424 * @portnum: Port number to enable
3425 * @sleepFlag: Specifies whether the process can sleep
3427 * Send PortEnable to bring IOC to OPERATIONAL state.
3429 * Returns 0 for success, non-zero for failure.
3432 SendPortEnable(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
)
3434 PortEnable_t port_enable
;
3435 MPIDefaultReply_t reply_buf
;
3440 /* Destination... */
3441 reply_sz
= sizeof(MPIDefaultReply_t
);
3442 memset(&reply_buf
, 0, reply_sz
);
3444 req_sz
= sizeof(PortEnable_t
);
3445 memset(&port_enable
, 0, req_sz
);
3447 port_enable
.Function
= MPI_FUNCTION_PORT_ENABLE
;
3448 port_enable
.PortNumber
= portnum
;
3449 /* port_enable.ChainOffset = 0; */
3450 /* port_enable.MsgFlags = 0; */
3451 /* port_enable.MsgContext = 0; */
3453 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending Port(%d)Enable (req @ %p)\n",
3454 ioc
->name
, portnum
, &port_enable
));
3456 /* RAID FW may take a long time to enable
3458 if (ioc
->ir_firmware
|| ioc
->bus_type
== SAS
) {
3459 rc
= mpt_handshake_req_reply_wait(ioc
, req_sz
,
3460 (u32
*)&port_enable
, reply_sz
, (u16
*)&reply_buf
,
3461 300 /*seconds*/, sleepFlag
);
3463 rc
= mpt_handshake_req_reply_wait(ioc
, req_sz
,
3464 (u32
*)&port_enable
, reply_sz
, (u16
*)&reply_buf
,
3465 30 /*seconds*/, sleepFlag
);
3471 * mpt_alloc_fw_memory - allocate firmware memory
3472 * @ioc: Pointer to MPT_ADAPTER structure
3473 * @size: total FW bytes
3475 * If memory has already been allocated, the same (cached) value
3478 * Return 0 if successful, or non-zero for failure
3481 mpt_alloc_fw_memory(MPT_ADAPTER
*ioc
, int size
)
3485 if (ioc
->cached_fw
) {
3486 rc
= 0; /* use already allocated memory */
3489 else if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
) {
3490 ioc
->cached_fw
= ioc
->alt_ioc
->cached_fw
; /* use alt_ioc's memory */
3491 ioc
->cached_fw_dma
= ioc
->alt_ioc
->cached_fw_dma
;
3495 ioc
->cached_fw
= pci_alloc_consistent(ioc
->pcidev
, size
, &ioc
->cached_fw_dma
);
3496 if (!ioc
->cached_fw
) {
3497 printk(MYIOC_s_ERR_FMT
"Unable to allocate memory for the cached firmware image!\n",
3501 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"FW Image @ %p[%p], sz=%d[%x] bytes\n",
3502 ioc
->name
, ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, size
, size
));
3503 ioc
->alloc_total
+= size
;
3511 * mpt_free_fw_memory - free firmware memory
3512 * @ioc: Pointer to MPT_ADAPTER structure
3514 * If alt_img is NULL, delete from ioc structure.
3515 * Else, delete a secondary image in same format.
3518 mpt_free_fw_memory(MPT_ADAPTER
*ioc
)
3522 if (!ioc
->cached_fw
)
3525 sz
= ioc
->facts
.FWImageSize
;
3526 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3527 ioc
->name
, ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, sz
, sz
));
3528 pci_free_consistent(ioc
->pcidev
, sz
, ioc
->cached_fw
, ioc
->cached_fw_dma
);
3529 ioc
->alloc_total
-= sz
;
3530 ioc
->cached_fw
= NULL
;
3533 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3535 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3536 * @ioc: Pointer to MPT_ADAPTER structure
3537 * @sleepFlag: Specifies whether the process can sleep
3539 * Returns 0 for success, >0 for handshake failure
3540 * <0 for fw upload failure.
3542 * Remark: If bound IOC and a successful FWUpload was performed
3543 * on the bound IOC, the second image is discarded
3544 * and memory is free'd. Both channels must upload to prevent
3545 * IOC from running in degraded mode.
3548 mpt_do_upload(MPT_ADAPTER
*ioc
, int sleepFlag
)
3550 u8 reply
[sizeof(FWUploadReply_t
)];
3551 FWUpload_t
*prequest
;
3552 FWUploadReply_t
*preply
;
3553 FWUploadTCSGE_t
*ptcsge
;
3555 int ii
, sz
, reply_sz
;
3558 /* If the image size is 0, we are done.
3560 if ((sz
= ioc
->facts
.FWImageSize
) == 0)
3563 if (mpt_alloc_fw_memory(ioc
, ioc
->facts
.FWImageSize
) != 0)
3566 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3567 ioc
->name
, ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, sz
, sz
));
3569 prequest
= (sleepFlag
== NO_SLEEP
) ? kzalloc(ioc
->req_sz
, GFP_ATOMIC
) :
3570 kzalloc(ioc
->req_sz
, GFP_KERNEL
);
3572 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"fw upload failed "
3573 "while allocating memory \n", ioc
->name
));
3574 mpt_free_fw_memory(ioc
);
3578 preply
= (FWUploadReply_t
*)&reply
;
3580 reply_sz
= sizeof(reply
);
3581 memset(preply
, 0, reply_sz
);
3583 prequest
->ImageType
= MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM
;
3584 prequest
->Function
= MPI_FUNCTION_FW_UPLOAD
;
3586 ptcsge
= (FWUploadTCSGE_t
*) &prequest
->SGL
;
3587 ptcsge
->DetailsLength
= 12;
3588 ptcsge
->Flags
= MPI_SGE_FLAGS_TRANSACTION_ELEMENT
;
3589 ptcsge
->ImageSize
= cpu_to_le32(sz
);
3592 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_READ
| sz
;
3593 ioc
->add_sge((char *)ptcsge
, flagsLength
, ioc
->cached_fw_dma
);
3594 request_size
= offsetof(FWUpload_t
, SGL
) + sizeof(FWUploadTCSGE_t
) +
3596 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending FW Upload "
3597 " (req @ %p) fw_size=%d mf_request_size=%d\n", ioc
->name
, prequest
,
3598 ioc
->facts
.FWImageSize
, request_size
));
3599 DBG_DUMP_FW_REQUEST_FRAME(ioc
, (u32
*)prequest
);
3601 ii
= mpt_handshake_req_reply_wait(ioc
, request_size
, (u32
*)prequest
,
3602 reply_sz
, (u16
*)preply
, 65 /*seconds*/, sleepFlag
);
3604 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"FW Upload completed "
3605 "rc=%x \n", ioc
->name
, ii
));
3607 cmdStatus
= -EFAULT
;
3609 /* Handshake transfer was complete and successful.
3610 * Check the Reply Frame.
3613 status
= le16_to_cpu(preply
->IOCStatus
) &
3615 if (status
== MPI_IOCSTATUS_SUCCESS
&&
3616 ioc
->facts
.FWImageSize
==
3617 le32_to_cpu(preply
->ActualImageSize
))
3620 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
": do_upload cmdStatus=%d \n",
3621 ioc
->name
, cmdStatus
));
3625 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"fw upload failed, "
3626 "freeing image \n", ioc
->name
));
3627 mpt_free_fw_memory(ioc
);
3634 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3636 * mpt_downloadboot - DownloadBoot code
3637 * @ioc: Pointer to MPT_ADAPTER structure
3638 * @pFwHeader: Pointer to firmware header info
3639 * @sleepFlag: Specifies whether the process can sleep
3641 * FwDownloadBoot requires Programmed IO access.
3643 * Returns 0 for success
3644 * -1 FW Image size is 0
3645 * -2 No valid cached_fw Pointer
3646 * <0 for fw upload failure.
3649 mpt_downloadboot(MPT_ADAPTER
*ioc
, MpiFwHeader_t
*pFwHeader
, int sleepFlag
)
3651 MpiExtImageHeader_t
*pExtImage
;
3661 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3662 ioc
->name
, pFwHeader
->ImageSize
, pFwHeader
->ImageSize
, pFwHeader
));
3664 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3665 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3666 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3667 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3668 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3669 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3671 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, (MPI_DIAG_PREVENT_IOC_BOOT
| MPI_DIAG_DISABLE_ARM
));
3674 if (sleepFlag
== CAN_SLEEP
) {
3680 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3681 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_RESET_ADAPTER
);
3683 for (count
= 0; count
< 30; count
++) {
3684 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3685 if (!(diag0val
& MPI_DIAG_RESET_ADAPTER
)) {
3686 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RESET_ADAPTER cleared, count=%d\n",
3691 if (sleepFlag
== CAN_SLEEP
) {
3698 if ( count
== 30 ) {
3699 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot failed! "
3700 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3701 ioc
->name
, diag0val
));
3705 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3706 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3707 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3708 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3709 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3710 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3712 /* Set the DiagRwEn and Disable ARM bits */
3713 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, (MPI_DIAG_RW_ENABLE
| MPI_DIAG_DISABLE_ARM
));
3715 fwSize
= (pFwHeader
->ImageSize
+ 3)/4;
3716 ptrFw
= (u32
*) pFwHeader
;
3718 /* Write the LoadStartAddress to the DiagRw Address Register
3719 * using Programmed IO
3721 if (ioc
->errata_flag_1064
)
3722 pci_enable_io_access(ioc
->pcidev
);
3724 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, pFwHeader
->LoadStartAddress
);
3725 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"LoadStart addr written 0x%x \n",
3726 ioc
->name
, pFwHeader
->LoadStartAddress
));
3728 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write FW Image: 0x%x bytes @ %p\n",
3729 ioc
->name
, fwSize
*4, ptrFw
));
3731 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, *ptrFw
++);
3734 nextImage
= pFwHeader
->NextImageHeaderOffset
;
3736 pExtImage
= (MpiExtImageHeader_t
*) ((char *)pFwHeader
+ nextImage
);
3738 load_addr
= pExtImage
->LoadStartAddress
;
3740 fwSize
= (pExtImage
->ImageSize
+ 3) >> 2;
3741 ptrFw
= (u32
*)pExtImage
;
3743 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3744 ioc
->name
, fwSize
*4, fwSize
*4, ptrFw
, load_addr
));
3745 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, load_addr
);
3748 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, *ptrFw
++);
3750 nextImage
= pExtImage
->NextImageHeaderOffset
;
3753 /* Write the IopResetVectorRegAddr */
3754 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write IopResetVector Addr=%x! \n", ioc
->name
, pFwHeader
->IopResetRegAddr
));
3755 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, pFwHeader
->IopResetRegAddr
);
3757 /* Write the IopResetVectorValue */
3758 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write IopResetVector Value=%x! \n", ioc
->name
, pFwHeader
->IopResetVectorValue
));
3759 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, pFwHeader
->IopResetVectorValue
);
3761 /* Clear the internal flash bad bit - autoincrementing register,
3762 * so must do two writes.
3764 if (ioc
->bus_type
== SPI
) {
3766 * 1030 and 1035 H/W errata, workaround to access
3767 * the ClearFlashBadSignatureBit
3769 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, 0x3F000000);
3770 diagRwData
= CHIPREG_PIO_READ32(&ioc
->pio_chip
->DiagRwData
);
3771 diagRwData
|= 0x40000000;
3772 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, 0x3F000000);
3773 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, diagRwData
);
3775 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3776 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3777 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
|
3778 MPI_DIAG_CLEAR_FLASH_BAD_SIG
);
3781 if (sleepFlag
== CAN_SLEEP
) {
3788 if (ioc
->errata_flag_1064
)
3789 pci_disable_io_access(ioc
->pcidev
);
3791 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3792 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot diag0val=%x, "
3793 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3794 ioc
->name
, diag0val
));
3795 diag0val
&= ~(MPI_DIAG_PREVENT_IOC_BOOT
| MPI_DIAG_DISABLE_ARM
| MPI_DIAG_RW_ENABLE
);
3796 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot now diag0val=%x\n",
3797 ioc
->name
, diag0val
));
3798 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
);
3800 /* Write 0xFF to reset the sequencer */
3801 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3803 if (ioc
->bus_type
== SAS
) {
3804 ioc_state
= mpt_GetIocState(ioc
, 0);
3805 if ( (GetIocFacts(ioc
, sleepFlag
,
3806 MPT_HOSTEVENT_IOC_BRINGUP
)) != 0 ) {
3807 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"GetIocFacts failed: IocState=%x\n",
3808 ioc
->name
, ioc_state
));
3813 for (count
=0; count
<HZ
*20; count
++) {
3814 if ((ioc_state
= mpt_GetIocState(ioc
, 0)) & MPI_IOC_STATE_READY
) {
3815 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3816 "downloadboot successful! (count=%d) IocState=%x\n",
3817 ioc
->name
, count
, ioc_state
));
3818 if (ioc
->bus_type
== SAS
) {
3821 if ((SendIocInit(ioc
, sleepFlag
)) != 0) {
3822 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3823 "downloadboot: SendIocInit failed\n",
3827 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3828 "downloadboot: SendIocInit successful\n",
3832 if (sleepFlag
== CAN_SLEEP
) {
3838 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3839 "downloadboot failed! IocState=%x\n",ioc
->name
, ioc_state
));
3843 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3845 * KickStart - Perform hard reset of MPT adapter.
3846 * @ioc: Pointer to MPT_ADAPTER structure
3847 * @force: Force hard reset
3848 * @sleepFlag: Specifies whether the process can sleep
3850 * This routine places MPT adapter in diagnostic mode via the
3851 * WriteSequence register, and then performs a hard reset of adapter
3852 * via the Diagnostic register.
3854 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3855 * or NO_SLEEP (interrupt thread, use mdelay)
3856 * force - 1 if doorbell active, board fault state
3857 * board operational, IOC_RECOVERY or
3858 * IOC_BRINGUP and there is an alt_ioc.
3862 * 1 - hard reset, READY
3863 * 0 - no reset due to History bit, READY
3864 * -1 - no reset due to History bit but not READY
3865 * OR reset but failed to come READY
3866 * -2 - no reset, could not enter DIAG mode
3867 * -3 - reset but bad FW bit
3870 KickStart(MPT_ADAPTER
*ioc
, int force
, int sleepFlag
)
3872 int hard_reset_done
= 0;
3876 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"KickStarting!\n", ioc
->name
));
3877 if (ioc
->bus_type
== SPI
) {
3878 /* Always issue a Msg Unit Reset first. This will clear some
3879 * SCSI bus hang conditions.
3881 SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
);
3883 if (sleepFlag
== CAN_SLEEP
) {
3890 hard_reset_done
= mpt_diag_reset(ioc
, force
, sleepFlag
);
3891 if (hard_reset_done
< 0)
3892 return hard_reset_done
;
3894 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Diagnostic reset successful!\n",
3897 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 2; /* 2 seconds */
3898 for (cnt
=0; cnt
<cntdn
; cnt
++) {
3899 ioc_state
= mpt_GetIocState(ioc
, 1);
3900 if ((ioc_state
== MPI_IOC_STATE_READY
) || (ioc_state
== MPI_IOC_STATE_OPERATIONAL
)) {
3901 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"KickStart successful! (cnt=%d)\n",
3903 return hard_reset_done
;
3905 if (sleepFlag
== CAN_SLEEP
) {
3912 dinitprintk(ioc
, printk(MYIOC_s_ERR_FMT
"Failed to come READY after reset! IocState=%x\n",
3913 ioc
->name
, mpt_GetIocState(ioc
, 0)));
3917 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3919 * mpt_diag_reset - Perform hard reset of the adapter.
3920 * @ioc: Pointer to MPT_ADAPTER structure
3921 * @ignore: Set if to honor and clear to ignore
3922 * the reset history bit
3923 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3924 * else set to NO_SLEEP (use mdelay instead)
3926 * This routine places the adapter in diagnostic mode via the
3927 * WriteSequence register and then performs a hard reset of adapter
3928 * via the Diagnostic register. Adapter should be in ready state
3929 * upon successful completion.
3931 * Returns: 1 hard reset successful
3932 * 0 no reset performed because reset history bit set
3933 * -2 enabling diagnostic mode failed
3934 * -3 diagnostic reset failed
3937 mpt_diag_reset(MPT_ADAPTER
*ioc
, int ignore
, int sleepFlag
)
3941 int hard_reset_done
= 0;
3944 MpiFwHeader_t
*cached_fw
; /* Pointer to FW */
3947 /* Clear any existing interrupts */
3948 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
3950 if (ioc
->pcidev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1078
) {
3955 drsprintk(ioc
, printk(MYIOC_s_WARN_FMT
"%s: Doorbell=%p; 1078 reset "
3956 "address=%p\n", ioc
->name
, __func__
,
3957 &ioc
->chip
->Doorbell
, &ioc
->chip
->Reset_1078
));
3958 CHIPREG_WRITE32(&ioc
->chip
->Reset_1078
, 0x07);
3959 if (sleepFlag
== CAN_SLEEP
)
3965 * Call each currently registered protocol IOC reset handler
3966 * with pre-reset indication.
3967 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3968 * MptResetHandlers[] registered yet.
3970 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
3971 if (MptResetHandlers
[cb_idx
])
3972 (*(MptResetHandlers
[cb_idx
]))(ioc
,
3976 for (count
= 0; count
< 60; count
++) {
3977 doorbell
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
3978 doorbell
&= MPI_IOC_STATE_MASK
;
3980 drsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3981 "looking for READY STATE: doorbell=%x"
3983 ioc
->name
, doorbell
, count
));
3985 if (doorbell
== MPI_IOC_STATE_READY
) {
3990 if (sleepFlag
== CAN_SLEEP
)
3998 /* Use "Diagnostic reset" method! (only thing available!) */
3999 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4001 if (ioc
->debug_level
& MPT_DEBUG
) {
4003 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
4004 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG1: diag0=%08x, diag1=%08x\n",
4005 ioc
->name
, diag0val
, diag1val
));
4008 /* Do the reset if we are told to ignore the reset history
4009 * or if the reset history is 0
4011 if (ignore
|| !(diag0val
& MPI_DIAG_RESET_HISTORY
)) {
4012 while ((diag0val
& MPI_DIAG_DRWE
) == 0) {
4013 /* Write magic sequence to WriteSequence register
4014 * Loop until in diagnostic mode
4016 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
4017 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
4018 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
4019 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
4020 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
4021 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
4024 if (sleepFlag
== CAN_SLEEP
) {
4032 printk(MYIOC_s_ERR_FMT
"Enable Diagnostic mode FAILED! (%02xh)\n",
4033 ioc
->name
, diag0val
);
4038 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4040 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Wrote magic DiagWriteEn sequence (%x)\n",
4041 ioc
->name
, diag0val
));
4044 if (ioc
->debug_level
& MPT_DEBUG
) {
4046 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
4047 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG2: diag0=%08x, diag1=%08x\n",
4048 ioc
->name
, diag0val
, diag1val
));
4051 * Disable the ARM (Bug fix)
4054 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_DISABLE_ARM
);
4058 * Now hit the reset bit in the Diagnostic register
4059 * (THE BIG HAMMER!) (Clears DRWE bit).
4061 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_RESET_ADAPTER
);
4062 hard_reset_done
= 1;
4063 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Diagnostic reset performed\n",
4067 * Call each currently registered protocol IOC reset handler
4068 * with pre-reset indication.
4069 * NOTE: If we're doing _IOC_BRINGUP, there can be no
4070 * MptResetHandlers[] registered yet.
4072 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
4073 if (MptResetHandlers
[cb_idx
]) {
4074 mpt_signal_reset(cb_idx
,
4075 ioc
, MPT_IOC_PRE_RESET
);
4077 mpt_signal_reset(cb_idx
,
4078 ioc
->alt_ioc
, MPT_IOC_PRE_RESET
);
4084 cached_fw
= (MpiFwHeader_t
*)ioc
->cached_fw
;
4085 else if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
)
4086 cached_fw
= (MpiFwHeader_t
*)ioc
->alt_ioc
->cached_fw
;
4090 /* If the DownloadBoot operation fails, the
4091 * IOC will be left unusable. This is a fatal error
4092 * case. _diag_reset will return < 0
4094 for (count
= 0; count
< 30; count
++) {
4095 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4096 if (!(diag0val
& MPI_DIAG_RESET_ADAPTER
)) {
4100 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"cached_fw: diag0val=%x count=%d\n",
4101 ioc
->name
, diag0val
, count
));
4103 if (sleepFlag
== CAN_SLEEP
) {
4109 if ((count
= mpt_downloadboot(ioc
, cached_fw
, sleepFlag
)) < 0) {
4110 printk(MYIOC_s_WARN_FMT
4111 "firmware downloadboot failure (%d)!\n", ioc
->name
, count
);
4115 /* Wait for FW to reload and for board
4116 * to go to the READY state.
4117 * Maximum wait is 60 seconds.
4118 * If fail, no error will check again
4119 * with calling program.
4121 for (count
= 0; count
< 60; count
++) {
4122 doorbell
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
4123 doorbell
&= MPI_IOC_STATE_MASK
;
4125 drsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4126 "looking for READY STATE: doorbell=%x"
4127 " count=%d\n", ioc
->name
, doorbell
, count
));
4129 if (doorbell
== MPI_IOC_STATE_READY
) {
4134 if (sleepFlag
== CAN_SLEEP
) {
4141 if (doorbell
!= MPI_IOC_STATE_READY
)
4142 printk(MYIOC_s_ERR_FMT
"Failed to come READY "
4143 "after reset! IocState=%x", ioc
->name
,
4148 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4149 if (ioc
->debug_level
& MPT_DEBUG
) {
4151 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
4152 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG3: diag0=%08x, diag1=%08x\n",
4153 ioc
->name
, diag0val
, diag1val
));
4156 /* Clear RESET_HISTORY bit! Place board in the
4157 * diagnostic mode to update the diag register.
4159 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4161 while ((diag0val
& MPI_DIAG_DRWE
) == 0) {
4162 /* Write magic sequence to WriteSequence register
4163 * Loop until in diagnostic mode
4165 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
4166 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
4167 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
4168 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
4169 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
4170 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
4173 if (sleepFlag
== CAN_SLEEP
) {
4181 printk(MYIOC_s_ERR_FMT
"Enable Diagnostic mode FAILED! (%02xh)\n",
4182 ioc
->name
, diag0val
);
4185 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4187 diag0val
&= ~MPI_DIAG_RESET_HISTORY
;
4188 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
);
4189 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4190 if (diag0val
& MPI_DIAG_RESET_HISTORY
) {
4191 printk(MYIOC_s_WARN_FMT
"ResetHistory bit failed to clear!\n",
4195 /* Disable Diagnostic Mode
4197 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFFFFFFFF);
4199 /* Check FW reload status flags.
4201 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4202 if (diag0val
& (MPI_DIAG_FLASH_BAD_SIG
| MPI_DIAG_RESET_ADAPTER
| MPI_DIAG_DISABLE_ARM
)) {
4203 printk(MYIOC_s_ERR_FMT
"Diagnostic reset FAILED! (%02xh)\n",
4204 ioc
->name
, diag0val
);
4208 if (ioc
->debug_level
& MPT_DEBUG
) {
4210 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
4211 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG4: diag0=%08x, diag1=%08x\n",
4212 ioc
->name
, diag0val
, diag1val
));
4216 * Reset flag that says we've enabled event notification
4218 ioc
->facts
.EventState
= 0;
4221 ioc
->alt_ioc
->facts
.EventState
= 0;
4223 return hard_reset_done
;
4226 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4228 * SendIocReset - Send IOCReset request to MPT adapter.
4229 * @ioc: Pointer to MPT_ADAPTER structure
4230 * @reset_type: reset type, expected values are
4231 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
4232 * @sleepFlag: Specifies whether the process can sleep
4234 * Send IOCReset request to the MPT adapter.
4236 * Returns 0 for success, non-zero for failure.
4239 SendIocReset(MPT_ADAPTER
*ioc
, u8 reset_type
, int sleepFlag
)
4245 drsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending IOC reset(0x%02x)!\n",
4246 ioc
->name
, reset_type
));
4247 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, reset_type
<<MPI_DOORBELL_FUNCTION_SHIFT
);
4248 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
4251 /* FW ACK'd request, wait for READY state
4254 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 15; /* 15 seconds */
4256 while ((state
= mpt_GetIocState(ioc
, 1)) != MPI_IOC_STATE_READY
) {
4260 if (sleepFlag
!= CAN_SLEEP
)
4263 printk(MYIOC_s_ERR_FMT
4264 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
4265 ioc
->name
, state
, (int)((count
+5)/HZ
));
4269 if (sleepFlag
== CAN_SLEEP
) {
4272 mdelay (1); /* 1 msec delay */
4277 * Cleanup all event stuff for this IOC; re-issue EventNotification
4278 * request if needed.
4280 if (ioc
->facts
.Function
)
4281 ioc
->facts
.EventState
= 0;
4286 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4288 * initChainBuffers - Allocate memory for and initialize chain buffers
4289 * @ioc: Pointer to MPT_ADAPTER structure
4291 * Allocates memory for and initializes chain buffers,
4292 * chain buffer control arrays and spinlock.
4295 initChainBuffers(MPT_ADAPTER
*ioc
)
4298 int sz
, ii
, num_chain
;
4299 int scale
, num_sge
, numSGE
;
4301 /* ReqToChain size must equal the req_depth
4304 if (ioc
->ReqToChain
== NULL
) {
4305 sz
= ioc
->req_depth
* sizeof(int);
4306 mem
= kmalloc(sz
, GFP_ATOMIC
);
4310 ioc
->ReqToChain
= (int *) mem
;
4311 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReqToChain alloc @ %p, sz=%d bytes\n",
4312 ioc
->name
, mem
, sz
));
4313 mem
= kmalloc(sz
, GFP_ATOMIC
);
4317 ioc
->RequestNB
= (int *) mem
;
4318 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestNB alloc @ %p, sz=%d bytes\n",
4319 ioc
->name
, mem
, sz
));
4321 for (ii
= 0; ii
< ioc
->req_depth
; ii
++) {
4322 ioc
->ReqToChain
[ii
] = MPT_HOST_NO_CHAIN
;
4325 /* ChainToChain size must equal the total number
4326 * of chain buffers to be allocated.
4329 * Calculate the number of chain buffers needed(plus 1) per I/O
4330 * then multiply the maximum number of simultaneous cmds
4332 * num_sge = num sge in request frame + last chain buffer
4333 * scale = num sge per chain buffer if no chain element
4335 scale
= ioc
->req_sz
/ ioc
->SGE_size
;
4336 if (ioc
->sg_addr_size
== sizeof(u64
))
4337 num_sge
= scale
+ (ioc
->req_sz
- 60) / ioc
->SGE_size
;
4339 num_sge
= 1 + scale
+ (ioc
->req_sz
- 64) / ioc
->SGE_size
;
4341 if (ioc
->sg_addr_size
== sizeof(u64
)) {
4342 numSGE
= (scale
- 1) * (ioc
->facts
.MaxChainDepth
-1) + scale
+
4343 (ioc
->req_sz
- 60) / ioc
->SGE_size
;
4345 numSGE
= 1 + (scale
- 1) * (ioc
->facts
.MaxChainDepth
-1) +
4346 scale
+ (ioc
->req_sz
- 64) / ioc
->SGE_size
;
4348 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"num_sge=%d numSGE=%d\n",
4349 ioc
->name
, num_sge
, numSGE
));
4351 if (ioc
->bus_type
== FC
) {
4352 if (numSGE
> MPT_SCSI_FC_SG_DEPTH
)
4353 numSGE
= MPT_SCSI_FC_SG_DEPTH
;
4355 if (numSGE
> MPT_SCSI_SG_DEPTH
)
4356 numSGE
= MPT_SCSI_SG_DEPTH
;
4360 while (numSGE
- num_sge
> 0) {
4362 num_sge
+= (scale
- 1);
4366 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Now numSGE=%d num_sge=%d num_chain=%d\n",
4367 ioc
->name
, numSGE
, num_sge
, num_chain
));
4369 if (ioc
->bus_type
== SPI
)
4370 num_chain
*= MPT_SCSI_CAN_QUEUE
;
4371 else if (ioc
->bus_type
== SAS
)
4372 num_chain
*= MPT_SAS_CAN_QUEUE
;
4374 num_chain
*= MPT_FC_CAN_QUEUE
;
4376 ioc
->num_chain
= num_chain
;
4378 sz
= num_chain
* sizeof(int);
4379 if (ioc
->ChainToChain
== NULL
) {
4380 mem
= kmalloc(sz
, GFP_ATOMIC
);
4384 ioc
->ChainToChain
= (int *) mem
;
4385 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainToChain alloc @ %p, sz=%d bytes\n",
4386 ioc
->name
, mem
, sz
));
4388 mem
= (u8
*) ioc
->ChainToChain
;
4390 memset(mem
, 0xFF, sz
);
4394 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4396 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
4397 * @ioc: Pointer to MPT_ADAPTER structure
4399 * This routine allocates memory for the MPT reply and request frame
4400 * pools (if necessary), and primes the IOC reply FIFO with
4403 * Returns 0 for success, non-zero for failure.
4406 PrimeIocFifos(MPT_ADAPTER
*ioc
)
4409 unsigned long flags
;
4410 dma_addr_t alloc_dma
;
4412 int i
, reply_sz
, sz
, total_size
, num_chain
;
4417 /* Prime reply FIFO... */
4419 if (ioc
->reply_frames
== NULL
) {
4420 if ( (num_chain
= initChainBuffers(ioc
)) < 0)
4423 * 1078 errata workaround for the 36GB limitation
4425 if (ioc
->pcidev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1078
&&
4426 ioc
->dma_mask
> DMA_BIT_MASK(35)) {
4427 if (!pci_set_dma_mask(ioc
->pcidev
, DMA_BIT_MASK(32))
4428 && !pci_set_consistent_dma_mask(ioc
->pcidev
,
4429 DMA_BIT_MASK(32))) {
4430 dma_mask
= DMA_BIT_MASK(35);
4431 d36memprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4432 "setting 35 bit addressing for "
4433 "Request/Reply/Chain and Sense Buffers\n",
4436 /*Reseting DMA mask to 64 bit*/
4437 pci_set_dma_mask(ioc
->pcidev
,
4439 pci_set_consistent_dma_mask(ioc
->pcidev
,
4442 printk(MYIOC_s_ERR_FMT
4443 "failed setting 35 bit addressing for "
4444 "Request/Reply/Chain and Sense Buffers\n",
4450 total_size
= reply_sz
= (ioc
->reply_sz
* ioc
->reply_depth
);
4451 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
4452 ioc
->name
, ioc
->reply_sz
, ioc
->reply_depth
));
4453 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffer sz=%d[%x] bytes\n",
4454 ioc
->name
, reply_sz
, reply_sz
));
4456 sz
= (ioc
->req_sz
* ioc
->req_depth
);
4457 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestBuffer sz=%d bytes, RequestDepth=%d\n",
4458 ioc
->name
, ioc
->req_sz
, ioc
->req_depth
));
4459 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestBuffer sz=%d[%x] bytes\n",
4460 ioc
->name
, sz
, sz
));
4463 sz
= num_chain
* ioc
->req_sz
; /* chain buffer pool size */
4464 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainBuffer sz=%d bytes, ChainDepth=%d\n",
4465 ioc
->name
, ioc
->req_sz
, num_chain
));
4466 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
4467 ioc
->name
, sz
, sz
, num_chain
));
4470 mem
= pci_alloc_consistent(ioc
->pcidev
, total_size
, &alloc_dma
);
4472 printk(MYIOC_s_ERR_FMT
"Unable to allocate Reply, Request, Chain Buffers!\n",
4477 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Total alloc @ %p[%p], sz=%d[%x] bytes\n",
4478 ioc
->name
, mem
, (void *)(ulong
)alloc_dma
, total_size
, total_size
));
4480 memset(mem
, 0, total_size
);
4481 ioc
->alloc_total
+= total_size
;
4483 ioc
->alloc_dma
= alloc_dma
;
4484 ioc
->alloc_sz
= total_size
;
4485 ioc
->reply_frames
= (MPT_FRAME_HDR
*) mem
;
4486 ioc
->reply_frames_low_dma
= (u32
) (alloc_dma
& 0xFFFFFFFF);
4488 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffers @ %p[%p]\n",
4489 ioc
->name
, ioc
->reply_frames
, (void *)(ulong
)alloc_dma
));
4491 alloc_dma
+= reply_sz
;
4494 /* Request FIFO - WE manage this! */
4496 ioc
->req_frames
= (MPT_FRAME_HDR
*) mem
;
4497 ioc
->req_frames_dma
= alloc_dma
;
4499 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestBuffers @ %p[%p]\n",
4500 ioc
->name
, mem
, (void *)(ulong
)alloc_dma
));
4502 ioc
->req_frames_low_dma
= (u32
) (alloc_dma
& 0xFFFFFFFF);
4504 for (i
= 0; i
< ioc
->req_depth
; i
++) {
4505 alloc_dma
+= ioc
->req_sz
;
4509 ioc
->ChainBuffer
= mem
;
4510 ioc
->ChainBufferDMA
= alloc_dma
;
4512 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainBuffers @ %p(%p)\n",
4513 ioc
->name
, ioc
->ChainBuffer
, (void *)(ulong
)ioc
->ChainBufferDMA
));
4515 /* Initialize the free chain Q.
4518 INIT_LIST_HEAD(&ioc
->FreeChainQ
);
4520 /* Post the chain buffers to the FreeChainQ.
4522 mem
= (u8
*)ioc
->ChainBuffer
;
4523 for (i
=0; i
< num_chain
; i
++) {
4524 mf
= (MPT_FRAME_HDR
*) mem
;
4525 list_add_tail(&mf
->u
.frame
.linkage
.list
, &ioc
->FreeChainQ
);
4529 /* Initialize Request frames linked list
4531 alloc_dma
= ioc
->req_frames_dma
;
4532 mem
= (u8
*) ioc
->req_frames
;
4534 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
4535 INIT_LIST_HEAD(&ioc
->FreeQ
);
4536 for (i
= 0; i
< ioc
->req_depth
; i
++) {
4537 mf
= (MPT_FRAME_HDR
*) mem
;
4539 /* Queue REQUESTs *internally*! */
4540 list_add_tail(&mf
->u
.frame
.linkage
.list
, &ioc
->FreeQ
);
4544 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
4546 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
4547 ioc
->sense_buf_pool
=
4548 pci_alloc_consistent(ioc
->pcidev
, sz
, &ioc
->sense_buf_pool_dma
);
4549 if (ioc
->sense_buf_pool
== NULL
) {
4550 printk(MYIOC_s_ERR_FMT
"Unable to allocate Sense Buffers!\n",
4555 ioc
->sense_buf_low_dma
= (u32
) (ioc
->sense_buf_pool_dma
& 0xFFFFFFFF);
4556 ioc
->alloc_total
+= sz
;
4557 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SenseBuffers @ %p[%p]\n",
4558 ioc
->name
, ioc
->sense_buf_pool
, (void *)(ulong
)ioc
->sense_buf_pool_dma
));
4562 /* Post Reply frames to FIFO
4564 alloc_dma
= ioc
->alloc_dma
;
4565 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffers @ %p[%p]\n",
4566 ioc
->name
, ioc
->reply_frames
, (void *)(ulong
)alloc_dma
));
4568 for (i
= 0; i
< ioc
->reply_depth
; i
++) {
4569 /* Write each address to the IOC! */
4570 CHIPREG_WRITE32(&ioc
->chip
->ReplyFifo
, alloc_dma
);
4571 alloc_dma
+= ioc
->reply_sz
;
4574 if (dma_mask
== DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc
->pcidev
,
4575 ioc
->dma_mask
) && !pci_set_consistent_dma_mask(ioc
->pcidev
,
4577 d36memprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4578 "restoring 64 bit addressing\n", ioc
->name
));
4584 if (ioc
->alloc
!= NULL
) {
4586 pci_free_consistent(ioc
->pcidev
,
4588 ioc
->alloc
, ioc
->alloc_dma
);
4589 ioc
->reply_frames
= NULL
;
4590 ioc
->req_frames
= NULL
;
4591 ioc
->alloc_total
-= sz
;
4593 if (ioc
->sense_buf_pool
!= NULL
) {
4594 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
4595 pci_free_consistent(ioc
->pcidev
,
4597 ioc
->sense_buf_pool
, ioc
->sense_buf_pool_dma
);
4598 ioc
->sense_buf_pool
= NULL
;
4601 if (dma_mask
== DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc
->pcidev
,
4602 DMA_BIT_MASK(64)) && !pci_set_consistent_dma_mask(ioc
->pcidev
,
4604 d36memprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4605 "restoring 64 bit addressing\n", ioc
->name
));
4610 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4612 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4613 * from IOC via doorbell handshake method.
4614 * @ioc: Pointer to MPT_ADAPTER structure
4615 * @reqBytes: Size of the request in bytes
4616 * @req: Pointer to MPT request frame
4617 * @replyBytes: Expected size of the reply in bytes
4618 * @u16reply: Pointer to area where reply should be written
4619 * @maxwait: Max wait time for a reply (in seconds)
4620 * @sleepFlag: Specifies whether the process can sleep
4622 * NOTES: It is the callers responsibility to byte-swap fields in the
4623 * request which are greater than 1 byte in size. It is also the
4624 * callers responsibility to byte-swap response fields which are
4625 * greater than 1 byte in size.
4627 * Returns 0 for success, non-zero for failure.
4630 mpt_handshake_req_reply_wait(MPT_ADAPTER
*ioc
, int reqBytes
, u32
*req
,
4631 int replyBytes
, u16
*u16reply
, int maxwait
, int sleepFlag
)
4633 MPIDefaultReply_t
*mptReply
;
4638 * Get ready to cache a handshake reply
4640 ioc
->hs_reply_idx
= 0;
4641 mptReply
= (MPIDefaultReply_t
*) ioc
->hs_reply
;
4642 mptReply
->MsgLength
= 0;
4645 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4646 * then tell IOC that we want to handshake a request of N words.
4647 * (WRITE u32val to Doorbell reg).
4649 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4650 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
,
4651 ((MPI_FUNCTION_HANDSHAKE
<<MPI_DOORBELL_FUNCTION_SHIFT
) |
4652 ((reqBytes
/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT
)));
4655 * Wait for IOC's doorbell handshake int
4657 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4660 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4661 ioc
->name
, reqBytes
, t
, failcnt
? " - MISSING DOORBELL HANDSHAKE!" : ""));
4663 /* Read doorbell and check for active bit */
4664 if (!(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & MPI_DOORBELL_ACTIVE
))
4668 * Clear doorbell int (WRITE 0 to IntStatus reg),
4669 * then wait for IOC to ACKnowledge that it's ready for
4670 * our handshake request.
4672 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4673 if (!failcnt
&& (t
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
4678 u8
*req_as_bytes
= (u8
*) req
;
4681 * Stuff request words via doorbell handshake,
4682 * with ACK from IOC for each.
4684 for (ii
= 0; !failcnt
&& ii
< reqBytes
/4; ii
++) {
4685 u32 word
= ((req_as_bytes
[(ii
*4) + 0] << 0) |
4686 (req_as_bytes
[(ii
*4) + 1] << 8) |
4687 (req_as_bytes
[(ii
*4) + 2] << 16) |
4688 (req_as_bytes
[(ii
*4) + 3] << 24));
4690 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, word
);
4691 if ((t
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
4695 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Handshake request frame (@%p) header\n", ioc
->name
, req
));
4696 DBG_DUMP_REQUEST_FRAME_HDR(ioc
, (u32
*)req
);
4698 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HandShake request post done, WaitCnt=%d%s\n",
4699 ioc
->name
, t
, failcnt
? " - MISSING DOORBELL ACK!" : ""));
4702 * Wait for completion of doorbell handshake reply from the IOC
4704 if (!failcnt
&& (t
= WaitForDoorbellReply(ioc
, maxwait
, sleepFlag
)) < 0)
4707 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HandShake reply count=%d%s\n",
4708 ioc
->name
, t
, failcnt
? " - MISSING DOORBELL REPLY!" : ""));
4711 * Copy out the cached reply...
4713 for (ii
=0; ii
< min(replyBytes
/2,mptReply
->MsgLength
*2); ii
++)
4714 u16reply
[ii
] = ioc
->hs_reply
[ii
];
4722 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4724 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4725 * @ioc: Pointer to MPT_ADAPTER structure
4726 * @howlong: How long to wait (in seconds)
4727 * @sleepFlag: Specifies whether the process can sleep
4729 * This routine waits (up to ~2 seconds max) for IOC doorbell
4730 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4731 * bit in its IntStatus register being clear.
4733 * Returns a negative value on failure, else wait loop count.
4736 WaitForDoorbellAck(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
4742 cntdn
= 1000 * howlong
;
4744 if (sleepFlag
== CAN_SLEEP
) {
4747 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4748 if (! (intstat
& MPI_HIS_IOP_DOORBELL_STATUS
))
4755 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4756 if (! (intstat
& MPI_HIS_IOP_DOORBELL_STATUS
))
4763 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitForDoorbell ACK (count=%d)\n",
4768 printk(MYIOC_s_ERR_FMT
"Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4769 ioc
->name
, count
, intstat
);
4773 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4775 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4776 * @ioc: Pointer to MPT_ADAPTER structure
4777 * @howlong: How long to wait (in seconds)
4778 * @sleepFlag: Specifies whether the process can sleep
4780 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4781 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4783 * Returns a negative value on failure, else wait loop count.
4786 WaitForDoorbellInt(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
4792 cntdn
= 1000 * howlong
;
4793 if (sleepFlag
== CAN_SLEEP
) {
4795 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4796 if (intstat
& MPI_HIS_DOORBELL_INTERRUPT
)
4803 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4804 if (intstat
& MPI_HIS_DOORBELL_INTERRUPT
)
4812 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4813 ioc
->name
, count
, howlong
));
4817 printk(MYIOC_s_ERR_FMT
"Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4818 ioc
->name
, count
, intstat
);
4822 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4824 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4825 * @ioc: Pointer to MPT_ADAPTER structure
4826 * @howlong: How long to wait (in seconds)
4827 * @sleepFlag: Specifies whether the process can sleep
4829 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4830 * Reply is cached to IOC private area large enough to hold a maximum
4831 * of 128 bytes of reply data.
4833 * Returns a negative value on failure, else size of reply in WORDS.
4836 WaitForDoorbellReply(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
4841 u16
*hs_reply
= ioc
->hs_reply
;
4842 volatile MPIDefaultReply_t
*mptReply
= (MPIDefaultReply_t
*) ioc
->hs_reply
;
4845 hs_reply
[0] = hs_reply
[1] = hs_reply
[7] = 0;
4848 * Get first two u16's so we can look at IOC's intended reply MsgLength
4851 if ((t
= WaitForDoorbellInt(ioc
, howlong
, sleepFlag
)) < 0) {
4854 hs_reply
[u16cnt
++] = le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4855 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4856 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4859 hs_reply
[u16cnt
++] = le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4860 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4864 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitCnt=%d First handshake reply word=%08x%s\n",
4865 ioc
->name
, t
, le32_to_cpu(*(u32
*)hs_reply
),
4866 failcnt
? " - MISSING DOORBELL HANDSHAKE!" : ""));
4869 * If no error (and IOC said MsgLength is > 0), piece together
4870 * reply 16 bits at a time.
4872 for (u16cnt
=2; !failcnt
&& u16cnt
< (2 * mptReply
->MsgLength
); u16cnt
++) {
4873 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4875 hword
= le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4876 /* don't overflow our IOC hs_reply[] buffer! */
4877 if (u16cnt
< ARRAY_SIZE(ioc
->hs_reply
))
4878 hs_reply
[u16cnt
] = hword
;
4879 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4882 if (!failcnt
&& (t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4884 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4887 printk(MYIOC_s_ERR_FMT
"Handshake reply failure!\n",
4892 else if (u16cnt
!= (2 * mptReply
->MsgLength
)) {
4895 else if ((mptReply
->IOCStatus
& MPI_IOCSTATUS_MASK
) != MPI_IOCSTATUS_SUCCESS
) {
4900 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Got Handshake reply:\n", ioc
->name
));
4901 DBG_DUMP_REPLY_FRAME(ioc
, (u32
*)mptReply
);
4903 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4904 ioc
->name
, t
, u16cnt
/2));
4908 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4910 * GetLanConfigPages - Fetch LANConfig pages.
4911 * @ioc: Pointer to MPT_ADAPTER structure
4913 * Return: 0 for success
4914 * -ENOMEM if no memory available
4915 * -EPERM if not allowed due to ISR context
4916 * -EAGAIN if no msg frames currently available
4917 * -EFAULT for non-successful reply or no reply (timeout)
4920 GetLanConfigPages(MPT_ADAPTER
*ioc
)
4922 ConfigPageHeader_t hdr
;
4924 LANPage0_t
*ppage0_alloc
;
4925 dma_addr_t page0_dma
;
4926 LANPage1_t
*ppage1_alloc
;
4927 dma_addr_t page1_dma
;
4932 /* Get LAN Page 0 header */
4933 hdr
.PageVersion
= 0;
4936 hdr
.PageType
= MPI_CONFIG_PAGETYPE_LAN
;
4937 cfg
.cfghdr
.hdr
= &hdr
;
4939 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4944 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
4947 if (hdr
.PageLength
> 0) {
4948 data_sz
= hdr
.PageLength
* 4;
4949 ppage0_alloc
= (LANPage0_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page0_dma
);
4952 memset((u8
*)ppage0_alloc
, 0, data_sz
);
4953 cfg
.physAddr
= page0_dma
;
4954 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4956 if ((rc
= mpt_config(ioc
, &cfg
)) == 0) {
4958 copy_sz
= min_t(int, sizeof(LANPage0_t
), data_sz
);
4959 memcpy(&ioc
->lan_cnfg_page0
, ppage0_alloc
, copy_sz
);
4963 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage0_alloc
, page0_dma
);
4966 * Normalize endianness of structure data,
4967 * by byte-swapping all > 1 byte fields!
4976 /* Get LAN Page 1 header */
4977 hdr
.PageVersion
= 0;
4980 hdr
.PageType
= MPI_CONFIG_PAGETYPE_LAN
;
4981 cfg
.cfghdr
.hdr
= &hdr
;
4983 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4987 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
4990 if (hdr
.PageLength
== 0)
4993 data_sz
= hdr
.PageLength
* 4;
4995 ppage1_alloc
= (LANPage1_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page1_dma
);
4997 memset((u8
*)ppage1_alloc
, 0, data_sz
);
4998 cfg
.physAddr
= page1_dma
;
4999 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5001 if ((rc
= mpt_config(ioc
, &cfg
)) == 0) {
5003 copy_sz
= min_t(int, sizeof(LANPage1_t
), data_sz
);
5004 memcpy(&ioc
->lan_cnfg_page1
, ppage1_alloc
, copy_sz
);
5007 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage1_alloc
, page1_dma
);
5010 * Normalize endianness of structure data,
5011 * by byte-swapping all > 1 byte fields!
5019 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5021 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
5022 * @ioc: Pointer to MPT_ADAPTER structure
5023 * @persist_opcode: see below
5025 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
5026 * devices not currently present.
5027 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
5029 * NOTE: Don't use not this function during interrupt time.
5031 * Returns 0 for success, non-zero error
5034 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5036 mptbase_sas_persist_operation(MPT_ADAPTER
*ioc
, u8 persist_opcode
)
5038 SasIoUnitControlRequest_t
*sasIoUnitCntrReq
;
5039 SasIoUnitControlReply_t
*sasIoUnitCntrReply
;
5040 MPT_FRAME_HDR
*mf
= NULL
;
5041 MPIHeader_t
*mpi_hdr
;
5043 unsigned long timeleft
;
5045 mutex_lock(&ioc
->mptbase_cmds
.mutex
);
5047 /* init the internal cmd struct */
5048 memset(ioc
->mptbase_cmds
.reply
, 0 , MPT_DEFAULT_FRAME_SIZE
);
5049 INITIALIZE_MGMT_STATUS(ioc
->mptbase_cmds
.status
)
5051 /* insure garbage is not sent to fw */
5052 switch(persist_opcode
) {
5054 case MPI_SAS_OP_CLEAR_NOT_PRESENT
:
5055 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT
:
5063 printk(KERN_DEBUG
"%s: persist_opcode=%x\n",
5064 __func__
, persist_opcode
);
5066 /* Get a MF for this command.
5068 if ((mf
= mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
5069 printk(KERN_DEBUG
"%s: no msg frames!\n", __func__
);
5074 mpi_hdr
= (MPIHeader_t
*) mf
;
5075 sasIoUnitCntrReq
= (SasIoUnitControlRequest_t
*)mf
;
5076 memset(sasIoUnitCntrReq
,0,sizeof(SasIoUnitControlRequest_t
));
5077 sasIoUnitCntrReq
->Function
= MPI_FUNCTION_SAS_IO_UNIT_CONTROL
;
5078 sasIoUnitCntrReq
->MsgContext
= mpi_hdr
->MsgContext
;
5079 sasIoUnitCntrReq
->Operation
= persist_opcode
;
5081 mpt_put_msg_frame(mpt_base_index
, ioc
, mf
);
5082 timeleft
= wait_for_completion_timeout(&ioc
->mptbase_cmds
.done
, 10*HZ
);
5083 if (!(ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_COMMAND_GOOD
)) {
5085 printk(KERN_DEBUG
"%s: failed\n", __func__
);
5086 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_DID_IOCRESET
)
5089 printk(MYIOC_s_WARN_FMT
5090 "Issuing Reset from %s!!, doorbell=0x%08x\n",
5091 ioc
->name
, __func__
, mpt_GetIocState(ioc
, 0));
5092 mpt_Soft_Hard_ResetHandler(ioc
, CAN_SLEEP
);
5093 mpt_free_msg_frame(ioc
, mf
);
5098 if (!(ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_RF_VALID
)) {
5103 sasIoUnitCntrReply
=
5104 (SasIoUnitControlReply_t
*)ioc
->mptbase_cmds
.reply
;
5105 if (le16_to_cpu(sasIoUnitCntrReply
->IOCStatus
) != MPI_IOCSTATUS_SUCCESS
) {
5106 printk(KERN_DEBUG
"%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
5107 __func__
, sasIoUnitCntrReply
->IOCStatus
,
5108 sasIoUnitCntrReply
->IOCLogInfo
);
5109 printk(KERN_DEBUG
"%s: failed\n", __func__
);
5112 printk(KERN_DEBUG
"%s: success\n", __func__
);
5115 CLEAR_MGMT_STATUS(ioc
->mptbase_cmds
.status
)
5116 mutex_unlock(&ioc
->mptbase_cmds
.mutex
);
5120 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5123 mptbase_raid_process_event_data(MPT_ADAPTER
*ioc
,
5124 MpiEventDataRaid_t
* pRaidEventData
)
5133 volume
= pRaidEventData
->VolumeID
;
5134 reason
= pRaidEventData
->ReasonCode
;
5135 disk
= pRaidEventData
->PhysDiskNum
;
5136 status
= le32_to_cpu(pRaidEventData
->SettingsStatus
);
5137 flags
= (status
>> 0) & 0xff;
5138 state
= (status
>> 8) & 0xff;
5140 if (reason
== MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
) {
5144 if ((reason
>= MPI_EVENT_RAID_RC_PHYSDISK_CREATED
&&
5145 reason
<= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
) ||
5146 (reason
== MPI_EVENT_RAID_RC_SMART_DATA
)) {
5147 printk(MYIOC_s_INFO_FMT
"RAID STATUS CHANGE for PhysDisk %d id=%d\n",
5148 ioc
->name
, disk
, volume
);
5150 printk(MYIOC_s_INFO_FMT
"RAID STATUS CHANGE for VolumeID %d\n",
5155 case MPI_EVENT_RAID_RC_VOLUME_CREATED
:
5156 printk(MYIOC_s_INFO_FMT
" volume has been created\n",
5160 case MPI_EVENT_RAID_RC_VOLUME_DELETED
:
5162 printk(MYIOC_s_INFO_FMT
" volume has been deleted\n",
5166 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED
:
5167 printk(MYIOC_s_INFO_FMT
" volume settings have been changed\n",
5171 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED
:
5172 printk(MYIOC_s_INFO_FMT
" volume is now %s%s%s%s\n",
5174 state
== MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
5176 : state
== MPI_RAIDVOL0_STATUS_STATE_DEGRADED
5178 : state
== MPI_RAIDVOL0_STATUS_STATE_FAILED
5181 flags
& MPI_RAIDVOL0_STATUS_FLAG_ENABLED
5183 flags
& MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
5184 ? ", quiesced" : "",
5185 flags
& MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
5186 ? ", resync in progress" : "" );
5189 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED
:
5190 printk(MYIOC_s_INFO_FMT
" volume membership of PhysDisk %d has changed\n",
5194 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED
:
5195 printk(MYIOC_s_INFO_FMT
" PhysDisk has been created\n",
5199 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED
:
5200 printk(MYIOC_s_INFO_FMT
" PhysDisk has been deleted\n",
5204 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED
:
5205 printk(MYIOC_s_INFO_FMT
" PhysDisk settings have been changed\n",
5209 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
:
5210 printk(MYIOC_s_INFO_FMT
" PhysDisk is now %s%s%s\n",
5212 state
== MPI_PHYSDISK0_STATUS_ONLINE
5214 : state
== MPI_PHYSDISK0_STATUS_MISSING
5216 : state
== MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
5218 : state
== MPI_PHYSDISK0_STATUS_FAILED
5220 : state
== MPI_PHYSDISK0_STATUS_INITIALIZING
5222 : state
== MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
5223 ? "offline requested"
5224 : state
== MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
5225 ? "failed requested"
5226 : state
== MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
5229 flags
& MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
5230 ? ", out of sync" : "",
5231 flags
& MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
5232 ? ", quiesced" : "" );
5235 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
:
5236 printk(MYIOC_s_INFO_FMT
" Domain Validation needed for PhysDisk %d\n",
5240 case MPI_EVENT_RAID_RC_SMART_DATA
:
5241 printk(MYIOC_s_INFO_FMT
" SMART data received, ASC/ASCQ = %02xh/%02xh\n",
5242 ioc
->name
, pRaidEventData
->ASC
, pRaidEventData
->ASCQ
);
5245 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED
:
5246 printk(MYIOC_s_INFO_FMT
" replacement of PhysDisk %d has started\n",
5252 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5254 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
5255 * @ioc: Pointer to MPT_ADAPTER structure
5257 * Returns: 0 for success
5258 * -ENOMEM if no memory available
5259 * -EPERM if not allowed due to ISR context
5260 * -EAGAIN if no msg frames currently available
5261 * -EFAULT for non-successful reply or no reply (timeout)
5264 GetIoUnitPage2(MPT_ADAPTER
*ioc
)
5266 ConfigPageHeader_t hdr
;
5268 IOUnitPage2_t
*ppage_alloc
;
5269 dma_addr_t page_dma
;
5273 /* Get the page header */
5274 hdr
.PageVersion
= 0;
5277 hdr
.PageType
= MPI_CONFIG_PAGETYPE_IO_UNIT
;
5278 cfg
.cfghdr
.hdr
= &hdr
;
5280 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5285 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
5288 if (hdr
.PageLength
== 0)
5291 /* Read the config page */
5292 data_sz
= hdr
.PageLength
* 4;
5294 ppage_alloc
= (IOUnitPage2_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page_dma
);
5296 memset((u8
*)ppage_alloc
, 0, data_sz
);
5297 cfg
.physAddr
= page_dma
;
5298 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5300 /* If Good, save data */
5301 if ((rc
= mpt_config(ioc
, &cfg
)) == 0)
5302 ioc
->biosVersion
= le32_to_cpu(ppage_alloc
->BiosVersion
);
5304 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage_alloc
, page_dma
);
5310 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5312 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
5313 * @ioc: Pointer to a Adapter Strucutre
5314 * @portnum: IOC port number
5316 * Return: -EFAULT if read of config page header fails
5318 * If read of SCSI Port Page 0 fails,
5319 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5320 * Adapter settings: async, narrow
5322 * If read of SCSI Port Page 2 fails,
5323 * Adapter settings valid
5324 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5329 * CHECK - what type of locking mechanisms should be used????
5332 mpt_GetScsiPortSettings(MPT_ADAPTER
*ioc
, int portnum
)
5337 ConfigPageHeader_t header
;
5343 if (!ioc
->spi_data
.nvram
) {
5346 sz
= MPT_MAX_SCSI_DEVICES
* sizeof(int);
5347 mem
= kmalloc(sz
, GFP_ATOMIC
);
5351 ioc
->spi_data
.nvram
= (int *) mem
;
5353 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SCSI device NVRAM settings @ %p, sz=%d\n",
5354 ioc
->name
, ioc
->spi_data
.nvram
, sz
));
5357 /* Invalidate NVRAM information
5359 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
5360 ioc
->spi_data
.nvram
[ii
] = MPT_HOST_NVRAM_INVALID
;
5363 /* Read SPP0 header, allocate memory, then read page.
5365 header
.PageVersion
= 0;
5366 header
.PageLength
= 0;
5367 header
.PageNumber
= 0;
5368 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_PORT
;
5369 cfg
.cfghdr
.hdr
= &header
;
5371 cfg
.pageAddr
= portnum
;
5372 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5374 cfg
.timeout
= 0; /* use default */
5375 if (mpt_config(ioc
, &cfg
) != 0)
5378 if (header
.PageLength
> 0) {
5379 pbuf
= pci_alloc_consistent(ioc
->pcidev
, header
.PageLength
* 4, &buf_dma
);
5381 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5382 cfg
.physAddr
= buf_dma
;
5383 if (mpt_config(ioc
, &cfg
) != 0) {
5384 ioc
->spi_data
.maxBusWidth
= MPT_NARROW
;
5385 ioc
->spi_data
.maxSyncOffset
= 0;
5386 ioc
->spi_data
.minSyncFactor
= MPT_ASYNC
;
5387 ioc
->spi_data
.busType
= MPT_HOST_BUS_UNKNOWN
;
5389 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5390 "Unable to read PortPage0 minSyncFactor=%x\n",
5391 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
5393 /* Save the Port Page 0 data
5395 SCSIPortPage0_t
*pPP0
= (SCSIPortPage0_t
*) pbuf
;
5396 pPP0
->Capabilities
= le32_to_cpu(pPP0
->Capabilities
);
5397 pPP0
->PhysicalInterface
= le32_to_cpu(pPP0
->PhysicalInterface
);
5399 if ( (pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_QAS
) == 0 ) {
5400 ioc
->spi_data
.noQas
|= MPT_TARGET_NO_NEGO_QAS
;
5401 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5402 "noQas due to Capabilities=%x\n",
5403 ioc
->name
, pPP0
->Capabilities
));
5405 ioc
->spi_data
.maxBusWidth
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_WIDE
? 1 : 0;
5406 data
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK
;
5408 ioc
->spi_data
.maxSyncOffset
= (u8
) (data
>> 16);
5409 data
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK
;
5410 ioc
->spi_data
.minSyncFactor
= (u8
) (data
>> 8);
5411 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5412 "PortPage0 minSyncFactor=%x\n",
5413 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
5415 ioc
->spi_data
.maxSyncOffset
= 0;
5416 ioc
->spi_data
.minSyncFactor
= MPT_ASYNC
;
5419 ioc
->spi_data
.busType
= pPP0
->PhysicalInterface
& MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK
;
5421 /* Update the minSyncFactor based on bus type.
5423 if ((ioc
->spi_data
.busType
== MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD
) ||
5424 (ioc
->spi_data
.busType
== MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE
)) {
5426 if (ioc
->spi_data
.minSyncFactor
< MPT_ULTRA
) {
5427 ioc
->spi_data
.minSyncFactor
= MPT_ULTRA
;
5428 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5429 "HVD or SE detected, minSyncFactor=%x\n",
5430 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
5435 pci_free_consistent(ioc
->pcidev
, header
.PageLength
* 4, pbuf
, buf_dma
);
5440 /* SCSI Port Page 2 - Read the header then the page.
5442 header
.PageVersion
= 0;
5443 header
.PageLength
= 0;
5444 header
.PageNumber
= 2;
5445 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_PORT
;
5446 cfg
.cfghdr
.hdr
= &header
;
5448 cfg
.pageAddr
= portnum
;
5449 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5451 if (mpt_config(ioc
, &cfg
) != 0)
5454 if (header
.PageLength
> 0) {
5455 /* Allocate memory and read SCSI Port Page 2
5457 pbuf
= pci_alloc_consistent(ioc
->pcidev
, header
.PageLength
* 4, &buf_dma
);
5459 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_NVRAM
;
5460 cfg
.physAddr
= buf_dma
;
5461 if (mpt_config(ioc
, &cfg
) != 0) {
5462 /* Nvram data is left with INVALID mark
5465 } else if (ioc
->pcidev
->vendor
== PCI_VENDOR_ID_ATTO
) {
5467 /* This is an ATTO adapter, read Page2 accordingly
5469 ATTO_SCSIPortPage2_t
*pPP2
= (ATTO_SCSIPortPage2_t
*) pbuf
;
5470 ATTODeviceInfo_t
*pdevice
= NULL
;
5473 /* Save the Port Page 2 data
5474 * (reformat into a 32bit quantity)
5476 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
5477 pdevice
= &pPP2
->DeviceSettings
[ii
];
5478 ATTOFlags
= le16_to_cpu(pdevice
->ATTOFlags
);
5481 /* Translate ATTO device flags to LSI format
5483 if (ATTOFlags
& ATTOFLAG_DISC
)
5484 data
|= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE
);
5485 if (ATTOFlags
& ATTOFLAG_ID_ENB
)
5486 data
|= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE
);
5487 if (ATTOFlags
& ATTOFLAG_LUN_ENB
)
5488 data
|= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE
);
5489 if (ATTOFlags
& ATTOFLAG_TAGGED
)
5490 data
|= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE
);
5491 if (!(ATTOFlags
& ATTOFLAG_WIDE_ENB
))
5492 data
|= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE
);
5494 data
= (data
<< 16) | (pdevice
->Period
<< 8) | 10;
5495 ioc
->spi_data
.nvram
[ii
] = data
;
5498 SCSIPortPage2_t
*pPP2
= (SCSIPortPage2_t
*) pbuf
;
5499 MpiDeviceInfo_t
*pdevice
= NULL
;
5502 * Save "Set to Avoid SCSI Bus Resets" flag
5504 ioc
->spi_data
.bus_reset
=
5505 (le32_to_cpu(pPP2
->PortFlags
) &
5506 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET
) ?
5509 /* Save the Port Page 2 data
5510 * (reformat into a 32bit quantity)
5512 data
= le32_to_cpu(pPP2
->PortFlags
) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK
;
5513 ioc
->spi_data
.PortFlags
= data
;
5514 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
5515 pdevice
= &pPP2
->DeviceSettings
[ii
];
5516 data
= (le16_to_cpu(pdevice
->DeviceFlags
) << 16) |
5517 (pdevice
->SyncFactor
<< 8) | pdevice
->Timeout
;
5518 ioc
->spi_data
.nvram
[ii
] = data
;
5522 pci_free_consistent(ioc
->pcidev
, header
.PageLength
* 4, pbuf
, buf_dma
);
5526 /* Update Adapter limits with those from NVRAM
5527 * Comment: Don't need to do this. Target performance
5528 * parameters will never exceed the adapters limits.
5534 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5536 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
5537 * @ioc: Pointer to a Adapter Strucutre
5538 * @portnum: IOC port number
5540 * Return: -EFAULT if read of config page header fails
5544 mpt_readScsiDevicePageHeaders(MPT_ADAPTER
*ioc
, int portnum
)
5547 ConfigPageHeader_t header
;
5549 /* Read the SCSI Device Page 1 header
5551 header
.PageVersion
= 0;
5552 header
.PageLength
= 0;
5553 header
.PageNumber
= 1;
5554 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_DEVICE
;
5555 cfg
.cfghdr
.hdr
= &header
;
5557 cfg
.pageAddr
= portnum
;
5558 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5561 if (mpt_config(ioc
, &cfg
) != 0)
5564 ioc
->spi_data
.sdp1version
= cfg
.cfghdr
.hdr
->PageVersion
;
5565 ioc
->spi_data
.sdp1length
= cfg
.cfghdr
.hdr
->PageLength
;
5567 header
.PageVersion
= 0;
5568 header
.PageLength
= 0;
5569 header
.PageNumber
= 0;
5570 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_DEVICE
;
5571 if (mpt_config(ioc
, &cfg
) != 0)
5574 ioc
->spi_data
.sdp0version
= cfg
.cfghdr
.hdr
->PageVersion
;
5575 ioc
->spi_data
.sdp0length
= cfg
.cfghdr
.hdr
->PageLength
;
5577 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Headers: 0: version %d length %d\n",
5578 ioc
->name
, ioc
->spi_data
.sdp0version
, ioc
->spi_data
.sdp0length
));
5580 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Headers: 1: version %d length %d\n",
5581 ioc
->name
, ioc
->spi_data
.sdp1version
, ioc
->spi_data
.sdp1length
));
5586 * mpt_inactive_raid_list_free - This clears this link list.
5587 * @ioc : pointer to per adapter structure
5590 mpt_inactive_raid_list_free(MPT_ADAPTER
*ioc
)
5592 struct inactive_raid_component_info
*component_info
, *pNext
;
5594 if (list_empty(&ioc
->raid_data
.inactive_list
))
5597 mutex_lock(&ioc
->raid_data
.inactive_list_mutex
);
5598 list_for_each_entry_safe(component_info
, pNext
,
5599 &ioc
->raid_data
.inactive_list
, list
) {
5600 list_del(&component_info
->list
);
5601 kfree(component_info
);
5603 mutex_unlock(&ioc
->raid_data
.inactive_list_mutex
);
5607 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5609 * @ioc : pointer to per adapter structure
5610 * @channel : volume channel
5611 * @id : volume target id
5614 mpt_inactive_raid_volumes(MPT_ADAPTER
*ioc
, u8 channel
, u8 id
)
5617 ConfigPageHeader_t hdr
;
5618 dma_addr_t dma_handle
;
5619 pRaidVolumePage0_t buffer
= NULL
;
5621 RaidPhysDiskPage0_t phys_disk
;
5622 struct inactive_raid_component_info
*component_info
;
5623 int handle_inactive_volumes
;
5625 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5626 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5627 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_VOLUME
;
5628 cfg
.pageAddr
= (channel
<< 8) + id
;
5629 cfg
.cfghdr
.hdr
= &hdr
;
5630 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5632 if (mpt_config(ioc
, &cfg
) != 0)
5635 if (!hdr
.PageLength
)
5638 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5644 cfg
.physAddr
= dma_handle
;
5645 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5647 if (mpt_config(ioc
, &cfg
) != 0)
5650 if (!buffer
->NumPhysDisks
)
5653 handle_inactive_volumes
=
5654 (buffer
->VolumeStatus
.Flags
& MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE
||
5655 (buffer
->VolumeStatus
.Flags
& MPI_RAIDVOL0_STATUS_FLAG_ENABLED
) == 0 ||
5656 buffer
->VolumeStatus
.State
== MPI_RAIDVOL0_STATUS_STATE_FAILED
||
5657 buffer
->VolumeStatus
.State
== MPI_RAIDVOL0_STATUS_STATE_MISSING
) ? 1 : 0;
5659 if (!handle_inactive_volumes
)
5662 mutex_lock(&ioc
->raid_data
.inactive_list_mutex
);
5663 for (i
= 0; i
< buffer
->NumPhysDisks
; i
++) {
5664 if(mpt_raid_phys_disk_pg0(ioc
,
5665 buffer
->PhysDisk
[i
].PhysDiskNum
, &phys_disk
) != 0)
5668 if ((component_info
= kmalloc(sizeof (*component_info
),
5669 GFP_KERNEL
)) == NULL
)
5672 component_info
->volumeID
= id
;
5673 component_info
->volumeBus
= channel
;
5674 component_info
->d
.PhysDiskNum
= phys_disk
.PhysDiskNum
;
5675 component_info
->d
.PhysDiskBus
= phys_disk
.PhysDiskBus
;
5676 component_info
->d
.PhysDiskID
= phys_disk
.PhysDiskID
;
5677 component_info
->d
.PhysDiskIOC
= phys_disk
.PhysDiskIOC
;
5679 list_add_tail(&component_info
->list
,
5680 &ioc
->raid_data
.inactive_list
);
5682 mutex_unlock(&ioc
->raid_data
.inactive_list_mutex
);
5686 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5691 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5692 * @ioc: Pointer to a Adapter Structure
5693 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5694 * @phys_disk: requested payload data returned
5698 * -EFAULT if read of config page header fails or data pointer not NULL
5699 * -ENOMEM if pci_alloc failed
5702 mpt_raid_phys_disk_pg0(MPT_ADAPTER
*ioc
, u8 phys_disk_num
,
5703 RaidPhysDiskPage0_t
*phys_disk
)
5706 ConfigPageHeader_t hdr
;
5707 dma_addr_t dma_handle
;
5708 pRaidPhysDiskPage0_t buffer
= NULL
;
5711 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5712 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5713 memset(phys_disk
, 0, sizeof(RaidPhysDiskPage0_t
));
5715 hdr
.PageVersion
= MPI_RAIDPHYSDISKPAGE0_PAGEVERSION
;
5716 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_PHYSDISK
;
5717 cfg
.cfghdr
.hdr
= &hdr
;
5719 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5721 if (mpt_config(ioc
, &cfg
) != 0) {
5726 if (!hdr
.PageLength
) {
5731 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5739 cfg
.physAddr
= dma_handle
;
5740 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5741 cfg
.pageAddr
= phys_disk_num
;
5743 if (mpt_config(ioc
, &cfg
) != 0) {
5749 memcpy(phys_disk
, buffer
, sizeof(*buffer
));
5750 phys_disk
->MaxLBA
= le32_to_cpu(buffer
->MaxLBA
);
5755 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5762 * mpt_raid_phys_disk_get_num_paths - returns number paths associated to this phys_num
5763 * @ioc: Pointer to a Adapter Structure
5764 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5767 * returns number paths
5770 mpt_raid_phys_disk_get_num_paths(MPT_ADAPTER
*ioc
, u8 phys_disk_num
)
5773 ConfigPageHeader_t hdr
;
5774 dma_addr_t dma_handle
;
5775 pRaidPhysDiskPage1_t buffer
= NULL
;
5778 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5779 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5781 hdr
.PageVersion
= MPI_RAIDPHYSDISKPAGE1_PAGEVERSION
;
5782 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_PHYSDISK
;
5784 cfg
.cfghdr
.hdr
= &hdr
;
5786 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5788 if (mpt_config(ioc
, &cfg
) != 0) {
5793 if (!hdr
.PageLength
) {
5798 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5806 cfg
.physAddr
= dma_handle
;
5807 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5808 cfg
.pageAddr
= phys_disk_num
;
5810 if (mpt_config(ioc
, &cfg
) != 0) {
5815 rc
= buffer
->NumPhysDiskPaths
;
5819 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5824 EXPORT_SYMBOL(mpt_raid_phys_disk_get_num_paths
);
5827 * mpt_raid_phys_disk_pg1 - returns phys disk page 1
5828 * @ioc: Pointer to a Adapter Structure
5829 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5830 * @phys_disk: requested payload data returned
5834 * -EFAULT if read of config page header fails or data pointer not NULL
5835 * -ENOMEM if pci_alloc failed
5838 mpt_raid_phys_disk_pg1(MPT_ADAPTER
*ioc
, u8 phys_disk_num
,
5839 RaidPhysDiskPage1_t
*phys_disk
)
5842 ConfigPageHeader_t hdr
;
5843 dma_addr_t dma_handle
;
5844 pRaidPhysDiskPage1_t buffer
= NULL
;
5849 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5850 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5853 hdr
.PageVersion
= MPI_RAIDPHYSDISKPAGE1_PAGEVERSION
;
5854 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_PHYSDISK
;
5856 cfg
.cfghdr
.hdr
= &hdr
;
5858 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5860 if (mpt_config(ioc
, &cfg
) != 0) {
5865 if (!hdr
.PageLength
) {
5870 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5878 cfg
.physAddr
= dma_handle
;
5879 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5880 cfg
.pageAddr
= phys_disk_num
;
5882 if (mpt_config(ioc
, &cfg
) != 0) {
5887 phys_disk
->NumPhysDiskPaths
= buffer
->NumPhysDiskPaths
;
5888 phys_disk
->PhysDiskNum
= phys_disk_num
;
5889 for (i
= 0; i
< phys_disk
->NumPhysDiskPaths
; i
++) {
5890 phys_disk
->Path
[i
].PhysDiskID
= buffer
->Path
[i
].PhysDiskID
;
5891 phys_disk
->Path
[i
].PhysDiskBus
= buffer
->Path
[i
].PhysDiskBus
;
5892 phys_disk
->Path
[i
].OwnerIdentifier
=
5893 buffer
->Path
[i
].OwnerIdentifier
;
5894 phys_disk
->Path
[i
].Flags
= le16_to_cpu(buffer
->Path
[i
].Flags
);
5895 memcpy(&sas_address
, &buffer
->Path
[i
].WWID
, sizeof(__le64
));
5896 sas_address
= le64_to_cpu(sas_address
);
5897 memcpy(&phys_disk
->Path
[i
].WWID
, &sas_address
, sizeof(__le64
));
5898 memcpy(&sas_address
,
5899 &buffer
->Path
[i
].OwnerWWID
, sizeof(__le64
));
5900 sas_address
= le64_to_cpu(sas_address
);
5901 memcpy(&phys_disk
->Path
[i
].OwnerWWID
,
5902 &sas_address
, sizeof(__le64
));
5908 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5913 EXPORT_SYMBOL(mpt_raid_phys_disk_pg1
);
5917 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5918 * @ioc: Pointer to a Adapter Strucutre
5922 * -EFAULT if read of config page header fails or data pointer not NULL
5923 * -ENOMEM if pci_alloc failed
5926 mpt_findImVolumes(MPT_ADAPTER
*ioc
)
5930 dma_addr_t ioc2_dma
;
5932 ConfigPageHeader_t header
;
5937 if (!ioc
->ir_firmware
)
5940 /* Free the old page
5942 kfree(ioc
->raid_data
.pIocPg2
);
5943 ioc
->raid_data
.pIocPg2
= NULL
;
5944 mpt_inactive_raid_list_free(ioc
);
5946 /* Read IOCP2 header then the page.
5948 header
.PageVersion
= 0;
5949 header
.PageLength
= 0;
5950 header
.PageNumber
= 2;
5951 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
5952 cfg
.cfghdr
.hdr
= &header
;
5955 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5958 if (mpt_config(ioc
, &cfg
) != 0)
5961 if (header
.PageLength
== 0)
5964 iocpage2sz
= header
.PageLength
* 4;
5965 pIoc2
= pci_alloc_consistent(ioc
->pcidev
, iocpage2sz
, &ioc2_dma
);
5969 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5970 cfg
.physAddr
= ioc2_dma
;
5971 if (mpt_config(ioc
, &cfg
) != 0)
5974 mem
= kmalloc(iocpage2sz
, GFP_KERNEL
);
5980 memcpy(mem
, (u8
*)pIoc2
, iocpage2sz
);
5981 ioc
->raid_data
.pIocPg2
= (IOCPage2_t
*) mem
;
5983 mpt_read_ioc_pg_3(ioc
);
5985 for (i
= 0; i
< pIoc2
->NumActiveVolumes
; i
++)
5986 mpt_inactive_raid_volumes(ioc
,
5987 pIoc2
->RaidVolume
[i
].VolumeBus
,
5988 pIoc2
->RaidVolume
[i
].VolumeID
);
5991 pci_free_consistent(ioc
->pcidev
, iocpage2sz
, pIoc2
, ioc2_dma
);
5997 mpt_read_ioc_pg_3(MPT_ADAPTER
*ioc
)
6002 ConfigPageHeader_t header
;
6003 dma_addr_t ioc3_dma
;
6006 /* Free the old page
6008 kfree(ioc
->raid_data
.pIocPg3
);
6009 ioc
->raid_data
.pIocPg3
= NULL
;
6011 /* There is at least one physical disk.
6012 * Read and save IOC Page 3
6014 header
.PageVersion
= 0;
6015 header
.PageLength
= 0;
6016 header
.PageNumber
= 3;
6017 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
6018 cfg
.cfghdr
.hdr
= &header
;
6021 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
6024 if (mpt_config(ioc
, &cfg
) != 0)
6027 if (header
.PageLength
== 0)
6030 /* Read Header good, alloc memory
6032 iocpage3sz
= header
.PageLength
* 4;
6033 pIoc3
= pci_alloc_consistent(ioc
->pcidev
, iocpage3sz
, &ioc3_dma
);
6037 /* Read the Page and save the data
6038 * into malloc'd memory.
6040 cfg
.physAddr
= ioc3_dma
;
6041 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
6042 if (mpt_config(ioc
, &cfg
) == 0) {
6043 mem
= kmalloc(iocpage3sz
, GFP_KERNEL
);
6045 memcpy(mem
, (u8
*)pIoc3
, iocpage3sz
);
6046 ioc
->raid_data
.pIocPg3
= (IOCPage3_t
*) mem
;
6050 pci_free_consistent(ioc
->pcidev
, iocpage3sz
, pIoc3
, ioc3_dma
);
6056 mpt_read_ioc_pg_4(MPT_ADAPTER
*ioc
)
6060 ConfigPageHeader_t header
;
6061 dma_addr_t ioc4_dma
;
6064 /* Read and save IOC Page 4
6066 header
.PageVersion
= 0;
6067 header
.PageLength
= 0;
6068 header
.PageNumber
= 4;
6069 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
6070 cfg
.cfghdr
.hdr
= &header
;
6073 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
6076 if (mpt_config(ioc
, &cfg
) != 0)
6079 if (header
.PageLength
== 0)
6082 if ( (pIoc4
= ioc
->spi_data
.pIocPg4
) == NULL
) {
6083 iocpage4sz
= (header
.PageLength
+ 4) * 4; /* Allow 4 additional SEP's */
6084 pIoc4
= pci_alloc_consistent(ioc
->pcidev
, iocpage4sz
, &ioc4_dma
);
6087 ioc
->alloc_total
+= iocpage4sz
;
6089 ioc4_dma
= ioc
->spi_data
.IocPg4_dma
;
6090 iocpage4sz
= ioc
->spi_data
.IocPg4Sz
;
6093 /* Read the Page into dma memory.
6095 cfg
.physAddr
= ioc4_dma
;
6096 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
6097 if (mpt_config(ioc
, &cfg
) == 0) {
6098 ioc
->spi_data
.pIocPg4
= (IOCPage4_t
*) pIoc4
;
6099 ioc
->spi_data
.IocPg4_dma
= ioc4_dma
;
6100 ioc
->spi_data
.IocPg4Sz
= iocpage4sz
;
6102 pci_free_consistent(ioc
->pcidev
, iocpage4sz
, pIoc4
, ioc4_dma
);
6103 ioc
->spi_data
.pIocPg4
= NULL
;
6104 ioc
->alloc_total
-= iocpage4sz
;
6109 mpt_read_ioc_pg_1(MPT_ADAPTER
*ioc
)
6113 ConfigPageHeader_t header
;
6114 dma_addr_t ioc1_dma
;
6118 /* Check the Coalescing Timeout in IOC Page 1
6120 header
.PageVersion
= 0;
6121 header
.PageLength
= 0;
6122 header
.PageNumber
= 1;
6123 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
6124 cfg
.cfghdr
.hdr
= &header
;
6127 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
6130 if (mpt_config(ioc
, &cfg
) != 0)
6133 if (header
.PageLength
== 0)
6136 /* Read Header good, alloc memory
6138 iocpage1sz
= header
.PageLength
* 4;
6139 pIoc1
= pci_alloc_consistent(ioc
->pcidev
, iocpage1sz
, &ioc1_dma
);
6143 /* Read the Page and check coalescing timeout
6145 cfg
.physAddr
= ioc1_dma
;
6146 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
6147 if (mpt_config(ioc
, &cfg
) == 0) {
6149 tmp
= le32_to_cpu(pIoc1
->Flags
) & MPI_IOCPAGE1_REPLY_COALESCING
;
6150 if (tmp
== MPI_IOCPAGE1_REPLY_COALESCING
) {
6151 tmp
= le32_to_cpu(pIoc1
->CoalescingTimeout
);
6153 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Coalescing Enabled Timeout = %d\n",
6156 if (tmp
> MPT_COALESCING_TIMEOUT
) {
6157 pIoc1
->CoalescingTimeout
= cpu_to_le32(MPT_COALESCING_TIMEOUT
);
6159 /* Write NVRAM and current
6162 cfg
.action
= MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT
;
6163 if (mpt_config(ioc
, &cfg
) == 0) {
6164 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Reset Current Coalescing Timeout to = %d\n",
6165 ioc
->name
, MPT_COALESCING_TIMEOUT
));
6167 cfg
.action
= MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM
;
6168 if (mpt_config(ioc
, &cfg
) == 0) {
6169 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6170 "Reset NVRAM Coalescing Timeout to = %d\n",
6171 ioc
->name
, MPT_COALESCING_TIMEOUT
));
6173 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6174 "Reset NVRAM Coalescing Timeout Failed\n",
6179 dprintk(ioc
, printk(MYIOC_s_WARN_FMT
6180 "Reset of Current Coalescing Timeout Failed!\n",
6186 dprintk(ioc
, printk(MYIOC_s_WARN_FMT
"Coalescing Disabled\n", ioc
->name
));
6190 pci_free_consistent(ioc
->pcidev
, iocpage1sz
, pIoc1
, ioc1_dma
);
6196 mpt_get_manufacturing_pg_0(MPT_ADAPTER
*ioc
)
6199 ConfigPageHeader_t hdr
;
6201 ManufacturingPage0_t
*pbuf
= NULL
;
6203 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
6204 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
6206 hdr
.PageType
= MPI_CONFIG_PAGETYPE_MANUFACTURING
;
6207 cfg
.cfghdr
.hdr
= &hdr
;
6209 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
6212 if (mpt_config(ioc
, &cfg
) != 0)
6215 if (!cfg
.cfghdr
.hdr
->PageLength
)
6218 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
6219 pbuf
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, &buf_dma
);
6223 cfg
.physAddr
= buf_dma
;
6225 if (mpt_config(ioc
, &cfg
) != 0)
6228 memcpy(ioc
->board_name
, pbuf
->BoardName
, sizeof(ioc
->board_name
));
6229 memcpy(ioc
->board_assembly
, pbuf
->BoardAssembly
, sizeof(ioc
->board_assembly
));
6230 memcpy(ioc
->board_tracer
, pbuf
->BoardTracerNumber
, sizeof(ioc
->board_tracer
));
6235 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, pbuf
, buf_dma
);
6238 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6240 * SendEventNotification - Send EventNotification (on or off) request to adapter
6241 * @ioc: Pointer to MPT_ADAPTER structure
6242 * @EvSwitch: Event switch flags
6243 * @sleepFlag: Specifies whether the process can sleep
6246 SendEventNotification(MPT_ADAPTER
*ioc
, u8 EvSwitch
, int sleepFlag
)
6248 EventNotification_t evn
;
6249 MPIDefaultReply_t reply_buf
;
6251 memset(&evn
, 0, sizeof(EventNotification_t
));
6252 memset(&reply_buf
, 0, sizeof(MPIDefaultReply_t
));
6254 evn
.Function
= MPI_FUNCTION_EVENT_NOTIFICATION
;
6255 evn
.Switch
= EvSwitch
;
6256 evn
.MsgContext
= cpu_to_le32(mpt_base_index
<< 16);
6258 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6259 "Sending EventNotification (%d) request %p\n",
6260 ioc
->name
, EvSwitch
, &evn
));
6262 return mpt_handshake_req_reply_wait(ioc
, sizeof(EventNotification_t
),
6263 (u32
*)&evn
, sizeof(MPIDefaultReply_t
), (u16
*)&reply_buf
, 30,
6267 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6269 * SendEventAck - Send EventAck request to MPT adapter.
6270 * @ioc: Pointer to MPT_ADAPTER structure
6271 * @evnp: Pointer to original EventNotification request
6274 SendEventAck(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*evnp
)
6278 if ((pAck
= (EventAck_t
*) mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
6279 dfailprintk(ioc
, printk(MYIOC_s_WARN_FMT
"%s, no msg frames!!\n",
6280 ioc
->name
, __func__
));
6284 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending EventAck\n", ioc
->name
));
6286 pAck
->Function
= MPI_FUNCTION_EVENT_ACK
;
6287 pAck
->ChainOffset
= 0;
6288 pAck
->Reserved
[0] = pAck
->Reserved
[1] = 0;
6290 pAck
->Reserved1
[0] = pAck
->Reserved1
[1] = pAck
->Reserved1
[2] = 0;
6291 pAck
->Event
= evnp
->Event
;
6292 pAck
->EventContext
= evnp
->EventContext
;
6294 mpt_put_msg_frame(mpt_base_index
, ioc
, (MPT_FRAME_HDR
*)pAck
);
6299 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6301 * mpt_config - Generic function to issue config message
6302 * @ioc: Pointer to an adapter structure
6303 * @pCfg: Pointer to a configuration structure. Struct contains
6304 * action, page address, direction, physical address
6305 * and pointer to a configuration page header
6306 * Page header is updated.
6308 * Returns 0 for success
6309 * -EPERM if not allowed due to ISR context
6310 * -EAGAIN if no msg frames currently available
6311 * -EFAULT for non-successful reply or no reply (timeout)
6314 mpt_config(MPT_ADAPTER
*ioc
, CONFIGPARMS
*pCfg
)
6317 ConfigReply_t
*pReply
;
6318 ConfigExtendedPageHeader_t
*pExtHdr
= NULL
;
6324 u8 page_type
= 0, extend_page
;
6325 unsigned long timeleft
;
6326 unsigned long flags
;
6328 u8 issue_hard_reset
= 0;
6331 /* Prevent calling wait_event() (below), if caller happens
6332 * to be in ISR context, because that is fatal!
6334 in_isr
= in_interrupt();
6336 dcprintk(ioc
, printk(MYIOC_s_WARN_FMT
"Config request not allowed in ISR context!\n",
6341 /* don't send a config page during diag reset */
6342 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
6343 if (ioc
->ioc_reset_in_progress
) {
6344 dfailprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6345 "%s: busy with host reset\n", ioc
->name
, __func__
));
6346 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6349 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6351 /* don't send if no chance of success */
6353 mpt_GetIocState(ioc
, 1) != MPI_IOC_STATE_OPERATIONAL
) {
6354 dfailprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6355 "%s: ioc not operational, %d, %xh\n",
6356 ioc
->name
, __func__
, ioc
->active
,
6357 mpt_GetIocState(ioc
, 0)));
6362 mutex_lock(&ioc
->mptbase_cmds
.mutex
);
6363 /* init the internal cmd struct */
6364 memset(ioc
->mptbase_cmds
.reply
, 0 , MPT_DEFAULT_FRAME_SIZE
);
6365 INITIALIZE_MGMT_STATUS(ioc
->mptbase_cmds
.status
)
6367 /* Get and Populate a free Frame
6369 if ((mf
= mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
6370 dcprintk(ioc
, printk(MYIOC_s_WARN_FMT
6371 "mpt_config: no msg frames!\n", ioc
->name
));
6376 pReq
= (Config_t
*)mf
;
6377 pReq
->Action
= pCfg
->action
;
6379 pReq
->ChainOffset
= 0;
6380 pReq
->Function
= MPI_FUNCTION_CONFIG
;
6382 /* Assume page type is not extended and clear "reserved" fields. */
6383 pReq
->ExtPageLength
= 0;
6384 pReq
->ExtPageType
= 0;
6387 for (ii
=0; ii
< 8; ii
++)
6388 pReq
->Reserved2
[ii
] = 0;
6390 pReq
->Header
.PageVersion
= pCfg
->cfghdr
.hdr
->PageVersion
;
6391 pReq
->Header
.PageLength
= pCfg
->cfghdr
.hdr
->PageLength
;
6392 pReq
->Header
.PageNumber
= pCfg
->cfghdr
.hdr
->PageNumber
;
6393 pReq
->Header
.PageType
= (pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
);
6395 if ((pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
) == MPI_CONFIG_PAGETYPE_EXTENDED
) {
6396 pExtHdr
= (ConfigExtendedPageHeader_t
*)pCfg
->cfghdr
.ehdr
;
6397 pReq
->ExtPageLength
= cpu_to_le16(pExtHdr
->ExtPageLength
);
6398 pReq
->ExtPageType
= pExtHdr
->ExtPageType
;
6399 pReq
->Header
.PageType
= MPI_CONFIG_PAGETYPE_EXTENDED
;
6401 /* Page Length must be treated as a reserved field for the
6404 pReq
->Header
.PageLength
= 0;
6407 pReq
->PageAddress
= cpu_to_le32(pCfg
->pageAddr
);
6409 /* Add a SGE to the config request.
6412 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_WRITE
;
6414 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_READ
;
6416 if ((pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
) ==
6417 MPI_CONFIG_PAGETYPE_EXTENDED
) {
6418 flagsLength
|= pExtHdr
->ExtPageLength
* 4;
6419 page_type
= pReq
->ExtPageType
;
6422 flagsLength
|= pCfg
->cfghdr
.hdr
->PageLength
* 4;
6423 page_type
= pReq
->Header
.PageType
;
6427 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6428 "Sending Config request type 0x%x, page 0x%x and action %d\n",
6429 ioc
->name
, page_type
, pReq
->Header
.PageNumber
, pReq
->Action
));
6431 ioc
->add_sge((char *)&pReq
->PageBufferSGE
, flagsLength
, pCfg
->physAddr
);
6432 timeout
= (pCfg
->timeout
< 15) ? HZ
*15 : HZ
*pCfg
->timeout
;
6433 mpt_put_msg_frame(mpt_base_index
, ioc
, mf
);
6434 timeleft
= wait_for_completion_timeout(&ioc
->mptbase_cmds
.done
,
6436 if (!(ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_COMMAND_GOOD
)) {
6438 dfailprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6439 "Failed Sending Config request type 0x%x, page 0x%x,"
6440 " action %d, status %xh, time left %ld\n\n",
6441 ioc
->name
, page_type
, pReq
->Header
.PageNumber
,
6442 pReq
->Action
, ioc
->mptbase_cmds
.status
, timeleft
));
6443 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_DID_IOCRESET
)
6446 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
6447 if (ioc
->ioc_reset_in_progress
) {
6448 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
,
6450 printk(MYIOC_s_INFO_FMT
"%s: host reset in"
6451 " progress mpt_config timed out.!!\n",
6452 __func__
, ioc
->name
);
6453 mutex_unlock(&ioc
->mptbase_cmds
.mutex
);
6456 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6457 issue_hard_reset
= 1;
6462 if (!(ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_RF_VALID
)) {
6466 pReply
= (ConfigReply_t
*)ioc
->mptbase_cmds
.reply
;
6467 ret
= le16_to_cpu(pReply
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
6468 if (ret
== MPI_IOCSTATUS_SUCCESS
) {
6470 pCfg
->cfghdr
.ehdr
->ExtPageLength
=
6471 le16_to_cpu(pReply
->ExtPageLength
);
6472 pCfg
->cfghdr
.ehdr
->ExtPageType
=
6473 pReply
->ExtPageType
;
6475 pCfg
->cfghdr
.hdr
->PageVersion
= pReply
->Header
.PageVersion
;
6476 pCfg
->cfghdr
.hdr
->PageLength
= pReply
->Header
.PageLength
;
6477 pCfg
->cfghdr
.hdr
->PageNumber
= pReply
->Header
.PageNumber
;
6478 pCfg
->cfghdr
.hdr
->PageType
= pReply
->Header
.PageType
;
6483 printk(MYIOC_s_INFO_FMT
"Retry completed "
6484 "ret=0x%x timeleft=%ld\n",
6485 ioc
->name
, ret
, timeleft
);
6487 dcprintk(ioc
, printk(KERN_DEBUG
"IOCStatus=%04xh, IOCLogInfo=%08xh\n",
6488 ret
, le32_to_cpu(pReply
->IOCLogInfo
)));
6492 CLEAR_MGMT_STATUS(ioc
->mptbase_cmds
.status
)
6493 mutex_unlock(&ioc
->mptbase_cmds
.mutex
);
6494 if (issue_hard_reset
) {
6495 issue_hard_reset
= 0;
6496 printk(MYIOC_s_WARN_FMT
6497 "Issuing Reset from %s!!, doorbell=0x%08x\n",
6498 ioc
->name
, __func__
, mpt_GetIocState(ioc
, 0));
6499 if (retry_count
== 0) {
6500 if (mpt_Soft_Hard_ResetHandler(ioc
, CAN_SLEEP
) != 0)
6503 mpt_HardResetHandler(ioc
, CAN_SLEEP
);
6505 mpt_free_msg_frame(ioc
, mf
);
6506 /* attempt one retry for a timed out command */
6507 if (retry_count
< 2) {
6508 printk(MYIOC_s_INFO_FMT
6509 "Attempting Retry Config request"
6510 " type 0x%x, page 0x%x,"
6511 " action %d\n", ioc
->name
, page_type
,
6512 pCfg
->cfghdr
.hdr
->PageNumber
, pCfg
->action
);
6521 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6523 * mpt_ioc_reset - Base cleanup for hard reset
6524 * @ioc: Pointer to the adapter structure
6525 * @reset_phase: Indicates pre- or post-reset functionality
6527 * Remark: Frees resources with internally generated commands.
6530 mpt_ioc_reset(MPT_ADAPTER
*ioc
, int reset_phase
)
6532 switch (reset_phase
) {
6533 case MPT_IOC_SETUP_RESET
:
6534 ioc
->taskmgmt_quiesce_io
= 1;
6535 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6536 "%s: MPT_IOC_SETUP_RESET\n", ioc
->name
, __func__
));
6538 case MPT_IOC_PRE_RESET
:
6539 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6540 "%s: MPT_IOC_PRE_RESET\n", ioc
->name
, __func__
));
6542 case MPT_IOC_POST_RESET
:
6543 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6544 "%s: MPT_IOC_POST_RESET\n", ioc
->name
, __func__
));
6545 /* wake up mptbase_cmds */
6546 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_PENDING
) {
6547 ioc
->mptbase_cmds
.status
|=
6548 MPT_MGMT_STATUS_DID_IOCRESET
;
6549 complete(&ioc
->mptbase_cmds
.done
);
6551 /* wake up taskmgmt_cmds */
6552 if (ioc
->taskmgmt_cmds
.status
& MPT_MGMT_STATUS_PENDING
) {
6553 ioc
->taskmgmt_cmds
.status
|=
6554 MPT_MGMT_STATUS_DID_IOCRESET
;
6555 complete(&ioc
->taskmgmt_cmds
.done
);
6562 return 1; /* currently means nothing really */
6566 #ifdef CONFIG_PROC_FS /* { */
6567 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6569 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
6571 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6573 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
6575 * Returns 0 for success, non-zero for failure.
6578 procmpt_create(void)
6580 mpt_proc_root_dir
= proc_mkdir(MPT_PROCFS_MPTBASEDIR
, NULL
);
6581 if (mpt_proc_root_dir
== NULL
)
6584 proc_create("summary", S_IRUGO
, mpt_proc_root_dir
, &mpt_summary_proc_fops
);
6585 proc_create("version", S_IRUGO
, mpt_proc_root_dir
, &mpt_version_proc_fops
);
6589 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6591 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
6593 * Returns 0 for success, non-zero for failure.
6596 procmpt_destroy(void)
6598 remove_proc_entry("version", mpt_proc_root_dir
);
6599 remove_proc_entry("summary", mpt_proc_root_dir
);
6600 remove_proc_entry(MPT_PROCFS_MPTBASEDIR
, NULL
);
6603 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6605 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
6607 static void seq_mpt_print_ioc_summary(MPT_ADAPTER
*ioc
, struct seq_file
*m
, int showlan
);
6609 static int mpt_summary_proc_show(struct seq_file
*m
, void *v
)
6611 MPT_ADAPTER
*ioc
= m
->private;
6614 seq_mpt_print_ioc_summary(ioc
, m
, 1);
6616 list_for_each_entry(ioc
, &ioc_list
, list
) {
6617 seq_mpt_print_ioc_summary(ioc
, m
, 1);
6624 static int mpt_summary_proc_open(struct inode
*inode
, struct file
*file
)
6626 return single_open(file
, mpt_summary_proc_show
, PDE_DATA(inode
));
6629 static const struct file_operations mpt_summary_proc_fops
= {
6630 .owner
= THIS_MODULE
,
6631 .open
= mpt_summary_proc_open
,
6633 .llseek
= seq_lseek
,
6634 .release
= single_release
,
6637 static int mpt_version_proc_show(struct seq_file
*m
, void *v
)
6640 int scsi
, fc
, sas
, lan
, ctl
, targ
, dmp
;
6643 seq_printf(m
, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON
);
6644 seq_printf(m
, " Fusion MPT base driver\n");
6646 scsi
= fc
= sas
= lan
= ctl
= targ
= dmp
= 0;
6647 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
6649 if (MptCallbacks
[cb_idx
]) {
6650 switch (MptDriverClass
[cb_idx
]) {
6652 if (!scsi
++) drvname
= "SPI host";
6655 if (!fc
++) drvname
= "FC host";
6658 if (!sas
++) drvname
= "SAS host";
6661 if (!lan
++) drvname
= "LAN";
6664 if (!targ
++) drvname
= "SCSI target";
6667 if (!ctl
++) drvname
= "ioctl";
6672 seq_printf(m
, " Fusion MPT %s driver\n", drvname
);
6679 static int mpt_version_proc_open(struct inode
*inode
, struct file
*file
)
6681 return single_open(file
, mpt_version_proc_show
, NULL
);
6684 static const struct file_operations mpt_version_proc_fops
= {
6685 .owner
= THIS_MODULE
,
6686 .open
= mpt_version_proc_open
,
6688 .llseek
= seq_lseek
,
6689 .release
= single_release
,
6692 static int mpt_iocinfo_proc_show(struct seq_file
*m
, void *v
)
6694 MPT_ADAPTER
*ioc
= m
->private;
6699 mpt_get_fw_exp_ver(expVer
, ioc
);
6701 seq_printf(m
, "%s:", ioc
->name
);
6702 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)
6703 seq_printf(m
, " (f/w download boot flag set)");
6704 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6705 // seq_printf(m, " CONFIG_CHECKSUM_FAIL!");
6707 seq_printf(m
, "\n ProductID = 0x%04x (%s)\n",
6708 ioc
->facts
.ProductID
,
6710 seq_printf(m
, " FWVersion = 0x%08x%s", ioc
->facts
.FWVersion
.Word
, expVer
);
6711 if (ioc
->facts
.FWImageSize
)
6712 seq_printf(m
, " (fw_size=%d)", ioc
->facts
.FWImageSize
);
6713 seq_printf(m
, "\n MsgVersion = 0x%04x\n", ioc
->facts
.MsgVersion
);
6714 seq_printf(m
, " FirstWhoInit = 0x%02x\n", ioc
->FirstWhoInit
);
6715 seq_printf(m
, " EventState = 0x%02x\n", ioc
->facts
.EventState
);
6717 seq_printf(m
, " CurrentHostMfaHighAddr = 0x%08x\n",
6718 ioc
->facts
.CurrentHostMfaHighAddr
);
6719 seq_printf(m
, " CurrentSenseBufferHighAddr = 0x%08x\n",
6720 ioc
->facts
.CurrentSenseBufferHighAddr
);
6722 seq_printf(m
, " MaxChainDepth = 0x%02x frames\n", ioc
->facts
.MaxChainDepth
);
6723 seq_printf(m
, " MinBlockSize = 0x%02x bytes\n", 4*ioc
->facts
.BlockSize
);
6725 seq_printf(m
, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6726 (void *)ioc
->req_frames
, (void *)(ulong
)ioc
->req_frames_dma
);
6728 * Rounding UP to nearest 4-kB boundary here...
6730 sz
= (ioc
->req_sz
* ioc
->req_depth
) + 128;
6731 sz
= ((sz
+ 0x1000UL
- 1UL) / 0x1000) * 0x1000;
6732 seq_printf(m
, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6733 ioc
->req_sz
, ioc
->req_depth
, ioc
->req_sz
*ioc
->req_depth
, sz
);
6734 seq_printf(m
, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
6735 4*ioc
->facts
.RequestFrameSize
,
6736 ioc
->facts
.GlobalCredits
);
6738 seq_printf(m
, " Frames @ 0x%p (Dma @ 0x%p)\n",
6739 (void *)ioc
->alloc
, (void *)(ulong
)ioc
->alloc_dma
);
6740 sz
= (ioc
->reply_sz
* ioc
->reply_depth
) + 128;
6741 seq_printf(m
, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6742 ioc
->reply_sz
, ioc
->reply_depth
, ioc
->reply_sz
*ioc
->reply_depth
, sz
);
6743 seq_printf(m
, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
6744 ioc
->facts
.CurReplyFrameSize
,
6745 ioc
->facts
.ReplyQueueDepth
);
6747 seq_printf(m
, " MaxDevices = %d\n",
6748 (ioc
->facts
.MaxDevices
==0) ? 255 : ioc
->facts
.MaxDevices
);
6749 seq_printf(m
, " MaxBuses = %d\n", ioc
->facts
.MaxBuses
);
6752 for (p
=0; p
< ioc
->facts
.NumberOfPorts
; p
++) {
6753 seq_printf(m
, " PortNumber = %d (of %d)\n",
6755 ioc
->facts
.NumberOfPorts
);
6756 if (ioc
->bus_type
== FC
) {
6757 if (ioc
->pfacts
[p
].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
) {
6758 u8
*a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
6759 seq_printf(m
, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6760 a
[5], a
[4], a
[3], a
[2], a
[1], a
[0]);
6762 seq_printf(m
, " WWN = %08X%08X:%08X%08X\n",
6763 ioc
->fc_port_page0
[p
].WWNN
.High
,
6764 ioc
->fc_port_page0
[p
].WWNN
.Low
,
6765 ioc
->fc_port_page0
[p
].WWPN
.High
,
6766 ioc
->fc_port_page0
[p
].WWPN
.Low
);
6773 static int mpt_iocinfo_proc_open(struct inode
*inode
, struct file
*file
)
6775 return single_open(file
, mpt_iocinfo_proc_show
, PDE_DATA(inode
));
6778 static const struct file_operations mpt_iocinfo_proc_fops
= {
6779 .owner
= THIS_MODULE
,
6780 .open
= mpt_iocinfo_proc_open
,
6782 .llseek
= seq_lseek
,
6783 .release
= single_release
,
6785 #endif /* CONFIG_PROC_FS } */
6787 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6789 mpt_get_fw_exp_ver(char *buf
, MPT_ADAPTER
*ioc
)
6792 if ((ioc
->facts
.FWVersion
.Word
>> 24) == 0x0E) {
6793 sprintf(buf
, " (Exp %02d%02d)",
6794 (ioc
->facts
.FWVersion
.Word
>> 16) & 0x00FF, /* Month */
6795 (ioc
->facts
.FWVersion
.Word
>> 8) & 0x1F); /* Day */
6798 if ((ioc
->facts
.FWVersion
.Word
>> 8) & 0x80)
6799 strcat(buf
, " [MDBG]");
6803 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6805 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6806 * @ioc: Pointer to MPT_ADAPTER structure
6807 * @buffer: Pointer to buffer where IOC summary info should be written
6808 * @size: Pointer to number of bytes we wrote (set by this routine)
6809 * @len: Offset at which to start writing in buffer
6810 * @showlan: Display LAN stuff?
6812 * This routine writes (english readable) ASCII text, which represents
6813 * a summary of IOC information, to a buffer.
6816 mpt_print_ioc_summary(MPT_ADAPTER
*ioc
, char *buffer
, int *size
, int len
, int showlan
)
6821 mpt_get_fw_exp_ver(expVer
, ioc
);
6824 * Shorter summary of attached ioc's...
6826 y
= sprintf(buffer
+len
, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6829 MPT_FW_REV_MAGIC_ID_STRING
, /* "FwRev=" or somesuch */
6830 ioc
->facts
.FWVersion
.Word
,
6832 ioc
->facts
.NumberOfPorts
,
6835 if (showlan
&& (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
)) {
6836 u8
*a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
6837 y
+= sprintf(buffer
+len
+y
, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6838 a
[5], a
[4], a
[3], a
[2], a
[1], a
[0]);
6841 y
+= sprintf(buffer
+len
+y
, ", IRQ=%d", ioc
->pci_irq
);
6844 y
+= sprintf(buffer
+len
+y
, " (disabled)");
6846 y
+= sprintf(buffer
+len
+y
, "\n");
6851 static void seq_mpt_print_ioc_summary(MPT_ADAPTER
*ioc
, struct seq_file
*m
, int showlan
)
6855 mpt_get_fw_exp_ver(expVer
, ioc
);
6858 * Shorter summary of attached ioc's...
6860 seq_printf(m
, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6863 MPT_FW_REV_MAGIC_ID_STRING
, /* "FwRev=" or somesuch */
6864 ioc
->facts
.FWVersion
.Word
,
6866 ioc
->facts
.NumberOfPorts
,
6869 if (showlan
&& (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
)) {
6870 u8
*a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
6871 seq_printf(m
, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6872 a
[5], a
[4], a
[3], a
[2], a
[1], a
[0]);
6875 seq_printf(m
, ", IRQ=%d", ioc
->pci_irq
);
6878 seq_printf(m
, " (disabled)");
6884 * mpt_set_taskmgmt_in_progress_flag - set flags associated with task management
6885 * @ioc: Pointer to MPT_ADAPTER structure
6887 * Returns 0 for SUCCESS or -1 if FAILED.
6889 * If -1 is return, then it was not possible to set the flags
6892 mpt_set_taskmgmt_in_progress_flag(MPT_ADAPTER
*ioc
)
6894 unsigned long flags
;
6897 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
6898 if (ioc
->ioc_reset_in_progress
|| ioc
->taskmgmt_in_progress
||
6899 (ioc
->alt_ioc
&& ioc
->alt_ioc
->taskmgmt_in_progress
)) {
6904 ioc
->taskmgmt_in_progress
= 1;
6905 ioc
->taskmgmt_quiesce_io
= 1;
6907 ioc
->alt_ioc
->taskmgmt_in_progress
= 1;
6908 ioc
->alt_ioc
->taskmgmt_quiesce_io
= 1;
6911 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6914 EXPORT_SYMBOL(mpt_set_taskmgmt_in_progress_flag
);
6917 * mpt_clear_taskmgmt_in_progress_flag - clear flags associated with task management
6918 * @ioc: Pointer to MPT_ADAPTER structure
6922 mpt_clear_taskmgmt_in_progress_flag(MPT_ADAPTER
*ioc
)
6924 unsigned long flags
;
6926 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
6927 ioc
->taskmgmt_in_progress
= 0;
6928 ioc
->taskmgmt_quiesce_io
= 0;
6930 ioc
->alt_ioc
->taskmgmt_in_progress
= 0;
6931 ioc
->alt_ioc
->taskmgmt_quiesce_io
= 0;
6933 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6935 EXPORT_SYMBOL(mpt_clear_taskmgmt_in_progress_flag
);
6939 * mpt_halt_firmware - Halts the firmware if it is operational and panic
6941 * @ioc: Pointer to MPT_ADAPTER structure
6945 mpt_halt_firmware(MPT_ADAPTER
*ioc
)
6949 ioc_raw_state
= mpt_GetIocState(ioc
, 0);
6951 if ((ioc_raw_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_FAULT
) {
6952 printk(MYIOC_s_ERR_FMT
"IOC is in FAULT state (%04xh)!!!\n",
6953 ioc
->name
, ioc_raw_state
& MPI_DOORBELL_DATA_MASK
);
6954 panic("%s: IOC Fault (%04xh)!!!\n", ioc
->name
,
6955 ioc_raw_state
& MPI_DOORBELL_DATA_MASK
);
6957 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, 0xC0FFEE00);
6958 panic("%s: Firmware is halted due to command timeout\n",
6962 EXPORT_SYMBOL(mpt_halt_firmware
);
6965 * mpt_SoftResetHandler - Issues a less expensive reset
6966 * @ioc: Pointer to MPT_ADAPTER structure
6967 * @sleepFlag: Indicates if sleep or schedule must be called.
6969 * Returns 0 for SUCCESS or -1 if FAILED.
6971 * Message Unit Reset - instructs the IOC to reset the Reply Post and
6972 * Free FIFO's. All the Message Frames on Reply Free FIFO are discarded.
6973 * All posted buffers are freed, and event notification is turned off.
6974 * IOC doesn't reply to any outstanding request. This will transfer IOC
6978 mpt_SoftResetHandler(MPT_ADAPTER
*ioc
, int sleepFlag
)
6983 unsigned long flags
;
6985 unsigned long time_count
;
6987 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SoftResetHandler Entered!\n",
6990 ioc_state
= mpt_GetIocState(ioc
, 0) & MPI_IOC_STATE_MASK
;
6992 if (mpt_fwfault_debug
)
6993 mpt_halt_firmware(ioc
);
6995 if (ioc_state
== MPI_IOC_STATE_FAULT
||
6996 ioc_state
== MPI_IOC_STATE_RESET
) {
6997 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6998 "skipping, either in FAULT or RESET state!\n", ioc
->name
));
7002 if (ioc
->bus_type
== FC
) {
7003 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
7004 "skipping, because the bus type is FC!\n", ioc
->name
));
7008 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
7009 if (ioc
->ioc_reset_in_progress
) {
7010 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
7013 ioc
->ioc_reset_in_progress
= 1;
7014 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
7018 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
7019 if (MptResetHandlers
[cb_idx
])
7020 mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_SETUP_RESET
);
7023 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
7024 if (ioc
->taskmgmt_in_progress
) {
7025 ioc
->ioc_reset_in_progress
= 0;
7026 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
7029 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
7030 /* Disable reply interrupts (also blocks FreeQ) */
7031 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
7033 time_count
= jiffies
;
7035 rc
= SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
);
7037 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
7038 if (MptResetHandlers
[cb_idx
])
7039 mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_PRE_RESET
);
7045 ioc_state
= mpt_GetIocState(ioc
, 0) & MPI_IOC_STATE_MASK
;
7046 if (ioc_state
!= MPI_IOC_STATE_READY
)
7049 for (ii
= 0; ii
< 5; ii
++) {
7050 /* Get IOC facts! Allow 5 retries */
7051 rc
= GetIocFacts(ioc
, sleepFlag
,
7052 MPT_HOSTEVENT_IOC_RECOVER
);
7055 if (sleepFlag
== CAN_SLEEP
)
7063 rc
= PrimeIocFifos(ioc
);
7067 rc
= SendIocInit(ioc
, sleepFlag
);
7071 rc
= SendEventNotification(ioc
, 1, sleepFlag
);
7075 if (ioc
->hard_resets
< -1)
7079 * At this point, we know soft reset succeeded.
7083 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, MPI_HIM_DIM
);
7086 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
7087 ioc
->ioc_reset_in_progress
= 0;
7088 ioc
->taskmgmt_quiesce_io
= 0;
7089 ioc
->taskmgmt_in_progress
= 0;
7090 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
7092 if (ioc
->active
) { /* otherwise, hard reset coming */
7093 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
7094 if (MptResetHandlers
[cb_idx
])
7095 mpt_signal_reset(cb_idx
, ioc
,
7096 MPT_IOC_POST_RESET
);
7100 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
7101 "SoftResetHandler: completed (%d seconds): %s\n",
7102 ioc
->name
, jiffies_to_msecs(jiffies
- time_count
)/1000,
7103 ((rc
== 0) ? "SUCCESS" : "FAILED")));
7109 * mpt_Soft_Hard_ResetHandler - Try less expensive reset
7110 * @ioc: Pointer to MPT_ADAPTER structure
7111 * @sleepFlag: Indicates if sleep or schedule must be called.
7113 * Returns 0 for SUCCESS or -1 if FAILED.
7114 * Try for softreset first, only if it fails go for expensive
7118 mpt_Soft_Hard_ResetHandler(MPT_ADAPTER
*ioc
, int sleepFlag
) {
7121 ret
= mpt_SoftResetHandler(ioc
, sleepFlag
);
7124 ret
= mpt_HardResetHandler(ioc
, sleepFlag
);
7127 EXPORT_SYMBOL(mpt_Soft_Hard_ResetHandler
);
7129 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7133 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7135 * mpt_HardResetHandler - Generic reset handler
7136 * @ioc: Pointer to MPT_ADAPTER structure
7137 * @sleepFlag: Indicates if sleep or schedule must be called.
7139 * Issues SCSI Task Management call based on input arg values.
7140 * If TaskMgmt fails, returns associated SCSI request.
7142 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
7143 * or a non-interrupt thread. In the former, must not call schedule().
7145 * Note: A return of -1 is a FATAL error case, as it means a
7146 * FW reload/initialization failed.
7148 * Returns 0 for SUCCESS or -1 if FAILED.
7151 mpt_HardResetHandler(MPT_ADAPTER
*ioc
, int sleepFlag
)
7155 unsigned long flags
;
7156 unsigned long time_count
;
7158 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HardResetHandler Entered!\n", ioc
->name
));
7160 printk(MYIOC_s_INFO_FMT
"HardResetHandler Entered!\n", ioc
->name
);
7161 printk("MF count 0x%x !\n", ioc
->mfcnt
);
7163 if (mpt_fwfault_debug
)
7164 mpt_halt_firmware(ioc
);
7166 /* Reset the adapter. Prevent more than 1 call to
7167 * mpt_do_ioc_recovery at any instant in time.
7169 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
7170 if (ioc
->ioc_reset_in_progress
) {
7171 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
7172 ioc
->wait_on_reset_completion
= 1;
7175 } while (ioc
->ioc_reset_in_progress
== 1);
7176 ioc
->wait_on_reset_completion
= 0;
7177 return ioc
->reset_status
;
7179 if (ioc
->wait_on_reset_completion
) {
7180 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
7182 time_count
= jiffies
;
7185 ioc
->ioc_reset_in_progress
= 1;
7187 ioc
->alt_ioc
->ioc_reset_in_progress
= 1;
7188 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
7191 /* The SCSI driver needs to adjust timeouts on all current
7192 * commands prior to the diagnostic reset being issued.
7193 * Prevents timeouts occurring during a diagnostic reset...very bad.
7194 * For all other protocol drivers, this is a no-op.
7196 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
7197 if (MptResetHandlers
[cb_idx
]) {
7198 mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_SETUP_RESET
);
7200 mpt_signal_reset(cb_idx
, ioc
->alt_ioc
,
7201 MPT_IOC_SETUP_RESET
);
7205 time_count
= jiffies
;
7206 rc
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_RECOVER
, sleepFlag
);
7208 printk(KERN_WARNING MYNAM
7209 ": WARNING - (%d) Cannot recover %s, doorbell=0x%08x\n",
7210 rc
, ioc
->name
, mpt_GetIocState(ioc
, 0));
7212 if (ioc
->hard_resets
< -1)
7216 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
7217 ioc
->ioc_reset_in_progress
= 0;
7218 ioc
->taskmgmt_quiesce_io
= 0;
7219 ioc
->taskmgmt_in_progress
= 0;
7220 ioc
->reset_status
= rc
;
7222 ioc
->alt_ioc
->ioc_reset_in_progress
= 0;
7223 ioc
->alt_ioc
->taskmgmt_quiesce_io
= 0;
7224 ioc
->alt_ioc
->taskmgmt_in_progress
= 0;
7226 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
7228 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
7229 if (MptResetHandlers
[cb_idx
]) {
7230 mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_POST_RESET
);
7232 mpt_signal_reset(cb_idx
,
7233 ioc
->alt_ioc
, MPT_IOC_POST_RESET
);
7238 printk(MYIOC_s_DEBUG_FMT
7239 "HardResetHandler: completed (%d seconds): %s\n", ioc
->name
,
7240 jiffies_to_msecs(jiffies
- time_count
)/1000, ((rc
== 0) ?
7241 "SUCCESS" : "FAILED")));
7246 #ifdef CONFIG_FUSION_LOGGING
7248 mpt_display_event_info(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*pEventReply
)
7254 char *evStr
= ioc
->evStr
;
7256 event
= le32_to_cpu(pEventReply
->Event
) & 0xFF;
7257 evData0
= le32_to_cpu(pEventReply
->Data
[0]);
7260 case MPI_EVENT_NONE
:
7263 case MPI_EVENT_LOG_DATA
:
7266 case MPI_EVENT_STATE_CHANGE
:
7267 ds
= "State Change";
7269 case MPI_EVENT_UNIT_ATTENTION
:
7270 ds
= "Unit Attention";
7272 case MPI_EVENT_IOC_BUS_RESET
:
7273 ds
= "IOC Bus Reset";
7275 case MPI_EVENT_EXT_BUS_RESET
:
7276 ds
= "External Bus Reset";
7278 case MPI_EVENT_RESCAN
:
7279 ds
= "Bus Rescan Event";
7281 case MPI_EVENT_LINK_STATUS_CHANGE
:
7282 if (evData0
== MPI_EVENT_LINK_STATUS_FAILURE
)
7283 ds
= "Link Status(FAILURE) Change";
7285 ds
= "Link Status(ACTIVE) Change";
7287 case MPI_EVENT_LOOP_STATE_CHANGE
:
7288 if (evData0
== MPI_EVENT_LOOP_STATE_CHANGE_LIP
)
7289 ds
= "Loop State(LIP) Change";
7290 else if (evData0
== MPI_EVENT_LOOP_STATE_CHANGE_LPE
)
7291 ds
= "Loop State(LPE) Change";
7293 ds
= "Loop State(LPB) Change";
7295 case MPI_EVENT_LOGOUT
:
7298 case MPI_EVENT_EVENT_CHANGE
:
7304 case MPI_EVENT_INTEGRATED_RAID
:
7306 u8 ReasonCode
= (u8
)(evData0
>> 16);
7307 switch (ReasonCode
) {
7308 case MPI_EVENT_RAID_RC_VOLUME_CREATED
:
7309 ds
= "Integrated Raid: Volume Created";
7311 case MPI_EVENT_RAID_RC_VOLUME_DELETED
:
7312 ds
= "Integrated Raid: Volume Deleted";
7314 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED
:
7315 ds
= "Integrated Raid: Volume Settings Changed";
7317 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED
:
7318 ds
= "Integrated Raid: Volume Status Changed";
7320 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED
:
7321 ds
= "Integrated Raid: Volume Physdisk Changed";
7323 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED
:
7324 ds
= "Integrated Raid: Physdisk Created";
7326 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED
:
7327 ds
= "Integrated Raid: Physdisk Deleted";
7329 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED
:
7330 ds
= "Integrated Raid: Physdisk Settings Changed";
7332 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
:
7333 ds
= "Integrated Raid: Physdisk Status Changed";
7335 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
:
7336 ds
= "Integrated Raid: Domain Validation Needed";
7338 case MPI_EVENT_RAID_RC_SMART_DATA
:
7339 ds
= "Integrated Raid; Smart Data";
7341 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED
:
7342 ds
= "Integrated Raid: Replace Action Started";
7345 ds
= "Integrated Raid";
7350 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE
:
7351 ds
= "SCSI Device Status Change";
7353 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE
:
7355 u8 id
= (u8
)(evData0
);
7356 u8 channel
= (u8
)(evData0
>> 8);
7357 u8 ReasonCode
= (u8
)(evData0
>> 16);
7358 switch (ReasonCode
) {
7359 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED
:
7360 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7361 "SAS Device Status Change: Added: "
7362 "id=%d channel=%d", id
, channel
);
7364 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING
:
7365 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7366 "SAS Device Status Change: Deleted: "
7367 "id=%d channel=%d", id
, channel
);
7369 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA
:
7370 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7371 "SAS Device Status Change: SMART Data: "
7372 "id=%d channel=%d", id
, channel
);
7374 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED
:
7375 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7376 "SAS Device Status Change: No Persistancy: "
7377 "id=%d channel=%d", id
, channel
);
7379 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED
:
7380 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7381 "SAS Device Status Change: Unsupported Device "
7382 "Discovered : id=%d channel=%d", id
, channel
);
7384 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET
:
7385 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7386 "SAS Device Status Change: Internal Device "
7387 "Reset : id=%d channel=%d", id
, channel
);
7389 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL
:
7390 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7391 "SAS Device Status Change: Internal Task "
7392 "Abort : id=%d channel=%d", id
, channel
);
7394 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL
:
7395 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7396 "SAS Device Status Change: Internal Abort "
7397 "Task Set : id=%d channel=%d", id
, channel
);
7399 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL
:
7400 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7401 "SAS Device Status Change: Internal Clear "
7402 "Task Set : id=%d channel=%d", id
, channel
);
7404 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL
:
7405 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7406 "SAS Device Status Change: Internal Query "
7407 "Task : id=%d channel=%d", id
, channel
);
7410 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7411 "SAS Device Status Change: Unknown: "
7412 "id=%d channel=%d", id
, channel
);
7417 case MPI_EVENT_ON_BUS_TIMER_EXPIRED
:
7418 ds
= "Bus Timer Expired";
7420 case MPI_EVENT_QUEUE_FULL
:
7422 u16 curr_depth
= (u16
)(evData0
>> 16);
7423 u8 channel
= (u8
)(evData0
>> 8);
7424 u8 id
= (u8
)(evData0
);
7426 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7427 "Queue Full: channel=%d id=%d depth=%d",
7428 channel
, id
, curr_depth
);
7431 case MPI_EVENT_SAS_SES
:
7432 ds
= "SAS SES Event";
7434 case MPI_EVENT_PERSISTENT_TABLE_FULL
:
7435 ds
= "Persistent Table Full";
7437 case MPI_EVENT_SAS_PHY_LINK_STATUS
:
7439 u8 LinkRates
= (u8
)(evData0
>> 8);
7440 u8 PhyNumber
= (u8
)(evData0
);
7441 LinkRates
= (LinkRates
& MPI_EVENT_SAS_PLS_LR_CURRENT_MASK
) >>
7442 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT
;
7443 switch (LinkRates
) {
7444 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN
:
7445 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7446 "SAS PHY Link Status: Phy=%d:"
7447 " Rate Unknown",PhyNumber
);
7449 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED
:
7450 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7451 "SAS PHY Link Status: Phy=%d:"
7452 " Phy Disabled",PhyNumber
);
7454 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION
:
7455 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7456 "SAS PHY Link Status: Phy=%d:"
7457 " Failed Speed Nego",PhyNumber
);
7459 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE
:
7460 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7461 "SAS PHY Link Status: Phy=%d:"
7462 " Sata OOB Completed",PhyNumber
);
7464 case MPI_EVENT_SAS_PLS_LR_RATE_1_5
:
7465 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7466 "SAS PHY Link Status: Phy=%d:"
7467 " Rate 1.5 Gbps",PhyNumber
);
7469 case MPI_EVENT_SAS_PLS_LR_RATE_3_0
:
7470 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7471 "SAS PHY Link Status: Phy=%d:"
7472 " Rate 3.0 Gbps", PhyNumber
);
7474 case MPI_EVENT_SAS_PLS_LR_RATE_6_0
:
7475 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7476 "SAS PHY Link Status: Phy=%d:"
7477 " Rate 6.0 Gbps", PhyNumber
);
7480 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7481 "SAS PHY Link Status: Phy=%d", PhyNumber
);
7486 case MPI_EVENT_SAS_DISCOVERY_ERROR
:
7487 ds
= "SAS Discovery Error";
7489 case MPI_EVENT_IR_RESYNC_UPDATE
:
7491 u8 resync_complete
= (u8
)(evData0
>> 16);
7492 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7493 "IR Resync Update: Complete = %d:",resync_complete
);
7498 u8 id
= (u8
)(evData0
);
7499 u8 channel
= (u8
)(evData0
>> 8);
7500 u8 phys_num
= (u8
)(evData0
>> 24);
7501 u8 ReasonCode
= (u8
)(evData0
>> 16);
7503 switch (ReasonCode
) {
7504 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED
:
7505 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7506 "IR2: LD State Changed: "
7507 "id=%d channel=%d phys_num=%d",
7508 id
, channel
, phys_num
);
7510 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED
:
7511 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7512 "IR2: PD State Changed "
7513 "id=%d channel=%d phys_num=%d",
7514 id
, channel
, phys_num
);
7516 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL
:
7517 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7518 "IR2: Bad Block Table Full: "
7519 "id=%d channel=%d phys_num=%d",
7520 id
, channel
, phys_num
);
7522 case MPI_EVENT_IR2_RC_PD_INSERTED
:
7523 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7524 "IR2: PD Inserted: "
7525 "id=%d channel=%d phys_num=%d",
7526 id
, channel
, phys_num
);
7528 case MPI_EVENT_IR2_RC_PD_REMOVED
:
7529 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7531 "id=%d channel=%d phys_num=%d",
7532 id
, channel
, phys_num
);
7534 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED
:
7535 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7536 "IR2: Foreign CFG Detected: "
7537 "id=%d channel=%d phys_num=%d",
7538 id
, channel
, phys_num
);
7540 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR
:
7541 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7542 "IR2: Rebuild Medium Error: "
7543 "id=%d channel=%d phys_num=%d",
7544 id
, channel
, phys_num
);
7546 case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED
:
7547 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7548 "IR2: Dual Port Added: "
7549 "id=%d channel=%d phys_num=%d",
7550 id
, channel
, phys_num
);
7552 case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED
:
7553 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7554 "IR2: Dual Port Removed: "
7555 "id=%d channel=%d phys_num=%d",
7556 id
, channel
, phys_num
);
7564 case MPI_EVENT_SAS_DISCOVERY
:
7567 ds
= "SAS Discovery: Start";
7569 ds
= "SAS Discovery: Stop";
7572 case MPI_EVENT_LOG_ENTRY_ADDED
:
7573 ds
= "SAS Log Entry Added";
7576 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE
:
7578 u8 phy_num
= (u8
)(evData0
);
7579 u8 port_num
= (u8
)(evData0
>> 8);
7580 u8 port_width
= (u8
)(evData0
>> 16);
7581 u8 primative
= (u8
)(evData0
>> 24);
7582 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7583 "SAS Broadcase Primative: phy=%d port=%d "
7584 "width=%d primative=0x%02x",
7585 phy_num
, port_num
, port_width
, primative
);
7589 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE
:
7591 u8 reason
= (u8
)(evData0
);
7594 case MPI_EVENT_SAS_INIT_RC_ADDED
:
7595 ds
= "SAS Initiator Status Change: Added";
7597 case MPI_EVENT_SAS_INIT_RC_REMOVED
:
7598 ds
= "SAS Initiator Status Change: Deleted";
7601 ds
= "SAS Initiator Status Change";
7607 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW
:
7609 u8 max_init
= (u8
)(evData0
);
7610 u8 current_init
= (u8
)(evData0
>> 8);
7612 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7613 "SAS Initiator Device Table Overflow: max initiators=%02d "
7614 "current initators=%02d",
7615 max_init
, current_init
);
7618 case MPI_EVENT_SAS_SMP_ERROR
:
7620 u8 status
= (u8
)(evData0
);
7621 u8 port_num
= (u8
)(evData0
>> 8);
7622 u8 result
= (u8
)(evData0
>> 16);
7624 if (status
== MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID
)
7625 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7626 "SAS SMP Error: port=%d result=0x%02x",
7628 else if (status
== MPI_EVENT_SAS_SMP_CRC_ERROR
)
7629 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7630 "SAS SMP Error: port=%d : CRC Error",
7632 else if (status
== MPI_EVENT_SAS_SMP_TIMEOUT
)
7633 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7634 "SAS SMP Error: port=%d : Timeout",
7636 else if (status
== MPI_EVENT_SAS_SMP_NO_DESTINATION
)
7637 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7638 "SAS SMP Error: port=%d : No Destination",
7640 else if (status
== MPI_EVENT_SAS_SMP_BAD_DESTINATION
)
7641 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7642 "SAS SMP Error: port=%d : Bad Destination",
7645 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7646 "SAS SMP Error: port=%d : status=0x%02x",
7651 case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE
:
7653 u8 reason
= (u8
)(evData0
);
7656 case MPI_EVENT_SAS_EXP_RC_ADDED
:
7657 ds
= "Expander Status Change: Added";
7659 case MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING
:
7660 ds
= "Expander Status Change: Deleted";
7663 ds
= "Expander Status Change";
7670 * MPT base "custom" events may be added here...
7677 strncpy(evStr
, ds
, EVENT_DESCR_STR_SZ
);
7680 devtprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
7681 "MPT event:(%02Xh) : %s\n",
7682 ioc
->name
, event
, evStr
));
7684 devtverboseprintk(ioc
, printk(KERN_DEBUG MYNAM
7685 ": Event data:\n"));
7686 for (ii
= 0; ii
< le16_to_cpu(pEventReply
->EventDataLength
); ii
++)
7687 devtverboseprintk(ioc
, printk(" %08x",
7688 le32_to_cpu(pEventReply
->Data
[ii
])));
7689 devtverboseprintk(ioc
, printk(KERN_DEBUG
"\n"));
7692 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7694 * ProcessEventNotification - Route EventNotificationReply to all event handlers
7695 * @ioc: Pointer to MPT_ADAPTER structure
7696 * @pEventReply: Pointer to EventNotification reply frame
7697 * @evHandlers: Pointer to integer, number of event handlers
7699 * Routes a received EventNotificationReply to all currently registered
7701 * Returns sum of event handlers return values.
7704 ProcessEventNotification(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*pEventReply
, int *evHandlers
)
7715 * Do platform normalization of values
7717 event
= le32_to_cpu(pEventReply
->Event
) & 0xFF;
7718 evDataLen
= le16_to_cpu(pEventReply
->EventDataLength
);
7720 evData0
= le32_to_cpu(pEventReply
->Data
[0]);
7723 #ifdef CONFIG_FUSION_LOGGING
7725 mpt_display_event_info(ioc
, pEventReply
);
7729 * Do general / base driver event processing
7732 case MPI_EVENT_EVENT_CHANGE
: /* 0A */
7734 u8 evState
= evData0
& 0xFF;
7736 /* CHECKME! What if evState unexpectedly says OFF (0)? */
7738 /* Update EventState field in cached IocFacts */
7739 if (ioc
->facts
.Function
) {
7740 ioc
->facts
.EventState
= evState
;
7744 case MPI_EVENT_INTEGRATED_RAID
:
7745 mptbase_raid_process_event_data(ioc
,
7746 (MpiEventDataRaid_t
*)pEventReply
->Data
);
7753 * Should this event be logged? Events are written sequentially.
7754 * When buffer is full, start again at the top.
7756 if (ioc
->events
&& (ioc
->eventTypes
& ( 1 << event
))) {
7759 idx
= ioc
->eventContext
% MPTCTL_EVENT_LOG_SIZE
;
7761 ioc
->events
[idx
].event
= event
;
7762 ioc
->events
[idx
].eventContext
= ioc
->eventContext
;
7764 for (ii
= 0; ii
< 2; ii
++) {
7766 ioc
->events
[idx
].data
[ii
] = le32_to_cpu(pEventReply
->Data
[ii
]);
7768 ioc
->events
[idx
].data
[ii
] = 0;
7771 ioc
->eventContext
++;
7776 * Call each currently registered protocol event handler.
7778 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
7779 if (MptEvHandlers
[cb_idx
]) {
7780 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
7781 "Routing Event to event handler #%d\n",
7782 ioc
->name
, cb_idx
));
7783 r
+= (*(MptEvHandlers
[cb_idx
]))(ioc
, pEventReply
);
7787 /* FIXME? Examine results here? */
7790 * If needed, send (a single) EventAck.
7792 if (pEventReply
->AckRequired
== MPI_EVENT_NOTIFICATION_ACK_REQUIRED
) {
7793 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
7794 "EventAck required\n",ioc
->name
));
7795 if ((ii
= SendEventAck(ioc
, pEventReply
)) != 0) {
7796 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SendEventAck returned %d\n",
7801 *evHandlers
= handlers
;
7805 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7807 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
7808 * @ioc: Pointer to MPT_ADAPTER structure
7809 * @log_info: U32 LogInfo reply word from the IOC
7811 * Refer to lsi/mpi_log_fc.h.
7814 mpt_fc_log_info(MPT_ADAPTER
*ioc
, u32 log_info
)
7816 char *desc
= "unknown";
7818 switch (log_info
& 0xFF000000) {
7819 case MPI_IOCLOGINFO_FC_INIT_BASE
:
7820 desc
= "FCP Initiator";
7822 case MPI_IOCLOGINFO_FC_TARGET_BASE
:
7823 desc
= "FCP Target";
7825 case MPI_IOCLOGINFO_FC_LAN_BASE
:
7828 case MPI_IOCLOGINFO_FC_MSG_BASE
:
7829 desc
= "MPI Message Layer";
7831 case MPI_IOCLOGINFO_FC_LINK_BASE
:
7834 case MPI_IOCLOGINFO_FC_CTX_BASE
:
7835 desc
= "Context Manager";
7837 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET
:
7838 desc
= "Invalid Field Offset";
7840 case MPI_IOCLOGINFO_FC_STATE_CHANGE
:
7841 desc
= "State Change Info";
7845 printk(MYIOC_s_INFO_FMT
"LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
7846 ioc
->name
, log_info
, desc
, (log_info
& 0xFFFFFF));
7849 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7851 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
7852 * @ioc: Pointer to MPT_ADAPTER structure
7853 * @log_info: U32 LogInfo word from the IOC
7855 * Refer to lsi/sp_log.h.
7858 mpt_spi_log_info(MPT_ADAPTER
*ioc
, u32 log_info
)
7860 u32 info
= log_info
& 0x00FF0000;
7861 char *desc
= "unknown";
7865 desc
= "bug! MID not found";
7869 desc
= "Parity Error";
7873 desc
= "ASYNC Outbound Overrun";
7877 desc
= "SYNC Offset Error";
7885 desc
= "Msg In Overflow";
7893 desc
= "Outbound DMA Overrun";
7897 desc
= "Task Management";
7901 desc
= "Device Problem";
7905 desc
= "Invalid Phase Change";
7909 desc
= "Untagged Table Size";
7914 printk(MYIOC_s_INFO_FMT
"LogInfo(0x%08x): F/W: %s\n", ioc
->name
, log_info
, desc
);
7917 /* strings for sas loginfo */
7918 static char *originator_str
[] = {
7923 static char *iop_code_str
[] = {
7925 "Invalid SAS Address", /* 01h */
7927 "Invalid Page", /* 03h */
7928 "Diag Message Error", /* 04h */
7929 "Task Terminated", /* 05h */
7930 "Enclosure Management", /* 06h */
7931 "Target Mode" /* 07h */
7933 static char *pl_code_str
[] = {
7935 "Open Failure", /* 01h */
7936 "Invalid Scatter Gather List", /* 02h */
7937 "Wrong Relative Offset or Frame Length", /* 03h */
7938 "Frame Transfer Error", /* 04h */
7939 "Transmit Frame Connected Low", /* 05h */
7940 "SATA Non-NCQ RW Error Bit Set", /* 06h */
7941 "SATA Read Log Receive Data Error", /* 07h */
7942 "SATA NCQ Fail All Commands After Error", /* 08h */
7943 "SATA Error in Receive Set Device Bit FIS", /* 09h */
7944 "Receive Frame Invalid Message", /* 0Ah */
7945 "Receive Context Message Valid Error", /* 0Bh */
7946 "Receive Frame Current Frame Error", /* 0Ch */
7947 "SATA Link Down", /* 0Dh */
7948 "Discovery SATA Init W IOS", /* 0Eh */
7949 "Config Invalid Page", /* 0Fh */
7950 "Discovery SATA Init Timeout", /* 10h */
7953 "IO Not Yet Executed", /* 13h */
7954 "IO Executed", /* 14h */
7955 "Persistent Reservation Out Not Affiliation "
7957 "Open Transmit DMA Abort", /* 16h */
7958 "IO Device Missing Delay Retry", /* 17h */
7959 "IO Cancelled Due to Receive Error", /* 18h */
7967 "Enclosure Management" /* 20h */
7969 static char *ir_code_str
[] = {
7970 "Raid Action Error", /* 00h */
7980 static char *raid_sub_code_str
[] = {
7982 "Volume Creation Failed: Data Passed too "
7984 "Volume Creation Failed: Duplicate Volumes "
7985 "Attempted", /* 02h */
7986 "Volume Creation Failed: Max Number "
7987 "Supported Volumes Exceeded", /* 03h */
7988 "Volume Creation Failed: DMA Error", /* 04h */
7989 "Volume Creation Failed: Invalid Volume Type", /* 05h */
7990 "Volume Creation Failed: Error Reading "
7991 "MFG Page 4", /* 06h */
7992 "Volume Creation Failed: Creating Internal "
7993 "Structures", /* 07h */
8002 "Activation failed: Already Active Volume", /* 10h */
8003 "Activation failed: Unsupported Volume Type", /* 11h */
8004 "Activation failed: Too Many Active Volumes", /* 12h */
8005 "Activation failed: Volume ID in Use", /* 13h */
8006 "Activation failed: Reported Failure", /* 14h */
8007 "Activation failed: Importing a Volume", /* 15h */
8018 "Phys Disk failed: Too Many Phys Disks", /* 20h */
8019 "Phys Disk failed: Data Passed too Large", /* 21h */
8020 "Phys Disk failed: DMA Error", /* 22h */
8021 "Phys Disk failed: Invalid <channel:id>", /* 23h */
8022 "Phys Disk failed: Creating Phys Disk Config "
8035 "Compatibility Error: IR Disabled", /* 30h */
8036 "Compatibility Error: Inquiry Command Failed", /* 31h */
8037 "Compatibility Error: Device not Direct Access "
8038 "Device ", /* 32h */
8039 "Compatibility Error: Removable Device Found", /* 33h */
8040 "Compatibility Error: Device SCSI Version not "
8041 "2 or Higher", /* 34h */
8042 "Compatibility Error: SATA Device, 48 BIT LBA "
8043 "not Supported", /* 35h */
8044 "Compatibility Error: Device doesn't have "
8045 "512 Byte Block Sizes", /* 36h */
8046 "Compatibility Error: Volume Type Check Failed", /* 37h */
8047 "Compatibility Error: Volume Type is "
8048 "Unsupported by FW", /* 38h */
8049 "Compatibility Error: Disk Drive too Small for "
8050 "use in Volume", /* 39h */
8051 "Compatibility Error: Phys Disk for Create "
8052 "Volume not Found", /* 3Ah */
8053 "Compatibility Error: Too Many or too Few "
8054 "Disks for Volume Type", /* 3Bh */
8055 "Compatibility Error: Disk stripe Sizes "
8056 "Must be 64KB", /* 3Ch */
8057 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
8060 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8062 * mpt_sas_log_info - Log information returned from SAS IOC.
8063 * @ioc: Pointer to MPT_ADAPTER structure
8064 * @log_info: U32 LogInfo reply word from the IOC
8065 * @cb_idx: callback function's handle
8067 * Refer to lsi/mpi_log_sas.h.
8070 mpt_sas_log_info(MPT_ADAPTER
*ioc
, u32 log_info
, u8 cb_idx
)
8072 union loginfo_type
{
8081 union loginfo_type sas_loginfo
;
8082 char *originator_desc
= NULL
;
8083 char *code_desc
= NULL
;
8084 char *sub_code_desc
= NULL
;
8086 sas_loginfo
.loginfo
= log_info
;
8087 if ((sas_loginfo
.dw
.bus_type
!= 3 /*SAS*/) &&
8088 (sas_loginfo
.dw
.originator
< ARRAY_SIZE(originator_str
)))
8091 originator_desc
= originator_str
[sas_loginfo
.dw
.originator
];
8093 switch (sas_loginfo
.dw
.originator
) {
8096 if (sas_loginfo
.dw
.code
<
8097 ARRAY_SIZE(iop_code_str
))
8098 code_desc
= iop_code_str
[sas_loginfo
.dw
.code
];
8101 if (sas_loginfo
.dw
.code
<
8102 ARRAY_SIZE(pl_code_str
))
8103 code_desc
= pl_code_str
[sas_loginfo
.dw
.code
];
8106 if (sas_loginfo
.dw
.code
>=
8107 ARRAY_SIZE(ir_code_str
))
8109 code_desc
= ir_code_str
[sas_loginfo
.dw
.code
];
8110 if (sas_loginfo
.dw
.subcode
>=
8111 ARRAY_SIZE(raid_sub_code_str
))
8113 if (sas_loginfo
.dw
.code
== 0)
8115 raid_sub_code_str
[sas_loginfo
.dw
.subcode
];
8121 if (sub_code_desc
!= NULL
)
8122 printk(MYIOC_s_INFO_FMT
8123 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
8124 " SubCode={%s} cb_idx %s\n",
8125 ioc
->name
, log_info
, originator_desc
, code_desc
,
8126 sub_code_desc
, MptCallbacksName
[cb_idx
]);
8127 else if (code_desc
!= NULL
)
8128 printk(MYIOC_s_INFO_FMT
8129 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
8130 " SubCode(0x%04x) cb_idx %s\n",
8131 ioc
->name
, log_info
, originator_desc
, code_desc
,
8132 sas_loginfo
.dw
.subcode
, MptCallbacksName
[cb_idx
]);
8134 printk(MYIOC_s_INFO_FMT
8135 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
8136 " SubCode(0x%04x) cb_idx %s\n",
8137 ioc
->name
, log_info
, originator_desc
,
8138 sas_loginfo
.dw
.code
, sas_loginfo
.dw
.subcode
,
8139 MptCallbacksName
[cb_idx
]);
8142 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8144 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
8145 * @ioc: Pointer to MPT_ADAPTER structure
8146 * @ioc_status: U32 IOCStatus word from IOC
8147 * @mf: Pointer to MPT request frame
8149 * Refer to lsi/mpi.h.
8152 mpt_iocstatus_info_config(MPT_ADAPTER
*ioc
, u32 ioc_status
, MPT_FRAME_HDR
*mf
)
8154 Config_t
*pReq
= (Config_t
*)mf
;
8155 char extend_desc
[EVENT_DESCR_STR_SZ
];
8160 if (pReq
->Header
.PageType
== MPI_CONFIG_PAGETYPE_EXTENDED
)
8161 page_type
= pReq
->ExtPageType
;
8163 page_type
= pReq
->Header
.PageType
;
8166 * ignore invalid page messages for GET_NEXT_HANDLE
8168 form
= le32_to_cpu(pReq
->PageAddress
);
8169 if (ioc_status
== MPI_IOCSTATUS_CONFIG_INVALID_PAGE
) {
8170 if (page_type
== MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE
||
8171 page_type
== MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER
||
8172 page_type
== MPI_CONFIG_EXTPAGETYPE_ENCLOSURE
) {
8173 if ((form
>> MPI_SAS_DEVICE_PGAD_FORM_SHIFT
) ==
8174 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE
)
8177 if (page_type
== MPI_CONFIG_PAGETYPE_FC_DEVICE
)
8178 if ((form
& MPI_FC_DEVICE_PGAD_FORM_MASK
) ==
8179 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID
)
8183 snprintf(extend_desc
, EVENT_DESCR_STR_SZ
,
8184 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
8185 page_type
, pReq
->Header
.PageNumber
, pReq
->Action
, form
);
8187 switch (ioc_status
) {
8189 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION
: /* 0x0020 */
8190 desc
= "Config Page Invalid Action";
8193 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE
: /* 0x0021 */
8194 desc
= "Config Page Invalid Type";
8197 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE
: /* 0x0022 */
8198 desc
= "Config Page Invalid Page";
8201 case MPI_IOCSTATUS_CONFIG_INVALID_DATA
: /* 0x0023 */
8202 desc
= "Config Page Invalid Data";
8205 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS
: /* 0x0024 */
8206 desc
= "Config Page No Defaults";
8209 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT
: /* 0x0025 */
8210 desc
= "Config Page Can't Commit";
8217 dreplyprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"IOCStatus(0x%04X): %s: %s\n",
8218 ioc
->name
, ioc_status
, desc
, extend_desc
));
8222 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
8223 * @ioc: Pointer to MPT_ADAPTER structure
8224 * @ioc_status: U32 IOCStatus word from IOC
8225 * @mf: Pointer to MPT request frame
8227 * Refer to lsi/mpi.h.
8230 mpt_iocstatus_info(MPT_ADAPTER
*ioc
, u32 ioc_status
, MPT_FRAME_HDR
*mf
)
8232 u32 status
= ioc_status
& MPI_IOCSTATUS_MASK
;
8237 /****************************************************************************/
8238 /* Common IOCStatus values for all replies */
8239 /****************************************************************************/
8241 case MPI_IOCSTATUS_INVALID_FUNCTION
: /* 0x0001 */
8242 desc
= "Invalid Function";
8245 case MPI_IOCSTATUS_BUSY
: /* 0x0002 */
8249 case MPI_IOCSTATUS_INVALID_SGL
: /* 0x0003 */
8250 desc
= "Invalid SGL";
8253 case MPI_IOCSTATUS_INTERNAL_ERROR
: /* 0x0004 */
8254 desc
= "Internal Error";
8257 case MPI_IOCSTATUS_RESERVED
: /* 0x0005 */
8261 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES
: /* 0x0006 */
8262 desc
= "Insufficient Resources";
8265 case MPI_IOCSTATUS_INVALID_FIELD
: /* 0x0007 */
8266 desc
= "Invalid Field";
8269 case MPI_IOCSTATUS_INVALID_STATE
: /* 0x0008 */
8270 desc
= "Invalid State";
8273 /****************************************************************************/
8274 /* Config IOCStatus values */
8275 /****************************************************************************/
8277 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION
: /* 0x0020 */
8278 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE
: /* 0x0021 */
8279 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE
: /* 0x0022 */
8280 case MPI_IOCSTATUS_CONFIG_INVALID_DATA
: /* 0x0023 */
8281 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS
: /* 0x0024 */
8282 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT
: /* 0x0025 */
8283 mpt_iocstatus_info_config(ioc
, status
, mf
);
8286 /****************************************************************************/
8287 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
8289 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
8291 /****************************************************************************/
8293 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR
: /* 0x0040 */
8294 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN
: /* 0x0045 */
8295 case MPI_IOCSTATUS_SCSI_INVALID_BUS
: /* 0x0041 */
8296 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID
: /* 0x0042 */
8297 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE
: /* 0x0043 */
8298 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN
: /* 0x0044 */
8299 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR
: /* 0x0046 */
8300 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR
: /* 0x0047 */
8301 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED
: /* 0x0048 */
8302 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH
: /* 0x0049 */
8303 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED
: /* 0x004A */
8304 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED
: /* 0x004B */
8305 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED
: /* 0x004C */
8308 /****************************************************************************/
8309 /* SCSI Target values */
8310 /****************************************************************************/
8312 case MPI_IOCSTATUS_TARGET_PRIORITY_IO
: /* 0x0060 */
8313 desc
= "Target: Priority IO";
8316 case MPI_IOCSTATUS_TARGET_INVALID_PORT
: /* 0x0061 */
8317 desc
= "Target: Invalid Port";
8320 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX
: /* 0x0062 */
8321 desc
= "Target Invalid IO Index:";
8324 case MPI_IOCSTATUS_TARGET_ABORTED
: /* 0x0063 */
8325 desc
= "Target: Aborted";
8328 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE
: /* 0x0064 */
8329 desc
= "Target: No Conn Retryable";
8332 case MPI_IOCSTATUS_TARGET_NO_CONNECTION
: /* 0x0065 */
8333 desc
= "Target: No Connection";
8336 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH
: /* 0x006A */
8337 desc
= "Target: Transfer Count Mismatch";
8340 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT
: /* 0x006B */
8341 desc
= "Target: STS Data not Sent";
8344 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR
: /* 0x006D */
8345 desc
= "Target: Data Offset Error";
8348 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA
: /* 0x006E */
8349 desc
= "Target: Too Much Write Data";
8352 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT
: /* 0x006F */
8353 desc
= "Target: IU Too Short";
8356 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT
: /* 0x0070 */
8357 desc
= "Target: ACK NAK Timeout";
8360 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED
: /* 0x0071 */
8361 desc
= "Target: Nak Received";
8364 /****************************************************************************/
8365 /* Fibre Channel Direct Access values */
8366 /****************************************************************************/
8368 case MPI_IOCSTATUS_FC_ABORTED
: /* 0x0066 */
8369 desc
= "FC: Aborted";
8372 case MPI_IOCSTATUS_FC_RX_ID_INVALID
: /* 0x0067 */
8373 desc
= "FC: RX ID Invalid";
8376 case MPI_IOCSTATUS_FC_DID_INVALID
: /* 0x0068 */
8377 desc
= "FC: DID Invalid";
8380 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT
: /* 0x0069 */
8381 desc
= "FC: Node Logged Out";
8384 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED
: /* 0x006C */
8385 desc
= "FC: Exchange Canceled";
8388 /****************************************************************************/
8390 /****************************************************************************/
8392 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND
: /* 0x0080 */
8393 desc
= "LAN: Device not Found";
8396 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE
: /* 0x0081 */
8397 desc
= "LAN: Device Failure";
8400 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR
: /* 0x0082 */
8401 desc
= "LAN: Transmit Error";
8404 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED
: /* 0x0083 */
8405 desc
= "LAN: Transmit Aborted";
8408 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR
: /* 0x0084 */
8409 desc
= "LAN: Receive Error";
8412 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED
: /* 0x0085 */
8413 desc
= "LAN: Receive Aborted";
8416 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET
: /* 0x0086 */
8417 desc
= "LAN: Partial Packet";
8420 case MPI_IOCSTATUS_LAN_CANCELED
: /* 0x0087 */
8421 desc
= "LAN: Canceled";
8424 /****************************************************************************/
8425 /* Serial Attached SCSI values */
8426 /****************************************************************************/
8428 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED
: /* 0x0090 */
8429 desc
= "SAS: SMP Request Failed";
8432 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN
: /* 0x0090 */
8433 desc
= "SAS: SMP Data Overrun";
8444 dreplyprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"IOCStatus(0x%04X): %s\n",
8445 ioc
->name
, status
, desc
));
8448 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8449 EXPORT_SYMBOL(mpt_attach
);
8450 EXPORT_SYMBOL(mpt_detach
);
8452 EXPORT_SYMBOL(mpt_resume
);
8453 EXPORT_SYMBOL(mpt_suspend
);
8455 EXPORT_SYMBOL(ioc_list
);
8456 EXPORT_SYMBOL(mpt_register
);
8457 EXPORT_SYMBOL(mpt_deregister
);
8458 EXPORT_SYMBOL(mpt_event_register
);
8459 EXPORT_SYMBOL(mpt_event_deregister
);
8460 EXPORT_SYMBOL(mpt_reset_register
);
8461 EXPORT_SYMBOL(mpt_reset_deregister
);
8462 EXPORT_SYMBOL(mpt_device_driver_register
);
8463 EXPORT_SYMBOL(mpt_device_driver_deregister
);
8464 EXPORT_SYMBOL(mpt_get_msg_frame
);
8465 EXPORT_SYMBOL(mpt_put_msg_frame
);
8466 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri
);
8467 EXPORT_SYMBOL(mpt_free_msg_frame
);
8468 EXPORT_SYMBOL(mpt_send_handshake_request
);
8469 EXPORT_SYMBOL(mpt_verify_adapter
);
8470 EXPORT_SYMBOL(mpt_GetIocState
);
8471 EXPORT_SYMBOL(mpt_print_ioc_summary
);
8472 EXPORT_SYMBOL(mpt_HardResetHandler
);
8473 EXPORT_SYMBOL(mpt_config
);
8474 EXPORT_SYMBOL(mpt_findImVolumes
);
8475 EXPORT_SYMBOL(mpt_alloc_fw_memory
);
8476 EXPORT_SYMBOL(mpt_free_fw_memory
);
8477 EXPORT_SYMBOL(mptbase_sas_persist_operation
);
8478 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0
);
8480 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8482 * fusion_init - Fusion MPT base driver initialization routine.
8484 * Returns 0 for success, non-zero for failure.
8491 show_mptmod_ver(my_NAME
, my_VERSION
);
8492 printk(KERN_INFO COPYRIGHT
"\n");
8494 for (cb_idx
= 0; cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
; cb_idx
++) {
8495 MptCallbacks
[cb_idx
] = NULL
;
8496 MptDriverClass
[cb_idx
] = MPTUNKNOWN_DRIVER
;
8497 MptEvHandlers
[cb_idx
] = NULL
;
8498 MptResetHandlers
[cb_idx
] = NULL
;
8501 /* Register ourselves (mptbase) in order to facilitate
8502 * EventNotification handling.
8504 mpt_base_index
= mpt_register(mptbase_reply
, MPTBASE_DRIVER
,
8507 /* Register for hard reset handling callbacks.
8509 mpt_reset_register(mpt_base_index
, mpt_ioc_reset
);
8511 #ifdef CONFIG_PROC_FS
8512 (void) procmpt_create();
8517 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8519 * fusion_exit - Perform driver unload cleanup.
8521 * This routine frees all resources associated with each MPT adapter
8522 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
8528 mpt_reset_deregister(mpt_base_index
);
8530 #ifdef CONFIG_PROC_FS
8535 module_init(fusion_init
);
8536 module_exit(fusion_exit
);