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(dma_addr
));
1019 pSge
->Address
.High
= cpu_to_le32
1020 (upper_32_bits(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(dma_addr
));
1042 tmp
= (u32
)(upper_32_bits(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(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_HOST_TO_IOC
|
1301 MPI_SGE_FLAGS_END_OF_BUFFER
;
1302 flags_length
= flags_length
<< MPI_SGE_FLAGS_SHIFT
;
1303 flags_length
|= ioc
->HostPageBuffer_sz
;
1304 ioc
->add_sge(psge
, flags_length
, ioc
->HostPageBuffer_dma
);
1305 ioc
->facts
.HostPageBufferSGE
= ioc_init
->HostPageBufferSGE
;
1310 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1312 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1313 * @iocid: IOC unique identifier (integer)
1314 * @iocpp: Pointer to pointer to IOC adapter
1316 * Given a unique IOC identifier, set pointer to the associated MPT
1317 * adapter structure.
1319 * Returns iocid and sets iocpp if iocid is found.
1320 * Returns -1 if iocid is not found.
1323 mpt_verify_adapter(int iocid
, MPT_ADAPTER
**iocpp
)
1327 list_for_each_entry(ioc
,&ioc_list
,list
) {
1328 if (ioc
->id
== iocid
) {
1339 * mpt_get_product_name - returns product string
1340 * @vendor: pci vendor id
1341 * @device: pci device id
1342 * @revision: pci revision id
1343 * @prod_name: string returned
1345 * Returns product string displayed when driver loads,
1346 * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1350 mpt_get_product_name(u16 vendor
, u16 device
, u8 revision
, char *prod_name
)
1352 char *product_str
= NULL
;
1354 if (vendor
== PCI_VENDOR_ID_BROCADE
) {
1357 case MPI_MANUFACTPAGE_DEVICEID_FC949E
:
1361 product_str
= "BRE040 A0";
1364 product_str
= "BRE040 A1";
1367 product_str
= "BRE040";
1377 case MPI_MANUFACTPAGE_DEVICEID_FC909
:
1378 product_str
= "LSIFC909 B1";
1380 case MPI_MANUFACTPAGE_DEVICEID_FC919
:
1381 product_str
= "LSIFC919 B0";
1383 case MPI_MANUFACTPAGE_DEVICEID_FC929
:
1384 product_str
= "LSIFC929 B0";
1386 case MPI_MANUFACTPAGE_DEVICEID_FC919X
:
1387 if (revision
< 0x80)
1388 product_str
= "LSIFC919X A0";
1390 product_str
= "LSIFC919XL A1";
1392 case MPI_MANUFACTPAGE_DEVICEID_FC929X
:
1393 if (revision
< 0x80)
1394 product_str
= "LSIFC929X A0";
1396 product_str
= "LSIFC929XL A1";
1398 case MPI_MANUFACTPAGE_DEVICEID_FC939X
:
1399 product_str
= "LSIFC939X A1";
1401 case MPI_MANUFACTPAGE_DEVICEID_FC949X
:
1402 product_str
= "LSIFC949X A1";
1404 case MPI_MANUFACTPAGE_DEVICEID_FC949E
:
1408 product_str
= "LSIFC949E A0";
1411 product_str
= "LSIFC949E A1";
1414 product_str
= "LSIFC949E";
1418 case MPI_MANUFACTPAGE_DEVID_53C1030
:
1422 product_str
= "LSI53C1030 A0";
1425 product_str
= "LSI53C1030 B0";
1428 product_str
= "LSI53C1030 B1";
1431 product_str
= "LSI53C1030 B2";
1434 product_str
= "LSI53C1030 C0";
1437 product_str
= "LSI53C1030T A0";
1440 product_str
= "LSI53C1030T A2";
1443 product_str
= "LSI53C1030T A3";
1446 product_str
= "LSI53C1020A A1";
1449 product_str
= "LSI53C1030";
1453 case MPI_MANUFACTPAGE_DEVID_1030_53C1035
:
1457 product_str
= "LSI53C1035 A2";
1460 product_str
= "LSI53C1035 B0";
1463 product_str
= "LSI53C1035";
1467 case MPI_MANUFACTPAGE_DEVID_SAS1064
:
1471 product_str
= "LSISAS1064 A1";
1474 product_str
= "LSISAS1064 A2";
1477 product_str
= "LSISAS1064 A3";
1480 product_str
= "LSISAS1064 A4";
1483 product_str
= "LSISAS1064";
1487 case MPI_MANUFACTPAGE_DEVID_SAS1064E
:
1491 product_str
= "LSISAS1064E A0";
1494 product_str
= "LSISAS1064E B0";
1497 product_str
= "LSISAS1064E B1";
1500 product_str
= "LSISAS1064E B2";
1503 product_str
= "LSISAS1064E B3";
1506 product_str
= "LSISAS1064E";
1510 case MPI_MANUFACTPAGE_DEVID_SAS1068
:
1514 product_str
= "LSISAS1068 A0";
1517 product_str
= "LSISAS1068 B0";
1520 product_str
= "LSISAS1068 B1";
1523 product_str
= "LSISAS1068";
1527 case MPI_MANUFACTPAGE_DEVID_SAS1068E
:
1531 product_str
= "LSISAS1068E A0";
1534 product_str
= "LSISAS1068E B0";
1537 product_str
= "LSISAS1068E B1";
1540 product_str
= "LSISAS1068E B2";
1543 product_str
= "LSISAS1068E B3";
1546 product_str
= "LSISAS1068E";
1550 case MPI_MANUFACTPAGE_DEVID_SAS1078
:
1554 product_str
= "LSISAS1078 A0";
1557 product_str
= "LSISAS1078 B0";
1560 product_str
= "LSISAS1078 C0";
1563 product_str
= "LSISAS1078 C1";
1566 product_str
= "LSISAS1078 C2";
1569 product_str
= "LSISAS1078";
1577 sprintf(prod_name
, "%s", product_str
);
1581 * mpt_mapresources - map in memory mapped io
1582 * @ioc: Pointer to pointer to IOC adapter
1586 mpt_mapresources(MPT_ADAPTER
*ioc
)
1590 resource_size_t mem_phys
;
1596 struct pci_dev
*pdev
;
1599 ioc
->bars
= pci_select_bars(pdev
, IORESOURCE_MEM
);
1600 if (pci_enable_device_mem(pdev
)) {
1601 printk(MYIOC_s_ERR_FMT
"pci_enable_device_mem() "
1602 "failed\n", ioc
->name
);
1605 if (pci_request_selected_regions(pdev
, ioc
->bars
, "mpt")) {
1606 printk(MYIOC_s_ERR_FMT
"pci_request_selected_regions() with "
1607 "MEM failed\n", ioc
->name
);
1611 pci_read_config_byte(pdev
, PCI_CLASS_REVISION
, &revision
);
1613 if (sizeof(dma_addr_t
) > 4) {
1614 const uint64_t required_mask
= dma_get_required_mask
1616 if (required_mask
> DMA_BIT_MASK(32)
1617 && !pci_set_dma_mask(pdev
, DMA_BIT_MASK(64))
1618 && !pci_set_consistent_dma_mask(pdev
,
1619 DMA_BIT_MASK(64))) {
1620 ioc
->dma_mask
= DMA_BIT_MASK(64);
1621 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
1622 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1624 } else if (!pci_set_dma_mask(pdev
, DMA_BIT_MASK(32))
1625 && !pci_set_consistent_dma_mask(pdev
,
1626 DMA_BIT_MASK(32))) {
1627 ioc
->dma_mask
= DMA_BIT_MASK(32);
1628 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
1629 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1632 printk(MYIOC_s_WARN_FMT
"no suitable DMA mask for %s\n",
1633 ioc
->name
, pci_name(pdev
));
1637 if (!pci_set_dma_mask(pdev
, DMA_BIT_MASK(32))
1638 && !pci_set_consistent_dma_mask(pdev
,
1639 DMA_BIT_MASK(32))) {
1640 ioc
->dma_mask
= DMA_BIT_MASK(32);
1641 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
1642 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1645 printk(MYIOC_s_WARN_FMT
"no suitable DMA mask for %s\n",
1646 ioc
->name
, pci_name(pdev
));
1651 mem_phys
= msize
= 0;
1653 for (ii
= 0; ii
< DEVICE_COUNT_RESOURCE
; ii
++) {
1654 if (pci_resource_flags(pdev
, ii
) & PCI_BASE_ADDRESS_SPACE_IO
) {
1657 /* Get I/O space! */
1658 port
= pci_resource_start(pdev
, ii
);
1659 psize
= pci_resource_len(pdev
, ii
);
1664 mem_phys
= pci_resource_start(pdev
, ii
);
1665 msize
= pci_resource_len(pdev
, ii
);
1668 ioc
->mem_size
= msize
;
1671 /* Get logical ptr for PciMem0 space */
1672 /*mem = ioremap(mem_phys, msize);*/
1673 mem
= ioremap(mem_phys
, msize
);
1675 printk(MYIOC_s_ERR_FMT
": ERROR - Unable to map adapter"
1676 " memory!\n", ioc
->name
);
1680 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"mem = %p, mem_phys = %llx\n",
1681 ioc
->name
, mem
, (unsigned long long)mem_phys
));
1683 ioc
->mem_phys
= mem_phys
;
1684 ioc
->chip
= (SYSIF_REGS __iomem
*)mem
;
1686 /* Save Port IO values in case we need to do downloadboot */
1687 ioc
->pio_mem_phys
= port
;
1688 ioc
->pio_chip
= (SYSIF_REGS __iomem
*)port
;
1693 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1695 * mpt_attach - Install a PCI intelligent MPT adapter.
1696 * @pdev: Pointer to pci_dev structure
1697 * @id: PCI device ID information
1699 * This routine performs all the steps necessary to bring the IOC of
1700 * a MPT adapter to a OPERATIONAL state. This includes registering
1701 * memory regions, registering the interrupt, and allocating request
1702 * and reply memory pools.
1704 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1707 * Returns 0 for success, non-zero for failure.
1709 * TODO: Add support for polled controllers
1712 mpt_attach(struct pci_dev
*pdev
, const struct pci_device_id
*id
)
1719 static int mpt_ids
= 0;
1720 #ifdef CONFIG_PROC_FS
1721 struct proc_dir_entry
*dent
, *ent
;
1724 ioc
= kzalloc(sizeof(MPT_ADAPTER
), GFP_ATOMIC
);
1726 printk(KERN_ERR MYNAM
": ERROR - Insufficient memory to add adapter!\n");
1730 ioc
->id
= mpt_ids
++;
1731 sprintf(ioc
->name
, "ioc%d", ioc
->id
);
1732 dinitprintk(ioc
, printk(KERN_WARNING MYNAM
": mpt_adapter_install\n"));
1735 * set initial debug level
1736 * (refer to mptdebug.h)
1739 ioc
->debug_level
= mpt_debug_level
;
1740 if (mpt_debug_level
)
1741 printk(KERN_INFO
"mpt_debug_level=%xh\n", mpt_debug_level
);
1743 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
": mpt_adapter_install\n", ioc
->name
));
1746 if (mpt_mapresources(ioc
)) {
1752 * Setting up proper handlers for scatter gather handling
1754 if (ioc
->dma_mask
== DMA_BIT_MASK(64)) {
1755 if (pdev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1078
)
1756 ioc
->add_sge
= &mpt_add_sge_64bit_1078
;
1758 ioc
->add_sge
= &mpt_add_sge_64bit
;
1759 ioc
->add_chain
= &mpt_add_chain_64bit
;
1760 ioc
->sg_addr_size
= 8;
1762 ioc
->add_sge
= &mpt_add_sge
;
1763 ioc
->add_chain
= &mpt_add_chain
;
1764 ioc
->sg_addr_size
= 4;
1766 ioc
->SGE_size
= sizeof(u32
) + ioc
->sg_addr_size
;
1768 ioc
->alloc_total
= sizeof(MPT_ADAPTER
);
1769 ioc
->req_sz
= MPT_DEFAULT_FRAME_SIZE
; /* avoid div by zero! */
1770 ioc
->reply_sz
= MPT_REPLY_FRAME_SIZE
;
1774 spin_lock_init(&ioc
->taskmgmt_lock
);
1775 mutex_init(&ioc
->internal_cmds
.mutex
);
1776 init_completion(&ioc
->internal_cmds
.done
);
1777 mutex_init(&ioc
->mptbase_cmds
.mutex
);
1778 init_completion(&ioc
->mptbase_cmds
.done
);
1779 mutex_init(&ioc
->taskmgmt_cmds
.mutex
);
1780 init_completion(&ioc
->taskmgmt_cmds
.done
);
1782 /* Initialize the event logging.
1784 ioc
->eventTypes
= 0; /* None */
1785 ioc
->eventContext
= 0;
1786 ioc
->eventLogSize
= 0;
1794 ioc
->cached_fw
= NULL
;
1796 /* Initilize SCSI Config Data structure
1798 memset(&ioc
->spi_data
, 0, sizeof(SpiCfgData
));
1800 /* Initialize the fc rport list head.
1802 INIT_LIST_HEAD(&ioc
->fc_rports
);
1804 /* Find lookup slot. */
1805 INIT_LIST_HEAD(&ioc
->list
);
1808 /* Initialize workqueue */
1809 INIT_DELAYED_WORK(&ioc
->fault_reset_work
, mpt_fault_reset_work
);
1811 snprintf(ioc
->reset_work_q_name
, MPT_KOBJ_NAME_LEN
,
1812 "mpt_poll_%d", ioc
->id
);
1814 create_singlethread_workqueue(ioc
->reset_work_q_name
);
1815 if (!ioc
->reset_work_q
) {
1816 printk(MYIOC_s_ERR_FMT
"Insufficient memory to add adapter!\n",
1818 pci_release_selected_regions(pdev
, ioc
->bars
);
1823 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"facts @ %p, pfacts[0] @ %p\n",
1824 ioc
->name
, &ioc
->facts
, &ioc
->pfacts
[0]));
1826 pci_read_config_byte(pdev
, PCI_CLASS_REVISION
, &revision
);
1827 mpt_get_product_name(pdev
->vendor
, pdev
->device
, revision
, ioc
->prod_name
);
1829 switch (pdev
->device
)
1831 case MPI_MANUFACTPAGE_DEVICEID_FC939X
:
1832 case MPI_MANUFACTPAGE_DEVICEID_FC949X
:
1833 ioc
->errata_flag_1064
= 1;
1834 case MPI_MANUFACTPAGE_DEVICEID_FC909
:
1835 case MPI_MANUFACTPAGE_DEVICEID_FC929
:
1836 case MPI_MANUFACTPAGE_DEVICEID_FC919
:
1837 case MPI_MANUFACTPAGE_DEVICEID_FC949E
:
1841 case MPI_MANUFACTPAGE_DEVICEID_FC929X
:
1842 if (revision
< XL_929
) {
1843 /* 929X Chip Fix. Set Split transactions level
1844 * for PCIX. Set MOST bits to zero.
1846 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1848 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1850 /* 929XL Chip Fix. Set MMRBC to 0x08.
1852 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1854 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1859 case MPI_MANUFACTPAGE_DEVICEID_FC919X
:
1860 /* 919X Chip Fix. Set Split transactions level
1861 * for PCIX. Set MOST bits to zero.
1863 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1865 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1869 case MPI_MANUFACTPAGE_DEVID_53C1030
:
1870 /* 1030 Chip Fix. Disable Split transactions
1871 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1873 if (revision
< C0_1030
) {
1874 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1876 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1879 case MPI_MANUFACTPAGE_DEVID_1030_53C1035
:
1880 ioc
->bus_type
= SPI
;
1883 case MPI_MANUFACTPAGE_DEVID_SAS1064
:
1884 case MPI_MANUFACTPAGE_DEVID_SAS1068
:
1885 ioc
->errata_flag_1064
= 1;
1886 ioc
->bus_type
= SAS
;
1889 case MPI_MANUFACTPAGE_DEVID_SAS1064E
:
1890 case MPI_MANUFACTPAGE_DEVID_SAS1068E
:
1891 case MPI_MANUFACTPAGE_DEVID_SAS1078
:
1892 ioc
->bus_type
= SAS
;
1897 switch (ioc
->bus_type
) {
1900 ioc
->msi_enable
= mpt_msi_enable_sas
;
1904 ioc
->msi_enable
= mpt_msi_enable_spi
;
1908 ioc
->msi_enable
= mpt_msi_enable_fc
;
1912 ioc
->msi_enable
= 0;
1915 if (ioc
->errata_flag_1064
)
1916 pci_disable_io_access(pdev
);
1918 spin_lock_init(&ioc
->FreeQlock
);
1921 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
1923 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1925 /* Set IOC ptr in the pcidev's driver data. */
1926 pci_set_drvdata(ioc
->pcidev
, ioc
);
1928 /* Set lookup ptr. */
1929 list_add_tail(&ioc
->list
, &ioc_list
);
1931 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1933 mpt_detect_bound_ports(ioc
, pdev
);
1935 INIT_LIST_HEAD(&ioc
->fw_event_list
);
1936 spin_lock_init(&ioc
->fw_event_lock
);
1937 snprintf(ioc
->fw_event_q_name
, MPT_KOBJ_NAME_LEN
, "mpt/%d", ioc
->id
);
1938 ioc
->fw_event_q
= create_singlethread_workqueue(ioc
->fw_event_q_name
);
1940 if ((r
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_BRINGUP
,
1942 printk(MYIOC_s_ERR_FMT
"didn't initialize properly! (%d)\n",
1945 list_del(&ioc
->list
);
1947 ioc
->alt_ioc
->alt_ioc
= NULL
;
1948 iounmap(ioc
->memmap
);
1950 pci_release_selected_regions(pdev
, ioc
->bars
);
1952 destroy_workqueue(ioc
->reset_work_q
);
1953 ioc
->reset_work_q
= NULL
;
1956 pci_set_drvdata(pdev
, NULL
);
1960 /* call per device driver probe entry point */
1961 for(cb_idx
= 0; cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
; cb_idx
++) {
1962 if(MptDeviceDriverHandlers
[cb_idx
] &&
1963 MptDeviceDriverHandlers
[cb_idx
]->probe
) {
1964 MptDeviceDriverHandlers
[cb_idx
]->probe(pdev
,id
);
1968 #ifdef CONFIG_PROC_FS
1970 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1972 dent
= proc_mkdir(ioc
->name
, mpt_proc_root_dir
);
1974 ent
= create_proc_entry("info", S_IFREG
|S_IRUGO
, dent
);
1976 ent
->read_proc
= procmpt_iocinfo_read
;
1979 ent
= create_proc_entry("summary", S_IFREG
|S_IRUGO
, dent
);
1981 ent
->read_proc
= procmpt_summary_read
;
1988 queue_delayed_work(ioc
->reset_work_q
, &ioc
->fault_reset_work
,
1989 msecs_to_jiffies(MPT_POLLING_INTERVAL
));
1994 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1996 * mpt_detach - Remove a PCI intelligent MPT adapter.
1997 * @pdev: Pointer to pci_dev structure
2001 mpt_detach(struct pci_dev
*pdev
)
2003 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
2006 unsigned long flags
;
2007 struct workqueue_struct
*wq
;
2010 * Stop polling ioc for fault condition
2012 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
2013 wq
= ioc
->reset_work_q
;
2014 ioc
->reset_work_q
= NULL
;
2015 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
2016 cancel_delayed_work(&ioc
->fault_reset_work
);
2017 destroy_workqueue(wq
);
2019 spin_lock_irqsave(&ioc
->fw_event_lock
, flags
);
2020 wq
= ioc
->fw_event_q
;
2021 ioc
->fw_event_q
= NULL
;
2022 spin_unlock_irqrestore(&ioc
->fw_event_lock
, flags
);
2023 destroy_workqueue(wq
);
2025 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s/summary", ioc
->name
);
2026 remove_proc_entry(pname
, NULL
);
2027 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s/info", ioc
->name
);
2028 remove_proc_entry(pname
, NULL
);
2029 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s", ioc
->name
);
2030 remove_proc_entry(pname
, NULL
);
2032 /* call per device driver remove entry point */
2033 for(cb_idx
= 0; cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
; cb_idx
++) {
2034 if(MptDeviceDriverHandlers
[cb_idx
] &&
2035 MptDeviceDriverHandlers
[cb_idx
]->remove
) {
2036 MptDeviceDriverHandlers
[cb_idx
]->remove(pdev
);
2040 /* Disable interrupts! */
2041 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2044 synchronize_irq(pdev
->irq
);
2046 /* Clear any lingering interrupt */
2047 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
2049 CHIPREG_READ32(&ioc
->chip
->IntStatus
);
2051 mpt_adapter_dispose(ioc
);
2053 pci_set_drvdata(pdev
, NULL
);
2056 /**************************************************************************
2060 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2062 * mpt_suspend - Fusion MPT base driver suspend routine.
2063 * @pdev: Pointer to pci_dev structure
2064 * @state: new state to enter
2067 mpt_suspend(struct pci_dev
*pdev
, pm_message_t state
)
2070 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
2072 device_state
= pci_choose_state(pdev
, state
);
2073 printk(MYIOC_s_INFO_FMT
"pci-suspend: pdev=0x%p, slot=%s, Entering "
2074 "operating state [D%d]\n", ioc
->name
, pdev
, pci_name(pdev
),
2077 /* put ioc into READY_STATE */
2078 if(SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, CAN_SLEEP
)) {
2079 printk(MYIOC_s_ERR_FMT
2080 "pci-suspend: IOC msg unit reset failed!\n", ioc
->name
);
2083 /* disable interrupts */
2084 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2087 /* Clear any lingering interrupt */
2088 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
2090 free_irq(ioc
->pci_irq
, ioc
);
2091 if (ioc
->msi_enable
)
2092 pci_disable_msi(ioc
->pcidev
);
2094 pci_save_state(pdev
);
2095 pci_disable_device(pdev
);
2096 pci_release_selected_regions(pdev
, ioc
->bars
);
2097 pci_set_power_state(pdev
, device_state
);
2101 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2103 * mpt_resume - Fusion MPT base driver resume routine.
2104 * @pdev: Pointer to pci_dev structure
2107 mpt_resume(struct pci_dev
*pdev
)
2109 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
2110 u32 device_state
= pdev
->current_state
;
2114 printk(MYIOC_s_INFO_FMT
"pci-resume: pdev=0x%p, slot=%s, Previous "
2115 "operating state [D%d]\n", ioc
->name
, pdev
, pci_name(pdev
),
2118 pci_set_power_state(pdev
, PCI_D0
);
2119 pci_enable_wake(pdev
, PCI_D0
, 0);
2120 pci_restore_state(pdev
);
2122 err
= mpt_mapresources(ioc
);
2126 if (ioc
->dma_mask
== DMA_BIT_MASK(64)) {
2127 if (pdev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1078
)
2128 ioc
->add_sge
= &mpt_add_sge_64bit_1078
;
2130 ioc
->add_sge
= &mpt_add_sge_64bit
;
2131 ioc
->add_chain
= &mpt_add_chain_64bit
;
2132 ioc
->sg_addr_size
= 8;
2135 ioc
->add_sge
= &mpt_add_sge
;
2136 ioc
->add_chain
= &mpt_add_chain
;
2137 ioc
->sg_addr_size
= 4;
2139 ioc
->SGE_size
= sizeof(u32
) + ioc
->sg_addr_size
;
2141 printk(MYIOC_s_INFO_FMT
"pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
2142 ioc
->name
, (mpt_GetIocState(ioc
, 1) >> MPI_IOC_STATE_SHIFT
),
2143 CHIPREG_READ32(&ioc
->chip
->Doorbell
));
2146 * Errata workaround for SAS pci express:
2147 * Upon returning to the D0 state, the contents of the doorbell will be
2148 * stale data, and this will incorrectly signal to the host driver that
2149 * the firmware is ready to process mpt commands. The workaround is
2150 * to issue a diagnostic reset.
2152 if (ioc
->bus_type
== SAS
&& (pdev
->device
==
2153 MPI_MANUFACTPAGE_DEVID_SAS1068E
|| pdev
->device
==
2154 MPI_MANUFACTPAGE_DEVID_SAS1064E
)) {
2155 if (KickStart(ioc
, 1, CAN_SLEEP
) < 0) {
2156 printk(MYIOC_s_WARN_FMT
"pci-resume: Cannot recover\n",
2162 /* bring ioc to operational state */
2163 printk(MYIOC_s_INFO_FMT
"Sending mpt_do_ioc_recovery\n", ioc
->name
);
2164 recovery_state
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_BRINGUP
,
2166 if (recovery_state
!= 0)
2167 printk(MYIOC_s_WARN_FMT
"pci-resume: Cannot recover, "
2168 "error:[%x]\n", ioc
->name
, recovery_state
);
2170 printk(MYIOC_s_INFO_FMT
2171 "pci-resume: success\n", ioc
->name
);
2179 mpt_signal_reset(u8 index
, MPT_ADAPTER
*ioc
, int reset_phase
)
2181 if ((MptDriverClass
[index
] == MPTSPI_DRIVER
&&
2182 ioc
->bus_type
!= SPI
) ||
2183 (MptDriverClass
[index
] == MPTFC_DRIVER
&&
2184 ioc
->bus_type
!= FC
) ||
2185 (MptDriverClass
[index
] == MPTSAS_DRIVER
&&
2186 ioc
->bus_type
!= SAS
))
2187 /* make sure we only call the relevant reset handler
2190 return (MptResetHandlers
[index
])(ioc
, reset_phase
);
2193 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2195 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
2196 * @ioc: Pointer to MPT adapter structure
2197 * @reason: Event word / reason
2198 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
2200 * This routine performs all the steps necessary to bring the IOC
2201 * to a OPERATIONAL state.
2203 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
2208 * -1 if failed to get board READY
2209 * -2 if READY but IOCFacts Failed
2210 * -3 if READY but PrimeIOCFifos Failed
2211 * -4 if READY but IOCInit Failed
2212 * -5 if failed to enable_device and/or request_selected_regions
2213 * -6 if failed to upload firmware
2216 mpt_do_ioc_recovery(MPT_ADAPTER
*ioc
, u32 reason
, int sleepFlag
)
2218 int hard_reset_done
= 0;
2219 int alt_ioc_ready
= 0;
2224 int reset_alt_ioc_active
= 0;
2225 int irq_allocated
= 0;
2228 printk(MYIOC_s_INFO_FMT
"Initiating %s\n", ioc
->name
,
2229 reason
== MPT_HOSTEVENT_IOC_BRINGUP
? "bringup" : "recovery");
2231 /* Disable reply interrupts (also blocks FreeQ) */
2232 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2236 if (ioc
->alt_ioc
->active
||
2237 reason
== MPT_HOSTEVENT_IOC_RECOVER
) {
2238 reset_alt_ioc_active
= 1;
2239 /* Disable alt-IOC's reply interrupts
2240 * (and FreeQ) for a bit
2242 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
,
2244 ioc
->alt_ioc
->active
= 0;
2249 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)
2252 if ((hard_reset_done
= MakeIocReady(ioc
, hard
, sleepFlag
)) < 0) {
2253 if (hard_reset_done
== -4) {
2254 printk(MYIOC_s_WARN_FMT
"Owned by PEER..skipping!\n",
2257 if (reset_alt_ioc_active
&& ioc
->alt_ioc
) {
2258 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
2259 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
2260 "alt_ioc reply irq re-enabled\n", ioc
->alt_ioc
->name
));
2261 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
, MPI_HIM_DIM
);
2262 ioc
->alt_ioc
->active
= 1;
2266 printk(MYIOC_s_WARN_FMT
2267 "NOT READY WARNING!\n", ioc
->name
);
2273 /* hard_reset_done = 0 if a soft reset was performed
2274 * and 1 if a hard reset was performed.
2276 if (hard_reset_done
&& reset_alt_ioc_active
&& ioc
->alt_ioc
) {
2277 if ((rc
= MakeIocReady(ioc
->alt_ioc
, 0, sleepFlag
)) == 0)
2280 printk(MYIOC_s_WARN_FMT
2281 ": alt-ioc Not ready WARNING!\n",
2282 ioc
->alt_ioc
->name
);
2285 for (ii
=0; ii
<5; ii
++) {
2286 /* Get IOC facts! Allow 5 retries */
2287 if ((rc
= GetIocFacts(ioc
, sleepFlag
, reason
)) == 0)
2293 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2294 "Retry IocFacts failed rc=%x\n", ioc
->name
, rc
));
2296 } else if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
2297 MptDisplayIocCapabilities(ioc
);
2300 if (alt_ioc_ready
) {
2301 if ((rc
= GetIocFacts(ioc
->alt_ioc
, sleepFlag
, reason
)) != 0) {
2302 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2303 "Initial Alt IocFacts failed rc=%x\n",
2305 /* Retry - alt IOC was initialized once
2307 rc
= GetIocFacts(ioc
->alt_ioc
, sleepFlag
, reason
);
2310 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2311 "Retry Alt IocFacts failed rc=%x\n", ioc
->name
, rc
));
2313 reset_alt_ioc_active
= 0;
2314 } else if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
2315 MptDisplayIocCapabilities(ioc
->alt_ioc
);
2319 if ((ret
== 0) && (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) &&
2320 (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)) {
2321 pci_release_selected_regions(ioc
->pcidev
, ioc
->bars
);
2322 ioc
->bars
= pci_select_bars(ioc
->pcidev
, IORESOURCE_MEM
|
2324 if (pci_enable_device(ioc
->pcidev
))
2326 if (pci_request_selected_regions(ioc
->pcidev
, ioc
->bars
,
2332 * Device is reset now. It must have de-asserted the interrupt line
2333 * (if it was asserted) and it should be safe to register for the
2336 if ((ret
== 0) && (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)) {
2338 if (ioc
->pcidev
->irq
) {
2339 if (ioc
->msi_enable
&& !pci_enable_msi(ioc
->pcidev
))
2340 printk(MYIOC_s_INFO_FMT
"PCI-MSI enabled\n",
2343 ioc
->msi_enable
= 0;
2344 rc
= request_irq(ioc
->pcidev
->irq
, mpt_interrupt
,
2345 IRQF_SHARED
, ioc
->name
, ioc
);
2347 printk(MYIOC_s_ERR_FMT
"Unable to allocate "
2349 ioc
->name
, ioc
->pcidev
->irq
);
2350 if (ioc
->msi_enable
)
2351 pci_disable_msi(ioc
->pcidev
);
2356 ioc
->pci_irq
= ioc
->pcidev
->irq
;
2357 pci_set_master(ioc
->pcidev
); /* ?? */
2358 pci_set_drvdata(ioc
->pcidev
, ioc
);
2359 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
2360 "installed at interrupt %d\n", ioc
->name
,
2365 /* Prime reply & request queues!
2366 * (mucho alloc's) Must be done prior to
2367 * init as upper addresses are needed for init.
2368 * If fails, continue with alt-ioc processing
2370 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"PrimeIocFifos\n",
2372 if ((ret
== 0) && ((rc
= PrimeIocFifos(ioc
)) != 0))
2375 /* May need to check/upload firmware & data here!
2376 * If fails, continue with alt-ioc processing
2378 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"SendIocInit\n",
2380 if ((ret
== 0) && ((rc
= SendIocInit(ioc
, sleepFlag
)) != 0))
2383 if (alt_ioc_ready
&& ((rc
= PrimeIocFifos(ioc
->alt_ioc
)) != 0)) {
2384 printk(MYIOC_s_WARN_FMT
2385 ": alt-ioc (%d) FIFO mgmt alloc WARNING!\n",
2386 ioc
->alt_ioc
->name
, rc
);
2388 reset_alt_ioc_active
= 0;
2391 if (alt_ioc_ready
) {
2392 if ((rc
= SendIocInit(ioc
->alt_ioc
, sleepFlag
)) != 0) {
2394 reset_alt_ioc_active
= 0;
2395 printk(MYIOC_s_WARN_FMT
2396 ": alt-ioc: (%d) init failure WARNING!\n",
2397 ioc
->alt_ioc
->name
, rc
);
2401 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
){
2402 if (ioc
->upload_fw
) {
2403 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2404 "firmware upload required!\n", ioc
->name
));
2406 /* Controller is not operational, cannot do upload
2409 rc
= mpt_do_upload(ioc
, sleepFlag
);
2411 if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
) {
2413 * Maintain only one pointer to FW memory
2414 * so there will not be two attempt to
2415 * downloadboot onboard dual function
2416 * chips (mpt_adapter_disable,
2419 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2420 "mpt_upload: alt_%s has cached_fw=%p \n",
2421 ioc
->name
, ioc
->alt_ioc
->name
, ioc
->alt_ioc
->cached_fw
));
2422 ioc
->cached_fw
= NULL
;
2425 printk(MYIOC_s_WARN_FMT
2426 "firmware upload failure!\n", ioc
->name
);
2433 /* Enable MPT base driver management of EventNotification
2434 * and EventAck handling.
2436 if ((ret
== 0) && (!ioc
->facts
.EventState
)) {
2437 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
2438 "SendEventNotification\n",
2440 ret
= SendEventNotification(ioc
, 1, sleepFlag
); /* 1=Enable */
2443 if (ioc
->alt_ioc
&& alt_ioc_ready
&& !ioc
->alt_ioc
->facts
.EventState
)
2444 rc
= SendEventNotification(ioc
->alt_ioc
, 1, sleepFlag
);
2447 /* Enable! (reply interrupt) */
2448 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, MPI_HIM_DIM
);
2451 if (rc
== 0) { /* alt ioc */
2452 if (reset_alt_ioc_active
&& ioc
->alt_ioc
) {
2453 /* (re)Enable alt-IOC! (reply interrupt) */
2454 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"alt-ioc"
2455 "reply irq re-enabled\n",
2456 ioc
->alt_ioc
->name
));
2457 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
,
2459 ioc
->alt_ioc
->active
= 1;
2464 /* Add additional "reason" check before call to GetLanConfigPages
2465 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2466 * recursive scenario; GetLanConfigPages times out, timer expired
2467 * routine calls HardResetHandler, which calls into here again,
2468 * and we try GetLanConfigPages again...
2470 if ((ret
== 0) && (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)) {
2473 * Initalize link list for inactive raid volumes.
2475 mutex_init(&ioc
->raid_data
.inactive_list_mutex
);
2476 INIT_LIST_HEAD(&ioc
->raid_data
.inactive_list
);
2478 switch (ioc
->bus_type
) {
2481 /* clear persistency table */
2482 if(ioc
->facts
.IOCExceptions
&
2483 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL
) {
2484 ret
= mptbase_sas_persist_operation(ioc
,
2485 MPI_SAS_OP_CLEAR_NOT_PRESENT
);
2492 mpt_findImVolumes(ioc
);
2494 /* Check, and possibly reset, the coalescing value
2496 mpt_read_ioc_pg_1(ioc
);
2501 if ((ioc
->pfacts
[0].ProtocolFlags
&
2502 MPI_PORTFACTS_PROTOCOL_LAN
) &&
2503 (ioc
->lan_cnfg_page0
.Header
.PageLength
== 0)) {
2505 * Pre-fetch the ports LAN MAC address!
2506 * (LANPage1_t stuff)
2508 (void) GetLanConfigPages(ioc
);
2509 a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
2510 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2511 "LanAddr = %02X:%02X:%02X"
2512 ":%02X:%02X:%02X\n",
2513 ioc
->name
, a
[5], a
[4],
2514 a
[3], a
[2], a
[1], a
[0]));
2519 /* Get NVRAM and adapter maximums from SPP 0 and 2
2521 mpt_GetScsiPortSettings(ioc
, 0);
2523 /* Get version and length of SDP 1
2525 mpt_readScsiDevicePageHeaders(ioc
, 0);
2529 if (ioc
->facts
.MsgVersion
>= MPI_VERSION_01_02
)
2530 mpt_findImVolumes(ioc
);
2532 /* Check, and possibly reset, the coalescing value
2534 mpt_read_ioc_pg_1(ioc
);
2536 mpt_read_ioc_pg_4(ioc
);
2541 GetIoUnitPage2(ioc
);
2542 mpt_get_manufacturing_pg_0(ioc
);
2546 if ((ret
!= 0) && irq_allocated
) {
2547 free_irq(ioc
->pci_irq
, ioc
);
2548 if (ioc
->msi_enable
)
2549 pci_disable_msi(ioc
->pcidev
);
2554 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2556 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2557 * @ioc: Pointer to MPT adapter structure
2558 * @pdev: Pointer to (struct pci_dev) structure
2560 * Search for PCI bus/dev_function which matches
2561 * PCI bus/dev_function (+/-1) for newly discovered 929,
2562 * 929X, 1030 or 1035.
2564 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2565 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2568 mpt_detect_bound_ports(MPT_ADAPTER
*ioc
, struct pci_dev
*pdev
)
2570 struct pci_dev
*peer
=NULL
;
2571 unsigned int slot
= PCI_SLOT(pdev
->devfn
);
2572 unsigned int func
= PCI_FUNC(pdev
->devfn
);
2573 MPT_ADAPTER
*ioc_srch
;
2575 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"PCI device %s devfn=%x/%x,"
2576 " searching for devfn match on %x or %x\n",
2577 ioc
->name
, pci_name(pdev
), pdev
->bus
->number
,
2578 pdev
->devfn
, func
-1, func
+1));
2580 peer
= pci_get_slot(pdev
->bus
, PCI_DEVFN(slot
,func
-1));
2582 peer
= pci_get_slot(pdev
->bus
, PCI_DEVFN(slot
,func
+1));
2587 list_for_each_entry(ioc_srch
, &ioc_list
, list
) {
2588 struct pci_dev
*_pcidev
= ioc_srch
->pcidev
;
2589 if (_pcidev
== peer
) {
2590 /* Paranoia checks */
2591 if (ioc
->alt_ioc
!= NULL
) {
2592 printk(MYIOC_s_WARN_FMT
2593 "Oops, already bound (%s <==> %s)!\n",
2594 ioc
->name
, ioc
->name
, ioc
->alt_ioc
->name
);
2596 } else if (ioc_srch
->alt_ioc
!= NULL
) {
2597 printk(MYIOC_s_WARN_FMT
2598 "Oops, already bound (%s <==> %s)!\n",
2599 ioc_srch
->name
, ioc_srch
->name
,
2600 ioc_srch
->alt_ioc
->name
);
2603 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2604 "FOUND! binding %s <==> %s\n",
2605 ioc
->name
, ioc
->name
, ioc_srch
->name
));
2606 ioc_srch
->alt_ioc
= ioc
;
2607 ioc
->alt_ioc
= ioc_srch
;
2613 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2615 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2616 * @ioc: Pointer to MPT adapter structure
2619 mpt_adapter_disable(MPT_ADAPTER
*ioc
)
2624 if (ioc
->cached_fw
!= NULL
) {
2625 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2626 "%s: Pushing FW onto adapter\n", __func__
, ioc
->name
));
2627 if ((ret
= mpt_downloadboot(ioc
, (MpiFwHeader_t
*)
2628 ioc
->cached_fw
, CAN_SLEEP
)) < 0) {
2629 printk(MYIOC_s_WARN_FMT
2630 ": firmware downloadboot failure (%d)!\n",
2636 * Put the controller into ready state (if its not already)
2638 if (mpt_GetIocState(ioc
, 1) != MPI_IOC_STATE_READY
) {
2639 if (!SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
,
2641 if (mpt_GetIocState(ioc
, 1) != MPI_IOC_STATE_READY
)
2642 printk(MYIOC_s_ERR_FMT
"%s: IOC msg unit "
2643 "reset failed to put ioc in ready state!\n",
2644 ioc
->name
, __func__
);
2646 printk(MYIOC_s_ERR_FMT
"%s: IOC msg unit reset "
2647 "failed!\n", ioc
->name
, __func__
);
2651 /* Disable adapter interrupts! */
2652 synchronize_irq(ioc
->pcidev
->irq
);
2653 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
2656 /* Clear any lingering interrupt */
2657 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
2658 CHIPREG_READ32(&ioc
->chip
->IntStatus
);
2660 if (ioc
->alloc
!= NULL
) {
2662 dexitprintk(ioc
, printk(MYIOC_s_INFO_FMT
"free @ %p, sz=%d bytes\n",
2663 ioc
->name
, ioc
->alloc
, ioc
->alloc_sz
));
2664 pci_free_consistent(ioc
->pcidev
, sz
,
2665 ioc
->alloc
, ioc
->alloc_dma
);
2666 ioc
->reply_frames
= NULL
;
2667 ioc
->req_frames
= NULL
;
2669 ioc
->alloc_total
-= sz
;
2672 if (ioc
->sense_buf_pool
!= NULL
) {
2673 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
2674 pci_free_consistent(ioc
->pcidev
, sz
,
2675 ioc
->sense_buf_pool
, ioc
->sense_buf_pool_dma
);
2676 ioc
->sense_buf_pool
= NULL
;
2677 ioc
->alloc_total
-= sz
;
2680 if (ioc
->events
!= NULL
){
2681 sz
= MPTCTL_EVENT_LOG_SIZE
* sizeof(MPT_IOCTL_EVENTS
);
2684 ioc
->alloc_total
-= sz
;
2687 mpt_free_fw_memory(ioc
);
2689 kfree(ioc
->spi_data
.nvram
);
2690 mpt_inactive_raid_list_free(ioc
);
2691 kfree(ioc
->raid_data
.pIocPg2
);
2692 kfree(ioc
->raid_data
.pIocPg3
);
2693 ioc
->spi_data
.nvram
= NULL
;
2694 ioc
->raid_data
.pIocPg3
= NULL
;
2696 if (ioc
->spi_data
.pIocPg4
!= NULL
) {
2697 sz
= ioc
->spi_data
.IocPg4Sz
;
2698 pci_free_consistent(ioc
->pcidev
, sz
,
2699 ioc
->spi_data
.pIocPg4
,
2700 ioc
->spi_data
.IocPg4_dma
);
2701 ioc
->spi_data
.pIocPg4
= NULL
;
2702 ioc
->alloc_total
-= sz
;
2705 if (ioc
->ReqToChain
!= NULL
) {
2706 kfree(ioc
->ReqToChain
);
2707 kfree(ioc
->RequestNB
);
2708 ioc
->ReqToChain
= NULL
;
2711 kfree(ioc
->ChainToChain
);
2712 ioc
->ChainToChain
= NULL
;
2714 if (ioc
->HostPageBuffer
!= NULL
) {
2715 if((ret
= mpt_host_page_access_control(ioc
,
2716 MPI_DB_HPBAC_FREE_BUFFER
, NO_SLEEP
)) != 0) {
2717 printk(MYIOC_s_ERR_FMT
2718 ": %s: host page buffers free failed (%d)!\n",
2719 ioc
->name
, __func__
, ret
);
2721 dexitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
2722 "HostPageBuffer free @ %p, sz=%d bytes\n",
2723 ioc
->name
, ioc
->HostPageBuffer
,
2724 ioc
->HostPageBuffer_sz
));
2725 pci_free_consistent(ioc
->pcidev
, ioc
->HostPageBuffer_sz
,
2726 ioc
->HostPageBuffer
, ioc
->HostPageBuffer_dma
);
2727 ioc
->HostPageBuffer
= NULL
;
2728 ioc
->HostPageBuffer_sz
= 0;
2729 ioc
->alloc_total
-= ioc
->HostPageBuffer_sz
;
2732 pci_set_drvdata(ioc
->pcidev
, NULL
);
2734 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2736 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2737 * @ioc: Pointer to MPT adapter structure
2739 * This routine unregisters h/w resources and frees all alloc'd memory
2740 * associated with a MPT adapter structure.
2743 mpt_adapter_dispose(MPT_ADAPTER
*ioc
)
2745 int sz_first
, sz_last
;
2750 sz_first
= ioc
->alloc_total
;
2752 mpt_adapter_disable(ioc
);
2754 if (ioc
->pci_irq
!= -1) {
2755 free_irq(ioc
->pci_irq
, ioc
);
2756 if (ioc
->msi_enable
)
2757 pci_disable_msi(ioc
->pcidev
);
2761 if (ioc
->memmap
!= NULL
) {
2762 iounmap(ioc
->memmap
);
2766 pci_disable_device(ioc
->pcidev
);
2767 pci_release_selected_regions(ioc
->pcidev
, ioc
->bars
);
2769 #if defined(CONFIG_MTRR) && 0
2770 if (ioc
->mtrr_reg
> 0) {
2771 mtrr_del(ioc
->mtrr_reg
, 0, 0);
2772 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
"MTRR region de-registered\n", ioc
->name
));
2776 /* Zap the adapter lookup ptr! */
2777 list_del(&ioc
->list
);
2779 sz_last
= ioc
->alloc_total
;
2780 dprintk(ioc
, printk(MYIOC_s_INFO_FMT
"free'd %d of %d bytes\n",
2781 ioc
->name
, sz_first
-sz_last
+(int)sizeof(*ioc
), sz_first
));
2784 ioc
->alt_ioc
->alt_ioc
= NULL
;
2789 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2791 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2792 * @ioc: Pointer to MPT adapter structure
2795 MptDisplayIocCapabilities(MPT_ADAPTER
*ioc
)
2799 printk(KERN_INFO
"%s: ", ioc
->name
);
2801 printk("%s: ", ioc
->prod_name
);
2802 printk("Capabilities={");
2804 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_INITIATOR
) {
2805 printk("Initiator");
2809 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_TARGET
) {
2810 printk("%sTarget", i
? "," : "");
2814 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
) {
2815 printk("%sLAN", i
? "," : "");
2821 * This would probably evoke more questions than it's worth
2823 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_TARGET
) {
2824 printk("%sLogBusAddr", i
? "," : "");
2832 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2834 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2835 * @ioc: Pointer to MPT_ADAPTER structure
2836 * @force: Force hard KickStart of IOC
2837 * @sleepFlag: Specifies whether the process can sleep
2840 * 1 - DIAG reset and READY
2841 * 0 - READY initially OR soft reset and READY
2842 * -1 - Any failure on KickStart
2843 * -2 - Msg Unit Reset Failed
2844 * -3 - IO Unit Reset Failed
2845 * -4 - IOC owned by a PEER
2848 MakeIocReady(MPT_ADAPTER
*ioc
, int force
, int sleepFlag
)
2853 int hard_reset_done
= 0;
2858 /* Get current [raw] IOC state */
2859 ioc_state
= mpt_GetIocState(ioc
, 0);
2860 dhsprintk(ioc
, printk(MYIOC_s_INFO_FMT
"MakeIocReady [raw] state=%08x\n", ioc
->name
, ioc_state
));
2863 * Check to see if IOC got left/stuck in doorbell handshake
2864 * grip of death. If so, hard reset the IOC.
2866 if (ioc_state
& MPI_DOORBELL_ACTIVE
) {
2868 printk(MYIOC_s_WARN_FMT
"Unexpected doorbell active!\n",
2872 /* Is it already READY? */
2874 ((ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_READY
)) {
2875 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
2876 "IOC is in READY state\n", ioc
->name
));
2881 * Check to see if IOC is in FAULT state.
2883 if ((ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_FAULT
) {
2885 printk(MYIOC_s_WARN_FMT
"IOC is in FAULT state!!!\n",
2887 printk(MYIOC_s_WARN_FMT
" FAULT code = %04xh\n",
2888 ioc
->name
, ioc_state
& MPI_DOORBELL_DATA_MASK
);
2892 * Hmmm... Did it get left operational?
2894 if ((ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_OPERATIONAL
) {
2895 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"IOC operational unexpected\n",
2899 * If PCI Peer, exit.
2900 * Else, if no fault conditions are present, issue a MessageUnitReset
2901 * Else, fall through to KickStart case
2903 whoinit
= (ioc_state
& MPI_DOORBELL_WHO_INIT_MASK
) >> MPI_DOORBELL_WHO_INIT_SHIFT
;
2904 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
2905 "whoinit 0x%x statefault %d force %d\n",
2906 ioc
->name
, whoinit
, statefault
, force
));
2907 if (whoinit
== MPI_WHOINIT_PCI_PEER
)
2910 if ((statefault
== 0 ) && (force
== 0)) {
2911 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
)) == 0)
2918 hard_reset_done
= KickStart(ioc
, statefault
||force
, sleepFlag
);
2919 if (hard_reset_done
< 0)
2923 * Loop here waiting for IOC to come READY.
2926 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 5; /* 5 seconds */
2928 while ((ioc_state
= mpt_GetIocState(ioc
, 1)) != MPI_IOC_STATE_READY
) {
2929 if (ioc_state
== MPI_IOC_STATE_OPERATIONAL
) {
2931 * BIOS or previous driver load left IOC in OP state.
2932 * Reset messaging FIFOs.
2934 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
)) != 0) {
2935 printk(MYIOC_s_ERR_FMT
"IOC msg unit reset failed!\n", ioc
->name
);
2938 } else if (ioc_state
== MPI_IOC_STATE_RESET
) {
2940 * Something is wrong. Try to get IOC back
2943 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IO_UNIT_RESET
, sleepFlag
)) != 0) {
2944 printk(MYIOC_s_ERR_FMT
"IO unit reset failed!\n", ioc
->name
);
2951 printk(MYIOC_s_ERR_FMT
2952 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
2953 ioc
->name
, ioc_state
, (int)((ii
+5)/HZ
));
2957 if (sleepFlag
== CAN_SLEEP
) {
2960 mdelay (1); /* 1 msec delay */
2965 if (statefault
< 3) {
2966 printk(MYIOC_s_INFO_FMT
"Recovered from %s\n", ioc
->name
,
2967 statefault
== 1 ? "stuck handshake" : "IOC FAULT");
2970 return hard_reset_done
;
2973 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2975 * mpt_GetIocState - Get the current state of a MPT adapter.
2976 * @ioc: Pointer to MPT_ADAPTER structure
2977 * @cooked: Request raw or cooked IOC state
2979 * Returns all IOC Doorbell register bits if cooked==0, else just the
2980 * Doorbell bits in MPI_IOC_STATE_MASK.
2983 mpt_GetIocState(MPT_ADAPTER
*ioc
, int cooked
)
2988 s
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
2989 sc
= s
& MPI_IOC_STATE_MASK
;
2992 ioc
->last_state
= sc
;
2994 return cooked
? sc
: s
;
2997 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2999 * GetIocFacts - Send IOCFacts request to MPT adapter.
3000 * @ioc: Pointer to MPT_ADAPTER structure
3001 * @sleepFlag: Specifies whether the process can sleep
3002 * @reason: If recovery, only update facts.
3004 * Returns 0 for success, non-zero for failure.
3007 GetIocFacts(MPT_ADAPTER
*ioc
, int sleepFlag
, int reason
)
3009 IOCFacts_t get_facts
;
3010 IOCFactsReply_t
*facts
;
3018 /* IOC *must* NOT be in RESET state! */
3019 if (ioc
->last_state
== MPI_IOC_STATE_RESET
) {
3020 printk(KERN_ERR MYNAM
3021 ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
3022 ioc
->name
, ioc
->last_state
);
3026 facts
= &ioc
->facts
;
3028 /* Destination (reply area)... */
3029 reply_sz
= sizeof(*facts
);
3030 memset(facts
, 0, reply_sz
);
3032 /* Request area (get_facts on the stack right now!) */
3033 req_sz
= sizeof(get_facts
);
3034 memset(&get_facts
, 0, req_sz
);
3036 get_facts
.Function
= MPI_FUNCTION_IOC_FACTS
;
3037 /* Assert: All other get_facts fields are zero! */
3039 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3040 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
3041 ioc
->name
, req_sz
, reply_sz
));
3043 /* No non-zero fields in the get_facts request are greater than
3044 * 1 byte in size, so we can just fire it off as is.
3046 r
= mpt_handshake_req_reply_wait(ioc
, req_sz
, (u32
*)&get_facts
,
3047 reply_sz
, (u16
*)facts
, 5 /*seconds*/, sleepFlag
);
3052 * Now byte swap (GRRR) the necessary fields before any further
3053 * inspection of reply contents.
3055 * But need to do some sanity checks on MsgLength (byte) field
3056 * to make sure we don't zero IOC's req_sz!
3058 /* Did we get a valid reply? */
3059 if (facts
->MsgLength
> offsetof(IOCFactsReply_t
, RequestFrameSize
)/sizeof(u32
)) {
3060 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
3062 * If not been here, done that, save off first WhoInit value
3064 if (ioc
->FirstWhoInit
== WHOINIT_UNKNOWN
)
3065 ioc
->FirstWhoInit
= facts
->WhoInit
;
3068 facts
->MsgVersion
= le16_to_cpu(facts
->MsgVersion
);
3069 facts
->MsgContext
= le32_to_cpu(facts
->MsgContext
);
3070 facts
->IOCExceptions
= le16_to_cpu(facts
->IOCExceptions
);
3071 facts
->IOCStatus
= le16_to_cpu(facts
->IOCStatus
);
3072 facts
->IOCLogInfo
= le32_to_cpu(facts
->IOCLogInfo
);
3073 status
= le16_to_cpu(facts
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
3074 /* CHECKME! IOCStatus, IOCLogInfo */
3076 facts
->ReplyQueueDepth
= le16_to_cpu(facts
->ReplyQueueDepth
);
3077 facts
->RequestFrameSize
= le16_to_cpu(facts
->RequestFrameSize
);
3080 * FC f/w version changed between 1.1 and 1.2
3081 * Old: u16{Major(4),Minor(4),SubMinor(8)}
3082 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
3084 if (facts
->MsgVersion
< MPI_VERSION_01_02
) {
3086 * Handle old FC f/w style, convert to new...
3088 u16 oldv
= le16_to_cpu(facts
->Reserved_0101_FWVersion
);
3089 facts
->FWVersion
.Word
=
3090 ((oldv
<<12) & 0xFF000000) |
3091 ((oldv
<<8) & 0x000FFF00);
3093 facts
->FWVersion
.Word
= le32_to_cpu(facts
->FWVersion
.Word
);
3095 facts
->ProductID
= le16_to_cpu(facts
->ProductID
);
3097 if ((ioc
->facts
.ProductID
& MPI_FW_HEADER_PID_PROD_MASK
)
3098 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI
)
3099 ioc
->ir_firmware
= 1;
3101 facts
->CurrentHostMfaHighAddr
=
3102 le32_to_cpu(facts
->CurrentHostMfaHighAddr
);
3103 facts
->GlobalCredits
= le16_to_cpu(facts
->GlobalCredits
);
3104 facts
->CurrentSenseBufferHighAddr
=
3105 le32_to_cpu(facts
->CurrentSenseBufferHighAddr
);
3106 facts
->CurReplyFrameSize
=
3107 le16_to_cpu(facts
->CurReplyFrameSize
);
3108 facts
->IOCCapabilities
= le32_to_cpu(facts
->IOCCapabilities
);
3111 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
3112 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
3113 * to 14 in MPI-1.01.0x.
3115 if (facts
->MsgLength
>= (offsetof(IOCFactsReply_t
,FWImageSize
) + 7)/4 &&
3116 facts
->MsgVersion
> MPI_VERSION_01_00
) {
3117 facts
->FWImageSize
= le32_to_cpu(facts
->FWImageSize
);
3120 sz
= facts
->FWImageSize
;
3125 facts
->FWImageSize
= sz
;
3127 if (!facts
->RequestFrameSize
) {
3128 /* Something is wrong! */
3129 printk(MYIOC_s_ERR_FMT
"IOC reported invalid 0 request size!\n",
3134 r
= sz
= facts
->BlockSize
;
3135 vv
= ((63 / (sz
* 4)) + 1) & 0x03;
3136 ioc
->NB_for_64_byte_frame
= vv
;
3142 ioc
->NBShiftFactor
= shiftFactor
;
3143 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3144 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
3145 ioc
->name
, vv
, shiftFactor
, r
));
3147 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
3149 * Set values for this IOC's request & reply frame sizes,
3150 * and request & reply queue depths...
3152 ioc
->req_sz
= min(MPT_DEFAULT_FRAME_SIZE
, facts
->RequestFrameSize
* 4);
3153 ioc
->req_depth
= min_t(int, MPT_MAX_REQ_DEPTH
, facts
->GlobalCredits
);
3154 ioc
->reply_sz
= MPT_REPLY_FRAME_SIZE
;
3155 ioc
->reply_depth
= min_t(int, MPT_DEFAULT_REPLY_DEPTH
, facts
->ReplyQueueDepth
);
3157 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"reply_sz=%3d, reply_depth=%4d\n",
3158 ioc
->name
, ioc
->reply_sz
, ioc
->reply_depth
));
3159 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"req_sz =%3d, req_depth =%4d\n",
3160 ioc
->name
, ioc
->req_sz
, ioc
->req_depth
));
3162 /* Get port facts! */
3163 if ( (r
= GetPortFacts(ioc
, 0, sleepFlag
)) != 0 )
3167 printk(MYIOC_s_ERR_FMT
3168 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
3169 ioc
->name
, facts
->MsgLength
, (offsetof(IOCFactsReply_t
,
3170 RequestFrameSize
)/sizeof(u32
)));
3177 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3179 * GetPortFacts - Send PortFacts request to MPT adapter.
3180 * @ioc: Pointer to MPT_ADAPTER structure
3181 * @portnum: Port number
3182 * @sleepFlag: Specifies whether the process can sleep
3184 * Returns 0 for success, non-zero for failure.
3187 GetPortFacts(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
)
3189 PortFacts_t get_pfacts
;
3190 PortFactsReply_t
*pfacts
;
3196 /* IOC *must* NOT be in RESET state! */
3197 if (ioc
->last_state
== MPI_IOC_STATE_RESET
) {
3198 printk(MYIOC_s_ERR_FMT
"Can't get PortFacts NOT READY! (%08x)\n",
3199 ioc
->name
, ioc
->last_state
);
3203 pfacts
= &ioc
->pfacts
[portnum
];
3205 /* Destination (reply area)... */
3206 reply_sz
= sizeof(*pfacts
);
3207 memset(pfacts
, 0, reply_sz
);
3209 /* Request area (get_pfacts on the stack right now!) */
3210 req_sz
= sizeof(get_pfacts
);
3211 memset(&get_pfacts
, 0, req_sz
);
3213 get_pfacts
.Function
= MPI_FUNCTION_PORT_FACTS
;
3214 get_pfacts
.PortNumber
= portnum
;
3215 /* Assert: All other get_pfacts fields are zero! */
3217 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending get PortFacts(%d) request\n",
3218 ioc
->name
, portnum
));
3220 /* No non-zero fields in the get_pfacts request are greater than
3221 * 1 byte in size, so we can just fire it off as is.
3223 ii
= mpt_handshake_req_reply_wait(ioc
, req_sz
, (u32
*)&get_pfacts
,
3224 reply_sz
, (u16
*)pfacts
, 5 /*seconds*/, sleepFlag
);
3228 /* Did we get a valid reply? */
3230 /* Now byte swap the necessary fields in the response. */
3231 pfacts
->MsgContext
= le32_to_cpu(pfacts
->MsgContext
);
3232 pfacts
->IOCStatus
= le16_to_cpu(pfacts
->IOCStatus
);
3233 pfacts
->IOCLogInfo
= le32_to_cpu(pfacts
->IOCLogInfo
);
3234 pfacts
->MaxDevices
= le16_to_cpu(pfacts
->MaxDevices
);
3235 pfacts
->PortSCSIID
= le16_to_cpu(pfacts
->PortSCSIID
);
3236 pfacts
->ProtocolFlags
= le16_to_cpu(pfacts
->ProtocolFlags
);
3237 pfacts
->MaxPostedCmdBuffers
= le16_to_cpu(pfacts
->MaxPostedCmdBuffers
);
3238 pfacts
->MaxPersistentIDs
= le16_to_cpu(pfacts
->MaxPersistentIDs
);
3239 pfacts
->MaxLanBuckets
= le16_to_cpu(pfacts
->MaxLanBuckets
);
3241 max_id
= (ioc
->bus_type
== SAS
) ? pfacts
->PortSCSIID
:
3243 ioc
->devices_per_bus
= (max_id
> 255) ? 256 : max_id
;
3244 ioc
->number_of_buses
= (ioc
->devices_per_bus
< 256) ? 1 : max_id
/256;
3247 * Place all the devices on channels
3251 if (mpt_channel_mapping
) {
3252 ioc
->devices_per_bus
= 1;
3253 ioc
->number_of_buses
= (max_id
> 255) ? 255 : max_id
;
3259 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3261 * SendIocInit - Send IOCInit request to MPT adapter.
3262 * @ioc: Pointer to MPT_ADAPTER structure
3263 * @sleepFlag: Specifies whether the process can sleep
3265 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
3267 * Returns 0 for success, non-zero for failure.
3270 SendIocInit(MPT_ADAPTER
*ioc
, int sleepFlag
)
3273 MPIDefaultReply_t init_reply
;
3279 memset(&ioc_init
, 0, sizeof(ioc_init
));
3280 memset(&init_reply
, 0, sizeof(init_reply
));
3282 ioc_init
.WhoInit
= MPI_WHOINIT_HOST_DRIVER
;
3283 ioc_init
.Function
= MPI_FUNCTION_IOC_INIT
;
3285 /* If we are in a recovery mode and we uploaded the FW image,
3286 * then this pointer is not NULL. Skip the upload a second time.
3287 * Set this flag if cached_fw set for either IOC.
3289 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)
3293 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"upload_fw %d facts.Flags=%x\n",
3294 ioc
->name
, ioc
->upload_fw
, ioc
->facts
.Flags
));
3296 ioc_init
.MaxDevices
= (U8
)ioc
->devices_per_bus
;
3297 ioc_init
.MaxBuses
= (U8
)ioc
->number_of_buses
;
3299 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"facts.MsgVersion=%x\n",
3300 ioc
->name
, ioc
->facts
.MsgVersion
));
3301 if (ioc
->facts
.MsgVersion
>= MPI_VERSION_01_05
) {
3302 // set MsgVersion and HeaderVersion host driver was built with
3303 ioc_init
.MsgVersion
= cpu_to_le16(MPI_VERSION
);
3304 ioc_init
.HeaderVersion
= cpu_to_le16(MPI_HEADER_VERSION
);
3306 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT
) {
3307 ioc_init
.HostPageBufferSGE
= ioc
->facts
.HostPageBufferSGE
;
3308 } else if(mpt_host_page_alloc(ioc
, &ioc_init
))
3311 ioc_init
.ReplyFrameSize
= cpu_to_le16(ioc
->reply_sz
); /* in BYTES */
3313 if (ioc
->sg_addr_size
== sizeof(u64
)) {
3314 /* Save the upper 32-bits of the request
3315 * (reply) and sense buffers.
3317 ioc_init
.HostMfaHighAddr
= cpu_to_le32((u32
)((u64
)ioc
->alloc_dma
>> 32));
3318 ioc_init
.SenseBufferHighAddr
= cpu_to_le32((u32
)((u64
)ioc
->sense_buf_pool_dma
>> 32));
3320 /* Force 32-bit addressing */
3321 ioc_init
.HostMfaHighAddr
= cpu_to_le32(0);
3322 ioc_init
.SenseBufferHighAddr
= cpu_to_le32(0);
3325 ioc
->facts
.CurrentHostMfaHighAddr
= ioc_init
.HostMfaHighAddr
;
3326 ioc
->facts
.CurrentSenseBufferHighAddr
= ioc_init
.SenseBufferHighAddr
;
3327 ioc
->facts
.MaxDevices
= ioc_init
.MaxDevices
;
3328 ioc
->facts
.MaxBuses
= ioc_init
.MaxBuses
;
3330 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending IOCInit (req @ %p)\n",
3331 ioc
->name
, &ioc_init
));
3333 r
= mpt_handshake_req_reply_wait(ioc
, sizeof(IOCInit_t
), (u32
*)&ioc_init
,
3334 sizeof(MPIDefaultReply_t
), (u16
*)&init_reply
, 10 /*seconds*/, sleepFlag
);
3336 printk(MYIOC_s_ERR_FMT
"Sending IOCInit failed(%d)!\n",ioc
->name
, r
);
3340 /* No need to byte swap the multibyte fields in the reply
3341 * since we don't even look at its contents.
3344 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending PortEnable (req @ %p)\n",
3345 ioc
->name
, &ioc_init
));
3347 if ((r
= SendPortEnable(ioc
, 0, sleepFlag
)) != 0) {
3348 printk(MYIOC_s_ERR_FMT
"Sending PortEnable failed(%d)!\n",ioc
->name
, r
);
3352 /* YIKES! SUPER IMPORTANT!!!
3353 * Poll IocState until _OPERATIONAL while IOC is doing
3354 * LoopInit and TargetDiscovery!
3357 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 60; /* 60 seconds */
3358 state
= mpt_GetIocState(ioc
, 1);
3359 while (state
!= MPI_IOC_STATE_OPERATIONAL
&& --cntdn
) {
3360 if (sleepFlag
== CAN_SLEEP
) {
3367 printk(MYIOC_s_ERR_FMT
"Wait IOC_OP state timeout(%d)!\n",
3368 ioc
->name
, (int)((count
+5)/HZ
));
3372 state
= mpt_GetIocState(ioc
, 1);
3375 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Wait IOC_OPERATIONAL state (cnt=%d)\n",
3378 ioc
->aen_event_read_flag
=0;
3382 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3384 * SendPortEnable - Send PortEnable request to MPT adapter port.
3385 * @ioc: Pointer to MPT_ADAPTER structure
3386 * @portnum: Port number to enable
3387 * @sleepFlag: Specifies whether the process can sleep
3389 * Send PortEnable to bring IOC to OPERATIONAL state.
3391 * Returns 0 for success, non-zero for failure.
3394 SendPortEnable(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
)
3396 PortEnable_t port_enable
;
3397 MPIDefaultReply_t reply_buf
;
3402 /* Destination... */
3403 reply_sz
= sizeof(MPIDefaultReply_t
);
3404 memset(&reply_buf
, 0, reply_sz
);
3406 req_sz
= sizeof(PortEnable_t
);
3407 memset(&port_enable
, 0, req_sz
);
3409 port_enable
.Function
= MPI_FUNCTION_PORT_ENABLE
;
3410 port_enable
.PortNumber
= portnum
;
3411 /* port_enable.ChainOffset = 0; */
3412 /* port_enable.MsgFlags = 0; */
3413 /* port_enable.MsgContext = 0; */
3415 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending Port(%d)Enable (req @ %p)\n",
3416 ioc
->name
, portnum
, &port_enable
));
3418 /* RAID FW may take a long time to enable
3420 if (ioc
->ir_firmware
|| ioc
->bus_type
== SAS
) {
3421 rc
= mpt_handshake_req_reply_wait(ioc
, req_sz
,
3422 (u32
*)&port_enable
, reply_sz
, (u16
*)&reply_buf
,
3423 300 /*seconds*/, sleepFlag
);
3425 rc
= mpt_handshake_req_reply_wait(ioc
, req_sz
,
3426 (u32
*)&port_enable
, reply_sz
, (u16
*)&reply_buf
,
3427 30 /*seconds*/, sleepFlag
);
3433 * mpt_alloc_fw_memory - allocate firmware memory
3434 * @ioc: Pointer to MPT_ADAPTER structure
3435 * @size: total FW bytes
3437 * If memory has already been allocated, the same (cached) value
3440 * Return 0 if successfull, or non-zero for failure
3443 mpt_alloc_fw_memory(MPT_ADAPTER
*ioc
, int size
)
3447 if (ioc
->cached_fw
) {
3448 rc
= 0; /* use already allocated memory */
3451 else if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
) {
3452 ioc
->cached_fw
= ioc
->alt_ioc
->cached_fw
; /* use alt_ioc's memory */
3453 ioc
->cached_fw_dma
= ioc
->alt_ioc
->cached_fw_dma
;
3457 ioc
->cached_fw
= pci_alloc_consistent(ioc
->pcidev
, size
, &ioc
->cached_fw_dma
);
3458 if (!ioc
->cached_fw
) {
3459 printk(MYIOC_s_ERR_FMT
"Unable to allocate memory for the cached firmware image!\n",
3463 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"FW Image @ %p[%p], sz=%d[%x] bytes\n",
3464 ioc
->name
, ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, size
, size
));
3465 ioc
->alloc_total
+= size
;
3473 * mpt_free_fw_memory - free firmware memory
3474 * @ioc: Pointer to MPT_ADAPTER structure
3476 * If alt_img is NULL, delete from ioc structure.
3477 * Else, delete a secondary image in same format.
3480 mpt_free_fw_memory(MPT_ADAPTER
*ioc
)
3484 if (!ioc
->cached_fw
)
3487 sz
= ioc
->facts
.FWImageSize
;
3488 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3489 ioc
->name
, ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, sz
, sz
));
3490 pci_free_consistent(ioc
->pcidev
, sz
, ioc
->cached_fw
, ioc
->cached_fw_dma
);
3491 ioc
->alloc_total
-= sz
;
3492 ioc
->cached_fw
= NULL
;
3495 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3497 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3498 * @ioc: Pointer to MPT_ADAPTER structure
3499 * @sleepFlag: Specifies whether the process can sleep
3501 * Returns 0 for success, >0 for handshake failure
3502 * <0 for fw upload failure.
3504 * Remark: If bound IOC and a successful FWUpload was performed
3505 * on the bound IOC, the second image is discarded
3506 * and memory is free'd. Both channels must upload to prevent
3507 * IOC from running in degraded mode.
3510 mpt_do_upload(MPT_ADAPTER
*ioc
, int sleepFlag
)
3512 u8 reply
[sizeof(FWUploadReply_t
)];
3513 FWUpload_t
*prequest
;
3514 FWUploadReply_t
*preply
;
3515 FWUploadTCSGE_t
*ptcsge
;
3517 int ii
, sz
, reply_sz
;
3520 /* If the image size is 0, we are done.
3522 if ((sz
= ioc
->facts
.FWImageSize
) == 0)
3525 if (mpt_alloc_fw_memory(ioc
, ioc
->facts
.FWImageSize
) != 0)
3528 dinitprintk(ioc
, printk(MYIOC_s_INFO_FMT
": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3529 ioc
->name
, ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, sz
, sz
));
3531 prequest
= (sleepFlag
== NO_SLEEP
) ? kzalloc(ioc
->req_sz
, GFP_ATOMIC
) :
3532 kzalloc(ioc
->req_sz
, GFP_KERNEL
);
3534 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"fw upload failed "
3535 "while allocating memory \n", ioc
->name
));
3536 mpt_free_fw_memory(ioc
);
3540 preply
= (FWUploadReply_t
*)&reply
;
3542 reply_sz
= sizeof(reply
);
3543 memset(preply
, 0, reply_sz
);
3545 prequest
->ImageType
= MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM
;
3546 prequest
->Function
= MPI_FUNCTION_FW_UPLOAD
;
3548 ptcsge
= (FWUploadTCSGE_t
*) &prequest
->SGL
;
3549 ptcsge
->DetailsLength
= 12;
3550 ptcsge
->Flags
= MPI_SGE_FLAGS_TRANSACTION_ELEMENT
;
3551 ptcsge
->ImageSize
= cpu_to_le32(sz
);
3554 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_READ
| sz
;
3555 ioc
->add_sge((char *)ptcsge
, flagsLength
, ioc
->cached_fw_dma
);
3556 request_size
= offsetof(FWUpload_t
, SGL
) + sizeof(FWUploadTCSGE_t
) +
3558 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending FW Upload "
3559 " (req @ %p) fw_size=%d mf_request_size=%d\n", ioc
->name
, prequest
,
3560 ioc
->facts
.FWImageSize
, request_size
));
3561 DBG_DUMP_FW_REQUEST_FRAME(ioc
, (u32
*)prequest
);
3563 ii
= mpt_handshake_req_reply_wait(ioc
, request_size
, (u32
*)prequest
,
3564 reply_sz
, (u16
*)preply
, 65 /*seconds*/, sleepFlag
);
3566 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"FW Upload completed "
3567 "rc=%x \n", ioc
->name
, ii
));
3569 cmdStatus
= -EFAULT
;
3571 /* Handshake transfer was complete and successful.
3572 * Check the Reply Frame.
3575 status
= le16_to_cpu(preply
->IOCStatus
) &
3577 if (status
== MPI_IOCSTATUS_SUCCESS
&&
3578 ioc
->facts
.FWImageSize
==
3579 le32_to_cpu(preply
->ActualImageSize
))
3582 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
": do_upload cmdStatus=%d \n",
3583 ioc
->name
, cmdStatus
));
3587 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"fw upload failed, "
3588 "freeing image \n", ioc
->name
));
3589 mpt_free_fw_memory(ioc
);
3596 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3598 * mpt_downloadboot - DownloadBoot code
3599 * @ioc: Pointer to MPT_ADAPTER structure
3600 * @pFwHeader: Pointer to firmware header info
3601 * @sleepFlag: Specifies whether the process can sleep
3603 * FwDownloadBoot requires Programmed IO access.
3605 * Returns 0 for success
3606 * -1 FW Image size is 0
3607 * -2 No valid cached_fw Pointer
3608 * <0 for fw upload failure.
3611 mpt_downloadboot(MPT_ADAPTER
*ioc
, MpiFwHeader_t
*pFwHeader
, int sleepFlag
)
3613 MpiExtImageHeader_t
*pExtImage
;
3623 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3624 ioc
->name
, pFwHeader
->ImageSize
, pFwHeader
->ImageSize
, pFwHeader
));
3626 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3627 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3628 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3629 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3630 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3631 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3633 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, (MPI_DIAG_PREVENT_IOC_BOOT
| MPI_DIAG_DISABLE_ARM
));
3636 if (sleepFlag
== CAN_SLEEP
) {
3642 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3643 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_RESET_ADAPTER
);
3645 for (count
= 0; count
< 30; count
++) {
3646 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3647 if (!(diag0val
& MPI_DIAG_RESET_ADAPTER
)) {
3648 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RESET_ADAPTER cleared, count=%d\n",
3653 if (sleepFlag
== CAN_SLEEP
) {
3660 if ( count
== 30 ) {
3661 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot failed! "
3662 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3663 ioc
->name
, diag0val
));
3667 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3668 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3669 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3670 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3671 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3672 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3674 /* Set the DiagRwEn and Disable ARM bits */
3675 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, (MPI_DIAG_RW_ENABLE
| MPI_DIAG_DISABLE_ARM
));
3677 fwSize
= (pFwHeader
->ImageSize
+ 3)/4;
3678 ptrFw
= (u32
*) pFwHeader
;
3680 /* Write the LoadStartAddress to the DiagRw Address Register
3681 * using Programmed IO
3683 if (ioc
->errata_flag_1064
)
3684 pci_enable_io_access(ioc
->pcidev
);
3686 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, pFwHeader
->LoadStartAddress
);
3687 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"LoadStart addr written 0x%x \n",
3688 ioc
->name
, pFwHeader
->LoadStartAddress
));
3690 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write FW Image: 0x%x bytes @ %p\n",
3691 ioc
->name
, fwSize
*4, ptrFw
));
3693 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, *ptrFw
++);
3696 nextImage
= pFwHeader
->NextImageHeaderOffset
;
3698 pExtImage
= (MpiExtImageHeader_t
*) ((char *)pFwHeader
+ nextImage
);
3700 load_addr
= pExtImage
->LoadStartAddress
;
3702 fwSize
= (pExtImage
->ImageSize
+ 3) >> 2;
3703 ptrFw
= (u32
*)pExtImage
;
3705 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3706 ioc
->name
, fwSize
*4, fwSize
*4, ptrFw
, load_addr
));
3707 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, load_addr
);
3710 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, *ptrFw
++);
3712 nextImage
= pExtImage
->NextImageHeaderOffset
;
3715 /* Write the IopResetVectorRegAddr */
3716 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write IopResetVector Addr=%x! \n", ioc
->name
, pFwHeader
->IopResetRegAddr
));
3717 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, pFwHeader
->IopResetRegAddr
);
3719 /* Write the IopResetVectorValue */
3720 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Write IopResetVector Value=%x! \n", ioc
->name
, pFwHeader
->IopResetVectorValue
));
3721 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, pFwHeader
->IopResetVectorValue
);
3723 /* Clear the internal flash bad bit - autoincrementing register,
3724 * so must do two writes.
3726 if (ioc
->bus_type
== SPI
) {
3728 * 1030 and 1035 H/W errata, workaround to access
3729 * the ClearFlashBadSignatureBit
3731 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, 0x3F000000);
3732 diagRwData
= CHIPREG_PIO_READ32(&ioc
->pio_chip
->DiagRwData
);
3733 diagRwData
|= 0x40000000;
3734 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, 0x3F000000);
3735 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, diagRwData
);
3737 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3738 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3739 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
|
3740 MPI_DIAG_CLEAR_FLASH_BAD_SIG
);
3743 if (sleepFlag
== CAN_SLEEP
) {
3750 if (ioc
->errata_flag_1064
)
3751 pci_disable_io_access(ioc
->pcidev
);
3753 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3754 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot diag0val=%x, "
3755 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3756 ioc
->name
, diag0val
));
3757 diag0val
&= ~(MPI_DIAG_PREVENT_IOC_BOOT
| MPI_DIAG_DISABLE_ARM
| MPI_DIAG_RW_ENABLE
);
3758 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"downloadboot now diag0val=%x\n",
3759 ioc
->name
, diag0val
));
3760 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
);
3762 /* Write 0xFF to reset the sequencer */
3763 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3765 if (ioc
->bus_type
== SAS
) {
3766 ioc_state
= mpt_GetIocState(ioc
, 0);
3767 if ( (GetIocFacts(ioc
, sleepFlag
,
3768 MPT_HOSTEVENT_IOC_BRINGUP
)) != 0 ) {
3769 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"GetIocFacts failed: IocState=%x\n",
3770 ioc
->name
, ioc_state
));
3775 for (count
=0; count
<HZ
*20; count
++) {
3776 if ((ioc_state
= mpt_GetIocState(ioc
, 0)) & MPI_IOC_STATE_READY
) {
3777 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3778 "downloadboot successful! (count=%d) IocState=%x\n",
3779 ioc
->name
, count
, ioc_state
));
3780 if (ioc
->bus_type
== SAS
) {
3783 if ((SendIocInit(ioc
, sleepFlag
)) != 0) {
3784 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3785 "downloadboot: SendIocInit failed\n",
3789 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3790 "downloadboot: SendIocInit successful\n",
3794 if (sleepFlag
== CAN_SLEEP
) {
3800 ddlprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3801 "downloadboot failed! IocState=%x\n",ioc
->name
, ioc_state
));
3805 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3807 * KickStart - Perform hard reset of MPT adapter.
3808 * @ioc: Pointer to MPT_ADAPTER structure
3809 * @force: Force hard reset
3810 * @sleepFlag: Specifies whether the process can sleep
3812 * This routine places MPT adapter in diagnostic mode via the
3813 * WriteSequence register, and then performs a hard reset of adapter
3814 * via the Diagnostic register.
3816 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3817 * or NO_SLEEP (interrupt thread, use mdelay)
3818 * force - 1 if doorbell active, board fault state
3819 * board operational, IOC_RECOVERY or
3820 * IOC_BRINGUP and there is an alt_ioc.
3824 * 1 - hard reset, READY
3825 * 0 - no reset due to History bit, READY
3826 * -1 - no reset due to History bit but not READY
3827 * OR reset but failed to come READY
3828 * -2 - no reset, could not enter DIAG mode
3829 * -3 - reset but bad FW bit
3832 KickStart(MPT_ADAPTER
*ioc
, int force
, int sleepFlag
)
3834 int hard_reset_done
= 0;
3838 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"KickStarting!\n", ioc
->name
));
3839 if (ioc
->bus_type
== SPI
) {
3840 /* Always issue a Msg Unit Reset first. This will clear some
3841 * SCSI bus hang conditions.
3843 SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
);
3845 if (sleepFlag
== CAN_SLEEP
) {
3852 hard_reset_done
= mpt_diag_reset(ioc
, force
, sleepFlag
);
3853 if (hard_reset_done
< 0)
3854 return hard_reset_done
;
3856 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Diagnostic reset successful!\n",
3859 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 2; /* 2 seconds */
3860 for (cnt
=0; cnt
<cntdn
; cnt
++) {
3861 ioc_state
= mpt_GetIocState(ioc
, 1);
3862 if ((ioc_state
== MPI_IOC_STATE_READY
) || (ioc_state
== MPI_IOC_STATE_OPERATIONAL
)) {
3863 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"KickStart successful! (cnt=%d)\n",
3865 return hard_reset_done
;
3867 if (sleepFlag
== CAN_SLEEP
) {
3874 dinitprintk(ioc
, printk(MYIOC_s_ERR_FMT
"Failed to come READY after reset! IocState=%x\n",
3875 ioc
->name
, mpt_GetIocState(ioc
, 0)));
3879 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3881 * mpt_diag_reset - Perform hard reset of the adapter.
3882 * @ioc: Pointer to MPT_ADAPTER structure
3883 * @ignore: Set if to honor and clear to ignore
3884 * the reset history bit
3885 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3886 * else set to NO_SLEEP (use mdelay instead)
3888 * This routine places the adapter in diagnostic mode via the
3889 * WriteSequence register and then performs a hard reset of adapter
3890 * via the Diagnostic register. Adapter should be in ready state
3891 * upon successful completion.
3893 * Returns: 1 hard reset successful
3894 * 0 no reset performed because reset history bit set
3895 * -2 enabling diagnostic mode failed
3896 * -3 diagnostic reset failed
3899 mpt_diag_reset(MPT_ADAPTER
*ioc
, int ignore
, int sleepFlag
)
3903 int hard_reset_done
= 0;
3906 MpiFwHeader_t
*cached_fw
; /* Pointer to FW */
3909 /* Clear any existing interrupts */
3910 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
3912 if (ioc
->pcidev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1078
) {
3917 drsprintk(ioc
, printk(MYIOC_s_WARN_FMT
"%s: Doorbell=%p; 1078 reset "
3918 "address=%p\n", ioc
->name
, __func__
,
3919 &ioc
->chip
->Doorbell
, &ioc
->chip
->Reset_1078
));
3920 CHIPREG_WRITE32(&ioc
->chip
->Reset_1078
, 0x07);
3921 if (sleepFlag
== CAN_SLEEP
)
3927 * Call each currently registered protocol IOC reset handler
3928 * with pre-reset indication.
3929 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3930 * MptResetHandlers[] registered yet.
3932 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
3933 if (MptResetHandlers
[cb_idx
])
3934 (*(MptResetHandlers
[cb_idx
]))(ioc
,
3938 for (count
= 0; count
< 60; count
++) {
3939 doorbell
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
3940 doorbell
&= MPI_IOC_STATE_MASK
;
3942 drsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
3943 "looking for READY STATE: doorbell=%x"
3945 ioc
->name
, doorbell
, count
));
3947 if (doorbell
== MPI_IOC_STATE_READY
) {
3952 if (sleepFlag
== CAN_SLEEP
)
3960 /* Use "Diagnostic reset" method! (only thing available!) */
3961 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3963 if (ioc
->debug_level
& MPT_DEBUG
) {
3965 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
3966 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG1: diag0=%08x, diag1=%08x\n",
3967 ioc
->name
, diag0val
, diag1val
));
3970 /* Do the reset if we are told to ignore the reset history
3971 * or if the reset history is 0
3973 if (ignore
|| !(diag0val
& MPI_DIAG_RESET_HISTORY
)) {
3974 while ((diag0val
& MPI_DIAG_DRWE
) == 0) {
3975 /* Write magic sequence to WriteSequence register
3976 * Loop until in diagnostic mode
3978 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3979 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3980 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3981 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3982 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3983 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3986 if (sleepFlag
== CAN_SLEEP
) {
3994 printk(MYIOC_s_ERR_FMT
"Enable Diagnostic mode FAILED! (%02xh)\n",
3995 ioc
->name
, diag0val
);
4000 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4002 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Wrote magic DiagWriteEn sequence (%x)\n",
4003 ioc
->name
, diag0val
));
4006 if (ioc
->debug_level
& MPT_DEBUG
) {
4008 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
4009 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG2: diag0=%08x, diag1=%08x\n",
4010 ioc
->name
, diag0val
, diag1val
));
4013 * Disable the ARM (Bug fix)
4016 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_DISABLE_ARM
);
4020 * Now hit the reset bit in the Diagnostic register
4021 * (THE BIG HAMMER!) (Clears DRWE bit).
4023 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_RESET_ADAPTER
);
4024 hard_reset_done
= 1;
4025 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Diagnostic reset performed\n",
4029 * Call each currently registered protocol IOC reset handler
4030 * with pre-reset indication.
4031 * NOTE: If we're doing _IOC_BRINGUP, there can be no
4032 * MptResetHandlers[] registered yet.
4034 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
4035 if (MptResetHandlers
[cb_idx
]) {
4036 mpt_signal_reset(cb_idx
,
4037 ioc
, MPT_IOC_PRE_RESET
);
4039 mpt_signal_reset(cb_idx
,
4040 ioc
->alt_ioc
, MPT_IOC_PRE_RESET
);
4046 cached_fw
= (MpiFwHeader_t
*)ioc
->cached_fw
;
4047 else if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
)
4048 cached_fw
= (MpiFwHeader_t
*)ioc
->alt_ioc
->cached_fw
;
4052 /* If the DownloadBoot operation fails, the
4053 * IOC will be left unusable. This is a fatal error
4054 * case. _diag_reset will return < 0
4056 for (count
= 0; count
< 30; count
++) {
4057 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4058 if (!(diag0val
& MPI_DIAG_RESET_ADAPTER
)) {
4062 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"cached_fw: diag0val=%x count=%d\n",
4063 ioc
->name
, diag0val
, count
));
4065 if (sleepFlag
== CAN_SLEEP
) {
4071 if ((count
= mpt_downloadboot(ioc
, cached_fw
, sleepFlag
)) < 0) {
4072 printk(MYIOC_s_WARN_FMT
4073 "firmware downloadboot failure (%d)!\n", ioc
->name
, count
);
4077 /* Wait for FW to reload and for board
4078 * to go to the READY state.
4079 * Maximum wait is 60 seconds.
4080 * If fail, no error will check again
4081 * with calling program.
4083 for (count
= 0; count
< 60; count
++) {
4084 doorbell
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
4085 doorbell
&= MPI_IOC_STATE_MASK
;
4087 drsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4088 "looking for READY STATE: doorbell=%x"
4089 " count=%d\n", ioc
->name
, doorbell
, count
));
4091 if (doorbell
== MPI_IOC_STATE_READY
) {
4096 if (sleepFlag
== CAN_SLEEP
) {
4103 if (doorbell
!= MPI_IOC_STATE_READY
)
4104 printk(MYIOC_s_ERR_FMT
"Failed to come READY "
4105 "after reset! IocState=%x", ioc
->name
,
4110 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4111 if (ioc
->debug_level
& MPT_DEBUG
) {
4113 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
4114 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG3: diag0=%08x, diag1=%08x\n",
4115 ioc
->name
, diag0val
, diag1val
));
4118 /* Clear RESET_HISTORY bit! Place board in the
4119 * diagnostic mode to update the diag register.
4121 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4123 while ((diag0val
& MPI_DIAG_DRWE
) == 0) {
4124 /* Write magic sequence to WriteSequence register
4125 * Loop until in diagnostic mode
4127 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
4128 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
4129 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
4130 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
4131 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
4132 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
4135 if (sleepFlag
== CAN_SLEEP
) {
4143 printk(MYIOC_s_ERR_FMT
"Enable Diagnostic mode FAILED! (%02xh)\n",
4144 ioc
->name
, diag0val
);
4147 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4149 diag0val
&= ~MPI_DIAG_RESET_HISTORY
;
4150 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
);
4151 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4152 if (diag0val
& MPI_DIAG_RESET_HISTORY
) {
4153 printk(MYIOC_s_WARN_FMT
"ResetHistory bit failed to clear!\n",
4157 /* Disable Diagnostic Mode
4159 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFFFFFFFF);
4161 /* Check FW reload status flags.
4163 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
4164 if (diag0val
& (MPI_DIAG_FLASH_BAD_SIG
| MPI_DIAG_RESET_ADAPTER
| MPI_DIAG_DISABLE_ARM
)) {
4165 printk(MYIOC_s_ERR_FMT
"Diagnostic reset FAILED! (%02xh)\n",
4166 ioc
->name
, diag0val
);
4170 if (ioc
->debug_level
& MPT_DEBUG
) {
4172 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
4173 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"DbG4: diag0=%08x, diag1=%08x\n",
4174 ioc
->name
, diag0val
, diag1val
));
4178 * Reset flag that says we've enabled event notification
4180 ioc
->facts
.EventState
= 0;
4183 ioc
->alt_ioc
->facts
.EventState
= 0;
4185 return hard_reset_done
;
4188 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4190 * SendIocReset - Send IOCReset request to MPT adapter.
4191 * @ioc: Pointer to MPT_ADAPTER structure
4192 * @reset_type: reset type, expected values are
4193 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
4194 * @sleepFlag: Specifies whether the process can sleep
4196 * Send IOCReset request to the MPT adapter.
4198 * Returns 0 for success, non-zero for failure.
4201 SendIocReset(MPT_ADAPTER
*ioc
, u8 reset_type
, int sleepFlag
)
4207 drsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending IOC reset(0x%02x)!\n",
4208 ioc
->name
, reset_type
));
4209 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, reset_type
<<MPI_DOORBELL_FUNCTION_SHIFT
);
4210 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
4213 /* FW ACK'd request, wait for READY state
4216 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 15; /* 15 seconds */
4218 while ((state
= mpt_GetIocState(ioc
, 1)) != MPI_IOC_STATE_READY
) {
4222 if (sleepFlag
!= CAN_SLEEP
)
4225 printk(MYIOC_s_ERR_FMT
4226 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
4227 ioc
->name
, state
, (int)((count
+5)/HZ
));
4231 if (sleepFlag
== CAN_SLEEP
) {
4234 mdelay (1); /* 1 msec delay */
4239 * Cleanup all event stuff for this IOC; re-issue EventNotification
4240 * request if needed.
4242 if (ioc
->facts
.Function
)
4243 ioc
->facts
.EventState
= 0;
4248 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4250 * initChainBuffers - Allocate memory for and initialize chain buffers
4251 * @ioc: Pointer to MPT_ADAPTER structure
4253 * Allocates memory for and initializes chain buffers,
4254 * chain buffer control arrays and spinlock.
4257 initChainBuffers(MPT_ADAPTER
*ioc
)
4260 int sz
, ii
, num_chain
;
4261 int scale
, num_sge
, numSGE
;
4263 /* ReqToChain size must equal the req_depth
4266 if (ioc
->ReqToChain
== NULL
) {
4267 sz
= ioc
->req_depth
* sizeof(int);
4268 mem
= kmalloc(sz
, GFP_ATOMIC
);
4272 ioc
->ReqToChain
= (int *) mem
;
4273 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReqToChain alloc @ %p, sz=%d bytes\n",
4274 ioc
->name
, mem
, sz
));
4275 mem
= kmalloc(sz
, GFP_ATOMIC
);
4279 ioc
->RequestNB
= (int *) mem
;
4280 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestNB alloc @ %p, sz=%d bytes\n",
4281 ioc
->name
, mem
, sz
));
4283 for (ii
= 0; ii
< ioc
->req_depth
; ii
++) {
4284 ioc
->ReqToChain
[ii
] = MPT_HOST_NO_CHAIN
;
4287 /* ChainToChain size must equal the total number
4288 * of chain buffers to be allocated.
4291 * Calculate the number of chain buffers needed(plus 1) per I/O
4292 * then multiply the maximum number of simultaneous cmds
4294 * num_sge = num sge in request frame + last chain buffer
4295 * scale = num sge per chain buffer if no chain element
4297 scale
= ioc
->req_sz
/ ioc
->SGE_size
;
4298 if (ioc
->sg_addr_size
== sizeof(u64
))
4299 num_sge
= scale
+ (ioc
->req_sz
- 60) / ioc
->SGE_size
;
4301 num_sge
= 1 + scale
+ (ioc
->req_sz
- 64) / ioc
->SGE_size
;
4303 if (ioc
->sg_addr_size
== sizeof(u64
)) {
4304 numSGE
= (scale
- 1) * (ioc
->facts
.MaxChainDepth
-1) + scale
+
4305 (ioc
->req_sz
- 60) / ioc
->SGE_size
;
4307 numSGE
= 1 + (scale
- 1) * (ioc
->facts
.MaxChainDepth
-1) +
4308 scale
+ (ioc
->req_sz
- 64) / ioc
->SGE_size
;
4310 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"num_sge=%d numSGE=%d\n",
4311 ioc
->name
, num_sge
, numSGE
));
4313 if (ioc
->bus_type
== FC
) {
4314 if (numSGE
> MPT_SCSI_FC_SG_DEPTH
)
4315 numSGE
= MPT_SCSI_FC_SG_DEPTH
;
4317 if (numSGE
> MPT_SCSI_SG_DEPTH
)
4318 numSGE
= MPT_SCSI_SG_DEPTH
;
4322 while (numSGE
- num_sge
> 0) {
4324 num_sge
+= (scale
- 1);
4328 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Now numSGE=%d num_sge=%d num_chain=%d\n",
4329 ioc
->name
, numSGE
, num_sge
, num_chain
));
4331 if (ioc
->bus_type
== SPI
)
4332 num_chain
*= MPT_SCSI_CAN_QUEUE
;
4333 else if (ioc
->bus_type
== SAS
)
4334 num_chain
*= MPT_SAS_CAN_QUEUE
;
4336 num_chain
*= MPT_FC_CAN_QUEUE
;
4338 ioc
->num_chain
= num_chain
;
4340 sz
= num_chain
* sizeof(int);
4341 if (ioc
->ChainToChain
== NULL
) {
4342 mem
= kmalloc(sz
, GFP_ATOMIC
);
4346 ioc
->ChainToChain
= (int *) mem
;
4347 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainToChain alloc @ %p, sz=%d bytes\n",
4348 ioc
->name
, mem
, sz
));
4350 mem
= (u8
*) ioc
->ChainToChain
;
4352 memset(mem
, 0xFF, sz
);
4356 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4358 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
4359 * @ioc: Pointer to MPT_ADAPTER structure
4361 * This routine allocates memory for the MPT reply and request frame
4362 * pools (if necessary), and primes the IOC reply FIFO with
4365 * Returns 0 for success, non-zero for failure.
4368 PrimeIocFifos(MPT_ADAPTER
*ioc
)
4371 unsigned long flags
;
4372 dma_addr_t alloc_dma
;
4374 int i
, reply_sz
, sz
, total_size
, num_chain
;
4379 /* Prime reply FIFO... */
4381 if (ioc
->reply_frames
== NULL
) {
4382 if ( (num_chain
= initChainBuffers(ioc
)) < 0)
4385 * 1078 errata workaround for the 36GB limitation
4387 if (ioc
->pcidev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1078
&&
4388 ioc
->dma_mask
> DMA_BIT_MASK(35)) {
4389 if (!pci_set_dma_mask(ioc
->pcidev
, DMA_BIT_MASK(32))
4390 && !pci_set_consistent_dma_mask(ioc
->pcidev
,
4391 DMA_BIT_MASK(32))) {
4392 dma_mask
= DMA_BIT_MASK(35);
4393 d36memprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4394 "setting 35 bit addressing for "
4395 "Request/Reply/Chain and Sense Buffers\n",
4398 /*Reseting DMA mask to 64 bit*/
4399 pci_set_dma_mask(ioc
->pcidev
,
4401 pci_set_consistent_dma_mask(ioc
->pcidev
,
4404 printk(MYIOC_s_ERR_FMT
4405 "failed setting 35 bit addressing for "
4406 "Request/Reply/Chain and Sense Buffers\n",
4412 total_size
= reply_sz
= (ioc
->reply_sz
* ioc
->reply_depth
);
4413 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
4414 ioc
->name
, ioc
->reply_sz
, ioc
->reply_depth
));
4415 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffer sz=%d[%x] bytes\n",
4416 ioc
->name
, reply_sz
, reply_sz
));
4418 sz
= (ioc
->req_sz
* ioc
->req_depth
);
4419 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestBuffer sz=%d bytes, RequestDepth=%d\n",
4420 ioc
->name
, ioc
->req_sz
, ioc
->req_depth
));
4421 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestBuffer sz=%d[%x] bytes\n",
4422 ioc
->name
, sz
, sz
));
4425 sz
= num_chain
* ioc
->req_sz
; /* chain buffer pool size */
4426 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainBuffer sz=%d bytes, ChainDepth=%d\n",
4427 ioc
->name
, ioc
->req_sz
, num_chain
));
4428 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
4429 ioc
->name
, sz
, sz
, num_chain
));
4432 mem
= pci_alloc_consistent(ioc
->pcidev
, total_size
, &alloc_dma
);
4434 printk(MYIOC_s_ERR_FMT
"Unable to allocate Reply, Request, Chain Buffers!\n",
4439 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Total alloc @ %p[%p], sz=%d[%x] bytes\n",
4440 ioc
->name
, mem
, (void *)(ulong
)alloc_dma
, total_size
, total_size
));
4442 memset(mem
, 0, total_size
);
4443 ioc
->alloc_total
+= total_size
;
4445 ioc
->alloc_dma
= alloc_dma
;
4446 ioc
->alloc_sz
= total_size
;
4447 ioc
->reply_frames
= (MPT_FRAME_HDR
*) mem
;
4448 ioc
->reply_frames_low_dma
= (u32
) (alloc_dma
& 0xFFFFFFFF);
4450 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffers @ %p[%p]\n",
4451 ioc
->name
, ioc
->reply_frames
, (void *)(ulong
)alloc_dma
));
4453 alloc_dma
+= reply_sz
;
4456 /* Request FIFO - WE manage this! */
4458 ioc
->req_frames
= (MPT_FRAME_HDR
*) mem
;
4459 ioc
->req_frames_dma
= alloc_dma
;
4461 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"RequestBuffers @ %p[%p]\n",
4462 ioc
->name
, mem
, (void *)(ulong
)alloc_dma
));
4464 ioc
->req_frames_low_dma
= (u32
) (alloc_dma
& 0xFFFFFFFF);
4466 #if defined(CONFIG_MTRR) && 0
4468 * Enable Write Combining MTRR for IOC's memory region.
4469 * (at least as much as we can; "size and base must be
4470 * multiples of 4 kiB"
4472 ioc
->mtrr_reg
= mtrr_add(ioc
->req_frames_dma
,
4474 MTRR_TYPE_WRCOMB
, 1);
4475 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"MTRR region registered (base:size=%08x:%x)\n",
4476 ioc
->name
, ioc
->req_frames_dma
, sz
));
4479 for (i
= 0; i
< ioc
->req_depth
; i
++) {
4480 alloc_dma
+= ioc
->req_sz
;
4484 ioc
->ChainBuffer
= mem
;
4485 ioc
->ChainBufferDMA
= alloc_dma
;
4487 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ChainBuffers @ %p(%p)\n",
4488 ioc
->name
, ioc
->ChainBuffer
, (void *)(ulong
)ioc
->ChainBufferDMA
));
4490 /* Initialize the free chain Q.
4493 INIT_LIST_HEAD(&ioc
->FreeChainQ
);
4495 /* Post the chain buffers to the FreeChainQ.
4497 mem
= (u8
*)ioc
->ChainBuffer
;
4498 for (i
=0; i
< num_chain
; i
++) {
4499 mf
= (MPT_FRAME_HDR
*) mem
;
4500 list_add_tail(&mf
->u
.frame
.linkage
.list
, &ioc
->FreeChainQ
);
4504 /* Initialize Request frames linked list
4506 alloc_dma
= ioc
->req_frames_dma
;
4507 mem
= (u8
*) ioc
->req_frames
;
4509 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
4510 INIT_LIST_HEAD(&ioc
->FreeQ
);
4511 for (i
= 0; i
< ioc
->req_depth
; i
++) {
4512 mf
= (MPT_FRAME_HDR
*) mem
;
4514 /* Queue REQUESTs *internally*! */
4515 list_add_tail(&mf
->u
.frame
.linkage
.list
, &ioc
->FreeQ
);
4519 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
4521 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
4522 ioc
->sense_buf_pool
=
4523 pci_alloc_consistent(ioc
->pcidev
, sz
, &ioc
->sense_buf_pool_dma
);
4524 if (ioc
->sense_buf_pool
== NULL
) {
4525 printk(MYIOC_s_ERR_FMT
"Unable to allocate Sense Buffers!\n",
4530 ioc
->sense_buf_low_dma
= (u32
) (ioc
->sense_buf_pool_dma
& 0xFFFFFFFF);
4531 ioc
->alloc_total
+= sz
;
4532 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SenseBuffers @ %p[%p]\n",
4533 ioc
->name
, ioc
->sense_buf_pool
, (void *)(ulong
)ioc
->sense_buf_pool_dma
));
4537 /* Post Reply frames to FIFO
4539 alloc_dma
= ioc
->alloc_dma
;
4540 dinitprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"ReplyBuffers @ %p[%p]\n",
4541 ioc
->name
, ioc
->reply_frames
, (void *)(ulong
)alloc_dma
));
4543 for (i
= 0; i
< ioc
->reply_depth
; i
++) {
4544 /* Write each address to the IOC! */
4545 CHIPREG_WRITE32(&ioc
->chip
->ReplyFifo
, alloc_dma
);
4546 alloc_dma
+= ioc
->reply_sz
;
4549 if (dma_mask
== DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc
->pcidev
,
4550 ioc
->dma_mask
) && !pci_set_consistent_dma_mask(ioc
->pcidev
,
4552 d36memprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4553 "restoring 64 bit addressing\n", ioc
->name
));
4559 if (ioc
->alloc
!= NULL
) {
4561 pci_free_consistent(ioc
->pcidev
,
4563 ioc
->alloc
, ioc
->alloc_dma
);
4564 ioc
->reply_frames
= NULL
;
4565 ioc
->req_frames
= NULL
;
4566 ioc
->alloc_total
-= sz
;
4568 if (ioc
->sense_buf_pool
!= NULL
) {
4569 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
4570 pci_free_consistent(ioc
->pcidev
,
4572 ioc
->sense_buf_pool
, ioc
->sense_buf_pool_dma
);
4573 ioc
->sense_buf_pool
= NULL
;
4576 if (dma_mask
== DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc
->pcidev
,
4577 DMA_BIT_MASK(64)) && !pci_set_consistent_dma_mask(ioc
->pcidev
,
4579 d36memprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
4580 "restoring 64 bit addressing\n", ioc
->name
));
4585 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4587 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4588 * from IOC via doorbell handshake method.
4589 * @ioc: Pointer to MPT_ADAPTER structure
4590 * @reqBytes: Size of the request in bytes
4591 * @req: Pointer to MPT request frame
4592 * @replyBytes: Expected size of the reply in bytes
4593 * @u16reply: Pointer to area where reply should be written
4594 * @maxwait: Max wait time for a reply (in seconds)
4595 * @sleepFlag: Specifies whether the process can sleep
4597 * NOTES: It is the callers responsibility to byte-swap fields in the
4598 * request which are greater than 1 byte in size. It is also the
4599 * callers responsibility to byte-swap response fields which are
4600 * greater than 1 byte in size.
4602 * Returns 0 for success, non-zero for failure.
4605 mpt_handshake_req_reply_wait(MPT_ADAPTER
*ioc
, int reqBytes
, u32
*req
,
4606 int replyBytes
, u16
*u16reply
, int maxwait
, int sleepFlag
)
4608 MPIDefaultReply_t
*mptReply
;
4613 * Get ready to cache a handshake reply
4615 ioc
->hs_reply_idx
= 0;
4616 mptReply
= (MPIDefaultReply_t
*) ioc
->hs_reply
;
4617 mptReply
->MsgLength
= 0;
4620 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4621 * then tell IOC that we want to handshake a request of N words.
4622 * (WRITE u32val to Doorbell reg).
4624 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4625 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
,
4626 ((MPI_FUNCTION_HANDSHAKE
<<MPI_DOORBELL_FUNCTION_SHIFT
) |
4627 ((reqBytes
/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT
)));
4630 * Wait for IOC's doorbell handshake int
4632 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4635 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4636 ioc
->name
, reqBytes
, t
, failcnt
? " - MISSING DOORBELL HANDSHAKE!" : ""));
4638 /* Read doorbell and check for active bit */
4639 if (!(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & MPI_DOORBELL_ACTIVE
))
4643 * Clear doorbell int (WRITE 0 to IntStatus reg),
4644 * then wait for IOC to ACKnowledge that it's ready for
4645 * our handshake request.
4647 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4648 if (!failcnt
&& (t
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
4653 u8
*req_as_bytes
= (u8
*) req
;
4656 * Stuff request words via doorbell handshake,
4657 * with ACK from IOC for each.
4659 for (ii
= 0; !failcnt
&& ii
< reqBytes
/4; ii
++) {
4660 u32 word
= ((req_as_bytes
[(ii
*4) + 0] << 0) |
4661 (req_as_bytes
[(ii
*4) + 1] << 8) |
4662 (req_as_bytes
[(ii
*4) + 2] << 16) |
4663 (req_as_bytes
[(ii
*4) + 3] << 24));
4665 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, word
);
4666 if ((t
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
4670 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Handshake request frame (@%p) header\n", ioc
->name
, req
));
4671 DBG_DUMP_REQUEST_FRAME_HDR(ioc
, (u32
*)req
);
4673 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HandShake request post done, WaitCnt=%d%s\n",
4674 ioc
->name
, t
, failcnt
? " - MISSING DOORBELL ACK!" : ""));
4677 * Wait for completion of doorbell handshake reply from the IOC
4679 if (!failcnt
&& (t
= WaitForDoorbellReply(ioc
, maxwait
, sleepFlag
)) < 0)
4682 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HandShake reply count=%d%s\n",
4683 ioc
->name
, t
, failcnt
? " - MISSING DOORBELL REPLY!" : ""));
4686 * Copy out the cached reply...
4688 for (ii
=0; ii
< min(replyBytes
/2,mptReply
->MsgLength
*2); ii
++)
4689 u16reply
[ii
] = ioc
->hs_reply
[ii
];
4697 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4699 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4700 * @ioc: Pointer to MPT_ADAPTER structure
4701 * @howlong: How long to wait (in seconds)
4702 * @sleepFlag: Specifies whether the process can sleep
4704 * This routine waits (up to ~2 seconds max) for IOC doorbell
4705 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4706 * bit in its IntStatus register being clear.
4708 * Returns a negative value on failure, else wait loop count.
4711 WaitForDoorbellAck(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
4717 cntdn
= 1000 * howlong
;
4719 if (sleepFlag
== CAN_SLEEP
) {
4722 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4723 if (! (intstat
& MPI_HIS_IOP_DOORBELL_STATUS
))
4730 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4731 if (! (intstat
& MPI_HIS_IOP_DOORBELL_STATUS
))
4738 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitForDoorbell ACK (count=%d)\n",
4743 printk(MYIOC_s_ERR_FMT
"Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4744 ioc
->name
, count
, intstat
);
4748 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4750 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4751 * @ioc: Pointer to MPT_ADAPTER structure
4752 * @howlong: How long to wait (in seconds)
4753 * @sleepFlag: Specifies whether the process can sleep
4755 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4756 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4758 * Returns a negative value on failure, else wait loop count.
4761 WaitForDoorbellInt(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
4767 cntdn
= 1000 * howlong
;
4768 if (sleepFlag
== CAN_SLEEP
) {
4770 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4771 if (intstat
& MPI_HIS_DOORBELL_INTERRUPT
)
4778 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
4779 if (intstat
& MPI_HIS_DOORBELL_INTERRUPT
)
4787 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4788 ioc
->name
, count
, howlong
));
4792 printk(MYIOC_s_ERR_FMT
"Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4793 ioc
->name
, count
, intstat
);
4797 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4799 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4800 * @ioc: Pointer to MPT_ADAPTER structure
4801 * @howlong: How long to wait (in seconds)
4802 * @sleepFlag: Specifies whether the process can sleep
4804 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4805 * Reply is cached to IOC private area large enough to hold a maximum
4806 * of 128 bytes of reply data.
4808 * Returns a negative value on failure, else size of reply in WORDS.
4811 WaitForDoorbellReply(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
4816 u16
*hs_reply
= ioc
->hs_reply
;
4817 volatile MPIDefaultReply_t
*mptReply
= (MPIDefaultReply_t
*) ioc
->hs_reply
;
4820 hs_reply
[0] = hs_reply
[1] = hs_reply
[7] = 0;
4823 * Get first two u16's so we can look at IOC's intended reply MsgLength
4826 if ((t
= WaitForDoorbellInt(ioc
, howlong
, sleepFlag
)) < 0) {
4829 hs_reply
[u16cnt
++] = le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4830 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4831 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4834 hs_reply
[u16cnt
++] = le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4835 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4839 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitCnt=%d First handshake reply word=%08x%s\n",
4840 ioc
->name
, t
, le32_to_cpu(*(u32
*)hs_reply
),
4841 failcnt
? " - MISSING DOORBELL HANDSHAKE!" : ""));
4844 * If no error (and IOC said MsgLength is > 0), piece together
4845 * reply 16 bits at a time.
4847 for (u16cnt
=2; !failcnt
&& u16cnt
< (2 * mptReply
->MsgLength
); u16cnt
++) {
4848 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4850 hword
= le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4851 /* don't overflow our IOC hs_reply[] buffer! */
4852 if (u16cnt
< ARRAY_SIZE(ioc
->hs_reply
))
4853 hs_reply
[u16cnt
] = hword
;
4854 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4857 if (!failcnt
&& (t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4859 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4862 printk(MYIOC_s_ERR_FMT
"Handshake reply failure!\n",
4867 else if (u16cnt
!= (2 * mptReply
->MsgLength
)) {
4870 else if ((mptReply
->IOCStatus
& MPI_IOCSTATUS_MASK
) != MPI_IOCSTATUS_SUCCESS
) {
4875 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Got Handshake reply:\n", ioc
->name
));
4876 DBG_DUMP_REPLY_FRAME(ioc
, (u32
*)mptReply
);
4878 dhsprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4879 ioc
->name
, t
, u16cnt
/2));
4883 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4885 * GetLanConfigPages - Fetch LANConfig pages.
4886 * @ioc: Pointer to MPT_ADAPTER structure
4888 * Return: 0 for success
4889 * -ENOMEM if no memory available
4890 * -EPERM if not allowed due to ISR context
4891 * -EAGAIN if no msg frames currently available
4892 * -EFAULT for non-successful reply or no reply (timeout)
4895 GetLanConfigPages(MPT_ADAPTER
*ioc
)
4897 ConfigPageHeader_t hdr
;
4899 LANPage0_t
*ppage0_alloc
;
4900 dma_addr_t page0_dma
;
4901 LANPage1_t
*ppage1_alloc
;
4902 dma_addr_t page1_dma
;
4907 /* Get LAN Page 0 header */
4908 hdr
.PageVersion
= 0;
4911 hdr
.PageType
= MPI_CONFIG_PAGETYPE_LAN
;
4912 cfg
.cfghdr
.hdr
= &hdr
;
4914 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4919 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
4922 if (hdr
.PageLength
> 0) {
4923 data_sz
= hdr
.PageLength
* 4;
4924 ppage0_alloc
= (LANPage0_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page0_dma
);
4927 memset((u8
*)ppage0_alloc
, 0, data_sz
);
4928 cfg
.physAddr
= page0_dma
;
4929 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4931 if ((rc
= mpt_config(ioc
, &cfg
)) == 0) {
4933 copy_sz
= min_t(int, sizeof(LANPage0_t
), data_sz
);
4934 memcpy(&ioc
->lan_cnfg_page0
, ppage0_alloc
, copy_sz
);
4938 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage0_alloc
, page0_dma
);
4941 * Normalize endianness of structure data,
4942 * by byte-swapping all > 1 byte fields!
4951 /* Get LAN Page 1 header */
4952 hdr
.PageVersion
= 0;
4955 hdr
.PageType
= MPI_CONFIG_PAGETYPE_LAN
;
4956 cfg
.cfghdr
.hdr
= &hdr
;
4958 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4962 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
4965 if (hdr
.PageLength
== 0)
4968 data_sz
= hdr
.PageLength
* 4;
4970 ppage1_alloc
= (LANPage1_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page1_dma
);
4972 memset((u8
*)ppage1_alloc
, 0, data_sz
);
4973 cfg
.physAddr
= page1_dma
;
4974 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4976 if ((rc
= mpt_config(ioc
, &cfg
)) == 0) {
4978 copy_sz
= min_t(int, sizeof(LANPage1_t
), data_sz
);
4979 memcpy(&ioc
->lan_cnfg_page1
, ppage1_alloc
, copy_sz
);
4982 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage1_alloc
, page1_dma
);
4985 * Normalize endianness of structure data,
4986 * by byte-swapping all > 1 byte fields!
4994 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4996 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
4997 * @ioc: Pointer to MPT_ADAPTER structure
4998 * @persist_opcode: see below
5000 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
5001 * devices not currently present.
5002 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
5004 * NOTE: Don't use not this function during interrupt time.
5006 * Returns 0 for success, non-zero error
5009 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5011 mptbase_sas_persist_operation(MPT_ADAPTER
*ioc
, u8 persist_opcode
)
5013 SasIoUnitControlRequest_t
*sasIoUnitCntrReq
;
5014 SasIoUnitControlReply_t
*sasIoUnitCntrReply
;
5015 MPT_FRAME_HDR
*mf
= NULL
;
5016 MPIHeader_t
*mpi_hdr
;
5018 unsigned long timeleft
;
5020 mutex_lock(&ioc
->mptbase_cmds
.mutex
);
5022 /* init the internal cmd struct */
5023 memset(ioc
->mptbase_cmds
.reply
, 0 , MPT_DEFAULT_FRAME_SIZE
);
5024 INITIALIZE_MGMT_STATUS(ioc
->mptbase_cmds
.status
)
5026 /* insure garbage is not sent to fw */
5027 switch(persist_opcode
) {
5029 case MPI_SAS_OP_CLEAR_NOT_PRESENT
:
5030 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT
:
5038 printk(KERN_DEBUG
"%s: persist_opcode=%x\n",
5039 __func__
, persist_opcode
);
5041 /* Get a MF for this command.
5043 if ((mf
= mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
5044 printk(KERN_DEBUG
"%s: no msg frames!\n", __func__
);
5049 mpi_hdr
= (MPIHeader_t
*) mf
;
5050 sasIoUnitCntrReq
= (SasIoUnitControlRequest_t
*)mf
;
5051 memset(sasIoUnitCntrReq
,0,sizeof(SasIoUnitControlRequest_t
));
5052 sasIoUnitCntrReq
->Function
= MPI_FUNCTION_SAS_IO_UNIT_CONTROL
;
5053 sasIoUnitCntrReq
->MsgContext
= mpi_hdr
->MsgContext
;
5054 sasIoUnitCntrReq
->Operation
= persist_opcode
;
5056 mpt_put_msg_frame(mpt_base_index
, ioc
, mf
);
5057 timeleft
= wait_for_completion_timeout(&ioc
->mptbase_cmds
.done
, 10*HZ
);
5058 if (!(ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_COMMAND_GOOD
)) {
5060 printk(KERN_DEBUG
"%s: failed\n", __func__
);
5061 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_DID_IOCRESET
)
5064 printk(KERN_DEBUG
"%s: Issuing Reset from %s!!\n",
5065 ioc
->name
, __func__
);
5066 mpt_HardResetHandler(ioc
, CAN_SLEEP
);
5067 mpt_free_msg_frame(ioc
, mf
);
5072 if (!(ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_RF_VALID
)) {
5077 sasIoUnitCntrReply
=
5078 (SasIoUnitControlReply_t
*)ioc
->mptbase_cmds
.reply
;
5079 if (le16_to_cpu(sasIoUnitCntrReply
->IOCStatus
) != MPI_IOCSTATUS_SUCCESS
) {
5080 printk(KERN_DEBUG
"%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
5081 __func__
, sasIoUnitCntrReply
->IOCStatus
,
5082 sasIoUnitCntrReply
->IOCLogInfo
);
5083 printk(KERN_DEBUG
"%s: failed\n", __func__
);
5086 printk(KERN_DEBUG
"%s: success\n", __func__
);
5089 CLEAR_MGMT_STATUS(ioc
->mptbase_cmds
.status
)
5090 mutex_unlock(&ioc
->mptbase_cmds
.mutex
);
5094 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5097 mptbase_raid_process_event_data(MPT_ADAPTER
*ioc
,
5098 MpiEventDataRaid_t
* pRaidEventData
)
5107 volume
= pRaidEventData
->VolumeID
;
5108 reason
= pRaidEventData
->ReasonCode
;
5109 disk
= pRaidEventData
->PhysDiskNum
;
5110 status
= le32_to_cpu(pRaidEventData
->SettingsStatus
);
5111 flags
= (status
>> 0) & 0xff;
5112 state
= (status
>> 8) & 0xff;
5114 if (reason
== MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
) {
5118 if ((reason
>= MPI_EVENT_RAID_RC_PHYSDISK_CREATED
&&
5119 reason
<= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
) ||
5120 (reason
== MPI_EVENT_RAID_RC_SMART_DATA
)) {
5121 printk(MYIOC_s_INFO_FMT
"RAID STATUS CHANGE for PhysDisk %d id=%d\n",
5122 ioc
->name
, disk
, volume
);
5124 printk(MYIOC_s_INFO_FMT
"RAID STATUS CHANGE for VolumeID %d\n",
5129 case MPI_EVENT_RAID_RC_VOLUME_CREATED
:
5130 printk(MYIOC_s_INFO_FMT
" volume has been created\n",
5134 case MPI_EVENT_RAID_RC_VOLUME_DELETED
:
5136 printk(MYIOC_s_INFO_FMT
" volume has been deleted\n",
5140 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED
:
5141 printk(MYIOC_s_INFO_FMT
" volume settings have been changed\n",
5145 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED
:
5146 printk(MYIOC_s_INFO_FMT
" volume is now %s%s%s%s\n",
5148 state
== MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
5150 : state
== MPI_RAIDVOL0_STATUS_STATE_DEGRADED
5152 : state
== MPI_RAIDVOL0_STATUS_STATE_FAILED
5155 flags
& MPI_RAIDVOL0_STATUS_FLAG_ENABLED
5157 flags
& MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
5158 ? ", quiesced" : "",
5159 flags
& MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
5160 ? ", resync in progress" : "" );
5163 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED
:
5164 printk(MYIOC_s_INFO_FMT
" volume membership of PhysDisk %d has changed\n",
5168 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED
:
5169 printk(MYIOC_s_INFO_FMT
" PhysDisk has been created\n",
5173 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED
:
5174 printk(MYIOC_s_INFO_FMT
" PhysDisk has been deleted\n",
5178 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED
:
5179 printk(MYIOC_s_INFO_FMT
" PhysDisk settings have been changed\n",
5183 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
:
5184 printk(MYIOC_s_INFO_FMT
" PhysDisk is now %s%s%s\n",
5186 state
== MPI_PHYSDISK0_STATUS_ONLINE
5188 : state
== MPI_PHYSDISK0_STATUS_MISSING
5190 : state
== MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
5192 : state
== MPI_PHYSDISK0_STATUS_FAILED
5194 : state
== MPI_PHYSDISK0_STATUS_INITIALIZING
5196 : state
== MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
5197 ? "offline requested"
5198 : state
== MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
5199 ? "failed requested"
5200 : state
== MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
5203 flags
& MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
5204 ? ", out of sync" : "",
5205 flags
& MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
5206 ? ", quiesced" : "" );
5209 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
:
5210 printk(MYIOC_s_INFO_FMT
" Domain Validation needed for PhysDisk %d\n",
5214 case MPI_EVENT_RAID_RC_SMART_DATA
:
5215 printk(MYIOC_s_INFO_FMT
" SMART data received, ASC/ASCQ = %02xh/%02xh\n",
5216 ioc
->name
, pRaidEventData
->ASC
, pRaidEventData
->ASCQ
);
5219 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED
:
5220 printk(MYIOC_s_INFO_FMT
" replacement of PhysDisk %d has started\n",
5226 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5228 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
5229 * @ioc: Pointer to MPT_ADAPTER structure
5231 * Returns: 0 for success
5232 * -ENOMEM if no memory available
5233 * -EPERM if not allowed due to ISR context
5234 * -EAGAIN if no msg frames currently available
5235 * -EFAULT for non-successful reply or no reply (timeout)
5238 GetIoUnitPage2(MPT_ADAPTER
*ioc
)
5240 ConfigPageHeader_t hdr
;
5242 IOUnitPage2_t
*ppage_alloc
;
5243 dma_addr_t page_dma
;
5247 /* Get the page header */
5248 hdr
.PageVersion
= 0;
5251 hdr
.PageType
= MPI_CONFIG_PAGETYPE_IO_UNIT
;
5252 cfg
.cfghdr
.hdr
= &hdr
;
5254 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5259 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
5262 if (hdr
.PageLength
== 0)
5265 /* Read the config page */
5266 data_sz
= hdr
.PageLength
* 4;
5268 ppage_alloc
= (IOUnitPage2_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page_dma
);
5270 memset((u8
*)ppage_alloc
, 0, data_sz
);
5271 cfg
.physAddr
= page_dma
;
5272 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5274 /* If Good, save data */
5275 if ((rc
= mpt_config(ioc
, &cfg
)) == 0)
5276 ioc
->biosVersion
= le32_to_cpu(ppage_alloc
->BiosVersion
);
5278 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage_alloc
, page_dma
);
5284 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5286 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
5287 * @ioc: Pointer to a Adapter Strucutre
5288 * @portnum: IOC port number
5290 * Return: -EFAULT if read of config page header fails
5292 * If read of SCSI Port Page 0 fails,
5293 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5294 * Adapter settings: async, narrow
5296 * If read of SCSI Port Page 2 fails,
5297 * Adapter settings valid
5298 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5303 * CHECK - what type of locking mechanisms should be used????
5306 mpt_GetScsiPortSettings(MPT_ADAPTER
*ioc
, int portnum
)
5311 ConfigPageHeader_t header
;
5317 if (!ioc
->spi_data
.nvram
) {
5320 sz
= MPT_MAX_SCSI_DEVICES
* sizeof(int);
5321 mem
= kmalloc(sz
, GFP_ATOMIC
);
5325 ioc
->spi_data
.nvram
= (int *) mem
;
5327 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SCSI device NVRAM settings @ %p, sz=%d\n",
5328 ioc
->name
, ioc
->spi_data
.nvram
, sz
));
5331 /* Invalidate NVRAM information
5333 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
5334 ioc
->spi_data
.nvram
[ii
] = MPT_HOST_NVRAM_INVALID
;
5337 /* Read SPP0 header, allocate memory, then read page.
5339 header
.PageVersion
= 0;
5340 header
.PageLength
= 0;
5341 header
.PageNumber
= 0;
5342 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_PORT
;
5343 cfg
.cfghdr
.hdr
= &header
;
5345 cfg
.pageAddr
= portnum
;
5346 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5348 cfg
.timeout
= 0; /* use default */
5349 if (mpt_config(ioc
, &cfg
) != 0)
5352 if (header
.PageLength
> 0) {
5353 pbuf
= pci_alloc_consistent(ioc
->pcidev
, header
.PageLength
* 4, &buf_dma
);
5355 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5356 cfg
.physAddr
= buf_dma
;
5357 if (mpt_config(ioc
, &cfg
) != 0) {
5358 ioc
->spi_data
.maxBusWidth
= MPT_NARROW
;
5359 ioc
->spi_data
.maxSyncOffset
= 0;
5360 ioc
->spi_data
.minSyncFactor
= MPT_ASYNC
;
5361 ioc
->spi_data
.busType
= MPT_HOST_BUS_UNKNOWN
;
5363 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5364 "Unable to read PortPage0 minSyncFactor=%x\n",
5365 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
5367 /* Save the Port Page 0 data
5369 SCSIPortPage0_t
*pPP0
= (SCSIPortPage0_t
*) pbuf
;
5370 pPP0
->Capabilities
= le32_to_cpu(pPP0
->Capabilities
);
5371 pPP0
->PhysicalInterface
= le32_to_cpu(pPP0
->PhysicalInterface
);
5373 if ( (pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_QAS
) == 0 ) {
5374 ioc
->spi_data
.noQas
|= MPT_TARGET_NO_NEGO_QAS
;
5375 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5376 "noQas due to Capabilities=%x\n",
5377 ioc
->name
, pPP0
->Capabilities
));
5379 ioc
->spi_data
.maxBusWidth
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_WIDE
? 1 : 0;
5380 data
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK
;
5382 ioc
->spi_data
.maxSyncOffset
= (u8
) (data
>> 16);
5383 data
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK
;
5384 ioc
->spi_data
.minSyncFactor
= (u8
) (data
>> 8);
5385 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5386 "PortPage0 minSyncFactor=%x\n",
5387 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
5389 ioc
->spi_data
.maxSyncOffset
= 0;
5390 ioc
->spi_data
.minSyncFactor
= MPT_ASYNC
;
5393 ioc
->spi_data
.busType
= pPP0
->PhysicalInterface
& MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK
;
5395 /* Update the minSyncFactor based on bus type.
5397 if ((ioc
->spi_data
.busType
== MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD
) ||
5398 (ioc
->spi_data
.busType
== MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE
)) {
5400 if (ioc
->spi_data
.minSyncFactor
< MPT_ULTRA
) {
5401 ioc
->spi_data
.minSyncFactor
= MPT_ULTRA
;
5402 ddvprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
5403 "HVD or SE detected, minSyncFactor=%x\n",
5404 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
5409 pci_free_consistent(ioc
->pcidev
, header
.PageLength
* 4, pbuf
, buf_dma
);
5414 /* SCSI Port Page 2 - Read the header then the page.
5416 header
.PageVersion
= 0;
5417 header
.PageLength
= 0;
5418 header
.PageNumber
= 2;
5419 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_PORT
;
5420 cfg
.cfghdr
.hdr
= &header
;
5422 cfg
.pageAddr
= portnum
;
5423 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5425 if (mpt_config(ioc
, &cfg
) != 0)
5428 if (header
.PageLength
> 0) {
5429 /* Allocate memory and read SCSI Port Page 2
5431 pbuf
= pci_alloc_consistent(ioc
->pcidev
, header
.PageLength
* 4, &buf_dma
);
5433 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_NVRAM
;
5434 cfg
.physAddr
= buf_dma
;
5435 if (mpt_config(ioc
, &cfg
) != 0) {
5436 /* Nvram data is left with INVALID mark
5439 } else if (ioc
->pcidev
->vendor
== PCI_VENDOR_ID_ATTO
) {
5441 /* This is an ATTO adapter, read Page2 accordingly
5443 ATTO_SCSIPortPage2_t
*pPP2
= (ATTO_SCSIPortPage2_t
*) pbuf
;
5444 ATTODeviceInfo_t
*pdevice
= NULL
;
5447 /* Save the Port Page 2 data
5448 * (reformat into a 32bit quantity)
5450 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
5451 pdevice
= &pPP2
->DeviceSettings
[ii
];
5452 ATTOFlags
= le16_to_cpu(pdevice
->ATTOFlags
);
5455 /* Translate ATTO device flags to LSI format
5457 if (ATTOFlags
& ATTOFLAG_DISC
)
5458 data
|= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE
);
5459 if (ATTOFlags
& ATTOFLAG_ID_ENB
)
5460 data
|= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE
);
5461 if (ATTOFlags
& ATTOFLAG_LUN_ENB
)
5462 data
|= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE
);
5463 if (ATTOFlags
& ATTOFLAG_TAGGED
)
5464 data
|= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE
);
5465 if (!(ATTOFlags
& ATTOFLAG_WIDE_ENB
))
5466 data
|= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE
);
5468 data
= (data
<< 16) | (pdevice
->Period
<< 8) | 10;
5469 ioc
->spi_data
.nvram
[ii
] = data
;
5472 SCSIPortPage2_t
*pPP2
= (SCSIPortPage2_t
*) pbuf
;
5473 MpiDeviceInfo_t
*pdevice
= NULL
;
5476 * Save "Set to Avoid SCSI Bus Resets" flag
5478 ioc
->spi_data
.bus_reset
=
5479 (le32_to_cpu(pPP2
->PortFlags
) &
5480 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET
) ?
5483 /* Save the Port Page 2 data
5484 * (reformat into a 32bit quantity)
5486 data
= le32_to_cpu(pPP2
->PortFlags
) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK
;
5487 ioc
->spi_data
.PortFlags
= data
;
5488 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
5489 pdevice
= &pPP2
->DeviceSettings
[ii
];
5490 data
= (le16_to_cpu(pdevice
->DeviceFlags
) << 16) |
5491 (pdevice
->SyncFactor
<< 8) | pdevice
->Timeout
;
5492 ioc
->spi_data
.nvram
[ii
] = data
;
5496 pci_free_consistent(ioc
->pcidev
, header
.PageLength
* 4, pbuf
, buf_dma
);
5500 /* Update Adapter limits with those from NVRAM
5501 * Comment: Don't need to do this. Target performance
5502 * parameters will never exceed the adapters limits.
5508 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5510 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
5511 * @ioc: Pointer to a Adapter Strucutre
5512 * @portnum: IOC port number
5514 * Return: -EFAULT if read of config page header fails
5518 mpt_readScsiDevicePageHeaders(MPT_ADAPTER
*ioc
, int portnum
)
5521 ConfigPageHeader_t header
;
5523 /* Read the SCSI Device Page 1 header
5525 header
.PageVersion
= 0;
5526 header
.PageLength
= 0;
5527 header
.PageNumber
= 1;
5528 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_DEVICE
;
5529 cfg
.cfghdr
.hdr
= &header
;
5531 cfg
.pageAddr
= portnum
;
5532 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5535 if (mpt_config(ioc
, &cfg
) != 0)
5538 ioc
->spi_data
.sdp1version
= cfg
.cfghdr
.hdr
->PageVersion
;
5539 ioc
->spi_data
.sdp1length
= cfg
.cfghdr
.hdr
->PageLength
;
5541 header
.PageVersion
= 0;
5542 header
.PageLength
= 0;
5543 header
.PageNumber
= 0;
5544 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_DEVICE
;
5545 if (mpt_config(ioc
, &cfg
) != 0)
5548 ioc
->spi_data
.sdp0version
= cfg
.cfghdr
.hdr
->PageVersion
;
5549 ioc
->spi_data
.sdp0length
= cfg
.cfghdr
.hdr
->PageLength
;
5551 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Headers: 0: version %d length %d\n",
5552 ioc
->name
, ioc
->spi_data
.sdp0version
, ioc
->spi_data
.sdp0length
));
5554 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Headers: 1: version %d length %d\n",
5555 ioc
->name
, ioc
->spi_data
.sdp1version
, ioc
->spi_data
.sdp1length
));
5560 * mpt_inactive_raid_list_free - This clears this link list.
5561 * @ioc : pointer to per adapter structure
5564 mpt_inactive_raid_list_free(MPT_ADAPTER
*ioc
)
5566 struct inactive_raid_component_info
*component_info
, *pNext
;
5568 if (list_empty(&ioc
->raid_data
.inactive_list
))
5571 mutex_lock(&ioc
->raid_data
.inactive_list_mutex
);
5572 list_for_each_entry_safe(component_info
, pNext
,
5573 &ioc
->raid_data
.inactive_list
, list
) {
5574 list_del(&component_info
->list
);
5575 kfree(component_info
);
5577 mutex_unlock(&ioc
->raid_data
.inactive_list_mutex
);
5581 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5583 * @ioc : pointer to per adapter structure
5584 * @channel : volume channel
5585 * @id : volume target id
5588 mpt_inactive_raid_volumes(MPT_ADAPTER
*ioc
, u8 channel
, u8 id
)
5591 ConfigPageHeader_t hdr
;
5592 dma_addr_t dma_handle
;
5593 pRaidVolumePage0_t buffer
= NULL
;
5595 RaidPhysDiskPage0_t phys_disk
;
5596 struct inactive_raid_component_info
*component_info
;
5597 int handle_inactive_volumes
;
5599 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5600 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5601 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_VOLUME
;
5602 cfg
.pageAddr
= (channel
<< 8) + id
;
5603 cfg
.cfghdr
.hdr
= &hdr
;
5604 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5606 if (mpt_config(ioc
, &cfg
) != 0)
5609 if (!hdr
.PageLength
)
5612 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5618 cfg
.physAddr
= dma_handle
;
5619 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5621 if (mpt_config(ioc
, &cfg
) != 0)
5624 if (!buffer
->NumPhysDisks
)
5627 handle_inactive_volumes
=
5628 (buffer
->VolumeStatus
.Flags
& MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE
||
5629 (buffer
->VolumeStatus
.Flags
& MPI_RAIDVOL0_STATUS_FLAG_ENABLED
) == 0 ||
5630 buffer
->VolumeStatus
.State
== MPI_RAIDVOL0_STATUS_STATE_FAILED
||
5631 buffer
->VolumeStatus
.State
== MPI_RAIDVOL0_STATUS_STATE_MISSING
) ? 1 : 0;
5633 if (!handle_inactive_volumes
)
5636 mutex_lock(&ioc
->raid_data
.inactive_list_mutex
);
5637 for (i
= 0; i
< buffer
->NumPhysDisks
; i
++) {
5638 if(mpt_raid_phys_disk_pg0(ioc
,
5639 buffer
->PhysDisk
[i
].PhysDiskNum
, &phys_disk
) != 0)
5642 if ((component_info
= kmalloc(sizeof (*component_info
),
5643 GFP_KERNEL
)) == NULL
)
5646 component_info
->volumeID
= id
;
5647 component_info
->volumeBus
= channel
;
5648 component_info
->d
.PhysDiskNum
= phys_disk
.PhysDiskNum
;
5649 component_info
->d
.PhysDiskBus
= phys_disk
.PhysDiskBus
;
5650 component_info
->d
.PhysDiskID
= phys_disk
.PhysDiskID
;
5651 component_info
->d
.PhysDiskIOC
= phys_disk
.PhysDiskIOC
;
5653 list_add_tail(&component_info
->list
,
5654 &ioc
->raid_data
.inactive_list
);
5656 mutex_unlock(&ioc
->raid_data
.inactive_list_mutex
);
5660 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5665 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5666 * @ioc: Pointer to a Adapter Structure
5667 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5668 * @phys_disk: requested payload data returned
5672 * -EFAULT if read of config page header fails or data pointer not NULL
5673 * -ENOMEM if pci_alloc failed
5676 mpt_raid_phys_disk_pg0(MPT_ADAPTER
*ioc
, u8 phys_disk_num
,
5677 RaidPhysDiskPage0_t
*phys_disk
)
5680 ConfigPageHeader_t hdr
;
5681 dma_addr_t dma_handle
;
5682 pRaidPhysDiskPage0_t buffer
= NULL
;
5685 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5686 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5687 memset(phys_disk
, 0, sizeof(RaidPhysDiskPage0_t
));
5689 hdr
.PageVersion
= MPI_RAIDPHYSDISKPAGE0_PAGEVERSION
;
5690 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_PHYSDISK
;
5691 cfg
.cfghdr
.hdr
= &hdr
;
5693 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5695 if (mpt_config(ioc
, &cfg
) != 0) {
5700 if (!hdr
.PageLength
) {
5705 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5713 cfg
.physAddr
= dma_handle
;
5714 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5715 cfg
.pageAddr
= phys_disk_num
;
5717 if (mpt_config(ioc
, &cfg
) != 0) {
5723 memcpy(phys_disk
, buffer
, sizeof(*buffer
));
5724 phys_disk
->MaxLBA
= le32_to_cpu(buffer
->MaxLBA
);
5729 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5736 * mpt_raid_phys_disk_get_num_paths - returns number paths associated to this phys_num
5737 * @ioc: Pointer to a Adapter Structure
5738 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5741 * returns number paths
5744 mpt_raid_phys_disk_get_num_paths(MPT_ADAPTER
*ioc
, u8 phys_disk_num
)
5747 ConfigPageHeader_t hdr
;
5748 dma_addr_t dma_handle
;
5749 pRaidPhysDiskPage1_t buffer
= NULL
;
5752 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5753 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5755 hdr
.PageVersion
= MPI_RAIDPHYSDISKPAGE1_PAGEVERSION
;
5756 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_PHYSDISK
;
5758 cfg
.cfghdr
.hdr
= &hdr
;
5760 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5762 if (mpt_config(ioc
, &cfg
) != 0) {
5767 if (!hdr
.PageLength
) {
5772 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5780 cfg
.physAddr
= dma_handle
;
5781 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5782 cfg
.pageAddr
= phys_disk_num
;
5784 if (mpt_config(ioc
, &cfg
) != 0) {
5789 rc
= buffer
->NumPhysDiskPaths
;
5793 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5798 EXPORT_SYMBOL(mpt_raid_phys_disk_get_num_paths
);
5801 * mpt_raid_phys_disk_pg1 - returns phys disk page 1
5802 * @ioc: Pointer to a Adapter Structure
5803 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5804 * @phys_disk: requested payload data returned
5808 * -EFAULT if read of config page header fails or data pointer not NULL
5809 * -ENOMEM if pci_alloc failed
5812 mpt_raid_phys_disk_pg1(MPT_ADAPTER
*ioc
, u8 phys_disk_num
,
5813 RaidPhysDiskPage1_t
*phys_disk
)
5816 ConfigPageHeader_t hdr
;
5817 dma_addr_t dma_handle
;
5818 pRaidPhysDiskPage1_t buffer
= NULL
;
5823 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
5824 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
5827 hdr
.PageVersion
= MPI_RAIDPHYSDISKPAGE1_PAGEVERSION
;
5828 hdr
.PageType
= MPI_CONFIG_PAGETYPE_RAID_PHYSDISK
;
5830 cfg
.cfghdr
.hdr
= &hdr
;
5832 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5834 if (mpt_config(ioc
, &cfg
) != 0) {
5839 if (!hdr
.PageLength
) {
5844 buffer
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4,
5852 cfg
.physAddr
= dma_handle
;
5853 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5854 cfg
.pageAddr
= phys_disk_num
;
5856 if (mpt_config(ioc
, &cfg
) != 0) {
5861 phys_disk
->NumPhysDiskPaths
= buffer
->NumPhysDiskPaths
;
5862 phys_disk
->PhysDiskNum
= phys_disk_num
;
5863 for (i
= 0; i
< phys_disk
->NumPhysDiskPaths
; i
++) {
5864 phys_disk
->Path
[i
].PhysDiskID
= buffer
->Path
[i
].PhysDiskID
;
5865 phys_disk
->Path
[i
].PhysDiskBus
= buffer
->Path
[i
].PhysDiskBus
;
5866 phys_disk
->Path
[i
].OwnerIdentifier
=
5867 buffer
->Path
[i
].OwnerIdentifier
;
5868 phys_disk
->Path
[i
].Flags
= le16_to_cpu(buffer
->Path
[i
].Flags
);
5869 memcpy(&sas_address
, &buffer
->Path
[i
].WWID
, sizeof(__le64
));
5870 sas_address
= le64_to_cpu(sas_address
);
5871 memcpy(&phys_disk
->Path
[i
].WWID
, &sas_address
, sizeof(__le64
));
5872 memcpy(&sas_address
,
5873 &buffer
->Path
[i
].OwnerWWID
, sizeof(__le64
));
5874 sas_address
= le64_to_cpu(sas_address
);
5875 memcpy(&phys_disk
->Path
[i
].OwnerWWID
,
5876 &sas_address
, sizeof(__le64
));
5882 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, buffer
,
5887 EXPORT_SYMBOL(mpt_raid_phys_disk_pg1
);
5891 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5892 * @ioc: Pointer to a Adapter Strucutre
5896 * -EFAULT if read of config page header fails or data pointer not NULL
5897 * -ENOMEM if pci_alloc failed
5900 mpt_findImVolumes(MPT_ADAPTER
*ioc
)
5904 dma_addr_t ioc2_dma
;
5906 ConfigPageHeader_t header
;
5911 if (!ioc
->ir_firmware
)
5914 /* Free the old page
5916 kfree(ioc
->raid_data
.pIocPg2
);
5917 ioc
->raid_data
.pIocPg2
= NULL
;
5918 mpt_inactive_raid_list_free(ioc
);
5920 /* Read IOCP2 header then the page.
5922 header
.PageVersion
= 0;
5923 header
.PageLength
= 0;
5924 header
.PageNumber
= 2;
5925 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
5926 cfg
.cfghdr
.hdr
= &header
;
5929 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5932 if (mpt_config(ioc
, &cfg
) != 0)
5935 if (header
.PageLength
== 0)
5938 iocpage2sz
= header
.PageLength
* 4;
5939 pIoc2
= pci_alloc_consistent(ioc
->pcidev
, iocpage2sz
, &ioc2_dma
);
5943 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5944 cfg
.physAddr
= ioc2_dma
;
5945 if (mpt_config(ioc
, &cfg
) != 0)
5948 mem
= kmalloc(iocpage2sz
, GFP_KERNEL
);
5952 memcpy(mem
, (u8
*)pIoc2
, iocpage2sz
);
5953 ioc
->raid_data
.pIocPg2
= (IOCPage2_t
*) mem
;
5955 mpt_read_ioc_pg_3(ioc
);
5957 for (i
= 0; i
< pIoc2
->NumActiveVolumes
; i
++)
5958 mpt_inactive_raid_volumes(ioc
,
5959 pIoc2
->RaidVolume
[i
].VolumeBus
,
5960 pIoc2
->RaidVolume
[i
].VolumeID
);
5963 pci_free_consistent(ioc
->pcidev
, iocpage2sz
, pIoc2
, ioc2_dma
);
5969 mpt_read_ioc_pg_3(MPT_ADAPTER
*ioc
)
5974 ConfigPageHeader_t header
;
5975 dma_addr_t ioc3_dma
;
5978 /* Free the old page
5980 kfree(ioc
->raid_data
.pIocPg3
);
5981 ioc
->raid_data
.pIocPg3
= NULL
;
5983 /* There is at least one physical disk.
5984 * Read and save IOC Page 3
5986 header
.PageVersion
= 0;
5987 header
.PageLength
= 0;
5988 header
.PageNumber
= 3;
5989 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
5990 cfg
.cfghdr
.hdr
= &header
;
5993 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5996 if (mpt_config(ioc
, &cfg
) != 0)
5999 if (header
.PageLength
== 0)
6002 /* Read Header good, alloc memory
6004 iocpage3sz
= header
.PageLength
* 4;
6005 pIoc3
= pci_alloc_consistent(ioc
->pcidev
, iocpage3sz
, &ioc3_dma
);
6009 /* Read the Page and save the data
6010 * into malloc'd memory.
6012 cfg
.physAddr
= ioc3_dma
;
6013 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
6014 if (mpt_config(ioc
, &cfg
) == 0) {
6015 mem
= kmalloc(iocpage3sz
, GFP_KERNEL
);
6017 memcpy(mem
, (u8
*)pIoc3
, iocpage3sz
);
6018 ioc
->raid_data
.pIocPg3
= (IOCPage3_t
*) mem
;
6022 pci_free_consistent(ioc
->pcidev
, iocpage3sz
, pIoc3
, ioc3_dma
);
6028 mpt_read_ioc_pg_4(MPT_ADAPTER
*ioc
)
6032 ConfigPageHeader_t header
;
6033 dma_addr_t ioc4_dma
;
6036 /* Read and save IOC Page 4
6038 header
.PageVersion
= 0;
6039 header
.PageLength
= 0;
6040 header
.PageNumber
= 4;
6041 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
6042 cfg
.cfghdr
.hdr
= &header
;
6045 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
6048 if (mpt_config(ioc
, &cfg
) != 0)
6051 if (header
.PageLength
== 0)
6054 if ( (pIoc4
= ioc
->spi_data
.pIocPg4
) == NULL
) {
6055 iocpage4sz
= (header
.PageLength
+ 4) * 4; /* Allow 4 additional SEP's */
6056 pIoc4
= pci_alloc_consistent(ioc
->pcidev
, iocpage4sz
, &ioc4_dma
);
6059 ioc
->alloc_total
+= iocpage4sz
;
6061 ioc4_dma
= ioc
->spi_data
.IocPg4_dma
;
6062 iocpage4sz
= ioc
->spi_data
.IocPg4Sz
;
6065 /* Read the Page into dma memory.
6067 cfg
.physAddr
= ioc4_dma
;
6068 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
6069 if (mpt_config(ioc
, &cfg
) == 0) {
6070 ioc
->spi_data
.pIocPg4
= (IOCPage4_t
*) pIoc4
;
6071 ioc
->spi_data
.IocPg4_dma
= ioc4_dma
;
6072 ioc
->spi_data
.IocPg4Sz
= iocpage4sz
;
6074 pci_free_consistent(ioc
->pcidev
, iocpage4sz
, pIoc4
, ioc4_dma
);
6075 ioc
->spi_data
.pIocPg4
= NULL
;
6076 ioc
->alloc_total
-= iocpage4sz
;
6081 mpt_read_ioc_pg_1(MPT_ADAPTER
*ioc
)
6085 ConfigPageHeader_t header
;
6086 dma_addr_t ioc1_dma
;
6090 /* Check the Coalescing Timeout in IOC Page 1
6092 header
.PageVersion
= 0;
6093 header
.PageLength
= 0;
6094 header
.PageNumber
= 1;
6095 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
6096 cfg
.cfghdr
.hdr
= &header
;
6099 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
6102 if (mpt_config(ioc
, &cfg
) != 0)
6105 if (header
.PageLength
== 0)
6108 /* Read Header good, alloc memory
6110 iocpage1sz
= header
.PageLength
* 4;
6111 pIoc1
= pci_alloc_consistent(ioc
->pcidev
, iocpage1sz
, &ioc1_dma
);
6115 /* Read the Page and check coalescing timeout
6117 cfg
.physAddr
= ioc1_dma
;
6118 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
6119 if (mpt_config(ioc
, &cfg
) == 0) {
6121 tmp
= le32_to_cpu(pIoc1
->Flags
) & MPI_IOCPAGE1_REPLY_COALESCING
;
6122 if (tmp
== MPI_IOCPAGE1_REPLY_COALESCING
) {
6123 tmp
= le32_to_cpu(pIoc1
->CoalescingTimeout
);
6125 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Coalescing Enabled Timeout = %d\n",
6128 if (tmp
> MPT_COALESCING_TIMEOUT
) {
6129 pIoc1
->CoalescingTimeout
= cpu_to_le32(MPT_COALESCING_TIMEOUT
);
6131 /* Write NVRAM and current
6134 cfg
.action
= MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT
;
6135 if (mpt_config(ioc
, &cfg
) == 0) {
6136 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Reset Current Coalescing Timeout to = %d\n",
6137 ioc
->name
, MPT_COALESCING_TIMEOUT
));
6139 cfg
.action
= MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM
;
6140 if (mpt_config(ioc
, &cfg
) == 0) {
6141 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6142 "Reset NVRAM Coalescing Timeout to = %d\n",
6143 ioc
->name
, MPT_COALESCING_TIMEOUT
));
6145 dprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6146 "Reset NVRAM Coalescing Timeout Failed\n",
6151 dprintk(ioc
, printk(MYIOC_s_WARN_FMT
6152 "Reset of Current Coalescing Timeout Failed!\n",
6158 dprintk(ioc
, printk(MYIOC_s_WARN_FMT
"Coalescing Disabled\n", ioc
->name
));
6162 pci_free_consistent(ioc
->pcidev
, iocpage1sz
, pIoc1
, ioc1_dma
);
6168 mpt_get_manufacturing_pg_0(MPT_ADAPTER
*ioc
)
6171 ConfigPageHeader_t hdr
;
6173 ManufacturingPage0_t
*pbuf
= NULL
;
6175 memset(&cfg
, 0 , sizeof(CONFIGPARMS
));
6176 memset(&hdr
, 0 , sizeof(ConfigPageHeader_t
));
6178 hdr
.PageType
= MPI_CONFIG_PAGETYPE_MANUFACTURING
;
6179 cfg
.cfghdr
.hdr
= &hdr
;
6181 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
6184 if (mpt_config(ioc
, &cfg
) != 0)
6187 if (!cfg
.cfghdr
.hdr
->PageLength
)
6190 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
6191 pbuf
= pci_alloc_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, &buf_dma
);
6195 cfg
.physAddr
= buf_dma
;
6197 if (mpt_config(ioc
, &cfg
) != 0)
6200 memcpy(ioc
->board_name
, pbuf
->BoardName
, sizeof(ioc
->board_name
));
6201 memcpy(ioc
->board_assembly
, pbuf
->BoardAssembly
, sizeof(ioc
->board_assembly
));
6202 memcpy(ioc
->board_tracer
, pbuf
->BoardTracerNumber
, sizeof(ioc
->board_tracer
));
6207 pci_free_consistent(ioc
->pcidev
, hdr
.PageLength
* 4, pbuf
, buf_dma
);
6210 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6212 * SendEventNotification - Send EventNotification (on or off) request to adapter
6213 * @ioc: Pointer to MPT_ADAPTER structure
6214 * @EvSwitch: Event switch flags
6215 * @sleepFlag: Specifies whether the process can sleep
6218 SendEventNotification(MPT_ADAPTER
*ioc
, u8 EvSwitch
, int sleepFlag
)
6220 EventNotification_t evn
;
6221 MPIDefaultReply_t reply_buf
;
6223 memset(&evn
, 0, sizeof(EventNotification_t
));
6224 memset(&reply_buf
, 0, sizeof(MPIDefaultReply_t
));
6226 evn
.Function
= MPI_FUNCTION_EVENT_NOTIFICATION
;
6227 evn
.Switch
= EvSwitch
;
6228 evn
.MsgContext
= cpu_to_le32(mpt_base_index
<< 16);
6230 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6231 "Sending EventNotification (%d) request %p\n",
6232 ioc
->name
, EvSwitch
, &evn
));
6234 return mpt_handshake_req_reply_wait(ioc
, sizeof(EventNotification_t
),
6235 (u32
*)&evn
, sizeof(MPIDefaultReply_t
), (u16
*)&reply_buf
, 30,
6239 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6241 * SendEventAck - Send EventAck request to MPT adapter.
6242 * @ioc: Pointer to MPT_ADAPTER structure
6243 * @evnp: Pointer to original EventNotification request
6246 SendEventAck(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*evnp
)
6250 if ((pAck
= (EventAck_t
*) mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
6251 dfailprintk(ioc
, printk(MYIOC_s_WARN_FMT
"%s, no msg frames!!\n",
6252 ioc
->name
, __func__
));
6256 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"Sending EventAck\n", ioc
->name
));
6258 pAck
->Function
= MPI_FUNCTION_EVENT_ACK
;
6259 pAck
->ChainOffset
= 0;
6260 pAck
->Reserved
[0] = pAck
->Reserved
[1] = 0;
6262 pAck
->Reserved1
[0] = pAck
->Reserved1
[1] = pAck
->Reserved1
[2] = 0;
6263 pAck
->Event
= evnp
->Event
;
6264 pAck
->EventContext
= evnp
->EventContext
;
6266 mpt_put_msg_frame(mpt_base_index
, ioc
, (MPT_FRAME_HDR
*)pAck
);
6271 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6273 * mpt_config - Generic function to issue config message
6274 * @ioc: Pointer to an adapter structure
6275 * @pCfg: Pointer to a configuration structure. Struct contains
6276 * action, page address, direction, physical address
6277 * and pointer to a configuration page header
6278 * Page header is updated.
6280 * Returns 0 for success
6281 * -EPERM if not allowed due to ISR context
6282 * -EAGAIN if no msg frames currently available
6283 * -EFAULT for non-successful reply or no reply (timeout)
6286 mpt_config(MPT_ADAPTER
*ioc
, CONFIGPARMS
*pCfg
)
6289 ConfigReply_t
*pReply
;
6290 ConfigExtendedPageHeader_t
*pExtHdr
= NULL
;
6296 u8 page_type
= 0, extend_page
;
6297 unsigned long timeleft
;
6298 unsigned long flags
;
6300 u8 issue_hard_reset
= 0;
6303 /* Prevent calling wait_event() (below), if caller happens
6304 * to be in ISR context, because that is fatal!
6306 in_isr
= in_interrupt();
6308 dcprintk(ioc
, printk(MYIOC_s_WARN_FMT
"Config request not allowed in ISR context!\n",
6313 /* don't send a config page during diag reset */
6314 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
6315 if (ioc
->ioc_reset_in_progress
) {
6316 dfailprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6317 "%s: busy with host reset\n", ioc
->name
, __func__
));
6318 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6321 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6323 /* don't send if no chance of success */
6325 mpt_GetIocState(ioc
, 1) != MPI_IOC_STATE_OPERATIONAL
) {
6326 dfailprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6327 "%s: ioc not operational, %d, %xh\n",
6328 ioc
->name
, __func__
, ioc
->active
,
6329 mpt_GetIocState(ioc
, 0)));
6334 mutex_lock(&ioc
->mptbase_cmds
.mutex
);
6335 /* init the internal cmd struct */
6336 memset(ioc
->mptbase_cmds
.reply
, 0 , MPT_DEFAULT_FRAME_SIZE
);
6337 INITIALIZE_MGMT_STATUS(ioc
->mptbase_cmds
.status
)
6339 /* Get and Populate a free Frame
6341 if ((mf
= mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
6342 dcprintk(ioc
, printk(MYIOC_s_WARN_FMT
6343 "mpt_config: no msg frames!\n", ioc
->name
));
6348 pReq
= (Config_t
*)mf
;
6349 pReq
->Action
= pCfg
->action
;
6351 pReq
->ChainOffset
= 0;
6352 pReq
->Function
= MPI_FUNCTION_CONFIG
;
6354 /* Assume page type is not extended and clear "reserved" fields. */
6355 pReq
->ExtPageLength
= 0;
6356 pReq
->ExtPageType
= 0;
6359 for (ii
=0; ii
< 8; ii
++)
6360 pReq
->Reserved2
[ii
] = 0;
6362 pReq
->Header
.PageVersion
= pCfg
->cfghdr
.hdr
->PageVersion
;
6363 pReq
->Header
.PageLength
= pCfg
->cfghdr
.hdr
->PageLength
;
6364 pReq
->Header
.PageNumber
= pCfg
->cfghdr
.hdr
->PageNumber
;
6365 pReq
->Header
.PageType
= (pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
);
6367 if ((pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
) == MPI_CONFIG_PAGETYPE_EXTENDED
) {
6368 pExtHdr
= (ConfigExtendedPageHeader_t
*)pCfg
->cfghdr
.ehdr
;
6369 pReq
->ExtPageLength
= cpu_to_le16(pExtHdr
->ExtPageLength
);
6370 pReq
->ExtPageType
= pExtHdr
->ExtPageType
;
6371 pReq
->Header
.PageType
= MPI_CONFIG_PAGETYPE_EXTENDED
;
6373 /* Page Length must be treated as a reserved field for the
6376 pReq
->Header
.PageLength
= 0;
6379 pReq
->PageAddress
= cpu_to_le32(pCfg
->pageAddr
);
6381 /* Add a SGE to the config request.
6384 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_WRITE
;
6386 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_READ
;
6388 if ((pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
) ==
6389 MPI_CONFIG_PAGETYPE_EXTENDED
) {
6390 flagsLength
|= pExtHdr
->ExtPageLength
* 4;
6391 page_type
= pReq
->ExtPageType
;
6394 flagsLength
|= pCfg
->cfghdr
.hdr
->PageLength
* 4;
6395 page_type
= pReq
->Header
.PageType
;
6399 dcprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6400 "Sending Config request type 0x%x, page 0x%x and action %d\n",
6401 ioc
->name
, page_type
, pReq
->Header
.PageNumber
, pReq
->Action
));
6403 ioc
->add_sge((char *)&pReq
->PageBufferSGE
, flagsLength
, pCfg
->physAddr
);
6404 timeout
= (pCfg
->timeout
< 15) ? HZ
*15 : HZ
*pCfg
->timeout
;
6405 mpt_put_msg_frame(mpt_base_index
, ioc
, mf
);
6406 timeleft
= wait_for_completion_timeout(&ioc
->mptbase_cmds
.done
,
6408 if (!(ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_COMMAND_GOOD
)) {
6410 dfailprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6411 "Failed Sending Config request type 0x%x, page 0x%x,"
6412 " action %d, status %xh, time left %ld\n\n",
6413 ioc
->name
, page_type
, pReq
->Header
.PageNumber
,
6414 pReq
->Action
, ioc
->mptbase_cmds
.status
, timeleft
));
6415 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_DID_IOCRESET
)
6418 issue_hard_reset
= 1;
6422 if (!(ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_RF_VALID
)) {
6426 pReply
= (ConfigReply_t
*)ioc
->mptbase_cmds
.reply
;
6427 ret
= le16_to_cpu(pReply
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
6428 if (ret
== MPI_IOCSTATUS_SUCCESS
) {
6430 pCfg
->cfghdr
.ehdr
->ExtPageLength
=
6431 le16_to_cpu(pReply
->ExtPageLength
);
6432 pCfg
->cfghdr
.ehdr
->ExtPageType
=
6433 pReply
->ExtPageType
;
6435 pCfg
->cfghdr
.hdr
->PageVersion
= pReply
->Header
.PageVersion
;
6436 pCfg
->cfghdr
.hdr
->PageLength
= pReply
->Header
.PageLength
;
6437 pCfg
->cfghdr
.hdr
->PageNumber
= pReply
->Header
.PageNumber
;
6438 pCfg
->cfghdr
.hdr
->PageType
= pReply
->Header
.PageType
;
6443 printk(MYIOC_s_INFO_FMT
"Retry completed "
6444 "ret=0x%x timeleft=%ld\n",
6445 ioc
->name
, ret
, timeleft
);
6447 dcprintk(ioc
, printk(KERN_DEBUG
"IOCStatus=%04xh, IOCLogInfo=%08xh\n",
6448 ret
, le32_to_cpu(pReply
->IOCLogInfo
)));
6452 CLEAR_MGMT_STATUS(ioc
->mptbase_cmds
.status
)
6453 mutex_unlock(&ioc
->mptbase_cmds
.mutex
);
6454 if (issue_hard_reset
) {
6455 issue_hard_reset
= 0;
6456 printk(MYIOC_s_WARN_FMT
"Issuing Reset from %s!!\n",
6457 ioc
->name
, __func__
);
6458 mpt_HardResetHandler(ioc
, CAN_SLEEP
);
6459 mpt_free_msg_frame(ioc
, mf
);
6460 /* attempt one retry for a timed out command */
6462 printk(MYIOC_s_INFO_FMT
6463 "Attempting Retry Config request"
6464 " type 0x%x, page 0x%x,"
6465 " action %d\n", ioc
->name
, page_type
,
6466 pCfg
->cfghdr
.hdr
->PageNumber
, pCfg
->action
);
6475 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6477 * mpt_ioc_reset - Base cleanup for hard reset
6478 * @ioc: Pointer to the adapter structure
6479 * @reset_phase: Indicates pre- or post-reset functionality
6481 * Remark: Frees resources with internally generated commands.
6484 mpt_ioc_reset(MPT_ADAPTER
*ioc
, int reset_phase
)
6486 switch (reset_phase
) {
6487 case MPT_IOC_SETUP_RESET
:
6488 ioc
->taskmgmt_quiesce_io
= 1;
6489 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6490 "%s: MPT_IOC_SETUP_RESET\n", ioc
->name
, __func__
));
6492 case MPT_IOC_PRE_RESET
:
6493 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6494 "%s: MPT_IOC_PRE_RESET\n", ioc
->name
, __func__
));
6496 case MPT_IOC_POST_RESET
:
6497 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
6498 "%s: MPT_IOC_POST_RESET\n", ioc
->name
, __func__
));
6499 /* wake up mptbase_cmds */
6500 if (ioc
->mptbase_cmds
.status
& MPT_MGMT_STATUS_PENDING
) {
6501 ioc
->mptbase_cmds
.status
|=
6502 MPT_MGMT_STATUS_DID_IOCRESET
;
6503 complete(&ioc
->mptbase_cmds
.done
);
6505 /* wake up taskmgmt_cmds */
6506 if (ioc
->taskmgmt_cmds
.status
& MPT_MGMT_STATUS_PENDING
) {
6507 ioc
->taskmgmt_cmds
.status
|=
6508 MPT_MGMT_STATUS_DID_IOCRESET
;
6509 complete(&ioc
->taskmgmt_cmds
.done
);
6516 return 1; /* currently means nothing really */
6520 #ifdef CONFIG_PROC_FS /* { */
6521 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6523 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
6525 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6527 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
6529 * Returns 0 for success, non-zero for failure.
6532 procmpt_create(void)
6534 struct proc_dir_entry
*ent
;
6536 mpt_proc_root_dir
= proc_mkdir(MPT_PROCFS_MPTBASEDIR
, NULL
);
6537 if (mpt_proc_root_dir
== NULL
)
6540 ent
= create_proc_entry("summary", S_IFREG
|S_IRUGO
, mpt_proc_root_dir
);
6542 ent
->read_proc
= procmpt_summary_read
;
6544 ent
= create_proc_entry("version", S_IFREG
|S_IRUGO
, mpt_proc_root_dir
);
6546 ent
->read_proc
= procmpt_version_read
;
6551 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6553 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
6555 * Returns 0 for success, non-zero for failure.
6558 procmpt_destroy(void)
6560 remove_proc_entry("version", mpt_proc_root_dir
);
6561 remove_proc_entry("summary", mpt_proc_root_dir
);
6562 remove_proc_entry(MPT_PROCFS_MPTBASEDIR
, NULL
);
6565 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6567 * procmpt_summary_read - Handle read request of a summary file
6568 * @buf: Pointer to area to write information
6569 * @start: Pointer to start pointer
6570 * @offset: Offset to start writing
6571 * @request: Amount of read data requested
6572 * @eof: Pointer to EOF integer
6575 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
6576 * Returns number of characters written to process performing the read.
6579 procmpt_summary_read(char *buf
, char **start
, off_t offset
, int request
, int *eof
, void *data
)
6589 mpt_print_ioc_summary(ioc
, out
, &more
, 0, 1);
6593 list_for_each_entry(ioc
, &ioc_list
, list
) {
6596 mpt_print_ioc_summary(ioc
, out
, &more
, 0, 1);
6599 if ((out
-buf
) >= request
)
6606 MPT_PROC_READ_RETURN(buf
,start
,offset
,request
,eof
,len
);
6609 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6611 * procmpt_version_read - Handle read request from /proc/mpt/version.
6612 * @buf: Pointer to area to write information
6613 * @start: Pointer to start pointer
6614 * @offset: Offset to start writing
6615 * @request: Amount of read data requested
6616 * @eof: Pointer to EOF integer
6619 * Returns number of characters written to process performing the read.
6622 procmpt_version_read(char *buf
, char **start
, off_t offset
, int request
, int *eof
, void *data
)
6625 int scsi
, fc
, sas
, lan
, ctl
, targ
, dmp
;
6629 len
= sprintf(buf
, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON
);
6630 len
+= sprintf(buf
+len
, " Fusion MPT base driver\n");
6632 scsi
= fc
= sas
= lan
= ctl
= targ
= dmp
= 0;
6633 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
6635 if (MptCallbacks
[cb_idx
]) {
6636 switch (MptDriverClass
[cb_idx
]) {
6638 if (!scsi
++) drvname
= "SPI host";
6641 if (!fc
++) drvname
= "FC host";
6644 if (!sas
++) drvname
= "SAS host";
6647 if (!lan
++) drvname
= "LAN";
6650 if (!targ
++) drvname
= "SCSI target";
6653 if (!ctl
++) drvname
= "ioctl";
6658 len
+= sprintf(buf
+len
, " Fusion MPT %s driver\n", drvname
);
6662 MPT_PROC_READ_RETURN(buf
,start
,offset
,request
,eof
,len
);
6665 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6667 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
6668 * @buf: Pointer to area to write information
6669 * @start: Pointer to start pointer
6670 * @offset: Offset to start writing
6671 * @request: Amount of read data requested
6672 * @eof: Pointer to EOF integer
6675 * Returns number of characters written to process performing the read.
6678 procmpt_iocinfo_read(char *buf
, char **start
, off_t offset
, int request
, int *eof
, void *data
)
6680 MPT_ADAPTER
*ioc
= data
;
6686 mpt_get_fw_exp_ver(expVer
, ioc
);
6688 len
= sprintf(buf
, "%s:", ioc
->name
);
6689 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)
6690 len
+= sprintf(buf
+len
, " (f/w download boot flag set)");
6691 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6692 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
6694 len
+= sprintf(buf
+len
, "\n ProductID = 0x%04x (%s)\n",
6695 ioc
->facts
.ProductID
,
6697 len
+= sprintf(buf
+len
, " FWVersion = 0x%08x%s", ioc
->facts
.FWVersion
.Word
, expVer
);
6698 if (ioc
->facts
.FWImageSize
)
6699 len
+= sprintf(buf
+len
, " (fw_size=%d)", ioc
->facts
.FWImageSize
);
6700 len
+= sprintf(buf
+len
, "\n MsgVersion = 0x%04x\n", ioc
->facts
.MsgVersion
);
6701 len
+= sprintf(buf
+len
, " FirstWhoInit = 0x%02x\n", ioc
->FirstWhoInit
);
6702 len
+= sprintf(buf
+len
, " EventState = 0x%02x\n", ioc
->facts
.EventState
);
6704 len
+= sprintf(buf
+len
, " CurrentHostMfaHighAddr = 0x%08x\n",
6705 ioc
->facts
.CurrentHostMfaHighAddr
);
6706 len
+= sprintf(buf
+len
, " CurrentSenseBufferHighAddr = 0x%08x\n",
6707 ioc
->facts
.CurrentSenseBufferHighAddr
);
6709 len
+= sprintf(buf
+len
, " MaxChainDepth = 0x%02x frames\n", ioc
->facts
.MaxChainDepth
);
6710 len
+= sprintf(buf
+len
, " MinBlockSize = 0x%02x bytes\n", 4*ioc
->facts
.BlockSize
);
6712 len
+= sprintf(buf
+len
, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6713 (void *)ioc
->req_frames
, (void *)(ulong
)ioc
->req_frames_dma
);
6715 * Rounding UP to nearest 4-kB boundary here...
6717 sz
= (ioc
->req_sz
* ioc
->req_depth
) + 128;
6718 sz
= ((sz
+ 0x1000UL
- 1UL) / 0x1000) * 0x1000;
6719 len
+= sprintf(buf
+len
, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6720 ioc
->req_sz
, ioc
->req_depth
, ioc
->req_sz
*ioc
->req_depth
, sz
);
6721 len
+= sprintf(buf
+len
, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
6722 4*ioc
->facts
.RequestFrameSize
,
6723 ioc
->facts
.GlobalCredits
);
6725 len
+= sprintf(buf
+len
, " Frames @ 0x%p (Dma @ 0x%p)\n",
6726 (void *)ioc
->alloc
, (void *)(ulong
)ioc
->alloc_dma
);
6727 sz
= (ioc
->reply_sz
* ioc
->reply_depth
) + 128;
6728 len
+= sprintf(buf
+len
, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6729 ioc
->reply_sz
, ioc
->reply_depth
, ioc
->reply_sz
*ioc
->reply_depth
, sz
);
6730 len
+= sprintf(buf
+len
, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
6731 ioc
->facts
.CurReplyFrameSize
,
6732 ioc
->facts
.ReplyQueueDepth
);
6734 len
+= sprintf(buf
+len
, " MaxDevices = %d\n",
6735 (ioc
->facts
.MaxDevices
==0) ? 255 : ioc
->facts
.MaxDevices
);
6736 len
+= sprintf(buf
+len
, " MaxBuses = %d\n", ioc
->facts
.MaxBuses
);
6739 for (p
=0; p
< ioc
->facts
.NumberOfPorts
; p
++) {
6740 len
+= sprintf(buf
+len
, " PortNumber = %d (of %d)\n",
6742 ioc
->facts
.NumberOfPorts
);
6743 if (ioc
->bus_type
== FC
) {
6744 if (ioc
->pfacts
[p
].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
) {
6745 u8
*a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
6746 len
+= sprintf(buf
+len
, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6747 a
[5], a
[4], a
[3], a
[2], a
[1], a
[0]);
6749 len
+= sprintf(buf
+len
, " WWN = %08X%08X:%08X%08X\n",
6750 ioc
->fc_port_page0
[p
].WWNN
.High
,
6751 ioc
->fc_port_page0
[p
].WWNN
.Low
,
6752 ioc
->fc_port_page0
[p
].WWPN
.High
,
6753 ioc
->fc_port_page0
[p
].WWPN
.Low
);
6757 MPT_PROC_READ_RETURN(buf
,start
,offset
,request
,eof
,len
);
6760 #endif /* CONFIG_PROC_FS } */
6762 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6764 mpt_get_fw_exp_ver(char *buf
, MPT_ADAPTER
*ioc
)
6767 if ((ioc
->facts
.FWVersion
.Word
>> 24) == 0x0E) {
6768 sprintf(buf
, " (Exp %02d%02d)",
6769 (ioc
->facts
.FWVersion
.Word
>> 16) & 0x00FF, /* Month */
6770 (ioc
->facts
.FWVersion
.Word
>> 8) & 0x1F); /* Day */
6773 if ((ioc
->facts
.FWVersion
.Word
>> 8) & 0x80)
6774 strcat(buf
, " [MDBG]");
6778 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6780 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6781 * @ioc: Pointer to MPT_ADAPTER structure
6782 * @buffer: Pointer to buffer where IOC summary info should be written
6783 * @size: Pointer to number of bytes we wrote (set by this routine)
6784 * @len: Offset at which to start writing in buffer
6785 * @showlan: Display LAN stuff?
6787 * This routine writes (english readable) ASCII text, which represents
6788 * a summary of IOC information, to a buffer.
6791 mpt_print_ioc_summary(MPT_ADAPTER
*ioc
, char *buffer
, int *size
, int len
, int showlan
)
6796 mpt_get_fw_exp_ver(expVer
, ioc
);
6799 * Shorter summary of attached ioc's...
6801 y
= sprintf(buffer
+len
, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6804 MPT_FW_REV_MAGIC_ID_STRING
, /* "FwRev=" or somesuch */
6805 ioc
->facts
.FWVersion
.Word
,
6807 ioc
->facts
.NumberOfPorts
,
6810 if (showlan
&& (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
)) {
6811 u8
*a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
6812 y
+= sprintf(buffer
+len
+y
, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6813 a
[5], a
[4], a
[3], a
[2], a
[1], a
[0]);
6816 y
+= sprintf(buffer
+len
+y
, ", IRQ=%d", ioc
->pci_irq
);
6819 y
+= sprintf(buffer
+len
+y
, " (disabled)");
6821 y
+= sprintf(buffer
+len
+y
, "\n");
6826 * mpt_set_taskmgmt_in_progress_flag - set flags associated with task management
6827 * @ioc: Pointer to MPT_ADAPTER structure
6829 * Returns 0 for SUCCESS or -1 if FAILED.
6831 * If -1 is return, then it was not possible to set the flags
6834 mpt_set_taskmgmt_in_progress_flag(MPT_ADAPTER
*ioc
)
6836 unsigned long flags
;
6839 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
6840 if (ioc
->ioc_reset_in_progress
|| ioc
->taskmgmt_in_progress
||
6841 (ioc
->alt_ioc
&& ioc
->alt_ioc
->taskmgmt_in_progress
)) {
6846 ioc
->taskmgmt_in_progress
= 1;
6847 ioc
->taskmgmt_quiesce_io
= 1;
6849 ioc
->alt_ioc
->taskmgmt_in_progress
= 1;
6850 ioc
->alt_ioc
->taskmgmt_quiesce_io
= 1;
6853 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6856 EXPORT_SYMBOL(mpt_set_taskmgmt_in_progress_flag
);
6859 * mpt_clear_taskmgmt_in_progress_flag - clear flags associated with task management
6860 * @ioc: Pointer to MPT_ADAPTER structure
6864 mpt_clear_taskmgmt_in_progress_flag(MPT_ADAPTER
*ioc
)
6866 unsigned long flags
;
6868 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
6869 ioc
->taskmgmt_in_progress
= 0;
6870 ioc
->taskmgmt_quiesce_io
= 0;
6872 ioc
->alt_ioc
->taskmgmt_in_progress
= 0;
6873 ioc
->alt_ioc
->taskmgmt_quiesce_io
= 0;
6875 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6877 EXPORT_SYMBOL(mpt_clear_taskmgmt_in_progress_flag
);
6881 * mpt_halt_firmware - Halts the firmware if it is operational and panic
6883 * @ioc: Pointer to MPT_ADAPTER structure
6887 mpt_halt_firmware(MPT_ADAPTER
*ioc
)
6891 ioc_raw_state
= mpt_GetIocState(ioc
, 0);
6893 if ((ioc_raw_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_FAULT
) {
6894 printk(MYIOC_s_ERR_FMT
"IOC is in FAULT state (%04xh)!!!\n",
6895 ioc
->name
, ioc_raw_state
& MPI_DOORBELL_DATA_MASK
);
6896 panic("%s: IOC Fault (%04xh)!!!\n", ioc
->name
,
6897 ioc_raw_state
& MPI_DOORBELL_DATA_MASK
);
6899 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, 0xC0FFEE00);
6900 panic("%s: Firmware is halted due to command timeout\n",
6904 EXPORT_SYMBOL(mpt_halt_firmware
);
6906 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6910 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6912 * mpt_HardResetHandler - Generic reset handler
6913 * @ioc: Pointer to MPT_ADAPTER structure
6914 * @sleepFlag: Indicates if sleep or schedule must be called.
6916 * Issues SCSI Task Management call based on input arg values.
6917 * If TaskMgmt fails, returns associated SCSI request.
6919 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
6920 * or a non-interrupt thread. In the former, must not call schedule().
6922 * Note: A return of -1 is a FATAL error case, as it means a
6923 * FW reload/initialization failed.
6925 * Returns 0 for SUCCESS or -1 if FAILED.
6928 mpt_HardResetHandler(MPT_ADAPTER
*ioc
, int sleepFlag
)
6932 unsigned long flags
;
6933 unsigned long time_count
;
6935 dtmprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"HardResetHandler Entered!\n", ioc
->name
));
6937 printk(MYIOC_s_INFO_FMT
"HardResetHandler Entered!\n", ioc
->name
);
6938 printk("MF count 0x%x !\n", ioc
->mfcnt
);
6940 if (mpt_fwfault_debug
)
6941 mpt_halt_firmware(ioc
);
6943 /* Reset the adapter. Prevent more than 1 call to
6944 * mpt_do_ioc_recovery at any instant in time.
6946 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
6947 if (ioc
->ioc_reset_in_progress
) {
6948 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6951 ioc
->ioc_reset_in_progress
= 1;
6953 ioc
->alt_ioc
->ioc_reset_in_progress
= 1;
6954 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6957 /* The SCSI driver needs to adjust timeouts on all current
6958 * commands prior to the diagnostic reset being issued.
6959 * Prevents timeouts occurring during a diagnostic reset...very bad.
6960 * For all other protocol drivers, this is a no-op.
6962 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
6963 if (MptResetHandlers
[cb_idx
]) {
6964 mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_SETUP_RESET
);
6966 mpt_signal_reset(cb_idx
, ioc
->alt_ioc
,
6967 MPT_IOC_SETUP_RESET
);
6971 time_count
= jiffies
;
6972 rc
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_RECOVER
, sleepFlag
);
6974 printk(KERN_WARNING MYNAM
6975 ": WARNING - (%d) Cannot recover %s\n", rc
, ioc
->name
);
6977 if (ioc
->hard_resets
< -1)
6981 spin_lock_irqsave(&ioc
->taskmgmt_lock
, flags
);
6982 ioc
->ioc_reset_in_progress
= 0;
6983 ioc
->taskmgmt_quiesce_io
= 0;
6984 ioc
->taskmgmt_in_progress
= 0;
6986 ioc
->alt_ioc
->ioc_reset_in_progress
= 0;
6987 ioc
->alt_ioc
->taskmgmt_quiesce_io
= 0;
6988 ioc
->alt_ioc
->taskmgmt_in_progress
= 0;
6990 spin_unlock_irqrestore(&ioc
->taskmgmt_lock
, flags
);
6992 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
6993 if (MptResetHandlers
[cb_idx
]) {
6994 mpt_signal_reset(cb_idx
, ioc
, MPT_IOC_POST_RESET
);
6996 mpt_signal_reset(cb_idx
,
6997 ioc
->alt_ioc
, MPT_IOC_POST_RESET
);
7002 printk(MYIOC_s_DEBUG_FMT
7003 "HardResetHandler: completed (%d seconds): %s\n", ioc
->name
,
7004 jiffies_to_msecs(jiffies
- time_count
)/1000, ((rc
== 0) ?
7005 "SUCCESS" : "FAILED")));
7010 #ifdef CONFIG_FUSION_LOGGING
7012 mpt_display_event_info(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*pEventReply
)
7018 char *evStr
= ioc
->evStr
;
7020 event
= le32_to_cpu(pEventReply
->Event
) & 0xFF;
7021 evData0
= le32_to_cpu(pEventReply
->Data
[0]);
7024 case MPI_EVENT_NONE
:
7027 case MPI_EVENT_LOG_DATA
:
7030 case MPI_EVENT_STATE_CHANGE
:
7031 ds
= "State Change";
7033 case MPI_EVENT_UNIT_ATTENTION
:
7034 ds
= "Unit Attention";
7036 case MPI_EVENT_IOC_BUS_RESET
:
7037 ds
= "IOC Bus Reset";
7039 case MPI_EVENT_EXT_BUS_RESET
:
7040 ds
= "External Bus Reset";
7042 case MPI_EVENT_RESCAN
:
7043 ds
= "Bus Rescan Event";
7045 case MPI_EVENT_LINK_STATUS_CHANGE
:
7046 if (evData0
== MPI_EVENT_LINK_STATUS_FAILURE
)
7047 ds
= "Link Status(FAILURE) Change";
7049 ds
= "Link Status(ACTIVE) Change";
7051 case MPI_EVENT_LOOP_STATE_CHANGE
:
7052 if (evData0
== MPI_EVENT_LOOP_STATE_CHANGE_LIP
)
7053 ds
= "Loop State(LIP) Change";
7054 else if (evData0
== MPI_EVENT_LOOP_STATE_CHANGE_LPE
)
7055 ds
= "Loop State(LPE) Change";
7057 ds
= "Loop State(LPB) Change";
7059 case MPI_EVENT_LOGOUT
:
7062 case MPI_EVENT_EVENT_CHANGE
:
7068 case MPI_EVENT_INTEGRATED_RAID
:
7070 u8 ReasonCode
= (u8
)(evData0
>> 16);
7071 switch (ReasonCode
) {
7072 case MPI_EVENT_RAID_RC_VOLUME_CREATED
:
7073 ds
= "Integrated Raid: Volume Created";
7075 case MPI_EVENT_RAID_RC_VOLUME_DELETED
:
7076 ds
= "Integrated Raid: Volume Deleted";
7078 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED
:
7079 ds
= "Integrated Raid: Volume Settings Changed";
7081 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED
:
7082 ds
= "Integrated Raid: Volume Status Changed";
7084 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED
:
7085 ds
= "Integrated Raid: Volume Physdisk Changed";
7087 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED
:
7088 ds
= "Integrated Raid: Physdisk Created";
7090 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED
:
7091 ds
= "Integrated Raid: Physdisk Deleted";
7093 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED
:
7094 ds
= "Integrated Raid: Physdisk Settings Changed";
7096 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
:
7097 ds
= "Integrated Raid: Physdisk Status Changed";
7099 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
:
7100 ds
= "Integrated Raid: Domain Validation Needed";
7102 case MPI_EVENT_RAID_RC_SMART_DATA
:
7103 ds
= "Integrated Raid; Smart Data";
7105 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED
:
7106 ds
= "Integrated Raid: Replace Action Started";
7109 ds
= "Integrated Raid";
7114 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE
:
7115 ds
= "SCSI Device Status Change";
7117 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE
:
7119 u8 id
= (u8
)(evData0
);
7120 u8 channel
= (u8
)(evData0
>> 8);
7121 u8 ReasonCode
= (u8
)(evData0
>> 16);
7122 switch (ReasonCode
) {
7123 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED
:
7124 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7125 "SAS Device Status Change: Added: "
7126 "id=%d channel=%d", id
, channel
);
7128 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING
:
7129 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7130 "SAS Device Status Change: Deleted: "
7131 "id=%d channel=%d", id
, channel
);
7133 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA
:
7134 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7135 "SAS Device Status Change: SMART Data: "
7136 "id=%d channel=%d", id
, channel
);
7138 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED
:
7139 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7140 "SAS Device Status Change: No Persistancy: "
7141 "id=%d channel=%d", id
, channel
);
7143 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED
:
7144 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7145 "SAS Device Status Change: Unsupported Device "
7146 "Discovered : id=%d channel=%d", id
, channel
);
7148 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET
:
7149 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7150 "SAS Device Status Change: Internal Device "
7151 "Reset : id=%d channel=%d", id
, channel
);
7153 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL
:
7154 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7155 "SAS Device Status Change: Internal Task "
7156 "Abort : id=%d channel=%d", id
, channel
);
7158 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL
:
7159 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7160 "SAS Device Status Change: Internal Abort "
7161 "Task Set : id=%d channel=%d", id
, channel
);
7163 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL
:
7164 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7165 "SAS Device Status Change: Internal Clear "
7166 "Task Set : id=%d channel=%d", id
, channel
);
7168 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL
:
7169 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7170 "SAS Device Status Change: Internal Query "
7171 "Task : id=%d channel=%d", id
, channel
);
7174 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7175 "SAS Device Status Change: Unknown: "
7176 "id=%d channel=%d", id
, channel
);
7181 case MPI_EVENT_ON_BUS_TIMER_EXPIRED
:
7182 ds
= "Bus Timer Expired";
7184 case MPI_EVENT_QUEUE_FULL
:
7186 u16 curr_depth
= (u16
)(evData0
>> 16);
7187 u8 channel
= (u8
)(evData0
>> 8);
7188 u8 id
= (u8
)(evData0
);
7190 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7191 "Queue Full: channel=%d id=%d depth=%d",
7192 channel
, id
, curr_depth
);
7195 case MPI_EVENT_SAS_SES
:
7196 ds
= "SAS SES Event";
7198 case MPI_EVENT_PERSISTENT_TABLE_FULL
:
7199 ds
= "Persistent Table Full";
7201 case MPI_EVENT_SAS_PHY_LINK_STATUS
:
7203 u8 LinkRates
= (u8
)(evData0
>> 8);
7204 u8 PhyNumber
= (u8
)(evData0
);
7205 LinkRates
= (LinkRates
& MPI_EVENT_SAS_PLS_LR_CURRENT_MASK
) >>
7206 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT
;
7207 switch (LinkRates
) {
7208 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN
:
7209 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7210 "SAS PHY Link Status: Phy=%d:"
7211 " Rate Unknown",PhyNumber
);
7213 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED
:
7214 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7215 "SAS PHY Link Status: Phy=%d:"
7216 " Phy Disabled",PhyNumber
);
7218 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION
:
7219 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7220 "SAS PHY Link Status: Phy=%d:"
7221 " Failed Speed Nego",PhyNumber
);
7223 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE
:
7224 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7225 "SAS PHY Link Status: Phy=%d:"
7226 " Sata OOB Completed",PhyNumber
);
7228 case MPI_EVENT_SAS_PLS_LR_RATE_1_5
:
7229 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7230 "SAS PHY Link Status: Phy=%d:"
7231 " Rate 1.5 Gbps",PhyNumber
);
7233 case MPI_EVENT_SAS_PLS_LR_RATE_3_0
:
7234 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7235 "SAS PHY Link Status: Phy=%d:"
7236 " Rate 3.0 Gpbs",PhyNumber
);
7239 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7240 "SAS PHY Link Status: Phy=%d", PhyNumber
);
7245 case MPI_EVENT_SAS_DISCOVERY_ERROR
:
7246 ds
= "SAS Discovery Error";
7248 case MPI_EVENT_IR_RESYNC_UPDATE
:
7250 u8 resync_complete
= (u8
)(evData0
>> 16);
7251 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7252 "IR Resync Update: Complete = %d:",resync_complete
);
7257 u8 id
= (u8
)(evData0
);
7258 u8 channel
= (u8
)(evData0
>> 8);
7259 u8 phys_num
= (u8
)(evData0
>> 24);
7260 u8 ReasonCode
= (u8
)(evData0
>> 16);
7262 switch (ReasonCode
) {
7263 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED
:
7264 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7265 "IR2: LD State Changed: "
7266 "id=%d channel=%d phys_num=%d",
7267 id
, channel
, phys_num
);
7269 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED
:
7270 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7271 "IR2: PD State Changed "
7272 "id=%d channel=%d phys_num=%d",
7273 id
, channel
, phys_num
);
7275 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL
:
7276 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7277 "IR2: Bad Block Table Full: "
7278 "id=%d channel=%d phys_num=%d",
7279 id
, channel
, phys_num
);
7281 case MPI_EVENT_IR2_RC_PD_INSERTED
:
7282 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7283 "IR2: PD Inserted: "
7284 "id=%d channel=%d phys_num=%d",
7285 id
, channel
, phys_num
);
7287 case MPI_EVENT_IR2_RC_PD_REMOVED
:
7288 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7290 "id=%d channel=%d phys_num=%d",
7291 id
, channel
, phys_num
);
7293 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED
:
7294 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7295 "IR2: Foreign CFG Detected: "
7296 "id=%d channel=%d phys_num=%d",
7297 id
, channel
, phys_num
);
7299 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR
:
7300 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7301 "IR2: Rebuild Medium Error: "
7302 "id=%d channel=%d phys_num=%d",
7303 id
, channel
, phys_num
);
7305 case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED
:
7306 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7307 "IR2: Dual Port Added: "
7308 "id=%d channel=%d phys_num=%d",
7309 id
, channel
, phys_num
);
7311 case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED
:
7312 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7313 "IR2: Dual Port Removed: "
7314 "id=%d channel=%d phys_num=%d",
7315 id
, channel
, phys_num
);
7323 case MPI_EVENT_SAS_DISCOVERY
:
7326 ds
= "SAS Discovery: Start";
7328 ds
= "SAS Discovery: Stop";
7331 case MPI_EVENT_LOG_ENTRY_ADDED
:
7332 ds
= "SAS Log Entry Added";
7335 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE
:
7337 u8 phy_num
= (u8
)(evData0
);
7338 u8 port_num
= (u8
)(evData0
>> 8);
7339 u8 port_width
= (u8
)(evData0
>> 16);
7340 u8 primative
= (u8
)(evData0
>> 24);
7341 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7342 "SAS Broadcase Primative: phy=%d port=%d "
7343 "width=%d primative=0x%02x",
7344 phy_num
, port_num
, port_width
, primative
);
7348 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE
:
7350 u8 reason
= (u8
)(evData0
);
7353 case MPI_EVENT_SAS_INIT_RC_ADDED
:
7354 ds
= "SAS Initiator Status Change: Added";
7356 case MPI_EVENT_SAS_INIT_RC_REMOVED
:
7357 ds
= "SAS Initiator Status Change: Deleted";
7360 ds
= "SAS Initiator Status Change";
7366 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW
:
7368 u8 max_init
= (u8
)(evData0
);
7369 u8 current_init
= (u8
)(evData0
>> 8);
7371 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7372 "SAS Initiator Device Table Overflow: max initiators=%02d "
7373 "current initators=%02d",
7374 max_init
, current_init
);
7377 case MPI_EVENT_SAS_SMP_ERROR
:
7379 u8 status
= (u8
)(evData0
);
7380 u8 port_num
= (u8
)(evData0
>> 8);
7381 u8 result
= (u8
)(evData0
>> 16);
7383 if (status
== MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID
)
7384 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7385 "SAS SMP Error: port=%d result=0x%02x",
7387 else if (status
== MPI_EVENT_SAS_SMP_CRC_ERROR
)
7388 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7389 "SAS SMP Error: port=%d : CRC Error",
7391 else if (status
== MPI_EVENT_SAS_SMP_TIMEOUT
)
7392 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7393 "SAS SMP Error: port=%d : Timeout",
7395 else if (status
== MPI_EVENT_SAS_SMP_NO_DESTINATION
)
7396 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7397 "SAS SMP Error: port=%d : No Destination",
7399 else if (status
== MPI_EVENT_SAS_SMP_BAD_DESTINATION
)
7400 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7401 "SAS SMP Error: port=%d : Bad Destination",
7404 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
7405 "SAS SMP Error: port=%d : status=0x%02x",
7410 case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE
:
7412 u8 reason
= (u8
)(evData0
);
7415 case MPI_EVENT_SAS_EXP_RC_ADDED
:
7416 ds
= "Expander Status Change: Added";
7418 case MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING
:
7419 ds
= "Expander Status Change: Deleted";
7422 ds
= "Expander Status Change";
7429 * MPT base "custom" events may be added here...
7436 strncpy(evStr
, ds
, EVENT_DESCR_STR_SZ
);
7439 devtprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
7440 "MPT event:(%02Xh) : %s\n",
7441 ioc
->name
, event
, evStr
));
7443 devtverboseprintk(ioc
, printk(KERN_DEBUG MYNAM
7444 ": Event data:\n"));
7445 for (ii
= 0; ii
< le16_to_cpu(pEventReply
->EventDataLength
); ii
++)
7446 devtverboseprintk(ioc
, printk(" %08x",
7447 le32_to_cpu(pEventReply
->Data
[ii
])));
7448 devtverboseprintk(ioc
, printk(KERN_DEBUG
"\n"));
7451 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7453 * ProcessEventNotification - Route EventNotificationReply to all event handlers
7454 * @ioc: Pointer to MPT_ADAPTER structure
7455 * @pEventReply: Pointer to EventNotification reply frame
7456 * @evHandlers: Pointer to integer, number of event handlers
7458 * Routes a received EventNotificationReply to all currently registered
7460 * Returns sum of event handlers return values.
7463 ProcessEventNotification(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*pEventReply
, int *evHandlers
)
7474 * Do platform normalization of values
7476 event
= le32_to_cpu(pEventReply
->Event
) & 0xFF;
7477 evDataLen
= le16_to_cpu(pEventReply
->EventDataLength
);
7479 evData0
= le32_to_cpu(pEventReply
->Data
[0]);
7482 #ifdef CONFIG_FUSION_LOGGING
7484 mpt_display_event_info(ioc
, pEventReply
);
7488 * Do general / base driver event processing
7491 case MPI_EVENT_EVENT_CHANGE
: /* 0A */
7493 u8 evState
= evData0
& 0xFF;
7495 /* CHECKME! What if evState unexpectedly says OFF (0)? */
7497 /* Update EventState field in cached IocFacts */
7498 if (ioc
->facts
.Function
) {
7499 ioc
->facts
.EventState
= evState
;
7503 case MPI_EVENT_INTEGRATED_RAID
:
7504 mptbase_raid_process_event_data(ioc
,
7505 (MpiEventDataRaid_t
*)pEventReply
->Data
);
7512 * Should this event be logged? Events are written sequentially.
7513 * When buffer is full, start again at the top.
7515 if (ioc
->events
&& (ioc
->eventTypes
& ( 1 << event
))) {
7518 idx
= ioc
->eventContext
% MPTCTL_EVENT_LOG_SIZE
;
7520 ioc
->events
[idx
].event
= event
;
7521 ioc
->events
[idx
].eventContext
= ioc
->eventContext
;
7523 for (ii
= 0; ii
< 2; ii
++) {
7525 ioc
->events
[idx
].data
[ii
] = le32_to_cpu(pEventReply
->Data
[ii
]);
7527 ioc
->events
[idx
].data
[ii
] = 0;
7530 ioc
->eventContext
++;
7535 * Call each currently registered protocol event handler.
7537 for (cb_idx
= MPT_MAX_PROTOCOL_DRIVERS
-1; cb_idx
; cb_idx
--) {
7538 if (MptEvHandlers
[cb_idx
]) {
7539 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
7540 "Routing Event to event handler #%d\n",
7541 ioc
->name
, cb_idx
));
7542 r
+= (*(MptEvHandlers
[cb_idx
]))(ioc
, pEventReply
);
7546 /* FIXME? Examine results here? */
7549 * If needed, send (a single) EventAck.
7551 if (pEventReply
->AckRequired
== MPI_EVENT_NOTIFICATION_ACK_REQUIRED
) {
7552 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
7553 "EventAck required\n",ioc
->name
));
7554 if ((ii
= SendEventAck(ioc
, pEventReply
)) != 0) {
7555 devtverboseprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"SendEventAck returned %d\n",
7560 *evHandlers
= handlers
;
7564 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7566 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
7567 * @ioc: Pointer to MPT_ADAPTER structure
7568 * @log_info: U32 LogInfo reply word from the IOC
7570 * Refer to lsi/mpi_log_fc.h.
7573 mpt_fc_log_info(MPT_ADAPTER
*ioc
, u32 log_info
)
7575 char *desc
= "unknown";
7577 switch (log_info
& 0xFF000000) {
7578 case MPI_IOCLOGINFO_FC_INIT_BASE
:
7579 desc
= "FCP Initiator";
7581 case MPI_IOCLOGINFO_FC_TARGET_BASE
:
7582 desc
= "FCP Target";
7584 case MPI_IOCLOGINFO_FC_LAN_BASE
:
7587 case MPI_IOCLOGINFO_FC_MSG_BASE
:
7588 desc
= "MPI Message Layer";
7590 case MPI_IOCLOGINFO_FC_LINK_BASE
:
7593 case MPI_IOCLOGINFO_FC_CTX_BASE
:
7594 desc
= "Context Manager";
7596 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET
:
7597 desc
= "Invalid Field Offset";
7599 case MPI_IOCLOGINFO_FC_STATE_CHANGE
:
7600 desc
= "State Change Info";
7604 printk(MYIOC_s_INFO_FMT
"LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
7605 ioc
->name
, log_info
, desc
, (log_info
& 0xFFFFFF));
7608 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7610 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
7611 * @ioc: Pointer to MPT_ADAPTER structure
7612 * @log_info: U32 LogInfo word from the IOC
7614 * Refer to lsi/sp_log.h.
7617 mpt_spi_log_info(MPT_ADAPTER
*ioc
, u32 log_info
)
7619 u32 info
= log_info
& 0x00FF0000;
7620 char *desc
= "unknown";
7624 desc
= "bug! MID not found";
7628 desc
= "Parity Error";
7632 desc
= "ASYNC Outbound Overrun";
7636 desc
= "SYNC Offset Error";
7644 desc
= "Msg In Overflow";
7652 desc
= "Outbound DMA Overrun";
7656 desc
= "Task Management";
7660 desc
= "Device Problem";
7664 desc
= "Invalid Phase Change";
7668 desc
= "Untagged Table Size";
7673 printk(MYIOC_s_INFO_FMT
"LogInfo(0x%08x): F/W: %s\n", ioc
->name
, log_info
, desc
);
7676 /* strings for sas loginfo */
7677 static char *originator_str
[] = {
7682 static char *iop_code_str
[] = {
7684 "Invalid SAS Address", /* 01h */
7686 "Invalid Page", /* 03h */
7687 "Diag Message Error", /* 04h */
7688 "Task Terminated", /* 05h */
7689 "Enclosure Management", /* 06h */
7690 "Target Mode" /* 07h */
7692 static char *pl_code_str
[] = {
7694 "Open Failure", /* 01h */
7695 "Invalid Scatter Gather List", /* 02h */
7696 "Wrong Relative Offset or Frame Length", /* 03h */
7697 "Frame Transfer Error", /* 04h */
7698 "Transmit Frame Connected Low", /* 05h */
7699 "SATA Non-NCQ RW Error Bit Set", /* 06h */
7700 "SATA Read Log Receive Data Error", /* 07h */
7701 "SATA NCQ Fail All Commands After Error", /* 08h */
7702 "SATA Error in Receive Set Device Bit FIS", /* 09h */
7703 "Receive Frame Invalid Message", /* 0Ah */
7704 "Receive Context Message Valid Error", /* 0Bh */
7705 "Receive Frame Current Frame Error", /* 0Ch */
7706 "SATA Link Down", /* 0Dh */
7707 "Discovery SATA Init W IOS", /* 0Eh */
7708 "Config Invalid Page", /* 0Fh */
7709 "Discovery SATA Init Timeout", /* 10h */
7712 "IO Not Yet Executed", /* 13h */
7713 "IO Executed", /* 14h */
7714 "Persistent Reservation Out Not Affiliation "
7716 "Open Transmit DMA Abort", /* 16h */
7717 "IO Device Missing Delay Retry", /* 17h */
7718 "IO Cancelled Due to Recieve Error", /* 18h */
7726 "Enclosure Management" /* 20h */
7728 static char *ir_code_str
[] = {
7729 "Raid Action Error", /* 00h */
7739 static char *raid_sub_code_str
[] = {
7741 "Volume Creation Failed: Data Passed too "
7743 "Volume Creation Failed: Duplicate Volumes "
7744 "Attempted", /* 02h */
7745 "Volume Creation Failed: Max Number "
7746 "Supported Volumes Exceeded", /* 03h */
7747 "Volume Creation Failed: DMA Error", /* 04h */
7748 "Volume Creation Failed: Invalid Volume Type", /* 05h */
7749 "Volume Creation Failed: Error Reading "
7750 "MFG Page 4", /* 06h */
7751 "Volume Creation Failed: Creating Internal "
7752 "Structures", /* 07h */
7761 "Activation failed: Already Active Volume", /* 10h */
7762 "Activation failed: Unsupported Volume Type", /* 11h */
7763 "Activation failed: Too Many Active Volumes", /* 12h */
7764 "Activation failed: Volume ID in Use", /* 13h */
7765 "Activation failed: Reported Failure", /* 14h */
7766 "Activation failed: Importing a Volume", /* 15h */
7777 "Phys Disk failed: Too Many Phys Disks", /* 20h */
7778 "Phys Disk failed: Data Passed too Large", /* 21h */
7779 "Phys Disk failed: DMA Error", /* 22h */
7780 "Phys Disk failed: Invalid <channel:id>", /* 23h */
7781 "Phys Disk failed: Creating Phys Disk Config "
7794 "Compatibility Error: IR Disabled", /* 30h */
7795 "Compatibility Error: Inquiry Comand Failed", /* 31h */
7796 "Compatibility Error: Device not Direct Access "
7797 "Device ", /* 32h */
7798 "Compatibility Error: Removable Device Found", /* 33h */
7799 "Compatibility Error: Device SCSI Version not "
7800 "2 or Higher", /* 34h */
7801 "Compatibility Error: SATA Device, 48 BIT LBA "
7802 "not Supported", /* 35h */
7803 "Compatibility Error: Device doesn't have "
7804 "512 Byte Block Sizes", /* 36h */
7805 "Compatibility Error: Volume Type Check Failed", /* 37h */
7806 "Compatibility Error: Volume Type is "
7807 "Unsupported by FW", /* 38h */
7808 "Compatibility Error: Disk Drive too Small for "
7809 "use in Volume", /* 39h */
7810 "Compatibility Error: Phys Disk for Create "
7811 "Volume not Found", /* 3Ah */
7812 "Compatibility Error: Too Many or too Few "
7813 "Disks for Volume Type", /* 3Bh */
7814 "Compatibility Error: Disk stripe Sizes "
7815 "Must be 64KB", /* 3Ch */
7816 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
7819 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7821 * mpt_sas_log_info - Log information returned from SAS IOC.
7822 * @ioc: Pointer to MPT_ADAPTER structure
7823 * @log_info: U32 LogInfo reply word from the IOC
7825 * Refer to lsi/mpi_log_sas.h.
7828 mpt_sas_log_info(MPT_ADAPTER
*ioc
, u32 log_info
)
7830 union loginfo_type
{
7839 union loginfo_type sas_loginfo
;
7840 char *originator_desc
= NULL
;
7841 char *code_desc
= NULL
;
7842 char *sub_code_desc
= NULL
;
7844 sas_loginfo
.loginfo
= log_info
;
7845 if ((sas_loginfo
.dw
.bus_type
!= 3 /*SAS*/) &&
7846 (sas_loginfo
.dw
.originator
< ARRAY_SIZE(originator_str
)))
7849 originator_desc
= originator_str
[sas_loginfo
.dw
.originator
];
7851 switch (sas_loginfo
.dw
.originator
) {
7854 if (sas_loginfo
.dw
.code
<
7855 ARRAY_SIZE(iop_code_str
))
7856 code_desc
= iop_code_str
[sas_loginfo
.dw
.code
];
7859 if (sas_loginfo
.dw
.code
<
7860 ARRAY_SIZE(pl_code_str
))
7861 code_desc
= pl_code_str
[sas_loginfo
.dw
.code
];
7864 if (sas_loginfo
.dw
.code
>=
7865 ARRAY_SIZE(ir_code_str
))
7867 code_desc
= ir_code_str
[sas_loginfo
.dw
.code
];
7868 if (sas_loginfo
.dw
.subcode
>=
7869 ARRAY_SIZE(raid_sub_code_str
))
7871 if (sas_loginfo
.dw
.code
== 0)
7873 raid_sub_code_str
[sas_loginfo
.dw
.subcode
];
7879 if (sub_code_desc
!= NULL
)
7880 printk(MYIOC_s_INFO_FMT
7881 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7883 ioc
->name
, log_info
, originator_desc
, code_desc
,
7885 else if (code_desc
!= NULL
)
7886 printk(MYIOC_s_INFO_FMT
7887 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7888 " SubCode(0x%04x)\n",
7889 ioc
->name
, log_info
, originator_desc
, code_desc
,
7890 sas_loginfo
.dw
.subcode
);
7892 printk(MYIOC_s_INFO_FMT
7893 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
7894 " SubCode(0x%04x)\n",
7895 ioc
->name
, log_info
, originator_desc
,
7896 sas_loginfo
.dw
.code
, sas_loginfo
.dw
.subcode
);
7899 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7901 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
7902 * @ioc: Pointer to MPT_ADAPTER structure
7903 * @ioc_status: U32 IOCStatus word from IOC
7904 * @mf: Pointer to MPT request frame
7906 * Refer to lsi/mpi.h.
7909 mpt_iocstatus_info_config(MPT_ADAPTER
*ioc
, u32 ioc_status
, MPT_FRAME_HDR
*mf
)
7911 Config_t
*pReq
= (Config_t
*)mf
;
7912 char extend_desc
[EVENT_DESCR_STR_SZ
];
7917 if (pReq
->Header
.PageType
== MPI_CONFIG_PAGETYPE_EXTENDED
)
7918 page_type
= pReq
->ExtPageType
;
7920 page_type
= pReq
->Header
.PageType
;
7923 * ignore invalid page messages for GET_NEXT_HANDLE
7925 form
= le32_to_cpu(pReq
->PageAddress
);
7926 if (ioc_status
== MPI_IOCSTATUS_CONFIG_INVALID_PAGE
) {
7927 if (page_type
== MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE
||
7928 page_type
== MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER
||
7929 page_type
== MPI_CONFIG_EXTPAGETYPE_ENCLOSURE
) {
7930 if ((form
>> MPI_SAS_DEVICE_PGAD_FORM_SHIFT
) ==
7931 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE
)
7934 if (page_type
== MPI_CONFIG_PAGETYPE_FC_DEVICE
)
7935 if ((form
& MPI_FC_DEVICE_PGAD_FORM_MASK
) ==
7936 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID
)
7940 snprintf(extend_desc
, EVENT_DESCR_STR_SZ
,
7941 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
7942 page_type
, pReq
->Header
.PageNumber
, pReq
->Action
, form
);
7944 switch (ioc_status
) {
7946 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION
: /* 0x0020 */
7947 desc
= "Config Page Invalid Action";
7950 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE
: /* 0x0021 */
7951 desc
= "Config Page Invalid Type";
7954 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE
: /* 0x0022 */
7955 desc
= "Config Page Invalid Page";
7958 case MPI_IOCSTATUS_CONFIG_INVALID_DATA
: /* 0x0023 */
7959 desc
= "Config Page Invalid Data";
7962 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS
: /* 0x0024 */
7963 desc
= "Config Page No Defaults";
7966 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT
: /* 0x0025 */
7967 desc
= "Config Page Can't Commit";
7974 dreplyprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"IOCStatus(0x%04X): %s: %s\n",
7975 ioc
->name
, ioc_status
, desc
, extend_desc
));
7979 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
7980 * @ioc: Pointer to MPT_ADAPTER structure
7981 * @ioc_status: U32 IOCStatus word from IOC
7982 * @mf: Pointer to MPT request frame
7984 * Refer to lsi/mpi.h.
7987 mpt_iocstatus_info(MPT_ADAPTER
*ioc
, u32 ioc_status
, MPT_FRAME_HDR
*mf
)
7989 u32 status
= ioc_status
& MPI_IOCSTATUS_MASK
;
7994 /****************************************************************************/
7995 /* Common IOCStatus values for all replies */
7996 /****************************************************************************/
7998 case MPI_IOCSTATUS_INVALID_FUNCTION
: /* 0x0001 */
7999 desc
= "Invalid Function";
8002 case MPI_IOCSTATUS_BUSY
: /* 0x0002 */
8006 case MPI_IOCSTATUS_INVALID_SGL
: /* 0x0003 */
8007 desc
= "Invalid SGL";
8010 case MPI_IOCSTATUS_INTERNAL_ERROR
: /* 0x0004 */
8011 desc
= "Internal Error";
8014 case MPI_IOCSTATUS_RESERVED
: /* 0x0005 */
8018 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES
: /* 0x0006 */
8019 desc
= "Insufficient Resources";
8022 case MPI_IOCSTATUS_INVALID_FIELD
: /* 0x0007 */
8023 desc
= "Invalid Field";
8026 case MPI_IOCSTATUS_INVALID_STATE
: /* 0x0008 */
8027 desc
= "Invalid State";
8030 /****************************************************************************/
8031 /* Config IOCStatus values */
8032 /****************************************************************************/
8034 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION
: /* 0x0020 */
8035 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE
: /* 0x0021 */
8036 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE
: /* 0x0022 */
8037 case MPI_IOCSTATUS_CONFIG_INVALID_DATA
: /* 0x0023 */
8038 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS
: /* 0x0024 */
8039 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT
: /* 0x0025 */
8040 mpt_iocstatus_info_config(ioc
, status
, mf
);
8043 /****************************************************************************/
8044 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
8046 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
8048 /****************************************************************************/
8050 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR
: /* 0x0040 */
8051 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN
: /* 0x0045 */
8052 case MPI_IOCSTATUS_SCSI_INVALID_BUS
: /* 0x0041 */
8053 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID
: /* 0x0042 */
8054 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE
: /* 0x0043 */
8055 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN
: /* 0x0044 */
8056 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR
: /* 0x0046 */
8057 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR
: /* 0x0047 */
8058 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED
: /* 0x0048 */
8059 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH
: /* 0x0049 */
8060 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED
: /* 0x004A */
8061 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED
: /* 0x004B */
8062 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED
: /* 0x004C */
8065 /****************************************************************************/
8066 /* SCSI Target values */
8067 /****************************************************************************/
8069 case MPI_IOCSTATUS_TARGET_PRIORITY_IO
: /* 0x0060 */
8070 desc
= "Target: Priority IO";
8073 case MPI_IOCSTATUS_TARGET_INVALID_PORT
: /* 0x0061 */
8074 desc
= "Target: Invalid Port";
8077 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX
: /* 0x0062 */
8078 desc
= "Target Invalid IO Index:";
8081 case MPI_IOCSTATUS_TARGET_ABORTED
: /* 0x0063 */
8082 desc
= "Target: Aborted";
8085 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE
: /* 0x0064 */
8086 desc
= "Target: No Conn Retryable";
8089 case MPI_IOCSTATUS_TARGET_NO_CONNECTION
: /* 0x0065 */
8090 desc
= "Target: No Connection";
8093 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH
: /* 0x006A */
8094 desc
= "Target: Transfer Count Mismatch";
8097 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT
: /* 0x006B */
8098 desc
= "Target: STS Data not Sent";
8101 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR
: /* 0x006D */
8102 desc
= "Target: Data Offset Error";
8105 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA
: /* 0x006E */
8106 desc
= "Target: Too Much Write Data";
8109 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT
: /* 0x006F */
8110 desc
= "Target: IU Too Short";
8113 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT
: /* 0x0070 */
8114 desc
= "Target: ACK NAK Timeout";
8117 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED
: /* 0x0071 */
8118 desc
= "Target: Nak Received";
8121 /****************************************************************************/
8122 /* Fibre Channel Direct Access values */
8123 /****************************************************************************/
8125 case MPI_IOCSTATUS_FC_ABORTED
: /* 0x0066 */
8126 desc
= "FC: Aborted";
8129 case MPI_IOCSTATUS_FC_RX_ID_INVALID
: /* 0x0067 */
8130 desc
= "FC: RX ID Invalid";
8133 case MPI_IOCSTATUS_FC_DID_INVALID
: /* 0x0068 */
8134 desc
= "FC: DID Invalid";
8137 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT
: /* 0x0069 */
8138 desc
= "FC: Node Logged Out";
8141 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED
: /* 0x006C */
8142 desc
= "FC: Exchange Canceled";
8145 /****************************************************************************/
8147 /****************************************************************************/
8149 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND
: /* 0x0080 */
8150 desc
= "LAN: Device not Found";
8153 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE
: /* 0x0081 */
8154 desc
= "LAN: Device Failure";
8157 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR
: /* 0x0082 */
8158 desc
= "LAN: Transmit Error";
8161 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED
: /* 0x0083 */
8162 desc
= "LAN: Transmit Aborted";
8165 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR
: /* 0x0084 */
8166 desc
= "LAN: Receive Error";
8169 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED
: /* 0x0085 */
8170 desc
= "LAN: Receive Aborted";
8173 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET
: /* 0x0086 */
8174 desc
= "LAN: Partial Packet";
8177 case MPI_IOCSTATUS_LAN_CANCELED
: /* 0x0087 */
8178 desc
= "LAN: Canceled";
8181 /****************************************************************************/
8182 /* Serial Attached SCSI values */
8183 /****************************************************************************/
8185 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED
: /* 0x0090 */
8186 desc
= "SAS: SMP Request Failed";
8189 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN
: /* 0x0090 */
8190 desc
= "SAS: SMP Data Overrun";
8201 dreplyprintk(ioc
, printk(MYIOC_s_DEBUG_FMT
"IOCStatus(0x%04X): %s\n",
8202 ioc
->name
, status
, desc
));
8205 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8206 EXPORT_SYMBOL(mpt_attach
);
8207 EXPORT_SYMBOL(mpt_detach
);
8209 EXPORT_SYMBOL(mpt_resume
);
8210 EXPORT_SYMBOL(mpt_suspend
);
8212 EXPORT_SYMBOL(ioc_list
);
8213 EXPORT_SYMBOL(mpt_register
);
8214 EXPORT_SYMBOL(mpt_deregister
);
8215 EXPORT_SYMBOL(mpt_event_register
);
8216 EXPORT_SYMBOL(mpt_event_deregister
);
8217 EXPORT_SYMBOL(mpt_reset_register
);
8218 EXPORT_SYMBOL(mpt_reset_deregister
);
8219 EXPORT_SYMBOL(mpt_device_driver_register
);
8220 EXPORT_SYMBOL(mpt_device_driver_deregister
);
8221 EXPORT_SYMBOL(mpt_get_msg_frame
);
8222 EXPORT_SYMBOL(mpt_put_msg_frame
);
8223 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri
);
8224 EXPORT_SYMBOL(mpt_free_msg_frame
);
8225 EXPORT_SYMBOL(mpt_send_handshake_request
);
8226 EXPORT_SYMBOL(mpt_verify_adapter
);
8227 EXPORT_SYMBOL(mpt_GetIocState
);
8228 EXPORT_SYMBOL(mpt_print_ioc_summary
);
8229 EXPORT_SYMBOL(mpt_HardResetHandler
);
8230 EXPORT_SYMBOL(mpt_config
);
8231 EXPORT_SYMBOL(mpt_findImVolumes
);
8232 EXPORT_SYMBOL(mpt_alloc_fw_memory
);
8233 EXPORT_SYMBOL(mpt_free_fw_memory
);
8234 EXPORT_SYMBOL(mptbase_sas_persist_operation
);
8235 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0
);
8237 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8239 * fusion_init - Fusion MPT base driver initialization routine.
8241 * Returns 0 for success, non-zero for failure.
8248 show_mptmod_ver(my_NAME
, my_VERSION
);
8249 printk(KERN_INFO COPYRIGHT
"\n");
8251 for (cb_idx
= 0; cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
; cb_idx
++) {
8252 MptCallbacks
[cb_idx
] = NULL
;
8253 MptDriverClass
[cb_idx
] = MPTUNKNOWN_DRIVER
;
8254 MptEvHandlers
[cb_idx
] = NULL
;
8255 MptResetHandlers
[cb_idx
] = NULL
;
8258 /* Register ourselves (mptbase) in order to facilitate
8259 * EventNotification handling.
8261 mpt_base_index
= mpt_register(mptbase_reply
, MPTBASE_DRIVER
);
8263 /* Register for hard reset handling callbacks.
8265 mpt_reset_register(mpt_base_index
, mpt_ioc_reset
);
8267 #ifdef CONFIG_PROC_FS
8268 (void) procmpt_create();
8273 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8275 * fusion_exit - Perform driver unload cleanup.
8277 * This routine frees all resources associated with each MPT adapter
8278 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
8284 mpt_reset_deregister(mpt_base_index
);
8286 #ifdef CONFIG_PROC_FS
8291 module_init(fusion_init
);
8292 module_exit(fusion_exit
);