2 * linux/drivers/message/fusion/mptbase.c
3 * This is the Fusion MPT base driver which supports multiple
4 * (SCSI + LAN) specialized protocol drivers.
5 * For use with LSI PCI chip/adapter(s)
6 * running LSI Fusion MPT (Message Passing Technology) firmware.
8 * Copyright (c) 1999-2008 LSI Corporation
9 * (mailto:DL-MPTFusionLinux@lsi.com)
12 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; version 2 of the License.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
24 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
25 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
26 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
27 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
28 solely responsible for determining the appropriateness of using and
29 distributing the Program and assumes all risks associated with its
30 exercise of rights under this Agreement, including but not limited to
31 the risks and costs of program errors, damage to or loss of data,
32 programs or equipment, and unavailability or interruption of operations.
34 DISCLAIMER OF LIABILITY
35 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
36 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
38 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
39 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
40 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
41 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
43 You should have received a copy of the GNU General Public License
44 along with this program; if not, write to the Free Software
45 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
47 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
49 #include <linux/kernel.h>
50 #include <linux/module.h>
51 #include <linux/errno.h>
52 #include <linux/init.h>
53 #include <linux/slab.h>
54 #include <linux/types.h>
55 #include <linux/pci.h>
56 #include <linux/kdev_t.h>
57 #include <linux/blkdev.h>
58 #include <linux/delay.h>
59 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
60 #include <linux/dma-mapping.h>
67 #include "lsi/mpi_log_fc.h"
69 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
70 #define my_NAME "Fusion MPT base driver"
71 #define my_VERSION MPT_LINUX_VERSION_COMMON
72 #define MYNAM "mptbase"
74 MODULE_AUTHOR(MODULEAUTHOR
);
75 MODULE_DESCRIPTION(my_NAME
);
76 MODULE_LICENSE("GPL");
77 MODULE_VERSION(my_VERSION
);
83 static int mpt_msi_enable_spi
;
84 module_param(mpt_msi_enable_spi
, int, 0);
85 MODULE_PARM_DESC(mpt_msi_enable_spi
, " Enable MSI Support for SPI \
86 controllers (default=0)");
88 static int mpt_msi_enable_fc
;
89 module_param(mpt_msi_enable_fc
, int, 0);
90 MODULE_PARM_DESC(mpt_msi_enable_fc
, " Enable MSI Support for FC \
91 controllers (default=0)");
93 static int mpt_msi_enable_sas
;
94 module_param(mpt_msi_enable_sas
, int, 0);
95 MODULE_PARM_DESC(mpt_msi_enable_sas
, " Enable MSI Support for SAS \
96 controllers (default=0)");
99 static int mpt_channel_mapping
;
100 module_param(mpt_channel_mapping
, int, 0);
101 MODULE_PARM_DESC(mpt_channel_mapping
, " Mapping id's to channels (default=0)");
103 static int mpt_debug_level
;
104 static int mpt_set_debug_level(const char *val
, struct kernel_param
*kp
);
105 module_param_call(mpt_debug_level
, mpt_set_debug_level
, param_get_int
,
106 &mpt_debug_level
, 0600);
107 MODULE_PARM_DESC(mpt_debug_level
, " debug level - refer to mptdebug.h \
110 int mpt_fwfault_debug
;
111 EXPORT_SYMBOL(mpt_fwfault_debug
);
112 module_param_call(mpt_fwfault_debug
, param_set_int
, param_get_int
,
113 &mpt_fwfault_debug
, 0600);
114 MODULE_PARM_DESC(mpt_fwfault_debug
, "Enable detection of Firmware fault"
115 " and halt Firmware on fault - (default=0)");
120 static int mfcounter
= 0;
121 #define PRINT_MF_COUNT 20000
124 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
129 static struct proc_dir_entry
*mpt_proc_root_dir
;
131 #define WHOINIT_UNKNOWN 0xAA
133 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
137 /* Adapter link list */
139 /* Callback lookup table */
140 static MPT_CALLBACK MptCallbacks
[MPT_MAX_PROTOCOL_DRIVERS
];
141 /* Protocol driver class lookup table */
142 static int MptDriverClass
[MPT_MAX_PROTOCOL_DRIVERS
];
143 /* Event handler lookup table */
144 static MPT_EVHANDLER MptEvHandlers
[MPT_MAX_PROTOCOL_DRIVERS
];
145 /* Reset handler lookup table */
146 static MPT_RESETHANDLER MptResetHandlers
[MPT_MAX_PROTOCOL_DRIVERS
];
147 static struct mpt_pci_driver
*MptDeviceDriverHandlers
[MPT_MAX_PROTOCOL_DRIVERS
];
151 * Driver Callback Index's
153 static u8 mpt_base_index
= MPT_MAX_PROTOCOL_DRIVERS
;
154 static u8 last_drv_idx
;
156 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
160 static irqreturn_t
mpt_interrupt(int irq
, void *bus_id
);
161 static int mptbase_reply(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*req
,
162 MPT_FRAME_HDR
*reply
);
163 static int mpt_handshake_req_reply_wait(MPT_ADAPTER
*ioc
, int reqBytes
,
164 u32
*req
, int replyBytes
, u16
*u16reply
, int maxwait
,
166 static int mpt_do_ioc_recovery(MPT_ADAPTER
*ioc
, u32 reason
, int sleepFlag
);
167 static void mpt_detect_bound_ports(MPT_ADAPTER
*ioc
, struct pci_dev
*pdev
);
168 static void mpt_adapter_disable(MPT_ADAPTER
*ioc
);
169 static void mpt_adapter_dispose(MPT_ADAPTER
*ioc
);
171 static void MptDisplayIocCapabilities(MPT_ADAPTER
*ioc
);
172 static int MakeIocReady(MPT_ADAPTER
*ioc
, int force
, int sleepFlag
);
173 static int GetIocFacts(MPT_ADAPTER
*ioc
, int sleepFlag
, int reason
);
174 static int GetPortFacts(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
);
175 static int SendIocInit(MPT_ADAPTER
*ioc
, int sleepFlag
);
176 static int SendPortEnable(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
);
177 static int mpt_do_upload(MPT_ADAPTER
*ioc
, int sleepFlag
);
178 static int mpt_downloadboot(MPT_ADAPTER
*ioc
, MpiFwHeader_t
*pFwHeader
, int sleepFlag
);
179 static int mpt_diag_reset(MPT_ADAPTER
*ioc
, int ignore
, int sleepFlag
);
180 static int KickStart(MPT_ADAPTER
*ioc
, int ignore
, int sleepFlag
);
181 static int SendIocReset(MPT_ADAPTER
*ioc
, u8 reset_type
, int sleepFlag
);
182 static int PrimeIocFifos(MPT_ADAPTER
*ioc
);
183 static int WaitForDoorbellAck(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
);
184 static int WaitForDoorbellInt(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
);
185 static int WaitForDoorbellReply(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
);
186 static int GetLanConfigPages(MPT_ADAPTER
*ioc
);
187 static int GetIoUnitPage2(MPT_ADAPTER
*ioc
);
188 int mptbase_sas_persist_operation(MPT_ADAPTER
*ioc
, u8 persist_opcode
);
189 static int mpt_GetScsiPortSettings(MPT_ADAPTER
*ioc
, int portnum
);
190 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER
*ioc
, int portnum
);
191 static void mpt_read_ioc_pg_1(MPT_ADAPTER
*ioc
);
192 static void mpt_read_ioc_pg_4(MPT_ADAPTER
*ioc
);
193 static void mpt_get_manufacturing_pg_0(MPT_ADAPTER
*ioc
);
194 static int SendEventNotification(MPT_ADAPTER
*ioc
, u8 EvSwitch
,
196 static int SendEventAck(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*evnp
);
197 static int mpt_host_page_access_control(MPT_ADAPTER
*ioc
, u8 access_control_value
, int sleepFlag
);
198 static int mpt_host_page_alloc(MPT_ADAPTER
*ioc
, pIOCInit_t ioc_init
);
200 #ifdef CONFIG_PROC_FS
201 static int procmpt_summary_read(char *buf
, char **start
, off_t offset
,
202 int request
, int *eof
, void *data
);
203 static int procmpt_version_read(char *buf
, char **start
, off_t offset
,
204 int request
, int *eof
, void *data
);
205 static int procmpt_iocinfo_read(char *buf
, char **start
, off_t offset
,
206 int request
, int *eof
, void *data
);
208 static void mpt_get_fw_exp_ver(char *buf
, MPT_ADAPTER
*ioc
);
210 static int ProcessEventNotification(MPT_ADAPTER
*ioc
,
211 EventNotificationReply_t
*evReply
, int *evHandlers
);
212 static void mpt_iocstatus_info(MPT_ADAPTER
*ioc
, u32 ioc_status
, MPT_FRAME_HDR
*mf
);
213 static void mpt_fc_log_info(MPT_ADAPTER
*ioc
, u32 log_info
);
214 static void mpt_spi_log_info(MPT_ADAPTER
*ioc
, u32 log_info
);
215 static void mpt_sas_log_info(MPT_ADAPTER
*ioc
, u32 log_info
);
216 static int mpt_read_ioc_pg_3(MPT_ADAPTER
*ioc
);
217 static void mpt_inactive_raid_list_free(MPT_ADAPTER
*ioc
);
219 /* module entry point */
220 static int __init
fusion_init (void);
221 static void __exit
fusion_exit (void);
223 #define CHIPREG_READ32(addr) readl_relaxed(addr)
224 #define CHIPREG_READ32_dmasync(addr) readl(addr)
225 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
226 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
227 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
230 pci_disable_io_access(struct pci_dev
*pdev
)
234 pci_read_config_word(pdev
, PCI_COMMAND
, &command_reg
);
236 pci_write_config_word(pdev
, PCI_COMMAND
, command_reg
);
240 pci_enable_io_access(struct pci_dev
*pdev
)
244 pci_read_config_word(pdev
, PCI_COMMAND
, &command_reg
);
246 pci_write_config_word(pdev
, PCI_COMMAND
, command_reg
);
249 static int mpt_set_debug_level(const char *val
, struct kernel_param
*kp
)
251 int ret
= param_set_int(val
, kp
);
257 list_for_each_entry(ioc
, &ioc_list
, list
)
258 ioc
->debug_level
= mpt_debug_level
;
263 * mpt_get_cb_idx - obtain cb_idx for registered driver
264 * @dclass: class driver enum
266 * Returns cb_idx, or zero means it wasn't found
269 mpt_get_cb_idx(MPT_DRIVER_CLASS dclass
)
273 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--)
274 if (MptDriverClass
[cb_idx
] == dclass
)
280 * mpt_is_discovery_complete - determine if discovery has completed
281 * @ioc: per adatper instance
283 * Returns 1 when discovery completed, else zero.
286 mpt_is_discovery_complete(MPT_ADAPTER
*ioc
)
288 ConfigExtendedPageHeader_t hdr
;
290 SasIOUnitPage0_t
*buffer
;
291 dma_addr_t dma_handle
;
294 memset(&hdr
, 0, sizeof(ConfigExtendedPageHeader_t
));
295 memset(&cfg
, 0, sizeof(CONFIGPARMS
));
296 hdr
.PageVersion
= MPI_SASIOUNITPAGE0_PAGEVERSION
;
297 hdr
.PageType
= MPI_CONFIG_PAGETYPE_EXTENDED
;
298 hdr
.ExtPageType
= MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT
;
299 cfg
.cfghdr
.ehdr
= &hdr
;
300 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
302 if ((mpt_config(ioc
, &cfg
)))
304 if (!hdr
.ExtPageLength
)
307 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.ExtPageLength
* 4,
312 cfg
.physAddr
= dma_handle
;
313 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
315 if ((mpt_config(ioc
, &cfg
)))
316 goto out_free_consistent
;
318 if (!(buffer
->PhyData
[0].PortFlags
&
319 MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS
))
323 pci_free_consistent(ioc
->pcidev
, hdr
.ExtPageLength
* 4,
330 * mpt_fault_reset_work - work performed on workq after ioc fault
331 * @work: input argument, used to derive ioc
335 mpt_fault_reset_work(struct work_struct
*work
)
338 container_of(work
, MPT_ADAPTER
, fault_reset_work
.work
);
343 if (ioc
->ioc_reset_in_progress
|| !ioc
->active
)
346 ioc_raw_state
= mpt_GetIocState(ioc
, 0);
347 if ((ioc_raw_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_FAULT
) {
348 printk(MYIOC_s_WARN_FMT
"IOC is in FAULT state (%04xh)!!!\n",
349 ioc
->name
, ioc_raw_state
& MPI_DOORBELL_DATA_MASK
);
350 printk(MYIOC_s_WARN_FMT
"Issuing HardReset from %s!!\n",
351 ioc
->name
, __func__
);
352 rc
= mpt_HardResetHandler(ioc
, CAN_SLEEP
);
353 printk(MYIOC_s_WARN_FMT
"%s: HardReset: %s\n", ioc
->name
,
354 __func__
, (rc
== 0) ? "success" : "failed");
355 ioc_raw_state
= mpt_GetIocState(ioc
, 0);
356 if ((ioc_raw_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_FAULT
)
357 printk(MYIOC_s_WARN_FMT
"IOC is in FAULT state after "
358 "reset (%04xh)\n", ioc
->name
, ioc_raw_state
&
359 MPI_DOORBELL_DATA_MASK
);
360 } else if (ioc
->bus_type
== SAS
&& ioc
->sas_discovery_quiesce_io
) {
361 if ((mpt_is_discovery_complete(ioc
))) {
362 devtprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"clearing "
363 "discovery_quiesce_io flag\n", ioc
->name
));
364 ioc
->sas_discovery_quiesce_io
= 0;
370 * Take turns polling alternate controller
375 /* rearm the timer */
376 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
377 if (ioc
->reset_work_q
)
378 queue_delayed_work(ioc
->reset_work_q
, &ioc
->fault_reset_work
,
379 msecs_to_jiffies(MPT_POLLING_INTERVAL
));
380 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
385 * Process turbo (context) reply...
388 mpt_turbo_reply(MPT_ADAPTER
*ioc
, u32 pa
)
390 MPT_FRAME_HDR
*mf
= NULL
;
391 MPT_FRAME_HDR
*mr
= NULL
;
395 dmfprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Got TURBO reply req_idx=%08x\n",
398 switch (pa
>> MPI_CONTEXT_REPLY_TYPE_SHIFT
) {
399 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT
:
400 req_idx
= pa
& 0x0000FFFF;
401 cb_idx
= (pa
& 0x00FF0000) >> 16;
402 mf
= MPT_INDEX_2_MFPTR(ioc
, req_idx
);
404 case MPI_CONTEXT_REPLY_TYPE_LAN
:
405 cb_idx
= mpt_get_cb_idx(MPTLAN_DRIVER
);
407 * Blind set of mf to NULL here was fatal
408 * after lan_reply says "freeme"
409 * Fix sort of combined with an optimization here;
410 * added explicit check for case where lan_reply
411 * was just returning 1 and doing nothing else.
412 * For this case skip the callback, but set up
413 * proper mf value first here:-)
415 if ((pa
& 0x58000000) == 0x58000000) {
416 req_idx
= pa
& 0x0000FFFF;
417 mf
= MPT_INDEX_2_MFPTR(ioc
, req_idx
);
418 mpt_free_msg_frame(ioc
, mf
);
423 mr
= (MPT_FRAME_HDR
*) CAST_U32_TO_PTR(pa
);
425 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET
:
426 cb_idx
= mpt_get_cb_idx(MPTSTM_DRIVER
);
427 mr
= (MPT_FRAME_HDR
*) CAST_U32_TO_PTR(pa
);
434 /* Check for (valid) IO callback! */
435 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
||
436 MptCallbacks
[cb_idx
] == NULL
) {
437 printk(MYIOC_s_WARN_FMT
"%s: Invalid cb_idx (%d)!\n",
438 __func__
, ioc
->name
, cb_idx
);
442 if (MptCallbacks
[cb_idx
](ioc
, mf
, mr
))
443 mpt_free_msg_frame(ioc
, mf
);
449 mpt_reply(MPT_ADAPTER
*ioc
, u32 pa
)
460 /* non-TURBO reply! Hmmm, something may be up...
461 * Newest turbo reply mechanism; get address
462 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
465 /* Map DMA address of reply header to cpu address.
466 * pa is 32 bits - but the dma address may be 32 or 64 bits
467 * get offset based only only the low addresses
470 reply_dma_low
= (pa
<<= 1);
471 mr
= (MPT_FRAME_HDR
*)((u8
*)ioc
->reply_frames
+
472 (reply_dma_low
- ioc
->reply_frames_low_dma
));
474 req_idx
= le16_to_cpu(mr
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
);
475 cb_idx
= mr
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
;
476 mf
= MPT_INDEX_2_MFPTR(ioc
, req_idx
);
478 dmfprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
479 ioc
->name
, mr
, req_idx
, cb_idx
, mr
->u
.hdr
.Function
));
480 DBG_DUMP_REPLY_FRAME(ioc
, (u32
*)mr
);
482 /* Check/log IOC log info
484 ioc_stat
= le16_to_cpu(mr
->u
.reply
.IOCStatus
);
485 if (ioc_stat
& MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE
) {
486 u32 log_info
= le32_to_cpu(mr
->u
.reply
.IOCLogInfo
);
487 if (ioc
->bus_type
== FC
)
488 mpt_fc_log_info(ioc
, log_info
);
489 else if (ioc
->bus_type
== SPI
)
490 mpt_spi_log_info(ioc
, log_info
);
491 else if (ioc
->bus_type
== SAS
)
492 mpt_sas_log_info(ioc
, log_info
);
495 if (ioc_stat
& MPI_IOCSTATUS_MASK
)
496 mpt_iocstatus_info(ioc
, (u32
)ioc_stat
, mf
);
498 /* Check for (valid) IO callback! */
499 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
||
500 MptCallbacks
[cb_idx
] == NULL
) {
501 printk(MYIOC_s_WARN_FMT
"%s: Invalid cb_idx (%d)!\n",
502 __func__
, ioc
->name
, cb_idx
);
507 freeme
= MptCallbacks
[cb_idx
](ioc
, mf
, mr
);
510 /* Flush (non-TURBO) reply with a WRITE! */
511 CHIPREG_WRITE32(&ioc
->chip
->ReplyFifo
, pa
);
514 mpt_free_msg_frame(ioc
, mf
);
518 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
520 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
521 * @irq: irq number (not used)
522 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
524 * This routine is registered via the request_irq() kernel API call,
525 * and handles all interrupts generated from a specific MPT adapter
526 * (also referred to as a IO Controller or IOC).
527 * This routine must clear the interrupt from the adapter and does
528 * so by reading the reply FIFO. Multiple replies may be processed
529 * per single call to this routine.
531 * This routine handles register-level access of the adapter but
532 * dispatches (calls) a protocol-specific callback routine to handle
533 * the protocol-specific details of the MPT request completion.
536 mpt_interrupt(int irq
, void *bus_id
)
538 MPT_ADAPTER
*ioc
= bus_id
;
539 u32 pa
= CHIPREG_READ32_dmasync(&ioc
->chip
->ReplyFifo
);
541 if (pa
== 0xFFFFFFFF)
545 * Drain the reply FIFO!
548 if (pa
& MPI_ADDRESS_REPLY_A_BIT
)
551 mpt_turbo_reply(ioc
, pa
);
552 pa
= CHIPREG_READ32_dmasync(&ioc
->chip
->ReplyFifo
);
553 } while (pa
!= 0xFFFFFFFF);
558 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
560 * mptbase_reply - MPT base driver's callback routine
561 * @ioc: Pointer to MPT_ADAPTER structure
562 * @req: Pointer to original MPT request frame
563 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
565 * MPT base driver's callback routine; all base driver
566 * "internal" request/reply processing is routed here.
567 * Currently used for EventNotification and EventAck handling.
569 * Returns 1 indicating original alloc'd request frame ptr
570 * should be freed, or 0 if it shouldn't.
573 mptbase_reply(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*req
, MPT_FRAME_HDR
*reply
)
575 EventNotificationReply_t
*pEventReply
;
580 switch (reply
->u
.hdr
.Function
) {
581 case MPI_FUNCTION_EVENT_NOTIFICATION
:
582 pEventReply
= (EventNotificationReply_t
*)reply
;
584 ProcessEventNotification(ioc
, pEventReply
, &evHandlers
);
585 event
= le32_to_cpu(pEventReply
->Event
) & 0xFF;
586 if (pEventReply
->MsgFlags
& MPI_MSGFLAGS_CONTINUATION_REPLY
)
588 if (event
!= MPI_EVENT_EVENT_CHANGE
)
590 case MPI_FUNCTION_CONFIG
:
591 case MPI_FUNCTION_SAS_IO_UNIT_CONTROL
:
592 ioc
->mptbase_cmds
.status
|= MPT_MGMT_STATUS_COMMAND_GOOD
;
594 ioc
->mptbase_cmds
.status
|= MPT_MGMT_STATUS_RF_VALID
;
595 memcpy(ioc
->mptbase_cmds
.reply
, reply
,
596 min(MPT_DEFAULT_FRAME_SIZE
,
597 4 * reply
->u
.reply
.MsgLength
));
599 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_PENDING
) {
600 ioc
->mptbase_cmds
.status
&= ~MPT_MGMT_STATUS_PENDING
;
601 complete(&ioc
->mptbase_cmds
.done
);
604 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_FREE_MF
)
607 case MPI_FUNCTION_EVENT_ACK
:
608 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
609 "EventAck reply received\n", ioc
->name
));
612 printk(MYIOC_s_ERR_FMT
613 "Unexpected msg function (=%02Xh) reply received!\n",
614 ioc
->name
, reply
->u
.hdr
.Function
);
619 * Conditionally tell caller to free the original
620 * EventNotification/EventAck/unexpected request frame!
625 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
627 * mpt_register - Register protocol-specific main callback handler.
628 * @cbfunc: callback function pointer
629 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
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
)
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
;
668 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
670 * mpt_deregister - Deregister a protocol drivers resources.
671 * @cb_idx: previously registered callback handle
673 * Each protocol-specific driver should call this routine when its
674 * module is unloaded.
677 mpt_deregister(u8 cb_idx
)
679 if (cb_idx
&& (cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
)) {
680 MptCallbacks
[cb_idx
] = NULL
;
681 MptDriverClass
[cb_idx
] = MPTUNKNOWN_DRIVER
;
682 MptEvHandlers
[cb_idx
] = NULL
;
688 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
690 * mpt_event_register - Register protocol-specific event callback handler.
691 * @cb_idx: previously registered (via mpt_register) callback handle
692 * @ev_cbfunc: callback function
694 * This routine can be called by one or more protocol-specific drivers
695 * if/when they choose to be notified of MPT events.
697 * Returns 0 for success.
700 mpt_event_register(u8 cb_idx
, MPT_EVHANDLER ev_cbfunc
)
702 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
705 MptEvHandlers
[cb_idx
] = ev_cbfunc
;
709 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
711 * mpt_event_deregister - Deregister protocol-specific event callback handler
712 * @cb_idx: previously registered callback handle
714 * Each protocol-specific driver should call this routine
715 * when it does not (or can no longer) handle events,
716 * or when its module is unloaded.
719 mpt_event_deregister(u8 cb_idx
)
721 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
724 MptEvHandlers
[cb_idx
] = NULL
;
727 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
729 * mpt_reset_register - Register protocol-specific IOC reset handler.
730 * @cb_idx: previously registered (via mpt_register) callback handle
731 * @reset_func: reset function
733 * This routine can be called by one or more protocol-specific drivers
734 * if/when they choose to be notified of IOC resets.
736 * Returns 0 for success.
739 mpt_reset_register(u8 cb_idx
, MPT_RESETHANDLER reset_func
)
741 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
744 MptResetHandlers
[cb_idx
] = reset_func
;
748 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
750 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
751 * @cb_idx: previously registered callback handle
753 * Each protocol-specific driver should call this routine
754 * when it does not (or can no longer) handle IOC reset handling,
755 * or when its module is unloaded.
758 mpt_reset_deregister(u8 cb_idx
)
760 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
763 MptResetHandlers
[cb_idx
] = NULL
;
766 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
768 * mpt_device_driver_register - Register device driver hooks
769 * @dd_cbfunc: driver callbacks struct
770 * @cb_idx: MPT protocol driver index
773 mpt_device_driver_register(struct mpt_pci_driver
* dd_cbfunc
, u8 cb_idx
)
776 const struct pci_device_id
*id
;
778 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
781 MptDeviceDriverHandlers
[cb_idx
] = dd_cbfunc
;
783 /* call per pci device probe entry point */
784 list_for_each_entry(ioc
, &ioc_list
, list
) {
785 id
= ioc
->pcidev
->driver
?
786 ioc
->pcidev
->driver
->id_table
: NULL
;
787 if (dd_cbfunc
->probe
)
788 dd_cbfunc
->probe(ioc
->pcidev
, id
);
794 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
796 * mpt_device_driver_deregister - DeRegister device driver hooks
797 * @cb_idx: MPT protocol driver index
800 mpt_device_driver_deregister(u8 cb_idx
)
802 struct mpt_pci_driver
*dd_cbfunc
;
805 if (!cb_idx
|| cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
808 dd_cbfunc
= MptDeviceDriverHandlers
[cb_idx
];
810 list_for_each_entry(ioc
, &ioc_list
, list
) {
811 if (dd_cbfunc
->remove
)
812 dd_cbfunc
->remove(ioc
->pcidev
);
815 MptDeviceDriverHandlers
[cb_idx
] = NULL
;
819 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
821 * mpt_get_msg_frame - Obtain an MPT request frame from the pool
822 * @cb_idx: Handle of registered MPT protocol driver
823 * @ioc: Pointer to MPT adapter structure
825 * Obtain an MPT request frame from the pool (of 1024) that are
826 * allocated per MPT adapter.
828 * Returns pointer to a MPT request frame or %NULL if none are available
829 * or IOC is not active.
832 mpt_get_msg_frame(u8 cb_idx
, MPT_ADAPTER
*ioc
)
836 u16 req_idx
; /* Request index */
838 /* validate handle and ioc identifier */
842 printk(MYIOC_s_WARN_FMT
"IOC Not Active! mpt_get_msg_frame "
843 "returning NULL!\n", ioc
->name
);
846 /* If interrupts are not attached, do not return a request frame */
850 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
851 if (!list_empty(&ioc
->FreeQ
)) {
854 mf
= list_entry(ioc
->FreeQ
.next
, MPT_FRAME_HDR
,
855 u
.frame
.linkage
.list
);
856 list_del(&mf
->u
.frame
.linkage
.list
);
857 mf
->u
.frame
.linkage
.arg1
= 0;
858 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= cb_idx
; /* byte */
859 req_offset
= (u8
*)mf
- (u8
*)ioc
->req_frames
;
861 req_idx
= req_offset
/ ioc
->req_sz
;
862 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(req_idx
);
863 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.rsvd
= 0;
864 /* Default, will be changed if necessary in SG generation */
865 ioc
->RequestNB
[req_idx
] = ioc
->NB_for_64_byte_frame
;
872 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
876 printk(MYIOC_s_WARN_FMT
"IOC Active. No free Msg Frames! "
877 "Count 0x%x Max 0x%x\n", ioc
->name
, ioc
->mfcnt
,
880 if (mfcounter
== PRINT_MF_COUNT
)
881 printk(MYIOC_s_INFO_FMT
"MF Count 0x%x Max 0x%x \n", ioc
->name
,
882 ioc
->mfcnt
, ioc
->req_depth
);
885 dmfprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mpt_get_msg_frame(%d,%d), got mf=%p\n",
886 ioc
->name
, cb_idx
, ioc
->id
, mf
));
890 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
892 * mpt_put_msg_frame - Send a protocol-specific MPT request frame to an IOC
893 * @cb_idx: Handle of registered MPT protocol driver
894 * @ioc: Pointer to MPT adapter structure
895 * @mf: Pointer to MPT request frame
897 * This routine posts an MPT request frame to the request post FIFO of a
898 * specific MPT adapter.
901 mpt_put_msg_frame(u8 cb_idx
, MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
)
905 u16 req_idx
; /* Request index */
907 /* ensure values are reset properly! */
908 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= cb_idx
; /* byte */
909 req_offset
= (u8
*)mf
- (u8
*)ioc
->req_frames
;
911 req_idx
= req_offset
/ ioc
->req_sz
;
912 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(req_idx
);
913 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.rsvd
= 0;
915 DBG_DUMP_PUT_MSG_FRAME(ioc
, (u32
*)mf
);
917 mf_dma_addr
= (ioc
->req_frames_low_dma
+ req_offset
) | ioc
->RequestNB
[req_idx
];
918 dsgprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mf_dma_addr=%x req_idx=%d "
919 "RequestNB=%x\n", ioc
->name
, mf_dma_addr
, req_idx
,
920 ioc
->RequestNB
[req_idx
]));
921 CHIPREG_WRITE32(&ioc
->chip
->RequestFifo
, mf_dma_addr
);
925 * mpt_put_msg_frame_hi_pri - Send a hi-pri protocol-specific MPT request frame
926 * @cb_idx: Handle of registered MPT protocol driver
927 * @ioc: Pointer to MPT adapter structure
928 * @mf: Pointer to MPT request frame
930 * Send a protocol-specific MPT request frame to an IOC using
931 * hi-priority request queue.
933 * This routine posts an MPT request frame to the request post FIFO of a
934 * specific MPT adapter.
937 mpt_put_msg_frame_hi_pri(u8 cb_idx
, MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
)
941 u16 req_idx
; /* Request index */
943 /* ensure values are reset properly! */
944 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= cb_idx
;
945 req_offset
= (u8
*)mf
- (u8
*)ioc
->req_frames
;
946 req_idx
= req_offset
/ ioc
->req_sz
;
947 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(req_idx
);
948 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.rsvd
= 0;
950 DBG_DUMP_PUT_MSG_FRAME(ioc
, (u32
*)mf
);
952 mf_dma_addr
= (ioc
->req_frames_low_dma
+ req_offset
);
953 dsgprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mf_dma_addr=%x req_idx=%d\n",
954 ioc
->name
, mf_dma_addr
, req_idx
));
955 CHIPREG_WRITE32(&ioc
->chip
->RequestHiPriFifo
, mf_dma_addr
);
958 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
960 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
961 * @ioc: Pointer to MPT adapter structure
962 * @mf: Pointer to MPT request frame
964 * This routine places a MPT request frame back on the MPT adapter's
968 mpt_free_msg_frame(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
)
972 /* Put Request back on FreeQ! */
973 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
974 if (cpu_to_le32(mf
->u
.frame
.linkage
.arg1
) == 0xdeadbeaf)
976 /* signature to know if this mf is freed */
977 mf
->u
.frame
.linkage
.arg1
= cpu_to_le32(0xdeadbeaf);
978 list_add_tail(&mf
->u
.frame
.linkage
.list
, &ioc
->FreeQ
);
983 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
986 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
988 * mpt_add_sge - Place a simple 32 bit SGE at address pAddr.
989 * @pAddr: virtual address for SGE
990 * @flagslength: SGE flags and data transfer length
991 * @dma_addr: Physical address
993 * This routine places a MPT request frame back on the MPT adapter's
997 mpt_add_sge(void *pAddr
, u32 flagslength
, dma_addr_t dma_addr
)
999 SGESimple32_t
*pSge
= (SGESimple32_t
*) pAddr
;
1000 pSge
->FlagsLength
= cpu_to_le32(flagslength
);
1001 pSge
->Address
= cpu_to_le32(dma_addr
);
1005 * mpt_add_sge_64bit - Place a simple 64 bit SGE at address pAddr.
1006 * @pAddr: virtual address for SGE
1007 * @flagslength: SGE flags and data transfer length
1008 * @dma_addr: Physical address
1010 * This routine places a MPT request frame back on the MPT adapter's
1014 mpt_add_sge_64bit(void *pAddr
, u32 flagslength
, dma_addr_t dma_addr
)
1016 SGESimple64_t
*pSge
= (SGESimple64_t
*) pAddr
;
1017 pSge
->Address
.Low
= cpu_to_le32
1018 (lower_32_bits((unsigned long)(dma_addr
)));
1019 pSge
->Address
.High
= cpu_to_le32
1020 (upper_32_bits((unsigned long)dma_addr
));
1021 pSge
->FlagsLength
= cpu_to_le32
1022 ((flagslength
| MPT_SGE_FLAGS_64_BIT_ADDRESSING
));
1026 * mpt_add_sge_64bit_1078 - Place a simple 64 bit SGE at address pAddr (1078 workaround).
1027 * @pAddr: virtual address for SGE
1028 * @flagslength: SGE flags and data transfer length
1029 * @dma_addr: Physical address
1031 * This routine places a MPT request frame back on the MPT adapter's
1035 mpt_add_sge_64bit_1078(void *pAddr
, u32 flagslength
, dma_addr_t dma_addr
)
1037 SGESimple64_t
*pSge
= (SGESimple64_t
*) pAddr
;
1040 pSge
->Address
.Low
= cpu_to_le32
1041 (lower_32_bits((unsigned long)(dma_addr
)));
1042 tmp
= (u32
)(upper_32_bits((unsigned long)dma_addr
));
1045 * 1078 errata workaround for the 36GB limitation
1047 if ((((u64
)dma_addr
+ MPI_SGE_LENGTH(flagslength
)) >> 32) == 9) {
1049 MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_LOCAL_ADDRESS
);
1051 if (mpt_debug_level
& MPT_DEBUG_36GB_MEM
)
1052 printk(KERN_DEBUG
"1078 P0M2 addressing for "
1053 "addr = 0x%llx len = %d\n",
1054 (unsigned long long)dma_addr
,
1055 MPI_SGE_LENGTH(flagslength
));
1058 pSge
->Address
.High
= cpu_to_le32(tmp
);
1059 pSge
->FlagsLength
= cpu_to_le32(
1060 (flagslength
| MPT_SGE_FLAGS_64_BIT_ADDRESSING
));
1063 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1065 * mpt_add_chain - Place a 32 bit chain SGE at address pAddr.
1066 * @pAddr: virtual address for SGE
1067 * @next: nextChainOffset value (u32's)
1068 * @length: length of next SGL segment
1069 * @dma_addr: Physical address
1073 mpt_add_chain(void *pAddr
, u8 next
, u16 length
, dma_addr_t dma_addr
)
1075 SGEChain32_t
*pChain
= (SGEChain32_t
*) pAddr
;
1076 pChain
->Length
= cpu_to_le16(length
);
1077 pChain
->Flags
= MPI_SGE_FLAGS_CHAIN_ELEMENT
;
1078 pChain
->NextChainOffset
= next
;
1079 pChain
->Address
= cpu_to_le32(dma_addr
);
1082 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1084 * mpt_add_chain_64bit - Place a 64 bit chain SGE at address pAddr.
1085 * @pAddr: virtual address for SGE
1086 * @next: nextChainOffset value (u32's)
1087 * @length: length of next SGL segment
1088 * @dma_addr: Physical address
1092 mpt_add_chain_64bit(void *pAddr
, u8 next
, u16 length
, dma_addr_t dma_addr
)
1094 SGEChain64_t
*pChain
= (SGEChain64_t
*) pAddr
;
1095 u32 tmp
= dma_addr
& 0xFFFFFFFF;
1097 pChain
->Length
= cpu_to_le16(length
);
1098 pChain
->Flags
= (MPI_SGE_FLAGS_CHAIN_ELEMENT
|
1099 MPI_SGE_FLAGS_64_BIT_ADDRESSING
);
1101 pChain
->NextChainOffset
= next
;
1103 pChain
->Address
.Low
= cpu_to_le32(tmp
);
1104 tmp
= (u32
)(upper_32_bits((unsigned long)dma_addr
));
1105 pChain
->Address
.High
= cpu_to_le32(tmp
);
1108 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1110 * mpt_send_handshake_request - Send MPT request via doorbell handshake method.
1111 * @cb_idx: Handle of registered MPT protocol driver
1112 * @ioc: Pointer to MPT adapter structure
1113 * @reqBytes: Size of the request in bytes
1114 * @req: Pointer to MPT request frame
1115 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1117 * This routine is used exclusively to send MptScsiTaskMgmt
1118 * requests since they are required to be sent via doorbell handshake.
1120 * NOTE: It is the callers responsibility to byte-swap fields in the
1121 * request which are greater than 1 byte in size.
1123 * Returns 0 for success, non-zero for failure.
1126 mpt_send_handshake_request(u8 cb_idx
, MPT_ADAPTER
*ioc
, int reqBytes
, u32
*req
, int sleepFlag
)
1132 /* State is known to be good upon entering
1133 * this function so issue the bus reset
1138 * Emulate what mpt_put_msg_frame() does /wrt to sanity
1139 * setting cb_idx/req_idx. But ONLY if this request
1140 * is in proper (pre-alloc'd) request buffer range...
1142 ii
= MFPTR_2_MPT_INDEX(ioc
,(MPT_FRAME_HDR
*)req
);
1143 if (reqBytes
>= 12 && ii
>= 0 && ii
< ioc
->req_depth
) {
1144 MPT_FRAME_HDR
*mf
= (MPT_FRAME_HDR
*)req
;
1145 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(ii
);
1146 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= cb_idx
;
1149 /* Make sure there are no doorbells */
1150 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1152 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
,
1153 ((MPI_FUNCTION_HANDSHAKE
<<MPI_DOORBELL_FUNCTION_SHIFT
) |
1154 ((reqBytes
/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT
)));
1156 /* Wait for IOC doorbell int */
1157 if ((ii
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0) {
1161 /* Read doorbell and check for active bit */
1162 if (!(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & MPI_DOORBELL_ACTIVE
))
1165 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"mpt_send_handshake_request start, WaitCnt=%d\n",
1168 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1170 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0) {
1174 /* Send request via doorbell handshake */
1175 req_as_bytes
= (u8
*) req
;
1176 for (ii
= 0; ii
< reqBytes
/4; ii
++) {
1179 word
= ((req_as_bytes
[(ii
*4) + 0] << 0) |
1180 (req_as_bytes
[(ii
*4) + 1] << 8) |
1181 (req_as_bytes
[(ii
*4) + 2] << 16) |
1182 (req_as_bytes
[(ii
*4) + 3] << 24));
1183 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, word
);
1184 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0) {
1190 if (r
>= 0 && WaitForDoorbellInt(ioc
, 10, sleepFlag
) >= 0)
1195 /* Make sure there are no doorbells */
1196 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1201 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1203 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
1204 * @ioc: Pointer to MPT adapter structure
1205 * @access_control_value: define bits below
1206 * @sleepFlag: Specifies whether the process can sleep
1208 * Provides mechanism for the host driver to control the IOC's
1209 * Host Page Buffer access.
1211 * Access Control Value - bits[15:12]
1213 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1214 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1215 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1217 * Returns 0 for success, non-zero for failure.
1221 mpt_host_page_access_control(MPT_ADAPTER
*ioc
, u8 access_control_value
, int sleepFlag
)
1225 /* return if in use */
1226 if (CHIPREG_READ32(&ioc
->chip
->Doorbell
)
1227 & MPI_DOORBELL_ACTIVE
)
1230 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1232 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
,
1233 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1234 <<MPI_DOORBELL_FUNCTION_SHIFT
) |
1235 (access_control_value
<<12)));
1237 /* Wait for IOC to clear Doorbell Status bit */
1238 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0) {
1244 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1246 * mpt_host_page_alloc - allocate system memory for the fw
1247 * @ioc: Pointer to pointer to IOC adapter
1248 * @ioc_init: Pointer to ioc init config page
1250 * If we already allocated memory in past, then resend the same pointer.
1251 * Returns 0 for success, non-zero for failure.
1254 mpt_host_page_alloc(MPT_ADAPTER
*ioc
, pIOCInit_t ioc_init
)
1258 u32 host_page_buffer_sz
=0;
1260 if(!ioc
->HostPageBuffer
) {
1262 host_page_buffer_sz
=
1263 le32_to_cpu(ioc
->facts
.HostPageBufferSGE
.FlagsLength
) & 0xFFFFFF;
1265 if(!host_page_buffer_sz
)
1266 return 0; /* fw doesn't need any host buffers */
1268 /* spin till we get enough memory */
1269 while(host_page_buffer_sz
> 0) {
1271 if((ioc
->HostPageBuffer
= pci_alloc_consistent(
1273 host_page_buffer_sz
,
1274 &ioc
->HostPageBuffer_dma
)) != NULL
) {
1276 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
1277 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1278 ioc
->name
, ioc
->HostPageBuffer
,
1279 (u32
)ioc
->HostPageBuffer_dma
,
1280 host_page_buffer_sz
));
1281 ioc
->alloc_total
+= host_page_buffer_sz
;
1282 ioc
->HostPageBuffer_sz
= host_page_buffer_sz
;
1286 host_page_buffer_sz
-= (4*1024);
1290 if(!ioc
->HostPageBuffer
) {
1291 printk(MYIOC_s_ERR_FMT
1292 "Failed to alloc memory for host_page_buffer!\n",
1297 psge
= (char *)&ioc_init
->HostPageBufferSGE
;
1298 flags_length
= MPI_SGE_FLAGS_SIMPLE_ELEMENT
|
1299 MPI_SGE_FLAGS_SYSTEM_ADDRESS
|
1300 MPI_SGE_FLAGS_32_BIT_ADDRESSING
|
1301 MPI_SGE_FLAGS_HOST_TO_IOC
|
1302 MPI_SGE_FLAGS_END_OF_BUFFER
;
1303 if (sizeof(dma_addr_t
) == sizeof(u64
)) {
1304 flags_length
|= MPI_SGE_FLAGS_64_BIT_ADDRESSING
;
1306 flags_length
= flags_length
<< MPI_SGE_FLAGS_SHIFT
;
1307 flags_length
|= ioc
->HostPageBuffer_sz
;
1308 ioc
->add_sge(psge
, flags_length
, ioc
->HostPageBuffer_dma
);
1309 ioc
->facts
.HostPageBufferSGE
= ioc_init
->HostPageBufferSGE
;
1314 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1316 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1317 * @iocid: IOC unique identifier (integer)
1318 * @iocpp: Pointer to pointer to IOC adapter
1320 * Given a unique IOC identifier, set pointer to the associated MPT
1321 * adapter structure.
1323 * Returns iocid and sets iocpp if iocid is found.
1324 * Returns -1 if iocid is not found.
1327 mpt_verify_adapter(int iocid
, MPT_ADAPTER
**iocpp
)
1331 list_for_each_entry(ioc
,&ioc_list
,list
) {
1332 if (ioc
->id
== iocid
) {
1343 * mpt_get_product_name - returns product string
1344 * @vendor: pci vendor id
1345 * @device: pci device id
1346 * @revision: pci revision id
1347 * @prod_name: string returned
1349 * Returns product string displayed when driver loads,
1350 * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1354 mpt_get_product_name(u16 vendor
, u16 device
, u8 revision
, char *prod_name
)
1356 char *product_str
= NULL
;
1358 if (vendor
== PCI_VENDOR_ID_BROCADE
) {
1361 case MPI_MANUFACTPAGE_DEVICEID_FC949E
:
1365 product_str
= "BRE040 A0";
1368 product_str
= "BRE040 A1";
1371 product_str
= "BRE040";
1381 case MPI_MANUFACTPAGE_DEVICEID_FC909
:
1382 product_str
= "LSIFC909 B1";
1384 case MPI_MANUFACTPAGE_DEVICEID_FC919
:
1385 product_str
= "LSIFC919 B0";
1387 case MPI_MANUFACTPAGE_DEVICEID_FC929
:
1388 product_str
= "LSIFC929 B0";
1390 case MPI_MANUFACTPAGE_DEVICEID_FC919X
:
1391 if (revision
< 0x80)
1392 product_str
= "LSIFC919X A0";
1394 product_str
= "LSIFC919XL A1";
1396 case MPI_MANUFACTPAGE_DEVICEID_FC929X
:
1397 if (revision
< 0x80)
1398 product_str
= "LSIFC929X A0";
1400 product_str
= "LSIFC929XL A1";
1402 case MPI_MANUFACTPAGE_DEVICEID_FC939X
:
1403 product_str
= "LSIFC939X A1";
1405 case MPI_MANUFACTPAGE_DEVICEID_FC949X
:
1406 product_str
= "LSIFC949X A1";
1408 case MPI_MANUFACTPAGE_DEVICEID_FC949E
:
1412 product_str
= "LSIFC949E A0";
1415 product_str
= "LSIFC949E A1";
1418 product_str
= "LSIFC949E";
1422 case MPI_MANUFACTPAGE_DEVID_53C1030
:
1426 product_str
= "LSI53C1030 A0";
1429 product_str
= "LSI53C1030 B0";
1432 product_str
= "LSI53C1030 B1";
1435 product_str
= "LSI53C1030 B2";
1438 product_str
= "LSI53C1030 C0";
1441 product_str
= "LSI53C1030T A0";
1444 product_str
= "LSI53C1030T A2";
1447 product_str
= "LSI53C1030T A3";
1450 product_str
= "LSI53C1020A A1";
1453 product_str
= "LSI53C1030";
1457 case MPI_MANUFACTPAGE_DEVID_1030_53C1035
:
1461 product_str
= "LSI53C1035 A2";
1464 product_str
= "LSI53C1035 B0";
1467 product_str
= "LSI53C1035";
1471 case MPI_MANUFACTPAGE_DEVID_SAS1064
:
1475 product_str
= "LSISAS1064 A1";
1478 product_str
= "LSISAS1064 A2";
1481 product_str
= "LSISAS1064 A3";
1484 product_str
= "LSISAS1064 A4";
1487 product_str
= "LSISAS1064";
1491 case MPI_MANUFACTPAGE_DEVID_SAS1064E
:
1495 product_str
= "LSISAS1064E A0";
1498 product_str
= "LSISAS1064E B0";
1501 product_str
= "LSISAS1064E B1";
1504 product_str
= "LSISAS1064E B2";
1507 product_str
= "LSISAS1064E B3";
1510 product_str
= "LSISAS1064E";
1514 case MPI_MANUFACTPAGE_DEVID_SAS1068
:
1518 product_str
= "LSISAS1068 A0";
1521 product_str
= "LSISAS1068 B0";
1524 product_str
= "LSISAS1068 B1";
1527 product_str
= "LSISAS1068";
1531 case MPI_MANUFACTPAGE_DEVID_SAS1068E
:
1535 product_str
= "LSISAS1068E A0";
1538 product_str
= "LSISAS1068E B0";
1541 product_str
= "LSISAS1068E B1";
1544 product_str
= "LSISAS1068E B2";
1547 product_str
= "LSISAS1068E B3";
1550 product_str
= "LSISAS1068E";
1554 case MPI_MANUFACTPAGE_DEVID_SAS1078
:
1558 product_str
= "LSISAS1078 A0";
1561 product_str
= "LSISAS1078 B0";
1564 product_str
= "LSISAS1078 C0";
1567 product_str
= "LSISAS1078 C1";
1570 product_str
= "LSISAS1078 C2";
1573 product_str
= "LSISAS1078";
1581 sprintf(prod_name
, "%s", product_str
);
1585 * mpt_mapresources - map in memory mapped io
1586 * @ioc: Pointer to pointer to IOC adapter
1590 mpt_mapresources(MPT_ADAPTER
*ioc
)
1594 unsigned long mem_phys
;
1600 struct pci_dev
*pdev
;
1603 ioc
->bars
= pci_select_bars(pdev
, IORESOURCE_MEM
);
1604 if (pci_enable_device_mem(pdev
)) {
1605 printk(MYIOC_s_ERR_FMT
"pci_enable_device_mem() "
1606 "failed\n", ioc
->name
);
1609 if (pci_request_selected_regions(pdev
, ioc
->bars
, "mpt")) {
1610 printk(MYIOC_s_ERR_FMT
"pci_request_selected_regions() with "
1611 "MEM failed\n", ioc
->name
);
1615 pci_read_config_byte(pdev
, PCI_CLASS_REVISION
, &revision
);
1617 if (sizeof(dma_addr_t
) > 4) {
1618 const uint64_t required_mask
= dma_get_required_mask
1620 if (required_mask
> DMA_BIT_MASK(32)
1621 && !pci_set_dma_mask(pdev
, DMA_BIT_MASK(64))
1622 && !pci_set_consistent_dma_mask(pdev
,
1623 DMA_BIT_MASK(64))) {
1624 ioc
->dma_mask
= DMA_BIT_MASK(64);
1625 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
1626 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1628 } else if (!pci_set_dma_mask(pdev
, DMA_BIT_MASK(32))
1629 && !pci_set_consistent_dma_mask(pdev
,
1630 DMA_BIT_MASK(32))) {
1631 ioc
->dma_mask
= DMA_BIT_MASK(32);
1632 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
1633 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1636 printk(MYIOC_s_WARN_FMT
"no suitable DMA mask for %s\n",
1637 ioc
->name
, pci_name(pdev
));
1641 if (!pci_set_dma_mask(pdev
, DMA_BIT_MASK(32))
1642 && !pci_set_consistent_dma_mask(pdev
,
1643 DMA_BIT_MASK(32))) {
1644 ioc
->dma_mask
= DMA_BIT_MASK(32);
1645 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
1646 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1649 printk(MYIOC_s_WARN_FMT
"no suitable DMA mask for %s\n",
1650 ioc
->name
, pci_name(pdev
));
1655 mem_phys
= msize
= 0;
1657 for (ii
= 0; ii
< DEVICE_COUNT_RESOURCE
; ii
++) {
1658 if (pci_resource_flags(pdev
, ii
) & PCI_BASE_ADDRESS_SPACE_IO
) {
1661 /* Get I/O space! */
1662 port
= pci_resource_start(pdev
, ii
);
1663 psize
= pci_resource_len(pdev
, ii
);
1668 mem_phys
= pci_resource_start(pdev
, ii
);
1669 msize
= pci_resource_len(pdev
, ii
);
1672 ioc
->mem_size
= msize
;
1675 /* Get logical ptr for PciMem0 space */
1676 /*mem = ioremap(mem_phys, msize);*/
1677 mem
= ioremap(mem_phys
, msize
);
1679 printk(MYIOC_s_ERR_FMT
": ERROR - Unable to map adapter"
1680 " memory!\n", ioc
->name
);
1684 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"mem = %p, mem_phys = %lx\n",
1685 ioc
->name
, mem
, mem_phys
));
1687 ioc
->mem_phys
= mem_phys
;
1688 ioc
->chip
= (SYSIF_REGS __iomem
*)mem
;
1690 /* Save Port IO values in case we need to do downloadboot */
1691 ioc
->pio_mem_phys
= port
;
1692 ioc
->pio_chip
= (SYSIF_REGS __iomem
*)port
;
1697 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1699 * mpt_attach - Install a PCI intelligent MPT adapter.
1700 * @pdev: Pointer to pci_dev structure
1701 * @id: PCI device ID information
1703 * This routine performs all the steps necessary to bring the IOC of
1704 * a MPT adapter to a OPERATIONAL state. This includes registering
1705 * memory regions, registering the interrupt, and allocating request
1706 * and reply memory pools.
1708 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1711 * Returns 0 for success, non-zero for failure.
1713 * TODO: Add support for polled controllers
1716 mpt_attach(struct pci_dev
*pdev
, const struct pci_device_id
*id
)
1723 static int mpt_ids
= 0;
1724 #ifdef CONFIG_PROC_FS
1725 struct proc_dir_entry
*dent
, *ent
;
1728 ioc
= kzalloc(sizeof(MPT_ADAPTER
), GFP_ATOMIC
);
1730 printk(KERN_ERR MYNAM
": ERROR - Insufficient memory to add adapter!\n");
1734 ioc
->id
= mpt_ids
++;
1735 sprintf(ioc
->name
, "ioc%d", ioc
->id
);
1736 dinitprintk(ioc
, printk(KERN_WARNING MYNAM
": mpt_adapter_install\n"));
1739 * set initial debug level
1740 * (refer to mptdebug.h)
1743 ioc
->debug_level
= mpt_debug_level
;
1744 if (mpt_debug_level
)
1745 printk(KERN_INFO
"mpt_debug_level=%xh\n", mpt_debug_level
);
1747 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
": mpt_adapter_install\n", ioc
->name
));
1750 if (mpt_mapresources(ioc
)) {
1756 * Setting up proper handlers for scatter gather handling
1758 if (ioc
->dma_mask
== DMA_BIT_MASK(64)) {
1759 if (pdev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1078
)
1760 ioc
->add_sge
= &mpt_add_sge_64bit_1078
;
1762 ioc
->add_sge
= &mpt_add_sge_64bit
;
1763 ioc
->add_chain
= &mpt_add_chain_64bit
;
1764 ioc
->sg_addr_size
= 8;
1766 ioc
->add_sge
= &mpt_add_sge
;
1767 ioc
->add_chain
= &mpt_add_chain
;
1768 ioc
->sg_addr_size
= 4;
1770 ioc
->SGE_size
= sizeof(u32
) + ioc
->sg_addr_size
;
1772 ioc
->alloc_total
= sizeof(MPT_ADAPTER
);
1773 ioc
->req_sz
= MPT_DEFAULT_FRAME_SIZE
; /* avoid div by zero! */
1774 ioc
->reply_sz
= MPT_REPLY_FRAME_SIZE
;
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 /* Initilize 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;
1919 if (ioc
->errata_flag_1064
)
1920 pci_disable_io_access(pdev
);
1922 spin_lock_init(&ioc
->FreeQlock
);
1925 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
1927 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1929 /* Set IOC ptr in the pcidev's driver data. */
1930 pci_set_drvdata(ioc
->pcidev
, ioc
);
1932 /* Set lookup ptr. */
1933 list_add_tail(&ioc
->list
, &ioc_list
);
1935 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1937 mpt_detect_bound_ports(ioc
, pdev
);
1939 INIT_LIST_HEAD(&ioc
->fw_event_list
);
1940 spin_lock_init(&ioc
->fw_event_lock
);
1941 snprintf(ioc
->fw_event_q_name
, MPT_KOBJ_NAME_LEN
, "mpt/%d", ioc
->id
);
1942 ioc
->fw_event_q
= create_singlethread_workqueue(ioc
->fw_event_q_name
);
1944 if ((r
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_BRINGUP
,
1946 printk(MYIOC_s_ERR_FMT
"didn't initialize properly! (%d)\n",
1949 list_del(&ioc
->list
);
1951 ioc
->alt_ioc
->alt_ioc
= NULL
;
1952 iounmap(ioc
->memmap
);
1954 pci_release_selected_regions(pdev
, ioc
->bars
);
1956 destroy_workqueue(ioc
->reset_work_q
);
1957 ioc
->reset_work_q
= NULL
;
1960 pci_set_drvdata(pdev
, NULL
);
1964 /* call per device driver probe entry point */
1965 for(cb_idx
= 0; cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
; cb_idx
++) {
1966 if(MptDeviceDriverHandlers
[cb_idx
] &&
1967 MptDeviceDriverHandlers
[cb_idx
]->probe
) {
1968 MptDeviceDriverHandlers
[cb_idx
]->probe(pdev
,id
);
1972 #ifdef CONFIG_PROC_FS
1974 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1976 dent
= proc_mkdir(ioc
->name
, mpt_proc_root_dir
);
1978 ent
= create_proc_entry("info", S_IFREG
|S_IRUGO
, dent
);
1980 ent
->read_proc
= procmpt_iocinfo_read
;
1983 ent
= create_proc_entry("summary", S_IFREG
|S_IRUGO
, dent
);
1985 ent
->read_proc
= procmpt_summary_read
;
1992 queue_delayed_work(ioc
->reset_work_q
, &ioc
->fault_reset_work
,
1993 msecs_to_jiffies(MPT_POLLING_INTERVAL
));
1998 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2000 * mpt_detach - Remove a PCI intelligent MPT adapter.
2001 * @pdev: Pointer to pci_dev structure
2005 mpt_detach(struct pci_dev
*pdev
)
2007 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
2010 unsigned long flags
;
2011 struct workqueue_struct
*wq
;
2014 * Stop polling ioc for fault condition
2016 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
2017 wq
= ioc
->reset_work_q
;
2018 ioc
->reset_work_q
= NULL
;
2019 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
2020 cancel_delayed_work(&ioc
->fault_reset_work
);
2021 destroy_workqueue(wq
);
2023 spin_lock_irqsave(&ioc
->fw_event_lock
, flags
);
2024 wq
= ioc
->fw_event_q
;
2025 ioc
->fw_event_q
= NULL
;
2026 spin_unlock_irqrestore(&ioc
->fw_event_lock
, flags
);
2027 destroy_workqueue(wq
);
2029 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s/summary", ioc
->name
);
2030 remove_proc_entry(pname
, NULL
);
2031 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s/info", ioc
->name
);
2032 remove_proc_entry(pname
, NULL
);
2033 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s", ioc
->name
);
2034 remove_proc_entry(pname
, NULL
);
2036 /* call per device driver remove entry point */
2037 for(cb_idx
= 0; cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
; cb_idx
++) {
2038 if(MptDeviceDriverHandlers
[cb_idx
] &&
2039 MptDeviceDriverHandlers
[cb_idx
]->remove
) {
2040 MptDeviceDriverHandlers
[cb_idx
]->remove(pdev
);
2044 /* Disable interrupts! */
2045 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2048 synchronize_irq(pdev
->irq
);
2050 /* Clear any lingering interrupt */
2051 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
2053 CHIPREG_READ32(&ioc
->chip
->IntStatus
);
2055 mpt_adapter_dispose(ioc
);
2057 pci_set_drvdata(pdev
, NULL
);
2060 /**************************************************************************
2064 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2066 * mpt_suspend - Fusion MPT base driver suspend routine.
2067 * @pdev: Pointer to pci_dev structure
2068 * @state: new state to enter
2071 mpt_suspend(struct pci_dev
*pdev
, pm_message_t state
)
2074 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
2076 device_state
= pci_choose_state(pdev
, state
);
2077 printk(MYIOC_s_INFO_FMT
"pci-suspend: pdev=0x%p, slot=%s, Entering "
2078 "operating state [D%d]\n", ioc
->name
, pdev
, pci_name(pdev
),
2081 /* put ioc into READY_STATE */
2082 if(SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, CAN_SLEEP
)) {
2083 printk(MYIOC_s_ERR_FMT
2084 "pci-suspend: IOC msg unit reset failed!\n", ioc
->name
);
2087 /* disable interrupts */
2088 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2091 /* Clear any lingering interrupt */
2092 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
2094 free_irq(ioc
->pci_irq
, ioc
);
2095 if (ioc
->msi_enable
)
2096 pci_disable_msi(ioc
->pcidev
);
2098 pci_save_state(pdev
);
2099 pci_disable_device(pdev
);
2100 pci_release_selected_regions(pdev
, ioc
->bars
);
2101 pci_set_power_state(pdev
, device_state
);
2105 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2107 * mpt_resume - Fusion MPT base driver resume routine.
2108 * @pdev: Pointer to pci_dev structure
2111 mpt_resume(struct pci_dev
*pdev
)
2113 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
2114 u32 device_state
= pdev
->current_state
;
2118 printk(MYIOC_s_INFO_FMT
"pci-resume: pdev=0x%p, slot=%s, Previous "
2119 "operating state [D%d]\n", ioc
->name
, pdev
, pci_name(pdev
),
2122 pci_set_power_state(pdev
, PCI_D0
);
2123 pci_enable_wake(pdev
, PCI_D0
, 0);
2124 pci_restore_state(pdev
);
2126 err
= mpt_mapresources(ioc
);
2130 if (ioc
->dma_mask
== DMA_BIT_MASK(64)) {
2131 if (pdev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1078
)
2132 ioc
->add_sge
= &mpt_add_sge_64bit_1078
;
2134 ioc
->add_sge
= &mpt_add_sge_64bit
;
2135 ioc
->add_chain
= &mpt_add_chain_64bit
;
2136 ioc
->sg_addr_size
= 8;
2139 ioc
->add_sge
= &mpt_add_sge
;
2140 ioc
->add_chain
= &mpt_add_chain
;
2141 ioc
->sg_addr_size
= 4;
2143 ioc
->SGE_size
= sizeof(u32
) + ioc
->sg_addr_size
;
2145 printk(MYIOC_s_INFO_FMT
"pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
2146 ioc
->name
, (mpt_GetIocState(ioc
, 1) >> MPI_IOC_STATE_SHIFT
),
2147 CHIPREG_READ32(&ioc
->chip
->Doorbell
));
2150 * Errata workaround for SAS pci express:
2151 * Upon returning to the D0 state, the contents of the doorbell will be
2152 * stale data, and this will incorrectly signal to the host driver that
2153 * the firmware is ready to process mpt commands. The workaround is
2154 * to issue a diagnostic reset.
2156 if (ioc
->bus_type
== SAS
&& (pdev
->device
==
2157 MPI_MANUFACTPAGE_DEVID_SAS1068E
|| pdev
->device
==
2158 MPI_MANUFACTPAGE_DEVID_SAS1064E
)) {
2159 if (KickStart(ioc
, 1, CAN_SLEEP
) < 0) {
2160 printk(MYIOC_s_WARN_FMT
"pci-resume: Cannot recover\n",
2166 /* bring ioc to operational state */
2167 printk(MYIOC_s_INFO_FMT
"Sending mpt_do_ioc_recovery\n", ioc
->name
);
2168 recovery_state
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_BRINGUP
,
2170 if (recovery_state
!= 0)
2171 printk(MYIOC_s_WARN_FMT
"pci-resume: Cannot recover, "
2172 "error:[%x]\n", ioc
->name
, recovery_state
);
2174 printk(MYIOC_s_INFO_FMT
2175 "pci-resume: success\n", ioc
->name
);
2183 mpt_signal_reset(u8 index
, MPT_ADAPTER
*ioc
, int reset_phase
)
2185 if ((MptDriverClass
[index
] == MPTSPI_DRIVER
&&
2186 ioc
->bus_type
!= SPI
) ||
2187 (MptDriverClass
[index
] == MPTFC_DRIVER
&&
2188 ioc
->bus_type
!= FC
) ||
2189 (MptDriverClass
[index
] == MPTSAS_DRIVER
&&
2190 ioc
->bus_type
!= SAS
))
2191 /* make sure we only call the relevant reset handler
2194 return (MptResetHandlers
[index
])(ioc
, reset_phase
);
2197 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2199 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
2200 * @ioc: Pointer to MPT adapter structure
2201 * @reason: Event word / reason
2202 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
2204 * This routine performs all the steps necessary to bring the IOC
2205 * to a OPERATIONAL state.
2207 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
2212 * -1 if failed to get board READY
2213 * -2 if READY but IOCFacts Failed
2214 * -3 if READY but PrimeIOCFifos Failed
2215 * -4 if READY but IOCInit Failed
2216 * -5 if failed to enable_device and/or request_selected_regions
2217 * -6 if failed to upload firmware
2220 mpt_do_ioc_recovery(MPT_ADAPTER
*ioc
, u32 reason
, int sleepFlag
)
2222 int hard_reset_done
= 0;
2223 int alt_ioc_ready
= 0;
2230 int reset_alt_ioc_active
= 0;
2231 int irq_allocated
= 0;
2234 printk(MYIOC_s_INFO_FMT
"Initiating %s\n", ioc
->name
,
2235 reason
== MPT_HOSTEVENT_IOC_BRINGUP
? "bringup" : "recovery");
2237 /* Disable reply interrupts (also blocks FreeQ) */
2238 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2242 if (ioc
->alt_ioc
->active
||
2243 reason
== MPT_HOSTEVENT_IOC_RECOVER
) {
2244 reset_alt_ioc_active
= 1;
2245 /* Disable alt-IOC's reply interrupts
2246 * (and FreeQ) for a bit
2248 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
,
2250 ioc
->alt_ioc
->active
= 0;
2255 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)
2258 if ((hard_reset_done
= MakeIocReady(ioc
, hard
, sleepFlag
)) < 0) {
2259 if (hard_reset_done
== -4) {
2260 printk(MYIOC_s_WARN_FMT
"Owned by PEER..skipping!\n",
2263 if (reset_alt_ioc_active
&& ioc
->alt_ioc
) {
2264 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
2265 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
2266 "alt_ioc reply irq re-enabled\n", ioc
->alt_ioc
->name
));
2267 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
, MPI_HIM_DIM
);
2268 ioc
->alt_ioc
->active
= 1;
2272 printk(MYIOC_s_WARN_FMT
2273 "NOT READY WARNING!\n", ioc
->name
);
2279 /* hard_reset_done = 0 if a soft reset was performed
2280 * and 1 if a hard reset was performed.
2282 if (hard_reset_done
&& reset_alt_ioc_active
&& ioc
->alt_ioc
) {
2283 if ((rc
= MakeIocReady(ioc
->alt_ioc
, 0, sleepFlag
)) == 0)
2286 printk(MYIOC_s_WARN_FMT
2287 ": alt-ioc Not ready WARNING!\n",
2288 ioc
->alt_ioc
->name
);
2291 for (ii
=0; ii
<5; ii
++) {
2292 /* Get IOC facts! Allow 5 retries */
2293 if ((rc
= GetIocFacts(ioc
, sleepFlag
, reason
)) == 0)
2299 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2300 "Retry IocFacts failed rc=%x\n", ioc
->name
, rc
));
2302 } else if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
2303 MptDisplayIocCapabilities(ioc
);
2306 if (alt_ioc_ready
) {
2307 if ((rc
= GetIocFacts(ioc
->alt_ioc
, sleepFlag
, reason
)) != 0) {
2308 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2309 "Initial Alt IocFacts failed rc=%x\n",
2311 /* Retry - alt IOC was initialized once
2313 rc
= GetIocFacts(ioc
->alt_ioc
, sleepFlag
, reason
);
2316 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2317 "Retry Alt IocFacts failed rc=%x\n", ioc
->name
, rc
));
2319 reset_alt_ioc_active
= 0;
2320 } else if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
2321 MptDisplayIocCapabilities(ioc
->alt_ioc
);
2325 if ((ret
== 0) && (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) &&
2326 (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)) {
2327 pci_release_selected_regions(ioc
->pcidev
, ioc
->bars
);
2328 ioc
->bars
= pci_select_bars(ioc
->pcidev
, IORESOURCE_MEM
|
2330 if (pci_enable_device(ioc
->pcidev
))
2332 if (pci_request_selected_regions(ioc
->pcidev
, ioc
->bars
,
2338 * Device is reset now. It must have de-asserted the interrupt line
2339 * (if it was asserted) and it should be safe to register for the
2342 if ((ret
== 0) && (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)) {
2344 if (ioc
->pcidev
->irq
) {
2345 if (ioc
->msi_enable
&& !pci_enable_msi(ioc
->pcidev
))
2346 printk(MYIOC_s_INFO_FMT
"PCI-MSI enabled\n",
2349 ioc
->msi_enable
= 0;
2350 rc
= request_irq(ioc
->pcidev
->irq
, mpt_interrupt
,
2351 IRQF_SHARED
, ioc
->name
, ioc
);
2353 printk(MYIOC_s_ERR_FMT
"Unable to allocate "
2355 ioc
->name
, ioc
->pcidev
->irq
);
2356 if (ioc
->msi_enable
)
2357 pci_disable_msi(ioc
->pcidev
);
2362 ioc
->pci_irq
= ioc
->pcidev
->irq
;
2363 pci_set_master(ioc
->pcidev
); /* ?? */
2364 pci_set_drvdata(ioc
->pcidev
, ioc
);
2365 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
2366 "installed at interrupt %d\n", ioc
->name
,
2371 /* Prime reply & request queues!
2372 * (mucho alloc's) Must be done prior to
2373 * init as upper addresses are needed for init.
2374 * If fails, continue with alt-ioc processing
2376 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"PrimeIocFifos\n",
2378 if ((ret
== 0) && ((rc
= PrimeIocFifos(ioc
)) != 0))
2381 /* May need to check/upload firmware & data here!
2382 * If fails, continue with alt-ioc processing
2384 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"SendIocInit\n",
2386 if ((ret
== 0) && ((rc
= SendIocInit(ioc
, sleepFlag
)) != 0))
2389 if (alt_ioc_ready
&& ((rc
= PrimeIocFifos(ioc
->alt_ioc
)) != 0)) {
2390 printk(MYIOC_s_WARN_FMT
2391 ": alt-ioc (%d) FIFO mgmt alloc WARNING!\n",
2392 ioc
->alt_ioc
->name
, rc
);
2394 reset_alt_ioc_active
= 0;
2397 if (alt_ioc_ready
) {
2398 if ((rc
= SendIocInit(ioc
->alt_ioc
, sleepFlag
)) != 0) {
2400 reset_alt_ioc_active
= 0;
2401 printk(MYIOC_s_WARN_FMT
2402 ": alt-ioc: (%d) init failure WARNING!\n",
2403 ioc
->alt_ioc
->name
, rc
);
2407 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
){
2408 if (ioc
->upload_fw
) {
2409 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2410 "firmware upload required!\n", ioc
->name
));
2412 /* Controller is not operational, cannot do upload
2415 rc
= mpt_do_upload(ioc
, sleepFlag
);
2417 if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
) {
2419 * Maintain only one pointer to FW memory
2420 * so there will not be two attempt to
2421 * downloadboot onboard dual function
2422 * chips (mpt_adapter_disable,
2425 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2426 "mpt_upload: alt_%s has cached_fw=%p \n",
2427 ioc
->name
, ioc
->alt_ioc
->name
, ioc
->alt_ioc
->cached_fw
));
2428 ioc
->cached_fw
= NULL
;
2431 printk(MYIOC_s_WARN_FMT
2432 "firmware upload failure!\n", ioc
->name
);
2439 /* Enable MPT base driver management of EventNotification
2440 * and EventAck handling.
2442 if ((ret
== 0) && (!ioc
->facts
.EventState
)) {
2443 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
2444 "SendEventNotification\n",
2446 ret
= SendEventNotification(ioc
, 1, sleepFlag
); /* 1=Enable */
2449 if (ioc
->alt_ioc
&& alt_ioc_ready
&& !ioc
->alt_ioc
->facts
.EventState
)
2450 rc
= SendEventNotification(ioc
->alt_ioc
, 1, sleepFlag
);
2453 /* Enable! (reply interrupt) */
2454 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, MPI_HIM_DIM
);
2457 if (rc
== 0) { /* alt ioc */
2458 if (reset_alt_ioc_active
&& ioc
->alt_ioc
) {
2459 /* (re)Enable alt-IOC! (reply interrupt) */
2460 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"alt-ioc"
2461 "reply irq re-enabled\n",
2462 ioc
->alt_ioc
->name
));
2463 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
,
2465 ioc
->alt_ioc
->active
= 1;
2470 /* Add additional "reason" check before call to GetLanConfigPages
2471 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2472 * recursive scenario; GetLanConfigPages times out, timer expired
2473 * routine calls HardResetHandler, which calls into here again,
2474 * and we try GetLanConfigPages again...
2476 if ((ret
== 0) && (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)) {
2479 * Initalize link list for inactive raid volumes.
2481 mutex_init(&ioc
->raid_data
.inactive_list_mutex
);
2482 INIT_LIST_HEAD(&ioc
->raid_data
.inactive_list
);
2484 switch (ioc
->bus_type
) {
2487 /* clear persistency table */
2488 if(ioc
->facts
.IOCExceptions
&
2489 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL
) {
2490 ret
= mptbase_sas_persist_operation(ioc
,
2491 MPI_SAS_OP_CLEAR_NOT_PRESENT
);
2498 mpt_findImVolumes(ioc
);
2500 /* Check, and possibly reset, the coalescing value
2502 mpt_read_ioc_pg_1(ioc
);
2507 if ((ioc
->pfacts
[0].ProtocolFlags
&
2508 MPI_PORTFACTS_PROTOCOL_LAN
) &&
2509 (ioc
->lan_cnfg_page0
.Header
.PageLength
== 0)) {
2511 * Pre-fetch the ports LAN MAC address!
2512 * (LANPage1_t stuff)
2514 (void) GetLanConfigPages(ioc
);
2515 a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
2516 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2517 "LanAddr = %02X:%02X:%02X"
2518 ":%02X:%02X:%02X\n",
2519 ioc
->name
, a
[5], a
[4],
2520 a
[3], a
[2], a
[1], a
[0]));
2525 /* Get NVRAM and adapter maximums from SPP 0 and 2
2527 mpt_GetScsiPortSettings(ioc
, 0);
2529 /* Get version and length of SDP 1
2531 mpt_readScsiDevicePageHeaders(ioc
, 0);
2535 if (ioc
->facts
.MsgVersion
>= MPI_VERSION_01_02
)
2536 mpt_findImVolumes(ioc
);
2538 /* Check, and possibly reset, the coalescing value
2540 mpt_read_ioc_pg_1(ioc
);
2542 mpt_read_ioc_pg_4(ioc
);
2547 GetIoUnitPage2(ioc
);
2548 mpt_get_manufacturing_pg_0(ioc
);
2552 * Call each currently registered protocol IOC reset handler
2553 * with post-reset indication.
2554 * NOTE: If we're doing _IOC_BRINGUP, there can be no
2555 * MptResetHandlers[] registered yet.
2557 if (hard_reset_done
) {
2559 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
2560 if ((ret
== 0) && MptResetHandlers
[cb_idx
]) {
2561 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2562 "Calling IOC post_reset handler #%d\n",
2563 ioc
->name
, cb_idx
));
2564 rc
+= mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_POST_RESET
);
2568 if (alt_ioc_ready
&& MptResetHandlers
[cb_idx
]) {
2569 drsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2570 "Calling IOC post_reset handler #%d\n",
2571 ioc
->alt_ioc
->name
, cb_idx
));
2572 rc
+= mpt_signal_reset(cb_idx
, ioc
->alt_ioc
, MPT_IOC_POST_RESET
);
2576 /* FIXME? Examine results here? */
2580 if ((ret
!= 0) && irq_allocated
) {
2581 free_irq(ioc
->pci_irq
, ioc
);
2582 if (ioc
->msi_enable
)
2583 pci_disable_msi(ioc
->pcidev
);
2588 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2590 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2591 * @ioc: Pointer to MPT adapter structure
2592 * @pdev: Pointer to (struct pci_dev) structure
2594 * Search for PCI bus/dev_function which matches
2595 * PCI bus/dev_function (+/-1) for newly discovered 929,
2596 * 929X, 1030 or 1035.
2598 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2599 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2602 mpt_detect_bound_ports(MPT_ADAPTER
*ioc
, struct pci_dev
*pdev
)
2604 struct pci_dev
*peer
=NULL
;
2605 unsigned int slot
= PCI_SLOT(pdev
->devfn
);
2606 unsigned int func
= PCI_FUNC(pdev
->devfn
);
2607 MPT_ADAPTER
*ioc_srch
;
2609 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"PCI device %s devfn=%x/%x,"
2610 " searching for devfn match on %x or %x\n",
2611 ioc
->name
, pci_name(pdev
), pdev
->bus
->number
,
2612 pdev
->devfn
, func
-1, func
+1));
2614 peer
= pci_get_slot(pdev
->bus
, PCI_DEVFN(slot
,func
-1));
2616 peer
= pci_get_slot(pdev
->bus
, PCI_DEVFN(slot
,func
+1));
2621 list_for_each_entry(ioc_srch
, &ioc_list
, list
) {
2622 struct pci_dev
*_pcidev
= ioc_srch
->pcidev
;
2623 if (_pcidev
== peer
) {
2624 /* Paranoia checks */
2625 if (ioc
->alt_ioc
!= NULL
) {
2626 printk(MYIOC_s_WARN_FMT
2627 "Oops, already bound (%s <==> %s)!\n",
2628 ioc
->name
, ioc
->name
, ioc
->alt_ioc
->name
);
2630 } else if (ioc_srch
->alt_ioc
!= NULL
) {
2631 printk(MYIOC_s_WARN_FMT
2632 "Oops, already bound (%s <==> %s)!\n",
2633 ioc_srch
->name
, ioc_srch
->name
,
2634 ioc_srch
->alt_ioc
->name
);
2637 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2638 "FOUND! binding %s <==> %s\n",
2639 ioc
->name
, ioc
->name
, ioc_srch
->name
));
2640 ioc_srch
->alt_ioc
= ioc
;
2641 ioc
->alt_ioc
= ioc_srch
;
2647 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2649 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2650 * @ioc: Pointer to MPT adapter structure
2653 mpt_adapter_disable(MPT_ADAPTER
*ioc
)
2658 if (ioc
->cached_fw
!= NULL
) {
2659 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2660 "%s: Pushing FW onto adapter\n", __func__
, ioc
->name
));
2661 if ((ret
= mpt_downloadboot(ioc
, (MpiFwHeader_t
*)
2662 ioc
->cached_fw
, CAN_SLEEP
)) < 0) {
2663 printk(MYIOC_s_WARN_FMT
2664 ": firmware downloadboot failure (%d)!\n",
2670 * Put the controller into ready state (if its not already)
2672 if (mpt_GetIocState(ioc
, 1) != MPI_IOC_STATE_READY
) {
2673 if (!SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
,
2675 if (mpt_GetIocState(ioc
, 1) != MPI_IOC_STATE_READY
)
2676 printk(MYIOC_s_ERR_FMT
"%s: IOC msg unit "
2677 "reset failed to put ioc in ready state!\n",
2678 ioc
->name
, __func__
);
2680 printk(MYIOC_s_ERR_FMT
"%s: IOC msg unit reset "
2681 "failed!\n", ioc
->name
, __func__
);
2685 /* Disable adapter interrupts! */
2686 synchronize_irq(ioc
->pcidev
->irq
);
2687 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2690 /* Clear any lingering interrupt */
2691 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
2692 CHIPREG_READ32(&ioc
->chip
->IntStatus
);
2694 if (ioc
->alloc
!= NULL
) {
2696 dexitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"free @ %p, sz=%d bytes\n",
2697 ioc
->name
, ioc
->alloc
, ioc
->alloc_sz
));
2698 pci_free_consistent(ioc
->pcidev
, sz
,
2699 ioc
->alloc
, ioc
->alloc_dma
);
2700 ioc
->reply_frames
= NULL
;
2701 ioc
->req_frames
= NULL
;
2703 ioc
->alloc_total
-= sz
;
2706 if (ioc
->sense_buf_pool
!= NULL
) {
2707 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
2708 pci_free_consistent(ioc
->pcidev
, sz
,
2709 ioc
->sense_buf_pool
, ioc
->sense_buf_pool_dma
);
2710 ioc
->sense_buf_pool
= NULL
;
2711 ioc
->alloc_total
-= sz
;
2714 if (ioc
->events
!= NULL
){
2715 sz
= MPTCTL_EVENT_LOG_SIZE
* sizeof(MPT_IOCTL_EVENTS
);
2718 ioc
->alloc_total
-= sz
;
2721 mpt_free_fw_memory(ioc
);
2723 kfree(ioc
->spi_data
.nvram
);
2724 mpt_inactive_raid_list_free(ioc
);
2725 kfree(ioc
->raid_data
.pIocPg2
);
2726 kfree(ioc
->raid_data
.pIocPg3
);
2727 ioc
->spi_data
.nvram
= NULL
;
2728 ioc
->raid_data
.pIocPg3
= NULL
;
2730 if (ioc
->spi_data
.pIocPg4
!= NULL
) {
2731 sz
= ioc
->spi_data
.IocPg4Sz
;
2732 pci_free_consistent(ioc
->pcidev
, sz
,
2733 ioc
->spi_data
.pIocPg4
,
2734 ioc
->spi_data
.IocPg4_dma
);
2735 ioc
->spi_data
.pIocPg4
= NULL
;
2736 ioc
->alloc_total
-= sz
;
2739 if (ioc
->ReqToChain
!= NULL
) {
2740 kfree(ioc
->ReqToChain
);
2741 kfree(ioc
->RequestNB
);
2742 ioc
->ReqToChain
= NULL
;
2745 kfree(ioc
->ChainToChain
);
2746 ioc
->ChainToChain
= NULL
;
2748 if (ioc
->HostPageBuffer
!= NULL
) {
2749 if((ret
= mpt_host_page_access_control(ioc
,
2750 MPI_DB_HPBAC_FREE_BUFFER
, NO_SLEEP
)) != 0) {
2751 printk(MYIOC_s_ERR_FMT
2752 ": %s: host page buffers free failed (%d)!\n",
2753 ioc
->name
, __func__
, ret
);
2755 dexitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2756 "HostPageBuffer free @ %p, sz=%d bytes\n",
2757 ioc
->name
, ioc
->HostPageBuffer
,
2758 ioc
->HostPageBuffer_sz
));
2759 pci_free_consistent(ioc
->pcidev
, ioc
->HostPageBuffer_sz
,
2760 ioc
->HostPageBuffer
, ioc
->HostPageBuffer_dma
);
2761 ioc
->HostPageBuffer
= NULL
;
2762 ioc
->HostPageBuffer_sz
= 0;
2763 ioc
->alloc_total
-= ioc
->HostPageBuffer_sz
;
2766 pci_set_drvdata(ioc
->pcidev
, NULL
);
2768 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2770 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2771 * @ioc: Pointer to MPT adapter structure
2773 * This routine unregisters h/w resources and frees all alloc'd memory
2774 * associated with a MPT adapter structure.
2777 mpt_adapter_dispose(MPT_ADAPTER
*ioc
)
2779 int sz_first
, sz_last
;
2784 sz_first
= ioc
->alloc_total
;
2786 mpt_adapter_disable(ioc
);
2788 if (ioc
->pci_irq
!= -1) {
2789 free_irq(ioc
->pci_irq
, ioc
);
2790 if (ioc
->msi_enable
)
2791 pci_disable_msi(ioc
->pcidev
);
2795 if (ioc
->memmap
!= NULL
) {
2796 iounmap(ioc
->memmap
);
2800 pci_disable_device(ioc
->pcidev
);
2801 pci_release_selected_regions(ioc
->pcidev
, ioc
->bars
);
2803 #if defined(CONFIG_MTRR) && 0
2804 if (ioc
->mtrr_reg
> 0) {
2805 mtrr_del(ioc
->mtrr_reg
, 0, 0);
2806 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
"MTRR region de-registered\n", ioc
->name
));
2810 /* Zap the adapter lookup ptr! */
2811 list_del(&ioc
->list
);
2813 sz_last
= ioc
->alloc_total
;
2814 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
"free'd %d of %d bytes\n",
2815 ioc
->name
, sz_first
-sz_last
+(int)sizeof(*ioc
), sz_first
));
2818 ioc
->alt_ioc
->alt_ioc
= NULL
;
2823 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2825 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2826 * @ioc: Pointer to MPT adapter structure
2829 MptDisplayIocCapabilities(MPT_ADAPTER
*ioc
)
2833 printk(KERN_INFO
"%s: ", ioc
->name
);
2835 printk("%s: ", ioc
->prod_name
);
2836 printk("Capabilities={");
2838 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_INITIATOR
) {
2839 printk("Initiator");
2843 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_TARGET
) {
2844 printk("%sTarget", i
? "," : "");
2848 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
) {
2849 printk("%sLAN", i
? "," : "");
2855 * This would probably evoke more questions than it's worth
2857 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_TARGET
) {
2858 printk("%sLogBusAddr", i
? "," : "");
2866 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2868 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2869 * @ioc: Pointer to MPT_ADAPTER structure
2870 * @force: Force hard KickStart of IOC
2871 * @sleepFlag: Specifies whether the process can sleep
2874 * 1 - DIAG reset and READY
2875 * 0 - READY initially OR soft reset and READY
2876 * -1 - Any failure on KickStart
2877 * -2 - Msg Unit Reset Failed
2878 * -3 - IO Unit Reset Failed
2879 * -4 - IOC owned by a PEER
2882 MakeIocReady(MPT_ADAPTER
*ioc
, int force
, int sleepFlag
)
2887 int hard_reset_done
= 0;
2892 /* Get current [raw] IOC state */
2893 ioc_state
= mpt_GetIocState(ioc
, 0);
2894 dhsprintk(ioc
, printk(MYIOC_s_INFO_FMT
"MakeIocReady [raw] state=%08x\n", ioc
->name
, ioc_state
));
2897 * Check to see if IOC got left/stuck in doorbell handshake
2898 * grip of death. If so, hard reset the IOC.
2900 if (ioc_state
& MPI_DOORBELL_ACTIVE
) {
2902 printk(MYIOC_s_WARN_FMT
"Unexpected doorbell active!\n",
2906 /* Is it already READY? */
2908 ((ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_READY
)) {
2909 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
2910 "IOC is in READY state\n", ioc
->name
));
2915 * Check to see if IOC is in FAULT state.
2917 if ((ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_FAULT
) {
2919 printk(MYIOC_s_WARN_FMT
"IOC is in FAULT state!!!\n",
2921 printk(MYIOC_s_WARN_FMT
" FAULT code = %04xh\n",
2922 ioc
->name
, ioc_state
& MPI_DOORBELL_DATA_MASK
);
2926 * Hmmm... Did it get left operational?
2928 if ((ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_OPERATIONAL
) {
2929 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"IOC operational unexpected\n",
2933 * If PCI Peer, exit.
2934 * Else, if no fault conditions are present, issue a MessageUnitReset
2935 * Else, fall through to KickStart case
2937 whoinit
= (ioc_state
& MPI_DOORBELL_WHO_INIT_MASK
) >> MPI_DOORBELL_WHO_INIT_SHIFT
;
2938 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
2939 "whoinit 0x%x statefault %d force %d\n",
2940 ioc
->name
, whoinit
, statefault
, force
));
2941 if (whoinit
== MPI_WHOINIT_PCI_PEER
)
2944 if ((statefault
== 0 ) && (force
== 0)) {
2945 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
)) == 0)
2952 hard_reset_done
= KickStart(ioc
, statefault
||force
, sleepFlag
);
2953 if (hard_reset_done
< 0)
2957 * Loop here waiting for IOC to come READY.
2960 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 5; /* 5 seconds */
2962 while ((ioc_state
= mpt_GetIocState(ioc
, 1)) != MPI_IOC_STATE_READY
) {
2963 if (ioc_state
== MPI_IOC_STATE_OPERATIONAL
) {
2965 * BIOS or previous driver load left IOC in OP state.
2966 * Reset messaging FIFOs.
2968 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
)) != 0) {
2969 printk(MYIOC_s_ERR_FMT
"IOC msg unit reset failed!\n", ioc
->name
);
2972 } else if (ioc_state
== MPI_IOC_STATE_RESET
) {
2974 * Something is wrong. Try to get IOC back
2977 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IO_UNIT_RESET
, sleepFlag
)) != 0) {
2978 printk(MYIOC_s_ERR_FMT
"IO unit reset failed!\n", ioc
->name
);
2985 printk(MYIOC_s_ERR_FMT
2986 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
2987 ioc
->name
, ioc_state
, (int)((ii
+5)/HZ
));
2991 if (sleepFlag
== CAN_SLEEP
) {
2994 mdelay (1); /* 1 msec delay */
2999 if (statefault
< 3) {
3000 printk(MYIOC_s_INFO_FMT
"Recovered from %s\n", ioc
->name
,
3001 statefault
== 1 ? "stuck handshake" : "IOC FAULT");
3004 return hard_reset_done
;
3007 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3009 * mpt_GetIocState - Get the current state of a MPT adapter.
3010 * @ioc: Pointer to MPT_ADAPTER structure
3011 * @cooked: Request raw or cooked IOC state
3013 * Returns all IOC Doorbell register bits if cooked==0, else just the
3014 * Doorbell bits in MPI_IOC_STATE_MASK.
3017 mpt_GetIocState(MPT_ADAPTER
*ioc
, int cooked
)
3022 s
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
3023 sc
= s
& MPI_IOC_STATE_MASK
;
3026 ioc
->last_state
= sc
;
3028 return cooked
? sc
: s
;
3031 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3033 * GetIocFacts - Send IOCFacts request to MPT adapter.
3034 * @ioc: Pointer to MPT_ADAPTER structure
3035 * @sleepFlag: Specifies whether the process can sleep
3036 * @reason: If recovery, only update facts.
3038 * Returns 0 for success, non-zero for failure.
3041 GetIocFacts(MPT_ADAPTER
*ioc
, int sleepFlag
, int reason
)
3043 IOCFacts_t get_facts
;
3044 IOCFactsReply_t
*facts
;
3052 /* IOC *must* NOT be in RESET state! */
3053 if (ioc
->last_state
== MPI_IOC_STATE_RESET
) {
3054 printk(KERN_ERR MYNAM
3055 ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
3056 ioc
->name
, ioc
->last_state
);
3060 facts
= &ioc
->facts
;
3062 /* Destination (reply area)... */
3063 reply_sz
= sizeof(*facts
);
3064 memset(facts
, 0, reply_sz
);
3066 /* Request area (get_facts on the stack right now!) */
3067 req_sz
= sizeof(get_facts
);
3068 memset(&get_facts
, 0, req_sz
);
3070 get_facts
.Function
= MPI_FUNCTION_IOC_FACTS
;
3071 /* Assert: All other get_facts fields are zero! */
3073 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3074 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
3075 ioc
->name
, req_sz
, reply_sz
));
3077 /* No non-zero fields in the get_facts request are greater than
3078 * 1 byte in size, so we can just fire it off as is.
3080 r
= mpt_handshake_req_reply_wait(ioc
, req_sz
, (u32
*)&get_facts
,
3081 reply_sz
, (u16
*)facts
, 5 /*seconds*/, sleepFlag
);
3086 * Now byte swap (GRRR) the necessary fields before any further
3087 * inspection of reply contents.
3089 * But need to do some sanity checks on MsgLength (byte) field
3090 * to make sure we don't zero IOC's req_sz!
3092 /* Did we get a valid reply? */
3093 if (facts
->MsgLength
> offsetof(IOCFactsReply_t
, RequestFrameSize
)/sizeof(u32
)) {
3094 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
3096 * If not been here, done that, save off first WhoInit value
3098 if (ioc
->FirstWhoInit
== WHOINIT_UNKNOWN
)
3099 ioc
->FirstWhoInit
= facts
->WhoInit
;
3102 facts
->MsgVersion
= le16_to_cpu(facts
->MsgVersion
);
3103 facts
->MsgContext
= le32_to_cpu(facts
->MsgContext
);
3104 facts
->IOCExceptions
= le16_to_cpu(facts
->IOCExceptions
);
3105 facts
->IOCStatus
= le16_to_cpu(facts
->IOCStatus
);
3106 facts
->IOCLogInfo
= le32_to_cpu(facts
->IOCLogInfo
);
3107 status
= le16_to_cpu(facts
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
3108 /* CHECKME! IOCStatus, IOCLogInfo */
3110 facts
->ReplyQueueDepth
= le16_to_cpu(facts
->ReplyQueueDepth
);
3111 facts
->RequestFrameSize
= le16_to_cpu(facts
->RequestFrameSize
);
3114 * FC f/w version changed between 1.1 and 1.2
3115 * Old: u16{Major(4),Minor(4),SubMinor(8)}
3116 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
3118 if (facts
->MsgVersion
< MPI_VERSION_01_02
) {
3120 * Handle old FC f/w style, convert to new...
3122 u16 oldv
= le16_to_cpu(facts
->Reserved_0101_FWVersion
);
3123 facts
->FWVersion
.Word
=
3124 ((oldv
<<12) & 0xFF000000) |
3125 ((oldv
<<8) & 0x000FFF00);
3127 facts
->FWVersion
.Word
= le32_to_cpu(facts
->FWVersion
.Word
);
3129 facts
->ProductID
= le16_to_cpu(facts
->ProductID
);
3131 if ((ioc
->facts
.ProductID
& MPI_FW_HEADER_PID_PROD_MASK
)
3132 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI
)
3133 ioc
->ir_firmware
= 1;
3135 facts
->CurrentHostMfaHighAddr
=
3136 le32_to_cpu(facts
->CurrentHostMfaHighAddr
);
3137 facts
->GlobalCredits
= le16_to_cpu(facts
->GlobalCredits
);
3138 facts
->CurrentSenseBufferHighAddr
=
3139 le32_to_cpu(facts
->CurrentSenseBufferHighAddr
);
3140 facts
->CurReplyFrameSize
=
3141 le16_to_cpu(facts
->CurReplyFrameSize
);
3142 facts
->IOCCapabilities
= le32_to_cpu(facts
->IOCCapabilities
);
3145 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
3146 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
3147 * to 14 in MPI-1.01.0x.
3149 if (facts
->MsgLength
>= (offsetof(IOCFactsReply_t
,FWImageSize
) + 7)/4 &&
3150 facts
->MsgVersion
> MPI_VERSION_01_00
) {
3151 facts
->FWImageSize
= le32_to_cpu(facts
->FWImageSize
);
3154 sz
= facts
->FWImageSize
;
3159 facts
->FWImageSize
= sz
;
3161 if (!facts
->RequestFrameSize
) {
3162 /* Something is wrong! */
3163 printk(MYIOC_s_ERR_FMT
"IOC reported invalid 0 request size!\n",
3168 r
= sz
= facts
->BlockSize
;
3169 vv
= ((63 / (sz
* 4)) + 1) & 0x03;
3170 ioc
->NB_for_64_byte_frame
= vv
;
3176 ioc
->NBShiftFactor
= shiftFactor
;
3177 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3178 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
3179 ioc
->name
, vv
, shiftFactor
, r
));
3181 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
3183 * Set values for this IOC's request & reply frame sizes,
3184 * and request & reply queue depths...
3186 ioc
->req_sz
= min(MPT_DEFAULT_FRAME_SIZE
, facts
->RequestFrameSize
* 4);
3187 ioc
->req_depth
= min_t(int, MPT_MAX_REQ_DEPTH
, facts
->GlobalCredits
);
3188 ioc
->reply_sz
= MPT_REPLY_FRAME_SIZE
;
3189 ioc
->reply_depth
= min_t(int, MPT_DEFAULT_REPLY_DEPTH
, facts
->ReplyQueueDepth
);
3191 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"reply_sz=%3d, reply_depth=%4d\n",
3192 ioc
->name
, ioc
->reply_sz
, ioc
->reply_depth
));
3193 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"req_sz =%3d, req_depth =%4d\n",
3194 ioc
->name
, ioc
->req_sz
, ioc
->req_depth
));
3196 /* Get port facts! */
3197 if ( (r
= GetPortFacts(ioc
, 0, sleepFlag
)) != 0 )
3201 printk(MYIOC_s_ERR_FMT
3202 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
3203 ioc
->name
, facts
->MsgLength
, (offsetof(IOCFactsReply_t
,
3204 RequestFrameSize
)/sizeof(u32
)));
3211 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3213 * GetPortFacts - Send PortFacts request to MPT adapter.
3214 * @ioc: Pointer to MPT_ADAPTER structure
3215 * @portnum: Port number
3216 * @sleepFlag: Specifies whether the process can sleep
3218 * Returns 0 for success, non-zero for failure.
3221 GetPortFacts(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
)
3223 PortFacts_t get_pfacts
;
3224 PortFactsReply_t
*pfacts
;
3230 /* IOC *must* NOT be in RESET state! */
3231 if (ioc
->last_state
== MPI_IOC_STATE_RESET
) {
3232 printk(MYIOC_s_ERR_FMT
"Can't get PortFacts NOT READY! (%08x)\n",
3233 ioc
->name
, ioc
->last_state
);
3237 pfacts
= &ioc
->pfacts
[portnum
];
3239 /* Destination (reply area)... */
3240 reply_sz
= sizeof(*pfacts
);
3241 memset(pfacts
, 0, reply_sz
);
3243 /* Request area (get_pfacts on the stack right now!) */
3244 req_sz
= sizeof(get_pfacts
);
3245 memset(&get_pfacts
, 0, req_sz
);
3247 get_pfacts
.Function
= MPI_FUNCTION_PORT_FACTS
;
3248 get_pfacts
.PortNumber
= portnum
;
3249 /* Assert: All other get_pfacts fields are zero! */
3251 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending get PortFacts(%d) request\n",
3252 ioc
->name
, portnum
));
3254 /* No non-zero fields in the get_pfacts request are greater than
3255 * 1 byte in size, so we can just fire it off as is.
3257 ii
= mpt_handshake_req_reply_wait(ioc
, req_sz
, (u32
*)&get_pfacts
,
3258 reply_sz
, (u16
*)pfacts
, 5 /*seconds*/, sleepFlag
);
3262 /* Did we get a valid reply? */
3264 /* Now byte swap the necessary fields in the response. */
3265 pfacts
->MsgContext
= le32_to_cpu(pfacts
->MsgContext
);
3266 pfacts
->IOCStatus
= le16_to_cpu(pfacts
->IOCStatus
);
3267 pfacts
->IOCLogInfo
= le32_to_cpu(pfacts
->IOCLogInfo
);
3268 pfacts
->MaxDevices
= le16_to_cpu(pfacts
->MaxDevices
);
3269 pfacts
->PortSCSIID
= le16_to_cpu(pfacts
->PortSCSIID
);
3270 pfacts
->ProtocolFlags
= le16_to_cpu(pfacts
->ProtocolFlags
);
3271 pfacts
->MaxPostedCmdBuffers
= le16_to_cpu(pfacts
->MaxPostedCmdBuffers
);
3272 pfacts
->MaxPersistentIDs
= le16_to_cpu(pfacts
->MaxPersistentIDs
);
3273 pfacts
->MaxLanBuckets
= le16_to_cpu(pfacts
->MaxLanBuckets
);
3275 max_id
= (ioc
->bus_type
== SAS
) ? pfacts
->PortSCSIID
:
3277 ioc
->devices_per_bus
= (max_id
> 255) ? 256 : max_id
;
3278 ioc
->number_of_buses
= (ioc
->devices_per_bus
< 256) ? 1 : max_id
/256;
3281 * Place all the devices on channels
3285 if (mpt_channel_mapping
) {
3286 ioc
->devices_per_bus
= 1;
3287 ioc
->number_of_buses
= (max_id
> 255) ? 255 : max_id
;
3293 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3295 * SendIocInit - Send IOCInit request to MPT adapter.
3296 * @ioc: Pointer to MPT_ADAPTER structure
3297 * @sleepFlag: Specifies whether the process can sleep
3299 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
3301 * Returns 0 for success, non-zero for failure.
3304 SendIocInit(MPT_ADAPTER
*ioc
, int sleepFlag
)
3307 MPIDefaultReply_t init_reply
;
3313 memset(&ioc_init
, 0, sizeof(ioc_init
));
3314 memset(&init_reply
, 0, sizeof(init_reply
));
3316 ioc_init
.WhoInit
= MPI_WHOINIT_HOST_DRIVER
;
3317 ioc_init
.Function
= MPI_FUNCTION_IOC_INIT
;
3319 /* If we are in a recovery mode and we uploaded the FW image,
3320 * then this pointer is not NULL. Skip the upload a second time.
3321 * Set this flag if cached_fw set for either IOC.
3323 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)
3327 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"upload_fw %d facts.Flags=%x\n",
3328 ioc
->name
, ioc
->upload_fw
, ioc
->facts
.Flags
));
3330 ioc_init
.MaxDevices
= (U8
)ioc
->devices_per_bus
;
3331 ioc_init
.MaxBuses
= (U8
)ioc
->number_of_buses
;
3333 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"facts.MsgVersion=%x\n",
3334 ioc
->name
, ioc
->facts
.MsgVersion
));
3335 if (ioc
->facts
.MsgVersion
>= MPI_VERSION_01_05
) {
3336 // set MsgVersion and HeaderVersion host driver was built with
3337 ioc_init
.MsgVersion
= cpu_to_le16(MPI_VERSION
);
3338 ioc_init
.HeaderVersion
= cpu_to_le16(MPI_HEADER_VERSION
);
3340 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT
) {
3341 ioc_init
.HostPageBufferSGE
= ioc
->facts
.HostPageBufferSGE
;
3342 } else if(mpt_host_page_alloc(ioc
, &ioc_init
))
3345 ioc_init
.ReplyFrameSize
= cpu_to_le16(ioc
->reply_sz
); /* in BYTES */
3347 if (ioc
->sg_addr_size
== sizeof(u64
)) {
3348 /* Save the upper 32-bits of the request
3349 * (reply) and sense buffers.
3351 ioc_init
.HostMfaHighAddr
= cpu_to_le32((u32
)((u64
)ioc
->alloc_dma
>> 32));
3352 ioc_init
.SenseBufferHighAddr
= cpu_to_le32((u32
)((u64
)ioc
->sense_buf_pool_dma
>> 32));
3354 /* Force 32-bit addressing */
3355 ioc_init
.HostMfaHighAddr
= cpu_to_le32(0);
3356 ioc_init
.SenseBufferHighAddr
= cpu_to_le32(0);
3359 ioc
->facts
.CurrentHostMfaHighAddr
= ioc_init
.HostMfaHighAddr
;
3360 ioc
->facts
.CurrentSenseBufferHighAddr
= ioc_init
.SenseBufferHighAddr
;
3361 ioc
->facts
.MaxDevices
= ioc_init
.MaxDevices
;
3362 ioc
->facts
.MaxBuses
= ioc_init
.MaxBuses
;
3364 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending IOCInit (req @ %p)\n",
3365 ioc
->name
, &ioc_init
));
3367 r
= mpt_handshake_req_reply_wait(ioc
, sizeof(IOCInit_t
), (u32
*)&ioc_init
,
3368 sizeof(MPIDefaultReply_t
), (u16
*)&init_reply
, 10 /*seconds*/, sleepFlag
);
3370 printk(MYIOC_s_ERR_FMT
"Sending IOCInit failed(%d)!\n",ioc
->name
, r
);
3374 /* No need to byte swap the multibyte fields in the reply
3375 * since we don't even look at its contents.
3378 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending PortEnable (req @ %p)\n",
3379 ioc
->name
, &ioc_init
));
3381 if ((r
= SendPortEnable(ioc
, 0, sleepFlag
)) != 0) {
3382 printk(MYIOC_s_ERR_FMT
"Sending PortEnable failed(%d)!\n",ioc
->name
, r
);
3386 /* YIKES! SUPER IMPORTANT!!!
3387 * Poll IocState until _OPERATIONAL while IOC is doing
3388 * LoopInit and TargetDiscovery!
3391 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 60; /* 60 seconds */
3392 state
= mpt_GetIocState(ioc
, 1);
3393 while (state
!= MPI_IOC_STATE_OPERATIONAL
&& --cntdn
) {
3394 if (sleepFlag
== CAN_SLEEP
) {
3401 printk(MYIOC_s_ERR_FMT
"Wait IOC_OP state timeout(%d)!\n",
3402 ioc
->name
, (int)((count
+5)/HZ
));
3406 state
= mpt_GetIocState(ioc
, 1);
3409 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Wait IOC_OPERATIONAL state (cnt=%d)\n",
3412 ioc
->aen_event_read_flag
=0;
3416 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3418 * SendPortEnable - Send PortEnable request to MPT adapter port.
3419 * @ioc: Pointer to MPT_ADAPTER structure
3420 * @portnum: Port number to enable
3421 * @sleepFlag: Specifies whether the process can sleep
3423 * Send PortEnable to bring IOC to OPERATIONAL state.
3425 * Returns 0 for success, non-zero for failure.
3428 SendPortEnable(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
)
3430 PortEnable_t port_enable
;
3431 MPIDefaultReply_t reply_buf
;
3436 /* Destination... */
3437 reply_sz
= sizeof(MPIDefaultReply_t
);
3438 memset(&reply_buf
, 0, reply_sz
);
3440 req_sz
= sizeof(PortEnable_t
);
3441 memset(&port_enable
, 0, req_sz
);
3443 port_enable
.Function
= MPI_FUNCTION_PORT_ENABLE
;
3444 port_enable
.PortNumber
= portnum
;
3445 /* port_enable.ChainOffset = 0; */
3446 /* port_enable.MsgFlags = 0; */
3447 /* port_enable.MsgContext = 0; */
3449 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending Port(%d)Enable (req @ %p)\n",
3450 ioc
->name
, portnum
, &port_enable
));
3452 /* RAID FW may take a long time to enable
3454 if (ioc
->ir_firmware
|| ioc
->bus_type
== SAS
) {
3455 rc
= mpt_handshake_req_reply_wait(ioc
, req_sz
,
3456 (u32
*)&port_enable
, reply_sz
, (u16
*)&reply_buf
,
3457 300 /*seconds*/, sleepFlag
);
3459 rc
= mpt_handshake_req_reply_wait(ioc
, req_sz
,
3460 (u32
*)&port_enable
, reply_sz
, (u16
*)&reply_buf
,
3461 30 /*seconds*/, sleepFlag
);
3467 * mpt_alloc_fw_memory - allocate firmware memory
3468 * @ioc: Pointer to MPT_ADAPTER structure
3469 * @size: total FW bytes
3471 * If memory has already been allocated, the same (cached) value
3474 * Return 0 if successfull, or non-zero for failure
3477 mpt_alloc_fw_memory(MPT_ADAPTER
*ioc
, int size
)
3481 if (ioc
->cached_fw
) {
3482 rc
= 0; /* use already allocated memory */
3485 else if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
) {
3486 ioc
->cached_fw
= ioc
->alt_ioc
->cached_fw
; /* use alt_ioc's memory */
3487 ioc
->cached_fw_dma
= ioc
->alt_ioc
->cached_fw_dma
;
3491 ioc
->cached_fw
= pci_alloc_consistent(ioc
->pcidev
, size
, &ioc
->cached_fw_dma
);
3492 if (!ioc
->cached_fw
) {
3493 printk(MYIOC_s_ERR_FMT
"Unable to allocate memory for the cached firmware image!\n",
3497 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"FW Image @ %p[%p], sz=%d[%x] bytes\n",
3498 ioc
->name
, ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, size
, size
));
3499 ioc
->alloc_total
+= size
;
3507 * mpt_free_fw_memory - free firmware memory
3508 * @ioc: Pointer to MPT_ADAPTER structure
3510 * If alt_img is NULL, delete from ioc structure.
3511 * Else, delete a secondary image in same format.
3514 mpt_free_fw_memory(MPT_ADAPTER
*ioc
)
3518 if (!ioc
->cached_fw
)
3521 sz
= ioc
->facts
.FWImageSize
;
3522 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3523 ioc
->name
, ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, sz
, sz
));
3524 pci_free_consistent(ioc
->pcidev
, sz
, ioc
->cached_fw
, ioc
->cached_fw_dma
);
3525 ioc
->alloc_total
-= sz
;
3526 ioc
->cached_fw
= NULL
;
3529 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3531 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3532 * @ioc: Pointer to MPT_ADAPTER structure
3533 * @sleepFlag: Specifies whether the process can sleep
3535 * Returns 0 for success, >0 for handshake failure
3536 * <0 for fw upload failure.
3538 * Remark: If bound IOC and a successful FWUpload was performed
3539 * on the bound IOC, the second image is discarded
3540 * and memory is free'd. Both channels must upload to prevent
3541 * IOC from running in degraded mode.
3544 mpt_do_upload(MPT_ADAPTER
*ioc
, int sleepFlag
)
3546 u8 reply
[sizeof(FWUploadReply_t
)];
3547 FWUpload_t
*prequest
;
3548 FWUploadReply_t
*preply
;
3549 FWUploadTCSGE_t
*ptcsge
;
3551 int ii
, sz
, reply_sz
;
3554 /* If the image size is 0, we are done.
3556 if ((sz
= ioc
->facts
.FWImageSize
) == 0)
3559 if (mpt_alloc_fw_memory(ioc
, ioc
->facts
.FWImageSize
) != 0)
3562 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3563 ioc
->name
, ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, sz
, sz
));
3565 prequest
= (sleepFlag
== NO_SLEEP
) ? kzalloc(ioc
->req_sz
, GFP_ATOMIC
) :
3566 kzalloc(ioc
->req_sz
, GFP_KERNEL
);
3568 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"fw upload failed "
3569 "while allocating memory \n", ioc
->name
));
3570 mpt_free_fw_memory(ioc
);
3574 preply
= (FWUploadReply_t
*)&reply
;
3576 reply_sz
= sizeof(reply
);
3577 memset(preply
, 0, reply_sz
);
3579 prequest
->ImageType
= MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM
;
3580 prequest
->Function
= MPI_FUNCTION_FW_UPLOAD
;
3582 ptcsge
= (FWUploadTCSGE_t
*) &prequest
->SGL
;
3583 ptcsge
->DetailsLength
= 12;
3584 ptcsge
->Flags
= MPI_SGE_FLAGS_TRANSACTION_ELEMENT
;
3585 ptcsge
->ImageSize
= cpu_to_le32(sz
);
3588 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_READ
| sz
;
3589 ioc
->add_sge((char *)ptcsge
, flagsLength
, ioc
->cached_fw_dma
);
3590 request_size
= offsetof(FWUpload_t
, SGL
) + sizeof(FWUploadTCSGE_t
) +
3592 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending FW Upload "
3593 " (req @ %p) fw_size=%d mf_request_size=%d\n", ioc
->name
, prequest
,
3594 ioc
->facts
.FWImageSize
, request_size
));
3595 DBG_DUMP_FW_REQUEST_FRAME(ioc
, (u32
*)prequest
);
3597 ii
= mpt_handshake_req_reply_wait(ioc
, request_size
, (u32
*)prequest
,
3598 reply_sz
, (u16
*)preply
, 65 /*seconds*/, sleepFlag
);
3600 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"FW Upload completed "
3601 "rc=%x \n", ioc
->name
, ii
));
3603 cmdStatus
= -EFAULT
;
3605 /* Handshake transfer was complete and successful.
3606 * Check the Reply Frame.
3609 status
= le16_to_cpu(preply
->IOCStatus
) &
3611 if (status
== MPI_IOCSTATUS_SUCCESS
&&
3612 ioc
->facts
.FWImageSize
==
3613 le32_to_cpu(preply
->ActualImageSize
))
3616 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
": do_upload cmdStatus=%d \n",
3617 ioc
->name
, cmdStatus
));
3621 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"fw upload failed, "
3622 "freeing image \n", ioc
->name
));
3623 mpt_free_fw_memory(ioc
);
3630 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3632 * mpt_downloadboot - DownloadBoot code
3633 * @ioc: Pointer to MPT_ADAPTER structure
3634 * @pFwHeader: Pointer to firmware header info
3635 * @sleepFlag: Specifies whether the process can sleep
3637 * FwDownloadBoot requires Programmed IO access.
3639 * Returns 0 for success
3640 * -1 FW Image size is 0
3641 * -2 No valid cached_fw Pointer
3642 * <0 for fw upload failure.
3645 mpt_downloadboot(MPT_ADAPTER
*ioc
, MpiFwHeader_t
*pFwHeader
, int sleepFlag
)
3647 MpiExtImageHeader_t
*pExtImage
;
3657 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3658 ioc
->name
, pFwHeader
->ImageSize
, pFwHeader
->ImageSize
, pFwHeader
));
3660 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3661 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3662 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3663 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3664 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3665 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3667 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, (MPI_DIAG_PREVENT_IOC_BOOT
| MPI_DIAG_DISABLE_ARM
));
3670 if (sleepFlag
== CAN_SLEEP
) {
3676 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3677 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_RESET_ADAPTER
);
3679 for (count
= 0; count
< 30; count
++) {
3680 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3681 if (!(diag0val
& MPI_DIAG_RESET_ADAPTER
)) {
3682 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RESET_ADAPTER cleared, count=%d\n",
3687 if (sleepFlag
== CAN_SLEEP
) {
3694 if ( count
== 30 ) {
3695 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot failed! "
3696 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3697 ioc
->name
, diag0val
));
3701 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3702 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3703 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3704 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3705 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3706 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3708 /* Set the DiagRwEn and Disable ARM bits */
3709 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, (MPI_DIAG_RW_ENABLE
| MPI_DIAG_DISABLE_ARM
));
3711 fwSize
= (pFwHeader
->ImageSize
+ 3)/4;
3712 ptrFw
= (u32
*) pFwHeader
;
3714 /* Write the LoadStartAddress to the DiagRw Address Register
3715 * using Programmed IO
3717 if (ioc
->errata_flag_1064
)
3718 pci_enable_io_access(ioc
->pcidev
);
3720 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, pFwHeader
->LoadStartAddress
);
3721 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"LoadStart addr written 0x%x \n",
3722 ioc
->name
, pFwHeader
->LoadStartAddress
));
3724 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write FW Image: 0x%x bytes @ %p\n",
3725 ioc
->name
, fwSize
*4, ptrFw
));
3727 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, *ptrFw
++);
3730 nextImage
= pFwHeader
->NextImageHeaderOffset
;
3732 pExtImage
= (MpiExtImageHeader_t
*) ((char *)pFwHeader
+ nextImage
);
3734 load_addr
= pExtImage
->LoadStartAddress
;
3736 fwSize
= (pExtImage
->ImageSize
+ 3) >> 2;
3737 ptrFw
= (u32
*)pExtImage
;
3739 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3740 ioc
->name
, fwSize
*4, fwSize
*4, ptrFw
, load_addr
));
3741 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, load_addr
);
3744 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, *ptrFw
++);
3746 nextImage
= pExtImage
->NextImageHeaderOffset
;
3749 /* Write the IopResetVectorRegAddr */
3750 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write IopResetVector Addr=%x! \n", ioc
->name
, pFwHeader
->IopResetRegAddr
));
3751 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, pFwHeader
->IopResetRegAddr
);
3753 /* Write the IopResetVectorValue */
3754 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write IopResetVector Value=%x! \n", ioc
->name
, pFwHeader
->IopResetVectorValue
));
3755 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, pFwHeader
->IopResetVectorValue
);
3757 /* Clear the internal flash bad bit - autoincrementing register,
3758 * so must do two writes.
3760 if (ioc
->bus_type
== SPI
) {
3762 * 1030 and 1035 H/W errata, workaround to access
3763 * the ClearFlashBadSignatureBit
3765 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, 0x3F000000);
3766 diagRwData
= CHIPREG_PIO_READ32(&ioc
->pio_chip
->DiagRwData
);
3767 diagRwData
|= 0x40000000;
3768 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, 0x3F000000);
3769 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, diagRwData
);
3771 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3772 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3773 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
|
3774 MPI_DIAG_CLEAR_FLASH_BAD_SIG
);
3777 if (sleepFlag
== CAN_SLEEP
) {
3784 if (ioc
->errata_flag_1064
)
3785 pci_disable_io_access(ioc
->pcidev
);
3787 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3788 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot diag0val=%x, "
3789 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3790 ioc
->name
, diag0val
));
3791 diag0val
&= ~(MPI_DIAG_PREVENT_IOC_BOOT
| MPI_DIAG_DISABLE_ARM
| MPI_DIAG_RW_ENABLE
);
3792 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot now diag0val=%x\n",
3793 ioc
->name
, diag0val
));
3794 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
);
3796 /* Write 0xFF to reset the sequencer */
3797 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3799 if (ioc
->bus_type
== SAS
) {
3800 ioc_state
= mpt_GetIocState(ioc
, 0);
3801 if ( (GetIocFacts(ioc
, sleepFlag
,
3802 MPT_HOSTEVENT_IOC_BRINGUP
)) != 0 ) {
3803 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"GetIocFacts failed: IocState=%x\n",
3804 ioc
->name
, ioc_state
));
3809 for (count
=0; count
<HZ
*20; count
++) {
3810 if ((ioc_state
= mpt_GetIocState(ioc
, 0)) & MPI_IOC_STATE_READY
) {
3811 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3812 "downloadboot successful! (count=%d) IocState=%x\n",
3813 ioc
->name
, count
, ioc_state
));
3814 if (ioc
->bus_type
== SAS
) {
3817 if ((SendIocInit(ioc
, sleepFlag
)) != 0) {
3818 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3819 "downloadboot: SendIocInit failed\n",
3823 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3824 "downloadboot: SendIocInit successful\n",
3828 if (sleepFlag
== CAN_SLEEP
) {
3834 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3835 "downloadboot failed! IocState=%x\n",ioc
->name
, ioc_state
));
3839 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3841 * KickStart - Perform hard reset of MPT adapter.
3842 * @ioc: Pointer to MPT_ADAPTER structure
3843 * @force: Force hard reset
3844 * @sleepFlag: Specifies whether the process can sleep
3846 * This routine places MPT adapter in diagnostic mode via the
3847 * WriteSequence register, and then performs a hard reset of adapter
3848 * via the Diagnostic register.
3850 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3851 * or NO_SLEEP (interrupt thread, use mdelay)
3852 * force - 1 if doorbell active, board fault state
3853 * board operational, IOC_RECOVERY or
3854 * IOC_BRINGUP and there is an alt_ioc.
3858 * 1 - hard reset, READY
3859 * 0 - no reset due to History bit, READY
3860 * -1 - no reset due to History bit but not READY
3861 * OR reset but failed to come READY
3862 * -2 - no reset, could not enter DIAG mode
3863 * -3 - reset but bad FW bit
3866 KickStart(MPT_ADAPTER
*ioc
, int force
, int sleepFlag
)
3868 int hard_reset_done
= 0;
3872 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"KickStarting!\n", ioc
->name
));
3873 if (ioc
->bus_type
== SPI
) {
3874 /* Always issue a Msg Unit Reset first. This will clear some
3875 * SCSI bus hang conditions.
3877 SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
);
3879 if (sleepFlag
== CAN_SLEEP
) {
3886 hard_reset_done
= mpt_diag_reset(ioc
, force
, sleepFlag
);
3887 if (hard_reset_done
< 0)
3888 return hard_reset_done
;
3890 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Diagnostic reset successful!\n",
3893 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 2; /* 2 seconds */
3894 for (cnt
=0; cnt
<cntdn
; cnt
++) {
3895 ioc_state
= mpt_GetIocState(ioc
, 1);
3896 if ((ioc_state
== MPI_IOC_STATE_READY
) || (ioc_state
== MPI_IOC_STATE_OPERATIONAL
)) {
3897 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"KickStart successful! (cnt=%d)\n",
3899 return hard_reset_done
;
3901 if (sleepFlag
== CAN_SLEEP
) {
3908 dinitprintk(ioc
, printk(MYIOC_s_ERR_FMT
"Failed to come READY after reset! IocState=%x\n",
3909 ioc
->name
, mpt_GetIocState(ioc
, 0)));
3913 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3915 * mpt_diag_reset - Perform hard reset of the adapter.
3916 * @ioc: Pointer to MPT_ADAPTER structure
3917 * @ignore: Set if to honor and clear to ignore
3918 * the reset history bit
3919 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3920 * else set to NO_SLEEP (use mdelay instead)
3922 * This routine places the adapter in diagnostic mode via the
3923 * WriteSequence register and then performs a hard reset of adapter
3924 * via the Diagnostic register. Adapter should be in ready state
3925 * upon successful completion.
3927 * Returns: 1 hard reset successful
3928 * 0 no reset performed because reset history bit set
3929 * -2 enabling diagnostic mode failed
3930 * -3 diagnostic reset failed
3933 mpt_diag_reset(MPT_ADAPTER
*ioc
, int ignore
, int sleepFlag
)
3937 int hard_reset_done
= 0;
3940 MpiFwHeader_t
*cached_fw
; /* Pointer to FW */
3942 /* Clear any existing interrupts */
3943 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
3945 if (ioc
->pcidev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1078
) {
3950 drsprintk(ioc
, printk(MYIOC_s_WARN_FMT
"%s: Doorbell=%p; 1078 reset "
3951 "address=%p\n", ioc
->name
, __func__
,
3952 &ioc
->chip
->Doorbell
, &ioc
->chip
->Reset_1078
));
3953 CHIPREG_WRITE32(&ioc
->chip
->Reset_1078
, 0x07);
3954 if (sleepFlag
== CAN_SLEEP
)
3959 for (count
= 0; count
< 60; count
++) {
3960 doorbell
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
3961 doorbell
&= MPI_IOC_STATE_MASK
;
3963 drsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3964 "looking for READY STATE: doorbell=%x"
3966 ioc
->name
, doorbell
, count
));
3968 if (doorbell
== MPI_IOC_STATE_READY
) {
3973 if (sleepFlag
== CAN_SLEEP
)
3981 /* Use "Diagnostic reset" method! (only thing available!) */
3982 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3984 if (ioc
->debug_level
& MPT_DEBUG
) {
3986 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
3987 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG1: diag0=%08x, diag1=%08x\n",
3988 ioc
->name
, diag0val
, diag1val
));
3991 /* Do the reset if we are told to ignore the reset history
3992 * or if the reset history is 0
3994 if (ignore
|| !(diag0val
& MPI_DIAG_RESET_HISTORY
)) {
3995 while ((diag0val
& MPI_DIAG_DRWE
) == 0) {
3996 /* Write magic sequence to WriteSequence register
3997 * Loop until in diagnostic mode
3999 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
4000 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
4001 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
4002 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
4003 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
4004 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
4007 if (sleepFlag
== CAN_SLEEP
) {
4015 printk(MYIOC_s_ERR_FMT
"Enable Diagnostic mode FAILED! (%02xh)\n",
4016 ioc
->name
, diag0val
);
4021 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4023 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Wrote magic DiagWriteEn sequence (%x)\n",
4024 ioc
->name
, diag0val
));
4027 if (ioc
->debug_level
& MPT_DEBUG
) {
4029 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
4030 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG2: diag0=%08x, diag1=%08x\n",
4031 ioc
->name
, diag0val
, diag1val
));
4034 * Disable the ARM (Bug fix)
4037 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_DISABLE_ARM
);
4041 * Now hit the reset bit in the Diagnostic register
4042 * (THE BIG HAMMER!) (Clears DRWE bit).
4044 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_RESET_ADAPTER
);
4045 hard_reset_done
= 1;
4046 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Diagnostic reset performed\n",
4050 * Call each currently registered protocol IOC reset handler
4051 * with pre-reset indication.
4052 * NOTE: If we're doing _IOC_BRINGUP, there can be no
4053 * MptResetHandlers[] registered yet.
4059 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
4060 if (MptResetHandlers
[cb_idx
]) {
4061 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4062 "Calling IOC pre_reset handler #%d\n",
4063 ioc
->name
, cb_idx
));
4064 r
+= mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_PRE_RESET
);
4066 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4067 "Calling alt-%s pre_reset handler #%d\n",
4068 ioc
->name
, ioc
->alt_ioc
->name
, cb_idx
));
4069 r
+= mpt_signal_reset(cb_idx
, ioc
->alt_ioc
, MPT_IOC_PRE_RESET
);
4073 /* FIXME? Examine results here? */
4077 cached_fw
= (MpiFwHeader_t
*)ioc
->cached_fw
;
4078 else if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
)
4079 cached_fw
= (MpiFwHeader_t
*)ioc
->alt_ioc
->cached_fw
;
4083 /* If the DownloadBoot operation fails, the
4084 * IOC will be left unusable. This is a fatal error
4085 * case. _diag_reset will return < 0
4087 for (count
= 0; count
< 30; count
++) {
4088 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4089 if (!(diag0val
& MPI_DIAG_RESET_ADAPTER
)) {
4093 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"cached_fw: diag0val=%x count=%d\n",
4094 ioc
->name
, diag0val
, count
));
4096 if (sleepFlag
== CAN_SLEEP
) {
4102 if ((count
= mpt_downloadboot(ioc
, cached_fw
, sleepFlag
)) < 0) {
4103 printk(MYIOC_s_WARN_FMT
4104 "firmware downloadboot failure (%d)!\n", ioc
->name
, count
);
4108 /* Wait for FW to reload and for board
4109 * to go to the READY state.
4110 * Maximum wait is 60 seconds.
4111 * If fail, no error will check again
4112 * with calling program.
4114 for (count
= 0; count
< 60; count
++) {
4115 doorbell
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
4116 doorbell
&= MPI_IOC_STATE_MASK
;
4118 drsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4119 "looking for READY STATE: doorbell=%x"
4120 " count=%d\n", ioc
->name
, doorbell
, count
));
4122 if (doorbell
== MPI_IOC_STATE_READY
) {
4127 if (sleepFlag
== CAN_SLEEP
) {
4134 if (doorbell
!= MPI_IOC_STATE_READY
)
4135 printk(MYIOC_s_ERR_FMT
"Failed to come READY "
4136 "after reset! IocState=%x", ioc
->name
,
4141 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4142 if (ioc
->debug_level
& MPT_DEBUG
) {
4144 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
4145 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG3: diag0=%08x, diag1=%08x\n",
4146 ioc
->name
, diag0val
, diag1val
));
4149 /* Clear RESET_HISTORY bit! Place board in the
4150 * diagnostic mode to update the diag register.
4152 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4154 while ((diag0val
& MPI_DIAG_DRWE
) == 0) {
4155 /* Write magic sequence to WriteSequence register
4156 * Loop until in diagnostic mode
4158 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
4159 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
4160 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
4161 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
4162 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
4163 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
4166 if (sleepFlag
== CAN_SLEEP
) {
4174 printk(MYIOC_s_ERR_FMT
"Enable Diagnostic mode FAILED! (%02xh)\n",
4175 ioc
->name
, diag0val
);
4178 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4180 diag0val
&= ~MPI_DIAG_RESET_HISTORY
;
4181 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
);
4182 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4183 if (diag0val
& MPI_DIAG_RESET_HISTORY
) {
4184 printk(MYIOC_s_WARN_FMT
"ResetHistory bit failed to clear!\n",
4188 /* Disable Diagnostic Mode
4190 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFFFFFFFF);
4192 /* Check FW reload status flags.
4194 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4195 if (diag0val
& (MPI_DIAG_FLASH_BAD_SIG
| MPI_DIAG_RESET_ADAPTER
| MPI_DIAG_DISABLE_ARM
)) {
4196 printk(MYIOC_s_ERR_FMT
"Diagnostic reset FAILED! (%02xh)\n",
4197 ioc
->name
, diag0val
);
4201 if (ioc
->debug_level
& MPT_DEBUG
) {
4203 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
4204 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG4: diag0=%08x, diag1=%08x\n",
4205 ioc
->name
, diag0val
, diag1val
));
4209 * Reset flag that says we've enabled event notification
4211 ioc
->facts
.EventState
= 0;
4214 ioc
->alt_ioc
->facts
.EventState
= 0;
4216 return hard_reset_done
;
4219 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4221 * SendIocReset - Send IOCReset request to MPT adapter.
4222 * @ioc: Pointer to MPT_ADAPTER structure
4223 * @reset_type: reset type, expected values are
4224 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
4225 * @sleepFlag: Specifies whether the process can sleep
4227 * Send IOCReset request to the MPT adapter.
4229 * Returns 0 for success, non-zero for failure.
4232 SendIocReset(MPT_ADAPTER
*ioc
, u8 reset_type
, int sleepFlag
)
4238 drsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending IOC reset(0x%02x)!\n",
4239 ioc
->name
, reset_type
));
4240 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, reset_type
<<MPI_DOORBELL_FUNCTION_SHIFT
);
4241 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
4244 /* FW ACK'd request, wait for READY state
4247 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 15; /* 15 seconds */
4249 while ((state
= mpt_GetIocState(ioc
, 1)) != MPI_IOC_STATE_READY
) {
4253 if (sleepFlag
!= CAN_SLEEP
)
4256 printk(MYIOC_s_ERR_FMT
4257 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
4258 ioc
->name
, state
, (int)((count
+5)/HZ
));
4262 if (sleepFlag
== CAN_SLEEP
) {
4265 mdelay (1); /* 1 msec delay */
4270 * Cleanup all event stuff for this IOC; re-issue EventNotification
4271 * request if needed.
4273 if (ioc
->facts
.Function
)
4274 ioc
->facts
.EventState
= 0;
4279 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4281 * initChainBuffers - Allocate memory for and initialize chain buffers
4282 * @ioc: Pointer to MPT_ADAPTER structure
4284 * Allocates memory for and initializes chain buffers,
4285 * chain buffer control arrays and spinlock.
4288 initChainBuffers(MPT_ADAPTER
*ioc
)
4291 int sz
, ii
, num_chain
;
4292 int scale
, num_sge
, numSGE
;
4294 /* ReqToChain size must equal the req_depth
4297 if (ioc
->ReqToChain
== NULL
) {
4298 sz
= ioc
->req_depth
* sizeof(int);
4299 mem
= kmalloc(sz
, GFP_ATOMIC
);
4303 ioc
->ReqToChain
= (int *) mem
;
4304 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReqToChain alloc @ %p, sz=%d bytes\n",
4305 ioc
->name
, mem
, sz
));
4306 mem
= kmalloc(sz
, GFP_ATOMIC
);
4310 ioc
->RequestNB
= (int *) mem
;
4311 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestNB alloc @ %p, sz=%d bytes\n",
4312 ioc
->name
, mem
, sz
));
4314 for (ii
= 0; ii
< ioc
->req_depth
; ii
++) {
4315 ioc
->ReqToChain
[ii
] = MPT_HOST_NO_CHAIN
;
4318 /* ChainToChain size must equal the total number
4319 * of chain buffers to be allocated.
4322 * Calculate the number of chain buffers needed(plus 1) per I/O
4323 * then multiply the maximum number of simultaneous cmds
4325 * num_sge = num sge in request frame + last chain buffer
4326 * scale = num sge per chain buffer if no chain element
4328 scale
= ioc
->req_sz
/ ioc
->SGE_size
;
4329 if (ioc
->sg_addr_size
== sizeof(u64
))
4330 num_sge
= scale
+ (ioc
->req_sz
- 60) / ioc
->SGE_size
;
4332 num_sge
= 1 + scale
+ (ioc
->req_sz
- 64) / ioc
->SGE_size
;
4334 if (ioc
->sg_addr_size
== sizeof(u64
)) {
4335 numSGE
= (scale
- 1) * (ioc
->facts
.MaxChainDepth
-1) + scale
+
4336 (ioc
->req_sz
- 60) / ioc
->SGE_size
;
4338 numSGE
= 1 + (scale
- 1) * (ioc
->facts
.MaxChainDepth
-1) +
4339 scale
+ (ioc
->req_sz
- 64) / ioc
->SGE_size
;
4341 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"num_sge=%d numSGE=%d\n",
4342 ioc
->name
, num_sge
, numSGE
));
4344 if (ioc
->bus_type
== FC
) {
4345 if (numSGE
> MPT_SCSI_FC_SG_DEPTH
)
4346 numSGE
= MPT_SCSI_FC_SG_DEPTH
;
4348 if (numSGE
> MPT_SCSI_SG_DEPTH
)
4349 numSGE
= MPT_SCSI_SG_DEPTH
;
4353 while (numSGE
- num_sge
> 0) {
4355 num_sge
+= (scale
- 1);
4359 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Now numSGE=%d num_sge=%d num_chain=%d\n",
4360 ioc
->name
, numSGE
, num_sge
, num_chain
));
4362 if (ioc
->bus_type
== SPI
)
4363 num_chain
*= MPT_SCSI_CAN_QUEUE
;
4365 num_chain
*= MPT_FC_CAN_QUEUE
;
4367 ioc
->num_chain
= num_chain
;
4369 sz
= num_chain
* sizeof(int);
4370 if (ioc
->ChainToChain
== NULL
) {
4371 mem
= kmalloc(sz
, GFP_ATOMIC
);
4375 ioc
->ChainToChain
= (int *) mem
;
4376 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainToChain alloc @ %p, sz=%d bytes\n",
4377 ioc
->name
, mem
, sz
));
4379 mem
= (u8
*) ioc
->ChainToChain
;
4381 memset(mem
, 0xFF, sz
);
4385 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4387 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
4388 * @ioc: Pointer to MPT_ADAPTER structure
4390 * This routine allocates memory for the MPT reply and request frame
4391 * pools (if necessary), and primes the IOC reply FIFO with
4394 * Returns 0 for success, non-zero for failure.
4397 PrimeIocFifos(MPT_ADAPTER
*ioc
)
4400 unsigned long flags
;
4401 dma_addr_t alloc_dma
;
4403 int i
, reply_sz
, sz
, total_size
, num_chain
;
4408 /* Prime reply FIFO... */
4410 if (ioc
->reply_frames
== NULL
) {
4411 if ( (num_chain
= initChainBuffers(ioc
)) < 0)
4414 * 1078 errata workaround for the 36GB limitation
4416 if (ioc
->pcidev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1078
&&
4417 ioc
->dma_mask
> DMA_BIT_MASK(35)) {
4418 if (!pci_set_dma_mask(ioc
->pcidev
, DMA_BIT_MASK(32))
4419 && !pci_set_consistent_dma_mask(ioc
->pcidev
,
4420 DMA_BIT_MASK(32))) {
4421 dma_mask
= DMA_BIT_MASK(35);
4422 d36memprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4423 "setting 35 bit addressing for "
4424 "Request/Reply/Chain and Sense Buffers\n",
4427 /*Reseting DMA mask to 64 bit*/
4428 pci_set_dma_mask(ioc
->pcidev
,
4430 pci_set_consistent_dma_mask(ioc
->pcidev
,
4433 printk(MYIOC_s_ERR_FMT
4434 "failed setting 35 bit addressing for "
4435 "Request/Reply/Chain and Sense Buffers\n",
4441 total_size
= reply_sz
= (ioc
->reply_sz
* ioc
->reply_depth
);
4442 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
4443 ioc
->name
, ioc
->reply_sz
, ioc
->reply_depth
));
4444 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffer sz=%d[%x] bytes\n",
4445 ioc
->name
, reply_sz
, reply_sz
));
4447 sz
= (ioc
->req_sz
* ioc
->req_depth
);
4448 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestBuffer sz=%d bytes, RequestDepth=%d\n",
4449 ioc
->name
, ioc
->req_sz
, ioc
->req_depth
));
4450 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestBuffer sz=%d[%x] bytes\n",
4451 ioc
->name
, sz
, sz
));
4454 sz
= num_chain
* ioc
->req_sz
; /* chain buffer pool size */
4455 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainBuffer sz=%d bytes, ChainDepth=%d\n",
4456 ioc
->name
, ioc
->req_sz
, num_chain
));
4457 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
4458 ioc
->name
, sz
, sz
, num_chain
));
4461 mem
= pci_alloc_consistent(ioc
->pcidev
, total_size
, &alloc_dma
);
4463 printk(MYIOC_s_ERR_FMT
"Unable to allocate Reply, Request, Chain Buffers!\n",
4468 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Total alloc @ %p[%p], sz=%d[%x] bytes\n",
4469 ioc
->name
, mem
, (void *)(ulong
)alloc_dma
, total_size
, total_size
));
4471 memset(mem
, 0, total_size
);
4472 ioc
->alloc_total
+= total_size
;
4474 ioc
->alloc_dma
= alloc_dma
;
4475 ioc
->alloc_sz
= total_size
;
4476 ioc
->reply_frames
= (MPT_FRAME_HDR
*) mem
;
4477 ioc
->reply_frames_low_dma
= (u32
) (alloc_dma
& 0xFFFFFFFF);
4479 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffers @ %p[%p]\n",
4480 ioc
->name
, ioc
->reply_frames
, (void *)(ulong
)alloc_dma
));
4482 alloc_dma
+= reply_sz
;
4485 /* Request FIFO - WE manage this! */
4487 ioc
->req_frames
= (MPT_FRAME_HDR
*) mem
;
4488 ioc
->req_frames_dma
= alloc_dma
;
4490 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestBuffers @ %p[%p]\n",
4491 ioc
->name
, mem
, (void *)(ulong
)alloc_dma
));
4493 ioc
->req_frames_low_dma
= (u32
) (alloc_dma
& 0xFFFFFFFF);
4495 #if defined(CONFIG_MTRR) && 0
4497 * Enable Write Combining MTRR for IOC's memory region.
4498 * (at least as much as we can; "size and base must be
4499 * multiples of 4 kiB"
4501 ioc
->mtrr_reg
= mtrr_add(ioc
->req_frames_dma
,
4503 MTRR_TYPE_WRCOMB
, 1);
4504 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"MTRR region registered (base:size=%08x:%x)\n",
4505 ioc
->name
, ioc
->req_frames_dma
, sz
));
4508 for (i
= 0; i
< ioc
->req_depth
; i
++) {
4509 alloc_dma
+= ioc
->req_sz
;
4513 ioc
->ChainBuffer
= mem
;
4514 ioc
->ChainBufferDMA
= alloc_dma
;
4516 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainBuffers @ %p(%p)\n",
4517 ioc
->name
, ioc
->ChainBuffer
, (void *)(ulong
)ioc
->ChainBufferDMA
));
4519 /* Initialize the free chain Q.
4522 INIT_LIST_HEAD(&ioc
->FreeChainQ
);
4524 /* Post the chain buffers to the FreeChainQ.
4526 mem
= (u8
*)ioc
->ChainBuffer
;
4527 for (i
=0; i
< num_chain
; i
++) {
4528 mf
= (MPT_FRAME_HDR
*) mem
;
4529 list_add_tail(&mf
->u
.frame
.linkage
.list
, &ioc
->FreeChainQ
);
4533 /* Initialize Request frames linked list
4535 alloc_dma
= ioc
->req_frames_dma
;
4536 mem
= (u8
*) ioc
->req_frames
;
4538 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
4539 INIT_LIST_HEAD(&ioc
->FreeQ
);
4540 for (i
= 0; i
< ioc
->req_depth
; i
++) {
4541 mf
= (MPT_FRAME_HDR
*) mem
;
4543 /* Queue REQUESTs *internally*! */
4544 list_add_tail(&mf
->u
.frame
.linkage
.list
, &ioc
->FreeQ
);
4548 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
4550 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
4551 ioc
->sense_buf_pool
=
4552 pci_alloc_consistent(ioc
->pcidev
, sz
, &ioc
->sense_buf_pool_dma
);
4553 if (ioc
->sense_buf_pool
== NULL
) {
4554 printk(MYIOC_s_ERR_FMT
"Unable to allocate Sense Buffers!\n",
4559 ioc
->sense_buf_low_dma
= (u32
) (ioc
->sense_buf_pool_dma
& 0xFFFFFFFF);
4560 ioc
->alloc_total
+= sz
;
4561 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SenseBuffers @ %p[%p]\n",
4562 ioc
->name
, ioc
->sense_buf_pool
, (void *)(ulong
)ioc
->sense_buf_pool_dma
));
4566 /* Post Reply frames to FIFO
4568 alloc_dma
= ioc
->alloc_dma
;
4569 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffers @ %p[%p]\n",
4570 ioc
->name
, ioc
->reply_frames
, (void *)(ulong
)alloc_dma
));
4572 for (i
= 0; i
< ioc
->reply_depth
; i
++) {
4573 /* Write each address to the IOC! */
4574 CHIPREG_WRITE32(&ioc
->chip
->ReplyFifo
, alloc_dma
);
4575 alloc_dma
+= ioc
->reply_sz
;
4578 if (dma_mask
== DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc
->pcidev
,
4579 ioc
->dma_mask
) && !pci_set_consistent_dma_mask(ioc
->pcidev
,
4581 d36memprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4582 "restoring 64 bit addressing\n", ioc
->name
));
4588 if (ioc
->alloc
!= NULL
) {
4590 pci_free_consistent(ioc
->pcidev
,
4592 ioc
->alloc
, ioc
->alloc_dma
);
4593 ioc
->reply_frames
= NULL
;
4594 ioc
->req_frames
= NULL
;
4595 ioc
->alloc_total
-= sz
;
4597 if (ioc
->sense_buf_pool
!= NULL
) {
4598 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
4599 pci_free_consistent(ioc
->pcidev
,
4601 ioc
->sense_buf_pool
, ioc
->sense_buf_pool_dma
);
4602 ioc
->sense_buf_pool
= NULL
;
4605 if (dma_mask
== DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc
->pcidev
,
4606 DMA_BIT_MASK(64)) && !pci_set_consistent_dma_mask(ioc
->pcidev
,
4608 d36memprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4609 "restoring 64 bit addressing\n", ioc
->name
));
4614 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4616 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4617 * from IOC via doorbell handshake method.
4618 * @ioc: Pointer to MPT_ADAPTER structure
4619 * @reqBytes: Size of the request in bytes
4620 * @req: Pointer to MPT request frame
4621 * @replyBytes: Expected size of the reply in bytes
4622 * @u16reply: Pointer to area where reply should be written
4623 * @maxwait: Max wait time for a reply (in seconds)
4624 * @sleepFlag: Specifies whether the process can sleep
4626 * NOTES: It is the callers responsibility to byte-swap fields in the
4627 * request which are greater than 1 byte in size. It is also the
4628 * callers responsibility to byte-swap response fields which are
4629 * greater than 1 byte in size.
4631 * Returns 0 for success, non-zero for failure.
4634 mpt_handshake_req_reply_wait(MPT_ADAPTER
*ioc
, int reqBytes
, u32
*req
,
4635 int replyBytes
, u16
*u16reply
, int maxwait
, int sleepFlag
)
4637 MPIDefaultReply_t
*mptReply
;
4642 * Get ready to cache a handshake reply
4644 ioc
->hs_reply_idx
= 0;
4645 mptReply
= (MPIDefaultReply_t
*) ioc
->hs_reply
;
4646 mptReply
->MsgLength
= 0;
4649 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4650 * then tell IOC that we want to handshake a request of N words.
4651 * (WRITE u32val to Doorbell reg).
4653 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4654 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
,
4655 ((MPI_FUNCTION_HANDSHAKE
<<MPI_DOORBELL_FUNCTION_SHIFT
) |
4656 ((reqBytes
/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT
)));
4659 * Wait for IOC's doorbell handshake int
4661 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4664 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4665 ioc
->name
, reqBytes
, t
, failcnt
? " - MISSING DOORBELL HANDSHAKE!" : ""));
4667 /* Read doorbell and check for active bit */
4668 if (!(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & MPI_DOORBELL_ACTIVE
))
4672 * Clear doorbell int (WRITE 0 to IntStatus reg),
4673 * then wait for IOC to ACKnowledge that it's ready for
4674 * our handshake request.
4676 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4677 if (!failcnt
&& (t
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
4682 u8
*req_as_bytes
= (u8
*) req
;
4685 * Stuff request words via doorbell handshake,
4686 * with ACK from IOC for each.
4688 for (ii
= 0; !failcnt
&& ii
< reqBytes
/4; ii
++) {
4689 u32 word
= ((req_as_bytes
[(ii
*4) + 0] << 0) |
4690 (req_as_bytes
[(ii
*4) + 1] << 8) |
4691 (req_as_bytes
[(ii
*4) + 2] << 16) |
4692 (req_as_bytes
[(ii
*4) + 3] << 24));
4694 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, word
);
4695 if ((t
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
4699 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Handshake request frame (@%p) header\n", ioc
->name
, req
));
4700 DBG_DUMP_REQUEST_FRAME_HDR(ioc
, (u32
*)req
);
4702 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HandShake request post done, WaitCnt=%d%s\n",
4703 ioc
->name
, t
, failcnt
? " - MISSING DOORBELL ACK!" : ""));
4706 * Wait for completion of doorbell handshake reply from the IOC
4708 if (!failcnt
&& (t
= WaitForDoorbellReply(ioc
, maxwait
, sleepFlag
)) < 0)
4711 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HandShake reply count=%d%s\n",
4712 ioc
->name
, t
, failcnt
? " - MISSING DOORBELL REPLY!" : ""));
4715 * Copy out the cached reply...
4717 for (ii
=0; ii
< min(replyBytes
/2,mptReply
->MsgLength
*2); ii
++)
4718 u16reply
[ii
] = ioc
->hs_reply
[ii
];
4726 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4728 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4729 * @ioc: Pointer to MPT_ADAPTER structure
4730 * @howlong: How long to wait (in seconds)
4731 * @sleepFlag: Specifies whether the process can sleep
4733 * This routine waits (up to ~2 seconds max) for IOC doorbell
4734 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4735 * bit in its IntStatus register being clear.
4737 * Returns a negative value on failure, else wait loop count.
4740 WaitForDoorbellAck(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
4746 cntdn
= 1000 * howlong
;
4748 if (sleepFlag
== CAN_SLEEP
) {
4751 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4752 if (! (intstat
& MPI_HIS_IOP_DOORBELL_STATUS
))
4759 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4760 if (! (intstat
& MPI_HIS_IOP_DOORBELL_STATUS
))
4767 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitForDoorbell ACK (count=%d)\n",
4772 printk(MYIOC_s_ERR_FMT
"Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4773 ioc
->name
, count
, intstat
);
4777 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4779 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4780 * @ioc: Pointer to MPT_ADAPTER structure
4781 * @howlong: How long to wait (in seconds)
4782 * @sleepFlag: Specifies whether the process can sleep
4784 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4785 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4787 * Returns a negative value on failure, else wait loop count.
4790 WaitForDoorbellInt(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
4796 cntdn
= 1000 * howlong
;
4797 if (sleepFlag
== CAN_SLEEP
) {
4799 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4800 if (intstat
& MPI_HIS_DOORBELL_INTERRUPT
)
4807 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4808 if (intstat
& MPI_HIS_DOORBELL_INTERRUPT
)
4816 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4817 ioc
->name
, count
, howlong
));
4821 printk(MYIOC_s_ERR_FMT
"Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4822 ioc
->name
, count
, intstat
);
4826 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4828 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4829 * @ioc: Pointer to MPT_ADAPTER structure
4830 * @howlong: How long to wait (in seconds)
4831 * @sleepFlag: Specifies whether the process can sleep
4833 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4834 * Reply is cached to IOC private area large enough to hold a maximum
4835 * of 128 bytes of reply data.
4837 * Returns a negative value on failure, else size of reply in WORDS.
4840 WaitForDoorbellReply(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
4845 u16
*hs_reply
= ioc
->hs_reply
;
4846 volatile MPIDefaultReply_t
*mptReply
= (MPIDefaultReply_t
*) ioc
->hs_reply
;
4849 hs_reply
[0] = hs_reply
[1] = hs_reply
[7] = 0;
4852 * Get first two u16's so we can look at IOC's intended reply MsgLength
4855 if ((t
= WaitForDoorbellInt(ioc
, howlong
, sleepFlag
)) < 0) {
4858 hs_reply
[u16cnt
++] = le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4859 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4860 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4863 hs_reply
[u16cnt
++] = le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4864 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4868 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitCnt=%d First handshake reply word=%08x%s\n",
4869 ioc
->name
, t
, le32_to_cpu(*(u32
*)hs_reply
),
4870 failcnt
? " - MISSING DOORBELL HANDSHAKE!" : ""));
4873 * If no error (and IOC said MsgLength is > 0), piece together
4874 * reply 16 bits at a time.
4876 for (u16cnt
=2; !failcnt
&& u16cnt
< (2 * mptReply
->MsgLength
); u16cnt
++) {
4877 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4879 hword
= le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4880 /* don't overflow our IOC hs_reply[] buffer! */
4881 if (u16cnt
< ARRAY_SIZE(ioc
->hs_reply
))
4882 hs_reply
[u16cnt
] = hword
;
4883 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4886 if (!failcnt
&& (t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4888 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4891 printk(MYIOC_s_ERR_FMT
"Handshake reply failure!\n",
4896 else if (u16cnt
!= (2 * mptReply
->MsgLength
)) {
4899 else if ((mptReply
->IOCStatus
& MPI_IOCSTATUS_MASK
) != MPI_IOCSTATUS_SUCCESS
) {
4904 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Got Handshake reply:\n", ioc
->name
));
4905 DBG_DUMP_REPLY_FRAME(ioc
, (u32
*)mptReply
);
4907 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4908 ioc
->name
, t
, u16cnt
/2));
4912 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4914 * GetLanConfigPages - Fetch LANConfig pages.
4915 * @ioc: Pointer to MPT_ADAPTER structure
4917 * Return: 0 for success
4918 * -ENOMEM if no memory available
4919 * -EPERM if not allowed due to ISR context
4920 * -EAGAIN if no msg frames currently available
4921 * -EFAULT for non-successful reply or no reply (timeout)
4924 GetLanConfigPages(MPT_ADAPTER
*ioc
)
4926 ConfigPageHeader_t hdr
;
4928 LANPage0_t
*ppage0_alloc
;
4929 dma_addr_t page0_dma
;
4930 LANPage1_t
*ppage1_alloc
;
4931 dma_addr_t page1_dma
;
4936 /* Get LAN Page 0 header */
4937 hdr
.PageVersion
= 0;
4940 hdr
.PageType
= MPI_CONFIG_PAGETYPE_LAN
;
4941 cfg
.cfghdr
.hdr
= &hdr
;
4943 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4948 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
4951 if (hdr
.PageLength
> 0) {
4952 data_sz
= hdr
.PageLength
* 4;
4953 ppage0_alloc
= (LANPage0_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page0_dma
);
4956 memset((u8
*)ppage0_alloc
, 0, data_sz
);
4957 cfg
.physAddr
= page0_dma
;
4958 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4960 if ((rc
= mpt_config(ioc
, &cfg
)) == 0) {
4962 copy_sz
= min_t(int, sizeof(LANPage0_t
), data_sz
);
4963 memcpy(&ioc
->lan_cnfg_page0
, ppage0_alloc
, copy_sz
);
4967 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage0_alloc
, page0_dma
);
4970 * Normalize endianness of structure data,
4971 * by byte-swapping all > 1 byte fields!
4980 /* Get LAN Page 1 header */
4981 hdr
.PageVersion
= 0;
4984 hdr
.PageType
= MPI_CONFIG_PAGETYPE_LAN
;
4985 cfg
.cfghdr
.hdr
= &hdr
;
4987 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4991 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
4994 if (hdr
.PageLength
== 0)
4997 data_sz
= hdr
.PageLength
* 4;
4999 ppage1_alloc
= (LANPage1_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page1_dma
);
5001 memset((u8
*)ppage1_alloc
, 0, data_sz
);
5002 cfg
.physAddr
= page1_dma
;
5003 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5005 if ((rc
= mpt_config(ioc
, &cfg
)) == 0) {
5007 copy_sz
= min_t(int, sizeof(LANPage1_t
), data_sz
);
5008 memcpy(&ioc
->lan_cnfg_page1
, ppage1_alloc
, copy_sz
);
5011 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage1_alloc
, page1_dma
);
5014 * Normalize endianness of structure data,
5015 * by byte-swapping all > 1 byte fields!
5023 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5025 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
5026 * @ioc: Pointer to MPT_ADAPTER structure
5027 * @persist_opcode: see below
5029 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
5030 * devices not currently present.
5031 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
5033 * NOTE: Don't use not this function during interrupt time.
5035 * Returns 0 for success, non-zero error
5038 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5040 mptbase_sas_persist_operation(MPT_ADAPTER
*ioc
, u8 persist_opcode
)
5042 SasIoUnitControlRequest_t
*sasIoUnitCntrReq
;
5043 SasIoUnitControlReply_t
*sasIoUnitCntrReply
;
5044 MPT_FRAME_HDR
*mf
= NULL
;
5045 MPIHeader_t
*mpi_hdr
;
5047 unsigned long timeleft
;
5049 mutex_lock(&ioc
->mptbase_cmds
.mutex
);
5051 /* init the internal cmd struct */
5052 memset(ioc
->mptbase_cmds
.reply
, 0 , MPT_DEFAULT_FRAME_SIZE
);
5053 INITIALIZE_MGMT_STATUS(ioc
->mptbase_cmds
.status
)
5055 /* insure garbage is not sent to fw */
5056 switch(persist_opcode
) {
5058 case MPI_SAS_OP_CLEAR_NOT_PRESENT
:
5059 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT
:
5067 printk(KERN_DEBUG
"%s: persist_opcode=%x\n",
5068 __func__
, persist_opcode
);
5070 /* Get a MF for this command.
5072 if ((mf
= mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
5073 printk(KERN_DEBUG
"%s: no msg frames!\n", __func__
);
5078 mpi_hdr
= (MPIHeader_t
*) mf
;
5079 sasIoUnitCntrReq
= (SasIoUnitControlRequest_t
*)mf
;
5080 memset(sasIoUnitCntrReq
,0,sizeof(SasIoUnitControlRequest_t
));
5081 sasIoUnitCntrReq
->Function
= MPI_FUNCTION_SAS_IO_UNIT_CONTROL
;
5082 sasIoUnitCntrReq
->MsgContext
= mpi_hdr
->MsgContext
;
5083 sasIoUnitCntrReq
->Operation
= persist_opcode
;
5085 mpt_put_msg_frame(mpt_base_index
, ioc
, mf
);
5086 timeleft
= wait_for_completion_timeout(&ioc
->mptbase_cmds
.done
, 10*HZ
);
5087 if (!(ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_COMMAND_GOOD
)) {
5089 printk(KERN_DEBUG
"%s: failed\n", __func__
);
5090 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_DID_IOCRESET
)
5093 printk(KERN_DEBUG
"%s: Issuing Reset from %s!!\n",
5094 ioc
->name
, __func__
);
5095 mpt_HardResetHandler(ioc
, CAN_SLEEP
);
5096 mpt_free_msg_frame(ioc
, mf
);
5101 if (!(ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_RF_VALID
)) {
5106 sasIoUnitCntrReply
=
5107 (SasIoUnitControlReply_t
*)ioc
->mptbase_cmds
.reply
;
5108 if (le16_to_cpu(sasIoUnitCntrReply
->IOCStatus
) != MPI_IOCSTATUS_SUCCESS
) {
5109 printk(KERN_DEBUG
"%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
5110 __func__
, sasIoUnitCntrReply
->IOCStatus
,
5111 sasIoUnitCntrReply
->IOCLogInfo
);
5112 printk(KERN_DEBUG
"%s: failed\n", __func__
);
5115 printk(KERN_DEBUG
"%s: success\n", __func__
);
5118 CLEAR_MGMT_STATUS(ioc
->mptbase_cmds
.status
)
5119 mutex_unlock(&ioc
->mptbase_cmds
.mutex
);
5123 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5126 mptbase_raid_process_event_data(MPT_ADAPTER
*ioc
,
5127 MpiEventDataRaid_t
* pRaidEventData
)
5136 volume
= pRaidEventData
->VolumeID
;
5137 reason
= pRaidEventData
->ReasonCode
;
5138 disk
= pRaidEventData
->PhysDiskNum
;
5139 status
= le32_to_cpu(pRaidEventData
->SettingsStatus
);
5140 flags
= (status
>> 0) & 0xff;
5141 state
= (status
>> 8) & 0xff;
5143 if (reason
== MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
) {
5147 if ((reason
>= MPI_EVENT_RAID_RC_PHYSDISK_CREATED
&&
5148 reason
<= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
) ||
5149 (reason
== MPI_EVENT_RAID_RC_SMART_DATA
)) {
5150 printk(MYIOC_s_INFO_FMT
"RAID STATUS CHANGE for PhysDisk %d id=%d\n",
5151 ioc
->name
, disk
, volume
);
5153 printk(MYIOC_s_INFO_FMT
"RAID STATUS CHANGE for VolumeID %d\n",
5158 case MPI_EVENT_RAID_RC_VOLUME_CREATED
:
5159 printk(MYIOC_s_INFO_FMT
" volume has been created\n",
5163 case MPI_EVENT_RAID_RC_VOLUME_DELETED
:
5165 printk(MYIOC_s_INFO_FMT
" volume has been deleted\n",
5169 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED
:
5170 printk(MYIOC_s_INFO_FMT
" volume settings have been changed\n",
5174 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED
:
5175 printk(MYIOC_s_INFO_FMT
" volume is now %s%s%s%s\n",
5177 state
== MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
5179 : state
== MPI_RAIDVOL0_STATUS_STATE_DEGRADED
5181 : state
== MPI_RAIDVOL0_STATUS_STATE_FAILED
5184 flags
& MPI_RAIDVOL0_STATUS_FLAG_ENABLED
5186 flags
& MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
5187 ? ", quiesced" : "",
5188 flags
& MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
5189 ? ", resync in progress" : "" );
5192 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED
:
5193 printk(MYIOC_s_INFO_FMT
" volume membership of PhysDisk %d has changed\n",
5197 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED
:
5198 printk(MYIOC_s_INFO_FMT
" PhysDisk has been created\n",
5202 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED
:
5203 printk(MYIOC_s_INFO_FMT
" PhysDisk has been deleted\n",
5207 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED
:
5208 printk(MYIOC_s_INFO_FMT
" PhysDisk settings have been changed\n",
5212 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
:
5213 printk(MYIOC_s_INFO_FMT
" PhysDisk is now %s%s%s\n",
5215 state
== MPI_PHYSDISK0_STATUS_ONLINE
5217 : state
== MPI_PHYSDISK0_STATUS_MISSING
5219 : state
== MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
5221 : state
== MPI_PHYSDISK0_STATUS_FAILED
5223 : state
== MPI_PHYSDISK0_STATUS_INITIALIZING
5225 : state
== MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
5226 ? "offline requested"
5227 : state
== MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
5228 ? "failed requested"
5229 : state
== MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
5232 flags
& MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
5233 ? ", out of sync" : "",
5234 flags
& MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
5235 ? ", quiesced" : "" );
5238 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
:
5239 printk(MYIOC_s_INFO_FMT
" Domain Validation needed for PhysDisk %d\n",
5243 case MPI_EVENT_RAID_RC_SMART_DATA
:
5244 printk(MYIOC_s_INFO_FMT
" SMART data received, ASC/ASCQ = %02xh/%02xh\n",
5245 ioc
->name
, pRaidEventData
->ASC
, pRaidEventData
->ASCQ
);
5248 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED
:
5249 printk(MYIOC_s_INFO_FMT
" replacement of PhysDisk %d has started\n",
5255 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5257 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
5258 * @ioc: Pointer to MPT_ADAPTER structure
5260 * Returns: 0 for success
5261 * -ENOMEM if no memory available
5262 * -EPERM if not allowed due to ISR context
5263 * -EAGAIN if no msg frames currently available
5264 * -EFAULT for non-successful reply or no reply (timeout)
5267 GetIoUnitPage2(MPT_ADAPTER
*ioc
)
5269 ConfigPageHeader_t hdr
;
5271 IOUnitPage2_t
*ppage_alloc
;
5272 dma_addr_t page_dma
;
5276 /* Get the page header */
5277 hdr
.PageVersion
= 0;
5280 hdr
.PageType
= MPI_CONFIG_PAGETYPE_IO_UNIT
;
5281 cfg
.cfghdr
.hdr
= &hdr
;
5283 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5288 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
5291 if (hdr
.PageLength
== 0)
5294 /* Read the config page */
5295 data_sz
= hdr
.PageLength
* 4;
5297 ppage_alloc
= (IOUnitPage2_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page_dma
);
5299 memset((u8
*)ppage_alloc
, 0, data_sz
);
5300 cfg
.physAddr
= page_dma
;
5301 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5303 /* If Good, save data */
5304 if ((rc
= mpt_config(ioc
, &cfg
)) == 0)
5305 ioc
->biosVersion
= le32_to_cpu(ppage_alloc
->BiosVersion
);
5307 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage_alloc
, page_dma
);
5313 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5315 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
5316 * @ioc: Pointer to a Adapter Strucutre
5317 * @portnum: IOC port number
5319 * Return: -EFAULT if read of config page header fails
5321 * If read of SCSI Port Page 0 fails,
5322 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5323 * Adapter settings: async, narrow
5325 * If read of SCSI Port Page 2 fails,
5326 * Adapter settings valid
5327 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5332 * CHECK - what type of locking mechanisms should be used????
5335 mpt_GetScsiPortSettings(MPT_ADAPTER
*ioc
, int portnum
)
5340 ConfigPageHeader_t header
;
5346 if (!ioc
->spi_data
.nvram
) {
5349 sz
= MPT_MAX_SCSI_DEVICES
* sizeof(int);
5350 mem
= kmalloc(sz
, GFP_ATOMIC
);
5354 ioc
->spi_data
.nvram
= (int *) mem
;
5356 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SCSI device NVRAM settings @ %p, sz=%d\n",
5357 ioc
->name
, ioc
->spi_data
.nvram
, sz
));
5360 /* Invalidate NVRAM information
5362 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
5363 ioc
->spi_data
.nvram
[ii
] = MPT_HOST_NVRAM_INVALID
;
5366 /* Read SPP0 header, allocate memory, then read page.
5368 header
.PageVersion
= 0;
5369 header
.PageLength
= 0;
5370 header
.PageNumber
= 0;
5371 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_PORT
;
5372 cfg
.cfghdr
.hdr
= &header
;
5374 cfg
.pageAddr
= portnum
;
5375 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5377 cfg
.timeout
= 0; /* use default */
5378 if (mpt_config(ioc
, &cfg
) != 0)
5381 if (header
.PageLength
> 0) {
5382 pbuf
= pci_alloc_consistent(ioc
->pcidev
, header
.PageLength
* 4, &buf_dma
);
5384 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5385 cfg
.physAddr
= buf_dma
;
5386 if (mpt_config(ioc
, &cfg
) != 0) {
5387 ioc
->spi_data
.maxBusWidth
= MPT_NARROW
;
5388 ioc
->spi_data
.maxSyncOffset
= 0;
5389 ioc
->spi_data
.minSyncFactor
= MPT_ASYNC
;
5390 ioc
->spi_data
.busType
= MPT_HOST_BUS_UNKNOWN
;
5392 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5393 "Unable to read PortPage0 minSyncFactor=%x\n",
5394 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
5396 /* Save the Port Page 0 data
5398 SCSIPortPage0_t
*pPP0
= (SCSIPortPage0_t
*) pbuf
;
5399 pPP0
->Capabilities
= le32_to_cpu(pPP0
->Capabilities
);
5400 pPP0
->PhysicalInterface
= le32_to_cpu(pPP0
->PhysicalInterface
);
5402 if ( (pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_QAS
) == 0 ) {
5403 ioc
->spi_data
.noQas
|= MPT_TARGET_NO_NEGO_QAS
;
5404 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5405 "noQas due to Capabilities=%x\n",
5406 ioc
->name
, pPP0
->Capabilities
));
5408 ioc
->spi_data
.maxBusWidth
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_WIDE
? 1 : 0;
5409 data
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK
;
5411 ioc
->spi_data
.maxSyncOffset
= (u8
) (data
>> 16);
5412 data
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK
;
5413 ioc
->spi_data
.minSyncFactor
= (u8
) (data
>> 8);
5414 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5415 "PortPage0 minSyncFactor=%x\n",
5416 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
5418 ioc
->spi_data
.maxSyncOffset
= 0;
5419 ioc
->spi_data
.minSyncFactor
= MPT_ASYNC
;
5422 ioc
->spi_data
.busType
= pPP0
->PhysicalInterface
& MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK
;
5424 /* Update the minSyncFactor based on bus type.
5426 if ((ioc
->spi_data
.busType
== MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD
) ||
5427 (ioc
->spi_data
.busType
== MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE
)) {
5429 if (ioc
->spi_data
.minSyncFactor
< MPT_ULTRA
) {
5430 ioc
->spi_data
.minSyncFactor
= MPT_ULTRA
;
5431 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5432 "HVD or SE detected, minSyncFactor=%x\n",
5433 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
5438 pci_free_consistent(ioc
->pcidev
, header
.PageLength
* 4, pbuf
, buf_dma
);
5443 /* SCSI Port Page 2 - Read the header then the page.
5445 header
.PageVersion
= 0;
5446 header
.PageLength
= 0;
5447 header
.PageNumber
= 2;
5448 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_PORT
;
5449 cfg
.cfghdr
.hdr
= &header
;
5451 cfg
.pageAddr
= portnum
;
5452 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5454 if (mpt_config(ioc
, &cfg
) != 0)
5457 if (header
.PageLength
> 0) {
5458 /* Allocate memory and read SCSI Port Page 2
5460 pbuf
= pci_alloc_consistent(ioc
->pcidev
, header
.PageLength
* 4, &buf_dma
);
5462 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_NVRAM
;
5463 cfg
.physAddr
= buf_dma
;
5464 if (mpt_config(ioc
, &cfg
) != 0) {
5465 /* Nvram data is left with INVALID mark
5468 } else if (ioc
->pcidev
->vendor
== PCI_VENDOR_ID_ATTO
) {
5470 /* This is an ATTO adapter, read Page2 accordingly
5472 ATTO_SCSIPortPage2_t
*pPP2
= (ATTO_SCSIPortPage2_t
*) pbuf
;
5473 ATTODeviceInfo_t
*pdevice
= NULL
;
5476 /* Save the Port Page 2 data
5477 * (reformat into a 32bit quantity)
5479 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
5480 pdevice
= &pPP2
->DeviceSettings
[ii
];
5481 ATTOFlags
= le16_to_cpu(pdevice
->ATTOFlags
);
5484 /* Translate ATTO device flags to LSI format
5486 if (ATTOFlags
& ATTOFLAG_DISC
)
5487 data
|= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE
);
5488 if (ATTOFlags
& ATTOFLAG_ID_ENB
)
5489 data
|= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE
);
5490 if (ATTOFlags
& ATTOFLAG_LUN_ENB
)
5491 data
|= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE
);
5492 if (ATTOFlags
& ATTOFLAG_TAGGED
)
5493 data
|= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE
);
5494 if (!(ATTOFlags
& ATTOFLAG_WIDE_ENB
))
5495 data
|= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE
);
5497 data
= (data
<< 16) | (pdevice
->Period
<< 8) | 10;
5498 ioc
->spi_data
.nvram
[ii
] = data
;
5501 SCSIPortPage2_t
*pPP2
= (SCSIPortPage2_t
*) pbuf
;
5502 MpiDeviceInfo_t
*pdevice
= NULL
;
5505 * Save "Set to Avoid SCSI Bus Resets" flag
5507 ioc
->spi_data
.bus_reset
=
5508 (le32_to_cpu(pPP2
->PortFlags
) &
5509 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET
) ?
5512 /* Save the Port Page 2 data
5513 * (reformat into a 32bit quantity)
5515 data
= le32_to_cpu(pPP2
->PortFlags
) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK
;
5516 ioc
->spi_data
.PortFlags
= data
;
5517 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
5518 pdevice
= &pPP2
->DeviceSettings
[ii
];
5519 data
= (le16_to_cpu(pdevice
->DeviceFlags
) << 16) |
5520 (pdevice
->SyncFactor
<< 8) | pdevice
->Timeout
;
5521 ioc
->spi_data
.nvram
[ii
] = data
;
5525 pci_free_consistent(ioc
->pcidev
, header
.PageLength
* 4, pbuf
, buf_dma
);
5529 /* Update Adapter limits with those from NVRAM
5530 * Comment: Don't need to do this. Target performance
5531 * parameters will never exceed the adapters limits.
5537 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5539 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
5540 * @ioc: Pointer to a Adapter Strucutre
5541 * @portnum: IOC port number
5543 * Return: -EFAULT if read of config page header fails
5547 mpt_readScsiDevicePageHeaders(MPT_ADAPTER
*ioc
, int portnum
)
5550 ConfigPageHeader_t header
;
5552 /* Read the SCSI Device Page 1 header
5554 header
.PageVersion
= 0;
5555 header
.PageLength
= 0;
5556 header
.PageNumber
= 1;
5557 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_DEVICE
;
5558 cfg
.cfghdr
.hdr
= &header
;
5560 cfg
.pageAddr
= portnum
;
5561 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5564 if (mpt_config(ioc
, &cfg
) != 0)
5567 ioc
->spi_data
.sdp1version
= cfg
.cfghdr
.hdr
->PageVersion
;
5568 ioc
->spi_data
.sdp1length
= cfg
.cfghdr
.hdr
->PageLength
;
5570 header
.PageVersion
= 0;
5571 header
.PageLength
= 0;
5572 header
.PageNumber
= 0;
5573 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_DEVICE
;
5574 if (mpt_config(ioc
, &cfg
) != 0)
5577 ioc
->spi_data
.sdp0version
= cfg
.cfghdr
.hdr
->PageVersion
;
5578 ioc
->spi_data
.sdp0length
= cfg
.cfghdr
.hdr
->PageLength
;
5580 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Headers: 0: version %d length %d\n",
5581 ioc
->name
, ioc
->spi_data
.sdp0version
, ioc
->spi_data
.sdp0length
));
5583 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Headers: 1: version %d length %d\n",
5584 ioc
->name
, ioc
->spi_data
.sdp1version
, ioc
->spi_data
.sdp1length
));
5589 * mpt_inactive_raid_list_free - This clears this link list.
5590 * @ioc : pointer to per adapter structure
5593 mpt_inactive_raid_list_free(MPT_ADAPTER
*ioc
)
5595 struct inactive_raid_component_info
*component_info
, *pNext
;
5597 if (list_empty(&ioc
->raid_data
.inactive_list
))
5600 mutex_lock(&ioc
->raid_data
.inactive_list_mutex
);
5601 list_for_each_entry_safe(component_info
, pNext
,
5602 &ioc
->raid_data
.inactive_list
, list
) {
5603 list_del(&component_info
->list
);
5604 kfree(component_info
);
5606 mutex_unlock(&ioc
->raid_data
.inactive_list_mutex
);
5610 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5612 * @ioc : pointer to per adapter structure
5613 * @channel : volume channel
5614 * @id : volume target id
5617 mpt_inactive_raid_volumes(MPT_ADAPTER
*ioc
, u8 channel
, u8 id
)
5620 ConfigPageHeader_t hdr
;
5621 dma_addr_t dma_handle
;
5622 pRaidVolumePage0_t buffer
= NULL
;
5624 RaidPhysDiskPage0_t phys_disk
;
5625 struct inactive_raid_component_info
*component_info
;
5626 int handle_inactive_volumes
;
5628 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5629 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5630 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_VOLUME
;
5631 cfg
.pageAddr
= (channel
<< 8) + id
;
5632 cfg
.cfghdr
.hdr
= &hdr
;
5633 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5635 if (mpt_config(ioc
, &cfg
) != 0)
5638 if (!hdr
.PageLength
)
5641 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5647 cfg
.physAddr
= dma_handle
;
5648 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5650 if (mpt_config(ioc
, &cfg
) != 0)
5653 if (!buffer
->NumPhysDisks
)
5656 handle_inactive_volumes
=
5657 (buffer
->VolumeStatus
.Flags
& MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE
||
5658 (buffer
->VolumeStatus
.Flags
& MPI_RAIDVOL0_STATUS_FLAG_ENABLED
) == 0 ||
5659 buffer
->VolumeStatus
.State
== MPI_RAIDVOL0_STATUS_STATE_FAILED
||
5660 buffer
->VolumeStatus
.State
== MPI_RAIDVOL0_STATUS_STATE_MISSING
) ? 1 : 0;
5662 if (!handle_inactive_volumes
)
5665 mutex_lock(&ioc
->raid_data
.inactive_list_mutex
);
5666 for (i
= 0; i
< buffer
->NumPhysDisks
; i
++) {
5667 if(mpt_raid_phys_disk_pg0(ioc
,
5668 buffer
->PhysDisk
[i
].PhysDiskNum
, &phys_disk
) != 0)
5671 if ((component_info
= kmalloc(sizeof (*component_info
),
5672 GFP_KERNEL
)) == NULL
)
5675 component_info
->volumeID
= id
;
5676 component_info
->volumeBus
= channel
;
5677 component_info
->d
.PhysDiskNum
= phys_disk
.PhysDiskNum
;
5678 component_info
->d
.PhysDiskBus
= phys_disk
.PhysDiskBus
;
5679 component_info
->d
.PhysDiskID
= phys_disk
.PhysDiskID
;
5680 component_info
->d
.PhysDiskIOC
= phys_disk
.PhysDiskIOC
;
5682 list_add_tail(&component_info
->list
,
5683 &ioc
->raid_data
.inactive_list
);
5685 mutex_unlock(&ioc
->raid_data
.inactive_list_mutex
);
5689 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5694 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5695 * @ioc: Pointer to a Adapter Structure
5696 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5697 * @phys_disk: requested payload data returned
5701 * -EFAULT if read of config page header fails or data pointer not NULL
5702 * -ENOMEM if pci_alloc failed
5705 mpt_raid_phys_disk_pg0(MPT_ADAPTER
*ioc
, u8 phys_disk_num
,
5706 RaidPhysDiskPage0_t
*phys_disk
)
5709 ConfigPageHeader_t hdr
;
5710 dma_addr_t dma_handle
;
5711 pRaidPhysDiskPage0_t buffer
= NULL
;
5714 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5715 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5716 memset(phys_disk
, 0, sizeof(RaidPhysDiskPage0_t
));
5718 hdr
.PageVersion
= MPI_RAIDPHYSDISKPAGE0_PAGEVERSION
;
5719 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_PHYSDISK
;
5720 cfg
.cfghdr
.hdr
= &hdr
;
5722 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5724 if (mpt_config(ioc
, &cfg
) != 0) {
5729 if (!hdr
.PageLength
) {
5734 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5742 cfg
.physAddr
= dma_handle
;
5743 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5744 cfg
.pageAddr
= phys_disk_num
;
5746 if (mpt_config(ioc
, &cfg
) != 0) {
5752 memcpy(phys_disk
, buffer
, sizeof(*buffer
));
5753 phys_disk
->MaxLBA
= le32_to_cpu(buffer
->MaxLBA
);
5758 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5765 * mpt_raid_phys_disk_get_num_paths - returns number paths associated to this phys_num
5766 * @ioc: Pointer to a Adapter Structure
5767 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5770 * returns number paths
5773 mpt_raid_phys_disk_get_num_paths(MPT_ADAPTER
*ioc
, u8 phys_disk_num
)
5776 ConfigPageHeader_t hdr
;
5777 dma_addr_t dma_handle
;
5778 pRaidPhysDiskPage1_t buffer
= NULL
;
5781 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5782 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5784 hdr
.PageVersion
= MPI_RAIDPHYSDISKPAGE1_PAGEVERSION
;
5785 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_PHYSDISK
;
5787 cfg
.cfghdr
.hdr
= &hdr
;
5789 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5791 if (mpt_config(ioc
, &cfg
) != 0) {
5796 if (!hdr
.PageLength
) {
5801 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5809 cfg
.physAddr
= dma_handle
;
5810 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5811 cfg
.pageAddr
= phys_disk_num
;
5813 if (mpt_config(ioc
, &cfg
) != 0) {
5818 rc
= buffer
->NumPhysDiskPaths
;
5822 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5827 EXPORT_SYMBOL(mpt_raid_phys_disk_get_num_paths
);
5830 * mpt_raid_phys_disk_pg1 - returns phys disk page 1
5831 * @ioc: Pointer to a Adapter Structure
5832 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5833 * @phys_disk: requested payload data returned
5837 * -EFAULT if read of config page header fails or data pointer not NULL
5838 * -ENOMEM if pci_alloc failed
5841 mpt_raid_phys_disk_pg1(MPT_ADAPTER
*ioc
, u8 phys_disk_num
,
5842 RaidPhysDiskPage1_t
*phys_disk
)
5845 ConfigPageHeader_t hdr
;
5846 dma_addr_t dma_handle
;
5847 pRaidPhysDiskPage1_t buffer
= NULL
;
5852 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5853 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5856 hdr
.PageVersion
= MPI_RAIDPHYSDISKPAGE1_PAGEVERSION
;
5857 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_PHYSDISK
;
5859 cfg
.cfghdr
.hdr
= &hdr
;
5861 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5863 if (mpt_config(ioc
, &cfg
) != 0) {
5868 if (!hdr
.PageLength
) {
5873 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5881 cfg
.physAddr
= dma_handle
;
5882 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5883 cfg
.pageAddr
= phys_disk_num
;
5885 if (mpt_config(ioc
, &cfg
) != 0) {
5890 phys_disk
->NumPhysDiskPaths
= buffer
->NumPhysDiskPaths
;
5891 phys_disk
->PhysDiskNum
= phys_disk_num
;
5892 for (i
= 0; i
< phys_disk
->NumPhysDiskPaths
; i
++) {
5893 phys_disk
->Path
[i
].PhysDiskID
= buffer
->Path
[i
].PhysDiskID
;
5894 phys_disk
->Path
[i
].PhysDiskBus
= buffer
->Path
[i
].PhysDiskBus
;
5895 phys_disk
->Path
[i
].OwnerIdentifier
=
5896 buffer
->Path
[i
].OwnerIdentifier
;
5897 phys_disk
->Path
[i
].Flags
= le16_to_cpu(buffer
->Path
[i
].Flags
);
5898 memcpy(&sas_address
, &buffer
->Path
[i
].WWID
, sizeof(__le64
));
5899 sas_address
= le64_to_cpu(sas_address
);
5900 memcpy(&phys_disk
->Path
[i
].WWID
, &sas_address
, sizeof(__le64
));
5901 memcpy(&sas_address
,
5902 &buffer
->Path
[i
].OwnerWWID
, sizeof(__le64
));
5903 sas_address
= le64_to_cpu(sas_address
);
5904 memcpy(&phys_disk
->Path
[i
].OwnerWWID
,
5905 &sas_address
, sizeof(__le64
));
5911 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5916 EXPORT_SYMBOL(mpt_raid_phys_disk_pg1
);
5920 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5921 * @ioc: Pointer to a Adapter Strucutre
5925 * -EFAULT if read of config page header fails or data pointer not NULL
5926 * -ENOMEM if pci_alloc failed
5929 mpt_findImVolumes(MPT_ADAPTER
*ioc
)
5933 dma_addr_t ioc2_dma
;
5935 ConfigPageHeader_t header
;
5940 if (!ioc
->ir_firmware
)
5943 /* Free the old page
5945 kfree(ioc
->raid_data
.pIocPg2
);
5946 ioc
->raid_data
.pIocPg2
= NULL
;
5947 mpt_inactive_raid_list_free(ioc
);
5949 /* Read IOCP2 header then the page.
5951 header
.PageVersion
= 0;
5952 header
.PageLength
= 0;
5953 header
.PageNumber
= 2;
5954 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
5955 cfg
.cfghdr
.hdr
= &header
;
5958 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5961 if (mpt_config(ioc
, &cfg
) != 0)
5964 if (header
.PageLength
== 0)
5967 iocpage2sz
= header
.PageLength
* 4;
5968 pIoc2
= pci_alloc_consistent(ioc
->pcidev
, iocpage2sz
, &ioc2_dma
);
5972 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5973 cfg
.physAddr
= ioc2_dma
;
5974 if (mpt_config(ioc
, &cfg
) != 0)
5977 mem
= kmalloc(iocpage2sz
, GFP_KERNEL
);
5981 memcpy(mem
, (u8
*)pIoc2
, iocpage2sz
);
5982 ioc
->raid_data
.pIocPg2
= (IOCPage2_t
*) mem
;
5984 mpt_read_ioc_pg_3(ioc
);
5986 for (i
= 0; i
< pIoc2
->NumActiveVolumes
; i
++)
5987 mpt_inactive_raid_volumes(ioc
,
5988 pIoc2
->RaidVolume
[i
].VolumeBus
,
5989 pIoc2
->RaidVolume
[i
].VolumeID
);
5992 pci_free_consistent(ioc
->pcidev
, iocpage2sz
, pIoc2
, ioc2_dma
);
5998 mpt_read_ioc_pg_3(MPT_ADAPTER
*ioc
)
6003 ConfigPageHeader_t header
;
6004 dma_addr_t ioc3_dma
;
6007 /* Free the old page
6009 kfree(ioc
->raid_data
.pIocPg3
);
6010 ioc
->raid_data
.pIocPg3
= NULL
;
6012 /* There is at least one physical disk.
6013 * Read and save IOC Page 3
6015 header
.PageVersion
= 0;
6016 header
.PageLength
= 0;
6017 header
.PageNumber
= 3;
6018 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
6019 cfg
.cfghdr
.hdr
= &header
;
6022 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
6025 if (mpt_config(ioc
, &cfg
) != 0)
6028 if (header
.PageLength
== 0)
6031 /* Read Header good, alloc memory
6033 iocpage3sz
= header
.PageLength
* 4;
6034 pIoc3
= pci_alloc_consistent(ioc
->pcidev
, iocpage3sz
, &ioc3_dma
);
6038 /* Read the Page and save the data
6039 * into malloc'd memory.
6041 cfg
.physAddr
= ioc3_dma
;
6042 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
6043 if (mpt_config(ioc
, &cfg
) == 0) {
6044 mem
= kmalloc(iocpage3sz
, GFP_KERNEL
);
6046 memcpy(mem
, (u8
*)pIoc3
, iocpage3sz
);
6047 ioc
->raid_data
.pIocPg3
= (IOCPage3_t
*) mem
;
6051 pci_free_consistent(ioc
->pcidev
, iocpage3sz
, pIoc3
, ioc3_dma
);
6057 mpt_read_ioc_pg_4(MPT_ADAPTER
*ioc
)
6061 ConfigPageHeader_t header
;
6062 dma_addr_t ioc4_dma
;
6065 /* Read and save IOC Page 4
6067 header
.PageVersion
= 0;
6068 header
.PageLength
= 0;
6069 header
.PageNumber
= 4;
6070 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
6071 cfg
.cfghdr
.hdr
= &header
;
6074 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
6077 if (mpt_config(ioc
, &cfg
) != 0)
6080 if (header
.PageLength
== 0)
6083 if ( (pIoc4
= ioc
->spi_data
.pIocPg4
) == NULL
) {
6084 iocpage4sz
= (header
.PageLength
+ 4) * 4; /* Allow 4 additional SEP's */
6085 pIoc4
= pci_alloc_consistent(ioc
->pcidev
, iocpage4sz
, &ioc4_dma
);
6088 ioc
->alloc_total
+= iocpage4sz
;
6090 ioc4_dma
= ioc
->spi_data
.IocPg4_dma
;
6091 iocpage4sz
= ioc
->spi_data
.IocPg4Sz
;
6094 /* Read the Page into dma memory.
6096 cfg
.physAddr
= ioc4_dma
;
6097 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
6098 if (mpt_config(ioc
, &cfg
) == 0) {
6099 ioc
->spi_data
.pIocPg4
= (IOCPage4_t
*) pIoc4
;
6100 ioc
->spi_data
.IocPg4_dma
= ioc4_dma
;
6101 ioc
->spi_data
.IocPg4Sz
= iocpage4sz
;
6103 pci_free_consistent(ioc
->pcidev
, iocpage4sz
, pIoc4
, ioc4_dma
);
6104 ioc
->spi_data
.pIocPg4
= NULL
;
6105 ioc
->alloc_total
-= iocpage4sz
;
6110 mpt_read_ioc_pg_1(MPT_ADAPTER
*ioc
)
6114 ConfigPageHeader_t header
;
6115 dma_addr_t ioc1_dma
;
6119 /* Check the Coalescing Timeout in IOC Page 1
6121 header
.PageVersion
= 0;
6122 header
.PageLength
= 0;
6123 header
.PageNumber
= 1;
6124 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
6125 cfg
.cfghdr
.hdr
= &header
;
6128 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
6131 if (mpt_config(ioc
, &cfg
) != 0)
6134 if (header
.PageLength
== 0)
6137 /* Read Header good, alloc memory
6139 iocpage1sz
= header
.PageLength
* 4;
6140 pIoc1
= pci_alloc_consistent(ioc
->pcidev
, iocpage1sz
, &ioc1_dma
);
6144 /* Read the Page and check coalescing timeout
6146 cfg
.physAddr
= ioc1_dma
;
6147 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
6148 if (mpt_config(ioc
, &cfg
) == 0) {
6150 tmp
= le32_to_cpu(pIoc1
->Flags
) & MPI_IOCPAGE1_REPLY_COALESCING
;
6151 if (tmp
== MPI_IOCPAGE1_REPLY_COALESCING
) {
6152 tmp
= le32_to_cpu(pIoc1
->CoalescingTimeout
);
6154 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Coalescing Enabled Timeout = %d\n",
6157 if (tmp
> MPT_COALESCING_TIMEOUT
) {
6158 pIoc1
->CoalescingTimeout
= cpu_to_le32(MPT_COALESCING_TIMEOUT
);
6160 /* Write NVRAM and current
6163 cfg
.action
= MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT
;
6164 if (mpt_config(ioc
, &cfg
) == 0) {
6165 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Reset Current Coalescing Timeout to = %d\n",
6166 ioc
->name
, MPT_COALESCING_TIMEOUT
));
6168 cfg
.action
= MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM
;
6169 if (mpt_config(ioc
, &cfg
) == 0) {
6170 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6171 "Reset NVRAM Coalescing Timeout to = %d\n",
6172 ioc
->name
, MPT_COALESCING_TIMEOUT
));
6174 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6175 "Reset NVRAM Coalescing Timeout Failed\n",
6180 dprintk(ioc
, printk(MYIOC_s_WARN_FMT
6181 "Reset of Current Coalescing Timeout Failed!\n",
6187 dprintk(ioc
, printk(MYIOC_s_WARN_FMT
"Coalescing Disabled\n", ioc
->name
));
6191 pci_free_consistent(ioc
->pcidev
, iocpage1sz
, pIoc1
, ioc1_dma
);
6197 mpt_get_manufacturing_pg_0(MPT_ADAPTER
*ioc
)
6200 ConfigPageHeader_t hdr
;
6202 ManufacturingPage0_t
*pbuf
= NULL
;
6204 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
6205 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
6207 hdr
.PageType
= MPI_CONFIG_PAGETYPE_MANUFACTURING
;
6208 cfg
.cfghdr
.hdr
= &hdr
;
6210 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
6213 if (mpt_config(ioc
, &cfg
) != 0)
6216 if (!cfg
.cfghdr
.hdr
->PageLength
)
6219 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
6220 pbuf
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, &buf_dma
);
6224 cfg
.physAddr
= buf_dma
;
6226 if (mpt_config(ioc
, &cfg
) != 0)
6229 memcpy(ioc
->board_name
, pbuf
->BoardName
, sizeof(ioc
->board_name
));
6230 memcpy(ioc
->board_assembly
, pbuf
->BoardAssembly
, sizeof(ioc
->board_assembly
));
6231 memcpy(ioc
->board_tracer
, pbuf
->BoardTracerNumber
, sizeof(ioc
->board_tracer
));
6236 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, pbuf
, buf_dma
);
6239 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6241 * SendEventNotification - Send EventNotification (on or off) request to adapter
6242 * @ioc: Pointer to MPT_ADAPTER structure
6243 * @EvSwitch: Event switch flags
6244 * @sleepFlag: Specifies whether the process can sleep
6247 SendEventNotification(MPT_ADAPTER
*ioc
, u8 EvSwitch
, int sleepFlag
)
6249 EventNotification_t evn
;
6250 MPIDefaultReply_t reply_buf
;
6252 memset(&evn
, 0, sizeof(EventNotification_t
));
6253 memset(&reply_buf
, 0, sizeof(MPIDefaultReply_t
));
6255 evn
.Function
= MPI_FUNCTION_EVENT_NOTIFICATION
;
6256 evn
.Switch
= EvSwitch
;
6257 evn
.MsgContext
= cpu_to_le32(mpt_base_index
<< 16);
6259 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6260 "Sending EventNotification (%d) request %p\n",
6261 ioc
->name
, EvSwitch
, &evn
));
6263 return mpt_handshake_req_reply_wait(ioc
, sizeof(EventNotification_t
),
6264 (u32
*)&evn
, sizeof(MPIDefaultReply_t
), (u16
*)&reply_buf
, 30,
6268 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6270 * SendEventAck - Send EventAck request to MPT adapter.
6271 * @ioc: Pointer to MPT_ADAPTER structure
6272 * @evnp: Pointer to original EventNotification request
6275 SendEventAck(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*evnp
)
6279 if ((pAck
= (EventAck_t
*) mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
6280 dfailprintk(ioc
, printk(MYIOC_s_WARN_FMT
"%s, no msg frames!!\n",
6281 ioc
->name
, __func__
));
6285 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending EventAck\n", ioc
->name
));
6287 pAck
->Function
= MPI_FUNCTION_EVENT_ACK
;
6288 pAck
->ChainOffset
= 0;
6289 pAck
->Reserved
[0] = pAck
->Reserved
[1] = 0;
6291 pAck
->Reserved1
[0] = pAck
->Reserved1
[1] = pAck
->Reserved1
[2] = 0;
6292 pAck
->Event
= evnp
->Event
;
6293 pAck
->EventContext
= evnp
->EventContext
;
6295 mpt_put_msg_frame(mpt_base_index
, ioc
, (MPT_FRAME_HDR
*)pAck
);
6300 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6302 * mpt_config - Generic function to issue config message
6303 * @ioc: Pointer to an adapter structure
6304 * @pCfg: Pointer to a configuration structure. Struct contains
6305 * action, page address, direction, physical address
6306 * and pointer to a configuration page header
6307 * Page header is updated.
6309 * Returns 0 for success
6310 * -EPERM if not allowed due to ISR context
6311 * -EAGAIN if no msg frames currently available
6312 * -EFAULT for non-successful reply or no reply (timeout)
6315 mpt_config(MPT_ADAPTER
*ioc
, CONFIGPARMS
*pCfg
)
6318 ConfigReply_t
*pReply
;
6319 ConfigExtendedPageHeader_t
*pExtHdr
= NULL
;
6325 u8 page_type
= 0, extend_page
;
6326 unsigned long timeleft
;
6327 unsigned long flags
;
6329 u8 issue_hard_reset
= 0;
6332 /* Prevent calling wait_event() (below), if caller happens
6333 * to be in ISR context, because that is fatal!
6335 in_isr
= in_interrupt();
6337 dcprintk(ioc
, printk(MYIOC_s_WARN_FMT
"Config request not allowed in ISR context!\n",
6342 /* don't send a config page during diag reset */
6343 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
6344 if (ioc
->ioc_reset_in_progress
) {
6345 dfailprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6346 "%s: busy with host reset\n", ioc
->name
, __func__
));
6347 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6350 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6352 /* don't send if no chance of success */
6354 mpt_GetIocState(ioc
, 1) != MPI_IOC_STATE_OPERATIONAL
) {
6355 dfailprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6356 "%s: ioc not operational, %d, %xh\n",
6357 ioc
->name
, __func__
, ioc
->active
,
6358 mpt_GetIocState(ioc
, 0)));
6363 mutex_lock(&ioc
->mptbase_cmds
.mutex
);
6364 /* init the internal cmd struct */
6365 memset(ioc
->mptbase_cmds
.reply
, 0 , MPT_DEFAULT_FRAME_SIZE
);
6366 INITIALIZE_MGMT_STATUS(ioc
->mptbase_cmds
.status
)
6368 /* Get and Populate a free Frame
6370 if ((mf
= mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
6371 dcprintk(ioc
, printk(MYIOC_s_WARN_FMT
6372 "mpt_config: no msg frames!\n", ioc
->name
));
6377 pReq
= (Config_t
*)mf
;
6378 pReq
->Action
= pCfg
->action
;
6380 pReq
->ChainOffset
= 0;
6381 pReq
->Function
= MPI_FUNCTION_CONFIG
;
6383 /* Assume page type is not extended and clear "reserved" fields. */
6384 pReq
->ExtPageLength
= 0;
6385 pReq
->ExtPageType
= 0;
6388 for (ii
=0; ii
< 8; ii
++)
6389 pReq
->Reserved2
[ii
] = 0;
6391 pReq
->Header
.PageVersion
= pCfg
->cfghdr
.hdr
->PageVersion
;
6392 pReq
->Header
.PageLength
= pCfg
->cfghdr
.hdr
->PageLength
;
6393 pReq
->Header
.PageNumber
= pCfg
->cfghdr
.hdr
->PageNumber
;
6394 pReq
->Header
.PageType
= (pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
);
6396 if ((pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
) == MPI_CONFIG_PAGETYPE_EXTENDED
) {
6397 pExtHdr
= (ConfigExtendedPageHeader_t
*)pCfg
->cfghdr
.ehdr
;
6398 pReq
->ExtPageLength
= cpu_to_le16(pExtHdr
->ExtPageLength
);
6399 pReq
->ExtPageType
= pExtHdr
->ExtPageType
;
6400 pReq
->Header
.PageType
= MPI_CONFIG_PAGETYPE_EXTENDED
;
6402 /* Page Length must be treated as a reserved field for the
6405 pReq
->Header
.PageLength
= 0;
6408 pReq
->PageAddress
= cpu_to_le32(pCfg
->pageAddr
);
6410 /* Add a SGE to the config request.
6413 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_WRITE
;
6415 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_READ
;
6417 if ((pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
) ==
6418 MPI_CONFIG_PAGETYPE_EXTENDED
) {
6419 flagsLength
|= pExtHdr
->ExtPageLength
* 4;
6420 page_type
= pReq
->ExtPageType
;
6423 flagsLength
|= pCfg
->cfghdr
.hdr
->PageLength
* 4;
6424 page_type
= pReq
->Header
.PageType
;
6428 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6429 "Sending Config request type 0x%x, page 0x%x and action %d\n",
6430 ioc
->name
, page_type
, pReq
->Header
.PageNumber
, pReq
->Action
));
6432 ioc
->add_sge((char *)&pReq
->PageBufferSGE
, flagsLength
, pCfg
->physAddr
);
6433 timeout
= (pCfg
->timeout
< 15) ? HZ
*15 : HZ
*pCfg
->timeout
;
6434 mpt_put_msg_frame(mpt_base_index
, ioc
, mf
);
6435 timeleft
= wait_for_completion_timeout(&ioc
->mptbase_cmds
.done
,
6437 if (!(ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_COMMAND_GOOD
)) {
6439 dfailprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6440 "Failed Sending Config request type 0x%x, page 0x%x,"
6441 " action %d, status %xh, time left %ld\n\n",
6442 ioc
->name
, page_type
, pReq
->Header
.PageNumber
,
6443 pReq
->Action
, ioc
->mptbase_cmds
.status
, timeleft
));
6444 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_DID_IOCRESET
)
6447 issue_hard_reset
= 1;
6451 if (!(ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_RF_VALID
)) {
6455 pReply
= (ConfigReply_t
*)ioc
->mptbase_cmds
.reply
;
6456 ret
= le16_to_cpu(pReply
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
6457 if (ret
== MPI_IOCSTATUS_SUCCESS
) {
6459 pCfg
->cfghdr
.ehdr
->ExtPageLength
=
6460 le16_to_cpu(pReply
->ExtPageLength
);
6461 pCfg
->cfghdr
.ehdr
->ExtPageType
=
6462 pReply
->ExtPageType
;
6464 pCfg
->cfghdr
.hdr
->PageVersion
= pReply
->Header
.PageVersion
;
6465 pCfg
->cfghdr
.hdr
->PageLength
= pReply
->Header
.PageLength
;
6466 pCfg
->cfghdr
.hdr
->PageNumber
= pReply
->Header
.PageNumber
;
6467 pCfg
->cfghdr
.hdr
->PageType
= pReply
->Header
.PageType
;
6472 printk(MYIOC_s_INFO_FMT
"Retry completed "
6473 "ret=0x%x timeleft=%ld\n",
6474 ioc
->name
, ret
, timeleft
);
6476 dcprintk(ioc
, printk(KERN_DEBUG
"IOCStatus=%04xh, IOCLogInfo=%08xh\n",
6477 ret
, le32_to_cpu(pReply
->IOCLogInfo
)));
6481 CLEAR_MGMT_STATUS(ioc
->mptbase_cmds
.status
)
6482 mutex_unlock(&ioc
->mptbase_cmds
.mutex
);
6483 if (issue_hard_reset
) {
6484 issue_hard_reset
= 0;
6485 printk(MYIOC_s_WARN_FMT
"Issuing Reset from %s!!\n",
6486 ioc
->name
, __func__
);
6487 mpt_HardResetHandler(ioc
, CAN_SLEEP
);
6488 mpt_free_msg_frame(ioc
, mf
);
6489 /* attempt one retry for a timed out command */
6491 printk(MYIOC_s_INFO_FMT
6492 "Attempting Retry Config request"
6493 " type 0x%x, page 0x%x,"
6494 " action %d\n", ioc
->name
, page_type
,
6495 pCfg
->cfghdr
.hdr
->PageNumber
, pCfg
->action
);
6504 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6506 * mpt_ioc_reset - Base cleanup for hard reset
6507 * @ioc: Pointer to the adapter structure
6508 * @reset_phase: Indicates pre- or post-reset functionality
6510 * Remark: Frees resources with internally generated commands.
6513 mpt_ioc_reset(MPT_ADAPTER
*ioc
, int reset_phase
)
6515 switch (reset_phase
) {
6516 case MPT_IOC_SETUP_RESET
:
6517 ioc
->taskmgmt_quiesce_io
= 1;
6518 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6519 "%s: MPT_IOC_SETUP_RESET\n", ioc
->name
, __func__
));
6521 case MPT_IOC_PRE_RESET
:
6522 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6523 "%s: MPT_IOC_PRE_RESET\n", ioc
->name
, __func__
));
6525 case MPT_IOC_POST_RESET
:
6526 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6527 "%s: MPT_IOC_POST_RESET\n", ioc
->name
, __func__
));
6528 /* wake up mptbase_cmds */
6529 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_PENDING
) {
6530 ioc
->mptbase_cmds
.status
|=
6531 MPT_MGMT_STATUS_DID_IOCRESET
;
6532 complete(&ioc
->mptbase_cmds
.done
);
6534 /* wake up taskmgmt_cmds */
6535 if (ioc
->taskmgmt_cmds
.status
& MPT_MGMT_STATUS_PENDING
) {
6536 ioc
->taskmgmt_cmds
.status
|=
6537 MPT_MGMT_STATUS_DID_IOCRESET
;
6538 complete(&ioc
->taskmgmt_cmds
.done
);
6545 return 1; /* currently means nothing really */
6549 #ifdef CONFIG_PROC_FS /* { */
6550 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6552 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
6554 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6556 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
6558 * Returns 0 for success, non-zero for failure.
6561 procmpt_create(void)
6563 struct proc_dir_entry
*ent
;
6565 mpt_proc_root_dir
= proc_mkdir(MPT_PROCFS_MPTBASEDIR
, NULL
);
6566 if (mpt_proc_root_dir
== NULL
)
6569 ent
= create_proc_entry("summary", S_IFREG
|S_IRUGO
, mpt_proc_root_dir
);
6571 ent
->read_proc
= procmpt_summary_read
;
6573 ent
= create_proc_entry("version", S_IFREG
|S_IRUGO
, mpt_proc_root_dir
);
6575 ent
->read_proc
= procmpt_version_read
;
6580 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6582 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
6584 * Returns 0 for success, non-zero for failure.
6587 procmpt_destroy(void)
6589 remove_proc_entry("version", mpt_proc_root_dir
);
6590 remove_proc_entry("summary", mpt_proc_root_dir
);
6591 remove_proc_entry(MPT_PROCFS_MPTBASEDIR
, NULL
);
6594 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6596 * procmpt_summary_read - Handle read request of a summary file
6597 * @buf: Pointer to area to write information
6598 * @start: Pointer to start pointer
6599 * @offset: Offset to start writing
6600 * @request: Amount of read data requested
6601 * @eof: Pointer to EOF integer
6604 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
6605 * Returns number of characters written to process performing the read.
6608 procmpt_summary_read(char *buf
, char **start
, off_t offset
, int request
, int *eof
, void *data
)
6618 mpt_print_ioc_summary(ioc
, out
, &more
, 0, 1);
6622 list_for_each_entry(ioc
, &ioc_list
, list
) {
6625 mpt_print_ioc_summary(ioc
, out
, &more
, 0, 1);
6628 if ((out
-buf
) >= request
)
6635 MPT_PROC_READ_RETURN(buf
,start
,offset
,request
,eof
,len
);
6638 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6640 * procmpt_version_read - Handle read request from /proc/mpt/version.
6641 * @buf: Pointer to area to write information
6642 * @start: Pointer to start pointer
6643 * @offset: Offset to start writing
6644 * @request: Amount of read data requested
6645 * @eof: Pointer to EOF integer
6648 * Returns number of characters written to process performing the read.
6651 procmpt_version_read(char *buf
, char **start
, off_t offset
, int request
, int *eof
, void *data
)
6654 int scsi
, fc
, sas
, lan
, ctl
, targ
, dmp
;
6658 len
= sprintf(buf
, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON
);
6659 len
+= sprintf(buf
+len
, " Fusion MPT base driver\n");
6661 scsi
= fc
= sas
= lan
= ctl
= targ
= dmp
= 0;
6662 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
6664 if (MptCallbacks
[cb_idx
]) {
6665 switch (MptDriverClass
[cb_idx
]) {
6667 if (!scsi
++) drvname
= "SPI host";
6670 if (!fc
++) drvname
= "FC host";
6673 if (!sas
++) drvname
= "SAS host";
6676 if (!lan
++) drvname
= "LAN";
6679 if (!targ
++) drvname
= "SCSI target";
6682 if (!ctl
++) drvname
= "ioctl";
6687 len
+= sprintf(buf
+len
, " Fusion MPT %s driver\n", drvname
);
6691 MPT_PROC_READ_RETURN(buf
,start
,offset
,request
,eof
,len
);
6694 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6696 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
6697 * @buf: Pointer to area to write information
6698 * @start: Pointer to start pointer
6699 * @offset: Offset to start writing
6700 * @request: Amount of read data requested
6701 * @eof: Pointer to EOF integer
6704 * Returns number of characters written to process performing the read.
6707 procmpt_iocinfo_read(char *buf
, char **start
, off_t offset
, int request
, int *eof
, void *data
)
6709 MPT_ADAPTER
*ioc
= data
;
6715 mpt_get_fw_exp_ver(expVer
, ioc
);
6717 len
= sprintf(buf
, "%s:", ioc
->name
);
6718 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)
6719 len
+= sprintf(buf
+len
, " (f/w download boot flag set)");
6720 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6721 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
6723 len
+= sprintf(buf
+len
, "\n ProductID = 0x%04x (%s)\n",
6724 ioc
->facts
.ProductID
,
6726 len
+= sprintf(buf
+len
, " FWVersion = 0x%08x%s", ioc
->facts
.FWVersion
.Word
, expVer
);
6727 if (ioc
->facts
.FWImageSize
)
6728 len
+= sprintf(buf
+len
, " (fw_size=%d)", ioc
->facts
.FWImageSize
);
6729 len
+= sprintf(buf
+len
, "\n MsgVersion = 0x%04x\n", ioc
->facts
.MsgVersion
);
6730 len
+= sprintf(buf
+len
, " FirstWhoInit = 0x%02x\n", ioc
->FirstWhoInit
);
6731 len
+= sprintf(buf
+len
, " EventState = 0x%02x\n", ioc
->facts
.EventState
);
6733 len
+= sprintf(buf
+len
, " CurrentHostMfaHighAddr = 0x%08x\n",
6734 ioc
->facts
.CurrentHostMfaHighAddr
);
6735 len
+= sprintf(buf
+len
, " CurrentSenseBufferHighAddr = 0x%08x\n",
6736 ioc
->facts
.CurrentSenseBufferHighAddr
);
6738 len
+= sprintf(buf
+len
, " MaxChainDepth = 0x%02x frames\n", ioc
->facts
.MaxChainDepth
);
6739 len
+= sprintf(buf
+len
, " MinBlockSize = 0x%02x bytes\n", 4*ioc
->facts
.BlockSize
);
6741 len
+= sprintf(buf
+len
, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6742 (void *)ioc
->req_frames
, (void *)(ulong
)ioc
->req_frames_dma
);
6744 * Rounding UP to nearest 4-kB boundary here...
6746 sz
= (ioc
->req_sz
* ioc
->req_depth
) + 128;
6747 sz
= ((sz
+ 0x1000UL
- 1UL) / 0x1000) * 0x1000;
6748 len
+= sprintf(buf
+len
, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6749 ioc
->req_sz
, ioc
->req_depth
, ioc
->req_sz
*ioc
->req_depth
, sz
);
6750 len
+= sprintf(buf
+len
, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
6751 4*ioc
->facts
.RequestFrameSize
,
6752 ioc
->facts
.GlobalCredits
);
6754 len
+= sprintf(buf
+len
, " Frames @ 0x%p (Dma @ 0x%p)\n",
6755 (void *)ioc
->alloc
, (void *)(ulong
)ioc
->alloc_dma
);
6756 sz
= (ioc
->reply_sz
* ioc
->reply_depth
) + 128;
6757 len
+= sprintf(buf
+len
, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6758 ioc
->reply_sz
, ioc
->reply_depth
, ioc
->reply_sz
*ioc
->reply_depth
, sz
);
6759 len
+= sprintf(buf
+len
, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
6760 ioc
->facts
.CurReplyFrameSize
,
6761 ioc
->facts
.ReplyQueueDepth
);
6763 len
+= sprintf(buf
+len
, " MaxDevices = %d\n",
6764 (ioc
->facts
.MaxDevices
==0) ? 255 : ioc
->facts
.MaxDevices
);
6765 len
+= sprintf(buf
+len
, " MaxBuses = %d\n", ioc
->facts
.MaxBuses
);
6768 for (p
=0; p
< ioc
->facts
.NumberOfPorts
; p
++) {
6769 len
+= sprintf(buf
+len
, " PortNumber = %d (of %d)\n",
6771 ioc
->facts
.NumberOfPorts
);
6772 if (ioc
->bus_type
== FC
) {
6773 if (ioc
->pfacts
[p
].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
) {
6774 u8
*a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
6775 len
+= sprintf(buf
+len
, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6776 a
[5], a
[4], a
[3], a
[2], a
[1], a
[0]);
6778 len
+= sprintf(buf
+len
, " WWN = %08X%08X:%08X%08X\n",
6779 ioc
->fc_port_page0
[p
].WWNN
.High
,
6780 ioc
->fc_port_page0
[p
].WWNN
.Low
,
6781 ioc
->fc_port_page0
[p
].WWPN
.High
,
6782 ioc
->fc_port_page0
[p
].WWPN
.Low
);
6786 MPT_PROC_READ_RETURN(buf
,start
,offset
,request
,eof
,len
);
6789 #endif /* CONFIG_PROC_FS } */
6791 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6793 mpt_get_fw_exp_ver(char *buf
, MPT_ADAPTER
*ioc
)
6796 if ((ioc
->facts
.FWVersion
.Word
>> 24) == 0x0E) {
6797 sprintf(buf
, " (Exp %02d%02d)",
6798 (ioc
->facts
.FWVersion
.Word
>> 16) & 0x00FF, /* Month */
6799 (ioc
->facts
.FWVersion
.Word
>> 8) & 0x1F); /* Day */
6802 if ((ioc
->facts
.FWVersion
.Word
>> 8) & 0x80)
6803 strcat(buf
, " [MDBG]");
6807 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6809 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6810 * @ioc: Pointer to MPT_ADAPTER structure
6811 * @buffer: Pointer to buffer where IOC summary info should be written
6812 * @size: Pointer to number of bytes we wrote (set by this routine)
6813 * @len: Offset at which to start writing in buffer
6814 * @showlan: Display LAN stuff?
6816 * This routine writes (english readable) ASCII text, which represents
6817 * a summary of IOC information, to a buffer.
6820 mpt_print_ioc_summary(MPT_ADAPTER
*ioc
, char *buffer
, int *size
, int len
, int showlan
)
6825 mpt_get_fw_exp_ver(expVer
, ioc
);
6828 * Shorter summary of attached ioc's...
6830 y
= sprintf(buffer
+len
, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6833 MPT_FW_REV_MAGIC_ID_STRING
, /* "FwRev=" or somesuch */
6834 ioc
->facts
.FWVersion
.Word
,
6836 ioc
->facts
.NumberOfPorts
,
6839 if (showlan
&& (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
)) {
6840 u8
*a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
6841 y
+= sprintf(buffer
+len
+y
, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6842 a
[5], a
[4], a
[3], a
[2], a
[1], a
[0]);
6845 y
+= sprintf(buffer
+len
+y
, ", IRQ=%d", ioc
->pci_irq
);
6848 y
+= sprintf(buffer
+len
+y
, " (disabled)");
6850 y
+= sprintf(buffer
+len
+y
, "\n");
6855 * mpt_set_taskmgmt_in_progress_flag - set flags associated with task managment
6856 * @ioc: Pointer to MPT_ADAPTER structure
6858 * Returns 0 for SUCCESS or -1 if FAILED.
6860 * If -1 is return, then it was not possible to set the flags
6863 mpt_set_taskmgmt_in_progress_flag(MPT_ADAPTER
*ioc
)
6865 unsigned long flags
;
6868 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
6869 if (ioc
->ioc_reset_in_progress
|| ioc
->taskmgmt_in_progress
||
6870 (ioc
->alt_ioc
&& ioc
->alt_ioc
->taskmgmt_in_progress
)) {
6875 ioc
->taskmgmt_in_progress
= 1;
6876 ioc
->taskmgmt_quiesce_io
= 1;
6878 ioc
->alt_ioc
->taskmgmt_in_progress
= 1;
6879 ioc
->alt_ioc
->taskmgmt_quiesce_io
= 1;
6882 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6885 EXPORT_SYMBOL(mpt_set_taskmgmt_in_progress_flag
);
6888 * mpt_clear_taskmgmt_in_progress_flag - clear flags associated with task managment
6889 * @ioc: Pointer to MPT_ADAPTER structure
6893 mpt_clear_taskmgmt_in_progress_flag(MPT_ADAPTER
*ioc
)
6895 unsigned long flags
;
6897 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
6898 ioc
->taskmgmt_in_progress
= 0;
6899 ioc
->taskmgmt_quiesce_io
= 0;
6901 ioc
->alt_ioc
->taskmgmt_in_progress
= 0;
6902 ioc
->alt_ioc
->taskmgmt_quiesce_io
= 0;
6904 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6906 EXPORT_SYMBOL(mpt_clear_taskmgmt_in_progress_flag
);
6910 * mpt_halt_firmware - Halts the firmware if it is operational and panic
6912 * @ioc: Pointer to MPT_ADAPTER structure
6916 mpt_halt_firmware(MPT_ADAPTER
*ioc
)
6920 ioc_raw_state
= mpt_GetIocState(ioc
, 0);
6922 if ((ioc_raw_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_FAULT
) {
6923 printk(MYIOC_s_ERR_FMT
"IOC is in FAULT state (%04xh)!!!\n",
6924 ioc
->name
, ioc_raw_state
& MPI_DOORBELL_DATA_MASK
);
6925 panic("%s: IOC Fault (%04xh)!!!\n", ioc
->name
,
6926 ioc_raw_state
& MPI_DOORBELL_DATA_MASK
);
6928 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, 0xC0FFEE00);
6929 panic("%s: Firmware is halted due to command timeout\n",
6933 EXPORT_SYMBOL(mpt_halt_firmware
);
6935 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6939 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6941 * mpt_HardResetHandler - Generic reset handler
6942 * @ioc: Pointer to MPT_ADAPTER structure
6943 * @sleepFlag: Indicates if sleep or schedule must be called.
6945 * Issues SCSI Task Management call based on input arg values.
6946 * If TaskMgmt fails, returns associated SCSI request.
6948 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
6949 * or a non-interrupt thread. In the former, must not call schedule().
6951 * Note: A return of -1 is a FATAL error case, as it means a
6952 * FW reload/initialization failed.
6954 * Returns 0 for SUCCESS or -1 if FAILED.
6957 mpt_HardResetHandler(MPT_ADAPTER
*ioc
, int sleepFlag
)
6961 unsigned long flags
;
6962 unsigned long time_count
;
6964 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HardResetHandler Entered!\n", ioc
->name
));
6966 printk(MYIOC_s_INFO_FMT
"HardResetHandler Entered!\n", ioc
->name
);
6967 printk("MF count 0x%x !\n", ioc
->mfcnt
);
6969 if (mpt_fwfault_debug
)
6970 mpt_halt_firmware(ioc
);
6972 /* Reset the adapter. Prevent more than 1 call to
6973 * mpt_do_ioc_recovery at any instant in time.
6975 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
6976 if (ioc
->ioc_reset_in_progress
) {
6977 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6980 ioc
->ioc_reset_in_progress
= 1;
6982 ioc
->alt_ioc
->ioc_reset_in_progress
= 1;
6983 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6985 /* FIXME: If do_ioc_recovery fails, repeat....
6988 /* The SCSI driver needs to adjust timeouts on all current
6989 * commands prior to the diagnostic reset being issued.
6990 * Prevents timeouts occurring during a diagnostic reset...very bad.
6991 * For all other protocol drivers, this is a no-op.
6993 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
6994 if (MptResetHandlers
[cb_idx
]) {
6995 mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_SETUP_RESET
);
6997 mpt_signal_reset(cb_idx
, ioc
->alt_ioc
,
6998 MPT_IOC_SETUP_RESET
);
7002 time_count
= jiffies
;
7003 rc
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_RECOVER
, sleepFlag
);
7005 printk(KERN_WARNING MYNAM
7006 ": WARNING - (%d) Cannot recover %s\n", rc
, ioc
->name
);
7008 if (ioc
->hard_resets
< -1)
7012 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
7013 ioc
->ioc_reset_in_progress
= 0;
7014 ioc
->taskmgmt_quiesce_io
= 0;
7015 ioc
->taskmgmt_in_progress
= 0;
7017 ioc
->alt_ioc
->ioc_reset_in_progress
= 0;
7018 ioc
->alt_ioc
->taskmgmt_quiesce_io
= 0;
7019 ioc
->alt_ioc
->taskmgmt_in_progress
= 0;
7021 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
7024 printk(MYIOC_s_DEBUG_FMT
7025 "HardResetHandler: completed (%d seconds): %s\n", ioc
->name
,
7026 jiffies_to_msecs(jiffies
- time_count
)/1000, ((rc
== 0) ?
7027 "SUCCESS" : "FAILED")));
7032 #ifdef CONFIG_FUSION_LOGGING
7034 mpt_display_event_info(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*pEventReply
)
7040 char *evStr
= ioc
->evStr
;
7042 event
= le32_to_cpu(pEventReply
->Event
) & 0xFF;
7043 evData0
= le32_to_cpu(pEventReply
->Data
[0]);
7046 case MPI_EVENT_NONE
:
7049 case MPI_EVENT_LOG_DATA
:
7052 case MPI_EVENT_STATE_CHANGE
:
7053 ds
= "State Change";
7055 case MPI_EVENT_UNIT_ATTENTION
:
7056 ds
= "Unit Attention";
7058 case MPI_EVENT_IOC_BUS_RESET
:
7059 ds
= "IOC Bus Reset";
7061 case MPI_EVENT_EXT_BUS_RESET
:
7062 ds
= "External Bus Reset";
7064 case MPI_EVENT_RESCAN
:
7065 ds
= "Bus Rescan Event";
7067 case MPI_EVENT_LINK_STATUS_CHANGE
:
7068 if (evData0
== MPI_EVENT_LINK_STATUS_FAILURE
)
7069 ds
= "Link Status(FAILURE) Change";
7071 ds
= "Link Status(ACTIVE) Change";
7073 case MPI_EVENT_LOOP_STATE_CHANGE
:
7074 if (evData0
== MPI_EVENT_LOOP_STATE_CHANGE_LIP
)
7075 ds
= "Loop State(LIP) Change";
7076 else if (evData0
== MPI_EVENT_LOOP_STATE_CHANGE_LPE
)
7077 ds
= "Loop State(LPE) Change";
7079 ds
= "Loop State(LPB) Change";
7081 case MPI_EVENT_LOGOUT
:
7084 case MPI_EVENT_EVENT_CHANGE
:
7090 case MPI_EVENT_INTEGRATED_RAID
:
7092 u8 ReasonCode
= (u8
)(evData0
>> 16);
7093 switch (ReasonCode
) {
7094 case MPI_EVENT_RAID_RC_VOLUME_CREATED
:
7095 ds
= "Integrated Raid: Volume Created";
7097 case MPI_EVENT_RAID_RC_VOLUME_DELETED
:
7098 ds
= "Integrated Raid: Volume Deleted";
7100 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED
:
7101 ds
= "Integrated Raid: Volume Settings Changed";
7103 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED
:
7104 ds
= "Integrated Raid: Volume Status Changed";
7106 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED
:
7107 ds
= "Integrated Raid: Volume Physdisk Changed";
7109 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED
:
7110 ds
= "Integrated Raid: Physdisk Created";
7112 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED
:
7113 ds
= "Integrated Raid: Physdisk Deleted";
7115 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED
:
7116 ds
= "Integrated Raid: Physdisk Settings Changed";
7118 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
:
7119 ds
= "Integrated Raid: Physdisk Status Changed";
7121 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
:
7122 ds
= "Integrated Raid: Domain Validation Needed";
7124 case MPI_EVENT_RAID_RC_SMART_DATA
:
7125 ds
= "Integrated Raid; Smart Data";
7127 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED
:
7128 ds
= "Integrated Raid: Replace Action Started";
7131 ds
= "Integrated Raid";
7136 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE
:
7137 ds
= "SCSI Device Status Change";
7139 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE
:
7141 u8 id
= (u8
)(evData0
);
7142 u8 channel
= (u8
)(evData0
>> 8);
7143 u8 ReasonCode
= (u8
)(evData0
>> 16);
7144 switch (ReasonCode
) {
7145 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED
:
7146 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7147 "SAS Device Status Change: Added: "
7148 "id=%d channel=%d", id
, channel
);
7150 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING
:
7151 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7152 "SAS Device Status Change: Deleted: "
7153 "id=%d channel=%d", id
, channel
);
7155 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA
:
7156 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7157 "SAS Device Status Change: SMART Data: "
7158 "id=%d channel=%d", id
, channel
);
7160 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED
:
7161 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7162 "SAS Device Status Change: No Persistancy: "
7163 "id=%d channel=%d", id
, channel
);
7165 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED
:
7166 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7167 "SAS Device Status Change: Unsupported Device "
7168 "Discovered : id=%d channel=%d", id
, channel
);
7170 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET
:
7171 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7172 "SAS Device Status Change: Internal Device "
7173 "Reset : id=%d channel=%d", id
, channel
);
7175 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL
:
7176 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7177 "SAS Device Status Change: Internal Task "
7178 "Abort : id=%d channel=%d", id
, channel
);
7180 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL
:
7181 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7182 "SAS Device Status Change: Internal Abort "
7183 "Task Set : id=%d channel=%d", id
, channel
);
7185 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL
:
7186 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7187 "SAS Device Status Change: Internal Clear "
7188 "Task Set : id=%d channel=%d", id
, channel
);
7190 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL
:
7191 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7192 "SAS Device Status Change: Internal Query "
7193 "Task : id=%d channel=%d", id
, channel
);
7196 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7197 "SAS Device Status Change: Unknown: "
7198 "id=%d channel=%d", id
, channel
);
7203 case MPI_EVENT_ON_BUS_TIMER_EXPIRED
:
7204 ds
= "Bus Timer Expired";
7206 case MPI_EVENT_QUEUE_FULL
:
7208 u16 curr_depth
= (u16
)(evData0
>> 16);
7209 u8 channel
= (u8
)(evData0
>> 8);
7210 u8 id
= (u8
)(evData0
);
7212 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7213 "Queue Full: channel=%d id=%d depth=%d",
7214 channel
, id
, curr_depth
);
7217 case MPI_EVENT_SAS_SES
:
7218 ds
= "SAS SES Event";
7220 case MPI_EVENT_PERSISTENT_TABLE_FULL
:
7221 ds
= "Persistent Table Full";
7223 case MPI_EVENT_SAS_PHY_LINK_STATUS
:
7225 u8 LinkRates
= (u8
)(evData0
>> 8);
7226 u8 PhyNumber
= (u8
)(evData0
);
7227 LinkRates
= (LinkRates
& MPI_EVENT_SAS_PLS_LR_CURRENT_MASK
) >>
7228 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT
;
7229 switch (LinkRates
) {
7230 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN
:
7231 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7232 "SAS PHY Link Status: Phy=%d:"
7233 " Rate Unknown",PhyNumber
);
7235 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED
:
7236 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7237 "SAS PHY Link Status: Phy=%d:"
7238 " Phy Disabled",PhyNumber
);
7240 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION
:
7241 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7242 "SAS PHY Link Status: Phy=%d:"
7243 " Failed Speed Nego",PhyNumber
);
7245 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE
:
7246 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7247 "SAS PHY Link Status: Phy=%d:"
7248 " Sata OOB Completed",PhyNumber
);
7250 case MPI_EVENT_SAS_PLS_LR_RATE_1_5
:
7251 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7252 "SAS PHY Link Status: Phy=%d:"
7253 " Rate 1.5 Gbps",PhyNumber
);
7255 case MPI_EVENT_SAS_PLS_LR_RATE_3_0
:
7256 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7257 "SAS PHY Link Status: Phy=%d:"
7258 " Rate 3.0 Gpbs",PhyNumber
);
7261 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7262 "SAS PHY Link Status: Phy=%d", PhyNumber
);
7267 case MPI_EVENT_SAS_DISCOVERY_ERROR
:
7268 ds
= "SAS Discovery Error";
7270 case MPI_EVENT_IR_RESYNC_UPDATE
:
7272 u8 resync_complete
= (u8
)(evData0
>> 16);
7273 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7274 "IR Resync Update: Complete = %d:",resync_complete
);
7279 u8 id
= (u8
)(evData0
);
7280 u8 channel
= (u8
)(evData0
>> 8);
7281 u8 phys_num
= (u8
)(evData0
>> 24);
7282 u8 ReasonCode
= (u8
)(evData0
>> 16);
7284 switch (ReasonCode
) {
7285 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED
:
7286 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7287 "IR2: LD State Changed: "
7288 "id=%d channel=%d phys_num=%d",
7289 id
, channel
, phys_num
);
7291 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED
:
7292 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7293 "IR2: PD State Changed "
7294 "id=%d channel=%d phys_num=%d",
7295 id
, channel
, phys_num
);
7297 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL
:
7298 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7299 "IR2: Bad Block Table Full: "
7300 "id=%d channel=%d phys_num=%d",
7301 id
, channel
, phys_num
);
7303 case MPI_EVENT_IR2_RC_PD_INSERTED
:
7304 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7305 "IR2: PD Inserted: "
7306 "id=%d channel=%d phys_num=%d",
7307 id
, channel
, phys_num
);
7309 case MPI_EVENT_IR2_RC_PD_REMOVED
:
7310 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7312 "id=%d channel=%d phys_num=%d",
7313 id
, channel
, phys_num
);
7315 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED
:
7316 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7317 "IR2: Foreign CFG Detected: "
7318 "id=%d channel=%d phys_num=%d",
7319 id
, channel
, phys_num
);
7321 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR
:
7322 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7323 "IR2: Rebuild Medium Error: "
7324 "id=%d channel=%d phys_num=%d",
7325 id
, channel
, phys_num
);
7327 case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED
:
7328 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7329 "IR2: Dual Port Added: "
7330 "id=%d channel=%d phys_num=%d",
7331 id
, channel
, phys_num
);
7333 case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED
:
7334 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7335 "IR2: Dual Port Removed: "
7336 "id=%d channel=%d phys_num=%d",
7337 id
, channel
, phys_num
);
7345 case MPI_EVENT_SAS_DISCOVERY
:
7348 ds
= "SAS Discovery: Start";
7350 ds
= "SAS Discovery: Stop";
7353 case MPI_EVENT_LOG_ENTRY_ADDED
:
7354 ds
= "SAS Log Entry Added";
7357 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE
:
7359 u8 phy_num
= (u8
)(evData0
);
7360 u8 port_num
= (u8
)(evData0
>> 8);
7361 u8 port_width
= (u8
)(evData0
>> 16);
7362 u8 primative
= (u8
)(evData0
>> 24);
7363 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7364 "SAS Broadcase Primative: phy=%d port=%d "
7365 "width=%d primative=0x%02x",
7366 phy_num
, port_num
, port_width
, primative
);
7370 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE
:
7372 u8 reason
= (u8
)(evData0
);
7375 case MPI_EVENT_SAS_INIT_RC_ADDED
:
7376 ds
= "SAS Initiator Status Change: Added";
7378 case MPI_EVENT_SAS_INIT_RC_REMOVED
:
7379 ds
= "SAS Initiator Status Change: Deleted";
7382 ds
= "SAS Initiator Status Change";
7388 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW
:
7390 u8 max_init
= (u8
)(evData0
);
7391 u8 current_init
= (u8
)(evData0
>> 8);
7393 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7394 "SAS Initiator Device Table Overflow: max initiators=%02d "
7395 "current initators=%02d",
7396 max_init
, current_init
);
7399 case MPI_EVENT_SAS_SMP_ERROR
:
7401 u8 status
= (u8
)(evData0
);
7402 u8 port_num
= (u8
)(evData0
>> 8);
7403 u8 result
= (u8
)(evData0
>> 16);
7405 if (status
== MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID
)
7406 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7407 "SAS SMP Error: port=%d result=0x%02x",
7409 else if (status
== MPI_EVENT_SAS_SMP_CRC_ERROR
)
7410 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7411 "SAS SMP Error: port=%d : CRC Error",
7413 else if (status
== MPI_EVENT_SAS_SMP_TIMEOUT
)
7414 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7415 "SAS SMP Error: port=%d : Timeout",
7417 else if (status
== MPI_EVENT_SAS_SMP_NO_DESTINATION
)
7418 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7419 "SAS SMP Error: port=%d : No Destination",
7421 else if (status
== MPI_EVENT_SAS_SMP_BAD_DESTINATION
)
7422 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7423 "SAS SMP Error: port=%d : Bad Destination",
7426 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7427 "SAS SMP Error: port=%d : status=0x%02x",
7432 case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE
:
7434 u8 reason
= (u8
)(evData0
);
7437 case MPI_EVENT_SAS_EXP_RC_ADDED
:
7438 ds
= "Expander Status Change: Added";
7440 case MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING
:
7441 ds
= "Expander Status Change: Deleted";
7444 ds
= "Expander Status Change";
7451 * MPT base "custom" events may be added here...
7458 strncpy(evStr
, ds
, EVENT_DESCR_STR_SZ
);
7461 devtprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
7462 "MPT event:(%02Xh) : %s\n",
7463 ioc
->name
, event
, evStr
));
7465 devtverboseprintk(ioc
, printk(KERN_DEBUG MYNAM
7466 ": Event data:\n"));
7467 for (ii
= 0; ii
< le16_to_cpu(pEventReply
->EventDataLength
); ii
++)
7468 devtverboseprintk(ioc
, printk(" %08x",
7469 le32_to_cpu(pEventReply
->Data
[ii
])));
7470 devtverboseprintk(ioc
, printk(KERN_DEBUG
"\n"));
7473 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7475 * ProcessEventNotification - Route EventNotificationReply to all event handlers
7476 * @ioc: Pointer to MPT_ADAPTER structure
7477 * @pEventReply: Pointer to EventNotification reply frame
7478 * @evHandlers: Pointer to integer, number of event handlers
7480 * Routes a received EventNotificationReply to all currently registered
7482 * Returns sum of event handlers return values.
7485 ProcessEventNotification(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*pEventReply
, int *evHandlers
)
7496 * Do platform normalization of values
7498 event
= le32_to_cpu(pEventReply
->Event
) & 0xFF;
7499 evDataLen
= le16_to_cpu(pEventReply
->EventDataLength
);
7501 evData0
= le32_to_cpu(pEventReply
->Data
[0]);
7504 #ifdef CONFIG_FUSION_LOGGING
7506 mpt_display_event_info(ioc
, pEventReply
);
7510 * Do general / base driver event processing
7513 case MPI_EVENT_EVENT_CHANGE
: /* 0A */
7515 u8 evState
= evData0
& 0xFF;
7517 /* CHECKME! What if evState unexpectedly says OFF (0)? */
7519 /* Update EventState field in cached IocFacts */
7520 if (ioc
->facts
.Function
) {
7521 ioc
->facts
.EventState
= evState
;
7525 case MPI_EVENT_INTEGRATED_RAID
:
7526 mptbase_raid_process_event_data(ioc
,
7527 (MpiEventDataRaid_t
*)pEventReply
->Data
);
7534 * Should this event be logged? Events are written sequentially.
7535 * When buffer is full, start again at the top.
7537 if (ioc
->events
&& (ioc
->eventTypes
& ( 1 << event
))) {
7540 idx
= ioc
->eventContext
% MPTCTL_EVENT_LOG_SIZE
;
7542 ioc
->events
[idx
].event
= event
;
7543 ioc
->events
[idx
].eventContext
= ioc
->eventContext
;
7545 for (ii
= 0; ii
< 2; ii
++) {
7547 ioc
->events
[idx
].data
[ii
] = le32_to_cpu(pEventReply
->Data
[ii
]);
7549 ioc
->events
[idx
].data
[ii
] = 0;
7552 ioc
->eventContext
++;
7557 * Call each currently registered protocol event handler.
7559 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
7560 if (MptEvHandlers
[cb_idx
]) {
7561 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
7562 "Routing Event to event handler #%d\n",
7563 ioc
->name
, cb_idx
));
7564 r
+= (*(MptEvHandlers
[cb_idx
]))(ioc
, pEventReply
);
7568 /* FIXME? Examine results here? */
7571 * If needed, send (a single) EventAck.
7573 if (pEventReply
->AckRequired
== MPI_EVENT_NOTIFICATION_ACK_REQUIRED
) {
7574 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
7575 "EventAck required\n",ioc
->name
));
7576 if ((ii
= SendEventAck(ioc
, pEventReply
)) != 0) {
7577 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SendEventAck returned %d\n",
7582 *evHandlers
= handlers
;
7586 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7588 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
7589 * @ioc: Pointer to MPT_ADAPTER structure
7590 * @log_info: U32 LogInfo reply word from the IOC
7592 * Refer to lsi/mpi_log_fc.h.
7595 mpt_fc_log_info(MPT_ADAPTER
*ioc
, u32 log_info
)
7597 char *desc
= "unknown";
7599 switch (log_info
& 0xFF000000) {
7600 case MPI_IOCLOGINFO_FC_INIT_BASE
:
7601 desc
= "FCP Initiator";
7603 case MPI_IOCLOGINFO_FC_TARGET_BASE
:
7604 desc
= "FCP Target";
7606 case MPI_IOCLOGINFO_FC_LAN_BASE
:
7609 case MPI_IOCLOGINFO_FC_MSG_BASE
:
7610 desc
= "MPI Message Layer";
7612 case MPI_IOCLOGINFO_FC_LINK_BASE
:
7615 case MPI_IOCLOGINFO_FC_CTX_BASE
:
7616 desc
= "Context Manager";
7618 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET
:
7619 desc
= "Invalid Field Offset";
7621 case MPI_IOCLOGINFO_FC_STATE_CHANGE
:
7622 desc
= "State Change Info";
7626 printk(MYIOC_s_INFO_FMT
"LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
7627 ioc
->name
, log_info
, desc
, (log_info
& 0xFFFFFF));
7630 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7632 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
7633 * @ioc: Pointer to MPT_ADAPTER structure
7634 * @log_info: U32 LogInfo word from the IOC
7636 * Refer to lsi/sp_log.h.
7639 mpt_spi_log_info(MPT_ADAPTER
*ioc
, u32 log_info
)
7641 u32 info
= log_info
& 0x00FF0000;
7642 char *desc
= "unknown";
7646 desc
= "bug! MID not found";
7650 desc
= "Parity Error";
7654 desc
= "ASYNC Outbound Overrun";
7658 desc
= "SYNC Offset Error";
7666 desc
= "Msg In Overflow";
7674 desc
= "Outbound DMA Overrun";
7678 desc
= "Task Management";
7682 desc
= "Device Problem";
7686 desc
= "Invalid Phase Change";
7690 desc
= "Untagged Table Size";
7695 printk(MYIOC_s_INFO_FMT
"LogInfo(0x%08x): F/W: %s\n", ioc
->name
, log_info
, desc
);
7698 /* strings for sas loginfo */
7699 static char *originator_str
[] = {
7704 static char *iop_code_str
[] = {
7706 "Invalid SAS Address", /* 01h */
7708 "Invalid Page", /* 03h */
7709 "Diag Message Error", /* 04h */
7710 "Task Terminated", /* 05h */
7711 "Enclosure Management", /* 06h */
7712 "Target Mode" /* 07h */
7714 static char *pl_code_str
[] = {
7716 "Open Failure", /* 01h */
7717 "Invalid Scatter Gather List", /* 02h */
7718 "Wrong Relative Offset or Frame Length", /* 03h */
7719 "Frame Transfer Error", /* 04h */
7720 "Transmit Frame Connected Low", /* 05h */
7721 "SATA Non-NCQ RW Error Bit Set", /* 06h */
7722 "SATA Read Log Receive Data Error", /* 07h */
7723 "SATA NCQ Fail All Commands After Error", /* 08h */
7724 "SATA Error in Receive Set Device Bit FIS", /* 09h */
7725 "Receive Frame Invalid Message", /* 0Ah */
7726 "Receive Context Message Valid Error", /* 0Bh */
7727 "Receive Frame Current Frame Error", /* 0Ch */
7728 "SATA Link Down", /* 0Dh */
7729 "Discovery SATA Init W IOS", /* 0Eh */
7730 "Config Invalid Page", /* 0Fh */
7731 "Discovery SATA Init Timeout", /* 10h */
7734 "IO Not Yet Executed", /* 13h */
7735 "IO Executed", /* 14h */
7736 "Persistent Reservation Out Not Affiliation "
7738 "Open Transmit DMA Abort", /* 16h */
7739 "IO Device Missing Delay Retry", /* 17h */
7740 "IO Cancelled Due to Recieve Error", /* 18h */
7748 "Enclosure Management" /* 20h */
7750 static char *ir_code_str
[] = {
7751 "Raid Action Error", /* 00h */
7761 static char *raid_sub_code_str
[] = {
7763 "Volume Creation Failed: Data Passed too "
7765 "Volume Creation Failed: Duplicate Volumes "
7766 "Attempted", /* 02h */
7767 "Volume Creation Failed: Max Number "
7768 "Supported Volumes Exceeded", /* 03h */
7769 "Volume Creation Failed: DMA Error", /* 04h */
7770 "Volume Creation Failed: Invalid Volume Type", /* 05h */
7771 "Volume Creation Failed: Error Reading "
7772 "MFG Page 4", /* 06h */
7773 "Volume Creation Failed: Creating Internal "
7774 "Structures", /* 07h */
7783 "Activation failed: Already Active Volume", /* 10h */
7784 "Activation failed: Unsupported Volume Type", /* 11h */
7785 "Activation failed: Too Many Active Volumes", /* 12h */
7786 "Activation failed: Volume ID in Use", /* 13h */
7787 "Activation failed: Reported Failure", /* 14h */
7788 "Activation failed: Importing a Volume", /* 15h */
7799 "Phys Disk failed: Too Many Phys Disks", /* 20h */
7800 "Phys Disk failed: Data Passed too Large", /* 21h */
7801 "Phys Disk failed: DMA Error", /* 22h */
7802 "Phys Disk failed: Invalid <channel:id>", /* 23h */
7803 "Phys Disk failed: Creating Phys Disk Config "
7816 "Compatibility Error: IR Disabled", /* 30h */
7817 "Compatibility Error: Inquiry Comand Failed", /* 31h */
7818 "Compatibility Error: Device not Direct Access "
7819 "Device ", /* 32h */
7820 "Compatibility Error: Removable Device Found", /* 33h */
7821 "Compatibility Error: Device SCSI Version not "
7822 "2 or Higher", /* 34h */
7823 "Compatibility Error: SATA Device, 48 BIT LBA "
7824 "not Supported", /* 35h */
7825 "Compatibility Error: Device doesn't have "
7826 "512 Byte Block Sizes", /* 36h */
7827 "Compatibility Error: Volume Type Check Failed", /* 37h */
7828 "Compatibility Error: Volume Type is "
7829 "Unsupported by FW", /* 38h */
7830 "Compatibility Error: Disk Drive too Small for "
7831 "use in Volume", /* 39h */
7832 "Compatibility Error: Phys Disk for Create "
7833 "Volume not Found", /* 3Ah */
7834 "Compatibility Error: Too Many or too Few "
7835 "Disks for Volume Type", /* 3Bh */
7836 "Compatibility Error: Disk stripe Sizes "
7837 "Must be 64KB", /* 3Ch */
7838 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
7841 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7843 * mpt_sas_log_info - Log information returned from SAS IOC.
7844 * @ioc: Pointer to MPT_ADAPTER structure
7845 * @log_info: U32 LogInfo reply word from the IOC
7847 * Refer to lsi/mpi_log_sas.h.
7850 mpt_sas_log_info(MPT_ADAPTER
*ioc
, u32 log_info
)
7852 union loginfo_type
{
7861 union loginfo_type sas_loginfo
;
7862 char *originator_desc
= NULL
;
7863 char *code_desc
= NULL
;
7864 char *sub_code_desc
= NULL
;
7866 sas_loginfo
.loginfo
= log_info
;
7867 if ((sas_loginfo
.dw
.bus_type
!= 3 /*SAS*/) &&
7868 (sas_loginfo
.dw
.originator
< ARRAY_SIZE(originator_str
)))
7871 originator_desc
= originator_str
[sas_loginfo
.dw
.originator
];
7873 switch (sas_loginfo
.dw
.originator
) {
7876 if (sas_loginfo
.dw
.code
<
7877 ARRAY_SIZE(iop_code_str
))
7878 code_desc
= iop_code_str
[sas_loginfo
.dw
.code
];
7881 if (sas_loginfo
.dw
.code
<
7882 ARRAY_SIZE(pl_code_str
))
7883 code_desc
= pl_code_str
[sas_loginfo
.dw
.code
];
7886 if (sas_loginfo
.dw
.code
>=
7887 ARRAY_SIZE(ir_code_str
))
7889 code_desc
= ir_code_str
[sas_loginfo
.dw
.code
];
7890 if (sas_loginfo
.dw
.subcode
>=
7891 ARRAY_SIZE(raid_sub_code_str
))
7893 if (sas_loginfo
.dw
.code
== 0)
7895 raid_sub_code_str
[sas_loginfo
.dw
.subcode
];
7901 if (sub_code_desc
!= NULL
)
7902 printk(MYIOC_s_INFO_FMT
7903 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7905 ioc
->name
, log_info
, originator_desc
, code_desc
,
7907 else if (code_desc
!= NULL
)
7908 printk(MYIOC_s_INFO_FMT
7909 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7910 " SubCode(0x%04x)\n",
7911 ioc
->name
, log_info
, originator_desc
, code_desc
,
7912 sas_loginfo
.dw
.subcode
);
7914 printk(MYIOC_s_INFO_FMT
7915 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
7916 " SubCode(0x%04x)\n",
7917 ioc
->name
, log_info
, originator_desc
,
7918 sas_loginfo
.dw
.code
, sas_loginfo
.dw
.subcode
);
7921 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7923 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
7924 * @ioc: Pointer to MPT_ADAPTER structure
7925 * @ioc_status: U32 IOCStatus word from IOC
7926 * @mf: Pointer to MPT request frame
7928 * Refer to lsi/mpi.h.
7931 mpt_iocstatus_info_config(MPT_ADAPTER
*ioc
, u32 ioc_status
, MPT_FRAME_HDR
*mf
)
7933 Config_t
*pReq
= (Config_t
*)mf
;
7934 char extend_desc
[EVENT_DESCR_STR_SZ
];
7939 if (pReq
->Header
.PageType
== MPI_CONFIG_PAGETYPE_EXTENDED
)
7940 page_type
= pReq
->ExtPageType
;
7942 page_type
= pReq
->Header
.PageType
;
7945 * ignore invalid page messages for GET_NEXT_HANDLE
7947 form
= le32_to_cpu(pReq
->PageAddress
);
7948 if (ioc_status
== MPI_IOCSTATUS_CONFIG_INVALID_PAGE
) {
7949 if (page_type
== MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE
||
7950 page_type
== MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER
||
7951 page_type
== MPI_CONFIG_EXTPAGETYPE_ENCLOSURE
) {
7952 if ((form
>> MPI_SAS_DEVICE_PGAD_FORM_SHIFT
) ==
7953 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE
)
7956 if (page_type
== MPI_CONFIG_PAGETYPE_FC_DEVICE
)
7957 if ((form
& MPI_FC_DEVICE_PGAD_FORM_MASK
) ==
7958 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID
)
7962 snprintf(extend_desc
, EVENT_DESCR_STR_SZ
,
7963 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
7964 page_type
, pReq
->Header
.PageNumber
, pReq
->Action
, form
);
7966 switch (ioc_status
) {
7968 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION
: /* 0x0020 */
7969 desc
= "Config Page Invalid Action";
7972 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE
: /* 0x0021 */
7973 desc
= "Config Page Invalid Type";
7976 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE
: /* 0x0022 */
7977 desc
= "Config Page Invalid Page";
7980 case MPI_IOCSTATUS_CONFIG_INVALID_DATA
: /* 0x0023 */
7981 desc
= "Config Page Invalid Data";
7984 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS
: /* 0x0024 */
7985 desc
= "Config Page No Defaults";
7988 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT
: /* 0x0025 */
7989 desc
= "Config Page Can't Commit";
7996 dreplyprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"IOCStatus(0x%04X): %s: %s\n",
7997 ioc
->name
, ioc_status
, desc
, extend_desc
));
8001 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
8002 * @ioc: Pointer to MPT_ADAPTER structure
8003 * @ioc_status: U32 IOCStatus word from IOC
8004 * @mf: Pointer to MPT request frame
8006 * Refer to lsi/mpi.h.
8009 mpt_iocstatus_info(MPT_ADAPTER
*ioc
, u32 ioc_status
, MPT_FRAME_HDR
*mf
)
8011 u32 status
= ioc_status
& MPI_IOCSTATUS_MASK
;
8016 /****************************************************************************/
8017 /* Common IOCStatus values for all replies */
8018 /****************************************************************************/
8020 case MPI_IOCSTATUS_INVALID_FUNCTION
: /* 0x0001 */
8021 desc
= "Invalid Function";
8024 case MPI_IOCSTATUS_BUSY
: /* 0x0002 */
8028 case MPI_IOCSTATUS_INVALID_SGL
: /* 0x0003 */
8029 desc
= "Invalid SGL";
8032 case MPI_IOCSTATUS_INTERNAL_ERROR
: /* 0x0004 */
8033 desc
= "Internal Error";
8036 case MPI_IOCSTATUS_RESERVED
: /* 0x0005 */
8040 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES
: /* 0x0006 */
8041 desc
= "Insufficient Resources";
8044 case MPI_IOCSTATUS_INVALID_FIELD
: /* 0x0007 */
8045 desc
= "Invalid Field";
8048 case MPI_IOCSTATUS_INVALID_STATE
: /* 0x0008 */
8049 desc
= "Invalid State";
8052 /****************************************************************************/
8053 /* Config IOCStatus values */
8054 /****************************************************************************/
8056 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION
: /* 0x0020 */
8057 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE
: /* 0x0021 */
8058 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE
: /* 0x0022 */
8059 case MPI_IOCSTATUS_CONFIG_INVALID_DATA
: /* 0x0023 */
8060 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS
: /* 0x0024 */
8061 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT
: /* 0x0025 */
8062 mpt_iocstatus_info_config(ioc
, status
, mf
);
8065 /****************************************************************************/
8066 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
8068 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
8070 /****************************************************************************/
8072 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR
: /* 0x0040 */
8073 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN
: /* 0x0045 */
8074 case MPI_IOCSTATUS_SCSI_INVALID_BUS
: /* 0x0041 */
8075 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID
: /* 0x0042 */
8076 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE
: /* 0x0043 */
8077 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN
: /* 0x0044 */
8078 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR
: /* 0x0046 */
8079 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR
: /* 0x0047 */
8080 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED
: /* 0x0048 */
8081 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH
: /* 0x0049 */
8082 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED
: /* 0x004A */
8083 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED
: /* 0x004B */
8084 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED
: /* 0x004C */
8087 /****************************************************************************/
8088 /* SCSI Target values */
8089 /****************************************************************************/
8091 case MPI_IOCSTATUS_TARGET_PRIORITY_IO
: /* 0x0060 */
8092 desc
= "Target: Priority IO";
8095 case MPI_IOCSTATUS_TARGET_INVALID_PORT
: /* 0x0061 */
8096 desc
= "Target: Invalid Port";
8099 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX
: /* 0x0062 */
8100 desc
= "Target Invalid IO Index:";
8103 case MPI_IOCSTATUS_TARGET_ABORTED
: /* 0x0063 */
8104 desc
= "Target: Aborted";
8107 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE
: /* 0x0064 */
8108 desc
= "Target: No Conn Retryable";
8111 case MPI_IOCSTATUS_TARGET_NO_CONNECTION
: /* 0x0065 */
8112 desc
= "Target: No Connection";
8115 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH
: /* 0x006A */
8116 desc
= "Target: Transfer Count Mismatch";
8119 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT
: /* 0x006B */
8120 desc
= "Target: STS Data not Sent";
8123 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR
: /* 0x006D */
8124 desc
= "Target: Data Offset Error";
8127 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA
: /* 0x006E */
8128 desc
= "Target: Too Much Write Data";
8131 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT
: /* 0x006F */
8132 desc
= "Target: IU Too Short";
8135 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT
: /* 0x0070 */
8136 desc
= "Target: ACK NAK Timeout";
8139 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED
: /* 0x0071 */
8140 desc
= "Target: Nak Received";
8143 /****************************************************************************/
8144 /* Fibre Channel Direct Access values */
8145 /****************************************************************************/
8147 case MPI_IOCSTATUS_FC_ABORTED
: /* 0x0066 */
8148 desc
= "FC: Aborted";
8151 case MPI_IOCSTATUS_FC_RX_ID_INVALID
: /* 0x0067 */
8152 desc
= "FC: RX ID Invalid";
8155 case MPI_IOCSTATUS_FC_DID_INVALID
: /* 0x0068 */
8156 desc
= "FC: DID Invalid";
8159 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT
: /* 0x0069 */
8160 desc
= "FC: Node Logged Out";
8163 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED
: /* 0x006C */
8164 desc
= "FC: Exchange Canceled";
8167 /****************************************************************************/
8169 /****************************************************************************/
8171 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND
: /* 0x0080 */
8172 desc
= "LAN: Device not Found";
8175 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE
: /* 0x0081 */
8176 desc
= "LAN: Device Failure";
8179 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR
: /* 0x0082 */
8180 desc
= "LAN: Transmit Error";
8183 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED
: /* 0x0083 */
8184 desc
= "LAN: Transmit Aborted";
8187 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR
: /* 0x0084 */
8188 desc
= "LAN: Receive Error";
8191 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED
: /* 0x0085 */
8192 desc
= "LAN: Receive Aborted";
8195 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET
: /* 0x0086 */
8196 desc
= "LAN: Partial Packet";
8199 case MPI_IOCSTATUS_LAN_CANCELED
: /* 0x0087 */
8200 desc
= "LAN: Canceled";
8203 /****************************************************************************/
8204 /* Serial Attached SCSI values */
8205 /****************************************************************************/
8207 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED
: /* 0x0090 */
8208 desc
= "SAS: SMP Request Failed";
8211 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN
: /* 0x0090 */
8212 desc
= "SAS: SMP Data Overrun";
8223 dreplyprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"IOCStatus(0x%04X): %s\n",
8224 ioc
->name
, status
, desc
));
8227 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8228 EXPORT_SYMBOL(mpt_attach
);
8229 EXPORT_SYMBOL(mpt_detach
);
8231 EXPORT_SYMBOL(mpt_resume
);
8232 EXPORT_SYMBOL(mpt_suspend
);
8234 EXPORT_SYMBOL(ioc_list
);
8235 EXPORT_SYMBOL(mpt_register
);
8236 EXPORT_SYMBOL(mpt_deregister
);
8237 EXPORT_SYMBOL(mpt_event_register
);
8238 EXPORT_SYMBOL(mpt_event_deregister
);
8239 EXPORT_SYMBOL(mpt_reset_register
);
8240 EXPORT_SYMBOL(mpt_reset_deregister
);
8241 EXPORT_SYMBOL(mpt_device_driver_register
);
8242 EXPORT_SYMBOL(mpt_device_driver_deregister
);
8243 EXPORT_SYMBOL(mpt_get_msg_frame
);
8244 EXPORT_SYMBOL(mpt_put_msg_frame
);
8245 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri
);
8246 EXPORT_SYMBOL(mpt_free_msg_frame
);
8247 EXPORT_SYMBOL(mpt_send_handshake_request
);
8248 EXPORT_SYMBOL(mpt_verify_adapter
);
8249 EXPORT_SYMBOL(mpt_GetIocState
);
8250 EXPORT_SYMBOL(mpt_print_ioc_summary
);
8251 EXPORT_SYMBOL(mpt_HardResetHandler
);
8252 EXPORT_SYMBOL(mpt_config
);
8253 EXPORT_SYMBOL(mpt_findImVolumes
);
8254 EXPORT_SYMBOL(mpt_alloc_fw_memory
);
8255 EXPORT_SYMBOL(mpt_free_fw_memory
);
8256 EXPORT_SYMBOL(mptbase_sas_persist_operation
);
8257 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0
);
8259 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8261 * fusion_init - Fusion MPT base driver initialization routine.
8263 * Returns 0 for success, non-zero for failure.
8270 show_mptmod_ver(my_NAME
, my_VERSION
);
8271 printk(KERN_INFO COPYRIGHT
"\n");
8273 for (cb_idx
= 0; cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
; cb_idx
++) {
8274 MptCallbacks
[cb_idx
] = NULL
;
8275 MptDriverClass
[cb_idx
] = MPTUNKNOWN_DRIVER
;
8276 MptEvHandlers
[cb_idx
] = NULL
;
8277 MptResetHandlers
[cb_idx
] = NULL
;
8280 /* Register ourselves (mptbase) in order to facilitate
8281 * EventNotification handling.
8283 mpt_base_index
= mpt_register(mptbase_reply
, MPTBASE_DRIVER
);
8285 /* Register for hard reset handling callbacks.
8287 mpt_reset_register(mpt_base_index
, mpt_ioc_reset
);
8289 #ifdef CONFIG_PROC_FS
8290 (void) procmpt_create();
8295 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8297 * fusion_exit - Perform driver unload cleanup.
8299 * This routine frees all resources associated with each MPT adapter
8300 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
8306 mpt_reset_deregister(mpt_base_index
);
8308 #ifdef CONFIG_PROC_FS
8313 module_init(fusion_init
);
8314 module_exit(fusion_exit
);