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>
68 #include "lsi/mpi_log_fc.h"
70 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
71 #define my_NAME "Fusion MPT base driver"
72 #define my_VERSION MPT_LINUX_VERSION_COMMON
73 #define MYNAM "mptbase"
75 MODULE_AUTHOR(MODULEAUTHOR
);
76 MODULE_DESCRIPTION(my_NAME
);
77 MODULE_LICENSE("GPL");
78 MODULE_VERSION(my_VERSION
);
84 static int mpt_msi_enable_spi
;
85 module_param(mpt_msi_enable_spi
, int, 0);
86 MODULE_PARM_DESC(mpt_msi_enable_spi
, " Enable MSI Support for SPI \
87 controllers (default=0)");
89 static int mpt_msi_enable_fc
;
90 module_param(mpt_msi_enable_fc
, int, 0);
91 MODULE_PARM_DESC(mpt_msi_enable_fc
, " Enable MSI Support for FC \
92 controllers (default=0)");
94 static int mpt_msi_enable_sas
;
95 module_param(mpt_msi_enable_sas
, int, 0);
96 MODULE_PARM_DESC(mpt_msi_enable_sas
, " Enable MSI Support for SAS \
97 controllers (default=0)");
100 static int mpt_channel_mapping
;
101 module_param(mpt_channel_mapping
, int, 0);
102 MODULE_PARM_DESC(mpt_channel_mapping
, " Mapping id's to channels (default=0)");
104 static int mpt_debug_level
;
105 static int mpt_set_debug_level(const char *val
, struct kernel_param
*kp
);
106 module_param_call(mpt_debug_level
, mpt_set_debug_level
, param_get_int
,
107 &mpt_debug_level
, 0600);
108 MODULE_PARM_DESC(mpt_debug_level
, " debug level - refer to mptdebug.h \
111 int mpt_fwfault_debug
;
112 EXPORT_SYMBOL(mpt_fwfault_debug
);
113 module_param(mpt_fwfault_debug
, int, 0600);
114 MODULE_PARM_DESC(mpt_fwfault_debug
, "Enable detection of Firmware fault"
115 " and halt Firmware on fault - (default=0)");
118 static char MptCallbacksName
[MPT_MAX_PROTOCOL_DRIVERS
][50];
121 static int mfcounter
= 0;
122 #define PRINT_MF_COUNT 20000
125 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
130 #define WHOINIT_UNKNOWN 0xAA
132 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
136 /* Adapter link list */
138 /* Callback lookup table */
139 static MPT_CALLBACK MptCallbacks
[MPT_MAX_PROTOCOL_DRIVERS
];
140 /* Protocol driver class lookup table */
141 static int MptDriverClass
[MPT_MAX_PROTOCOL_DRIVERS
];
142 /* Event handler lookup table */
143 static MPT_EVHANDLER MptEvHandlers
[MPT_MAX_PROTOCOL_DRIVERS
];
144 /* Reset handler lookup table */
145 static MPT_RESETHANDLER MptResetHandlers
[MPT_MAX_PROTOCOL_DRIVERS
];
146 static struct mpt_pci_driver
*MptDeviceDriverHandlers
[MPT_MAX_PROTOCOL_DRIVERS
];
148 #ifdef CONFIG_PROC_FS
149 static struct proc_dir_entry
*mpt_proc_root_dir
;
153 * Driver Callback Index's
155 static u8 mpt_base_index
= MPT_MAX_PROTOCOL_DRIVERS
;
156 static u8 last_drv_idx
;
158 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
162 static irqreturn_t
mpt_interrupt(int irq
, void *bus_id
);
163 static int mptbase_reply(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*req
,
164 MPT_FRAME_HDR
*reply
);
165 static int mpt_handshake_req_reply_wait(MPT_ADAPTER
*ioc
, int reqBytes
,
166 u32
*req
, int replyBytes
, u16
*u16reply
, int maxwait
,
168 static int mpt_do_ioc_recovery(MPT_ADAPTER
*ioc
, u32 reason
, int sleepFlag
);
169 static void mpt_detect_bound_ports(MPT_ADAPTER
*ioc
, struct pci_dev
*pdev
);
170 static void mpt_adapter_disable(MPT_ADAPTER
*ioc
);
171 static void mpt_adapter_dispose(MPT_ADAPTER
*ioc
);
173 static void MptDisplayIocCapabilities(MPT_ADAPTER
*ioc
);
174 static int MakeIocReady(MPT_ADAPTER
*ioc
, int force
, int sleepFlag
);
175 static int GetIocFacts(MPT_ADAPTER
*ioc
, int sleepFlag
, int reason
);
176 static int GetPortFacts(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
);
177 static int SendIocInit(MPT_ADAPTER
*ioc
, int sleepFlag
);
178 static int SendPortEnable(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
);
179 static int mpt_do_upload(MPT_ADAPTER
*ioc
, int sleepFlag
);
180 static int mpt_downloadboot(MPT_ADAPTER
*ioc
, MpiFwHeader_t
*pFwHeader
, int sleepFlag
);
181 static int mpt_diag_reset(MPT_ADAPTER
*ioc
, int ignore
, int sleepFlag
);
182 static int KickStart(MPT_ADAPTER
*ioc
, int ignore
, int sleepFlag
);
183 static int SendIocReset(MPT_ADAPTER
*ioc
, u8 reset_type
, int sleepFlag
);
184 static int PrimeIocFifos(MPT_ADAPTER
*ioc
);
185 static int WaitForDoorbellAck(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
);
186 static int WaitForDoorbellInt(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
);
187 static int WaitForDoorbellReply(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
);
188 static int GetLanConfigPages(MPT_ADAPTER
*ioc
);
189 static int GetIoUnitPage2(MPT_ADAPTER
*ioc
);
190 int mptbase_sas_persist_operation(MPT_ADAPTER
*ioc
, u8 persist_opcode
);
191 static int mpt_GetScsiPortSettings(MPT_ADAPTER
*ioc
, int portnum
);
192 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER
*ioc
, int portnum
);
193 static void mpt_read_ioc_pg_1(MPT_ADAPTER
*ioc
);
194 static void mpt_read_ioc_pg_4(MPT_ADAPTER
*ioc
);
195 static void mpt_get_manufacturing_pg_0(MPT_ADAPTER
*ioc
);
196 static int SendEventNotification(MPT_ADAPTER
*ioc
, u8 EvSwitch
,
198 static int SendEventAck(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*evnp
);
199 static int mpt_host_page_access_control(MPT_ADAPTER
*ioc
, u8 access_control_value
, int sleepFlag
);
200 static int mpt_host_page_alloc(MPT_ADAPTER
*ioc
, pIOCInit_t ioc_init
);
202 #ifdef CONFIG_PROC_FS
203 static const struct file_operations mpt_summary_proc_fops
;
204 static const struct file_operations mpt_version_proc_fops
;
205 static const struct file_operations mpt_iocinfo_proc_fops
;
207 static void mpt_get_fw_exp_ver(char *buf
, MPT_ADAPTER
*ioc
);
209 static int ProcessEventNotification(MPT_ADAPTER
*ioc
,
210 EventNotificationReply_t
*evReply
, int *evHandlers
);
211 static void mpt_iocstatus_info(MPT_ADAPTER
*ioc
, u32 ioc_status
, MPT_FRAME_HDR
*mf
);
212 static void mpt_fc_log_info(MPT_ADAPTER
*ioc
, u32 log_info
);
213 static void mpt_spi_log_info(MPT_ADAPTER
*ioc
, u32 log_info
);
214 static void mpt_sas_log_info(MPT_ADAPTER
*ioc
, u32 log_info
, u8 cb_idx
);
215 static int mpt_read_ioc_pg_3(MPT_ADAPTER
*ioc
);
216 static void mpt_inactive_raid_list_free(MPT_ADAPTER
*ioc
);
218 /* module entry point */
219 static int __init
fusion_init (void);
220 static void __exit
fusion_exit (void);
222 #define CHIPREG_READ32(addr) readl_relaxed(addr)
223 #define CHIPREG_READ32_dmasync(addr) readl(addr)
224 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
225 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
226 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
229 pci_disable_io_access(struct pci_dev
*pdev
)
233 pci_read_config_word(pdev
, PCI_COMMAND
, &command_reg
);
235 pci_write_config_word(pdev
, PCI_COMMAND
, command_reg
);
239 pci_enable_io_access(struct pci_dev
*pdev
)
243 pci_read_config_word(pdev
, PCI_COMMAND
, &command_reg
);
245 pci_write_config_word(pdev
, PCI_COMMAND
, command_reg
);
248 static int mpt_set_debug_level(const char *val
, struct kernel_param
*kp
)
250 int ret
= param_set_int(val
, kp
);
256 list_for_each_entry(ioc
, &ioc_list
, list
)
257 ioc
->debug_level
= mpt_debug_level
;
262 * mpt_get_cb_idx - obtain cb_idx for registered driver
263 * @dclass: class driver enum
265 * Returns cb_idx, or zero means it wasn't found
268 mpt_get_cb_idx(MPT_DRIVER_CLASS dclass
)
272 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--)
273 if (MptDriverClass
[cb_idx
] == dclass
)
279 * mpt_is_discovery_complete - determine if discovery has completed
280 * @ioc: per adatper instance
282 * Returns 1 when discovery completed, else zero.
285 mpt_is_discovery_complete(MPT_ADAPTER
*ioc
)
287 ConfigExtendedPageHeader_t hdr
;
289 SasIOUnitPage0_t
*buffer
;
290 dma_addr_t dma_handle
;
293 memset(&hdr
, 0, sizeof(ConfigExtendedPageHeader_t
));
294 memset(&cfg
, 0, sizeof(CONFIGPARMS
));
295 hdr
.PageVersion
= MPI_SASIOUNITPAGE0_PAGEVERSION
;
296 hdr
.PageType
= MPI_CONFIG_PAGETYPE_EXTENDED
;
297 hdr
.ExtPageType
= MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT
;
298 cfg
.cfghdr
.ehdr
= &hdr
;
299 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
301 if ((mpt_config(ioc
, &cfg
)))
303 if (!hdr
.ExtPageLength
)
306 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.ExtPageLength
* 4,
311 cfg
.physAddr
= dma_handle
;
312 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
314 if ((mpt_config(ioc
, &cfg
)))
315 goto out_free_consistent
;
317 if (!(buffer
->PhyData
[0].PortFlags
&
318 MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS
))
322 pci_free_consistent(ioc
->pcidev
, hdr
.ExtPageLength
* 4,
329 * mpt_fault_reset_work - work performed on workq after ioc fault
330 * @work: input argument, used to derive ioc
334 mpt_fault_reset_work(struct work_struct
*work
)
337 container_of(work
, MPT_ADAPTER
, fault_reset_work
.work
);
342 if (ioc
->ioc_reset_in_progress
|| !ioc
->active
)
345 ioc_raw_state
= mpt_GetIocState(ioc
, 0);
346 if ((ioc_raw_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_FAULT
) {
347 printk(MYIOC_s_WARN_FMT
"IOC is in FAULT state (%04xh)!!!\n",
348 ioc
->name
, ioc_raw_state
& MPI_DOORBELL_DATA_MASK
);
349 printk(MYIOC_s_WARN_FMT
"Issuing HardReset from %s!!\n",
350 ioc
->name
, __func__
);
351 rc
= mpt_HardResetHandler(ioc
, CAN_SLEEP
);
352 printk(MYIOC_s_WARN_FMT
"%s: HardReset: %s\n", ioc
->name
,
353 __func__
, (rc
== 0) ? "success" : "failed");
354 ioc_raw_state
= mpt_GetIocState(ioc
, 0);
355 if ((ioc_raw_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_FAULT
)
356 printk(MYIOC_s_WARN_FMT
"IOC is in FAULT state after "
357 "reset (%04xh)\n", ioc
->name
, ioc_raw_state
&
358 MPI_DOORBELL_DATA_MASK
);
359 } else if (ioc
->bus_type
== SAS
&& ioc
->sas_discovery_quiesce_io
) {
360 if ((mpt_is_discovery_complete(ioc
))) {
361 devtprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"clearing "
362 "discovery_quiesce_io flag\n", ioc
->name
));
363 ioc
->sas_discovery_quiesce_io
= 0;
369 * Take turns polling alternate controller
374 /* rearm the timer */
375 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
376 if (ioc
->reset_work_q
)
377 queue_delayed_work(ioc
->reset_work_q
, &ioc
->fault_reset_work
,
378 msecs_to_jiffies(MPT_POLLING_INTERVAL
));
379 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
384 * Process turbo (context) reply...
387 mpt_turbo_reply(MPT_ADAPTER
*ioc
, u32 pa
)
389 MPT_FRAME_HDR
*mf
= NULL
;
390 MPT_FRAME_HDR
*mr
= NULL
;
394 dmfprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Got TURBO reply req_idx=%08x\n",
397 switch (pa
>> MPI_CONTEXT_REPLY_TYPE_SHIFT
) {
398 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT
:
399 req_idx
= pa
& 0x0000FFFF;
400 cb_idx
= (pa
& 0x00FF0000) >> 16;
401 mf
= MPT_INDEX_2_MFPTR(ioc
, req_idx
);
403 case MPI_CONTEXT_REPLY_TYPE_LAN
:
404 cb_idx
= mpt_get_cb_idx(MPTLAN_DRIVER
);
406 * Blind set of mf to NULL here was fatal
407 * after lan_reply says "freeme"
408 * Fix sort of combined with an optimization here;
409 * added explicit check for case where lan_reply
410 * was just returning 1 and doing nothing else.
411 * For this case skip the callback, but set up
412 * proper mf value first here:-)
414 if ((pa
& 0x58000000) == 0x58000000) {
415 req_idx
= pa
& 0x0000FFFF;
416 mf
= MPT_INDEX_2_MFPTR(ioc
, req_idx
);
417 mpt_free_msg_frame(ioc
, mf
);
422 mr
= (MPT_FRAME_HDR
*) CAST_U32_TO_PTR(pa
);
424 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET
:
425 cb_idx
= mpt_get_cb_idx(MPTSTM_DRIVER
);
426 mr
= (MPT_FRAME_HDR
*) CAST_U32_TO_PTR(pa
);
433 /* Check for (valid) IO callback! */
434 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
||
435 MptCallbacks
[cb_idx
] == NULL
) {
436 printk(MYIOC_s_WARN_FMT
"%s: Invalid cb_idx (%d)!\n",
437 __func__
, ioc
->name
, cb_idx
);
441 if (MptCallbacks
[cb_idx
](ioc
, mf
, mr
))
442 mpt_free_msg_frame(ioc
, mf
);
448 mpt_reply(MPT_ADAPTER
*ioc
, u32 pa
)
459 /* non-TURBO reply! Hmmm, something may be up...
460 * Newest turbo reply mechanism; get address
461 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
464 /* Map DMA address of reply header to cpu address.
465 * pa is 32 bits - but the dma address may be 32 or 64 bits
466 * get offset based only only the low addresses
469 reply_dma_low
= (pa
<<= 1);
470 mr
= (MPT_FRAME_HDR
*)((u8
*)ioc
->reply_frames
+
471 (reply_dma_low
- ioc
->reply_frames_low_dma
));
473 req_idx
= le16_to_cpu(mr
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
);
474 cb_idx
= mr
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
;
475 mf
= MPT_INDEX_2_MFPTR(ioc
, req_idx
);
477 dmfprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
478 ioc
->name
, mr
, req_idx
, cb_idx
, mr
->u
.hdr
.Function
));
479 DBG_DUMP_REPLY_FRAME(ioc
, (u32
*)mr
);
481 /* Check/log IOC log info
483 ioc_stat
= le16_to_cpu(mr
->u
.reply
.IOCStatus
);
484 if (ioc_stat
& MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE
) {
485 u32 log_info
= le32_to_cpu(mr
->u
.reply
.IOCLogInfo
);
486 if (ioc
->bus_type
== FC
)
487 mpt_fc_log_info(ioc
, log_info
);
488 else if (ioc
->bus_type
== SPI
)
489 mpt_spi_log_info(ioc
, log_info
);
490 else if (ioc
->bus_type
== SAS
)
491 mpt_sas_log_info(ioc
, log_info
, cb_idx
);
494 if (ioc_stat
& MPI_IOCSTATUS_MASK
)
495 mpt_iocstatus_info(ioc
, (u32
)ioc_stat
, mf
);
497 /* Check for (valid) IO callback! */
498 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
||
499 MptCallbacks
[cb_idx
] == NULL
) {
500 printk(MYIOC_s_WARN_FMT
"%s: Invalid cb_idx (%d)!\n",
501 __func__
, ioc
->name
, cb_idx
);
506 freeme
= MptCallbacks
[cb_idx
](ioc
, mf
, mr
);
509 /* Flush (non-TURBO) reply with a WRITE! */
510 CHIPREG_WRITE32(&ioc
->chip
->ReplyFifo
, pa
);
513 mpt_free_msg_frame(ioc
, mf
);
517 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
519 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
520 * @irq: irq number (not used)
521 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
523 * This routine is registered via the request_irq() kernel API call,
524 * and handles all interrupts generated from a specific MPT adapter
525 * (also referred to as a IO Controller or IOC).
526 * This routine must clear the interrupt from the adapter and does
527 * so by reading the reply FIFO. Multiple replies may be processed
528 * per single call to this routine.
530 * This routine handles register-level access of the adapter but
531 * dispatches (calls) a protocol-specific callback routine to handle
532 * the protocol-specific details of the MPT request completion.
535 mpt_interrupt(int irq
, void *bus_id
)
537 MPT_ADAPTER
*ioc
= bus_id
;
538 u32 pa
= CHIPREG_READ32_dmasync(&ioc
->chip
->ReplyFifo
);
540 if (pa
== 0xFFFFFFFF)
544 * Drain the reply FIFO!
547 if (pa
& MPI_ADDRESS_REPLY_A_BIT
)
550 mpt_turbo_reply(ioc
, pa
);
551 pa
= CHIPREG_READ32_dmasync(&ioc
->chip
->ReplyFifo
);
552 } while (pa
!= 0xFFFFFFFF);
557 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
559 * mptbase_reply - MPT base driver's callback routine
560 * @ioc: Pointer to MPT_ADAPTER structure
561 * @req: Pointer to original MPT request frame
562 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
564 * MPT base driver's callback routine; all base driver
565 * "internal" request/reply processing is routed here.
566 * Currently used for EventNotification and EventAck handling.
568 * Returns 1 indicating original alloc'd request frame ptr
569 * should be freed, or 0 if it shouldn't.
572 mptbase_reply(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*req
, MPT_FRAME_HDR
*reply
)
574 EventNotificationReply_t
*pEventReply
;
579 switch (reply
->u
.hdr
.Function
) {
580 case MPI_FUNCTION_EVENT_NOTIFICATION
:
581 pEventReply
= (EventNotificationReply_t
*)reply
;
583 ProcessEventNotification(ioc
, pEventReply
, &evHandlers
);
584 event
= le32_to_cpu(pEventReply
->Event
) & 0xFF;
585 if (pEventReply
->MsgFlags
& MPI_MSGFLAGS_CONTINUATION_REPLY
)
587 if (event
!= MPI_EVENT_EVENT_CHANGE
)
589 case MPI_FUNCTION_CONFIG
:
590 case MPI_FUNCTION_SAS_IO_UNIT_CONTROL
:
591 ioc
->mptbase_cmds
.status
|= MPT_MGMT_STATUS_COMMAND_GOOD
;
593 ioc
->mptbase_cmds
.status
|= MPT_MGMT_STATUS_RF_VALID
;
594 memcpy(ioc
->mptbase_cmds
.reply
, reply
,
595 min(MPT_DEFAULT_FRAME_SIZE
,
596 4 * reply
->u
.reply
.MsgLength
));
598 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_PENDING
) {
599 ioc
->mptbase_cmds
.status
&= ~MPT_MGMT_STATUS_PENDING
;
600 complete(&ioc
->mptbase_cmds
.done
);
603 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_FREE_MF
)
606 case MPI_FUNCTION_EVENT_ACK
:
607 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
608 "EventAck reply received\n", ioc
->name
));
611 printk(MYIOC_s_ERR_FMT
612 "Unexpected msg function (=%02Xh) reply received!\n",
613 ioc
->name
, reply
->u
.hdr
.Function
);
618 * Conditionally tell caller to free the original
619 * EventNotification/EventAck/unexpected request frame!
624 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
626 * mpt_register - Register protocol-specific main callback handler.
627 * @cbfunc: callback function pointer
628 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
629 * @func_name: call function's name
631 * This routine is called by a protocol-specific driver (SCSI host,
632 * LAN, SCSI target) to register its reply callback routine. Each
633 * protocol-specific driver must do this before it will be able to
634 * use any IOC resources, such as obtaining request frames.
636 * NOTES: The SCSI protocol driver currently calls this routine thrice
637 * in order to register separate callbacks; one for "normal" SCSI IO;
638 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
640 * Returns u8 valued "handle" in the range (and S.O.D. order)
641 * {N,...,7,6,5,...,1} if successful.
642 * A return value of MPT_MAX_PROTOCOL_DRIVERS (including zero!) should be
643 * considered an error by the caller.
646 mpt_register(MPT_CALLBACK cbfunc
, MPT_DRIVER_CLASS dclass
, char *func_name
)
649 last_drv_idx
= MPT_MAX_PROTOCOL_DRIVERS
;
652 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
653 * (slot/handle 0 is reserved!)
655 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
656 if (MptCallbacks
[cb_idx
] == NULL
) {
657 MptCallbacks
[cb_idx
] = cbfunc
;
658 MptDriverClass
[cb_idx
] = dclass
;
659 MptEvHandlers
[cb_idx
] = NULL
;
660 last_drv_idx
= cb_idx
;
661 memcpy(MptCallbacksName
[cb_idx
], func_name
,
662 strlen(func_name
) > 50 ? 50 : strlen(func_name
));
670 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
672 * mpt_deregister - Deregister a protocol drivers resources.
673 * @cb_idx: previously registered callback handle
675 * Each protocol-specific driver should call this routine when its
676 * module is unloaded.
679 mpt_deregister(u8 cb_idx
)
681 if (cb_idx
&& (cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
)) {
682 MptCallbacks
[cb_idx
] = NULL
;
683 MptDriverClass
[cb_idx
] = MPTUNKNOWN_DRIVER
;
684 MptEvHandlers
[cb_idx
] = NULL
;
690 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
692 * mpt_event_register - Register protocol-specific event callback handler.
693 * @cb_idx: previously registered (via mpt_register) callback handle
694 * @ev_cbfunc: callback function
696 * This routine can be called by one or more protocol-specific drivers
697 * if/when they choose to be notified of MPT events.
699 * Returns 0 for success.
702 mpt_event_register(u8 cb_idx
, MPT_EVHANDLER ev_cbfunc
)
704 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
707 MptEvHandlers
[cb_idx
] = ev_cbfunc
;
711 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
713 * mpt_event_deregister - Deregister protocol-specific event callback handler
714 * @cb_idx: previously registered callback handle
716 * Each protocol-specific driver should call this routine
717 * when it does not (or can no longer) handle events,
718 * or when its module is unloaded.
721 mpt_event_deregister(u8 cb_idx
)
723 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
726 MptEvHandlers
[cb_idx
] = NULL
;
729 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
731 * mpt_reset_register - Register protocol-specific IOC reset handler.
732 * @cb_idx: previously registered (via mpt_register) callback handle
733 * @reset_func: reset function
735 * This routine can be called by one or more protocol-specific drivers
736 * if/when they choose to be notified of IOC resets.
738 * Returns 0 for success.
741 mpt_reset_register(u8 cb_idx
, MPT_RESETHANDLER reset_func
)
743 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
746 MptResetHandlers
[cb_idx
] = reset_func
;
750 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
752 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
753 * @cb_idx: previously registered callback handle
755 * Each protocol-specific driver should call this routine
756 * when it does not (or can no longer) handle IOC reset handling,
757 * or when its module is unloaded.
760 mpt_reset_deregister(u8 cb_idx
)
762 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
765 MptResetHandlers
[cb_idx
] = NULL
;
768 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
770 * mpt_device_driver_register - Register device driver hooks
771 * @dd_cbfunc: driver callbacks struct
772 * @cb_idx: MPT protocol driver index
775 mpt_device_driver_register(struct mpt_pci_driver
* dd_cbfunc
, u8 cb_idx
)
778 const struct pci_device_id
*id
;
780 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
783 MptDeviceDriverHandlers
[cb_idx
] = dd_cbfunc
;
785 /* call per pci device probe entry point */
786 list_for_each_entry(ioc
, &ioc_list
, list
) {
787 id
= ioc
->pcidev
->driver
?
788 ioc
->pcidev
->driver
->id_table
: NULL
;
789 if (dd_cbfunc
->probe
)
790 dd_cbfunc
->probe(ioc
->pcidev
, id
);
796 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
798 * mpt_device_driver_deregister - DeRegister device driver hooks
799 * @cb_idx: MPT protocol driver index
802 mpt_device_driver_deregister(u8 cb_idx
)
804 struct mpt_pci_driver
*dd_cbfunc
;
807 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
810 dd_cbfunc
= MptDeviceDriverHandlers
[cb_idx
];
812 list_for_each_entry(ioc
, &ioc_list
, list
) {
813 if (dd_cbfunc
->remove
)
814 dd_cbfunc
->remove(ioc
->pcidev
);
817 MptDeviceDriverHandlers
[cb_idx
] = NULL
;
821 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
823 * mpt_get_msg_frame - Obtain an MPT request frame from the pool
824 * @cb_idx: Handle of registered MPT protocol driver
825 * @ioc: Pointer to MPT adapter structure
827 * Obtain an MPT request frame from the pool (of 1024) that are
828 * allocated per MPT adapter.
830 * Returns pointer to a MPT request frame or %NULL if none are available
831 * or IOC is not active.
834 mpt_get_msg_frame(u8 cb_idx
, MPT_ADAPTER
*ioc
)
838 u16 req_idx
; /* Request index */
840 /* validate handle and ioc identifier */
844 printk(MYIOC_s_WARN_FMT
"IOC Not Active! mpt_get_msg_frame "
845 "returning NULL!\n", ioc
->name
);
848 /* If interrupts are not attached, do not return a request frame */
852 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
853 if (!list_empty(&ioc
->FreeQ
)) {
856 mf
= list_entry(ioc
->FreeQ
.next
, MPT_FRAME_HDR
,
857 u
.frame
.linkage
.list
);
858 list_del(&mf
->u
.frame
.linkage
.list
);
859 mf
->u
.frame
.linkage
.arg1
= 0;
860 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= cb_idx
; /* byte */
861 req_offset
= (u8
*)mf
- (u8
*)ioc
->req_frames
;
863 req_idx
= req_offset
/ ioc
->req_sz
;
864 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(req_idx
);
865 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.rsvd
= 0;
866 /* Default, will be changed if necessary in SG generation */
867 ioc
->RequestNB
[req_idx
] = ioc
->NB_for_64_byte_frame
;
874 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
878 printk(MYIOC_s_WARN_FMT
"IOC Active. No free Msg Frames! "
879 "Count 0x%x Max 0x%x\n", ioc
->name
, ioc
->mfcnt
,
882 if (mfcounter
== PRINT_MF_COUNT
)
883 printk(MYIOC_s_INFO_FMT
"MF Count 0x%x Max 0x%x \n", ioc
->name
,
884 ioc
->mfcnt
, ioc
->req_depth
);
887 dmfprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mpt_get_msg_frame(%d,%d), got mf=%p\n",
888 ioc
->name
, cb_idx
, ioc
->id
, mf
));
892 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
894 * mpt_put_msg_frame - Send a protocol-specific MPT request frame to an IOC
895 * @cb_idx: Handle of registered MPT protocol driver
896 * @ioc: Pointer to MPT adapter structure
897 * @mf: Pointer to MPT request frame
899 * This routine posts an MPT request frame to the request post FIFO of a
900 * specific MPT adapter.
903 mpt_put_msg_frame(u8 cb_idx
, MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
)
907 u16 req_idx
; /* Request index */
909 /* ensure values are reset properly! */
910 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= cb_idx
; /* byte */
911 req_offset
= (u8
*)mf
- (u8
*)ioc
->req_frames
;
913 req_idx
= req_offset
/ ioc
->req_sz
;
914 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(req_idx
);
915 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.rsvd
= 0;
917 DBG_DUMP_PUT_MSG_FRAME(ioc
, (u32
*)mf
);
919 mf_dma_addr
= (ioc
->req_frames_low_dma
+ req_offset
) | ioc
->RequestNB
[req_idx
];
920 dsgprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mf_dma_addr=%x req_idx=%d "
921 "RequestNB=%x\n", ioc
->name
, mf_dma_addr
, req_idx
,
922 ioc
->RequestNB
[req_idx
]));
923 CHIPREG_WRITE32(&ioc
->chip
->RequestFifo
, mf_dma_addr
);
927 * mpt_put_msg_frame_hi_pri - Send a hi-pri protocol-specific MPT request frame
928 * @cb_idx: Handle of registered MPT protocol driver
929 * @ioc: Pointer to MPT adapter structure
930 * @mf: Pointer to MPT request frame
932 * Send a protocol-specific MPT request frame to an IOC using
933 * hi-priority request queue.
935 * This routine posts an MPT request frame to the request post FIFO of a
936 * specific MPT adapter.
939 mpt_put_msg_frame_hi_pri(u8 cb_idx
, MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
)
943 u16 req_idx
; /* Request index */
945 /* ensure values are reset properly! */
946 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= cb_idx
;
947 req_offset
= (u8
*)mf
- (u8
*)ioc
->req_frames
;
948 req_idx
= req_offset
/ ioc
->req_sz
;
949 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(req_idx
);
950 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.rsvd
= 0;
952 DBG_DUMP_PUT_MSG_FRAME(ioc
, (u32
*)mf
);
954 mf_dma_addr
= (ioc
->req_frames_low_dma
+ req_offset
);
955 dsgprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mf_dma_addr=%x req_idx=%d\n",
956 ioc
->name
, mf_dma_addr
, req_idx
));
957 CHIPREG_WRITE32(&ioc
->chip
->RequestHiPriFifo
, mf_dma_addr
);
960 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
962 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
963 * @ioc: Pointer to MPT adapter structure
964 * @mf: Pointer to MPT request frame
966 * This routine places a MPT request frame back on the MPT adapter's
970 mpt_free_msg_frame(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
)
974 /* Put Request back on FreeQ! */
975 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
976 if (cpu_to_le32(mf
->u
.frame
.linkage
.arg1
) == 0xdeadbeaf)
978 /* signature to know if this mf is freed */
979 mf
->u
.frame
.linkage
.arg1
= cpu_to_le32(0xdeadbeaf);
980 list_add_tail(&mf
->u
.frame
.linkage
.list
, &ioc
->FreeQ
);
985 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
988 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
990 * mpt_add_sge - Place a simple 32 bit SGE at address pAddr.
991 * @pAddr: virtual address for SGE
992 * @flagslength: SGE flags and data transfer length
993 * @dma_addr: Physical address
995 * This routine places a MPT request frame back on the MPT adapter's
999 mpt_add_sge(void *pAddr
, u32 flagslength
, dma_addr_t dma_addr
)
1001 SGESimple32_t
*pSge
= (SGESimple32_t
*) pAddr
;
1002 pSge
->FlagsLength
= cpu_to_le32(flagslength
);
1003 pSge
->Address
= cpu_to_le32(dma_addr
);
1007 * mpt_add_sge_64bit - Place a simple 64 bit SGE at address pAddr.
1008 * @pAddr: virtual address for SGE
1009 * @flagslength: SGE flags and data transfer length
1010 * @dma_addr: Physical address
1012 * This routine places a MPT request frame back on the MPT adapter's
1016 mpt_add_sge_64bit(void *pAddr
, u32 flagslength
, dma_addr_t dma_addr
)
1018 SGESimple64_t
*pSge
= (SGESimple64_t
*) pAddr
;
1019 pSge
->Address
.Low
= cpu_to_le32
1020 (lower_32_bits(dma_addr
));
1021 pSge
->Address
.High
= cpu_to_le32
1022 (upper_32_bits(dma_addr
));
1023 pSge
->FlagsLength
= cpu_to_le32
1024 ((flagslength
| MPT_SGE_FLAGS_64_BIT_ADDRESSING
));
1028 * mpt_add_sge_64bit_1078 - Place a simple 64 bit SGE at address pAddr (1078 workaround).
1029 * @pAddr: virtual address for SGE
1030 * @flagslength: SGE flags and data transfer length
1031 * @dma_addr: Physical address
1033 * This routine places a MPT request frame back on the MPT adapter's
1037 mpt_add_sge_64bit_1078(void *pAddr
, u32 flagslength
, dma_addr_t dma_addr
)
1039 SGESimple64_t
*pSge
= (SGESimple64_t
*) pAddr
;
1042 pSge
->Address
.Low
= cpu_to_le32
1043 (lower_32_bits(dma_addr
));
1044 tmp
= (u32
)(upper_32_bits(dma_addr
));
1047 * 1078 errata workaround for the 36GB limitation
1049 if ((((u64
)dma_addr
+ MPI_SGE_LENGTH(flagslength
)) >> 32) == 9) {
1051 MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_LOCAL_ADDRESS
);
1053 if (mpt_debug_level
& MPT_DEBUG_36GB_MEM
)
1054 printk(KERN_DEBUG
"1078 P0M2 addressing for "
1055 "addr = 0x%llx len = %d\n",
1056 (unsigned long long)dma_addr
,
1057 MPI_SGE_LENGTH(flagslength
));
1060 pSge
->Address
.High
= cpu_to_le32(tmp
);
1061 pSge
->FlagsLength
= cpu_to_le32(
1062 (flagslength
| MPT_SGE_FLAGS_64_BIT_ADDRESSING
));
1065 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1067 * mpt_add_chain - Place a 32 bit chain SGE at address pAddr.
1068 * @pAddr: virtual address for SGE
1069 * @next: nextChainOffset value (u32's)
1070 * @length: length of next SGL segment
1071 * @dma_addr: Physical address
1075 mpt_add_chain(void *pAddr
, u8 next
, u16 length
, dma_addr_t dma_addr
)
1077 SGEChain32_t
*pChain
= (SGEChain32_t
*) pAddr
;
1078 pChain
->Length
= cpu_to_le16(length
);
1079 pChain
->Flags
= MPI_SGE_FLAGS_CHAIN_ELEMENT
;
1080 pChain
->NextChainOffset
= next
;
1081 pChain
->Address
= cpu_to_le32(dma_addr
);
1084 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1086 * mpt_add_chain_64bit - Place a 64 bit chain SGE at address pAddr.
1087 * @pAddr: virtual address for SGE
1088 * @next: nextChainOffset value (u32's)
1089 * @length: length of next SGL segment
1090 * @dma_addr: Physical address
1094 mpt_add_chain_64bit(void *pAddr
, u8 next
, u16 length
, dma_addr_t dma_addr
)
1096 SGEChain64_t
*pChain
= (SGEChain64_t
*) pAddr
;
1097 u32 tmp
= dma_addr
& 0xFFFFFFFF;
1099 pChain
->Length
= cpu_to_le16(length
);
1100 pChain
->Flags
= (MPI_SGE_FLAGS_CHAIN_ELEMENT
|
1101 MPI_SGE_FLAGS_64_BIT_ADDRESSING
);
1103 pChain
->NextChainOffset
= next
;
1105 pChain
->Address
.Low
= cpu_to_le32(tmp
);
1106 tmp
= (u32
)(upper_32_bits(dma_addr
));
1107 pChain
->Address
.High
= cpu_to_le32(tmp
);
1110 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1112 * mpt_send_handshake_request - Send MPT request via doorbell handshake method.
1113 * @cb_idx: Handle of registered MPT protocol driver
1114 * @ioc: Pointer to MPT adapter structure
1115 * @reqBytes: Size of the request in bytes
1116 * @req: Pointer to MPT request frame
1117 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1119 * This routine is used exclusively to send MptScsiTaskMgmt
1120 * requests since they are required to be sent via doorbell handshake.
1122 * NOTE: It is the callers responsibility to byte-swap fields in the
1123 * request which are greater than 1 byte in size.
1125 * Returns 0 for success, non-zero for failure.
1128 mpt_send_handshake_request(u8 cb_idx
, MPT_ADAPTER
*ioc
, int reqBytes
, u32
*req
, int sleepFlag
)
1134 /* State is known to be good upon entering
1135 * this function so issue the bus reset
1140 * Emulate what mpt_put_msg_frame() does /wrt to sanity
1141 * setting cb_idx/req_idx. But ONLY if this request
1142 * is in proper (pre-alloc'd) request buffer range...
1144 ii
= MFPTR_2_MPT_INDEX(ioc
,(MPT_FRAME_HDR
*)req
);
1145 if (reqBytes
>= 12 && ii
>= 0 && ii
< ioc
->req_depth
) {
1146 MPT_FRAME_HDR
*mf
= (MPT_FRAME_HDR
*)req
;
1147 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(ii
);
1148 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= cb_idx
;
1151 /* Make sure there are no doorbells */
1152 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1154 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
,
1155 ((MPI_FUNCTION_HANDSHAKE
<<MPI_DOORBELL_FUNCTION_SHIFT
) |
1156 ((reqBytes
/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT
)));
1158 /* Wait for IOC doorbell int */
1159 if ((ii
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0) {
1163 /* Read doorbell and check for active bit */
1164 if (!(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & MPI_DOORBELL_ACTIVE
))
1167 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mpt_send_handshake_request start, WaitCnt=%d\n",
1170 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1172 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0) {
1176 /* Send request via doorbell handshake */
1177 req_as_bytes
= (u8
*) req
;
1178 for (ii
= 0; ii
< reqBytes
/4; ii
++) {
1181 word
= ((req_as_bytes
[(ii
*4) + 0] << 0) |
1182 (req_as_bytes
[(ii
*4) + 1] << 8) |
1183 (req_as_bytes
[(ii
*4) + 2] << 16) |
1184 (req_as_bytes
[(ii
*4) + 3] << 24));
1185 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, word
);
1186 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0) {
1192 if (r
>= 0 && WaitForDoorbellInt(ioc
, 10, sleepFlag
) >= 0)
1197 /* Make sure there are no doorbells */
1198 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1203 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1205 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
1206 * @ioc: Pointer to MPT adapter structure
1207 * @access_control_value: define bits below
1208 * @sleepFlag: Specifies whether the process can sleep
1210 * Provides mechanism for the host driver to control the IOC's
1211 * Host Page Buffer access.
1213 * Access Control Value - bits[15:12]
1215 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1216 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1217 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1219 * Returns 0 for success, non-zero for failure.
1223 mpt_host_page_access_control(MPT_ADAPTER
*ioc
, u8 access_control_value
, int sleepFlag
)
1227 /* return if in use */
1228 if (CHIPREG_READ32(&ioc
->chip
->Doorbell
)
1229 & MPI_DOORBELL_ACTIVE
)
1232 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1234 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
,
1235 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1236 <<MPI_DOORBELL_FUNCTION_SHIFT
) |
1237 (access_control_value
<<12)));
1239 /* Wait for IOC to clear Doorbell Status bit */
1240 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0) {
1246 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1248 * mpt_host_page_alloc - allocate system memory for the fw
1249 * @ioc: Pointer to pointer to IOC adapter
1250 * @ioc_init: Pointer to ioc init config page
1252 * If we already allocated memory in past, then resend the same pointer.
1253 * Returns 0 for success, non-zero for failure.
1256 mpt_host_page_alloc(MPT_ADAPTER
*ioc
, pIOCInit_t ioc_init
)
1260 u32 host_page_buffer_sz
=0;
1262 if(!ioc
->HostPageBuffer
) {
1264 host_page_buffer_sz
=
1265 le32_to_cpu(ioc
->facts
.HostPageBufferSGE
.FlagsLength
) & 0xFFFFFF;
1267 if(!host_page_buffer_sz
)
1268 return 0; /* fw doesn't need any host buffers */
1270 /* spin till we get enough memory */
1271 while(host_page_buffer_sz
> 0) {
1273 if((ioc
->HostPageBuffer
= pci_alloc_consistent(
1275 host_page_buffer_sz
,
1276 &ioc
->HostPageBuffer_dma
)) != NULL
) {
1278 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
1279 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1280 ioc
->name
, ioc
->HostPageBuffer
,
1281 (u32
)ioc
->HostPageBuffer_dma
,
1282 host_page_buffer_sz
));
1283 ioc
->alloc_total
+= host_page_buffer_sz
;
1284 ioc
->HostPageBuffer_sz
= host_page_buffer_sz
;
1288 host_page_buffer_sz
-= (4*1024);
1292 if(!ioc
->HostPageBuffer
) {
1293 printk(MYIOC_s_ERR_FMT
1294 "Failed to alloc memory for host_page_buffer!\n",
1299 psge
= (char *)&ioc_init
->HostPageBufferSGE
;
1300 flags_length
= MPI_SGE_FLAGS_SIMPLE_ELEMENT
|
1301 MPI_SGE_FLAGS_SYSTEM_ADDRESS
|
1302 MPI_SGE_FLAGS_HOST_TO_IOC
|
1303 MPI_SGE_FLAGS_END_OF_BUFFER
;
1304 flags_length
= flags_length
<< MPI_SGE_FLAGS_SHIFT
;
1305 flags_length
|= ioc
->HostPageBuffer_sz
;
1306 ioc
->add_sge(psge
, flags_length
, ioc
->HostPageBuffer_dma
);
1307 ioc
->facts
.HostPageBufferSGE
= ioc_init
->HostPageBufferSGE
;
1312 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1314 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1315 * @iocid: IOC unique identifier (integer)
1316 * @iocpp: Pointer to pointer to IOC adapter
1318 * Given a unique IOC identifier, set pointer to the associated MPT
1319 * adapter structure.
1321 * Returns iocid and sets iocpp if iocid is found.
1322 * Returns -1 if iocid is not found.
1325 mpt_verify_adapter(int iocid
, MPT_ADAPTER
**iocpp
)
1329 list_for_each_entry(ioc
,&ioc_list
,list
) {
1330 if (ioc
->id
== iocid
) {
1341 * mpt_get_product_name - returns product string
1342 * @vendor: pci vendor id
1343 * @device: pci device id
1344 * @revision: pci revision id
1345 * @prod_name: string returned
1347 * Returns product string displayed when driver loads,
1348 * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1352 mpt_get_product_name(u16 vendor
, u16 device
, u8 revision
, char *prod_name
)
1354 char *product_str
= NULL
;
1356 if (vendor
== PCI_VENDOR_ID_BROCADE
) {
1359 case MPI_MANUFACTPAGE_DEVICEID_FC949E
:
1363 product_str
= "BRE040 A0";
1366 product_str
= "BRE040 A1";
1369 product_str
= "BRE040";
1379 case MPI_MANUFACTPAGE_DEVICEID_FC909
:
1380 product_str
= "LSIFC909 B1";
1382 case MPI_MANUFACTPAGE_DEVICEID_FC919
:
1383 product_str
= "LSIFC919 B0";
1385 case MPI_MANUFACTPAGE_DEVICEID_FC929
:
1386 product_str
= "LSIFC929 B0";
1388 case MPI_MANUFACTPAGE_DEVICEID_FC919X
:
1389 if (revision
< 0x80)
1390 product_str
= "LSIFC919X A0";
1392 product_str
= "LSIFC919XL A1";
1394 case MPI_MANUFACTPAGE_DEVICEID_FC929X
:
1395 if (revision
< 0x80)
1396 product_str
= "LSIFC929X A0";
1398 product_str
= "LSIFC929XL A1";
1400 case MPI_MANUFACTPAGE_DEVICEID_FC939X
:
1401 product_str
= "LSIFC939X A1";
1403 case MPI_MANUFACTPAGE_DEVICEID_FC949X
:
1404 product_str
= "LSIFC949X A1";
1406 case MPI_MANUFACTPAGE_DEVICEID_FC949E
:
1410 product_str
= "LSIFC949E A0";
1413 product_str
= "LSIFC949E A1";
1416 product_str
= "LSIFC949E";
1420 case MPI_MANUFACTPAGE_DEVID_53C1030
:
1424 product_str
= "LSI53C1030 A0";
1427 product_str
= "LSI53C1030 B0";
1430 product_str
= "LSI53C1030 B1";
1433 product_str
= "LSI53C1030 B2";
1436 product_str
= "LSI53C1030 C0";
1439 product_str
= "LSI53C1030T A0";
1442 product_str
= "LSI53C1030T A2";
1445 product_str
= "LSI53C1030T A3";
1448 product_str
= "LSI53C1020A A1";
1451 product_str
= "LSI53C1030";
1455 case MPI_MANUFACTPAGE_DEVID_1030_53C1035
:
1459 product_str
= "LSI53C1035 A2";
1462 product_str
= "LSI53C1035 B0";
1465 product_str
= "LSI53C1035";
1469 case MPI_MANUFACTPAGE_DEVID_SAS1064
:
1473 product_str
= "LSISAS1064 A1";
1476 product_str
= "LSISAS1064 A2";
1479 product_str
= "LSISAS1064 A3";
1482 product_str
= "LSISAS1064 A4";
1485 product_str
= "LSISAS1064";
1489 case MPI_MANUFACTPAGE_DEVID_SAS1064E
:
1493 product_str
= "LSISAS1064E A0";
1496 product_str
= "LSISAS1064E B0";
1499 product_str
= "LSISAS1064E B1";
1502 product_str
= "LSISAS1064E B2";
1505 product_str
= "LSISAS1064E B3";
1508 product_str
= "LSISAS1064E";
1512 case MPI_MANUFACTPAGE_DEVID_SAS1068
:
1516 product_str
= "LSISAS1068 A0";
1519 product_str
= "LSISAS1068 B0";
1522 product_str
= "LSISAS1068 B1";
1525 product_str
= "LSISAS1068";
1529 case MPI_MANUFACTPAGE_DEVID_SAS1068E
:
1533 product_str
= "LSISAS1068E A0";
1536 product_str
= "LSISAS1068E B0";
1539 product_str
= "LSISAS1068E B1";
1542 product_str
= "LSISAS1068E B2";
1545 product_str
= "LSISAS1068E B3";
1548 product_str
= "LSISAS1068E";
1552 case MPI_MANUFACTPAGE_DEVID_SAS1078
:
1556 product_str
= "LSISAS1078 A0";
1559 product_str
= "LSISAS1078 B0";
1562 product_str
= "LSISAS1078 C0";
1565 product_str
= "LSISAS1078 C1";
1568 product_str
= "LSISAS1078 C2";
1571 product_str
= "LSISAS1078";
1579 sprintf(prod_name
, "%s", product_str
);
1583 * mpt_mapresources - map in memory mapped io
1584 * @ioc: Pointer to pointer to IOC adapter
1588 mpt_mapresources(MPT_ADAPTER
*ioc
)
1592 resource_size_t mem_phys
;
1598 struct pci_dev
*pdev
;
1601 ioc
->bars
= pci_select_bars(pdev
, IORESOURCE_MEM
);
1602 if (pci_enable_device_mem(pdev
)) {
1603 printk(MYIOC_s_ERR_FMT
"pci_enable_device_mem() "
1604 "failed\n", ioc
->name
);
1607 if (pci_request_selected_regions(pdev
, ioc
->bars
, "mpt")) {
1608 printk(MYIOC_s_ERR_FMT
"pci_request_selected_regions() with "
1609 "MEM failed\n", ioc
->name
);
1613 pci_read_config_byte(pdev
, PCI_CLASS_REVISION
, &revision
);
1615 if (sizeof(dma_addr_t
) > 4) {
1616 const uint64_t required_mask
= dma_get_required_mask
1618 if (required_mask
> DMA_BIT_MASK(32)
1619 && !pci_set_dma_mask(pdev
, DMA_BIT_MASK(64))
1620 && !pci_set_consistent_dma_mask(pdev
,
1621 DMA_BIT_MASK(64))) {
1622 ioc
->dma_mask
= DMA_BIT_MASK(64);
1623 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
1624 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1626 } else if (!pci_set_dma_mask(pdev
, DMA_BIT_MASK(32))
1627 && !pci_set_consistent_dma_mask(pdev
,
1628 DMA_BIT_MASK(32))) {
1629 ioc
->dma_mask
= DMA_BIT_MASK(32);
1630 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
1631 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1634 printk(MYIOC_s_WARN_FMT
"no suitable DMA mask for %s\n",
1635 ioc
->name
, pci_name(pdev
));
1636 pci_release_selected_regions(pdev
, ioc
->bars
);
1640 if (!pci_set_dma_mask(pdev
, DMA_BIT_MASK(32))
1641 && !pci_set_consistent_dma_mask(pdev
,
1642 DMA_BIT_MASK(32))) {
1643 ioc
->dma_mask
= DMA_BIT_MASK(32);
1644 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
1645 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1648 printk(MYIOC_s_WARN_FMT
"no suitable DMA mask for %s\n",
1649 ioc
->name
, pci_name(pdev
));
1650 pci_release_selected_regions(pdev
, ioc
->bars
);
1655 mem_phys
= msize
= 0;
1657 for (ii
= 0; ii
< DEVICE_COUNT_RESOURCE
; ii
++) {
1658 if (pci_resource_flags(pdev
, ii
) & PCI_BASE_ADDRESS_SPACE_IO
) {
1661 /* Get I/O space! */
1662 port
= pci_resource_start(pdev
, ii
);
1663 psize
= pci_resource_len(pdev
, ii
);
1668 mem_phys
= pci_resource_start(pdev
, ii
);
1669 msize
= pci_resource_len(pdev
, ii
);
1672 ioc
->mem_size
= msize
;
1675 /* Get logical ptr for PciMem0 space */
1676 /*mem = ioremap(mem_phys, msize);*/
1677 mem
= ioremap(mem_phys
, msize
);
1679 printk(MYIOC_s_ERR_FMT
": ERROR - Unable to map adapter"
1680 " memory!\n", ioc
->name
);
1681 pci_release_selected_regions(pdev
, ioc
->bars
);
1685 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"mem = %p, mem_phys = %llx\n",
1686 ioc
->name
, mem
, (unsigned long long)mem_phys
));
1688 ioc
->mem_phys
= mem_phys
;
1689 ioc
->chip
= (SYSIF_REGS __iomem
*)mem
;
1691 /* Save Port IO values in case we need to do downloadboot */
1692 ioc
->pio_mem_phys
= port
;
1693 ioc
->pio_chip
= (SYSIF_REGS __iomem
*)port
;
1698 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1700 * mpt_attach - Install a PCI intelligent MPT adapter.
1701 * @pdev: Pointer to pci_dev structure
1702 * @id: PCI device ID information
1704 * This routine performs all the steps necessary to bring the IOC of
1705 * a MPT adapter to a OPERATIONAL state. This includes registering
1706 * memory regions, registering the interrupt, and allocating request
1707 * and reply memory pools.
1709 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1712 * Returns 0 for success, non-zero for failure.
1714 * TODO: Add support for polled controllers
1717 mpt_attach(struct pci_dev
*pdev
, const struct pci_device_id
*id
)
1724 static int mpt_ids
= 0;
1725 #ifdef CONFIG_PROC_FS
1726 struct proc_dir_entry
*dent
;
1729 ioc
= kzalloc(sizeof(MPT_ADAPTER
), GFP_ATOMIC
);
1731 printk(KERN_ERR MYNAM
": ERROR - Insufficient memory to add adapter!\n");
1735 ioc
->id
= mpt_ids
++;
1736 sprintf(ioc
->name
, "ioc%d", ioc
->id
);
1737 dinitprintk(ioc
, printk(KERN_WARNING MYNAM
": mpt_adapter_install\n"));
1740 * set initial debug level
1741 * (refer to mptdebug.h)
1744 ioc
->debug_level
= mpt_debug_level
;
1745 if (mpt_debug_level
)
1746 printk(KERN_INFO
"mpt_debug_level=%xh\n", mpt_debug_level
);
1748 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
": mpt_adapter_install\n", ioc
->name
));
1751 if (mpt_mapresources(ioc
)) {
1757 * Setting up proper handlers for scatter gather handling
1759 if (ioc
->dma_mask
== DMA_BIT_MASK(64)) {
1760 if (pdev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1078
)
1761 ioc
->add_sge
= &mpt_add_sge_64bit_1078
;
1763 ioc
->add_sge
= &mpt_add_sge_64bit
;
1764 ioc
->add_chain
= &mpt_add_chain_64bit
;
1765 ioc
->sg_addr_size
= 8;
1767 ioc
->add_sge
= &mpt_add_sge
;
1768 ioc
->add_chain
= &mpt_add_chain
;
1769 ioc
->sg_addr_size
= 4;
1771 ioc
->SGE_size
= sizeof(u32
) + ioc
->sg_addr_size
;
1773 ioc
->alloc_total
= sizeof(MPT_ADAPTER
);
1774 ioc
->req_sz
= MPT_DEFAULT_FRAME_SIZE
; /* avoid div by zero! */
1775 ioc
->reply_sz
= MPT_REPLY_FRAME_SIZE
;
1778 spin_lock_init(&ioc
->taskmgmt_lock
);
1779 mutex_init(&ioc
->internal_cmds
.mutex
);
1780 init_completion(&ioc
->internal_cmds
.done
);
1781 mutex_init(&ioc
->mptbase_cmds
.mutex
);
1782 init_completion(&ioc
->mptbase_cmds
.done
);
1783 mutex_init(&ioc
->taskmgmt_cmds
.mutex
);
1784 init_completion(&ioc
->taskmgmt_cmds
.done
);
1786 /* Initialize the event logging.
1788 ioc
->eventTypes
= 0; /* None */
1789 ioc
->eventContext
= 0;
1790 ioc
->eventLogSize
= 0;
1798 ioc
->cached_fw
= NULL
;
1800 /* Initialize SCSI Config Data structure
1802 memset(&ioc
->spi_data
, 0, sizeof(SpiCfgData
));
1804 /* Initialize the fc rport list head.
1806 INIT_LIST_HEAD(&ioc
->fc_rports
);
1808 /* Find lookup slot. */
1809 INIT_LIST_HEAD(&ioc
->list
);
1812 /* Initialize workqueue */
1813 INIT_DELAYED_WORK(&ioc
->fault_reset_work
, mpt_fault_reset_work
);
1815 snprintf(ioc
->reset_work_q_name
, MPT_KOBJ_NAME_LEN
,
1816 "mpt_poll_%d", ioc
->id
);
1818 create_singlethread_workqueue(ioc
->reset_work_q_name
);
1819 if (!ioc
->reset_work_q
) {
1820 printk(MYIOC_s_ERR_FMT
"Insufficient memory to add adapter!\n",
1822 pci_release_selected_regions(pdev
, ioc
->bars
);
1827 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"facts @ %p, pfacts[0] @ %p\n",
1828 ioc
->name
, &ioc
->facts
, &ioc
->pfacts
[0]));
1830 pci_read_config_byte(pdev
, PCI_CLASS_REVISION
, &revision
);
1831 mpt_get_product_name(pdev
->vendor
, pdev
->device
, revision
, ioc
->prod_name
);
1833 switch (pdev
->device
)
1835 case MPI_MANUFACTPAGE_DEVICEID_FC939X
:
1836 case MPI_MANUFACTPAGE_DEVICEID_FC949X
:
1837 ioc
->errata_flag_1064
= 1;
1838 case MPI_MANUFACTPAGE_DEVICEID_FC909
:
1839 case MPI_MANUFACTPAGE_DEVICEID_FC929
:
1840 case MPI_MANUFACTPAGE_DEVICEID_FC919
:
1841 case MPI_MANUFACTPAGE_DEVICEID_FC949E
:
1845 case MPI_MANUFACTPAGE_DEVICEID_FC929X
:
1846 if (revision
< XL_929
) {
1847 /* 929X Chip Fix. Set Split transactions level
1848 * for PCIX. Set MOST bits to zero.
1850 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1852 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1854 /* 929XL Chip Fix. Set MMRBC to 0x08.
1856 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1858 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1863 case MPI_MANUFACTPAGE_DEVICEID_FC919X
:
1864 /* 919X Chip Fix. Set Split transactions level
1865 * for PCIX. Set MOST bits to zero.
1867 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1869 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1873 case MPI_MANUFACTPAGE_DEVID_53C1030
:
1874 /* 1030 Chip Fix. Disable Split transactions
1875 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1877 if (revision
< C0_1030
) {
1878 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1880 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1883 case MPI_MANUFACTPAGE_DEVID_1030_53C1035
:
1884 ioc
->bus_type
= SPI
;
1887 case MPI_MANUFACTPAGE_DEVID_SAS1064
:
1888 case MPI_MANUFACTPAGE_DEVID_SAS1068
:
1889 ioc
->errata_flag_1064
= 1;
1890 ioc
->bus_type
= SAS
;
1893 case MPI_MANUFACTPAGE_DEVID_SAS1064E
:
1894 case MPI_MANUFACTPAGE_DEVID_SAS1068E
:
1895 case MPI_MANUFACTPAGE_DEVID_SAS1078
:
1896 ioc
->bus_type
= SAS
;
1901 switch (ioc
->bus_type
) {
1904 ioc
->msi_enable
= mpt_msi_enable_sas
;
1908 ioc
->msi_enable
= mpt_msi_enable_spi
;
1912 ioc
->msi_enable
= mpt_msi_enable_fc
;
1916 ioc
->msi_enable
= 0;
1920 ioc
->fw_events_off
= 1;
1922 if (ioc
->errata_flag_1064
)
1923 pci_disable_io_access(pdev
);
1925 spin_lock_init(&ioc
->FreeQlock
);
1928 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
1930 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1932 /* Set IOC ptr in the pcidev's driver data. */
1933 pci_set_drvdata(ioc
->pcidev
, ioc
);
1935 /* Set lookup ptr. */
1936 list_add_tail(&ioc
->list
, &ioc_list
);
1938 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1940 mpt_detect_bound_ports(ioc
, pdev
);
1942 INIT_LIST_HEAD(&ioc
->fw_event_list
);
1943 spin_lock_init(&ioc
->fw_event_lock
);
1944 snprintf(ioc
->fw_event_q_name
, MPT_KOBJ_NAME_LEN
, "mpt/%d", ioc
->id
);
1945 ioc
->fw_event_q
= create_singlethread_workqueue(ioc
->fw_event_q_name
);
1947 if ((r
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_BRINGUP
,
1949 printk(MYIOC_s_ERR_FMT
"didn't initialize properly! (%d)\n",
1952 list_del(&ioc
->list
);
1954 ioc
->alt_ioc
->alt_ioc
= NULL
;
1955 iounmap(ioc
->memmap
);
1957 pci_release_selected_regions(pdev
, ioc
->bars
);
1959 destroy_workqueue(ioc
->reset_work_q
);
1960 ioc
->reset_work_q
= NULL
;
1963 pci_set_drvdata(pdev
, NULL
);
1967 /* call per device driver probe entry point */
1968 for(cb_idx
= 0; cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
; cb_idx
++) {
1969 if(MptDeviceDriverHandlers
[cb_idx
] &&
1970 MptDeviceDriverHandlers
[cb_idx
]->probe
) {
1971 MptDeviceDriverHandlers
[cb_idx
]->probe(pdev
,id
);
1975 #ifdef CONFIG_PROC_FS
1977 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1979 dent
= proc_mkdir(ioc
->name
, mpt_proc_root_dir
);
1981 proc_create_data("info", S_IRUGO
, dent
, &mpt_iocinfo_proc_fops
, ioc
);
1982 proc_create_data("summary", S_IRUGO
, dent
, &mpt_summary_proc_fops
, ioc
);
1987 queue_delayed_work(ioc
->reset_work_q
, &ioc
->fault_reset_work
,
1988 msecs_to_jiffies(MPT_POLLING_INTERVAL
));
1993 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1995 * mpt_detach - Remove a PCI intelligent MPT adapter.
1996 * @pdev: Pointer to pci_dev structure
2000 mpt_detach(struct pci_dev
*pdev
)
2002 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
2005 unsigned long flags
;
2006 struct workqueue_struct
*wq
;
2009 * Stop polling ioc for fault condition
2011 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
2012 wq
= ioc
->reset_work_q
;
2013 ioc
->reset_work_q
= NULL
;
2014 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
2015 cancel_delayed_work(&ioc
->fault_reset_work
);
2016 destroy_workqueue(wq
);
2018 spin_lock_irqsave(&ioc
->fw_event_lock
, flags
);
2019 wq
= ioc
->fw_event_q
;
2020 ioc
->fw_event_q
= NULL
;
2021 spin_unlock_irqrestore(&ioc
->fw_event_lock
, flags
);
2022 destroy_workqueue(wq
);
2024 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s/summary", ioc
->name
);
2025 remove_proc_entry(pname
, NULL
);
2026 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s/info", ioc
->name
);
2027 remove_proc_entry(pname
, NULL
);
2028 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s", ioc
->name
);
2029 remove_proc_entry(pname
, NULL
);
2031 /* call per device driver remove entry point */
2032 for(cb_idx
= 0; cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
; cb_idx
++) {
2033 if(MptDeviceDriverHandlers
[cb_idx
] &&
2034 MptDeviceDriverHandlers
[cb_idx
]->remove
) {
2035 MptDeviceDriverHandlers
[cb_idx
]->remove(pdev
);
2039 /* Disable interrupts! */
2040 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2043 synchronize_irq(pdev
->irq
);
2045 /* Clear any lingering interrupt */
2046 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
2048 CHIPREG_READ32(&ioc
->chip
->IntStatus
);
2050 mpt_adapter_dispose(ioc
);
2054 /**************************************************************************
2058 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2060 * mpt_suspend - Fusion MPT base driver suspend routine.
2061 * @pdev: Pointer to pci_dev structure
2062 * @state: new state to enter
2065 mpt_suspend(struct pci_dev
*pdev
, pm_message_t state
)
2068 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
2070 device_state
= pci_choose_state(pdev
, state
);
2071 printk(MYIOC_s_INFO_FMT
"pci-suspend: pdev=0x%p, slot=%s, Entering "
2072 "operating state [D%d]\n", ioc
->name
, pdev
, pci_name(pdev
),
2075 /* put ioc into READY_STATE */
2076 if(SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, CAN_SLEEP
)) {
2077 printk(MYIOC_s_ERR_FMT
2078 "pci-suspend: IOC msg unit reset failed!\n", ioc
->name
);
2081 /* disable interrupts */
2082 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2085 /* Clear any lingering interrupt */
2086 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
2088 free_irq(ioc
->pci_irq
, ioc
);
2089 if (ioc
->msi_enable
)
2090 pci_disable_msi(ioc
->pcidev
);
2092 pci_save_state(pdev
);
2093 pci_disable_device(pdev
);
2094 pci_release_selected_regions(pdev
, ioc
->bars
);
2095 pci_set_power_state(pdev
, device_state
);
2099 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2101 * mpt_resume - Fusion MPT base driver resume routine.
2102 * @pdev: Pointer to pci_dev structure
2105 mpt_resume(struct pci_dev
*pdev
)
2107 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
2108 u32 device_state
= pdev
->current_state
;
2112 printk(MYIOC_s_INFO_FMT
"pci-resume: pdev=0x%p, slot=%s, Previous "
2113 "operating state [D%d]\n", ioc
->name
, pdev
, pci_name(pdev
),
2116 pci_set_power_state(pdev
, PCI_D0
);
2117 pci_enable_wake(pdev
, PCI_D0
, 0);
2118 pci_restore_state(pdev
);
2120 err
= mpt_mapresources(ioc
);
2124 if (ioc
->dma_mask
== DMA_BIT_MASK(64)) {
2125 if (pdev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1078
)
2126 ioc
->add_sge
= &mpt_add_sge_64bit_1078
;
2128 ioc
->add_sge
= &mpt_add_sge_64bit
;
2129 ioc
->add_chain
= &mpt_add_chain_64bit
;
2130 ioc
->sg_addr_size
= 8;
2133 ioc
->add_sge
= &mpt_add_sge
;
2134 ioc
->add_chain
= &mpt_add_chain
;
2135 ioc
->sg_addr_size
= 4;
2137 ioc
->SGE_size
= sizeof(u32
) + ioc
->sg_addr_size
;
2139 printk(MYIOC_s_INFO_FMT
"pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
2140 ioc
->name
, (mpt_GetIocState(ioc
, 1) >> MPI_IOC_STATE_SHIFT
),
2141 CHIPREG_READ32(&ioc
->chip
->Doorbell
));
2144 * Errata workaround for SAS pci express:
2145 * Upon returning to the D0 state, the contents of the doorbell will be
2146 * stale data, and this will incorrectly signal to the host driver that
2147 * the firmware is ready to process mpt commands. The workaround is
2148 * to issue a diagnostic reset.
2150 if (ioc
->bus_type
== SAS
&& (pdev
->device
==
2151 MPI_MANUFACTPAGE_DEVID_SAS1068E
|| pdev
->device
==
2152 MPI_MANUFACTPAGE_DEVID_SAS1064E
)) {
2153 if (KickStart(ioc
, 1, CAN_SLEEP
) < 0) {
2154 printk(MYIOC_s_WARN_FMT
"pci-resume: Cannot recover\n",
2160 /* bring ioc to operational state */
2161 printk(MYIOC_s_INFO_FMT
"Sending mpt_do_ioc_recovery\n", ioc
->name
);
2162 recovery_state
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_BRINGUP
,
2164 if (recovery_state
!= 0)
2165 printk(MYIOC_s_WARN_FMT
"pci-resume: Cannot recover, "
2166 "error:[%x]\n", ioc
->name
, recovery_state
);
2168 printk(MYIOC_s_INFO_FMT
2169 "pci-resume: success\n", ioc
->name
);
2177 mpt_signal_reset(u8 index
, MPT_ADAPTER
*ioc
, int reset_phase
)
2179 if ((MptDriverClass
[index
] == MPTSPI_DRIVER
&&
2180 ioc
->bus_type
!= SPI
) ||
2181 (MptDriverClass
[index
] == MPTFC_DRIVER
&&
2182 ioc
->bus_type
!= FC
) ||
2183 (MptDriverClass
[index
] == MPTSAS_DRIVER
&&
2184 ioc
->bus_type
!= SAS
))
2185 /* make sure we only call the relevant reset handler
2188 return (MptResetHandlers
[index
])(ioc
, reset_phase
);
2191 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2193 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
2194 * @ioc: Pointer to MPT adapter structure
2195 * @reason: Event word / reason
2196 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
2198 * This routine performs all the steps necessary to bring the IOC
2199 * to a OPERATIONAL state.
2201 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
2206 * -1 if failed to get board READY
2207 * -2 if READY but IOCFacts Failed
2208 * -3 if READY but PrimeIOCFifos Failed
2209 * -4 if READY but IOCInit Failed
2210 * -5 if failed to enable_device and/or request_selected_regions
2211 * -6 if failed to upload firmware
2214 mpt_do_ioc_recovery(MPT_ADAPTER
*ioc
, u32 reason
, int sleepFlag
)
2216 int hard_reset_done
= 0;
2217 int alt_ioc_ready
= 0;
2222 int reset_alt_ioc_active
= 0;
2223 int irq_allocated
= 0;
2226 printk(MYIOC_s_INFO_FMT
"Initiating %s\n", ioc
->name
,
2227 reason
== MPT_HOSTEVENT_IOC_BRINGUP
? "bringup" : "recovery");
2229 /* Disable reply interrupts (also blocks FreeQ) */
2230 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2234 if (ioc
->alt_ioc
->active
||
2235 reason
== MPT_HOSTEVENT_IOC_RECOVER
) {
2236 reset_alt_ioc_active
= 1;
2237 /* Disable alt-IOC's reply interrupts
2238 * (and FreeQ) for a bit
2240 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
,
2242 ioc
->alt_ioc
->active
= 0;
2247 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)
2250 if ((hard_reset_done
= MakeIocReady(ioc
, hard
, sleepFlag
)) < 0) {
2251 if (hard_reset_done
== -4) {
2252 printk(MYIOC_s_WARN_FMT
"Owned by PEER..skipping!\n",
2255 if (reset_alt_ioc_active
&& ioc
->alt_ioc
) {
2256 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
2257 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
2258 "alt_ioc reply irq re-enabled\n", ioc
->alt_ioc
->name
));
2259 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
, MPI_HIM_DIM
);
2260 ioc
->alt_ioc
->active
= 1;
2264 printk(MYIOC_s_WARN_FMT
2265 "NOT READY WARNING!\n", ioc
->name
);
2271 /* hard_reset_done = 0 if a soft reset was performed
2272 * and 1 if a hard reset was performed.
2274 if (hard_reset_done
&& reset_alt_ioc_active
&& ioc
->alt_ioc
) {
2275 if ((rc
= MakeIocReady(ioc
->alt_ioc
, 0, sleepFlag
)) == 0)
2278 printk(MYIOC_s_WARN_FMT
2279 ": alt-ioc Not ready WARNING!\n",
2280 ioc
->alt_ioc
->name
);
2283 for (ii
=0; ii
<5; ii
++) {
2284 /* Get IOC facts! Allow 5 retries */
2285 if ((rc
= GetIocFacts(ioc
, sleepFlag
, reason
)) == 0)
2291 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2292 "Retry IocFacts failed rc=%x\n", ioc
->name
, rc
));
2294 } else if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
2295 MptDisplayIocCapabilities(ioc
);
2298 if (alt_ioc_ready
) {
2299 if ((rc
= GetIocFacts(ioc
->alt_ioc
, sleepFlag
, reason
)) != 0) {
2300 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2301 "Initial Alt IocFacts failed rc=%x\n",
2303 /* Retry - alt IOC was initialized once
2305 rc
= GetIocFacts(ioc
->alt_ioc
, sleepFlag
, reason
);
2308 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2309 "Retry Alt IocFacts failed rc=%x\n", ioc
->name
, rc
));
2311 reset_alt_ioc_active
= 0;
2312 } else if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
2313 MptDisplayIocCapabilities(ioc
->alt_ioc
);
2317 if ((ret
== 0) && (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) &&
2318 (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)) {
2319 pci_release_selected_regions(ioc
->pcidev
, ioc
->bars
);
2320 ioc
->bars
= pci_select_bars(ioc
->pcidev
, IORESOURCE_MEM
|
2322 if (pci_enable_device(ioc
->pcidev
))
2324 if (pci_request_selected_regions(ioc
->pcidev
, ioc
->bars
,
2330 * Device is reset now. It must have de-asserted the interrupt line
2331 * (if it was asserted) and it should be safe to register for the
2334 if ((ret
== 0) && (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)) {
2336 if (ioc
->pcidev
->irq
) {
2337 if (ioc
->msi_enable
&& !pci_enable_msi(ioc
->pcidev
))
2338 printk(MYIOC_s_INFO_FMT
"PCI-MSI enabled\n",
2341 ioc
->msi_enable
= 0;
2342 rc
= request_irq(ioc
->pcidev
->irq
, mpt_interrupt
,
2343 IRQF_SHARED
, ioc
->name
, ioc
);
2345 printk(MYIOC_s_ERR_FMT
"Unable to allocate "
2347 ioc
->name
, ioc
->pcidev
->irq
);
2348 if (ioc
->msi_enable
)
2349 pci_disable_msi(ioc
->pcidev
);
2354 ioc
->pci_irq
= ioc
->pcidev
->irq
;
2355 pci_set_master(ioc
->pcidev
); /* ?? */
2356 pci_set_drvdata(ioc
->pcidev
, ioc
);
2357 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
2358 "installed at interrupt %d\n", ioc
->name
,
2363 /* Prime reply & request queues!
2364 * (mucho alloc's) Must be done prior to
2365 * init as upper addresses are needed for init.
2366 * If fails, continue with alt-ioc processing
2368 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"PrimeIocFifos\n",
2370 if ((ret
== 0) && ((rc
= PrimeIocFifos(ioc
)) != 0))
2373 /* May need to check/upload firmware & data here!
2374 * If fails, continue with alt-ioc processing
2376 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"SendIocInit\n",
2378 if ((ret
== 0) && ((rc
= SendIocInit(ioc
, sleepFlag
)) != 0))
2381 if (alt_ioc_ready
&& ((rc
= PrimeIocFifos(ioc
->alt_ioc
)) != 0)) {
2382 printk(MYIOC_s_WARN_FMT
2383 ": alt-ioc (%d) FIFO mgmt alloc WARNING!\n",
2384 ioc
->alt_ioc
->name
, rc
);
2386 reset_alt_ioc_active
= 0;
2389 if (alt_ioc_ready
) {
2390 if ((rc
= SendIocInit(ioc
->alt_ioc
, sleepFlag
)) != 0) {
2392 reset_alt_ioc_active
= 0;
2393 printk(MYIOC_s_WARN_FMT
2394 ": alt-ioc: (%d) init failure WARNING!\n",
2395 ioc
->alt_ioc
->name
, rc
);
2399 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
){
2400 if (ioc
->upload_fw
) {
2401 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2402 "firmware upload required!\n", ioc
->name
));
2404 /* Controller is not operational, cannot do upload
2407 rc
= mpt_do_upload(ioc
, sleepFlag
);
2409 if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
) {
2411 * Maintain only one pointer to FW memory
2412 * so there will not be two attempt to
2413 * downloadboot onboard dual function
2414 * chips (mpt_adapter_disable,
2417 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2418 "mpt_upload: alt_%s has cached_fw=%p \n",
2419 ioc
->name
, ioc
->alt_ioc
->name
, ioc
->alt_ioc
->cached_fw
));
2420 ioc
->cached_fw
= NULL
;
2423 printk(MYIOC_s_WARN_FMT
2424 "firmware upload failure!\n", ioc
->name
);
2431 /* Enable MPT base driver management of EventNotification
2432 * and EventAck handling.
2434 if ((ret
== 0) && (!ioc
->facts
.EventState
)) {
2435 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
2436 "SendEventNotification\n",
2438 ret
= SendEventNotification(ioc
, 1, sleepFlag
); /* 1=Enable */
2441 if (ioc
->alt_ioc
&& alt_ioc_ready
&& !ioc
->alt_ioc
->facts
.EventState
)
2442 rc
= SendEventNotification(ioc
->alt_ioc
, 1, sleepFlag
);
2445 /* Enable! (reply interrupt) */
2446 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, MPI_HIM_DIM
);
2449 if (rc
== 0) { /* alt ioc */
2450 if (reset_alt_ioc_active
&& ioc
->alt_ioc
) {
2451 /* (re)Enable alt-IOC! (reply interrupt) */
2452 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"alt-ioc"
2453 "reply irq re-enabled\n",
2454 ioc
->alt_ioc
->name
));
2455 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
,
2457 ioc
->alt_ioc
->active
= 1;
2462 /* Add additional "reason" check before call to GetLanConfigPages
2463 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2464 * recursive scenario; GetLanConfigPages times out, timer expired
2465 * routine calls HardResetHandler, which calls into here again,
2466 * and we try GetLanConfigPages again...
2468 if ((ret
== 0) && (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)) {
2471 * Initialize link list for inactive raid volumes.
2473 mutex_init(&ioc
->raid_data
.inactive_list_mutex
);
2474 INIT_LIST_HEAD(&ioc
->raid_data
.inactive_list
);
2476 switch (ioc
->bus_type
) {
2479 /* clear persistency table */
2480 if(ioc
->facts
.IOCExceptions
&
2481 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL
) {
2482 ret
= mptbase_sas_persist_operation(ioc
,
2483 MPI_SAS_OP_CLEAR_NOT_PRESENT
);
2490 mpt_findImVolumes(ioc
);
2492 /* Check, and possibly reset, the coalescing value
2494 mpt_read_ioc_pg_1(ioc
);
2499 if ((ioc
->pfacts
[0].ProtocolFlags
&
2500 MPI_PORTFACTS_PROTOCOL_LAN
) &&
2501 (ioc
->lan_cnfg_page0
.Header
.PageLength
== 0)) {
2503 * Pre-fetch the ports LAN MAC address!
2504 * (LANPage1_t stuff)
2506 (void) GetLanConfigPages(ioc
);
2507 a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
2508 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2509 "LanAddr = %02X:%02X:%02X"
2510 ":%02X:%02X:%02X\n",
2511 ioc
->name
, a
[5], a
[4],
2512 a
[3], a
[2], a
[1], a
[0]));
2517 /* Get NVRAM and adapter maximums from SPP 0 and 2
2519 mpt_GetScsiPortSettings(ioc
, 0);
2521 /* Get version and length of SDP 1
2523 mpt_readScsiDevicePageHeaders(ioc
, 0);
2527 if (ioc
->facts
.MsgVersion
>= MPI_VERSION_01_02
)
2528 mpt_findImVolumes(ioc
);
2530 /* Check, and possibly reset, the coalescing value
2532 mpt_read_ioc_pg_1(ioc
);
2534 mpt_read_ioc_pg_4(ioc
);
2539 GetIoUnitPage2(ioc
);
2540 mpt_get_manufacturing_pg_0(ioc
);
2544 if ((ret
!= 0) && irq_allocated
) {
2545 free_irq(ioc
->pci_irq
, ioc
);
2546 if (ioc
->msi_enable
)
2547 pci_disable_msi(ioc
->pcidev
);
2552 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2554 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2555 * @ioc: Pointer to MPT adapter structure
2556 * @pdev: Pointer to (struct pci_dev) structure
2558 * Search for PCI bus/dev_function which matches
2559 * PCI bus/dev_function (+/-1) for newly discovered 929,
2560 * 929X, 1030 or 1035.
2562 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2563 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2566 mpt_detect_bound_ports(MPT_ADAPTER
*ioc
, struct pci_dev
*pdev
)
2568 struct pci_dev
*peer
=NULL
;
2569 unsigned int slot
= PCI_SLOT(pdev
->devfn
);
2570 unsigned int func
= PCI_FUNC(pdev
->devfn
);
2571 MPT_ADAPTER
*ioc_srch
;
2573 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"PCI device %s devfn=%x/%x,"
2574 " searching for devfn match on %x or %x\n",
2575 ioc
->name
, pci_name(pdev
), pdev
->bus
->number
,
2576 pdev
->devfn
, func
-1, func
+1));
2578 peer
= pci_get_slot(pdev
->bus
, PCI_DEVFN(slot
,func
-1));
2580 peer
= pci_get_slot(pdev
->bus
, PCI_DEVFN(slot
,func
+1));
2585 list_for_each_entry(ioc_srch
, &ioc_list
, list
) {
2586 struct pci_dev
*_pcidev
= ioc_srch
->pcidev
;
2587 if (_pcidev
== peer
) {
2588 /* Paranoia checks */
2589 if (ioc
->alt_ioc
!= NULL
) {
2590 printk(MYIOC_s_WARN_FMT
2591 "Oops, already bound (%s <==> %s)!\n",
2592 ioc
->name
, ioc
->name
, ioc
->alt_ioc
->name
);
2594 } else if (ioc_srch
->alt_ioc
!= NULL
) {
2595 printk(MYIOC_s_WARN_FMT
2596 "Oops, already bound (%s <==> %s)!\n",
2597 ioc_srch
->name
, ioc_srch
->name
,
2598 ioc_srch
->alt_ioc
->name
);
2601 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2602 "FOUND! binding %s <==> %s\n",
2603 ioc
->name
, ioc
->name
, ioc_srch
->name
));
2604 ioc_srch
->alt_ioc
= ioc
;
2605 ioc
->alt_ioc
= ioc_srch
;
2611 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2613 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2614 * @ioc: Pointer to MPT adapter structure
2617 mpt_adapter_disable(MPT_ADAPTER
*ioc
)
2622 if (ioc
->cached_fw
!= NULL
) {
2623 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2624 "%s: Pushing FW onto adapter\n", __func__
, ioc
->name
));
2625 if ((ret
= mpt_downloadboot(ioc
, (MpiFwHeader_t
*)
2626 ioc
->cached_fw
, CAN_SLEEP
)) < 0) {
2627 printk(MYIOC_s_WARN_FMT
2628 ": firmware downloadboot failure (%d)!\n",
2634 * Put the controller into ready state (if its not already)
2636 if (mpt_GetIocState(ioc
, 1) != MPI_IOC_STATE_READY
) {
2637 if (!SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
,
2639 if (mpt_GetIocState(ioc
, 1) != MPI_IOC_STATE_READY
)
2640 printk(MYIOC_s_ERR_FMT
"%s: IOC msg unit "
2641 "reset failed to put ioc in ready state!\n",
2642 ioc
->name
, __func__
);
2644 printk(MYIOC_s_ERR_FMT
"%s: IOC msg unit reset "
2645 "failed!\n", ioc
->name
, __func__
);
2649 /* Disable adapter interrupts! */
2650 synchronize_irq(ioc
->pcidev
->irq
);
2651 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2654 /* Clear any lingering interrupt */
2655 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
2656 CHIPREG_READ32(&ioc
->chip
->IntStatus
);
2658 if (ioc
->alloc
!= NULL
) {
2660 dexitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"free @ %p, sz=%d bytes\n",
2661 ioc
->name
, ioc
->alloc
, ioc
->alloc_sz
));
2662 pci_free_consistent(ioc
->pcidev
, sz
,
2663 ioc
->alloc
, ioc
->alloc_dma
);
2664 ioc
->reply_frames
= NULL
;
2665 ioc
->req_frames
= NULL
;
2667 ioc
->alloc_total
-= sz
;
2670 if (ioc
->sense_buf_pool
!= NULL
) {
2671 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
2672 pci_free_consistent(ioc
->pcidev
, sz
,
2673 ioc
->sense_buf_pool
, ioc
->sense_buf_pool_dma
);
2674 ioc
->sense_buf_pool
= NULL
;
2675 ioc
->alloc_total
-= sz
;
2678 if (ioc
->events
!= NULL
){
2679 sz
= MPTCTL_EVENT_LOG_SIZE
* sizeof(MPT_IOCTL_EVENTS
);
2682 ioc
->alloc_total
-= sz
;
2685 mpt_free_fw_memory(ioc
);
2687 kfree(ioc
->spi_data
.nvram
);
2688 mpt_inactive_raid_list_free(ioc
);
2689 kfree(ioc
->raid_data
.pIocPg2
);
2690 kfree(ioc
->raid_data
.pIocPg3
);
2691 ioc
->spi_data
.nvram
= NULL
;
2692 ioc
->raid_data
.pIocPg3
= NULL
;
2694 if (ioc
->spi_data
.pIocPg4
!= NULL
) {
2695 sz
= ioc
->spi_data
.IocPg4Sz
;
2696 pci_free_consistent(ioc
->pcidev
, sz
,
2697 ioc
->spi_data
.pIocPg4
,
2698 ioc
->spi_data
.IocPg4_dma
);
2699 ioc
->spi_data
.pIocPg4
= NULL
;
2700 ioc
->alloc_total
-= sz
;
2703 if (ioc
->ReqToChain
!= NULL
) {
2704 kfree(ioc
->ReqToChain
);
2705 kfree(ioc
->RequestNB
);
2706 ioc
->ReqToChain
= NULL
;
2709 kfree(ioc
->ChainToChain
);
2710 ioc
->ChainToChain
= NULL
;
2712 if (ioc
->HostPageBuffer
!= NULL
) {
2713 if((ret
= mpt_host_page_access_control(ioc
,
2714 MPI_DB_HPBAC_FREE_BUFFER
, NO_SLEEP
)) != 0) {
2715 printk(MYIOC_s_ERR_FMT
2716 ": %s: host page buffers free failed (%d)!\n",
2717 ioc
->name
, __func__
, ret
);
2719 dexitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2720 "HostPageBuffer free @ %p, sz=%d bytes\n",
2721 ioc
->name
, ioc
->HostPageBuffer
,
2722 ioc
->HostPageBuffer_sz
));
2723 pci_free_consistent(ioc
->pcidev
, ioc
->HostPageBuffer_sz
,
2724 ioc
->HostPageBuffer
, ioc
->HostPageBuffer_dma
);
2725 ioc
->HostPageBuffer
= NULL
;
2726 ioc
->HostPageBuffer_sz
= 0;
2727 ioc
->alloc_total
-= ioc
->HostPageBuffer_sz
;
2730 pci_set_drvdata(ioc
->pcidev
, NULL
);
2732 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2734 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2735 * @ioc: Pointer to MPT adapter structure
2737 * This routine unregisters h/w resources and frees all alloc'd memory
2738 * associated with a MPT adapter structure.
2741 mpt_adapter_dispose(MPT_ADAPTER
*ioc
)
2743 int sz_first
, sz_last
;
2748 sz_first
= ioc
->alloc_total
;
2750 mpt_adapter_disable(ioc
);
2752 if (ioc
->pci_irq
!= -1) {
2753 free_irq(ioc
->pci_irq
, ioc
);
2754 if (ioc
->msi_enable
)
2755 pci_disable_msi(ioc
->pcidev
);
2759 if (ioc
->memmap
!= NULL
) {
2760 iounmap(ioc
->memmap
);
2764 pci_disable_device(ioc
->pcidev
);
2765 pci_release_selected_regions(ioc
->pcidev
, ioc
->bars
);
2767 #if defined(CONFIG_MTRR) && 0
2768 if (ioc
->mtrr_reg
> 0) {
2769 mtrr_del(ioc
->mtrr_reg
, 0, 0);
2770 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
"MTRR region de-registered\n", ioc
->name
));
2774 /* Zap the adapter lookup ptr! */
2775 list_del(&ioc
->list
);
2777 sz_last
= ioc
->alloc_total
;
2778 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
"free'd %d of %d bytes\n",
2779 ioc
->name
, sz_first
-sz_last
+(int)sizeof(*ioc
), sz_first
));
2782 ioc
->alt_ioc
->alt_ioc
= NULL
;
2787 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2789 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2790 * @ioc: Pointer to MPT adapter structure
2793 MptDisplayIocCapabilities(MPT_ADAPTER
*ioc
)
2797 printk(KERN_INFO
"%s: ", ioc
->name
);
2799 printk("%s: ", ioc
->prod_name
);
2800 printk("Capabilities={");
2802 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_INITIATOR
) {
2803 printk("Initiator");
2807 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_TARGET
) {
2808 printk("%sTarget", i
? "," : "");
2812 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
) {
2813 printk("%sLAN", i
? "," : "");
2819 * This would probably evoke more questions than it's worth
2821 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_TARGET
) {
2822 printk("%sLogBusAddr", i
? "," : "");
2830 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2832 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2833 * @ioc: Pointer to MPT_ADAPTER structure
2834 * @force: Force hard KickStart of IOC
2835 * @sleepFlag: Specifies whether the process can sleep
2838 * 1 - DIAG reset and READY
2839 * 0 - READY initially OR soft reset and READY
2840 * -1 - Any failure on KickStart
2841 * -2 - Msg Unit Reset Failed
2842 * -3 - IO Unit Reset Failed
2843 * -4 - IOC owned by a PEER
2846 MakeIocReady(MPT_ADAPTER
*ioc
, int force
, int sleepFlag
)
2851 int hard_reset_done
= 0;
2856 /* Get current [raw] IOC state */
2857 ioc_state
= mpt_GetIocState(ioc
, 0);
2858 dhsprintk(ioc
, printk(MYIOC_s_INFO_FMT
"MakeIocReady [raw] state=%08x\n", ioc
->name
, ioc_state
));
2861 * Check to see if IOC got left/stuck in doorbell handshake
2862 * grip of death. If so, hard reset the IOC.
2864 if (ioc_state
& MPI_DOORBELL_ACTIVE
) {
2866 printk(MYIOC_s_WARN_FMT
"Unexpected doorbell active!\n",
2870 /* Is it already READY? */
2872 ((ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_READY
)) {
2873 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
2874 "IOC is in READY state\n", ioc
->name
));
2879 * Check to see if IOC is in FAULT state.
2881 if ((ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_FAULT
) {
2883 printk(MYIOC_s_WARN_FMT
"IOC is in FAULT state!!!\n",
2885 printk(MYIOC_s_WARN_FMT
" FAULT code = %04xh\n",
2886 ioc
->name
, ioc_state
& MPI_DOORBELL_DATA_MASK
);
2890 * Hmmm... Did it get left operational?
2892 if ((ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_OPERATIONAL
) {
2893 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"IOC operational unexpected\n",
2897 * If PCI Peer, exit.
2898 * Else, if no fault conditions are present, issue a MessageUnitReset
2899 * Else, fall through to KickStart case
2901 whoinit
= (ioc_state
& MPI_DOORBELL_WHO_INIT_MASK
) >> MPI_DOORBELL_WHO_INIT_SHIFT
;
2902 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
2903 "whoinit 0x%x statefault %d force %d\n",
2904 ioc
->name
, whoinit
, statefault
, force
));
2905 if (whoinit
== MPI_WHOINIT_PCI_PEER
)
2908 if ((statefault
== 0 ) && (force
== 0)) {
2909 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
)) == 0)
2916 hard_reset_done
= KickStart(ioc
, statefault
||force
, sleepFlag
);
2917 if (hard_reset_done
< 0)
2921 * Loop here waiting for IOC to come READY.
2924 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 5; /* 5 seconds */
2926 while ((ioc_state
= mpt_GetIocState(ioc
, 1)) != MPI_IOC_STATE_READY
) {
2927 if (ioc_state
== MPI_IOC_STATE_OPERATIONAL
) {
2929 * BIOS or previous driver load left IOC in OP state.
2930 * Reset messaging FIFOs.
2932 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
)) != 0) {
2933 printk(MYIOC_s_ERR_FMT
"IOC msg unit reset failed!\n", ioc
->name
);
2936 } else if (ioc_state
== MPI_IOC_STATE_RESET
) {
2938 * Something is wrong. Try to get IOC back
2941 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IO_UNIT_RESET
, sleepFlag
)) != 0) {
2942 printk(MYIOC_s_ERR_FMT
"IO unit reset failed!\n", ioc
->name
);
2949 printk(MYIOC_s_ERR_FMT
2950 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
2951 ioc
->name
, ioc_state
, (int)((ii
+5)/HZ
));
2955 if (sleepFlag
== CAN_SLEEP
) {
2958 mdelay (1); /* 1 msec delay */
2963 if (statefault
< 3) {
2964 printk(MYIOC_s_INFO_FMT
"Recovered from %s\n", ioc
->name
,
2965 statefault
== 1 ? "stuck handshake" : "IOC FAULT");
2968 return hard_reset_done
;
2971 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2973 * mpt_GetIocState - Get the current state of a MPT adapter.
2974 * @ioc: Pointer to MPT_ADAPTER structure
2975 * @cooked: Request raw or cooked IOC state
2977 * Returns all IOC Doorbell register bits if cooked==0, else just the
2978 * Doorbell bits in MPI_IOC_STATE_MASK.
2981 mpt_GetIocState(MPT_ADAPTER
*ioc
, int cooked
)
2986 s
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
2987 sc
= s
& MPI_IOC_STATE_MASK
;
2990 ioc
->last_state
= sc
;
2992 return cooked
? sc
: s
;
2995 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2997 * GetIocFacts - Send IOCFacts request to MPT adapter.
2998 * @ioc: Pointer to MPT_ADAPTER structure
2999 * @sleepFlag: Specifies whether the process can sleep
3000 * @reason: If recovery, only update facts.
3002 * Returns 0 for success, non-zero for failure.
3005 GetIocFacts(MPT_ADAPTER
*ioc
, int sleepFlag
, int reason
)
3007 IOCFacts_t get_facts
;
3008 IOCFactsReply_t
*facts
;
3016 /* IOC *must* NOT be in RESET state! */
3017 if (ioc
->last_state
== MPI_IOC_STATE_RESET
) {
3018 printk(KERN_ERR MYNAM
3019 ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
3020 ioc
->name
, ioc
->last_state
);
3024 facts
= &ioc
->facts
;
3026 /* Destination (reply area)... */
3027 reply_sz
= sizeof(*facts
);
3028 memset(facts
, 0, reply_sz
);
3030 /* Request area (get_facts on the stack right now!) */
3031 req_sz
= sizeof(get_facts
);
3032 memset(&get_facts
, 0, req_sz
);
3034 get_facts
.Function
= MPI_FUNCTION_IOC_FACTS
;
3035 /* Assert: All other get_facts fields are zero! */
3037 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3038 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
3039 ioc
->name
, req_sz
, reply_sz
));
3041 /* No non-zero fields in the get_facts request are greater than
3042 * 1 byte in size, so we can just fire it off as is.
3044 r
= mpt_handshake_req_reply_wait(ioc
, req_sz
, (u32
*)&get_facts
,
3045 reply_sz
, (u16
*)facts
, 5 /*seconds*/, sleepFlag
);
3050 * Now byte swap (GRRR) the necessary fields before any further
3051 * inspection of reply contents.
3053 * But need to do some sanity checks on MsgLength (byte) field
3054 * to make sure we don't zero IOC's req_sz!
3056 /* Did we get a valid reply? */
3057 if (facts
->MsgLength
> offsetof(IOCFactsReply_t
, RequestFrameSize
)/sizeof(u32
)) {
3058 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
3060 * If not been here, done that, save off first WhoInit value
3062 if (ioc
->FirstWhoInit
== WHOINIT_UNKNOWN
)
3063 ioc
->FirstWhoInit
= facts
->WhoInit
;
3066 facts
->MsgVersion
= le16_to_cpu(facts
->MsgVersion
);
3067 facts
->MsgContext
= le32_to_cpu(facts
->MsgContext
);
3068 facts
->IOCExceptions
= le16_to_cpu(facts
->IOCExceptions
);
3069 facts
->IOCStatus
= le16_to_cpu(facts
->IOCStatus
);
3070 facts
->IOCLogInfo
= le32_to_cpu(facts
->IOCLogInfo
);
3071 status
= le16_to_cpu(facts
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
3072 /* CHECKME! IOCStatus, IOCLogInfo */
3074 facts
->ReplyQueueDepth
= le16_to_cpu(facts
->ReplyQueueDepth
);
3075 facts
->RequestFrameSize
= le16_to_cpu(facts
->RequestFrameSize
);
3078 * FC f/w version changed between 1.1 and 1.2
3079 * Old: u16{Major(4),Minor(4),SubMinor(8)}
3080 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
3082 if (facts
->MsgVersion
< MPI_VERSION_01_02
) {
3084 * Handle old FC f/w style, convert to new...
3086 u16 oldv
= le16_to_cpu(facts
->Reserved_0101_FWVersion
);
3087 facts
->FWVersion
.Word
=
3088 ((oldv
<<12) & 0xFF000000) |
3089 ((oldv
<<8) & 0x000FFF00);
3091 facts
->FWVersion
.Word
= le32_to_cpu(facts
->FWVersion
.Word
);
3093 facts
->ProductID
= le16_to_cpu(facts
->ProductID
);
3095 if ((ioc
->facts
.ProductID
& MPI_FW_HEADER_PID_PROD_MASK
)
3096 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI
)
3097 ioc
->ir_firmware
= 1;
3099 facts
->CurrentHostMfaHighAddr
=
3100 le32_to_cpu(facts
->CurrentHostMfaHighAddr
);
3101 facts
->GlobalCredits
= le16_to_cpu(facts
->GlobalCredits
);
3102 facts
->CurrentSenseBufferHighAddr
=
3103 le32_to_cpu(facts
->CurrentSenseBufferHighAddr
);
3104 facts
->CurReplyFrameSize
=
3105 le16_to_cpu(facts
->CurReplyFrameSize
);
3106 facts
->IOCCapabilities
= le32_to_cpu(facts
->IOCCapabilities
);
3109 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
3110 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
3111 * to 14 in MPI-1.01.0x.
3113 if (facts
->MsgLength
>= (offsetof(IOCFactsReply_t
,FWImageSize
) + 7)/4 &&
3114 facts
->MsgVersion
> MPI_VERSION_01_00
) {
3115 facts
->FWImageSize
= le32_to_cpu(facts
->FWImageSize
);
3118 sz
= facts
->FWImageSize
;
3123 facts
->FWImageSize
= sz
;
3125 if (!facts
->RequestFrameSize
) {
3126 /* Something is wrong! */
3127 printk(MYIOC_s_ERR_FMT
"IOC reported invalid 0 request size!\n",
3132 r
= sz
= facts
->BlockSize
;
3133 vv
= ((63 / (sz
* 4)) + 1) & 0x03;
3134 ioc
->NB_for_64_byte_frame
= vv
;
3140 ioc
->NBShiftFactor
= shiftFactor
;
3141 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3142 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
3143 ioc
->name
, vv
, shiftFactor
, r
));
3145 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
3147 * Set values for this IOC's request & reply frame sizes,
3148 * and request & reply queue depths...
3150 ioc
->req_sz
= min(MPT_DEFAULT_FRAME_SIZE
, facts
->RequestFrameSize
* 4);
3151 ioc
->req_depth
= min_t(int, MPT_MAX_REQ_DEPTH
, facts
->GlobalCredits
);
3152 ioc
->reply_sz
= MPT_REPLY_FRAME_SIZE
;
3153 ioc
->reply_depth
= min_t(int, MPT_DEFAULT_REPLY_DEPTH
, facts
->ReplyQueueDepth
);
3155 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"reply_sz=%3d, reply_depth=%4d\n",
3156 ioc
->name
, ioc
->reply_sz
, ioc
->reply_depth
));
3157 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"req_sz =%3d, req_depth =%4d\n",
3158 ioc
->name
, ioc
->req_sz
, ioc
->req_depth
));
3160 /* Get port facts! */
3161 if ( (r
= GetPortFacts(ioc
, 0, sleepFlag
)) != 0 )
3165 printk(MYIOC_s_ERR_FMT
3166 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
3167 ioc
->name
, facts
->MsgLength
, (offsetof(IOCFactsReply_t
,
3168 RequestFrameSize
)/sizeof(u32
)));
3175 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3177 * GetPortFacts - Send PortFacts request to MPT adapter.
3178 * @ioc: Pointer to MPT_ADAPTER structure
3179 * @portnum: Port number
3180 * @sleepFlag: Specifies whether the process can sleep
3182 * Returns 0 for success, non-zero for failure.
3185 GetPortFacts(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
)
3187 PortFacts_t get_pfacts
;
3188 PortFactsReply_t
*pfacts
;
3194 /* IOC *must* NOT be in RESET state! */
3195 if (ioc
->last_state
== MPI_IOC_STATE_RESET
) {
3196 printk(MYIOC_s_ERR_FMT
"Can't get PortFacts NOT READY! (%08x)\n",
3197 ioc
->name
, ioc
->last_state
);
3201 pfacts
= &ioc
->pfacts
[portnum
];
3203 /* Destination (reply area)... */
3204 reply_sz
= sizeof(*pfacts
);
3205 memset(pfacts
, 0, reply_sz
);
3207 /* Request area (get_pfacts on the stack right now!) */
3208 req_sz
= sizeof(get_pfacts
);
3209 memset(&get_pfacts
, 0, req_sz
);
3211 get_pfacts
.Function
= MPI_FUNCTION_PORT_FACTS
;
3212 get_pfacts
.PortNumber
= portnum
;
3213 /* Assert: All other get_pfacts fields are zero! */
3215 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending get PortFacts(%d) request\n",
3216 ioc
->name
, portnum
));
3218 /* No non-zero fields in the get_pfacts request are greater than
3219 * 1 byte in size, so we can just fire it off as is.
3221 ii
= mpt_handshake_req_reply_wait(ioc
, req_sz
, (u32
*)&get_pfacts
,
3222 reply_sz
, (u16
*)pfacts
, 5 /*seconds*/, sleepFlag
);
3226 /* Did we get a valid reply? */
3228 /* Now byte swap the necessary fields in the response. */
3229 pfacts
->MsgContext
= le32_to_cpu(pfacts
->MsgContext
);
3230 pfacts
->IOCStatus
= le16_to_cpu(pfacts
->IOCStatus
);
3231 pfacts
->IOCLogInfo
= le32_to_cpu(pfacts
->IOCLogInfo
);
3232 pfacts
->MaxDevices
= le16_to_cpu(pfacts
->MaxDevices
);
3233 pfacts
->PortSCSIID
= le16_to_cpu(pfacts
->PortSCSIID
);
3234 pfacts
->ProtocolFlags
= le16_to_cpu(pfacts
->ProtocolFlags
);
3235 pfacts
->MaxPostedCmdBuffers
= le16_to_cpu(pfacts
->MaxPostedCmdBuffers
);
3236 pfacts
->MaxPersistentIDs
= le16_to_cpu(pfacts
->MaxPersistentIDs
);
3237 pfacts
->MaxLanBuckets
= le16_to_cpu(pfacts
->MaxLanBuckets
);
3239 max_id
= (ioc
->bus_type
== SAS
) ? pfacts
->PortSCSIID
:
3241 ioc
->devices_per_bus
= (max_id
> 255) ? 256 : max_id
;
3242 ioc
->number_of_buses
= (ioc
->devices_per_bus
< 256) ? 1 : max_id
/256;
3245 * Place all the devices on channels
3249 if (mpt_channel_mapping
) {
3250 ioc
->devices_per_bus
= 1;
3251 ioc
->number_of_buses
= (max_id
> 255) ? 255 : max_id
;
3257 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3259 * SendIocInit - Send IOCInit request to MPT adapter.
3260 * @ioc: Pointer to MPT_ADAPTER structure
3261 * @sleepFlag: Specifies whether the process can sleep
3263 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
3265 * Returns 0 for success, non-zero for failure.
3268 SendIocInit(MPT_ADAPTER
*ioc
, int sleepFlag
)
3271 MPIDefaultReply_t init_reply
;
3277 memset(&ioc_init
, 0, sizeof(ioc_init
));
3278 memset(&init_reply
, 0, sizeof(init_reply
));
3280 ioc_init
.WhoInit
= MPI_WHOINIT_HOST_DRIVER
;
3281 ioc_init
.Function
= MPI_FUNCTION_IOC_INIT
;
3283 /* If we are in a recovery mode and we uploaded the FW image,
3284 * then this pointer is not NULL. Skip the upload a second time.
3285 * Set this flag if cached_fw set for either IOC.
3287 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)
3291 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"upload_fw %d facts.Flags=%x\n",
3292 ioc
->name
, ioc
->upload_fw
, ioc
->facts
.Flags
));
3294 ioc_init
.MaxDevices
= (U8
)ioc
->devices_per_bus
;
3295 ioc_init
.MaxBuses
= (U8
)ioc
->number_of_buses
;
3297 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"facts.MsgVersion=%x\n",
3298 ioc
->name
, ioc
->facts
.MsgVersion
));
3299 if (ioc
->facts
.MsgVersion
>= MPI_VERSION_01_05
) {
3300 // set MsgVersion and HeaderVersion host driver was built with
3301 ioc_init
.MsgVersion
= cpu_to_le16(MPI_VERSION
);
3302 ioc_init
.HeaderVersion
= cpu_to_le16(MPI_HEADER_VERSION
);
3304 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT
) {
3305 ioc_init
.HostPageBufferSGE
= ioc
->facts
.HostPageBufferSGE
;
3306 } else if(mpt_host_page_alloc(ioc
, &ioc_init
))
3309 ioc_init
.ReplyFrameSize
= cpu_to_le16(ioc
->reply_sz
); /* in BYTES */
3311 if (ioc
->sg_addr_size
== sizeof(u64
)) {
3312 /* Save the upper 32-bits of the request
3313 * (reply) and sense buffers.
3315 ioc_init
.HostMfaHighAddr
= cpu_to_le32((u32
)((u64
)ioc
->alloc_dma
>> 32));
3316 ioc_init
.SenseBufferHighAddr
= cpu_to_le32((u32
)((u64
)ioc
->sense_buf_pool_dma
>> 32));
3318 /* Force 32-bit addressing */
3319 ioc_init
.HostMfaHighAddr
= cpu_to_le32(0);
3320 ioc_init
.SenseBufferHighAddr
= cpu_to_le32(0);
3323 ioc
->facts
.CurrentHostMfaHighAddr
= ioc_init
.HostMfaHighAddr
;
3324 ioc
->facts
.CurrentSenseBufferHighAddr
= ioc_init
.SenseBufferHighAddr
;
3325 ioc
->facts
.MaxDevices
= ioc_init
.MaxDevices
;
3326 ioc
->facts
.MaxBuses
= ioc_init
.MaxBuses
;
3328 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending IOCInit (req @ %p)\n",
3329 ioc
->name
, &ioc_init
));
3331 r
= mpt_handshake_req_reply_wait(ioc
, sizeof(IOCInit_t
), (u32
*)&ioc_init
,
3332 sizeof(MPIDefaultReply_t
), (u16
*)&init_reply
, 10 /*seconds*/, sleepFlag
);
3334 printk(MYIOC_s_ERR_FMT
"Sending IOCInit failed(%d)!\n",ioc
->name
, r
);
3338 /* No need to byte swap the multibyte fields in the reply
3339 * since we don't even look at its contents.
3342 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending PortEnable (req @ %p)\n",
3343 ioc
->name
, &ioc_init
));
3345 if ((r
= SendPortEnable(ioc
, 0, sleepFlag
)) != 0) {
3346 printk(MYIOC_s_ERR_FMT
"Sending PortEnable failed(%d)!\n",ioc
->name
, r
);
3350 /* YIKES! SUPER IMPORTANT!!!
3351 * Poll IocState until _OPERATIONAL while IOC is doing
3352 * LoopInit and TargetDiscovery!
3355 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 60; /* 60 seconds */
3356 state
= mpt_GetIocState(ioc
, 1);
3357 while (state
!= MPI_IOC_STATE_OPERATIONAL
&& --cntdn
) {
3358 if (sleepFlag
== CAN_SLEEP
) {
3365 printk(MYIOC_s_ERR_FMT
"Wait IOC_OP state timeout(%d)!\n",
3366 ioc
->name
, (int)((count
+5)/HZ
));
3370 state
= mpt_GetIocState(ioc
, 1);
3373 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Wait IOC_OPERATIONAL state (cnt=%d)\n",
3376 ioc
->aen_event_read_flag
=0;
3380 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3382 * SendPortEnable - Send PortEnable request to MPT adapter port.
3383 * @ioc: Pointer to MPT_ADAPTER structure
3384 * @portnum: Port number to enable
3385 * @sleepFlag: Specifies whether the process can sleep
3387 * Send PortEnable to bring IOC to OPERATIONAL state.
3389 * Returns 0 for success, non-zero for failure.
3392 SendPortEnable(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
)
3394 PortEnable_t port_enable
;
3395 MPIDefaultReply_t reply_buf
;
3400 /* Destination... */
3401 reply_sz
= sizeof(MPIDefaultReply_t
);
3402 memset(&reply_buf
, 0, reply_sz
);
3404 req_sz
= sizeof(PortEnable_t
);
3405 memset(&port_enable
, 0, req_sz
);
3407 port_enable
.Function
= MPI_FUNCTION_PORT_ENABLE
;
3408 port_enable
.PortNumber
= portnum
;
3409 /* port_enable.ChainOffset = 0; */
3410 /* port_enable.MsgFlags = 0; */
3411 /* port_enable.MsgContext = 0; */
3413 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending Port(%d)Enable (req @ %p)\n",
3414 ioc
->name
, portnum
, &port_enable
));
3416 /* RAID FW may take a long time to enable
3418 if (ioc
->ir_firmware
|| ioc
->bus_type
== SAS
) {
3419 rc
= mpt_handshake_req_reply_wait(ioc
, req_sz
,
3420 (u32
*)&port_enable
, reply_sz
, (u16
*)&reply_buf
,
3421 300 /*seconds*/, sleepFlag
);
3423 rc
= mpt_handshake_req_reply_wait(ioc
, req_sz
,
3424 (u32
*)&port_enable
, reply_sz
, (u16
*)&reply_buf
,
3425 30 /*seconds*/, sleepFlag
);
3431 * mpt_alloc_fw_memory - allocate firmware memory
3432 * @ioc: Pointer to MPT_ADAPTER structure
3433 * @size: total FW bytes
3435 * If memory has already been allocated, the same (cached) value
3438 * Return 0 if successfull, or non-zero for failure
3441 mpt_alloc_fw_memory(MPT_ADAPTER
*ioc
, int size
)
3445 if (ioc
->cached_fw
) {
3446 rc
= 0; /* use already allocated memory */
3449 else if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
) {
3450 ioc
->cached_fw
= ioc
->alt_ioc
->cached_fw
; /* use alt_ioc's memory */
3451 ioc
->cached_fw_dma
= ioc
->alt_ioc
->cached_fw_dma
;
3455 ioc
->cached_fw
= pci_alloc_consistent(ioc
->pcidev
, size
, &ioc
->cached_fw_dma
);
3456 if (!ioc
->cached_fw
) {
3457 printk(MYIOC_s_ERR_FMT
"Unable to allocate memory for the cached firmware image!\n",
3461 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"FW Image @ %p[%p], sz=%d[%x] bytes\n",
3462 ioc
->name
, ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, size
, size
));
3463 ioc
->alloc_total
+= size
;
3471 * mpt_free_fw_memory - free firmware memory
3472 * @ioc: Pointer to MPT_ADAPTER structure
3474 * If alt_img is NULL, delete from ioc structure.
3475 * Else, delete a secondary image in same format.
3478 mpt_free_fw_memory(MPT_ADAPTER
*ioc
)
3482 if (!ioc
->cached_fw
)
3485 sz
= ioc
->facts
.FWImageSize
;
3486 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3487 ioc
->name
, ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, sz
, sz
));
3488 pci_free_consistent(ioc
->pcidev
, sz
, ioc
->cached_fw
, ioc
->cached_fw_dma
);
3489 ioc
->alloc_total
-= sz
;
3490 ioc
->cached_fw
= NULL
;
3493 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3495 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3496 * @ioc: Pointer to MPT_ADAPTER structure
3497 * @sleepFlag: Specifies whether the process can sleep
3499 * Returns 0 for success, >0 for handshake failure
3500 * <0 for fw upload failure.
3502 * Remark: If bound IOC and a successful FWUpload was performed
3503 * on the bound IOC, the second image is discarded
3504 * and memory is free'd. Both channels must upload to prevent
3505 * IOC from running in degraded mode.
3508 mpt_do_upload(MPT_ADAPTER
*ioc
, int sleepFlag
)
3510 u8 reply
[sizeof(FWUploadReply_t
)];
3511 FWUpload_t
*prequest
;
3512 FWUploadReply_t
*preply
;
3513 FWUploadTCSGE_t
*ptcsge
;
3515 int ii
, sz
, reply_sz
;
3518 /* If the image size is 0, we are done.
3520 if ((sz
= ioc
->facts
.FWImageSize
) == 0)
3523 if (mpt_alloc_fw_memory(ioc
, ioc
->facts
.FWImageSize
) != 0)
3526 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3527 ioc
->name
, ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, sz
, sz
));
3529 prequest
= (sleepFlag
== NO_SLEEP
) ? kzalloc(ioc
->req_sz
, GFP_ATOMIC
) :
3530 kzalloc(ioc
->req_sz
, GFP_KERNEL
);
3532 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"fw upload failed "
3533 "while allocating memory \n", ioc
->name
));
3534 mpt_free_fw_memory(ioc
);
3538 preply
= (FWUploadReply_t
*)&reply
;
3540 reply_sz
= sizeof(reply
);
3541 memset(preply
, 0, reply_sz
);
3543 prequest
->ImageType
= MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM
;
3544 prequest
->Function
= MPI_FUNCTION_FW_UPLOAD
;
3546 ptcsge
= (FWUploadTCSGE_t
*) &prequest
->SGL
;
3547 ptcsge
->DetailsLength
= 12;
3548 ptcsge
->Flags
= MPI_SGE_FLAGS_TRANSACTION_ELEMENT
;
3549 ptcsge
->ImageSize
= cpu_to_le32(sz
);
3552 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_READ
| sz
;
3553 ioc
->add_sge((char *)ptcsge
, flagsLength
, ioc
->cached_fw_dma
);
3554 request_size
= offsetof(FWUpload_t
, SGL
) + sizeof(FWUploadTCSGE_t
) +
3556 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending FW Upload "
3557 " (req @ %p) fw_size=%d mf_request_size=%d\n", ioc
->name
, prequest
,
3558 ioc
->facts
.FWImageSize
, request_size
));
3559 DBG_DUMP_FW_REQUEST_FRAME(ioc
, (u32
*)prequest
);
3561 ii
= mpt_handshake_req_reply_wait(ioc
, request_size
, (u32
*)prequest
,
3562 reply_sz
, (u16
*)preply
, 65 /*seconds*/, sleepFlag
);
3564 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"FW Upload completed "
3565 "rc=%x \n", ioc
->name
, ii
));
3567 cmdStatus
= -EFAULT
;
3569 /* Handshake transfer was complete and successful.
3570 * Check the Reply Frame.
3573 status
= le16_to_cpu(preply
->IOCStatus
) &
3575 if (status
== MPI_IOCSTATUS_SUCCESS
&&
3576 ioc
->facts
.FWImageSize
==
3577 le32_to_cpu(preply
->ActualImageSize
))
3580 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
": do_upload cmdStatus=%d \n",
3581 ioc
->name
, cmdStatus
));
3585 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"fw upload failed, "
3586 "freeing image \n", ioc
->name
));
3587 mpt_free_fw_memory(ioc
);
3594 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3596 * mpt_downloadboot - DownloadBoot code
3597 * @ioc: Pointer to MPT_ADAPTER structure
3598 * @pFwHeader: Pointer to firmware header info
3599 * @sleepFlag: Specifies whether the process can sleep
3601 * FwDownloadBoot requires Programmed IO access.
3603 * Returns 0 for success
3604 * -1 FW Image size is 0
3605 * -2 No valid cached_fw Pointer
3606 * <0 for fw upload failure.
3609 mpt_downloadboot(MPT_ADAPTER
*ioc
, MpiFwHeader_t
*pFwHeader
, int sleepFlag
)
3611 MpiExtImageHeader_t
*pExtImage
;
3621 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3622 ioc
->name
, pFwHeader
->ImageSize
, pFwHeader
->ImageSize
, pFwHeader
));
3624 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3625 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3626 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3627 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3628 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3629 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3631 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, (MPI_DIAG_PREVENT_IOC_BOOT
| MPI_DIAG_DISABLE_ARM
));
3634 if (sleepFlag
== CAN_SLEEP
) {
3640 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3641 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_RESET_ADAPTER
);
3643 for (count
= 0; count
< 30; count
++) {
3644 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3645 if (!(diag0val
& MPI_DIAG_RESET_ADAPTER
)) {
3646 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RESET_ADAPTER cleared, count=%d\n",
3651 if (sleepFlag
== CAN_SLEEP
) {
3658 if ( count
== 30 ) {
3659 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot failed! "
3660 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3661 ioc
->name
, diag0val
));
3665 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3666 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3667 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3668 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3669 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3670 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3672 /* Set the DiagRwEn and Disable ARM bits */
3673 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, (MPI_DIAG_RW_ENABLE
| MPI_DIAG_DISABLE_ARM
));
3675 fwSize
= (pFwHeader
->ImageSize
+ 3)/4;
3676 ptrFw
= (u32
*) pFwHeader
;
3678 /* Write the LoadStartAddress to the DiagRw Address Register
3679 * using Programmed IO
3681 if (ioc
->errata_flag_1064
)
3682 pci_enable_io_access(ioc
->pcidev
);
3684 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, pFwHeader
->LoadStartAddress
);
3685 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"LoadStart addr written 0x%x \n",
3686 ioc
->name
, pFwHeader
->LoadStartAddress
));
3688 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write FW Image: 0x%x bytes @ %p\n",
3689 ioc
->name
, fwSize
*4, ptrFw
));
3691 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, *ptrFw
++);
3694 nextImage
= pFwHeader
->NextImageHeaderOffset
;
3696 pExtImage
= (MpiExtImageHeader_t
*) ((char *)pFwHeader
+ nextImage
);
3698 load_addr
= pExtImage
->LoadStartAddress
;
3700 fwSize
= (pExtImage
->ImageSize
+ 3) >> 2;
3701 ptrFw
= (u32
*)pExtImage
;
3703 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3704 ioc
->name
, fwSize
*4, fwSize
*4, ptrFw
, load_addr
));
3705 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, load_addr
);
3708 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, *ptrFw
++);
3710 nextImage
= pExtImage
->NextImageHeaderOffset
;
3713 /* Write the IopResetVectorRegAddr */
3714 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write IopResetVector Addr=%x! \n", ioc
->name
, pFwHeader
->IopResetRegAddr
));
3715 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, pFwHeader
->IopResetRegAddr
);
3717 /* Write the IopResetVectorValue */
3718 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write IopResetVector Value=%x! \n", ioc
->name
, pFwHeader
->IopResetVectorValue
));
3719 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, pFwHeader
->IopResetVectorValue
);
3721 /* Clear the internal flash bad bit - autoincrementing register,
3722 * so must do two writes.
3724 if (ioc
->bus_type
== SPI
) {
3726 * 1030 and 1035 H/W errata, workaround to access
3727 * the ClearFlashBadSignatureBit
3729 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, 0x3F000000);
3730 diagRwData
= CHIPREG_PIO_READ32(&ioc
->pio_chip
->DiagRwData
);
3731 diagRwData
|= 0x40000000;
3732 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, 0x3F000000);
3733 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, diagRwData
);
3735 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3736 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3737 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
|
3738 MPI_DIAG_CLEAR_FLASH_BAD_SIG
);
3741 if (sleepFlag
== CAN_SLEEP
) {
3748 if (ioc
->errata_flag_1064
)
3749 pci_disable_io_access(ioc
->pcidev
);
3751 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3752 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot diag0val=%x, "
3753 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3754 ioc
->name
, diag0val
));
3755 diag0val
&= ~(MPI_DIAG_PREVENT_IOC_BOOT
| MPI_DIAG_DISABLE_ARM
| MPI_DIAG_RW_ENABLE
);
3756 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot now diag0val=%x\n",
3757 ioc
->name
, diag0val
));
3758 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
);
3760 /* Write 0xFF to reset the sequencer */
3761 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3763 if (ioc
->bus_type
== SAS
) {
3764 ioc_state
= mpt_GetIocState(ioc
, 0);
3765 if ( (GetIocFacts(ioc
, sleepFlag
,
3766 MPT_HOSTEVENT_IOC_BRINGUP
)) != 0 ) {
3767 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"GetIocFacts failed: IocState=%x\n",
3768 ioc
->name
, ioc_state
));
3773 for (count
=0; count
<HZ
*20; count
++) {
3774 if ((ioc_state
= mpt_GetIocState(ioc
, 0)) & MPI_IOC_STATE_READY
) {
3775 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3776 "downloadboot successful! (count=%d) IocState=%x\n",
3777 ioc
->name
, count
, ioc_state
));
3778 if (ioc
->bus_type
== SAS
) {
3781 if ((SendIocInit(ioc
, sleepFlag
)) != 0) {
3782 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3783 "downloadboot: SendIocInit failed\n",
3787 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3788 "downloadboot: SendIocInit successful\n",
3792 if (sleepFlag
== CAN_SLEEP
) {
3798 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3799 "downloadboot failed! IocState=%x\n",ioc
->name
, ioc_state
));
3803 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3805 * KickStart - Perform hard reset of MPT adapter.
3806 * @ioc: Pointer to MPT_ADAPTER structure
3807 * @force: Force hard reset
3808 * @sleepFlag: Specifies whether the process can sleep
3810 * This routine places MPT adapter in diagnostic mode via the
3811 * WriteSequence register, and then performs a hard reset of adapter
3812 * via the Diagnostic register.
3814 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3815 * or NO_SLEEP (interrupt thread, use mdelay)
3816 * force - 1 if doorbell active, board fault state
3817 * board operational, IOC_RECOVERY or
3818 * IOC_BRINGUP and there is an alt_ioc.
3822 * 1 - hard reset, READY
3823 * 0 - no reset due to History bit, READY
3824 * -1 - no reset due to History bit but not READY
3825 * OR reset but failed to come READY
3826 * -2 - no reset, could not enter DIAG mode
3827 * -3 - reset but bad FW bit
3830 KickStart(MPT_ADAPTER
*ioc
, int force
, int sleepFlag
)
3832 int hard_reset_done
= 0;
3836 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"KickStarting!\n", ioc
->name
));
3837 if (ioc
->bus_type
== SPI
) {
3838 /* Always issue a Msg Unit Reset first. This will clear some
3839 * SCSI bus hang conditions.
3841 SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
);
3843 if (sleepFlag
== CAN_SLEEP
) {
3850 hard_reset_done
= mpt_diag_reset(ioc
, force
, sleepFlag
);
3851 if (hard_reset_done
< 0)
3852 return hard_reset_done
;
3854 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Diagnostic reset successful!\n",
3857 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 2; /* 2 seconds */
3858 for (cnt
=0; cnt
<cntdn
; cnt
++) {
3859 ioc_state
= mpt_GetIocState(ioc
, 1);
3860 if ((ioc_state
== MPI_IOC_STATE_READY
) || (ioc_state
== MPI_IOC_STATE_OPERATIONAL
)) {
3861 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"KickStart successful! (cnt=%d)\n",
3863 return hard_reset_done
;
3865 if (sleepFlag
== CAN_SLEEP
) {
3872 dinitprintk(ioc
, printk(MYIOC_s_ERR_FMT
"Failed to come READY after reset! IocState=%x\n",
3873 ioc
->name
, mpt_GetIocState(ioc
, 0)));
3877 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3879 * mpt_diag_reset - Perform hard reset of the adapter.
3880 * @ioc: Pointer to MPT_ADAPTER structure
3881 * @ignore: Set if to honor and clear to ignore
3882 * the reset history bit
3883 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3884 * else set to NO_SLEEP (use mdelay instead)
3886 * This routine places the adapter in diagnostic mode via the
3887 * WriteSequence register and then performs a hard reset of adapter
3888 * via the Diagnostic register. Adapter should be in ready state
3889 * upon successful completion.
3891 * Returns: 1 hard reset successful
3892 * 0 no reset performed because reset history bit set
3893 * -2 enabling diagnostic mode failed
3894 * -3 diagnostic reset failed
3897 mpt_diag_reset(MPT_ADAPTER
*ioc
, int ignore
, int sleepFlag
)
3901 int hard_reset_done
= 0;
3904 MpiFwHeader_t
*cached_fw
; /* Pointer to FW */
3907 /* Clear any existing interrupts */
3908 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
3910 if (ioc
->pcidev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1078
) {
3915 drsprintk(ioc
, printk(MYIOC_s_WARN_FMT
"%s: Doorbell=%p; 1078 reset "
3916 "address=%p\n", ioc
->name
, __func__
,
3917 &ioc
->chip
->Doorbell
, &ioc
->chip
->Reset_1078
));
3918 CHIPREG_WRITE32(&ioc
->chip
->Reset_1078
, 0x07);
3919 if (sleepFlag
== CAN_SLEEP
)
3925 * Call each currently registered protocol IOC reset handler
3926 * with pre-reset indication.
3927 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3928 * MptResetHandlers[] registered yet.
3930 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
3931 if (MptResetHandlers
[cb_idx
])
3932 (*(MptResetHandlers
[cb_idx
]))(ioc
,
3936 for (count
= 0; count
< 60; count
++) {
3937 doorbell
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
3938 doorbell
&= MPI_IOC_STATE_MASK
;
3940 drsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3941 "looking for READY STATE: doorbell=%x"
3943 ioc
->name
, doorbell
, count
));
3945 if (doorbell
== MPI_IOC_STATE_READY
) {
3950 if (sleepFlag
== CAN_SLEEP
)
3958 /* Use "Diagnostic reset" method! (only thing available!) */
3959 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3961 if (ioc
->debug_level
& MPT_DEBUG
) {
3963 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
3964 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG1: diag0=%08x, diag1=%08x\n",
3965 ioc
->name
, diag0val
, diag1val
));
3968 /* Do the reset if we are told to ignore the reset history
3969 * or if the reset history is 0
3971 if (ignore
|| !(diag0val
& MPI_DIAG_RESET_HISTORY
)) {
3972 while ((diag0val
& MPI_DIAG_DRWE
) == 0) {
3973 /* Write magic sequence to WriteSequence register
3974 * Loop until in diagnostic mode
3976 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3977 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3978 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3979 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3980 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3981 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3984 if (sleepFlag
== CAN_SLEEP
) {
3992 printk(MYIOC_s_ERR_FMT
"Enable Diagnostic mode FAILED! (%02xh)\n",
3993 ioc
->name
, diag0val
);
3998 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4000 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Wrote magic DiagWriteEn sequence (%x)\n",
4001 ioc
->name
, diag0val
));
4004 if (ioc
->debug_level
& MPT_DEBUG
) {
4006 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
4007 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG2: diag0=%08x, diag1=%08x\n",
4008 ioc
->name
, diag0val
, diag1val
));
4011 * Disable the ARM (Bug fix)
4014 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_DISABLE_ARM
);
4018 * Now hit the reset bit in the Diagnostic register
4019 * (THE BIG HAMMER!) (Clears DRWE bit).
4021 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_RESET_ADAPTER
);
4022 hard_reset_done
= 1;
4023 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Diagnostic reset performed\n",
4027 * Call each currently registered protocol IOC reset handler
4028 * with pre-reset indication.
4029 * NOTE: If we're doing _IOC_BRINGUP, there can be no
4030 * MptResetHandlers[] registered yet.
4032 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
4033 if (MptResetHandlers
[cb_idx
]) {
4034 mpt_signal_reset(cb_idx
,
4035 ioc
, MPT_IOC_PRE_RESET
);
4037 mpt_signal_reset(cb_idx
,
4038 ioc
->alt_ioc
, MPT_IOC_PRE_RESET
);
4044 cached_fw
= (MpiFwHeader_t
*)ioc
->cached_fw
;
4045 else if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
)
4046 cached_fw
= (MpiFwHeader_t
*)ioc
->alt_ioc
->cached_fw
;
4050 /* If the DownloadBoot operation fails, the
4051 * IOC will be left unusable. This is a fatal error
4052 * case. _diag_reset will return < 0
4054 for (count
= 0; count
< 30; count
++) {
4055 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4056 if (!(diag0val
& MPI_DIAG_RESET_ADAPTER
)) {
4060 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"cached_fw: diag0val=%x count=%d\n",
4061 ioc
->name
, diag0val
, count
));
4063 if (sleepFlag
== CAN_SLEEP
) {
4069 if ((count
= mpt_downloadboot(ioc
, cached_fw
, sleepFlag
)) < 0) {
4070 printk(MYIOC_s_WARN_FMT
4071 "firmware downloadboot failure (%d)!\n", ioc
->name
, count
);
4075 /* Wait for FW to reload and for board
4076 * to go to the READY state.
4077 * Maximum wait is 60 seconds.
4078 * If fail, no error will check again
4079 * with calling program.
4081 for (count
= 0; count
< 60; count
++) {
4082 doorbell
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
4083 doorbell
&= MPI_IOC_STATE_MASK
;
4085 drsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4086 "looking for READY STATE: doorbell=%x"
4087 " count=%d\n", ioc
->name
, doorbell
, count
));
4089 if (doorbell
== MPI_IOC_STATE_READY
) {
4094 if (sleepFlag
== CAN_SLEEP
) {
4101 if (doorbell
!= MPI_IOC_STATE_READY
)
4102 printk(MYIOC_s_ERR_FMT
"Failed to come READY "
4103 "after reset! IocState=%x", ioc
->name
,
4108 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4109 if (ioc
->debug_level
& MPT_DEBUG
) {
4111 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
4112 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG3: diag0=%08x, diag1=%08x\n",
4113 ioc
->name
, diag0val
, diag1val
));
4116 /* Clear RESET_HISTORY bit! Place board in the
4117 * diagnostic mode to update the diag register.
4119 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4121 while ((diag0val
& MPI_DIAG_DRWE
) == 0) {
4122 /* Write magic sequence to WriteSequence register
4123 * Loop until in diagnostic mode
4125 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
4126 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
4127 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
4128 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
4129 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
4130 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
4133 if (sleepFlag
== CAN_SLEEP
) {
4141 printk(MYIOC_s_ERR_FMT
"Enable Diagnostic mode FAILED! (%02xh)\n",
4142 ioc
->name
, diag0val
);
4145 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4147 diag0val
&= ~MPI_DIAG_RESET_HISTORY
;
4148 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
);
4149 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4150 if (diag0val
& MPI_DIAG_RESET_HISTORY
) {
4151 printk(MYIOC_s_WARN_FMT
"ResetHistory bit failed to clear!\n",
4155 /* Disable Diagnostic Mode
4157 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFFFFFFFF);
4159 /* Check FW reload status flags.
4161 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4162 if (diag0val
& (MPI_DIAG_FLASH_BAD_SIG
| MPI_DIAG_RESET_ADAPTER
| MPI_DIAG_DISABLE_ARM
)) {
4163 printk(MYIOC_s_ERR_FMT
"Diagnostic reset FAILED! (%02xh)\n",
4164 ioc
->name
, diag0val
);
4168 if (ioc
->debug_level
& MPT_DEBUG
) {
4170 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
4171 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG4: diag0=%08x, diag1=%08x\n",
4172 ioc
->name
, diag0val
, diag1val
));
4176 * Reset flag that says we've enabled event notification
4178 ioc
->facts
.EventState
= 0;
4181 ioc
->alt_ioc
->facts
.EventState
= 0;
4183 return hard_reset_done
;
4186 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4188 * SendIocReset - Send IOCReset request to MPT adapter.
4189 * @ioc: Pointer to MPT_ADAPTER structure
4190 * @reset_type: reset type, expected values are
4191 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
4192 * @sleepFlag: Specifies whether the process can sleep
4194 * Send IOCReset request to the MPT adapter.
4196 * Returns 0 for success, non-zero for failure.
4199 SendIocReset(MPT_ADAPTER
*ioc
, u8 reset_type
, int sleepFlag
)
4205 drsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending IOC reset(0x%02x)!\n",
4206 ioc
->name
, reset_type
));
4207 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, reset_type
<<MPI_DOORBELL_FUNCTION_SHIFT
);
4208 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
4211 /* FW ACK'd request, wait for READY state
4214 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 15; /* 15 seconds */
4216 while ((state
= mpt_GetIocState(ioc
, 1)) != MPI_IOC_STATE_READY
) {
4220 if (sleepFlag
!= CAN_SLEEP
)
4223 printk(MYIOC_s_ERR_FMT
4224 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
4225 ioc
->name
, state
, (int)((count
+5)/HZ
));
4229 if (sleepFlag
== CAN_SLEEP
) {
4232 mdelay (1); /* 1 msec delay */
4237 * Cleanup all event stuff for this IOC; re-issue EventNotification
4238 * request if needed.
4240 if (ioc
->facts
.Function
)
4241 ioc
->facts
.EventState
= 0;
4246 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4248 * initChainBuffers - Allocate memory for and initialize chain buffers
4249 * @ioc: Pointer to MPT_ADAPTER structure
4251 * Allocates memory for and initializes chain buffers,
4252 * chain buffer control arrays and spinlock.
4255 initChainBuffers(MPT_ADAPTER
*ioc
)
4258 int sz
, ii
, num_chain
;
4259 int scale
, num_sge
, numSGE
;
4261 /* ReqToChain size must equal the req_depth
4264 if (ioc
->ReqToChain
== NULL
) {
4265 sz
= ioc
->req_depth
* sizeof(int);
4266 mem
= kmalloc(sz
, GFP_ATOMIC
);
4270 ioc
->ReqToChain
= (int *) mem
;
4271 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReqToChain alloc @ %p, sz=%d bytes\n",
4272 ioc
->name
, mem
, sz
));
4273 mem
= kmalloc(sz
, GFP_ATOMIC
);
4277 ioc
->RequestNB
= (int *) mem
;
4278 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestNB alloc @ %p, sz=%d bytes\n",
4279 ioc
->name
, mem
, sz
));
4281 for (ii
= 0; ii
< ioc
->req_depth
; ii
++) {
4282 ioc
->ReqToChain
[ii
] = MPT_HOST_NO_CHAIN
;
4285 /* ChainToChain size must equal the total number
4286 * of chain buffers to be allocated.
4289 * Calculate the number of chain buffers needed(plus 1) per I/O
4290 * then multiply the maximum number of simultaneous cmds
4292 * num_sge = num sge in request frame + last chain buffer
4293 * scale = num sge per chain buffer if no chain element
4295 scale
= ioc
->req_sz
/ ioc
->SGE_size
;
4296 if (ioc
->sg_addr_size
== sizeof(u64
))
4297 num_sge
= scale
+ (ioc
->req_sz
- 60) / ioc
->SGE_size
;
4299 num_sge
= 1 + scale
+ (ioc
->req_sz
- 64) / ioc
->SGE_size
;
4301 if (ioc
->sg_addr_size
== sizeof(u64
)) {
4302 numSGE
= (scale
- 1) * (ioc
->facts
.MaxChainDepth
-1) + scale
+
4303 (ioc
->req_sz
- 60) / ioc
->SGE_size
;
4305 numSGE
= 1 + (scale
- 1) * (ioc
->facts
.MaxChainDepth
-1) +
4306 scale
+ (ioc
->req_sz
- 64) / ioc
->SGE_size
;
4308 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"num_sge=%d numSGE=%d\n",
4309 ioc
->name
, num_sge
, numSGE
));
4311 if (ioc
->bus_type
== FC
) {
4312 if (numSGE
> MPT_SCSI_FC_SG_DEPTH
)
4313 numSGE
= MPT_SCSI_FC_SG_DEPTH
;
4315 if (numSGE
> MPT_SCSI_SG_DEPTH
)
4316 numSGE
= MPT_SCSI_SG_DEPTH
;
4320 while (numSGE
- num_sge
> 0) {
4322 num_sge
+= (scale
- 1);
4326 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Now numSGE=%d num_sge=%d num_chain=%d\n",
4327 ioc
->name
, numSGE
, num_sge
, num_chain
));
4329 if (ioc
->bus_type
== SPI
)
4330 num_chain
*= MPT_SCSI_CAN_QUEUE
;
4331 else if (ioc
->bus_type
== SAS
)
4332 num_chain
*= MPT_SAS_CAN_QUEUE
;
4334 num_chain
*= MPT_FC_CAN_QUEUE
;
4336 ioc
->num_chain
= num_chain
;
4338 sz
= num_chain
* sizeof(int);
4339 if (ioc
->ChainToChain
== NULL
) {
4340 mem
= kmalloc(sz
, GFP_ATOMIC
);
4344 ioc
->ChainToChain
= (int *) mem
;
4345 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainToChain alloc @ %p, sz=%d bytes\n",
4346 ioc
->name
, mem
, sz
));
4348 mem
= (u8
*) ioc
->ChainToChain
;
4350 memset(mem
, 0xFF, sz
);
4354 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4356 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
4357 * @ioc: Pointer to MPT_ADAPTER structure
4359 * This routine allocates memory for the MPT reply and request frame
4360 * pools (if necessary), and primes the IOC reply FIFO with
4363 * Returns 0 for success, non-zero for failure.
4366 PrimeIocFifos(MPT_ADAPTER
*ioc
)
4369 unsigned long flags
;
4370 dma_addr_t alloc_dma
;
4372 int i
, reply_sz
, sz
, total_size
, num_chain
;
4377 /* Prime reply FIFO... */
4379 if (ioc
->reply_frames
== NULL
) {
4380 if ( (num_chain
= initChainBuffers(ioc
)) < 0)
4383 * 1078 errata workaround for the 36GB limitation
4385 if (ioc
->pcidev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1078
&&
4386 ioc
->dma_mask
> DMA_BIT_MASK(35)) {
4387 if (!pci_set_dma_mask(ioc
->pcidev
, DMA_BIT_MASK(32))
4388 && !pci_set_consistent_dma_mask(ioc
->pcidev
,
4389 DMA_BIT_MASK(32))) {
4390 dma_mask
= DMA_BIT_MASK(35);
4391 d36memprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4392 "setting 35 bit addressing for "
4393 "Request/Reply/Chain and Sense Buffers\n",
4396 /*Reseting DMA mask to 64 bit*/
4397 pci_set_dma_mask(ioc
->pcidev
,
4399 pci_set_consistent_dma_mask(ioc
->pcidev
,
4402 printk(MYIOC_s_ERR_FMT
4403 "failed setting 35 bit addressing for "
4404 "Request/Reply/Chain and Sense Buffers\n",
4410 total_size
= reply_sz
= (ioc
->reply_sz
* ioc
->reply_depth
);
4411 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
4412 ioc
->name
, ioc
->reply_sz
, ioc
->reply_depth
));
4413 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffer sz=%d[%x] bytes\n",
4414 ioc
->name
, reply_sz
, reply_sz
));
4416 sz
= (ioc
->req_sz
* ioc
->req_depth
);
4417 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestBuffer sz=%d bytes, RequestDepth=%d\n",
4418 ioc
->name
, ioc
->req_sz
, ioc
->req_depth
));
4419 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestBuffer sz=%d[%x] bytes\n",
4420 ioc
->name
, sz
, sz
));
4423 sz
= num_chain
* ioc
->req_sz
; /* chain buffer pool size */
4424 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainBuffer sz=%d bytes, ChainDepth=%d\n",
4425 ioc
->name
, ioc
->req_sz
, num_chain
));
4426 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
4427 ioc
->name
, sz
, sz
, num_chain
));
4430 mem
= pci_alloc_consistent(ioc
->pcidev
, total_size
, &alloc_dma
);
4432 printk(MYIOC_s_ERR_FMT
"Unable to allocate Reply, Request, Chain Buffers!\n",
4437 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Total alloc @ %p[%p], sz=%d[%x] bytes\n",
4438 ioc
->name
, mem
, (void *)(ulong
)alloc_dma
, total_size
, total_size
));
4440 memset(mem
, 0, total_size
);
4441 ioc
->alloc_total
+= total_size
;
4443 ioc
->alloc_dma
= alloc_dma
;
4444 ioc
->alloc_sz
= total_size
;
4445 ioc
->reply_frames
= (MPT_FRAME_HDR
*) mem
;
4446 ioc
->reply_frames_low_dma
= (u32
) (alloc_dma
& 0xFFFFFFFF);
4448 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffers @ %p[%p]\n",
4449 ioc
->name
, ioc
->reply_frames
, (void *)(ulong
)alloc_dma
));
4451 alloc_dma
+= reply_sz
;
4454 /* Request FIFO - WE manage this! */
4456 ioc
->req_frames
= (MPT_FRAME_HDR
*) mem
;
4457 ioc
->req_frames_dma
= alloc_dma
;
4459 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestBuffers @ %p[%p]\n",
4460 ioc
->name
, mem
, (void *)(ulong
)alloc_dma
));
4462 ioc
->req_frames_low_dma
= (u32
) (alloc_dma
& 0xFFFFFFFF);
4464 #if defined(CONFIG_MTRR) && 0
4466 * Enable Write Combining MTRR for IOC's memory region.
4467 * (at least as much as we can; "size and base must be
4468 * multiples of 4 kiB"
4470 ioc
->mtrr_reg
= mtrr_add(ioc
->req_frames_dma
,
4472 MTRR_TYPE_WRCOMB
, 1);
4473 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"MTRR region registered (base:size=%08x:%x)\n",
4474 ioc
->name
, ioc
->req_frames_dma
, sz
));
4477 for (i
= 0; i
< ioc
->req_depth
; i
++) {
4478 alloc_dma
+= ioc
->req_sz
;
4482 ioc
->ChainBuffer
= mem
;
4483 ioc
->ChainBufferDMA
= alloc_dma
;
4485 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainBuffers @ %p(%p)\n",
4486 ioc
->name
, ioc
->ChainBuffer
, (void *)(ulong
)ioc
->ChainBufferDMA
));
4488 /* Initialize the free chain Q.
4491 INIT_LIST_HEAD(&ioc
->FreeChainQ
);
4493 /* Post the chain buffers to the FreeChainQ.
4495 mem
= (u8
*)ioc
->ChainBuffer
;
4496 for (i
=0; i
< num_chain
; i
++) {
4497 mf
= (MPT_FRAME_HDR
*) mem
;
4498 list_add_tail(&mf
->u
.frame
.linkage
.list
, &ioc
->FreeChainQ
);
4502 /* Initialize Request frames linked list
4504 alloc_dma
= ioc
->req_frames_dma
;
4505 mem
= (u8
*) ioc
->req_frames
;
4507 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
4508 INIT_LIST_HEAD(&ioc
->FreeQ
);
4509 for (i
= 0; i
< ioc
->req_depth
; i
++) {
4510 mf
= (MPT_FRAME_HDR
*) mem
;
4512 /* Queue REQUESTs *internally*! */
4513 list_add_tail(&mf
->u
.frame
.linkage
.list
, &ioc
->FreeQ
);
4517 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
4519 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
4520 ioc
->sense_buf_pool
=
4521 pci_alloc_consistent(ioc
->pcidev
, sz
, &ioc
->sense_buf_pool_dma
);
4522 if (ioc
->sense_buf_pool
== NULL
) {
4523 printk(MYIOC_s_ERR_FMT
"Unable to allocate Sense Buffers!\n",
4528 ioc
->sense_buf_low_dma
= (u32
) (ioc
->sense_buf_pool_dma
& 0xFFFFFFFF);
4529 ioc
->alloc_total
+= sz
;
4530 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SenseBuffers @ %p[%p]\n",
4531 ioc
->name
, ioc
->sense_buf_pool
, (void *)(ulong
)ioc
->sense_buf_pool_dma
));
4535 /* Post Reply frames to FIFO
4537 alloc_dma
= ioc
->alloc_dma
;
4538 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffers @ %p[%p]\n",
4539 ioc
->name
, ioc
->reply_frames
, (void *)(ulong
)alloc_dma
));
4541 for (i
= 0; i
< ioc
->reply_depth
; i
++) {
4542 /* Write each address to the IOC! */
4543 CHIPREG_WRITE32(&ioc
->chip
->ReplyFifo
, alloc_dma
);
4544 alloc_dma
+= ioc
->reply_sz
;
4547 if (dma_mask
== DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc
->pcidev
,
4548 ioc
->dma_mask
) && !pci_set_consistent_dma_mask(ioc
->pcidev
,
4550 d36memprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4551 "restoring 64 bit addressing\n", ioc
->name
));
4557 if (ioc
->alloc
!= NULL
) {
4559 pci_free_consistent(ioc
->pcidev
,
4561 ioc
->alloc
, ioc
->alloc_dma
);
4562 ioc
->reply_frames
= NULL
;
4563 ioc
->req_frames
= NULL
;
4564 ioc
->alloc_total
-= sz
;
4566 if (ioc
->sense_buf_pool
!= NULL
) {
4567 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
4568 pci_free_consistent(ioc
->pcidev
,
4570 ioc
->sense_buf_pool
, ioc
->sense_buf_pool_dma
);
4571 ioc
->sense_buf_pool
= NULL
;
4574 if (dma_mask
== DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc
->pcidev
,
4575 DMA_BIT_MASK(64)) && !pci_set_consistent_dma_mask(ioc
->pcidev
,
4577 d36memprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4578 "restoring 64 bit addressing\n", ioc
->name
));
4583 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4585 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4586 * from IOC via doorbell handshake method.
4587 * @ioc: Pointer to MPT_ADAPTER structure
4588 * @reqBytes: Size of the request in bytes
4589 * @req: Pointer to MPT request frame
4590 * @replyBytes: Expected size of the reply in bytes
4591 * @u16reply: Pointer to area where reply should be written
4592 * @maxwait: Max wait time for a reply (in seconds)
4593 * @sleepFlag: Specifies whether the process can sleep
4595 * NOTES: It is the callers responsibility to byte-swap fields in the
4596 * request which are greater than 1 byte in size. It is also the
4597 * callers responsibility to byte-swap response fields which are
4598 * greater than 1 byte in size.
4600 * Returns 0 for success, non-zero for failure.
4603 mpt_handshake_req_reply_wait(MPT_ADAPTER
*ioc
, int reqBytes
, u32
*req
,
4604 int replyBytes
, u16
*u16reply
, int maxwait
, int sleepFlag
)
4606 MPIDefaultReply_t
*mptReply
;
4611 * Get ready to cache a handshake reply
4613 ioc
->hs_reply_idx
= 0;
4614 mptReply
= (MPIDefaultReply_t
*) ioc
->hs_reply
;
4615 mptReply
->MsgLength
= 0;
4618 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4619 * then tell IOC that we want to handshake a request of N words.
4620 * (WRITE u32val to Doorbell reg).
4622 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4623 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
,
4624 ((MPI_FUNCTION_HANDSHAKE
<<MPI_DOORBELL_FUNCTION_SHIFT
) |
4625 ((reqBytes
/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT
)));
4628 * Wait for IOC's doorbell handshake int
4630 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4633 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4634 ioc
->name
, reqBytes
, t
, failcnt
? " - MISSING DOORBELL HANDSHAKE!" : ""));
4636 /* Read doorbell and check for active bit */
4637 if (!(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & MPI_DOORBELL_ACTIVE
))
4641 * Clear doorbell int (WRITE 0 to IntStatus reg),
4642 * then wait for IOC to ACKnowledge that it's ready for
4643 * our handshake request.
4645 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4646 if (!failcnt
&& (t
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
4651 u8
*req_as_bytes
= (u8
*) req
;
4654 * Stuff request words via doorbell handshake,
4655 * with ACK from IOC for each.
4657 for (ii
= 0; !failcnt
&& ii
< reqBytes
/4; ii
++) {
4658 u32 word
= ((req_as_bytes
[(ii
*4) + 0] << 0) |
4659 (req_as_bytes
[(ii
*4) + 1] << 8) |
4660 (req_as_bytes
[(ii
*4) + 2] << 16) |
4661 (req_as_bytes
[(ii
*4) + 3] << 24));
4663 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, word
);
4664 if ((t
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
4668 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Handshake request frame (@%p) header\n", ioc
->name
, req
));
4669 DBG_DUMP_REQUEST_FRAME_HDR(ioc
, (u32
*)req
);
4671 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HandShake request post done, WaitCnt=%d%s\n",
4672 ioc
->name
, t
, failcnt
? " - MISSING DOORBELL ACK!" : ""));
4675 * Wait for completion of doorbell handshake reply from the IOC
4677 if (!failcnt
&& (t
= WaitForDoorbellReply(ioc
, maxwait
, sleepFlag
)) < 0)
4680 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HandShake reply count=%d%s\n",
4681 ioc
->name
, t
, failcnt
? " - MISSING DOORBELL REPLY!" : ""));
4684 * Copy out the cached reply...
4686 for (ii
=0; ii
< min(replyBytes
/2,mptReply
->MsgLength
*2); ii
++)
4687 u16reply
[ii
] = ioc
->hs_reply
[ii
];
4695 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4697 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4698 * @ioc: Pointer to MPT_ADAPTER structure
4699 * @howlong: How long to wait (in seconds)
4700 * @sleepFlag: Specifies whether the process can sleep
4702 * This routine waits (up to ~2 seconds max) for IOC doorbell
4703 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4704 * bit in its IntStatus register being clear.
4706 * Returns a negative value on failure, else wait loop count.
4709 WaitForDoorbellAck(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
4715 cntdn
= 1000 * howlong
;
4717 if (sleepFlag
== CAN_SLEEP
) {
4720 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4721 if (! (intstat
& MPI_HIS_IOP_DOORBELL_STATUS
))
4728 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4729 if (! (intstat
& MPI_HIS_IOP_DOORBELL_STATUS
))
4736 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitForDoorbell ACK (count=%d)\n",
4741 printk(MYIOC_s_ERR_FMT
"Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4742 ioc
->name
, count
, intstat
);
4746 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4748 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4749 * @ioc: Pointer to MPT_ADAPTER structure
4750 * @howlong: How long to wait (in seconds)
4751 * @sleepFlag: Specifies whether the process can sleep
4753 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4754 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4756 * Returns a negative value on failure, else wait loop count.
4759 WaitForDoorbellInt(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
4765 cntdn
= 1000 * howlong
;
4766 if (sleepFlag
== CAN_SLEEP
) {
4768 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4769 if (intstat
& MPI_HIS_DOORBELL_INTERRUPT
)
4776 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4777 if (intstat
& MPI_HIS_DOORBELL_INTERRUPT
)
4785 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4786 ioc
->name
, count
, howlong
));
4790 printk(MYIOC_s_ERR_FMT
"Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4791 ioc
->name
, count
, intstat
);
4795 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4797 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4798 * @ioc: Pointer to MPT_ADAPTER structure
4799 * @howlong: How long to wait (in seconds)
4800 * @sleepFlag: Specifies whether the process can sleep
4802 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4803 * Reply is cached to IOC private area large enough to hold a maximum
4804 * of 128 bytes of reply data.
4806 * Returns a negative value on failure, else size of reply in WORDS.
4809 WaitForDoorbellReply(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
4814 u16
*hs_reply
= ioc
->hs_reply
;
4815 volatile MPIDefaultReply_t
*mptReply
= (MPIDefaultReply_t
*) ioc
->hs_reply
;
4818 hs_reply
[0] = hs_reply
[1] = hs_reply
[7] = 0;
4821 * Get first two u16's so we can look at IOC's intended reply MsgLength
4824 if ((t
= WaitForDoorbellInt(ioc
, howlong
, sleepFlag
)) < 0) {
4827 hs_reply
[u16cnt
++] = le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4828 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4829 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4832 hs_reply
[u16cnt
++] = le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4833 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4837 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitCnt=%d First handshake reply word=%08x%s\n",
4838 ioc
->name
, t
, le32_to_cpu(*(u32
*)hs_reply
),
4839 failcnt
? " - MISSING DOORBELL HANDSHAKE!" : ""));
4842 * If no error (and IOC said MsgLength is > 0), piece together
4843 * reply 16 bits at a time.
4845 for (u16cnt
=2; !failcnt
&& u16cnt
< (2 * mptReply
->MsgLength
); u16cnt
++) {
4846 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4848 hword
= le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4849 /* don't overflow our IOC hs_reply[] buffer! */
4850 if (u16cnt
< ARRAY_SIZE(ioc
->hs_reply
))
4851 hs_reply
[u16cnt
] = hword
;
4852 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4855 if (!failcnt
&& (t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4857 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4860 printk(MYIOC_s_ERR_FMT
"Handshake reply failure!\n",
4865 else if (u16cnt
!= (2 * mptReply
->MsgLength
)) {
4868 else if ((mptReply
->IOCStatus
& MPI_IOCSTATUS_MASK
) != MPI_IOCSTATUS_SUCCESS
) {
4873 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Got Handshake reply:\n", ioc
->name
));
4874 DBG_DUMP_REPLY_FRAME(ioc
, (u32
*)mptReply
);
4876 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4877 ioc
->name
, t
, u16cnt
/2));
4881 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4883 * GetLanConfigPages - Fetch LANConfig pages.
4884 * @ioc: Pointer to MPT_ADAPTER structure
4886 * Return: 0 for success
4887 * -ENOMEM if no memory available
4888 * -EPERM if not allowed due to ISR context
4889 * -EAGAIN if no msg frames currently available
4890 * -EFAULT for non-successful reply or no reply (timeout)
4893 GetLanConfigPages(MPT_ADAPTER
*ioc
)
4895 ConfigPageHeader_t hdr
;
4897 LANPage0_t
*ppage0_alloc
;
4898 dma_addr_t page0_dma
;
4899 LANPage1_t
*ppage1_alloc
;
4900 dma_addr_t page1_dma
;
4905 /* Get LAN Page 0 header */
4906 hdr
.PageVersion
= 0;
4909 hdr
.PageType
= MPI_CONFIG_PAGETYPE_LAN
;
4910 cfg
.cfghdr
.hdr
= &hdr
;
4912 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4917 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
4920 if (hdr
.PageLength
> 0) {
4921 data_sz
= hdr
.PageLength
* 4;
4922 ppage0_alloc
= (LANPage0_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page0_dma
);
4925 memset((u8
*)ppage0_alloc
, 0, data_sz
);
4926 cfg
.physAddr
= page0_dma
;
4927 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4929 if ((rc
= mpt_config(ioc
, &cfg
)) == 0) {
4931 copy_sz
= min_t(int, sizeof(LANPage0_t
), data_sz
);
4932 memcpy(&ioc
->lan_cnfg_page0
, ppage0_alloc
, copy_sz
);
4936 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage0_alloc
, page0_dma
);
4939 * Normalize endianness of structure data,
4940 * by byte-swapping all > 1 byte fields!
4949 /* Get LAN Page 1 header */
4950 hdr
.PageVersion
= 0;
4953 hdr
.PageType
= MPI_CONFIG_PAGETYPE_LAN
;
4954 cfg
.cfghdr
.hdr
= &hdr
;
4956 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4960 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
4963 if (hdr
.PageLength
== 0)
4966 data_sz
= hdr
.PageLength
* 4;
4968 ppage1_alloc
= (LANPage1_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page1_dma
);
4970 memset((u8
*)ppage1_alloc
, 0, data_sz
);
4971 cfg
.physAddr
= page1_dma
;
4972 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4974 if ((rc
= mpt_config(ioc
, &cfg
)) == 0) {
4976 copy_sz
= min_t(int, sizeof(LANPage1_t
), data_sz
);
4977 memcpy(&ioc
->lan_cnfg_page1
, ppage1_alloc
, copy_sz
);
4980 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage1_alloc
, page1_dma
);
4983 * Normalize endianness of structure data,
4984 * by byte-swapping all > 1 byte fields!
4992 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4994 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
4995 * @ioc: Pointer to MPT_ADAPTER structure
4996 * @persist_opcode: see below
4998 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4999 * devices not currently present.
5000 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
5002 * NOTE: Don't use not this function during interrupt time.
5004 * Returns 0 for success, non-zero error
5007 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5009 mptbase_sas_persist_operation(MPT_ADAPTER
*ioc
, u8 persist_opcode
)
5011 SasIoUnitControlRequest_t
*sasIoUnitCntrReq
;
5012 SasIoUnitControlReply_t
*sasIoUnitCntrReply
;
5013 MPT_FRAME_HDR
*mf
= NULL
;
5014 MPIHeader_t
*mpi_hdr
;
5016 unsigned long timeleft
;
5018 mutex_lock(&ioc
->mptbase_cmds
.mutex
);
5020 /* init the internal cmd struct */
5021 memset(ioc
->mptbase_cmds
.reply
, 0 , MPT_DEFAULT_FRAME_SIZE
);
5022 INITIALIZE_MGMT_STATUS(ioc
->mptbase_cmds
.status
)
5024 /* insure garbage is not sent to fw */
5025 switch(persist_opcode
) {
5027 case MPI_SAS_OP_CLEAR_NOT_PRESENT
:
5028 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT
:
5036 printk(KERN_DEBUG
"%s: persist_opcode=%x\n",
5037 __func__
, persist_opcode
);
5039 /* Get a MF for this command.
5041 if ((mf
= mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
5042 printk(KERN_DEBUG
"%s: no msg frames!\n", __func__
);
5047 mpi_hdr
= (MPIHeader_t
*) mf
;
5048 sasIoUnitCntrReq
= (SasIoUnitControlRequest_t
*)mf
;
5049 memset(sasIoUnitCntrReq
,0,sizeof(SasIoUnitControlRequest_t
));
5050 sasIoUnitCntrReq
->Function
= MPI_FUNCTION_SAS_IO_UNIT_CONTROL
;
5051 sasIoUnitCntrReq
->MsgContext
= mpi_hdr
->MsgContext
;
5052 sasIoUnitCntrReq
->Operation
= persist_opcode
;
5054 mpt_put_msg_frame(mpt_base_index
, ioc
, mf
);
5055 timeleft
= wait_for_completion_timeout(&ioc
->mptbase_cmds
.done
, 10*HZ
);
5056 if (!(ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_COMMAND_GOOD
)) {
5058 printk(KERN_DEBUG
"%s: failed\n", __func__
);
5059 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_DID_IOCRESET
)
5062 printk(MYIOC_s_WARN_FMT
5063 "Issuing Reset from %s!!, doorbell=0x%08x\n",
5064 ioc
->name
, __func__
, mpt_GetIocState(ioc
, 0));
5065 mpt_Soft_Hard_ResetHandler(ioc
, CAN_SLEEP
);
5066 mpt_free_msg_frame(ioc
, mf
);
5071 if (!(ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_RF_VALID
)) {
5076 sasIoUnitCntrReply
=
5077 (SasIoUnitControlReply_t
*)ioc
->mptbase_cmds
.reply
;
5078 if (le16_to_cpu(sasIoUnitCntrReply
->IOCStatus
) != MPI_IOCSTATUS_SUCCESS
) {
5079 printk(KERN_DEBUG
"%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
5080 __func__
, sasIoUnitCntrReply
->IOCStatus
,
5081 sasIoUnitCntrReply
->IOCLogInfo
);
5082 printk(KERN_DEBUG
"%s: failed\n", __func__
);
5085 printk(KERN_DEBUG
"%s: success\n", __func__
);
5088 CLEAR_MGMT_STATUS(ioc
->mptbase_cmds
.status
)
5089 mutex_unlock(&ioc
->mptbase_cmds
.mutex
);
5093 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5096 mptbase_raid_process_event_data(MPT_ADAPTER
*ioc
,
5097 MpiEventDataRaid_t
* pRaidEventData
)
5106 volume
= pRaidEventData
->VolumeID
;
5107 reason
= pRaidEventData
->ReasonCode
;
5108 disk
= pRaidEventData
->PhysDiskNum
;
5109 status
= le32_to_cpu(pRaidEventData
->SettingsStatus
);
5110 flags
= (status
>> 0) & 0xff;
5111 state
= (status
>> 8) & 0xff;
5113 if (reason
== MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
) {
5117 if ((reason
>= MPI_EVENT_RAID_RC_PHYSDISK_CREATED
&&
5118 reason
<= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
) ||
5119 (reason
== MPI_EVENT_RAID_RC_SMART_DATA
)) {
5120 printk(MYIOC_s_INFO_FMT
"RAID STATUS CHANGE for PhysDisk %d id=%d\n",
5121 ioc
->name
, disk
, volume
);
5123 printk(MYIOC_s_INFO_FMT
"RAID STATUS CHANGE for VolumeID %d\n",
5128 case MPI_EVENT_RAID_RC_VOLUME_CREATED
:
5129 printk(MYIOC_s_INFO_FMT
" volume has been created\n",
5133 case MPI_EVENT_RAID_RC_VOLUME_DELETED
:
5135 printk(MYIOC_s_INFO_FMT
" volume has been deleted\n",
5139 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED
:
5140 printk(MYIOC_s_INFO_FMT
" volume settings have been changed\n",
5144 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED
:
5145 printk(MYIOC_s_INFO_FMT
" volume is now %s%s%s%s\n",
5147 state
== MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
5149 : state
== MPI_RAIDVOL0_STATUS_STATE_DEGRADED
5151 : state
== MPI_RAIDVOL0_STATUS_STATE_FAILED
5154 flags
& MPI_RAIDVOL0_STATUS_FLAG_ENABLED
5156 flags
& MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
5157 ? ", quiesced" : "",
5158 flags
& MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
5159 ? ", resync in progress" : "" );
5162 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED
:
5163 printk(MYIOC_s_INFO_FMT
" volume membership of PhysDisk %d has changed\n",
5167 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED
:
5168 printk(MYIOC_s_INFO_FMT
" PhysDisk has been created\n",
5172 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED
:
5173 printk(MYIOC_s_INFO_FMT
" PhysDisk has been deleted\n",
5177 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED
:
5178 printk(MYIOC_s_INFO_FMT
" PhysDisk settings have been changed\n",
5182 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
:
5183 printk(MYIOC_s_INFO_FMT
" PhysDisk is now %s%s%s\n",
5185 state
== MPI_PHYSDISK0_STATUS_ONLINE
5187 : state
== MPI_PHYSDISK0_STATUS_MISSING
5189 : state
== MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
5191 : state
== MPI_PHYSDISK0_STATUS_FAILED
5193 : state
== MPI_PHYSDISK0_STATUS_INITIALIZING
5195 : state
== MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
5196 ? "offline requested"
5197 : state
== MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
5198 ? "failed requested"
5199 : state
== MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
5202 flags
& MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
5203 ? ", out of sync" : "",
5204 flags
& MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
5205 ? ", quiesced" : "" );
5208 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
:
5209 printk(MYIOC_s_INFO_FMT
" Domain Validation needed for PhysDisk %d\n",
5213 case MPI_EVENT_RAID_RC_SMART_DATA
:
5214 printk(MYIOC_s_INFO_FMT
" SMART data received, ASC/ASCQ = %02xh/%02xh\n",
5215 ioc
->name
, pRaidEventData
->ASC
, pRaidEventData
->ASCQ
);
5218 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED
:
5219 printk(MYIOC_s_INFO_FMT
" replacement of PhysDisk %d has started\n",
5225 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5227 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
5228 * @ioc: Pointer to MPT_ADAPTER structure
5230 * Returns: 0 for success
5231 * -ENOMEM if no memory available
5232 * -EPERM if not allowed due to ISR context
5233 * -EAGAIN if no msg frames currently available
5234 * -EFAULT for non-successful reply or no reply (timeout)
5237 GetIoUnitPage2(MPT_ADAPTER
*ioc
)
5239 ConfigPageHeader_t hdr
;
5241 IOUnitPage2_t
*ppage_alloc
;
5242 dma_addr_t page_dma
;
5246 /* Get the page header */
5247 hdr
.PageVersion
= 0;
5250 hdr
.PageType
= MPI_CONFIG_PAGETYPE_IO_UNIT
;
5251 cfg
.cfghdr
.hdr
= &hdr
;
5253 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5258 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
5261 if (hdr
.PageLength
== 0)
5264 /* Read the config page */
5265 data_sz
= hdr
.PageLength
* 4;
5267 ppage_alloc
= (IOUnitPage2_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page_dma
);
5269 memset((u8
*)ppage_alloc
, 0, data_sz
);
5270 cfg
.physAddr
= page_dma
;
5271 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5273 /* If Good, save data */
5274 if ((rc
= mpt_config(ioc
, &cfg
)) == 0)
5275 ioc
->biosVersion
= le32_to_cpu(ppage_alloc
->BiosVersion
);
5277 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage_alloc
, page_dma
);
5283 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5285 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
5286 * @ioc: Pointer to a Adapter Strucutre
5287 * @portnum: IOC port number
5289 * Return: -EFAULT if read of config page header fails
5291 * If read of SCSI Port Page 0 fails,
5292 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5293 * Adapter settings: async, narrow
5295 * If read of SCSI Port Page 2 fails,
5296 * Adapter settings valid
5297 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5302 * CHECK - what type of locking mechanisms should be used????
5305 mpt_GetScsiPortSettings(MPT_ADAPTER
*ioc
, int portnum
)
5310 ConfigPageHeader_t header
;
5316 if (!ioc
->spi_data
.nvram
) {
5319 sz
= MPT_MAX_SCSI_DEVICES
* sizeof(int);
5320 mem
= kmalloc(sz
, GFP_ATOMIC
);
5324 ioc
->spi_data
.nvram
= (int *) mem
;
5326 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SCSI device NVRAM settings @ %p, sz=%d\n",
5327 ioc
->name
, ioc
->spi_data
.nvram
, sz
));
5330 /* Invalidate NVRAM information
5332 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
5333 ioc
->spi_data
.nvram
[ii
] = MPT_HOST_NVRAM_INVALID
;
5336 /* Read SPP0 header, allocate memory, then read page.
5338 header
.PageVersion
= 0;
5339 header
.PageLength
= 0;
5340 header
.PageNumber
= 0;
5341 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_PORT
;
5342 cfg
.cfghdr
.hdr
= &header
;
5344 cfg
.pageAddr
= portnum
;
5345 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5347 cfg
.timeout
= 0; /* use default */
5348 if (mpt_config(ioc
, &cfg
) != 0)
5351 if (header
.PageLength
> 0) {
5352 pbuf
= pci_alloc_consistent(ioc
->pcidev
, header
.PageLength
* 4, &buf_dma
);
5354 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5355 cfg
.physAddr
= buf_dma
;
5356 if (mpt_config(ioc
, &cfg
) != 0) {
5357 ioc
->spi_data
.maxBusWidth
= MPT_NARROW
;
5358 ioc
->spi_data
.maxSyncOffset
= 0;
5359 ioc
->spi_data
.minSyncFactor
= MPT_ASYNC
;
5360 ioc
->spi_data
.busType
= MPT_HOST_BUS_UNKNOWN
;
5362 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5363 "Unable to read PortPage0 minSyncFactor=%x\n",
5364 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
5366 /* Save the Port Page 0 data
5368 SCSIPortPage0_t
*pPP0
= (SCSIPortPage0_t
*) pbuf
;
5369 pPP0
->Capabilities
= le32_to_cpu(pPP0
->Capabilities
);
5370 pPP0
->PhysicalInterface
= le32_to_cpu(pPP0
->PhysicalInterface
);
5372 if ( (pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_QAS
) == 0 ) {
5373 ioc
->spi_data
.noQas
|= MPT_TARGET_NO_NEGO_QAS
;
5374 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5375 "noQas due to Capabilities=%x\n",
5376 ioc
->name
, pPP0
->Capabilities
));
5378 ioc
->spi_data
.maxBusWidth
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_WIDE
? 1 : 0;
5379 data
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK
;
5381 ioc
->spi_data
.maxSyncOffset
= (u8
) (data
>> 16);
5382 data
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK
;
5383 ioc
->spi_data
.minSyncFactor
= (u8
) (data
>> 8);
5384 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5385 "PortPage0 minSyncFactor=%x\n",
5386 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
5388 ioc
->spi_data
.maxSyncOffset
= 0;
5389 ioc
->spi_data
.minSyncFactor
= MPT_ASYNC
;
5392 ioc
->spi_data
.busType
= pPP0
->PhysicalInterface
& MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK
;
5394 /* Update the minSyncFactor based on bus type.
5396 if ((ioc
->spi_data
.busType
== MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD
) ||
5397 (ioc
->spi_data
.busType
== MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE
)) {
5399 if (ioc
->spi_data
.minSyncFactor
< MPT_ULTRA
) {
5400 ioc
->spi_data
.minSyncFactor
= MPT_ULTRA
;
5401 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5402 "HVD or SE detected, minSyncFactor=%x\n",
5403 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
5408 pci_free_consistent(ioc
->pcidev
, header
.PageLength
* 4, pbuf
, buf_dma
);
5413 /* SCSI Port Page 2 - Read the header then the page.
5415 header
.PageVersion
= 0;
5416 header
.PageLength
= 0;
5417 header
.PageNumber
= 2;
5418 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_PORT
;
5419 cfg
.cfghdr
.hdr
= &header
;
5421 cfg
.pageAddr
= portnum
;
5422 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5424 if (mpt_config(ioc
, &cfg
) != 0)
5427 if (header
.PageLength
> 0) {
5428 /* Allocate memory and read SCSI Port Page 2
5430 pbuf
= pci_alloc_consistent(ioc
->pcidev
, header
.PageLength
* 4, &buf_dma
);
5432 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_NVRAM
;
5433 cfg
.physAddr
= buf_dma
;
5434 if (mpt_config(ioc
, &cfg
) != 0) {
5435 /* Nvram data is left with INVALID mark
5438 } else if (ioc
->pcidev
->vendor
== PCI_VENDOR_ID_ATTO
) {
5440 /* This is an ATTO adapter, read Page2 accordingly
5442 ATTO_SCSIPortPage2_t
*pPP2
= (ATTO_SCSIPortPage2_t
*) pbuf
;
5443 ATTODeviceInfo_t
*pdevice
= NULL
;
5446 /* Save the Port Page 2 data
5447 * (reformat into a 32bit quantity)
5449 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
5450 pdevice
= &pPP2
->DeviceSettings
[ii
];
5451 ATTOFlags
= le16_to_cpu(pdevice
->ATTOFlags
);
5454 /* Translate ATTO device flags to LSI format
5456 if (ATTOFlags
& ATTOFLAG_DISC
)
5457 data
|= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE
);
5458 if (ATTOFlags
& ATTOFLAG_ID_ENB
)
5459 data
|= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE
);
5460 if (ATTOFlags
& ATTOFLAG_LUN_ENB
)
5461 data
|= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE
);
5462 if (ATTOFlags
& ATTOFLAG_TAGGED
)
5463 data
|= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE
);
5464 if (!(ATTOFlags
& ATTOFLAG_WIDE_ENB
))
5465 data
|= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE
);
5467 data
= (data
<< 16) | (pdevice
->Period
<< 8) | 10;
5468 ioc
->spi_data
.nvram
[ii
] = data
;
5471 SCSIPortPage2_t
*pPP2
= (SCSIPortPage2_t
*) pbuf
;
5472 MpiDeviceInfo_t
*pdevice
= NULL
;
5475 * Save "Set to Avoid SCSI Bus Resets" flag
5477 ioc
->spi_data
.bus_reset
=
5478 (le32_to_cpu(pPP2
->PortFlags
) &
5479 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET
) ?
5482 /* Save the Port Page 2 data
5483 * (reformat into a 32bit quantity)
5485 data
= le32_to_cpu(pPP2
->PortFlags
) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK
;
5486 ioc
->spi_data
.PortFlags
= data
;
5487 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
5488 pdevice
= &pPP2
->DeviceSettings
[ii
];
5489 data
= (le16_to_cpu(pdevice
->DeviceFlags
) << 16) |
5490 (pdevice
->SyncFactor
<< 8) | pdevice
->Timeout
;
5491 ioc
->spi_data
.nvram
[ii
] = data
;
5495 pci_free_consistent(ioc
->pcidev
, header
.PageLength
* 4, pbuf
, buf_dma
);
5499 /* Update Adapter limits with those from NVRAM
5500 * Comment: Don't need to do this. Target performance
5501 * parameters will never exceed the adapters limits.
5507 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5509 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
5510 * @ioc: Pointer to a Adapter Strucutre
5511 * @portnum: IOC port number
5513 * Return: -EFAULT if read of config page header fails
5517 mpt_readScsiDevicePageHeaders(MPT_ADAPTER
*ioc
, int portnum
)
5520 ConfigPageHeader_t header
;
5522 /* Read the SCSI Device Page 1 header
5524 header
.PageVersion
= 0;
5525 header
.PageLength
= 0;
5526 header
.PageNumber
= 1;
5527 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_DEVICE
;
5528 cfg
.cfghdr
.hdr
= &header
;
5530 cfg
.pageAddr
= portnum
;
5531 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5534 if (mpt_config(ioc
, &cfg
) != 0)
5537 ioc
->spi_data
.sdp1version
= cfg
.cfghdr
.hdr
->PageVersion
;
5538 ioc
->spi_data
.sdp1length
= cfg
.cfghdr
.hdr
->PageLength
;
5540 header
.PageVersion
= 0;
5541 header
.PageLength
= 0;
5542 header
.PageNumber
= 0;
5543 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_DEVICE
;
5544 if (mpt_config(ioc
, &cfg
) != 0)
5547 ioc
->spi_data
.sdp0version
= cfg
.cfghdr
.hdr
->PageVersion
;
5548 ioc
->spi_data
.sdp0length
= cfg
.cfghdr
.hdr
->PageLength
;
5550 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Headers: 0: version %d length %d\n",
5551 ioc
->name
, ioc
->spi_data
.sdp0version
, ioc
->spi_data
.sdp0length
));
5553 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Headers: 1: version %d length %d\n",
5554 ioc
->name
, ioc
->spi_data
.sdp1version
, ioc
->spi_data
.sdp1length
));
5559 * mpt_inactive_raid_list_free - This clears this link list.
5560 * @ioc : pointer to per adapter structure
5563 mpt_inactive_raid_list_free(MPT_ADAPTER
*ioc
)
5565 struct inactive_raid_component_info
*component_info
, *pNext
;
5567 if (list_empty(&ioc
->raid_data
.inactive_list
))
5570 mutex_lock(&ioc
->raid_data
.inactive_list_mutex
);
5571 list_for_each_entry_safe(component_info
, pNext
,
5572 &ioc
->raid_data
.inactive_list
, list
) {
5573 list_del(&component_info
->list
);
5574 kfree(component_info
);
5576 mutex_unlock(&ioc
->raid_data
.inactive_list_mutex
);
5580 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5582 * @ioc : pointer to per adapter structure
5583 * @channel : volume channel
5584 * @id : volume target id
5587 mpt_inactive_raid_volumes(MPT_ADAPTER
*ioc
, u8 channel
, u8 id
)
5590 ConfigPageHeader_t hdr
;
5591 dma_addr_t dma_handle
;
5592 pRaidVolumePage0_t buffer
= NULL
;
5594 RaidPhysDiskPage0_t phys_disk
;
5595 struct inactive_raid_component_info
*component_info
;
5596 int handle_inactive_volumes
;
5598 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5599 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5600 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_VOLUME
;
5601 cfg
.pageAddr
= (channel
<< 8) + id
;
5602 cfg
.cfghdr
.hdr
= &hdr
;
5603 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5605 if (mpt_config(ioc
, &cfg
) != 0)
5608 if (!hdr
.PageLength
)
5611 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5617 cfg
.physAddr
= dma_handle
;
5618 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5620 if (mpt_config(ioc
, &cfg
) != 0)
5623 if (!buffer
->NumPhysDisks
)
5626 handle_inactive_volumes
=
5627 (buffer
->VolumeStatus
.Flags
& MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE
||
5628 (buffer
->VolumeStatus
.Flags
& MPI_RAIDVOL0_STATUS_FLAG_ENABLED
) == 0 ||
5629 buffer
->VolumeStatus
.State
== MPI_RAIDVOL0_STATUS_STATE_FAILED
||
5630 buffer
->VolumeStatus
.State
== MPI_RAIDVOL0_STATUS_STATE_MISSING
) ? 1 : 0;
5632 if (!handle_inactive_volumes
)
5635 mutex_lock(&ioc
->raid_data
.inactive_list_mutex
);
5636 for (i
= 0; i
< buffer
->NumPhysDisks
; i
++) {
5637 if(mpt_raid_phys_disk_pg0(ioc
,
5638 buffer
->PhysDisk
[i
].PhysDiskNum
, &phys_disk
) != 0)
5641 if ((component_info
= kmalloc(sizeof (*component_info
),
5642 GFP_KERNEL
)) == NULL
)
5645 component_info
->volumeID
= id
;
5646 component_info
->volumeBus
= channel
;
5647 component_info
->d
.PhysDiskNum
= phys_disk
.PhysDiskNum
;
5648 component_info
->d
.PhysDiskBus
= phys_disk
.PhysDiskBus
;
5649 component_info
->d
.PhysDiskID
= phys_disk
.PhysDiskID
;
5650 component_info
->d
.PhysDiskIOC
= phys_disk
.PhysDiskIOC
;
5652 list_add_tail(&component_info
->list
,
5653 &ioc
->raid_data
.inactive_list
);
5655 mutex_unlock(&ioc
->raid_data
.inactive_list_mutex
);
5659 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5664 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5665 * @ioc: Pointer to a Adapter Structure
5666 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5667 * @phys_disk: requested payload data returned
5671 * -EFAULT if read of config page header fails or data pointer not NULL
5672 * -ENOMEM if pci_alloc failed
5675 mpt_raid_phys_disk_pg0(MPT_ADAPTER
*ioc
, u8 phys_disk_num
,
5676 RaidPhysDiskPage0_t
*phys_disk
)
5679 ConfigPageHeader_t hdr
;
5680 dma_addr_t dma_handle
;
5681 pRaidPhysDiskPage0_t buffer
= NULL
;
5684 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5685 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5686 memset(phys_disk
, 0, sizeof(RaidPhysDiskPage0_t
));
5688 hdr
.PageVersion
= MPI_RAIDPHYSDISKPAGE0_PAGEVERSION
;
5689 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_PHYSDISK
;
5690 cfg
.cfghdr
.hdr
= &hdr
;
5692 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5694 if (mpt_config(ioc
, &cfg
) != 0) {
5699 if (!hdr
.PageLength
) {
5704 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5712 cfg
.physAddr
= dma_handle
;
5713 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5714 cfg
.pageAddr
= phys_disk_num
;
5716 if (mpt_config(ioc
, &cfg
) != 0) {
5722 memcpy(phys_disk
, buffer
, sizeof(*buffer
));
5723 phys_disk
->MaxLBA
= le32_to_cpu(buffer
->MaxLBA
);
5728 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5735 * mpt_raid_phys_disk_get_num_paths - returns number paths associated to this phys_num
5736 * @ioc: Pointer to a Adapter Structure
5737 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5740 * returns number paths
5743 mpt_raid_phys_disk_get_num_paths(MPT_ADAPTER
*ioc
, u8 phys_disk_num
)
5746 ConfigPageHeader_t hdr
;
5747 dma_addr_t dma_handle
;
5748 pRaidPhysDiskPage1_t buffer
= NULL
;
5751 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5752 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5754 hdr
.PageVersion
= MPI_RAIDPHYSDISKPAGE1_PAGEVERSION
;
5755 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_PHYSDISK
;
5757 cfg
.cfghdr
.hdr
= &hdr
;
5759 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5761 if (mpt_config(ioc
, &cfg
) != 0) {
5766 if (!hdr
.PageLength
) {
5771 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5779 cfg
.physAddr
= dma_handle
;
5780 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5781 cfg
.pageAddr
= phys_disk_num
;
5783 if (mpt_config(ioc
, &cfg
) != 0) {
5788 rc
= buffer
->NumPhysDiskPaths
;
5792 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5797 EXPORT_SYMBOL(mpt_raid_phys_disk_get_num_paths
);
5800 * mpt_raid_phys_disk_pg1 - returns phys disk page 1
5801 * @ioc: Pointer to a Adapter Structure
5802 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5803 * @phys_disk: requested payload data returned
5807 * -EFAULT if read of config page header fails or data pointer not NULL
5808 * -ENOMEM if pci_alloc failed
5811 mpt_raid_phys_disk_pg1(MPT_ADAPTER
*ioc
, u8 phys_disk_num
,
5812 RaidPhysDiskPage1_t
*phys_disk
)
5815 ConfigPageHeader_t hdr
;
5816 dma_addr_t dma_handle
;
5817 pRaidPhysDiskPage1_t buffer
= NULL
;
5822 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5823 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5826 hdr
.PageVersion
= MPI_RAIDPHYSDISKPAGE1_PAGEVERSION
;
5827 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_PHYSDISK
;
5829 cfg
.cfghdr
.hdr
= &hdr
;
5831 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5833 if (mpt_config(ioc
, &cfg
) != 0) {
5838 if (!hdr
.PageLength
) {
5843 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5851 cfg
.physAddr
= dma_handle
;
5852 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5853 cfg
.pageAddr
= phys_disk_num
;
5855 if (mpt_config(ioc
, &cfg
) != 0) {
5860 phys_disk
->NumPhysDiskPaths
= buffer
->NumPhysDiskPaths
;
5861 phys_disk
->PhysDiskNum
= phys_disk_num
;
5862 for (i
= 0; i
< phys_disk
->NumPhysDiskPaths
; i
++) {
5863 phys_disk
->Path
[i
].PhysDiskID
= buffer
->Path
[i
].PhysDiskID
;
5864 phys_disk
->Path
[i
].PhysDiskBus
= buffer
->Path
[i
].PhysDiskBus
;
5865 phys_disk
->Path
[i
].OwnerIdentifier
=
5866 buffer
->Path
[i
].OwnerIdentifier
;
5867 phys_disk
->Path
[i
].Flags
= le16_to_cpu(buffer
->Path
[i
].Flags
);
5868 memcpy(&sas_address
, &buffer
->Path
[i
].WWID
, sizeof(__le64
));
5869 sas_address
= le64_to_cpu(sas_address
);
5870 memcpy(&phys_disk
->Path
[i
].WWID
, &sas_address
, sizeof(__le64
));
5871 memcpy(&sas_address
,
5872 &buffer
->Path
[i
].OwnerWWID
, sizeof(__le64
));
5873 sas_address
= le64_to_cpu(sas_address
);
5874 memcpy(&phys_disk
->Path
[i
].OwnerWWID
,
5875 &sas_address
, sizeof(__le64
));
5881 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5886 EXPORT_SYMBOL(mpt_raid_phys_disk_pg1
);
5890 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5891 * @ioc: Pointer to a Adapter Strucutre
5895 * -EFAULT if read of config page header fails or data pointer not NULL
5896 * -ENOMEM if pci_alloc failed
5899 mpt_findImVolumes(MPT_ADAPTER
*ioc
)
5903 dma_addr_t ioc2_dma
;
5905 ConfigPageHeader_t header
;
5910 if (!ioc
->ir_firmware
)
5913 /* Free the old page
5915 kfree(ioc
->raid_data
.pIocPg2
);
5916 ioc
->raid_data
.pIocPg2
= NULL
;
5917 mpt_inactive_raid_list_free(ioc
);
5919 /* Read IOCP2 header then the page.
5921 header
.PageVersion
= 0;
5922 header
.PageLength
= 0;
5923 header
.PageNumber
= 2;
5924 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
5925 cfg
.cfghdr
.hdr
= &header
;
5928 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5931 if (mpt_config(ioc
, &cfg
) != 0)
5934 if (header
.PageLength
== 0)
5937 iocpage2sz
= header
.PageLength
* 4;
5938 pIoc2
= pci_alloc_consistent(ioc
->pcidev
, iocpage2sz
, &ioc2_dma
);
5942 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5943 cfg
.physAddr
= ioc2_dma
;
5944 if (mpt_config(ioc
, &cfg
) != 0)
5947 mem
= kmalloc(iocpage2sz
, GFP_KERNEL
);
5953 memcpy(mem
, (u8
*)pIoc2
, iocpage2sz
);
5954 ioc
->raid_data
.pIocPg2
= (IOCPage2_t
*) mem
;
5956 mpt_read_ioc_pg_3(ioc
);
5958 for (i
= 0; i
< pIoc2
->NumActiveVolumes
; i
++)
5959 mpt_inactive_raid_volumes(ioc
,
5960 pIoc2
->RaidVolume
[i
].VolumeBus
,
5961 pIoc2
->RaidVolume
[i
].VolumeID
);
5964 pci_free_consistent(ioc
->pcidev
, iocpage2sz
, pIoc2
, ioc2_dma
);
5970 mpt_read_ioc_pg_3(MPT_ADAPTER
*ioc
)
5975 ConfigPageHeader_t header
;
5976 dma_addr_t ioc3_dma
;
5979 /* Free the old page
5981 kfree(ioc
->raid_data
.pIocPg3
);
5982 ioc
->raid_data
.pIocPg3
= NULL
;
5984 /* There is at least one physical disk.
5985 * Read and save IOC Page 3
5987 header
.PageVersion
= 0;
5988 header
.PageLength
= 0;
5989 header
.PageNumber
= 3;
5990 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
5991 cfg
.cfghdr
.hdr
= &header
;
5994 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5997 if (mpt_config(ioc
, &cfg
) != 0)
6000 if (header
.PageLength
== 0)
6003 /* Read Header good, alloc memory
6005 iocpage3sz
= header
.PageLength
* 4;
6006 pIoc3
= pci_alloc_consistent(ioc
->pcidev
, iocpage3sz
, &ioc3_dma
);
6010 /* Read the Page and save the data
6011 * into malloc'd memory.
6013 cfg
.physAddr
= ioc3_dma
;
6014 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
6015 if (mpt_config(ioc
, &cfg
) == 0) {
6016 mem
= kmalloc(iocpage3sz
, GFP_KERNEL
);
6018 memcpy(mem
, (u8
*)pIoc3
, iocpage3sz
);
6019 ioc
->raid_data
.pIocPg3
= (IOCPage3_t
*) mem
;
6023 pci_free_consistent(ioc
->pcidev
, iocpage3sz
, pIoc3
, ioc3_dma
);
6029 mpt_read_ioc_pg_4(MPT_ADAPTER
*ioc
)
6033 ConfigPageHeader_t header
;
6034 dma_addr_t ioc4_dma
;
6037 /* Read and save IOC Page 4
6039 header
.PageVersion
= 0;
6040 header
.PageLength
= 0;
6041 header
.PageNumber
= 4;
6042 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
6043 cfg
.cfghdr
.hdr
= &header
;
6046 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
6049 if (mpt_config(ioc
, &cfg
) != 0)
6052 if (header
.PageLength
== 0)
6055 if ( (pIoc4
= ioc
->spi_data
.pIocPg4
) == NULL
) {
6056 iocpage4sz
= (header
.PageLength
+ 4) * 4; /* Allow 4 additional SEP's */
6057 pIoc4
= pci_alloc_consistent(ioc
->pcidev
, iocpage4sz
, &ioc4_dma
);
6060 ioc
->alloc_total
+= iocpage4sz
;
6062 ioc4_dma
= ioc
->spi_data
.IocPg4_dma
;
6063 iocpage4sz
= ioc
->spi_data
.IocPg4Sz
;
6066 /* Read the Page into dma memory.
6068 cfg
.physAddr
= ioc4_dma
;
6069 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
6070 if (mpt_config(ioc
, &cfg
) == 0) {
6071 ioc
->spi_data
.pIocPg4
= (IOCPage4_t
*) pIoc4
;
6072 ioc
->spi_data
.IocPg4_dma
= ioc4_dma
;
6073 ioc
->spi_data
.IocPg4Sz
= iocpage4sz
;
6075 pci_free_consistent(ioc
->pcidev
, iocpage4sz
, pIoc4
, ioc4_dma
);
6076 ioc
->spi_data
.pIocPg4
= NULL
;
6077 ioc
->alloc_total
-= iocpage4sz
;
6082 mpt_read_ioc_pg_1(MPT_ADAPTER
*ioc
)
6086 ConfigPageHeader_t header
;
6087 dma_addr_t ioc1_dma
;
6091 /* Check the Coalescing Timeout in IOC Page 1
6093 header
.PageVersion
= 0;
6094 header
.PageLength
= 0;
6095 header
.PageNumber
= 1;
6096 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
6097 cfg
.cfghdr
.hdr
= &header
;
6100 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
6103 if (mpt_config(ioc
, &cfg
) != 0)
6106 if (header
.PageLength
== 0)
6109 /* Read Header good, alloc memory
6111 iocpage1sz
= header
.PageLength
* 4;
6112 pIoc1
= pci_alloc_consistent(ioc
->pcidev
, iocpage1sz
, &ioc1_dma
);
6116 /* Read the Page and check coalescing timeout
6118 cfg
.physAddr
= ioc1_dma
;
6119 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
6120 if (mpt_config(ioc
, &cfg
) == 0) {
6122 tmp
= le32_to_cpu(pIoc1
->Flags
) & MPI_IOCPAGE1_REPLY_COALESCING
;
6123 if (tmp
== MPI_IOCPAGE1_REPLY_COALESCING
) {
6124 tmp
= le32_to_cpu(pIoc1
->CoalescingTimeout
);
6126 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Coalescing Enabled Timeout = %d\n",
6129 if (tmp
> MPT_COALESCING_TIMEOUT
) {
6130 pIoc1
->CoalescingTimeout
= cpu_to_le32(MPT_COALESCING_TIMEOUT
);
6132 /* Write NVRAM and current
6135 cfg
.action
= MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT
;
6136 if (mpt_config(ioc
, &cfg
) == 0) {
6137 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Reset Current Coalescing Timeout to = %d\n",
6138 ioc
->name
, MPT_COALESCING_TIMEOUT
));
6140 cfg
.action
= MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM
;
6141 if (mpt_config(ioc
, &cfg
) == 0) {
6142 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6143 "Reset NVRAM Coalescing Timeout to = %d\n",
6144 ioc
->name
, MPT_COALESCING_TIMEOUT
));
6146 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6147 "Reset NVRAM Coalescing Timeout Failed\n",
6152 dprintk(ioc
, printk(MYIOC_s_WARN_FMT
6153 "Reset of Current Coalescing Timeout Failed!\n",
6159 dprintk(ioc
, printk(MYIOC_s_WARN_FMT
"Coalescing Disabled\n", ioc
->name
));
6163 pci_free_consistent(ioc
->pcidev
, iocpage1sz
, pIoc1
, ioc1_dma
);
6169 mpt_get_manufacturing_pg_0(MPT_ADAPTER
*ioc
)
6172 ConfigPageHeader_t hdr
;
6174 ManufacturingPage0_t
*pbuf
= NULL
;
6176 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
6177 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
6179 hdr
.PageType
= MPI_CONFIG_PAGETYPE_MANUFACTURING
;
6180 cfg
.cfghdr
.hdr
= &hdr
;
6182 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
6185 if (mpt_config(ioc
, &cfg
) != 0)
6188 if (!cfg
.cfghdr
.hdr
->PageLength
)
6191 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
6192 pbuf
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, &buf_dma
);
6196 cfg
.physAddr
= buf_dma
;
6198 if (mpt_config(ioc
, &cfg
) != 0)
6201 memcpy(ioc
->board_name
, pbuf
->BoardName
, sizeof(ioc
->board_name
));
6202 memcpy(ioc
->board_assembly
, pbuf
->BoardAssembly
, sizeof(ioc
->board_assembly
));
6203 memcpy(ioc
->board_tracer
, pbuf
->BoardTracerNumber
, sizeof(ioc
->board_tracer
));
6208 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, pbuf
, buf_dma
);
6211 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6213 * SendEventNotification - Send EventNotification (on or off) request to adapter
6214 * @ioc: Pointer to MPT_ADAPTER structure
6215 * @EvSwitch: Event switch flags
6216 * @sleepFlag: Specifies whether the process can sleep
6219 SendEventNotification(MPT_ADAPTER
*ioc
, u8 EvSwitch
, int sleepFlag
)
6221 EventNotification_t evn
;
6222 MPIDefaultReply_t reply_buf
;
6224 memset(&evn
, 0, sizeof(EventNotification_t
));
6225 memset(&reply_buf
, 0, sizeof(MPIDefaultReply_t
));
6227 evn
.Function
= MPI_FUNCTION_EVENT_NOTIFICATION
;
6228 evn
.Switch
= EvSwitch
;
6229 evn
.MsgContext
= cpu_to_le32(mpt_base_index
<< 16);
6231 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6232 "Sending EventNotification (%d) request %p\n",
6233 ioc
->name
, EvSwitch
, &evn
));
6235 return mpt_handshake_req_reply_wait(ioc
, sizeof(EventNotification_t
),
6236 (u32
*)&evn
, sizeof(MPIDefaultReply_t
), (u16
*)&reply_buf
, 30,
6240 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6242 * SendEventAck - Send EventAck request to MPT adapter.
6243 * @ioc: Pointer to MPT_ADAPTER structure
6244 * @evnp: Pointer to original EventNotification request
6247 SendEventAck(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*evnp
)
6251 if ((pAck
= (EventAck_t
*) mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
6252 dfailprintk(ioc
, printk(MYIOC_s_WARN_FMT
"%s, no msg frames!!\n",
6253 ioc
->name
, __func__
));
6257 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending EventAck\n", ioc
->name
));
6259 pAck
->Function
= MPI_FUNCTION_EVENT_ACK
;
6260 pAck
->ChainOffset
= 0;
6261 pAck
->Reserved
[0] = pAck
->Reserved
[1] = 0;
6263 pAck
->Reserved1
[0] = pAck
->Reserved1
[1] = pAck
->Reserved1
[2] = 0;
6264 pAck
->Event
= evnp
->Event
;
6265 pAck
->EventContext
= evnp
->EventContext
;
6267 mpt_put_msg_frame(mpt_base_index
, ioc
, (MPT_FRAME_HDR
*)pAck
);
6272 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6274 * mpt_config - Generic function to issue config message
6275 * @ioc: Pointer to an adapter structure
6276 * @pCfg: Pointer to a configuration structure. Struct contains
6277 * action, page address, direction, physical address
6278 * and pointer to a configuration page header
6279 * Page header is updated.
6281 * Returns 0 for success
6282 * -EPERM if not allowed due to ISR context
6283 * -EAGAIN if no msg frames currently available
6284 * -EFAULT for non-successful reply or no reply (timeout)
6287 mpt_config(MPT_ADAPTER
*ioc
, CONFIGPARMS
*pCfg
)
6290 ConfigReply_t
*pReply
;
6291 ConfigExtendedPageHeader_t
*pExtHdr
= NULL
;
6297 u8 page_type
= 0, extend_page
;
6298 unsigned long timeleft
;
6299 unsigned long flags
;
6301 u8 issue_hard_reset
= 0;
6304 /* Prevent calling wait_event() (below), if caller happens
6305 * to be in ISR context, because that is fatal!
6307 in_isr
= in_interrupt();
6309 dcprintk(ioc
, printk(MYIOC_s_WARN_FMT
"Config request not allowed in ISR context!\n",
6314 /* don't send a config page during diag reset */
6315 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
6316 if (ioc
->ioc_reset_in_progress
) {
6317 dfailprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6318 "%s: busy with host reset\n", ioc
->name
, __func__
));
6319 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6322 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6324 /* don't send if no chance of success */
6326 mpt_GetIocState(ioc
, 1) != MPI_IOC_STATE_OPERATIONAL
) {
6327 dfailprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6328 "%s: ioc not operational, %d, %xh\n",
6329 ioc
->name
, __func__
, ioc
->active
,
6330 mpt_GetIocState(ioc
, 0)));
6335 mutex_lock(&ioc
->mptbase_cmds
.mutex
);
6336 /* init the internal cmd struct */
6337 memset(ioc
->mptbase_cmds
.reply
, 0 , MPT_DEFAULT_FRAME_SIZE
);
6338 INITIALIZE_MGMT_STATUS(ioc
->mptbase_cmds
.status
)
6340 /* Get and Populate a free Frame
6342 if ((mf
= mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
6343 dcprintk(ioc
, printk(MYIOC_s_WARN_FMT
6344 "mpt_config: no msg frames!\n", ioc
->name
));
6349 pReq
= (Config_t
*)mf
;
6350 pReq
->Action
= pCfg
->action
;
6352 pReq
->ChainOffset
= 0;
6353 pReq
->Function
= MPI_FUNCTION_CONFIG
;
6355 /* Assume page type is not extended and clear "reserved" fields. */
6356 pReq
->ExtPageLength
= 0;
6357 pReq
->ExtPageType
= 0;
6360 for (ii
=0; ii
< 8; ii
++)
6361 pReq
->Reserved2
[ii
] = 0;
6363 pReq
->Header
.PageVersion
= pCfg
->cfghdr
.hdr
->PageVersion
;
6364 pReq
->Header
.PageLength
= pCfg
->cfghdr
.hdr
->PageLength
;
6365 pReq
->Header
.PageNumber
= pCfg
->cfghdr
.hdr
->PageNumber
;
6366 pReq
->Header
.PageType
= (pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
);
6368 if ((pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
) == MPI_CONFIG_PAGETYPE_EXTENDED
) {
6369 pExtHdr
= (ConfigExtendedPageHeader_t
*)pCfg
->cfghdr
.ehdr
;
6370 pReq
->ExtPageLength
= cpu_to_le16(pExtHdr
->ExtPageLength
);
6371 pReq
->ExtPageType
= pExtHdr
->ExtPageType
;
6372 pReq
->Header
.PageType
= MPI_CONFIG_PAGETYPE_EXTENDED
;
6374 /* Page Length must be treated as a reserved field for the
6377 pReq
->Header
.PageLength
= 0;
6380 pReq
->PageAddress
= cpu_to_le32(pCfg
->pageAddr
);
6382 /* Add a SGE to the config request.
6385 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_WRITE
;
6387 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_READ
;
6389 if ((pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
) ==
6390 MPI_CONFIG_PAGETYPE_EXTENDED
) {
6391 flagsLength
|= pExtHdr
->ExtPageLength
* 4;
6392 page_type
= pReq
->ExtPageType
;
6395 flagsLength
|= pCfg
->cfghdr
.hdr
->PageLength
* 4;
6396 page_type
= pReq
->Header
.PageType
;
6400 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6401 "Sending Config request type 0x%x, page 0x%x and action %d\n",
6402 ioc
->name
, page_type
, pReq
->Header
.PageNumber
, pReq
->Action
));
6404 ioc
->add_sge((char *)&pReq
->PageBufferSGE
, flagsLength
, pCfg
->physAddr
);
6405 timeout
= (pCfg
->timeout
< 15) ? HZ
*15 : HZ
*pCfg
->timeout
;
6406 mpt_put_msg_frame(mpt_base_index
, ioc
, mf
);
6407 timeleft
= wait_for_completion_timeout(&ioc
->mptbase_cmds
.done
,
6409 if (!(ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_COMMAND_GOOD
)) {
6411 dfailprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6412 "Failed Sending Config request type 0x%x, page 0x%x,"
6413 " action %d, status %xh, time left %ld\n\n",
6414 ioc
->name
, page_type
, pReq
->Header
.PageNumber
,
6415 pReq
->Action
, ioc
->mptbase_cmds
.status
, timeleft
));
6416 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_DID_IOCRESET
)
6419 issue_hard_reset
= 1;
6423 if (!(ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_RF_VALID
)) {
6427 pReply
= (ConfigReply_t
*)ioc
->mptbase_cmds
.reply
;
6428 ret
= le16_to_cpu(pReply
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
6429 if (ret
== MPI_IOCSTATUS_SUCCESS
) {
6431 pCfg
->cfghdr
.ehdr
->ExtPageLength
=
6432 le16_to_cpu(pReply
->ExtPageLength
);
6433 pCfg
->cfghdr
.ehdr
->ExtPageType
=
6434 pReply
->ExtPageType
;
6436 pCfg
->cfghdr
.hdr
->PageVersion
= pReply
->Header
.PageVersion
;
6437 pCfg
->cfghdr
.hdr
->PageLength
= pReply
->Header
.PageLength
;
6438 pCfg
->cfghdr
.hdr
->PageNumber
= pReply
->Header
.PageNumber
;
6439 pCfg
->cfghdr
.hdr
->PageType
= pReply
->Header
.PageType
;
6444 printk(MYIOC_s_INFO_FMT
"Retry completed "
6445 "ret=0x%x timeleft=%ld\n",
6446 ioc
->name
, ret
, timeleft
);
6448 dcprintk(ioc
, printk(KERN_DEBUG
"IOCStatus=%04xh, IOCLogInfo=%08xh\n",
6449 ret
, le32_to_cpu(pReply
->IOCLogInfo
)));
6453 CLEAR_MGMT_STATUS(ioc
->mptbase_cmds
.status
)
6454 mutex_unlock(&ioc
->mptbase_cmds
.mutex
);
6455 if (issue_hard_reset
) {
6456 issue_hard_reset
= 0;
6457 printk(MYIOC_s_WARN_FMT
6458 "Issuing Reset from %s!!, doorbell=0x%08x\n",
6459 ioc
->name
, __func__
, mpt_GetIocState(ioc
, 0));
6460 if (retry_count
== 0) {
6461 if (mpt_Soft_Hard_ResetHandler(ioc
, CAN_SLEEP
) != 0)
6464 mpt_HardResetHandler(ioc
, CAN_SLEEP
);
6466 mpt_free_msg_frame(ioc
, mf
);
6467 /* attempt one retry for a timed out command */
6468 if (retry_count
< 2) {
6469 printk(MYIOC_s_INFO_FMT
6470 "Attempting Retry Config request"
6471 " type 0x%x, page 0x%x,"
6472 " action %d\n", ioc
->name
, page_type
,
6473 pCfg
->cfghdr
.hdr
->PageNumber
, pCfg
->action
);
6482 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6484 * mpt_ioc_reset - Base cleanup for hard reset
6485 * @ioc: Pointer to the adapter structure
6486 * @reset_phase: Indicates pre- or post-reset functionality
6488 * Remark: Frees resources with internally generated commands.
6491 mpt_ioc_reset(MPT_ADAPTER
*ioc
, int reset_phase
)
6493 switch (reset_phase
) {
6494 case MPT_IOC_SETUP_RESET
:
6495 ioc
->taskmgmt_quiesce_io
= 1;
6496 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6497 "%s: MPT_IOC_SETUP_RESET\n", ioc
->name
, __func__
));
6499 case MPT_IOC_PRE_RESET
:
6500 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6501 "%s: MPT_IOC_PRE_RESET\n", ioc
->name
, __func__
));
6503 case MPT_IOC_POST_RESET
:
6504 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6505 "%s: MPT_IOC_POST_RESET\n", ioc
->name
, __func__
));
6506 /* wake up mptbase_cmds */
6507 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_PENDING
) {
6508 ioc
->mptbase_cmds
.status
|=
6509 MPT_MGMT_STATUS_DID_IOCRESET
;
6510 complete(&ioc
->mptbase_cmds
.done
);
6512 /* wake up taskmgmt_cmds */
6513 if (ioc
->taskmgmt_cmds
.status
& MPT_MGMT_STATUS_PENDING
) {
6514 ioc
->taskmgmt_cmds
.status
|=
6515 MPT_MGMT_STATUS_DID_IOCRESET
;
6516 complete(&ioc
->taskmgmt_cmds
.done
);
6523 return 1; /* currently means nothing really */
6527 #ifdef CONFIG_PROC_FS /* { */
6528 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6530 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
6532 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6534 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
6536 * Returns 0 for success, non-zero for failure.
6539 procmpt_create(void)
6541 mpt_proc_root_dir
= proc_mkdir(MPT_PROCFS_MPTBASEDIR
, NULL
);
6542 if (mpt_proc_root_dir
== NULL
)
6545 proc_create("summary", S_IRUGO
, mpt_proc_root_dir
, &mpt_summary_proc_fops
);
6546 proc_create("version", S_IRUGO
, mpt_proc_root_dir
, &mpt_version_proc_fops
);
6550 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6552 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
6554 * Returns 0 for success, non-zero for failure.
6557 procmpt_destroy(void)
6559 remove_proc_entry("version", mpt_proc_root_dir
);
6560 remove_proc_entry("summary", mpt_proc_root_dir
);
6561 remove_proc_entry(MPT_PROCFS_MPTBASEDIR
, NULL
);
6564 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6566 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
6568 static void seq_mpt_print_ioc_summary(MPT_ADAPTER
*ioc
, struct seq_file
*m
, int showlan
);
6570 static int mpt_summary_proc_show(struct seq_file
*m
, void *v
)
6572 MPT_ADAPTER
*ioc
= m
->private;
6575 seq_mpt_print_ioc_summary(ioc
, m
, 1);
6577 list_for_each_entry(ioc
, &ioc_list
, list
) {
6578 seq_mpt_print_ioc_summary(ioc
, m
, 1);
6585 static int mpt_summary_proc_open(struct inode
*inode
, struct file
*file
)
6587 return single_open(file
, mpt_summary_proc_show
, PDE(inode
)->data
);
6590 static const struct file_operations mpt_summary_proc_fops
= {
6591 .owner
= THIS_MODULE
,
6592 .open
= mpt_summary_proc_open
,
6594 .llseek
= seq_lseek
,
6595 .release
= single_release
,
6598 static int mpt_version_proc_show(struct seq_file
*m
, void *v
)
6601 int scsi
, fc
, sas
, lan
, ctl
, targ
, dmp
;
6604 seq_printf(m
, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON
);
6605 seq_printf(m
, " Fusion MPT base driver\n");
6607 scsi
= fc
= sas
= lan
= ctl
= targ
= dmp
= 0;
6608 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
6610 if (MptCallbacks
[cb_idx
]) {
6611 switch (MptDriverClass
[cb_idx
]) {
6613 if (!scsi
++) drvname
= "SPI host";
6616 if (!fc
++) drvname
= "FC host";
6619 if (!sas
++) drvname
= "SAS host";
6622 if (!lan
++) drvname
= "LAN";
6625 if (!targ
++) drvname
= "SCSI target";
6628 if (!ctl
++) drvname
= "ioctl";
6633 seq_printf(m
, " Fusion MPT %s driver\n", drvname
);
6640 static int mpt_version_proc_open(struct inode
*inode
, struct file
*file
)
6642 return single_open(file
, mpt_version_proc_show
, NULL
);
6645 static const struct file_operations mpt_version_proc_fops
= {
6646 .owner
= THIS_MODULE
,
6647 .open
= mpt_version_proc_open
,
6649 .llseek
= seq_lseek
,
6650 .release
= single_release
,
6653 static int mpt_iocinfo_proc_show(struct seq_file
*m
, void *v
)
6655 MPT_ADAPTER
*ioc
= m
->private;
6660 mpt_get_fw_exp_ver(expVer
, ioc
);
6662 seq_printf(m
, "%s:", ioc
->name
);
6663 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)
6664 seq_printf(m
, " (f/w download boot flag set)");
6665 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6666 // seq_printf(m, " CONFIG_CHECKSUM_FAIL!");
6668 seq_printf(m
, "\n ProductID = 0x%04x (%s)\n",
6669 ioc
->facts
.ProductID
,
6671 seq_printf(m
, " FWVersion = 0x%08x%s", ioc
->facts
.FWVersion
.Word
, expVer
);
6672 if (ioc
->facts
.FWImageSize
)
6673 seq_printf(m
, " (fw_size=%d)", ioc
->facts
.FWImageSize
);
6674 seq_printf(m
, "\n MsgVersion = 0x%04x\n", ioc
->facts
.MsgVersion
);
6675 seq_printf(m
, " FirstWhoInit = 0x%02x\n", ioc
->FirstWhoInit
);
6676 seq_printf(m
, " EventState = 0x%02x\n", ioc
->facts
.EventState
);
6678 seq_printf(m
, " CurrentHostMfaHighAddr = 0x%08x\n",
6679 ioc
->facts
.CurrentHostMfaHighAddr
);
6680 seq_printf(m
, " CurrentSenseBufferHighAddr = 0x%08x\n",
6681 ioc
->facts
.CurrentSenseBufferHighAddr
);
6683 seq_printf(m
, " MaxChainDepth = 0x%02x frames\n", ioc
->facts
.MaxChainDepth
);
6684 seq_printf(m
, " MinBlockSize = 0x%02x bytes\n", 4*ioc
->facts
.BlockSize
);
6686 seq_printf(m
, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6687 (void *)ioc
->req_frames
, (void *)(ulong
)ioc
->req_frames_dma
);
6689 * Rounding UP to nearest 4-kB boundary here...
6691 sz
= (ioc
->req_sz
* ioc
->req_depth
) + 128;
6692 sz
= ((sz
+ 0x1000UL
- 1UL) / 0x1000) * 0x1000;
6693 seq_printf(m
, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6694 ioc
->req_sz
, ioc
->req_depth
, ioc
->req_sz
*ioc
->req_depth
, sz
);
6695 seq_printf(m
, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
6696 4*ioc
->facts
.RequestFrameSize
,
6697 ioc
->facts
.GlobalCredits
);
6699 seq_printf(m
, " Frames @ 0x%p (Dma @ 0x%p)\n",
6700 (void *)ioc
->alloc
, (void *)(ulong
)ioc
->alloc_dma
);
6701 sz
= (ioc
->reply_sz
* ioc
->reply_depth
) + 128;
6702 seq_printf(m
, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6703 ioc
->reply_sz
, ioc
->reply_depth
, ioc
->reply_sz
*ioc
->reply_depth
, sz
);
6704 seq_printf(m
, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
6705 ioc
->facts
.CurReplyFrameSize
,
6706 ioc
->facts
.ReplyQueueDepth
);
6708 seq_printf(m
, " MaxDevices = %d\n",
6709 (ioc
->facts
.MaxDevices
==0) ? 255 : ioc
->facts
.MaxDevices
);
6710 seq_printf(m
, " MaxBuses = %d\n", ioc
->facts
.MaxBuses
);
6713 for (p
=0; p
< ioc
->facts
.NumberOfPorts
; p
++) {
6714 seq_printf(m
, " PortNumber = %d (of %d)\n",
6716 ioc
->facts
.NumberOfPorts
);
6717 if (ioc
->bus_type
== FC
) {
6718 if (ioc
->pfacts
[p
].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
) {
6719 u8
*a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
6720 seq_printf(m
, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6721 a
[5], a
[4], a
[3], a
[2], a
[1], a
[0]);
6723 seq_printf(m
, " WWN = %08X%08X:%08X%08X\n",
6724 ioc
->fc_port_page0
[p
].WWNN
.High
,
6725 ioc
->fc_port_page0
[p
].WWNN
.Low
,
6726 ioc
->fc_port_page0
[p
].WWPN
.High
,
6727 ioc
->fc_port_page0
[p
].WWPN
.Low
);
6734 static int mpt_iocinfo_proc_open(struct inode
*inode
, struct file
*file
)
6736 return single_open(file
, mpt_iocinfo_proc_show
, PDE(inode
)->data
);
6739 static const struct file_operations mpt_iocinfo_proc_fops
= {
6740 .owner
= THIS_MODULE
,
6741 .open
= mpt_iocinfo_proc_open
,
6743 .llseek
= seq_lseek
,
6744 .release
= single_release
,
6746 #endif /* CONFIG_PROC_FS } */
6748 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6750 mpt_get_fw_exp_ver(char *buf
, MPT_ADAPTER
*ioc
)
6753 if ((ioc
->facts
.FWVersion
.Word
>> 24) == 0x0E) {
6754 sprintf(buf
, " (Exp %02d%02d)",
6755 (ioc
->facts
.FWVersion
.Word
>> 16) & 0x00FF, /* Month */
6756 (ioc
->facts
.FWVersion
.Word
>> 8) & 0x1F); /* Day */
6759 if ((ioc
->facts
.FWVersion
.Word
>> 8) & 0x80)
6760 strcat(buf
, " [MDBG]");
6764 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6766 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6767 * @ioc: Pointer to MPT_ADAPTER structure
6768 * @buffer: Pointer to buffer where IOC summary info should be written
6769 * @size: Pointer to number of bytes we wrote (set by this routine)
6770 * @len: Offset at which to start writing in buffer
6771 * @showlan: Display LAN stuff?
6773 * This routine writes (english readable) ASCII text, which represents
6774 * a summary of IOC information, to a buffer.
6777 mpt_print_ioc_summary(MPT_ADAPTER
*ioc
, char *buffer
, int *size
, int len
, int showlan
)
6782 mpt_get_fw_exp_ver(expVer
, ioc
);
6785 * Shorter summary of attached ioc's...
6787 y
= sprintf(buffer
+len
, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6790 MPT_FW_REV_MAGIC_ID_STRING
, /* "FwRev=" or somesuch */
6791 ioc
->facts
.FWVersion
.Word
,
6793 ioc
->facts
.NumberOfPorts
,
6796 if (showlan
&& (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
)) {
6797 u8
*a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
6798 y
+= sprintf(buffer
+len
+y
, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6799 a
[5], a
[4], a
[3], a
[2], a
[1], a
[0]);
6802 y
+= sprintf(buffer
+len
+y
, ", IRQ=%d", ioc
->pci_irq
);
6805 y
+= sprintf(buffer
+len
+y
, " (disabled)");
6807 y
+= sprintf(buffer
+len
+y
, "\n");
6812 static void seq_mpt_print_ioc_summary(MPT_ADAPTER
*ioc
, struct seq_file
*m
, int showlan
)
6816 mpt_get_fw_exp_ver(expVer
, ioc
);
6819 * Shorter summary of attached ioc's...
6821 seq_printf(m
, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6824 MPT_FW_REV_MAGIC_ID_STRING
, /* "FwRev=" or somesuch */
6825 ioc
->facts
.FWVersion
.Word
,
6827 ioc
->facts
.NumberOfPorts
,
6830 if (showlan
&& (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
)) {
6831 u8
*a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
6832 seq_printf(m
, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6833 a
[5], a
[4], a
[3], a
[2], a
[1], a
[0]);
6836 seq_printf(m
, ", IRQ=%d", ioc
->pci_irq
);
6839 seq_printf(m
, " (disabled)");
6845 * mpt_set_taskmgmt_in_progress_flag - set flags associated with task management
6846 * @ioc: Pointer to MPT_ADAPTER structure
6848 * Returns 0 for SUCCESS or -1 if FAILED.
6850 * If -1 is return, then it was not possible to set the flags
6853 mpt_set_taskmgmt_in_progress_flag(MPT_ADAPTER
*ioc
)
6855 unsigned long flags
;
6858 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
6859 if (ioc
->ioc_reset_in_progress
|| ioc
->taskmgmt_in_progress
||
6860 (ioc
->alt_ioc
&& ioc
->alt_ioc
->taskmgmt_in_progress
)) {
6865 ioc
->taskmgmt_in_progress
= 1;
6866 ioc
->taskmgmt_quiesce_io
= 1;
6868 ioc
->alt_ioc
->taskmgmt_in_progress
= 1;
6869 ioc
->alt_ioc
->taskmgmt_quiesce_io
= 1;
6872 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6875 EXPORT_SYMBOL(mpt_set_taskmgmt_in_progress_flag
);
6878 * mpt_clear_taskmgmt_in_progress_flag - clear flags associated with task management
6879 * @ioc: Pointer to MPT_ADAPTER structure
6883 mpt_clear_taskmgmt_in_progress_flag(MPT_ADAPTER
*ioc
)
6885 unsigned long flags
;
6887 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
6888 ioc
->taskmgmt_in_progress
= 0;
6889 ioc
->taskmgmt_quiesce_io
= 0;
6891 ioc
->alt_ioc
->taskmgmt_in_progress
= 0;
6892 ioc
->alt_ioc
->taskmgmt_quiesce_io
= 0;
6894 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6896 EXPORT_SYMBOL(mpt_clear_taskmgmt_in_progress_flag
);
6900 * mpt_halt_firmware - Halts the firmware if it is operational and panic
6902 * @ioc: Pointer to MPT_ADAPTER structure
6906 mpt_halt_firmware(MPT_ADAPTER
*ioc
)
6910 ioc_raw_state
= mpt_GetIocState(ioc
, 0);
6912 if ((ioc_raw_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_FAULT
) {
6913 printk(MYIOC_s_ERR_FMT
"IOC is in FAULT state (%04xh)!!!\n",
6914 ioc
->name
, ioc_raw_state
& MPI_DOORBELL_DATA_MASK
);
6915 panic("%s: IOC Fault (%04xh)!!!\n", ioc
->name
,
6916 ioc_raw_state
& MPI_DOORBELL_DATA_MASK
);
6918 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, 0xC0FFEE00);
6919 panic("%s: Firmware is halted due to command timeout\n",
6923 EXPORT_SYMBOL(mpt_halt_firmware
);
6926 * mpt_SoftResetHandler - Issues a less expensive reset
6927 * @ioc: Pointer to MPT_ADAPTER structure
6928 * @sleepFlag: Indicates if sleep or schedule must be called.
6930 * Returns 0 for SUCCESS or -1 if FAILED.
6932 * Message Unit Reset - instructs the IOC to reset the Reply Post and
6933 * Free FIFO's. All the Message Frames on Reply Free FIFO are discarded.
6934 * All posted buffers are freed, and event notification is turned off.
6935 * IOC doesnt reply to any outstanding request. This will transfer IOC
6939 mpt_SoftResetHandler(MPT_ADAPTER
*ioc
, int sleepFlag
)
6944 unsigned long flags
;
6946 unsigned long time_count
;
6948 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SoftResetHandler Entered!\n",
6951 ioc_state
= mpt_GetIocState(ioc
, 0) & MPI_IOC_STATE_MASK
;
6953 if (mpt_fwfault_debug
)
6954 mpt_halt_firmware(ioc
);
6956 if (ioc_state
== MPI_IOC_STATE_FAULT
||
6957 ioc_state
== MPI_IOC_STATE_RESET
) {
6958 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6959 "skipping, either in FAULT or RESET state!\n", ioc
->name
));
6963 if (ioc
->bus_type
== FC
) {
6964 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6965 "skipping, because the bus type is FC!\n", ioc
->name
));
6969 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
6970 if (ioc
->ioc_reset_in_progress
) {
6971 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6974 ioc
->ioc_reset_in_progress
= 1;
6975 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6979 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
6980 if (MptResetHandlers
[cb_idx
])
6981 mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_SETUP_RESET
);
6984 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
6985 if (ioc
->taskmgmt_in_progress
) {
6986 ioc
->ioc_reset_in_progress
= 0;
6987 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6990 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6991 /* Disable reply interrupts (also blocks FreeQ) */
6992 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
6994 time_count
= jiffies
;
6996 rc
= SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
);
6998 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
6999 if (MptResetHandlers
[cb_idx
])
7000 mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_PRE_RESET
);
7006 ioc_state
= mpt_GetIocState(ioc
, 0) & MPI_IOC_STATE_MASK
;
7007 if (ioc_state
!= MPI_IOC_STATE_READY
)
7010 for (ii
= 0; ii
< 5; ii
++) {
7011 /* Get IOC facts! Allow 5 retries */
7012 rc
= GetIocFacts(ioc
, sleepFlag
,
7013 MPT_HOSTEVENT_IOC_RECOVER
);
7016 if (sleepFlag
== CAN_SLEEP
)
7024 rc
= PrimeIocFifos(ioc
);
7028 rc
= SendIocInit(ioc
, sleepFlag
);
7032 rc
= SendEventNotification(ioc
, 1, sleepFlag
);
7036 if (ioc
->hard_resets
< -1)
7040 * At this point, we know soft reset succeeded.
7044 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, MPI_HIM_DIM
);
7047 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
7048 ioc
->ioc_reset_in_progress
= 0;
7049 ioc
->taskmgmt_quiesce_io
= 0;
7050 ioc
->taskmgmt_in_progress
= 0;
7051 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
7053 if (ioc
->active
) { /* otherwise, hard reset coming */
7054 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
7055 if (MptResetHandlers
[cb_idx
])
7056 mpt_signal_reset(cb_idx
, ioc
,
7057 MPT_IOC_POST_RESET
);
7061 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
7062 "SoftResetHandler: completed (%d seconds): %s\n",
7063 ioc
->name
, jiffies_to_msecs(jiffies
- time_count
)/1000,
7064 ((rc
== 0) ? "SUCCESS" : "FAILED")));
7070 * mpt_Soft_Hard_ResetHandler - Try less expensive reset
7071 * @ioc: Pointer to MPT_ADAPTER structure
7072 * @sleepFlag: Indicates if sleep or schedule must be called.
7074 * Returns 0 for SUCCESS or -1 if FAILED.
7075 * Try for softreset first, only if it fails go for expensive
7079 mpt_Soft_Hard_ResetHandler(MPT_ADAPTER
*ioc
, int sleepFlag
) {
7082 ret
= mpt_SoftResetHandler(ioc
, sleepFlag
);
7085 ret
= mpt_HardResetHandler(ioc
, sleepFlag
);
7088 EXPORT_SYMBOL(mpt_Soft_Hard_ResetHandler
);
7090 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7094 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7096 * mpt_HardResetHandler - Generic reset handler
7097 * @ioc: Pointer to MPT_ADAPTER structure
7098 * @sleepFlag: Indicates if sleep or schedule must be called.
7100 * Issues SCSI Task Management call based on input arg values.
7101 * If TaskMgmt fails, returns associated SCSI request.
7103 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
7104 * or a non-interrupt thread. In the former, must not call schedule().
7106 * Note: A return of -1 is a FATAL error case, as it means a
7107 * FW reload/initialization failed.
7109 * Returns 0 for SUCCESS or -1 if FAILED.
7112 mpt_HardResetHandler(MPT_ADAPTER
*ioc
, int sleepFlag
)
7116 unsigned long flags
;
7117 unsigned long time_count
;
7119 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HardResetHandler Entered!\n", ioc
->name
));
7121 printk(MYIOC_s_INFO_FMT
"HardResetHandler Entered!\n", ioc
->name
);
7122 printk("MF count 0x%x !\n", ioc
->mfcnt
);
7124 if (mpt_fwfault_debug
)
7125 mpt_halt_firmware(ioc
);
7127 /* Reset the adapter. Prevent more than 1 call to
7128 * mpt_do_ioc_recovery at any instant in time.
7130 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
7131 if (ioc
->ioc_reset_in_progress
) {
7132 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
7135 ioc
->ioc_reset_in_progress
= 1;
7137 ioc
->alt_ioc
->ioc_reset_in_progress
= 1;
7138 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
7141 /* The SCSI driver needs to adjust timeouts on all current
7142 * commands prior to the diagnostic reset being issued.
7143 * Prevents timeouts occurring during a diagnostic reset...very bad.
7144 * For all other protocol drivers, this is a no-op.
7146 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
7147 if (MptResetHandlers
[cb_idx
]) {
7148 mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_SETUP_RESET
);
7150 mpt_signal_reset(cb_idx
, ioc
->alt_ioc
,
7151 MPT_IOC_SETUP_RESET
);
7155 time_count
= jiffies
;
7156 rc
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_RECOVER
, sleepFlag
);
7158 printk(KERN_WARNING MYNAM
7159 ": WARNING - (%d) Cannot recover %s, doorbell=0x%08x\n",
7160 rc
, ioc
->name
, mpt_GetIocState(ioc
, 0));
7162 if (ioc
->hard_resets
< -1)
7166 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
7167 ioc
->ioc_reset_in_progress
= 0;
7168 ioc
->taskmgmt_quiesce_io
= 0;
7169 ioc
->taskmgmt_in_progress
= 0;
7171 ioc
->alt_ioc
->ioc_reset_in_progress
= 0;
7172 ioc
->alt_ioc
->taskmgmt_quiesce_io
= 0;
7173 ioc
->alt_ioc
->taskmgmt_in_progress
= 0;
7175 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
7177 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
7178 if (MptResetHandlers
[cb_idx
]) {
7179 mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_POST_RESET
);
7181 mpt_signal_reset(cb_idx
,
7182 ioc
->alt_ioc
, MPT_IOC_POST_RESET
);
7187 printk(MYIOC_s_DEBUG_FMT
7188 "HardResetHandler: completed (%d seconds): %s\n", ioc
->name
,
7189 jiffies_to_msecs(jiffies
- time_count
)/1000, ((rc
== 0) ?
7190 "SUCCESS" : "FAILED")));
7195 #ifdef CONFIG_FUSION_LOGGING
7197 mpt_display_event_info(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*pEventReply
)
7203 char *evStr
= ioc
->evStr
;
7205 event
= le32_to_cpu(pEventReply
->Event
) & 0xFF;
7206 evData0
= le32_to_cpu(pEventReply
->Data
[0]);
7209 case MPI_EVENT_NONE
:
7212 case MPI_EVENT_LOG_DATA
:
7215 case MPI_EVENT_STATE_CHANGE
:
7216 ds
= "State Change";
7218 case MPI_EVENT_UNIT_ATTENTION
:
7219 ds
= "Unit Attention";
7221 case MPI_EVENT_IOC_BUS_RESET
:
7222 ds
= "IOC Bus Reset";
7224 case MPI_EVENT_EXT_BUS_RESET
:
7225 ds
= "External Bus Reset";
7227 case MPI_EVENT_RESCAN
:
7228 ds
= "Bus Rescan Event";
7230 case MPI_EVENT_LINK_STATUS_CHANGE
:
7231 if (evData0
== MPI_EVENT_LINK_STATUS_FAILURE
)
7232 ds
= "Link Status(FAILURE) Change";
7234 ds
= "Link Status(ACTIVE) Change";
7236 case MPI_EVENT_LOOP_STATE_CHANGE
:
7237 if (evData0
== MPI_EVENT_LOOP_STATE_CHANGE_LIP
)
7238 ds
= "Loop State(LIP) Change";
7239 else if (evData0
== MPI_EVENT_LOOP_STATE_CHANGE_LPE
)
7240 ds
= "Loop State(LPE) Change";
7242 ds
= "Loop State(LPB) Change";
7244 case MPI_EVENT_LOGOUT
:
7247 case MPI_EVENT_EVENT_CHANGE
:
7253 case MPI_EVENT_INTEGRATED_RAID
:
7255 u8 ReasonCode
= (u8
)(evData0
>> 16);
7256 switch (ReasonCode
) {
7257 case MPI_EVENT_RAID_RC_VOLUME_CREATED
:
7258 ds
= "Integrated Raid: Volume Created";
7260 case MPI_EVENT_RAID_RC_VOLUME_DELETED
:
7261 ds
= "Integrated Raid: Volume Deleted";
7263 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED
:
7264 ds
= "Integrated Raid: Volume Settings Changed";
7266 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED
:
7267 ds
= "Integrated Raid: Volume Status Changed";
7269 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED
:
7270 ds
= "Integrated Raid: Volume Physdisk Changed";
7272 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED
:
7273 ds
= "Integrated Raid: Physdisk Created";
7275 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED
:
7276 ds
= "Integrated Raid: Physdisk Deleted";
7278 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED
:
7279 ds
= "Integrated Raid: Physdisk Settings Changed";
7281 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
:
7282 ds
= "Integrated Raid: Physdisk Status Changed";
7284 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
:
7285 ds
= "Integrated Raid: Domain Validation Needed";
7287 case MPI_EVENT_RAID_RC_SMART_DATA
:
7288 ds
= "Integrated Raid; Smart Data";
7290 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED
:
7291 ds
= "Integrated Raid: Replace Action Started";
7294 ds
= "Integrated Raid";
7299 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE
:
7300 ds
= "SCSI Device Status Change";
7302 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE
:
7304 u8 id
= (u8
)(evData0
);
7305 u8 channel
= (u8
)(evData0
>> 8);
7306 u8 ReasonCode
= (u8
)(evData0
>> 16);
7307 switch (ReasonCode
) {
7308 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED
:
7309 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7310 "SAS Device Status Change: Added: "
7311 "id=%d channel=%d", id
, channel
);
7313 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING
:
7314 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7315 "SAS Device Status Change: Deleted: "
7316 "id=%d channel=%d", id
, channel
);
7318 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA
:
7319 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7320 "SAS Device Status Change: SMART Data: "
7321 "id=%d channel=%d", id
, channel
);
7323 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED
:
7324 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7325 "SAS Device Status Change: No Persistancy: "
7326 "id=%d channel=%d", id
, channel
);
7328 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED
:
7329 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7330 "SAS Device Status Change: Unsupported Device "
7331 "Discovered : id=%d channel=%d", id
, channel
);
7333 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET
:
7334 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7335 "SAS Device Status Change: Internal Device "
7336 "Reset : id=%d channel=%d", id
, channel
);
7338 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL
:
7339 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7340 "SAS Device Status Change: Internal Task "
7341 "Abort : id=%d channel=%d", id
, channel
);
7343 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL
:
7344 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7345 "SAS Device Status Change: Internal Abort "
7346 "Task Set : id=%d channel=%d", id
, channel
);
7348 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL
:
7349 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7350 "SAS Device Status Change: Internal Clear "
7351 "Task Set : id=%d channel=%d", id
, channel
);
7353 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL
:
7354 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7355 "SAS Device Status Change: Internal Query "
7356 "Task : id=%d channel=%d", id
, channel
);
7359 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7360 "SAS Device Status Change: Unknown: "
7361 "id=%d channel=%d", id
, channel
);
7366 case MPI_EVENT_ON_BUS_TIMER_EXPIRED
:
7367 ds
= "Bus Timer Expired";
7369 case MPI_EVENT_QUEUE_FULL
:
7371 u16 curr_depth
= (u16
)(evData0
>> 16);
7372 u8 channel
= (u8
)(evData0
>> 8);
7373 u8 id
= (u8
)(evData0
);
7375 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7376 "Queue Full: channel=%d id=%d depth=%d",
7377 channel
, id
, curr_depth
);
7380 case MPI_EVENT_SAS_SES
:
7381 ds
= "SAS SES Event";
7383 case MPI_EVENT_PERSISTENT_TABLE_FULL
:
7384 ds
= "Persistent Table Full";
7386 case MPI_EVENT_SAS_PHY_LINK_STATUS
:
7388 u8 LinkRates
= (u8
)(evData0
>> 8);
7389 u8 PhyNumber
= (u8
)(evData0
);
7390 LinkRates
= (LinkRates
& MPI_EVENT_SAS_PLS_LR_CURRENT_MASK
) >>
7391 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT
;
7392 switch (LinkRates
) {
7393 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN
:
7394 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7395 "SAS PHY Link Status: Phy=%d:"
7396 " Rate Unknown",PhyNumber
);
7398 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED
:
7399 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7400 "SAS PHY Link Status: Phy=%d:"
7401 " Phy Disabled",PhyNumber
);
7403 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION
:
7404 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7405 "SAS PHY Link Status: Phy=%d:"
7406 " Failed Speed Nego",PhyNumber
);
7408 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE
:
7409 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7410 "SAS PHY Link Status: Phy=%d:"
7411 " Sata OOB Completed",PhyNumber
);
7413 case MPI_EVENT_SAS_PLS_LR_RATE_1_5
:
7414 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7415 "SAS PHY Link Status: Phy=%d:"
7416 " Rate 1.5 Gbps",PhyNumber
);
7418 case MPI_EVENT_SAS_PLS_LR_RATE_3_0
:
7419 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7420 "SAS PHY Link Status: Phy=%d:"
7421 " Rate 3.0 Gpbs",PhyNumber
);
7424 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7425 "SAS PHY Link Status: Phy=%d", PhyNumber
);
7430 case MPI_EVENT_SAS_DISCOVERY_ERROR
:
7431 ds
= "SAS Discovery Error";
7433 case MPI_EVENT_IR_RESYNC_UPDATE
:
7435 u8 resync_complete
= (u8
)(evData0
>> 16);
7436 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7437 "IR Resync Update: Complete = %d:",resync_complete
);
7442 u8 id
= (u8
)(evData0
);
7443 u8 channel
= (u8
)(evData0
>> 8);
7444 u8 phys_num
= (u8
)(evData0
>> 24);
7445 u8 ReasonCode
= (u8
)(evData0
>> 16);
7447 switch (ReasonCode
) {
7448 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED
:
7449 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7450 "IR2: LD State Changed: "
7451 "id=%d channel=%d phys_num=%d",
7452 id
, channel
, phys_num
);
7454 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED
:
7455 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7456 "IR2: PD State Changed "
7457 "id=%d channel=%d phys_num=%d",
7458 id
, channel
, phys_num
);
7460 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL
:
7461 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7462 "IR2: Bad Block Table Full: "
7463 "id=%d channel=%d phys_num=%d",
7464 id
, channel
, phys_num
);
7466 case MPI_EVENT_IR2_RC_PD_INSERTED
:
7467 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7468 "IR2: PD Inserted: "
7469 "id=%d channel=%d phys_num=%d",
7470 id
, channel
, phys_num
);
7472 case MPI_EVENT_IR2_RC_PD_REMOVED
:
7473 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7475 "id=%d channel=%d phys_num=%d",
7476 id
, channel
, phys_num
);
7478 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED
:
7479 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7480 "IR2: Foreign CFG Detected: "
7481 "id=%d channel=%d phys_num=%d",
7482 id
, channel
, phys_num
);
7484 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR
:
7485 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7486 "IR2: Rebuild Medium Error: "
7487 "id=%d channel=%d phys_num=%d",
7488 id
, channel
, phys_num
);
7490 case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED
:
7491 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7492 "IR2: Dual Port Added: "
7493 "id=%d channel=%d phys_num=%d",
7494 id
, channel
, phys_num
);
7496 case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED
:
7497 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7498 "IR2: Dual Port Removed: "
7499 "id=%d channel=%d phys_num=%d",
7500 id
, channel
, phys_num
);
7508 case MPI_EVENT_SAS_DISCOVERY
:
7511 ds
= "SAS Discovery: Start";
7513 ds
= "SAS Discovery: Stop";
7516 case MPI_EVENT_LOG_ENTRY_ADDED
:
7517 ds
= "SAS Log Entry Added";
7520 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE
:
7522 u8 phy_num
= (u8
)(evData0
);
7523 u8 port_num
= (u8
)(evData0
>> 8);
7524 u8 port_width
= (u8
)(evData0
>> 16);
7525 u8 primative
= (u8
)(evData0
>> 24);
7526 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7527 "SAS Broadcase Primative: phy=%d port=%d "
7528 "width=%d primative=0x%02x",
7529 phy_num
, port_num
, port_width
, primative
);
7533 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE
:
7535 u8 reason
= (u8
)(evData0
);
7538 case MPI_EVENT_SAS_INIT_RC_ADDED
:
7539 ds
= "SAS Initiator Status Change: Added";
7541 case MPI_EVENT_SAS_INIT_RC_REMOVED
:
7542 ds
= "SAS Initiator Status Change: Deleted";
7545 ds
= "SAS Initiator Status Change";
7551 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW
:
7553 u8 max_init
= (u8
)(evData0
);
7554 u8 current_init
= (u8
)(evData0
>> 8);
7556 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7557 "SAS Initiator Device Table Overflow: max initiators=%02d "
7558 "current initators=%02d",
7559 max_init
, current_init
);
7562 case MPI_EVENT_SAS_SMP_ERROR
:
7564 u8 status
= (u8
)(evData0
);
7565 u8 port_num
= (u8
)(evData0
>> 8);
7566 u8 result
= (u8
)(evData0
>> 16);
7568 if (status
== MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID
)
7569 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7570 "SAS SMP Error: port=%d result=0x%02x",
7572 else if (status
== MPI_EVENT_SAS_SMP_CRC_ERROR
)
7573 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7574 "SAS SMP Error: port=%d : CRC Error",
7576 else if (status
== MPI_EVENT_SAS_SMP_TIMEOUT
)
7577 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7578 "SAS SMP Error: port=%d : Timeout",
7580 else if (status
== MPI_EVENT_SAS_SMP_NO_DESTINATION
)
7581 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7582 "SAS SMP Error: port=%d : No Destination",
7584 else if (status
== MPI_EVENT_SAS_SMP_BAD_DESTINATION
)
7585 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7586 "SAS SMP Error: port=%d : Bad Destination",
7589 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7590 "SAS SMP Error: port=%d : status=0x%02x",
7595 case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE
:
7597 u8 reason
= (u8
)(evData0
);
7600 case MPI_EVENT_SAS_EXP_RC_ADDED
:
7601 ds
= "Expander Status Change: Added";
7603 case MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING
:
7604 ds
= "Expander Status Change: Deleted";
7607 ds
= "Expander Status Change";
7614 * MPT base "custom" events may be added here...
7621 strncpy(evStr
, ds
, EVENT_DESCR_STR_SZ
);
7624 devtprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
7625 "MPT event:(%02Xh) : %s\n",
7626 ioc
->name
, event
, evStr
));
7628 devtverboseprintk(ioc
, printk(KERN_DEBUG MYNAM
7629 ": Event data:\n"));
7630 for (ii
= 0; ii
< le16_to_cpu(pEventReply
->EventDataLength
); ii
++)
7631 devtverboseprintk(ioc
, printk(" %08x",
7632 le32_to_cpu(pEventReply
->Data
[ii
])));
7633 devtverboseprintk(ioc
, printk(KERN_DEBUG
"\n"));
7636 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7638 * ProcessEventNotification - Route EventNotificationReply to all event handlers
7639 * @ioc: Pointer to MPT_ADAPTER structure
7640 * @pEventReply: Pointer to EventNotification reply frame
7641 * @evHandlers: Pointer to integer, number of event handlers
7643 * Routes a received EventNotificationReply to all currently registered
7645 * Returns sum of event handlers return values.
7648 ProcessEventNotification(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*pEventReply
, int *evHandlers
)
7659 * Do platform normalization of values
7661 event
= le32_to_cpu(pEventReply
->Event
) & 0xFF;
7662 evDataLen
= le16_to_cpu(pEventReply
->EventDataLength
);
7664 evData0
= le32_to_cpu(pEventReply
->Data
[0]);
7667 #ifdef CONFIG_FUSION_LOGGING
7669 mpt_display_event_info(ioc
, pEventReply
);
7673 * Do general / base driver event processing
7676 case MPI_EVENT_EVENT_CHANGE
: /* 0A */
7678 u8 evState
= evData0
& 0xFF;
7680 /* CHECKME! What if evState unexpectedly says OFF (0)? */
7682 /* Update EventState field in cached IocFacts */
7683 if (ioc
->facts
.Function
) {
7684 ioc
->facts
.EventState
= evState
;
7688 case MPI_EVENT_INTEGRATED_RAID
:
7689 mptbase_raid_process_event_data(ioc
,
7690 (MpiEventDataRaid_t
*)pEventReply
->Data
);
7697 * Should this event be logged? Events are written sequentially.
7698 * When buffer is full, start again at the top.
7700 if (ioc
->events
&& (ioc
->eventTypes
& ( 1 << event
))) {
7703 idx
= ioc
->eventContext
% MPTCTL_EVENT_LOG_SIZE
;
7705 ioc
->events
[idx
].event
= event
;
7706 ioc
->events
[idx
].eventContext
= ioc
->eventContext
;
7708 for (ii
= 0; ii
< 2; ii
++) {
7710 ioc
->events
[idx
].data
[ii
] = le32_to_cpu(pEventReply
->Data
[ii
]);
7712 ioc
->events
[idx
].data
[ii
] = 0;
7715 ioc
->eventContext
++;
7720 * Call each currently registered protocol event handler.
7722 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
7723 if (MptEvHandlers
[cb_idx
]) {
7724 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
7725 "Routing Event to event handler #%d\n",
7726 ioc
->name
, cb_idx
));
7727 r
+= (*(MptEvHandlers
[cb_idx
]))(ioc
, pEventReply
);
7731 /* FIXME? Examine results here? */
7734 * If needed, send (a single) EventAck.
7736 if (pEventReply
->AckRequired
== MPI_EVENT_NOTIFICATION_ACK_REQUIRED
) {
7737 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
7738 "EventAck required\n",ioc
->name
));
7739 if ((ii
= SendEventAck(ioc
, pEventReply
)) != 0) {
7740 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SendEventAck returned %d\n",
7745 *evHandlers
= handlers
;
7749 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7751 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
7752 * @ioc: Pointer to MPT_ADAPTER structure
7753 * @log_info: U32 LogInfo reply word from the IOC
7755 * Refer to lsi/mpi_log_fc.h.
7758 mpt_fc_log_info(MPT_ADAPTER
*ioc
, u32 log_info
)
7760 char *desc
= "unknown";
7762 switch (log_info
& 0xFF000000) {
7763 case MPI_IOCLOGINFO_FC_INIT_BASE
:
7764 desc
= "FCP Initiator";
7766 case MPI_IOCLOGINFO_FC_TARGET_BASE
:
7767 desc
= "FCP Target";
7769 case MPI_IOCLOGINFO_FC_LAN_BASE
:
7772 case MPI_IOCLOGINFO_FC_MSG_BASE
:
7773 desc
= "MPI Message Layer";
7775 case MPI_IOCLOGINFO_FC_LINK_BASE
:
7778 case MPI_IOCLOGINFO_FC_CTX_BASE
:
7779 desc
= "Context Manager";
7781 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET
:
7782 desc
= "Invalid Field Offset";
7784 case MPI_IOCLOGINFO_FC_STATE_CHANGE
:
7785 desc
= "State Change Info";
7789 printk(MYIOC_s_INFO_FMT
"LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
7790 ioc
->name
, log_info
, desc
, (log_info
& 0xFFFFFF));
7793 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7795 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
7796 * @ioc: Pointer to MPT_ADAPTER structure
7797 * @log_info: U32 LogInfo word from the IOC
7799 * Refer to lsi/sp_log.h.
7802 mpt_spi_log_info(MPT_ADAPTER
*ioc
, u32 log_info
)
7804 u32 info
= log_info
& 0x00FF0000;
7805 char *desc
= "unknown";
7809 desc
= "bug! MID not found";
7813 desc
= "Parity Error";
7817 desc
= "ASYNC Outbound Overrun";
7821 desc
= "SYNC Offset Error";
7829 desc
= "Msg In Overflow";
7837 desc
= "Outbound DMA Overrun";
7841 desc
= "Task Management";
7845 desc
= "Device Problem";
7849 desc
= "Invalid Phase Change";
7853 desc
= "Untagged Table Size";
7858 printk(MYIOC_s_INFO_FMT
"LogInfo(0x%08x): F/W: %s\n", ioc
->name
, log_info
, desc
);
7861 /* strings for sas loginfo */
7862 static char *originator_str
[] = {
7867 static char *iop_code_str
[] = {
7869 "Invalid SAS Address", /* 01h */
7871 "Invalid Page", /* 03h */
7872 "Diag Message Error", /* 04h */
7873 "Task Terminated", /* 05h */
7874 "Enclosure Management", /* 06h */
7875 "Target Mode" /* 07h */
7877 static char *pl_code_str
[] = {
7879 "Open Failure", /* 01h */
7880 "Invalid Scatter Gather List", /* 02h */
7881 "Wrong Relative Offset or Frame Length", /* 03h */
7882 "Frame Transfer Error", /* 04h */
7883 "Transmit Frame Connected Low", /* 05h */
7884 "SATA Non-NCQ RW Error Bit Set", /* 06h */
7885 "SATA Read Log Receive Data Error", /* 07h */
7886 "SATA NCQ Fail All Commands After Error", /* 08h */
7887 "SATA Error in Receive Set Device Bit FIS", /* 09h */
7888 "Receive Frame Invalid Message", /* 0Ah */
7889 "Receive Context Message Valid Error", /* 0Bh */
7890 "Receive Frame Current Frame Error", /* 0Ch */
7891 "SATA Link Down", /* 0Dh */
7892 "Discovery SATA Init W IOS", /* 0Eh */
7893 "Config Invalid Page", /* 0Fh */
7894 "Discovery SATA Init Timeout", /* 10h */
7897 "IO Not Yet Executed", /* 13h */
7898 "IO Executed", /* 14h */
7899 "Persistent Reservation Out Not Affiliation "
7901 "Open Transmit DMA Abort", /* 16h */
7902 "IO Device Missing Delay Retry", /* 17h */
7903 "IO Cancelled Due to Recieve Error", /* 18h */
7911 "Enclosure Management" /* 20h */
7913 static char *ir_code_str
[] = {
7914 "Raid Action Error", /* 00h */
7924 static char *raid_sub_code_str
[] = {
7926 "Volume Creation Failed: Data Passed too "
7928 "Volume Creation Failed: Duplicate Volumes "
7929 "Attempted", /* 02h */
7930 "Volume Creation Failed: Max Number "
7931 "Supported Volumes Exceeded", /* 03h */
7932 "Volume Creation Failed: DMA Error", /* 04h */
7933 "Volume Creation Failed: Invalid Volume Type", /* 05h */
7934 "Volume Creation Failed: Error Reading "
7935 "MFG Page 4", /* 06h */
7936 "Volume Creation Failed: Creating Internal "
7937 "Structures", /* 07h */
7946 "Activation failed: Already Active Volume", /* 10h */
7947 "Activation failed: Unsupported Volume Type", /* 11h */
7948 "Activation failed: Too Many Active Volumes", /* 12h */
7949 "Activation failed: Volume ID in Use", /* 13h */
7950 "Activation failed: Reported Failure", /* 14h */
7951 "Activation failed: Importing a Volume", /* 15h */
7962 "Phys Disk failed: Too Many Phys Disks", /* 20h */
7963 "Phys Disk failed: Data Passed too Large", /* 21h */
7964 "Phys Disk failed: DMA Error", /* 22h */
7965 "Phys Disk failed: Invalid <channel:id>", /* 23h */
7966 "Phys Disk failed: Creating Phys Disk Config "
7979 "Compatibility Error: IR Disabled", /* 30h */
7980 "Compatibility Error: Inquiry Comand Failed", /* 31h */
7981 "Compatibility Error: Device not Direct Access "
7982 "Device ", /* 32h */
7983 "Compatibility Error: Removable Device Found", /* 33h */
7984 "Compatibility Error: Device SCSI Version not "
7985 "2 or Higher", /* 34h */
7986 "Compatibility Error: SATA Device, 48 BIT LBA "
7987 "not Supported", /* 35h */
7988 "Compatibility Error: Device doesn't have "
7989 "512 Byte Block Sizes", /* 36h */
7990 "Compatibility Error: Volume Type Check Failed", /* 37h */
7991 "Compatibility Error: Volume Type is "
7992 "Unsupported by FW", /* 38h */
7993 "Compatibility Error: Disk Drive too Small for "
7994 "use in Volume", /* 39h */
7995 "Compatibility Error: Phys Disk for Create "
7996 "Volume not Found", /* 3Ah */
7997 "Compatibility Error: Too Many or too Few "
7998 "Disks for Volume Type", /* 3Bh */
7999 "Compatibility Error: Disk stripe Sizes "
8000 "Must be 64KB", /* 3Ch */
8001 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
8004 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8006 * mpt_sas_log_info - Log information returned from SAS IOC.
8007 * @ioc: Pointer to MPT_ADAPTER structure
8008 * @log_info: U32 LogInfo reply word from the IOC
8009 * @cb_idx: callback function's handle
8011 * Refer to lsi/mpi_log_sas.h.
8014 mpt_sas_log_info(MPT_ADAPTER
*ioc
, u32 log_info
, u8 cb_idx
)
8016 union loginfo_type
{
8025 union loginfo_type sas_loginfo
;
8026 char *originator_desc
= NULL
;
8027 char *code_desc
= NULL
;
8028 char *sub_code_desc
= NULL
;
8030 sas_loginfo
.loginfo
= log_info
;
8031 if ((sas_loginfo
.dw
.bus_type
!= 3 /*SAS*/) &&
8032 (sas_loginfo
.dw
.originator
< ARRAY_SIZE(originator_str
)))
8035 originator_desc
= originator_str
[sas_loginfo
.dw
.originator
];
8037 switch (sas_loginfo
.dw
.originator
) {
8040 if (sas_loginfo
.dw
.code
<
8041 ARRAY_SIZE(iop_code_str
))
8042 code_desc
= iop_code_str
[sas_loginfo
.dw
.code
];
8045 if (sas_loginfo
.dw
.code
<
8046 ARRAY_SIZE(pl_code_str
))
8047 code_desc
= pl_code_str
[sas_loginfo
.dw
.code
];
8050 if (sas_loginfo
.dw
.code
>=
8051 ARRAY_SIZE(ir_code_str
))
8053 code_desc
= ir_code_str
[sas_loginfo
.dw
.code
];
8054 if (sas_loginfo
.dw
.subcode
>=
8055 ARRAY_SIZE(raid_sub_code_str
))
8057 if (sas_loginfo
.dw
.code
== 0)
8059 raid_sub_code_str
[sas_loginfo
.dw
.subcode
];
8065 if (sub_code_desc
!= NULL
)
8066 printk(MYIOC_s_INFO_FMT
8067 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
8068 " SubCode={%s} cb_idx %s\n",
8069 ioc
->name
, log_info
, originator_desc
, code_desc
,
8070 sub_code_desc
, MptCallbacksName
[cb_idx
]);
8071 else if (code_desc
!= NULL
)
8072 printk(MYIOC_s_INFO_FMT
8073 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
8074 " SubCode(0x%04x) cb_idx %s\n",
8075 ioc
->name
, log_info
, originator_desc
, code_desc
,
8076 sas_loginfo
.dw
.subcode
, MptCallbacksName
[cb_idx
]);
8078 printk(MYIOC_s_INFO_FMT
8079 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
8080 " SubCode(0x%04x) cb_idx %s\n",
8081 ioc
->name
, log_info
, originator_desc
,
8082 sas_loginfo
.dw
.code
, sas_loginfo
.dw
.subcode
,
8083 MptCallbacksName
[cb_idx
]);
8086 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8088 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
8089 * @ioc: Pointer to MPT_ADAPTER structure
8090 * @ioc_status: U32 IOCStatus word from IOC
8091 * @mf: Pointer to MPT request frame
8093 * Refer to lsi/mpi.h.
8096 mpt_iocstatus_info_config(MPT_ADAPTER
*ioc
, u32 ioc_status
, MPT_FRAME_HDR
*mf
)
8098 Config_t
*pReq
= (Config_t
*)mf
;
8099 char extend_desc
[EVENT_DESCR_STR_SZ
];
8104 if (pReq
->Header
.PageType
== MPI_CONFIG_PAGETYPE_EXTENDED
)
8105 page_type
= pReq
->ExtPageType
;
8107 page_type
= pReq
->Header
.PageType
;
8110 * ignore invalid page messages for GET_NEXT_HANDLE
8112 form
= le32_to_cpu(pReq
->PageAddress
);
8113 if (ioc_status
== MPI_IOCSTATUS_CONFIG_INVALID_PAGE
) {
8114 if (page_type
== MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE
||
8115 page_type
== MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER
||
8116 page_type
== MPI_CONFIG_EXTPAGETYPE_ENCLOSURE
) {
8117 if ((form
>> MPI_SAS_DEVICE_PGAD_FORM_SHIFT
) ==
8118 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE
)
8121 if (page_type
== MPI_CONFIG_PAGETYPE_FC_DEVICE
)
8122 if ((form
& MPI_FC_DEVICE_PGAD_FORM_MASK
) ==
8123 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID
)
8127 snprintf(extend_desc
, EVENT_DESCR_STR_SZ
,
8128 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
8129 page_type
, pReq
->Header
.PageNumber
, pReq
->Action
, form
);
8131 switch (ioc_status
) {
8133 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION
: /* 0x0020 */
8134 desc
= "Config Page Invalid Action";
8137 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE
: /* 0x0021 */
8138 desc
= "Config Page Invalid Type";
8141 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE
: /* 0x0022 */
8142 desc
= "Config Page Invalid Page";
8145 case MPI_IOCSTATUS_CONFIG_INVALID_DATA
: /* 0x0023 */
8146 desc
= "Config Page Invalid Data";
8149 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS
: /* 0x0024 */
8150 desc
= "Config Page No Defaults";
8153 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT
: /* 0x0025 */
8154 desc
= "Config Page Can't Commit";
8161 dreplyprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"IOCStatus(0x%04X): %s: %s\n",
8162 ioc
->name
, ioc_status
, desc
, extend_desc
));
8166 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
8167 * @ioc: Pointer to MPT_ADAPTER structure
8168 * @ioc_status: U32 IOCStatus word from IOC
8169 * @mf: Pointer to MPT request frame
8171 * Refer to lsi/mpi.h.
8174 mpt_iocstatus_info(MPT_ADAPTER
*ioc
, u32 ioc_status
, MPT_FRAME_HDR
*mf
)
8176 u32 status
= ioc_status
& MPI_IOCSTATUS_MASK
;
8181 /****************************************************************************/
8182 /* Common IOCStatus values for all replies */
8183 /****************************************************************************/
8185 case MPI_IOCSTATUS_INVALID_FUNCTION
: /* 0x0001 */
8186 desc
= "Invalid Function";
8189 case MPI_IOCSTATUS_BUSY
: /* 0x0002 */
8193 case MPI_IOCSTATUS_INVALID_SGL
: /* 0x0003 */
8194 desc
= "Invalid SGL";
8197 case MPI_IOCSTATUS_INTERNAL_ERROR
: /* 0x0004 */
8198 desc
= "Internal Error";
8201 case MPI_IOCSTATUS_RESERVED
: /* 0x0005 */
8205 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES
: /* 0x0006 */
8206 desc
= "Insufficient Resources";
8209 case MPI_IOCSTATUS_INVALID_FIELD
: /* 0x0007 */
8210 desc
= "Invalid Field";
8213 case MPI_IOCSTATUS_INVALID_STATE
: /* 0x0008 */
8214 desc
= "Invalid State";
8217 /****************************************************************************/
8218 /* Config IOCStatus values */
8219 /****************************************************************************/
8221 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION
: /* 0x0020 */
8222 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE
: /* 0x0021 */
8223 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE
: /* 0x0022 */
8224 case MPI_IOCSTATUS_CONFIG_INVALID_DATA
: /* 0x0023 */
8225 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS
: /* 0x0024 */
8226 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT
: /* 0x0025 */
8227 mpt_iocstatus_info_config(ioc
, status
, mf
);
8230 /****************************************************************************/
8231 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
8233 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
8235 /****************************************************************************/
8237 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR
: /* 0x0040 */
8238 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN
: /* 0x0045 */
8239 case MPI_IOCSTATUS_SCSI_INVALID_BUS
: /* 0x0041 */
8240 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID
: /* 0x0042 */
8241 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE
: /* 0x0043 */
8242 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN
: /* 0x0044 */
8243 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR
: /* 0x0046 */
8244 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR
: /* 0x0047 */
8245 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED
: /* 0x0048 */
8246 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH
: /* 0x0049 */
8247 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED
: /* 0x004A */
8248 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED
: /* 0x004B */
8249 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED
: /* 0x004C */
8252 /****************************************************************************/
8253 /* SCSI Target values */
8254 /****************************************************************************/
8256 case MPI_IOCSTATUS_TARGET_PRIORITY_IO
: /* 0x0060 */
8257 desc
= "Target: Priority IO";
8260 case MPI_IOCSTATUS_TARGET_INVALID_PORT
: /* 0x0061 */
8261 desc
= "Target: Invalid Port";
8264 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX
: /* 0x0062 */
8265 desc
= "Target Invalid IO Index:";
8268 case MPI_IOCSTATUS_TARGET_ABORTED
: /* 0x0063 */
8269 desc
= "Target: Aborted";
8272 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE
: /* 0x0064 */
8273 desc
= "Target: No Conn Retryable";
8276 case MPI_IOCSTATUS_TARGET_NO_CONNECTION
: /* 0x0065 */
8277 desc
= "Target: No Connection";
8280 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH
: /* 0x006A */
8281 desc
= "Target: Transfer Count Mismatch";
8284 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT
: /* 0x006B */
8285 desc
= "Target: STS Data not Sent";
8288 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR
: /* 0x006D */
8289 desc
= "Target: Data Offset Error";
8292 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA
: /* 0x006E */
8293 desc
= "Target: Too Much Write Data";
8296 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT
: /* 0x006F */
8297 desc
= "Target: IU Too Short";
8300 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT
: /* 0x0070 */
8301 desc
= "Target: ACK NAK Timeout";
8304 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED
: /* 0x0071 */
8305 desc
= "Target: Nak Received";
8308 /****************************************************************************/
8309 /* Fibre Channel Direct Access values */
8310 /****************************************************************************/
8312 case MPI_IOCSTATUS_FC_ABORTED
: /* 0x0066 */
8313 desc
= "FC: Aborted";
8316 case MPI_IOCSTATUS_FC_RX_ID_INVALID
: /* 0x0067 */
8317 desc
= "FC: RX ID Invalid";
8320 case MPI_IOCSTATUS_FC_DID_INVALID
: /* 0x0068 */
8321 desc
= "FC: DID Invalid";
8324 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT
: /* 0x0069 */
8325 desc
= "FC: Node Logged Out";
8328 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED
: /* 0x006C */
8329 desc
= "FC: Exchange Canceled";
8332 /****************************************************************************/
8334 /****************************************************************************/
8336 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND
: /* 0x0080 */
8337 desc
= "LAN: Device not Found";
8340 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE
: /* 0x0081 */
8341 desc
= "LAN: Device Failure";
8344 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR
: /* 0x0082 */
8345 desc
= "LAN: Transmit Error";
8348 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED
: /* 0x0083 */
8349 desc
= "LAN: Transmit Aborted";
8352 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR
: /* 0x0084 */
8353 desc
= "LAN: Receive Error";
8356 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED
: /* 0x0085 */
8357 desc
= "LAN: Receive Aborted";
8360 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET
: /* 0x0086 */
8361 desc
= "LAN: Partial Packet";
8364 case MPI_IOCSTATUS_LAN_CANCELED
: /* 0x0087 */
8365 desc
= "LAN: Canceled";
8368 /****************************************************************************/
8369 /* Serial Attached SCSI values */
8370 /****************************************************************************/
8372 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED
: /* 0x0090 */
8373 desc
= "SAS: SMP Request Failed";
8376 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN
: /* 0x0090 */
8377 desc
= "SAS: SMP Data Overrun";
8388 dreplyprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"IOCStatus(0x%04X): %s\n",
8389 ioc
->name
, status
, desc
));
8392 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8393 EXPORT_SYMBOL(mpt_attach
);
8394 EXPORT_SYMBOL(mpt_detach
);
8396 EXPORT_SYMBOL(mpt_resume
);
8397 EXPORT_SYMBOL(mpt_suspend
);
8399 EXPORT_SYMBOL(ioc_list
);
8400 EXPORT_SYMBOL(mpt_register
);
8401 EXPORT_SYMBOL(mpt_deregister
);
8402 EXPORT_SYMBOL(mpt_event_register
);
8403 EXPORT_SYMBOL(mpt_event_deregister
);
8404 EXPORT_SYMBOL(mpt_reset_register
);
8405 EXPORT_SYMBOL(mpt_reset_deregister
);
8406 EXPORT_SYMBOL(mpt_device_driver_register
);
8407 EXPORT_SYMBOL(mpt_device_driver_deregister
);
8408 EXPORT_SYMBOL(mpt_get_msg_frame
);
8409 EXPORT_SYMBOL(mpt_put_msg_frame
);
8410 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri
);
8411 EXPORT_SYMBOL(mpt_free_msg_frame
);
8412 EXPORT_SYMBOL(mpt_send_handshake_request
);
8413 EXPORT_SYMBOL(mpt_verify_adapter
);
8414 EXPORT_SYMBOL(mpt_GetIocState
);
8415 EXPORT_SYMBOL(mpt_print_ioc_summary
);
8416 EXPORT_SYMBOL(mpt_HardResetHandler
);
8417 EXPORT_SYMBOL(mpt_config
);
8418 EXPORT_SYMBOL(mpt_findImVolumes
);
8419 EXPORT_SYMBOL(mpt_alloc_fw_memory
);
8420 EXPORT_SYMBOL(mpt_free_fw_memory
);
8421 EXPORT_SYMBOL(mptbase_sas_persist_operation
);
8422 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0
);
8424 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8426 * fusion_init - Fusion MPT base driver initialization routine.
8428 * Returns 0 for success, non-zero for failure.
8435 show_mptmod_ver(my_NAME
, my_VERSION
);
8436 printk(KERN_INFO COPYRIGHT
"\n");
8438 for (cb_idx
= 0; cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
; cb_idx
++) {
8439 MptCallbacks
[cb_idx
] = NULL
;
8440 MptDriverClass
[cb_idx
] = MPTUNKNOWN_DRIVER
;
8441 MptEvHandlers
[cb_idx
] = NULL
;
8442 MptResetHandlers
[cb_idx
] = NULL
;
8445 /* Register ourselves (mptbase) in order to facilitate
8446 * EventNotification handling.
8448 mpt_base_index
= mpt_register(mptbase_reply
, MPTBASE_DRIVER
,
8451 /* Register for hard reset handling callbacks.
8453 mpt_reset_register(mpt_base_index
, mpt_ioc_reset
);
8455 #ifdef CONFIG_PROC_FS
8456 (void) procmpt_create();
8461 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8463 * fusion_exit - Perform driver unload cleanup.
8465 * This routine frees all resources associated with each MPT adapter
8466 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
8472 mpt_reset_deregister(mpt_base_index
);
8474 #ifdef CONFIG_PROC_FS
8479 module_init(fusion_init
);
8480 module_exit(fusion_exit
);