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 Logic PCI chip/adapter(s)
6 * running LSI Logic Fusion MPT (Message Passing Technology) firmware.
8 * Copyright (c) 1999-2005 LSI Logic Corporation
9 * (mailto:mpt_linux_developer@lsil.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/config.h>
50 #include <linux/kernel.h>
51 #include <linux/module.h>
52 #include <linux/errno.h>
53 #include <linux/init.h>
54 #include <linux/slab.h>
55 #include <linux/types.h>
56 #include <linux/pci.h>
57 #include <linux/kdev_t.h>
58 #include <linux/blkdev.h>
59 #include <linux/delay.h>
60 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
61 #include <linux/dma-mapping.h>
67 #include <asm/irq.h> /* needed for __irq_itoa() proto */
72 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
73 #define my_NAME "Fusion MPT base driver"
74 #define my_VERSION MPT_LINUX_VERSION_COMMON
75 #define MYNAM "mptbase"
77 MODULE_AUTHOR(MODULEAUTHOR
);
78 MODULE_DESCRIPTION(my_NAME
);
79 MODULE_LICENSE("GPL");
84 static int mpt_msi_enable
;
85 module_param(mpt_msi_enable
, int, 0);
86 MODULE_PARM_DESC(mpt_msi_enable
, " MSI Support Enable (default=0)");
89 static int mfcounter
= 0;
90 #define PRINT_MF_COUNT 20000
93 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
97 int mpt_lan_index
= -1;
98 int mpt_stm_index
= -1;
100 struct proc_dir_entry
*mpt_proc_root_dir
;
102 #define WHOINIT_UNKNOWN 0xAA
104 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
108 /* Adapter link list */
110 /* Callback lookup table */
111 static MPT_CALLBACK MptCallbacks
[MPT_MAX_PROTOCOL_DRIVERS
];
112 /* Protocol driver class lookup table */
113 static int MptDriverClass
[MPT_MAX_PROTOCOL_DRIVERS
];
114 /* Event handler lookup table */
115 static MPT_EVHANDLER MptEvHandlers
[MPT_MAX_PROTOCOL_DRIVERS
];
116 /* Reset handler lookup table */
117 static MPT_RESETHANDLER MptResetHandlers
[MPT_MAX_PROTOCOL_DRIVERS
];
118 static struct mpt_pci_driver
*MptDeviceDriverHandlers
[MPT_MAX_PROTOCOL_DRIVERS
];
120 static int mpt_base_index
= -1;
121 static int last_drv_idx
= -1;
123 static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq
);
125 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
129 static irqreturn_t
mpt_interrupt(int irq
, void *bus_id
, struct pt_regs
*r
);
130 static int mpt_base_reply(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*req
, MPT_FRAME_HDR
*reply
);
131 static int mpt_handshake_req_reply_wait(MPT_ADAPTER
*ioc
, int reqBytes
,
132 u32
*req
, int replyBytes
, u16
*u16reply
, int maxwait
,
134 static int mpt_do_ioc_recovery(MPT_ADAPTER
*ioc
, u32 reason
, int sleepFlag
);
135 static void mpt_detect_bound_ports(MPT_ADAPTER
*ioc
, struct pci_dev
*pdev
);
136 static void mpt_adapter_disable(MPT_ADAPTER
*ioc
);
137 static void mpt_adapter_dispose(MPT_ADAPTER
*ioc
);
139 static void MptDisplayIocCapabilities(MPT_ADAPTER
*ioc
);
140 static int MakeIocReady(MPT_ADAPTER
*ioc
, int force
, int sleepFlag
);
141 static int GetIocFacts(MPT_ADAPTER
*ioc
, int sleepFlag
, int reason
);
142 static int GetPortFacts(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
);
143 static int SendIocInit(MPT_ADAPTER
*ioc
, int sleepFlag
);
144 static int SendPortEnable(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
);
145 static int mpt_do_upload(MPT_ADAPTER
*ioc
, int sleepFlag
);
146 static int mpt_downloadboot(MPT_ADAPTER
*ioc
, MpiFwHeader_t
*pFwHeader
, int sleepFlag
);
147 static int mpt_diag_reset(MPT_ADAPTER
*ioc
, int ignore
, int sleepFlag
);
148 static int KickStart(MPT_ADAPTER
*ioc
, int ignore
, int sleepFlag
);
149 static int SendIocReset(MPT_ADAPTER
*ioc
, u8 reset_type
, int sleepFlag
);
150 static int PrimeIocFifos(MPT_ADAPTER
*ioc
);
151 static int WaitForDoorbellAck(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
);
152 static int WaitForDoorbellInt(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
);
153 static int WaitForDoorbellReply(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
);
154 static int GetLanConfigPages(MPT_ADAPTER
*ioc
);
155 static int GetIoUnitPage2(MPT_ADAPTER
*ioc
);
156 int mptbase_sas_persist_operation(MPT_ADAPTER
*ioc
, u8 persist_opcode
);
157 static int mpt_GetScsiPortSettings(MPT_ADAPTER
*ioc
, int portnum
);
158 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER
*ioc
, int portnum
);
159 static void mpt_read_ioc_pg_1(MPT_ADAPTER
*ioc
);
160 static void mpt_read_ioc_pg_4(MPT_ADAPTER
*ioc
);
161 static void mpt_timer_expired(unsigned long data
);
162 static int SendEventNotification(MPT_ADAPTER
*ioc
, u8 EvSwitch
);
163 static int SendEventAck(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*evnp
);
164 static int mpt_host_page_access_control(MPT_ADAPTER
*ioc
, u8 access_control_value
, int sleepFlag
);
165 static int mpt_host_page_alloc(MPT_ADAPTER
*ioc
, pIOCInit_t ioc_init
);
167 #ifdef CONFIG_PROC_FS
168 static int procmpt_summary_read(char *buf
, char **start
, off_t offset
,
169 int request
, int *eof
, void *data
);
170 static int procmpt_version_read(char *buf
, char **start
, off_t offset
,
171 int request
, int *eof
, void *data
);
172 static int procmpt_iocinfo_read(char *buf
, char **start
, off_t offset
,
173 int request
, int *eof
, void *data
);
175 static void mpt_get_fw_exp_ver(char *buf
, MPT_ADAPTER
*ioc
);
177 //int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
178 static int ProcessEventNotification(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*evReply
, int *evHandlers
);
179 static void mpt_sp_ioc_info(MPT_ADAPTER
*ioc
, u32 ioc_status
, MPT_FRAME_HDR
*mf
);
180 static void mpt_fc_log_info(MPT_ADAPTER
*ioc
, u32 log_info
);
181 static void mpt_spi_log_info(MPT_ADAPTER
*ioc
, u32 log_info
);
182 static void mpt_sas_log_info(MPT_ADAPTER
*ioc
, u32 log_info
);
183 static int mpt_read_ioc_pg_3(MPT_ADAPTER
*ioc
);
185 /* module entry point */
186 static int __init
fusion_init (void);
187 static void __exit
fusion_exit (void);
189 #define CHIPREG_READ32(addr) readl_relaxed(addr)
190 #define CHIPREG_READ32_dmasync(addr) readl(addr)
191 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
192 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
193 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
196 pci_disable_io_access(struct pci_dev
*pdev
)
200 pci_read_config_word(pdev
, PCI_COMMAND
, &command_reg
);
202 pci_write_config_word(pdev
, PCI_COMMAND
, command_reg
);
206 pci_enable_io_access(struct pci_dev
*pdev
)
210 pci_read_config_word(pdev
, PCI_COMMAND
, &command_reg
);
212 pci_write_config_word(pdev
, PCI_COMMAND
, command_reg
);
216 * Process turbo (context) reply...
219 mpt_turbo_reply(MPT_ADAPTER
*ioc
, u32 pa
)
221 MPT_FRAME_HDR
*mf
= NULL
;
222 MPT_FRAME_HDR
*mr
= NULL
;
226 dmfprintk((MYIOC_s_INFO_FMT
"Got TURBO reply req_idx=%08x\n",
229 switch (pa
>> MPI_CONTEXT_REPLY_TYPE_SHIFT
) {
230 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT
:
231 req_idx
= pa
& 0x0000FFFF;
232 cb_idx
= (pa
& 0x00FF0000) >> 16;
233 mf
= MPT_INDEX_2_MFPTR(ioc
, req_idx
);
235 case MPI_CONTEXT_REPLY_TYPE_LAN
:
236 cb_idx
= mpt_lan_index
;
238 * Blind set of mf to NULL here was fatal
239 * after lan_reply says "freeme"
240 * Fix sort of combined with an optimization here;
241 * added explicit check for case where lan_reply
242 * was just returning 1 and doing nothing else.
243 * For this case skip the callback, but set up
244 * proper mf value first here:-)
246 if ((pa
& 0x58000000) == 0x58000000) {
247 req_idx
= pa
& 0x0000FFFF;
248 mf
= MPT_INDEX_2_MFPTR(ioc
, req_idx
);
249 mpt_free_msg_frame(ioc
, mf
);
254 mr
= (MPT_FRAME_HDR
*) CAST_U32_TO_PTR(pa
);
256 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET
:
257 cb_idx
= mpt_stm_index
;
258 mr
= (MPT_FRAME_HDR
*) CAST_U32_TO_PTR(pa
);
265 /* Check for (valid) IO callback! */
266 if (cb_idx
< 1 || cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
||
267 MptCallbacks
[cb_idx
] == NULL
) {
268 printk(MYIOC_s_WARN_FMT
"%s: Invalid cb_idx (%d)!\n",
269 __FUNCTION__
, ioc
->name
, cb_idx
);
273 if (MptCallbacks
[cb_idx
](ioc
, mf
, mr
))
274 mpt_free_msg_frame(ioc
, mf
);
280 mpt_reply(MPT_ADAPTER
*ioc
, u32 pa
)
291 /* non-TURBO reply! Hmmm, something may be up...
292 * Newest turbo reply mechanism; get address
293 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
296 /* Map DMA address of reply header to cpu address.
297 * pa is 32 bits - but the dma address may be 32 or 64 bits
298 * get offset based only only the low addresses
301 reply_dma_low
= (pa
<<= 1);
302 mr
= (MPT_FRAME_HDR
*)((u8
*)ioc
->reply_frames
+
303 (reply_dma_low
- ioc
->reply_frames_low_dma
));
305 req_idx
= le16_to_cpu(mr
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
);
306 cb_idx
= mr
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
;
307 mf
= MPT_INDEX_2_MFPTR(ioc
, req_idx
);
309 dmfprintk((MYIOC_s_INFO_FMT
"Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
310 ioc
->name
, mr
, req_idx
, cb_idx
, mr
->u
.hdr
.Function
));
311 DBG_DUMP_REPLY_FRAME(mr
)
313 /* Check/log IOC log info
315 ioc_stat
= le16_to_cpu(mr
->u
.reply
.IOCStatus
);
316 if (ioc_stat
& MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE
) {
317 u32 log_info
= le32_to_cpu(mr
->u
.reply
.IOCLogInfo
);
318 if (ioc
->bus_type
== FC
)
319 mpt_fc_log_info(ioc
, log_info
);
320 else if (ioc
->bus_type
== SPI
)
321 mpt_spi_log_info(ioc
, log_info
);
322 else if (ioc
->bus_type
== SAS
)
323 mpt_sas_log_info(ioc
, log_info
);
325 if (ioc_stat
& MPI_IOCSTATUS_MASK
) {
326 if (ioc
->bus_type
== SPI
&&
327 cb_idx
!= mpt_stm_index
&&
328 cb_idx
!= mpt_lan_index
)
329 mpt_sp_ioc_info(ioc
, (u32
)ioc_stat
, mf
);
333 /* Check for (valid) IO callback! */
334 if (cb_idx
< 1 || cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
||
335 MptCallbacks
[cb_idx
] == NULL
) {
336 printk(MYIOC_s_WARN_FMT
"%s: Invalid cb_idx (%d)!\n",
337 __FUNCTION__
, ioc
->name
, cb_idx
);
342 freeme
= MptCallbacks
[cb_idx
](ioc
, mf
, mr
);
345 /* Flush (non-TURBO) reply with a WRITE! */
346 CHIPREG_WRITE32(&ioc
->chip
->ReplyFifo
, pa
);
349 mpt_free_msg_frame(ioc
, mf
);
353 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
355 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
356 * @irq: irq number (not used)
357 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
358 * @r: pt_regs pointer (not used)
360 * This routine is registered via the request_irq() kernel API call,
361 * and handles all interrupts generated from a specific MPT adapter
362 * (also referred to as a IO Controller or IOC).
363 * This routine must clear the interrupt from the adapter and does
364 * so by reading the reply FIFO. Multiple replies may be processed
365 * per single call to this routine.
367 * This routine handles register-level access of the adapter but
368 * dispatches (calls) a protocol-specific callback routine to handle
369 * the protocol-specific details of the MPT request completion.
372 mpt_interrupt(int irq
, void *bus_id
, struct pt_regs
*r
)
374 MPT_ADAPTER
*ioc
= bus_id
;
378 * Drain the reply FIFO!
381 pa
= CHIPREG_READ32_dmasync(&ioc
->chip
->ReplyFifo
);
382 if (pa
== 0xFFFFFFFF)
384 else if (pa
& MPI_ADDRESS_REPLY_A_BIT
)
387 mpt_turbo_reply(ioc
, pa
);
393 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
395 * mpt_base_reply - MPT base driver's callback routine; all base driver
396 * "internal" request/reply processing is routed here.
397 * Currently used for EventNotification and EventAck handling.
398 * @ioc: Pointer to MPT_ADAPTER structure
399 * @mf: Pointer to original MPT request frame
400 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
402 * Returns 1 indicating original alloc'd request frame ptr
403 * should be freed, or 0 if it shouldn't.
406 mpt_base_reply(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
, MPT_FRAME_HDR
*reply
)
411 dmfprintk((MYIOC_s_INFO_FMT
"mpt_base_reply() called\n", ioc
->name
));
413 #if defined(MPT_DEBUG_MSG_FRAME)
414 if (!(reply
->u
.hdr
.MsgFlags
& MPI_MSGFLAGS_CONTINUATION_REPLY
)) {
415 dmfprintk((KERN_INFO MYNAM
": Original request frame (@%p) header\n", mf
));
416 DBG_DUMP_REQUEST_FRAME_HDR(mf
)
420 func
= reply
->u
.hdr
.Function
;
421 dmfprintk((MYIOC_s_INFO_FMT
"mpt_base_reply, Function=%02Xh\n",
424 if (func
== MPI_FUNCTION_EVENT_NOTIFICATION
) {
425 EventNotificationReply_t
*pEvReply
= (EventNotificationReply_t
*) reply
;
429 results
= ProcessEventNotification(ioc
, pEvReply
, &evHandlers
);
430 if (results
!= evHandlers
) {
431 /* CHECKME! Any special handling needed here? */
432 devtverboseprintk((MYIOC_s_WARN_FMT
"Called %d event handlers, sum results = %d\n",
433 ioc
->name
, evHandlers
, results
));
437 * Hmmm... It seems that EventNotificationReply is an exception
438 * to the rule of one reply per request.
440 if (pEvReply
->MsgFlags
& MPI_MSGFLAGS_CONTINUATION_REPLY
) {
442 devtverboseprintk((MYIOC_s_WARN_FMT
"EVENT_NOTIFICATION reply %p does not return Request frame\n",
443 ioc
->name
, pEvReply
));
445 devtverboseprintk((MYIOC_s_WARN_FMT
"EVENT_NOTIFICATION reply %p returns Request frame\n",
446 ioc
->name
, pEvReply
));
449 #ifdef CONFIG_PROC_FS
450 // LogEvent(ioc, pEvReply);
453 } else if (func
== MPI_FUNCTION_EVENT_ACK
) {
454 dprintk((MYIOC_s_INFO_FMT
"mpt_base_reply, EventAck reply received\n",
456 } else if (func
== MPI_FUNCTION_CONFIG
) {
460 dcprintk((MYIOC_s_INFO_FMT
"config_complete (mf=%p,mr=%p)\n",
461 ioc
->name
, mf
, reply
));
463 pCfg
= * ((CONFIGPARMS
**)((u8
*) mf
+ ioc
->req_sz
- sizeof(void *)));
466 /* disable timer and remove from linked list */
467 del_timer(&pCfg
->timer
);
469 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
470 list_del(&pCfg
->linkage
);
471 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
474 * If IOC Status is SUCCESS, save the header
475 * and set the status code to GOOD.
477 pCfg
->status
= MPT_CONFIG_ERROR
;
479 ConfigReply_t
*pReply
= (ConfigReply_t
*)reply
;
482 status
= le16_to_cpu(pReply
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
483 dcprintk((KERN_NOTICE
" IOCStatus=%04xh, IOCLogInfo=%08xh\n",
484 status
, le32_to_cpu(pReply
->IOCLogInfo
)));
486 pCfg
->status
= status
;
487 if (status
== MPI_IOCSTATUS_SUCCESS
) {
488 if ((pReply
->Header
.PageType
&
489 MPI_CONFIG_PAGETYPE_MASK
) ==
490 MPI_CONFIG_PAGETYPE_EXTENDED
) {
491 pCfg
->cfghdr
.ehdr
->ExtPageLength
=
492 le16_to_cpu(pReply
->ExtPageLength
);
493 pCfg
->cfghdr
.ehdr
->ExtPageType
=
496 pCfg
->cfghdr
.hdr
->PageVersion
= pReply
->Header
.PageVersion
;
498 /* If this is a regular header, save PageLength. */
499 /* LMP Do this better so not using a reserved field! */
500 pCfg
->cfghdr
.hdr
->PageLength
= pReply
->Header
.PageLength
;
501 pCfg
->cfghdr
.hdr
->PageNumber
= pReply
->Header
.PageNumber
;
502 pCfg
->cfghdr
.hdr
->PageType
= pReply
->Header
.PageType
;
507 * Wake up the original calling thread
512 } else if (func
== MPI_FUNCTION_SAS_IO_UNIT_CONTROL
) {
513 /* we should be always getting a reply frame */
514 memcpy(ioc
->persist_reply_frame
, reply
,
515 min(MPT_DEFAULT_FRAME_SIZE
,
516 4*reply
->u
.reply
.MsgLength
));
517 del_timer(&ioc
->persist_timer
);
518 ioc
->persist_wait_done
= 1;
521 printk(MYIOC_s_ERR_FMT
"Unexpected msg function (=%02Xh) reply received!\n",
526 * Conditionally tell caller to free the original
527 * EventNotification/EventAck/unexpected request frame!
532 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
534 * mpt_register - Register protocol-specific main callback handler.
535 * @cbfunc: callback function pointer
536 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
538 * This routine is called by a protocol-specific driver (SCSI host,
539 * LAN, SCSI target) to register it's reply callback routine. Each
540 * protocol-specific driver must do this before it will be able to
541 * use any IOC resources, such as obtaining request frames.
543 * NOTES: The SCSI protocol driver currently calls this routine thrice
544 * in order to register separate callbacks; one for "normal" SCSI IO;
545 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
547 * Returns a positive integer valued "handle" in the
548 * range (and S.O.D. order) {N,...,7,6,5,...,1} if successful.
549 * Any non-positive return value (including zero!) should be considered
550 * an error by the caller.
553 mpt_register(MPT_CALLBACK cbfunc
, MPT_DRIVER_CLASS dclass
)
560 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
561 * (slot/handle 0 is reserved!)
563 for (i
= MPT_MAX_PROTOCOL_DRIVERS
-1; i
; i
--) {
564 if (MptCallbacks
[i
] == NULL
) {
565 MptCallbacks
[i
] = cbfunc
;
566 MptDriverClass
[i
] = dclass
;
567 MptEvHandlers
[i
] = NULL
;
576 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
578 * mpt_deregister - Deregister a protocol drivers resources.
579 * @cb_idx: previously registered callback handle
581 * Each protocol-specific driver should call this routine when it's
582 * module is unloaded.
585 mpt_deregister(int cb_idx
)
587 if ((cb_idx
>= 0) && (cb_idx
< MPT_MAX_PROTOCOL_DRIVERS
)) {
588 MptCallbacks
[cb_idx
] = NULL
;
589 MptDriverClass
[cb_idx
] = MPTUNKNOWN_DRIVER
;
590 MptEvHandlers
[cb_idx
] = NULL
;
596 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
598 * mpt_event_register - Register protocol-specific event callback
600 * @cb_idx: previously registered (via mpt_register) callback handle
601 * @ev_cbfunc: callback function
603 * This routine can be called by one or more protocol-specific drivers
604 * if/when they choose to be notified of MPT events.
606 * Returns 0 for success.
609 mpt_event_register(int cb_idx
, MPT_EVHANDLER ev_cbfunc
)
611 if (cb_idx
< 1 || cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
614 MptEvHandlers
[cb_idx
] = ev_cbfunc
;
618 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
620 * mpt_event_deregister - Deregister protocol-specific event callback
622 * @cb_idx: previously registered callback handle
624 * Each protocol-specific driver should call this routine
625 * when it does not (or can no longer) handle events,
626 * or when it's module is unloaded.
629 mpt_event_deregister(int cb_idx
)
631 if (cb_idx
< 1 || cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
634 MptEvHandlers
[cb_idx
] = NULL
;
637 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
639 * mpt_reset_register - Register protocol-specific IOC reset handler.
640 * @cb_idx: previously registered (via mpt_register) callback handle
641 * @reset_func: reset function
643 * This routine can be called by one or more protocol-specific drivers
644 * if/when they choose to be notified of IOC resets.
646 * Returns 0 for success.
649 mpt_reset_register(int cb_idx
, MPT_RESETHANDLER reset_func
)
651 if (cb_idx
< 1 || cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
654 MptResetHandlers
[cb_idx
] = reset_func
;
658 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
660 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
661 * @cb_idx: previously registered callback handle
663 * Each protocol-specific driver should call this routine
664 * when it does not (or can no longer) handle IOC reset handling,
665 * or when it's module is unloaded.
668 mpt_reset_deregister(int cb_idx
)
670 if (cb_idx
< 1 || cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
673 MptResetHandlers
[cb_idx
] = NULL
;
676 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
678 * mpt_device_driver_register - Register device driver hooks
681 mpt_device_driver_register(struct mpt_pci_driver
* dd_cbfunc
, int cb_idx
)
685 if (cb_idx
< 1 || cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
) {
689 MptDeviceDriverHandlers
[cb_idx
] = dd_cbfunc
;
691 /* call per pci device probe entry point */
692 list_for_each_entry(ioc
, &ioc_list
, list
) {
693 if(dd_cbfunc
->probe
) {
694 dd_cbfunc
->probe(ioc
->pcidev
,
695 ioc
->pcidev
->driver
->id_table
);
702 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
704 * mpt_device_driver_deregister - DeRegister device driver hooks
707 mpt_device_driver_deregister(int cb_idx
)
709 struct mpt_pci_driver
*dd_cbfunc
;
712 if (cb_idx
< 1 || cb_idx
>= MPT_MAX_PROTOCOL_DRIVERS
)
715 dd_cbfunc
= MptDeviceDriverHandlers
[cb_idx
];
717 list_for_each_entry(ioc
, &ioc_list
, list
) {
718 if (dd_cbfunc
->remove
)
719 dd_cbfunc
->remove(ioc
->pcidev
);
722 MptDeviceDriverHandlers
[cb_idx
] = NULL
;
726 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
728 * mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024)
729 * allocated per MPT adapter.
730 * @handle: Handle of registered MPT protocol driver
731 * @ioc: Pointer to MPT adapter structure
733 * Returns pointer to a MPT request frame or %NULL if none are available
734 * or IOC is not active.
737 mpt_get_msg_frame(int handle
, MPT_ADAPTER
*ioc
)
741 u16 req_idx
; /* Request index */
743 /* validate handle and ioc identifier */
747 printk(KERN_WARNING
"IOC Not Active! mpt_get_msg_frame returning NULL!\n");
750 /* If interrupts are not attached, do not return a request frame */
754 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
755 if (!list_empty(&ioc
->FreeQ
)) {
758 mf
= list_entry(ioc
->FreeQ
.next
, MPT_FRAME_HDR
,
759 u
.frame
.linkage
.list
);
760 list_del(&mf
->u
.frame
.linkage
.list
);
761 mf
->u
.frame
.linkage
.arg1
= 0;
762 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= handle
; /* byte */
763 req_offset
= (u8
*)mf
- (u8
*)ioc
->req_frames
;
765 req_idx
= req_offset
/ ioc
->req_sz
;
766 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(req_idx
);
767 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.rsvd
= 0;
768 ioc
->RequestNB
[req_idx
] = ioc
->NB_for_64_byte_frame
; /* Default, will be changed if necessary in SG generation */
775 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
779 printk(KERN_WARNING
"IOC Active. No free Msg Frames! Count 0x%x Max 0x%x\n", ioc
->mfcnt
, ioc
->req_depth
);
781 if (mfcounter
== PRINT_MF_COUNT
)
782 printk(KERN_INFO
"MF Count 0x%x Max 0x%x \n", ioc
->mfcnt
, ioc
->req_depth
);
785 dmfprintk((KERN_INFO MYNAM
": %s: mpt_get_msg_frame(%d,%d), got mf=%p\n",
786 ioc
->name
, handle
, ioc
->id
, mf
));
790 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
792 * mpt_put_msg_frame - Send a protocol specific MPT request frame
794 * @handle: Handle of registered MPT protocol driver
795 * @ioc: Pointer to MPT adapter structure
796 * @mf: Pointer to MPT request frame
798 * This routine posts a MPT request frame to the request post FIFO of a
799 * specific MPT adapter.
802 mpt_put_msg_frame(int handle
, MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
)
806 u16 req_idx
; /* Request index */
808 /* ensure values are reset properly! */
809 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= handle
; /* byte */
810 req_offset
= (u8
*)mf
- (u8
*)ioc
->req_frames
;
812 req_idx
= req_offset
/ ioc
->req_sz
;
813 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(req_idx
);
814 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.rsvd
= 0;
816 #ifdef MPT_DEBUG_MSG_FRAME
818 u32
*m
= mf
->u
.frame
.hwhdr
.__hdr
;
821 printk(KERN_INFO MYNAM
": %s: About to Put msg frame @ %p:\n" KERN_INFO
" ",
823 n
= ioc
->req_sz
/4 - 1;
826 for (ii
=0; ii
<=n
; ii
++) {
827 if (ii
&& ((ii
%8)==0))
828 printk("\n" KERN_INFO
" ");
829 printk(" %08x", le32_to_cpu(m
[ii
]));
835 mf_dma_addr
= (ioc
->req_frames_low_dma
+ req_offset
) | ioc
->RequestNB
[req_idx
];
836 dsgprintk((MYIOC_s_INFO_FMT
"mf_dma_addr=%x req_idx=%d RequestNB=%x\n", ioc
->name
, mf_dma_addr
, req_idx
, ioc
->RequestNB
[req_idx
]));
837 CHIPREG_WRITE32(&ioc
->chip
->RequestFifo
, mf_dma_addr
);
840 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
842 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
843 * @handle: Handle of registered MPT protocol driver
844 * @ioc: Pointer to MPT adapter structure
845 * @mf: Pointer to MPT request frame
847 * This routine places a MPT request frame back on the MPT adapter's
851 mpt_free_msg_frame(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
)
855 /* Put Request back on FreeQ! */
856 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
857 mf
->u
.frame
.linkage
.arg1
= 0xdeadbeaf; /* signature to know if this mf is freed */
858 list_add_tail(&mf
->u
.frame
.linkage
.list
, &ioc
->FreeQ
);
862 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
865 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
867 * mpt_add_sge - Place a simple SGE at address pAddr.
868 * @pAddr: virtual address for SGE
869 * @flagslength: SGE flags and data transfer length
870 * @dma_addr: Physical address
872 * This routine places a MPT request frame back on the MPT adapter's
876 mpt_add_sge(char *pAddr
, u32 flagslength
, dma_addr_t dma_addr
)
878 if (sizeof(dma_addr_t
) == sizeof(u64
)) {
879 SGESimple64_t
*pSge
= (SGESimple64_t
*) pAddr
;
880 u32 tmp
= dma_addr
& 0xFFFFFFFF;
882 pSge
->FlagsLength
= cpu_to_le32(flagslength
);
883 pSge
->Address
.Low
= cpu_to_le32(tmp
);
884 tmp
= (u32
) ((u64
)dma_addr
>> 32);
885 pSge
->Address
.High
= cpu_to_le32(tmp
);
888 SGESimple32_t
*pSge
= (SGESimple32_t
*) pAddr
;
889 pSge
->FlagsLength
= cpu_to_le32(flagslength
);
890 pSge
->Address
= cpu_to_le32(dma_addr
);
894 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
896 * mpt_send_handshake_request - Send MPT request via doorbell
898 * @handle: Handle of registered MPT protocol driver
899 * @ioc: Pointer to MPT adapter structure
900 * @reqBytes: Size of the request in bytes
901 * @req: Pointer to MPT request frame
902 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
904 * This routine is used exclusively to send MptScsiTaskMgmt
905 * requests since they are required to be sent via doorbell handshake.
907 * NOTE: It is the callers responsibility to byte-swap fields in the
908 * request which are greater than 1 byte in size.
910 * Returns 0 for success, non-zero for failure.
913 mpt_send_handshake_request(int handle
, MPT_ADAPTER
*ioc
, int reqBytes
, u32
*req
, int sleepFlag
)
919 /* State is known to be good upon entering
920 * this function so issue the bus reset
925 * Emulate what mpt_put_msg_frame() does /wrt to sanity
926 * setting cb_idx/req_idx. But ONLY if this request
927 * is in proper (pre-alloc'd) request buffer range...
929 ii
= MFPTR_2_MPT_INDEX(ioc
,(MPT_FRAME_HDR
*)req
);
930 if (reqBytes
>= 12 && ii
>= 0 && ii
< ioc
->req_depth
) {
931 MPT_FRAME_HDR
*mf
= (MPT_FRAME_HDR
*)req
;
932 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
= cpu_to_le16(ii
);
933 mf
->u
.frame
.hwhdr
.msgctxu
.fld
.cb_idx
= handle
;
936 /* Make sure there are no doorbells */
937 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
939 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
,
940 ((MPI_FUNCTION_HANDSHAKE
<<MPI_DOORBELL_FUNCTION_SHIFT
) |
941 ((reqBytes
/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT
)));
943 /* Wait for IOC doorbell int */
944 if ((ii
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0) {
948 /* Read doorbell and check for active bit */
949 if (!(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & MPI_DOORBELL_ACTIVE
))
952 dhsprintk((KERN_INFO MYNAM
": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
955 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
957 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0) {
961 /* Send request via doorbell handshake */
962 req_as_bytes
= (u8
*) req
;
963 for (ii
= 0; ii
< reqBytes
/4; ii
++) {
966 word
= ((req_as_bytes
[(ii
*4) + 0] << 0) |
967 (req_as_bytes
[(ii
*4) + 1] << 8) |
968 (req_as_bytes
[(ii
*4) + 2] << 16) |
969 (req_as_bytes
[(ii
*4) + 3] << 24));
970 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, word
);
971 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0) {
977 if (r
>= 0 && WaitForDoorbellInt(ioc
, 10, sleepFlag
) >= 0)
982 /* Make sure there are no doorbells */
983 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
988 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
990 * mpt_host_page_access_control - provides mechanism for the host
991 * driver to control the IOC's Host Page Buffer access.
992 * @ioc: Pointer to MPT adapter structure
993 * @access_control_value: define bits below
995 * Access Control Value - bits[15:12]
997 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
998 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
999 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1001 * Returns 0 for success, non-zero for failure.
1005 mpt_host_page_access_control(MPT_ADAPTER
*ioc
, u8 access_control_value
, int sleepFlag
)
1009 /* return if in use */
1010 if (CHIPREG_READ32(&ioc
->chip
->Doorbell
)
1011 & MPI_DOORBELL_ACTIVE
)
1014 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1016 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
,
1017 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1018 <<MPI_DOORBELL_FUNCTION_SHIFT
) |
1019 (access_control_value
<<12)));
1021 /* Wait for IOC to clear Doorbell Status bit */
1022 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0) {
1028 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1030 * mpt_host_page_alloc - allocate system memory for the fw
1031 * If we already allocated memory in past, then resend the same pointer.
1032 * ioc@: Pointer to pointer to IOC adapter
1033 * ioc_init@: Pointer to ioc init config page
1035 * Returns 0 for success, non-zero for failure.
1038 mpt_host_page_alloc(MPT_ADAPTER
*ioc
, pIOCInit_t ioc_init
)
1042 u32 host_page_buffer_sz
=0;
1044 if(!ioc
->HostPageBuffer
) {
1046 host_page_buffer_sz
=
1047 le32_to_cpu(ioc
->facts
.HostPageBufferSGE
.FlagsLength
) & 0xFFFFFF;
1049 if(!host_page_buffer_sz
)
1050 return 0; /* fw doesn't need any host buffers */
1052 /* spin till we get enough memory */
1053 while(host_page_buffer_sz
> 0) {
1055 if((ioc
->HostPageBuffer
= pci_alloc_consistent(
1057 host_page_buffer_sz
,
1058 &ioc
->HostPageBuffer_dma
)) != NULL
) {
1060 dinitprintk((MYIOC_s_INFO_FMT
1061 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1063 ioc
->HostPageBuffer
,
1064 ioc
->HostPageBuffer_dma
,
1065 host_page_buffer_sz
));
1066 ioc
->alloc_total
+= host_page_buffer_sz
;
1067 ioc
->HostPageBuffer_sz
= host_page_buffer_sz
;
1071 host_page_buffer_sz
-= (4*1024);
1075 if(!ioc
->HostPageBuffer
) {
1076 printk(MYIOC_s_ERR_FMT
1077 "Failed to alloc memory for host_page_buffer!\n",
1082 psge
= (char *)&ioc_init
->HostPageBufferSGE
;
1083 flags_length
= MPI_SGE_FLAGS_SIMPLE_ELEMENT
|
1084 MPI_SGE_FLAGS_SYSTEM_ADDRESS
|
1085 MPI_SGE_FLAGS_32_BIT_ADDRESSING
|
1086 MPI_SGE_FLAGS_HOST_TO_IOC
|
1087 MPI_SGE_FLAGS_END_OF_BUFFER
;
1088 if (sizeof(dma_addr_t
) == sizeof(u64
)) {
1089 flags_length
|= MPI_SGE_FLAGS_64_BIT_ADDRESSING
;
1091 flags_length
= flags_length
<< MPI_SGE_FLAGS_SHIFT
;
1092 flags_length
|= ioc
->HostPageBuffer_sz
;
1093 mpt_add_sge(psge
, flags_length
, ioc
->HostPageBuffer_dma
);
1094 ioc
->facts
.HostPageBufferSGE
= ioc_init
->HostPageBufferSGE
;
1099 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1101 * mpt_verify_adapter - Given a unique IOC identifier, set pointer to
1102 * the associated MPT adapter structure.
1103 * @iocid: IOC unique identifier (integer)
1104 * @iocpp: Pointer to pointer to IOC adapter
1106 * Returns iocid and sets iocpp.
1109 mpt_verify_adapter(int iocid
, MPT_ADAPTER
**iocpp
)
1113 list_for_each_entry(ioc
,&ioc_list
,list
) {
1114 if (ioc
->id
== iocid
) {
1124 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1126 * mpt_attach - Install a PCI intelligent MPT adapter.
1127 * @pdev: Pointer to pci_dev structure
1129 * This routine performs all the steps necessary to bring the IOC of
1130 * a MPT adapter to a OPERATIONAL state. This includes registering
1131 * memory regions, registering the interrupt, and allocating request
1132 * and reply memory pools.
1134 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1137 * Returns 0 for success, non-zero for failure.
1139 * TODO: Add support for polled controllers
1142 mpt_attach(struct pci_dev
*pdev
, const struct pci_device_id
*id
)
1146 unsigned long mem_phys
;
1154 static int mpt_ids
= 0;
1155 #ifdef CONFIG_PROC_FS
1156 struct proc_dir_entry
*dent
, *ent
;
1159 if (pci_enable_device(pdev
))
1162 dinitprintk((KERN_WARNING MYNAM
": mpt_adapter_install\n"));
1164 if (!pci_set_dma_mask(pdev
, DMA_64BIT_MASK
)) {
1165 dprintk((KERN_INFO MYNAM
1166 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n"));
1167 } else if (pci_set_dma_mask(pdev
, DMA_32BIT_MASK
)) {
1168 printk(KERN_WARNING MYNAM
": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");
1172 if (!pci_set_consistent_dma_mask(pdev
, DMA_64BIT_MASK
))
1173 dprintk((KERN_INFO MYNAM
1174 ": Using 64 bit consistent mask\n"));
1176 dprintk((KERN_INFO MYNAM
1177 ": Not using 64 bit consistent mask\n"));
1179 ioc
= kzalloc(sizeof(MPT_ADAPTER
), GFP_ATOMIC
);
1181 printk(KERN_ERR MYNAM
": ERROR - Insufficient memory to add adapter!\n");
1184 ioc
->alloc_total
= sizeof(MPT_ADAPTER
);
1185 ioc
->req_sz
= MPT_DEFAULT_FRAME_SIZE
; /* avoid div by zero! */
1186 ioc
->reply_sz
= MPT_REPLY_FRAME_SIZE
;
1189 ioc
->diagPending
= 0;
1190 spin_lock_init(&ioc
->diagLock
);
1191 spin_lock_init(&ioc
->fc_rescan_work_lock
);
1192 spin_lock_init(&ioc
->initializing_hba_lock
);
1194 /* Initialize the event logging.
1196 ioc
->eventTypes
= 0; /* None */
1197 ioc
->eventContext
= 0;
1198 ioc
->eventLogSize
= 0;
1205 ioc
->cached_fw
= NULL
;
1207 /* Initilize SCSI Config Data structure
1209 memset(&ioc
->spi_data
, 0, sizeof(SpiCfgData
));
1211 /* Initialize the running configQ head.
1213 INIT_LIST_HEAD(&ioc
->configQ
);
1215 /* Initialize the fc rport list head.
1217 INIT_LIST_HEAD(&ioc
->fc_rports
);
1219 /* Find lookup slot. */
1220 INIT_LIST_HEAD(&ioc
->list
);
1221 ioc
->id
= mpt_ids
++;
1223 mem_phys
= msize
= 0;
1225 for (ii
=0; ii
< DEVICE_COUNT_RESOURCE
; ii
++) {
1226 if (pci_resource_flags(pdev
, ii
) & PCI_BASE_ADDRESS_SPACE_IO
) {
1227 /* Get I/O space! */
1228 port
= pci_resource_start(pdev
, ii
);
1229 psize
= pci_resource_len(pdev
,ii
);
1232 mem_phys
= pci_resource_start(pdev
, ii
);
1233 msize
= pci_resource_len(pdev
,ii
);
1237 ioc
->mem_size
= msize
;
1239 if (ii
== DEVICE_COUNT_RESOURCE
) {
1240 printk(KERN_ERR MYNAM
": ERROR - MPT adapter has no memory regions defined!\n");
1245 dinitprintk((KERN_INFO MYNAM
": MPT adapter @ %lx, msize=%dd bytes\n", mem_phys
, msize
));
1246 dinitprintk((KERN_INFO MYNAM
": (port i/o @ %lx, psize=%dd bytes)\n", port
, psize
));
1249 /* Get logical ptr for PciMem0 space */
1250 /*mem = ioremap(mem_phys, msize);*/
1251 mem
= ioremap(mem_phys
, 0x100);
1253 printk(KERN_ERR MYNAM
": ERROR - Unable to map adapter memory!\n");
1258 dinitprintk((KERN_INFO MYNAM
": mem = %p, mem_phys = %lx\n", mem
, mem_phys
));
1260 dinitprintk((KERN_INFO MYNAM
": facts @ %p, pfacts[0] @ %p\n",
1261 &ioc
->facts
, &ioc
->pfacts
[0]));
1263 ioc
->mem_phys
= mem_phys
;
1264 ioc
->chip
= (SYSIF_REGS __iomem
*)mem
;
1266 /* Save Port IO values in case we need to do downloadboot */
1268 u8
*pmem
= (u8
*)port
;
1269 ioc
->pio_mem_phys
= port
;
1270 ioc
->pio_chip
= (SYSIF_REGS __iomem
*)pmem
;
1273 if (pdev
->device
== MPI_MANUFACTPAGE_DEVICEID_FC909
) {
1274 ioc
->prod_name
= "LSIFC909";
1277 else if (pdev
->device
== MPI_MANUFACTPAGE_DEVICEID_FC929
) {
1278 ioc
->prod_name
= "LSIFC929";
1281 else if (pdev
->device
== MPI_MANUFACTPAGE_DEVICEID_FC919
) {
1282 ioc
->prod_name
= "LSIFC919";
1285 else if (pdev
->device
== MPI_MANUFACTPAGE_DEVICEID_FC929X
) {
1286 pci_read_config_byte(pdev
, PCI_CLASS_REVISION
, &revision
);
1288 if (revision
< XL_929
) {
1289 ioc
->prod_name
= "LSIFC929X";
1290 /* 929X Chip Fix. Set Split transactions level
1291 * for PCIX. Set MOST bits to zero.
1293 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1295 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1297 ioc
->prod_name
= "LSIFC929XL";
1298 /* 929XL Chip Fix. Set MMRBC to 0x08.
1300 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1302 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1305 else if (pdev
->device
== MPI_MANUFACTPAGE_DEVICEID_FC919X
) {
1306 ioc
->prod_name
= "LSIFC919X";
1308 /* 919X Chip Fix. Set Split transactions level
1309 * for PCIX. Set MOST bits to zero.
1311 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1313 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1315 else if (pdev
->device
== MPI_MANUFACTPAGE_DEVICEID_FC939X
) {
1316 ioc
->prod_name
= "LSIFC939X";
1318 ioc
->errata_flag_1064
= 1;
1320 else if (pdev
->device
== MPI_MANUFACTPAGE_DEVICEID_FC949X
) {
1321 ioc
->prod_name
= "LSIFC949X";
1323 ioc
->errata_flag_1064
= 1;
1325 else if (pdev
->device
== MPI_MANUFACTPAGE_DEVICEID_FC949E
) {
1326 ioc
->prod_name
= "LSIFC949E";
1329 else if (pdev
->device
== MPI_MANUFACTPAGE_DEVID_53C1030
) {
1330 ioc
->prod_name
= "LSI53C1030";
1331 ioc
->bus_type
= SPI
;
1332 /* 1030 Chip Fix. Disable Split transactions
1333 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1335 pci_read_config_byte(pdev
, PCI_CLASS_REVISION
, &revision
);
1336 if (revision
< C0_1030
) {
1337 pci_read_config_byte(pdev
, 0x6a, &pcixcmd
);
1339 pci_write_config_byte(pdev
, 0x6a, pcixcmd
);
1342 else if (pdev
->device
== MPI_MANUFACTPAGE_DEVID_1030_53C1035
) {
1343 ioc
->prod_name
= "LSI53C1035";
1344 ioc
->bus_type
= SPI
;
1346 else if (pdev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1064
) {
1347 ioc
->prod_name
= "LSISAS1064";
1348 ioc
->bus_type
= SAS
;
1349 ioc
->errata_flag_1064
= 1;
1351 else if (pdev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1066
) {
1352 ioc
->prod_name
= "LSISAS1066";
1353 ioc
->bus_type
= SAS
;
1354 ioc
->errata_flag_1064
= 1;
1356 else if (pdev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1068
) {
1357 ioc
->prod_name
= "LSISAS1068";
1358 ioc
->bus_type
= SAS
;
1359 ioc
->errata_flag_1064
= 1;
1361 else if (pdev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1064E
) {
1362 ioc
->prod_name
= "LSISAS1064E";
1363 ioc
->bus_type
= SAS
;
1365 else if (pdev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1066E
) {
1366 ioc
->prod_name
= "LSISAS1066E";
1367 ioc
->bus_type
= SAS
;
1369 else if (pdev
->device
== MPI_MANUFACTPAGE_DEVID_SAS1068E
) {
1370 ioc
->prod_name
= "LSISAS1068E";
1371 ioc
->bus_type
= SAS
;
1374 if (ioc
->errata_flag_1064
)
1375 pci_disable_io_access(pdev
);
1377 sprintf(ioc
->name
, "ioc%d", ioc
->id
);
1379 spin_lock_init(&ioc
->FreeQlock
);
1382 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
1384 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1386 /* Set lookup ptr. */
1387 list_add_tail(&ioc
->list
, &ioc_list
);
1391 if (mpt_msi_enable
&& !pci_enable_msi(pdev
))
1392 printk(MYIOC_s_INFO_FMT
"PCI-MSI enabled\n", ioc
->name
);
1394 r
= request_irq(pdev
->irq
, mpt_interrupt
, SA_SHIRQ
, ioc
->name
, ioc
);
1398 printk(MYIOC_s_ERR_FMT
"Unable to allocate interrupt %d!\n",
1399 ioc
->name
, pdev
->irq
);
1401 printk(MYIOC_s_ERR_FMT
"Unable to allocate interrupt %s!\n",
1402 ioc
->name
, __irq_itoa(pdev
->irq
));
1404 list_del(&ioc
->list
);
1410 ioc
->pci_irq
= pdev
->irq
;
1412 pci_set_master(pdev
); /* ?? */
1413 pci_set_drvdata(pdev
, ioc
);
1416 dprintk((KERN_INFO MYNAM
": %s installed at interrupt %d\n", ioc
->name
, pdev
->irq
));
1418 dprintk((KERN_INFO MYNAM
": %s installed at interrupt %s\n", ioc
->name
, __irq_itoa(pdev
->irq
)));
1422 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1424 mpt_detect_bound_ports(ioc
, pdev
);
1426 if ((r
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_BRINGUP
,
1428 printk(KERN_WARNING MYNAM
1429 ": WARNING - %s did not initialize properly! (%d)\n",
1432 list_del(&ioc
->list
);
1433 free_irq(ioc
->pci_irq
, ioc
);
1435 pci_disable_msi(pdev
);
1437 ioc
->alt_ioc
->alt_ioc
= NULL
;
1440 pci_set_drvdata(pdev
, NULL
);
1444 /* call per device driver probe entry point */
1445 for(ii
=0; ii
<MPT_MAX_PROTOCOL_DRIVERS
; ii
++) {
1446 if(MptDeviceDriverHandlers
[ii
] &&
1447 MptDeviceDriverHandlers
[ii
]->probe
) {
1448 MptDeviceDriverHandlers
[ii
]->probe(pdev
,id
);
1452 #ifdef CONFIG_PROC_FS
1454 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1456 dent
= proc_mkdir(ioc
->name
, mpt_proc_root_dir
);
1458 ent
= create_proc_entry("info", S_IFREG
|S_IRUGO
, dent
);
1460 ent
->read_proc
= procmpt_iocinfo_read
;
1463 ent
= create_proc_entry("summary", S_IFREG
|S_IRUGO
, dent
);
1465 ent
->read_proc
= procmpt_summary_read
;
1474 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1476 * mpt_detach - Remove a PCI intelligent MPT adapter.
1477 * @pdev: Pointer to pci_dev structure
1482 mpt_detach(struct pci_dev
*pdev
)
1484 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
1488 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s/summary", ioc
->name
);
1489 remove_proc_entry(pname
, NULL
);
1490 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s/info", ioc
->name
);
1491 remove_proc_entry(pname
, NULL
);
1492 sprintf(pname
, MPT_PROCFS_MPTBASEDIR
"/%s", ioc
->name
);
1493 remove_proc_entry(pname
, NULL
);
1495 /* call per device driver remove entry point */
1496 for(ii
=0; ii
<MPT_MAX_PROTOCOL_DRIVERS
; ii
++) {
1497 if(MptDeviceDriverHandlers
[ii
] &&
1498 MptDeviceDriverHandlers
[ii
]->remove
) {
1499 MptDeviceDriverHandlers
[ii
]->remove(pdev
);
1503 /* Disable interrupts! */
1504 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
1507 synchronize_irq(pdev
->irq
);
1509 /* Clear any lingering interrupt */
1510 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1512 CHIPREG_READ32(&ioc
->chip
->IntStatus
);
1514 mpt_adapter_dispose(ioc
);
1516 pci_set_drvdata(pdev
, NULL
);
1519 /**************************************************************************
1523 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1525 * mpt_suspend - Fusion MPT base driver suspend routine.
1530 mpt_suspend(struct pci_dev
*pdev
, pm_message_t state
)
1533 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
1535 device_state
=pci_choose_state(pdev
, state
);
1537 printk(MYIOC_s_INFO_FMT
1538 "pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
1539 ioc
->name
, pdev
, pci_name(pdev
), device_state
);
1541 pci_save_state(pdev
);
1543 /* put ioc into READY_STATE */
1544 if(SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, CAN_SLEEP
)) {
1545 printk(MYIOC_s_ERR_FMT
1546 "pci-suspend: IOC msg unit reset failed!\n", ioc
->name
);
1549 /* disable interrupts */
1550 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
1553 /* Clear any lingering interrupt */
1554 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1556 pci_disable_device(pdev
);
1557 pci_set_power_state(pdev
, device_state
);
1562 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1564 * mpt_resume - Fusion MPT base driver resume routine.
1569 mpt_resume(struct pci_dev
*pdev
)
1571 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
1572 u32 device_state
= pdev
->current_state
;
1575 printk(MYIOC_s_INFO_FMT
1576 "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
1577 ioc
->name
, pdev
, pci_name(pdev
), device_state
);
1579 pci_set_power_state(pdev
, 0);
1580 pci_restore_state(pdev
);
1581 pci_enable_device(pdev
);
1583 /* enable interrupts */
1584 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, MPI_HIM_DIM
);
1587 printk(MYIOC_s_INFO_FMT
1588 "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1590 (mpt_GetIocState(ioc
, 1) >> MPI_IOC_STATE_SHIFT
),
1591 CHIPREG_READ32(&ioc
->chip
->Doorbell
));
1593 /* bring ioc to operational state */
1594 if ((recovery_state
= mpt_do_ioc_recovery(ioc
,
1595 MPT_HOSTEVENT_IOC_RECOVER
, CAN_SLEEP
)) != 0) {
1596 printk(MYIOC_s_INFO_FMT
1597 "pci-resume: Cannot recover, error:[%x]\n",
1598 ioc
->name
, recovery_state
);
1600 printk(MYIOC_s_INFO_FMT
1601 "pci-resume: success\n", ioc
->name
);
1609 mpt_signal_reset(int index
, MPT_ADAPTER
*ioc
, int reset_phase
)
1611 if ((MptDriverClass
[index
] == MPTSPI_DRIVER
&&
1612 ioc
->bus_type
!= SPI
) ||
1613 (MptDriverClass
[index
] == MPTFC_DRIVER
&&
1614 ioc
->bus_type
!= FC
) ||
1615 (MptDriverClass
[index
] == MPTSAS_DRIVER
&&
1616 ioc
->bus_type
!= SAS
))
1617 /* make sure we only call the relevant reset handler
1620 return (MptResetHandlers
[index
])(ioc
, reset_phase
);
1623 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1625 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1626 * @ioc: Pointer to MPT adapter structure
1627 * @reason: Event word / reason
1628 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1630 * This routine performs all the steps necessary to bring the IOC
1631 * to a OPERATIONAL state.
1633 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1638 * -1 if failed to get board READY
1639 * -2 if READY but IOCFacts Failed
1640 * -3 if READY but PrimeIOCFifos Failed
1641 * -4 if READY but IOCInit Failed
1644 mpt_do_ioc_recovery(MPT_ADAPTER
*ioc
, u32 reason
, int sleepFlag
)
1646 int hard_reset_done
= 0;
1647 int alt_ioc_ready
= 0;
1653 int reset_alt_ioc_active
= 0;
1655 printk(KERN_INFO MYNAM
": Initiating %s %s\n",
1656 ioc
->name
, reason
==MPT_HOSTEVENT_IOC_BRINGUP
? "bringup" : "recovery");
1658 /* Disable reply interrupts (also blocks FreeQ) */
1659 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
1663 if (ioc
->alt_ioc
->active
)
1664 reset_alt_ioc_active
= 1;
1666 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1667 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
, 0xFFFFFFFF);
1668 ioc
->alt_ioc
->active
= 0;
1672 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)
1675 if ((hard_reset_done
= MakeIocReady(ioc
, hard
, sleepFlag
)) < 0) {
1676 if (hard_reset_done
== -4) {
1677 printk(KERN_WARNING MYNAM
": %s Owned by PEER..skipping!\n",
1680 if (reset_alt_ioc_active
&& ioc
->alt_ioc
) {
1681 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1682 dprintk((KERN_INFO MYNAM
": alt-%s reply irq re-enabled\n",
1683 ioc
->alt_ioc
->name
));
1684 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
, MPI_HIM_DIM
);
1685 ioc
->alt_ioc
->active
= 1;
1689 printk(KERN_WARNING MYNAM
": %s NOT READY WARNING!\n",
1695 /* hard_reset_done = 0 if a soft reset was performed
1696 * and 1 if a hard reset was performed.
1698 if (hard_reset_done
&& reset_alt_ioc_active
&& ioc
->alt_ioc
) {
1699 if ((rc
= MakeIocReady(ioc
->alt_ioc
, 0, sleepFlag
)) == 0)
1702 printk(KERN_WARNING MYNAM
1703 ": alt-%s: Not ready WARNING!\n",
1704 ioc
->alt_ioc
->name
);
1707 for (ii
=0; ii
<5; ii
++) {
1708 /* Get IOC facts! Allow 5 retries */
1709 if ((rc
= GetIocFacts(ioc
, sleepFlag
, reason
)) == 0)
1715 dinitprintk((MYIOC_s_INFO_FMT
"Retry IocFacts failed rc=%x\n", ioc
->name
, rc
));
1717 } else if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
1718 MptDisplayIocCapabilities(ioc
);
1721 if (alt_ioc_ready
) {
1722 if ((rc
= GetIocFacts(ioc
->alt_ioc
, sleepFlag
, reason
)) != 0) {
1723 dinitprintk((MYIOC_s_INFO_FMT
"Initial Alt IocFacts failed rc=%x\n", ioc
->name
, rc
));
1724 /* Retry - alt IOC was initialized once
1726 rc
= GetIocFacts(ioc
->alt_ioc
, sleepFlag
, reason
);
1729 dinitprintk((MYIOC_s_INFO_FMT
"Retry Alt IocFacts failed rc=%x\n", ioc
->name
, rc
));
1731 reset_alt_ioc_active
= 0;
1732 } else if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
1733 MptDisplayIocCapabilities(ioc
->alt_ioc
);
1737 /* Prime reply & request queues!
1738 * (mucho alloc's) Must be done prior to
1739 * init as upper addresses are needed for init.
1740 * If fails, continue with alt-ioc processing
1742 if ((ret
== 0) && ((rc
= PrimeIocFifos(ioc
)) != 0))
1745 /* May need to check/upload firmware & data here!
1746 * If fails, continue with alt-ioc processing
1748 if ((ret
== 0) && ((rc
= SendIocInit(ioc
, sleepFlag
)) != 0))
1751 if (alt_ioc_ready
&& ((rc
= PrimeIocFifos(ioc
->alt_ioc
)) != 0)) {
1752 printk(KERN_WARNING MYNAM
": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
1753 ioc
->alt_ioc
->name
, rc
);
1755 reset_alt_ioc_active
= 0;
1758 if (alt_ioc_ready
) {
1759 if ((rc
= SendIocInit(ioc
->alt_ioc
, sleepFlag
)) != 0) {
1761 reset_alt_ioc_active
= 0;
1762 printk(KERN_WARNING MYNAM
1763 ": alt-%s: (%d) init failure WARNING!\n",
1764 ioc
->alt_ioc
->name
, rc
);
1768 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
){
1769 if (ioc
->upload_fw
) {
1770 ddlprintk((MYIOC_s_INFO_FMT
1771 "firmware upload required!\n", ioc
->name
));
1773 /* Controller is not operational, cannot do upload
1776 rc
= mpt_do_upload(ioc
, sleepFlag
);
1778 if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
) {
1780 * Maintain only one pointer to FW memory
1781 * so there will not be two attempt to
1782 * downloadboot onboard dual function
1783 * chips (mpt_adapter_disable,
1786 ioc
->cached_fw
= NULL
;
1787 ddlprintk((MYIOC_s_INFO_FMT
": mpt_upload: alt_%s has cached_fw=%p \n",
1788 ioc
->name
, ioc
->alt_ioc
->name
, ioc
->alt_ioc
->cached_fw
));
1791 printk(KERN_WARNING MYNAM
": firmware upload failure!\n");
1799 /* Enable! (reply interrupt) */
1800 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, MPI_HIM_DIM
);
1804 if (reset_alt_ioc_active
&& ioc
->alt_ioc
) {
1805 /* (re)Enable alt-IOC! (reply interrupt) */
1806 dinitprintk((KERN_INFO MYNAM
": alt-%s reply irq re-enabled\n",
1807 ioc
->alt_ioc
->name
));
1808 CHIPREG_WRITE32(&ioc
->alt_ioc
->chip
->IntMask
, MPI_HIM_DIM
);
1809 ioc
->alt_ioc
->active
= 1;
1812 /* Enable MPT base driver management of EventNotification
1813 * and EventAck handling.
1815 if ((ret
== 0) && (!ioc
->facts
.EventState
))
1816 (void) SendEventNotification(ioc
, 1); /* 1=Enable EventNotification */
1818 if (ioc
->alt_ioc
&& alt_ioc_ready
&& !ioc
->alt_ioc
->facts
.EventState
)
1819 (void) SendEventNotification(ioc
->alt_ioc
, 1); /* 1=Enable EventNotification */
1821 /* Add additional "reason" check before call to GetLanConfigPages
1822 * (combined with GetIoUnitPage2 call). This prevents a somewhat
1823 * recursive scenario; GetLanConfigPages times out, timer expired
1824 * routine calls HardResetHandler, which calls into here again,
1825 * and we try GetLanConfigPages again...
1827 if ((ret
== 0) && (reason
== MPT_HOSTEVENT_IOC_BRINGUP
)) {
1828 if (ioc
->bus_type
== SAS
) {
1830 /* clear persistency table */
1831 if(ioc
->facts
.IOCExceptions
&
1832 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL
) {
1833 ret
= mptbase_sas_persist_operation(ioc
,
1834 MPI_SAS_OP_CLEAR_NOT_PRESENT
);
1841 mpt_findImVolumes(ioc
);
1843 } else if (ioc
->bus_type
== FC
) {
1845 * Pre-fetch FC port WWN and stuff...
1846 * (FCPortPage0_t stuff)
1848 for (ii
=0; ii
< ioc
->facts
.NumberOfPorts
; ii
++) {
1849 (void) mptbase_GetFcPortPage0(ioc
, ii
);
1852 if ((ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
) &&
1853 (ioc
->lan_cnfg_page0
.Header
.PageLength
== 0)) {
1855 * Pre-fetch the ports LAN MAC address!
1856 * (LANPage1_t stuff)
1858 (void) GetLanConfigPages(ioc
);
1861 u8
*a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
1862 dprintk((MYIOC_s_INFO_FMT
"LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
1863 ioc
->name
, a
[5], a
[4], a
[3], a
[2], a
[1], a
[0] ));
1868 /* Get NVRAM and adapter maximums from SPP 0 and 2
1870 mpt_GetScsiPortSettings(ioc
, 0);
1872 /* Get version and length of SDP 1
1874 mpt_readScsiDevicePageHeaders(ioc
, 0);
1878 if (ioc
->facts
.MsgVersion
>= MPI_VERSION_01_02
)
1879 mpt_findImVolumes(ioc
);
1881 /* Check, and possibly reset, the coalescing value
1883 mpt_read_ioc_pg_1(ioc
);
1885 mpt_read_ioc_pg_4(ioc
);
1888 GetIoUnitPage2(ioc
);
1892 * Call each currently registered protocol IOC reset handler
1893 * with post-reset indication.
1894 * NOTE: If we're doing _IOC_BRINGUP, there can be no
1895 * MptResetHandlers[] registered yet.
1897 if (hard_reset_done
) {
1899 for (ii
=MPT_MAX_PROTOCOL_DRIVERS
-1; ii
; ii
--) {
1900 if ((ret
== 0) && MptResetHandlers
[ii
]) {
1901 dprintk((MYIOC_s_INFO_FMT
"Calling IOC post_reset handler #%d\n",
1903 rc
+= mpt_signal_reset(ii
, ioc
, MPT_IOC_POST_RESET
);
1907 if (alt_ioc_ready
&& MptResetHandlers
[ii
]) {
1908 drsprintk((MYIOC_s_INFO_FMT
"Calling alt-%s post_reset handler #%d\n",
1909 ioc
->name
, ioc
->alt_ioc
->name
, ii
));
1910 rc
+= mpt_signal_reset(ii
, ioc
->alt_ioc
, MPT_IOC_POST_RESET
);
1914 /* FIXME? Examine results here? */
1920 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1922 * mpt_detect_bound_ports - Search for PCI bus/dev_function
1923 * which matches PCI bus/dev_function (+/-1) for newly discovered 929,
1924 * 929X, 1030 or 1035.
1925 * @ioc: Pointer to MPT adapter structure
1926 * @pdev: Pointer to (struct pci_dev) structure
1928 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
1929 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
1932 mpt_detect_bound_ports(MPT_ADAPTER
*ioc
, struct pci_dev
*pdev
)
1934 struct pci_dev
*peer
=NULL
;
1935 unsigned int slot
= PCI_SLOT(pdev
->devfn
);
1936 unsigned int func
= PCI_FUNC(pdev
->devfn
);
1937 MPT_ADAPTER
*ioc_srch
;
1939 dprintk((MYIOC_s_INFO_FMT
"PCI device %s devfn=%x/%x,"
1940 " searching for devfn match on %x or %x\n",
1941 ioc
->name
, pci_name(pdev
), pdev
->bus
->number
,
1942 pdev
->devfn
, func
-1, func
+1));
1944 peer
= pci_get_slot(pdev
->bus
, PCI_DEVFN(slot
,func
-1));
1946 peer
= pci_get_slot(pdev
->bus
, PCI_DEVFN(slot
,func
+1));
1951 list_for_each_entry(ioc_srch
, &ioc_list
, list
) {
1952 struct pci_dev
*_pcidev
= ioc_srch
->pcidev
;
1953 if (_pcidev
== peer
) {
1954 /* Paranoia checks */
1955 if (ioc
->alt_ioc
!= NULL
) {
1956 printk(KERN_WARNING MYNAM
": Oops, already bound (%s <==> %s)!\n",
1957 ioc
->name
, ioc
->alt_ioc
->name
);
1959 } else if (ioc_srch
->alt_ioc
!= NULL
) {
1960 printk(KERN_WARNING MYNAM
": Oops, already bound (%s <==> %s)!\n",
1961 ioc_srch
->name
, ioc_srch
->alt_ioc
->name
);
1964 dprintk((KERN_INFO MYNAM
": FOUND! binding %s <==> %s\n",
1965 ioc
->name
, ioc_srch
->name
));
1966 ioc_srch
->alt_ioc
= ioc
;
1967 ioc
->alt_ioc
= ioc_srch
;
1973 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1975 * mpt_adapter_disable - Disable misbehaving MPT adapter.
1976 * @this: Pointer to MPT adapter structure
1979 mpt_adapter_disable(MPT_ADAPTER
*ioc
)
1984 if (ioc
->cached_fw
!= NULL
) {
1985 ddlprintk((KERN_INFO MYNAM
": mpt_adapter_disable: Pushing FW onto adapter\n"));
1986 if ((ret
= mpt_downloadboot(ioc
, (MpiFwHeader_t
*)ioc
->cached_fw
, NO_SLEEP
)) < 0) {
1987 printk(KERN_WARNING MYNAM
1988 ": firmware downloadboot failure (%d)!\n", ret
);
1992 /* Disable adapter interrupts! */
1993 CHIPREG_WRITE32(&ioc
->chip
->IntMask
, 0xFFFFFFFF);
1995 /* Clear any lingering interrupt */
1996 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
1998 if (ioc
->alloc
!= NULL
) {
2000 dexitprintk((KERN_INFO MYNAM
": %s.free @ %p, sz=%d bytes\n",
2001 ioc
->name
, ioc
->alloc
, ioc
->alloc_sz
));
2002 pci_free_consistent(ioc
->pcidev
, sz
,
2003 ioc
->alloc
, ioc
->alloc_dma
);
2004 ioc
->reply_frames
= NULL
;
2005 ioc
->req_frames
= NULL
;
2007 ioc
->alloc_total
-= sz
;
2010 if (ioc
->sense_buf_pool
!= NULL
) {
2011 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
2012 pci_free_consistent(ioc
->pcidev
, sz
,
2013 ioc
->sense_buf_pool
, ioc
->sense_buf_pool_dma
);
2014 ioc
->sense_buf_pool
= NULL
;
2015 ioc
->alloc_total
-= sz
;
2018 if (ioc
->events
!= NULL
){
2019 sz
= MPTCTL_EVENT_LOG_SIZE
* sizeof(MPT_IOCTL_EVENTS
);
2022 ioc
->alloc_total
-= sz
;
2025 if (ioc
->cached_fw
!= NULL
) {
2026 sz
= ioc
->facts
.FWImageSize
;
2027 pci_free_consistent(ioc
->pcidev
, sz
,
2028 ioc
->cached_fw
, ioc
->cached_fw_dma
);
2029 ioc
->cached_fw
= NULL
;
2030 ioc
->alloc_total
-= sz
;
2033 kfree(ioc
->spi_data
.nvram
);
2034 kfree(ioc
->raid_data
.pIocPg3
);
2035 ioc
->spi_data
.nvram
= NULL
;
2036 ioc
->raid_data
.pIocPg3
= NULL
;
2038 if (ioc
->spi_data
.pIocPg4
!= NULL
) {
2039 sz
= ioc
->spi_data
.IocPg4Sz
;
2040 pci_free_consistent(ioc
->pcidev
, sz
,
2041 ioc
->spi_data
.pIocPg4
,
2042 ioc
->spi_data
.IocPg4_dma
);
2043 ioc
->spi_data
.pIocPg4
= NULL
;
2044 ioc
->alloc_total
-= sz
;
2047 if (ioc
->ReqToChain
!= NULL
) {
2048 kfree(ioc
->ReqToChain
);
2049 kfree(ioc
->RequestNB
);
2050 ioc
->ReqToChain
= NULL
;
2053 kfree(ioc
->ChainToChain
);
2054 ioc
->ChainToChain
= NULL
;
2056 if (ioc
->HostPageBuffer
!= NULL
) {
2057 if((ret
= mpt_host_page_access_control(ioc
,
2058 MPI_DB_HPBAC_FREE_BUFFER
, NO_SLEEP
)) != 0) {
2059 printk(KERN_ERR MYNAM
2060 ": %s: host page buffers free failed (%d)!\n",
2063 dexitprintk((KERN_INFO MYNAM
": %s HostPageBuffer free @ %p, sz=%d bytes\n",
2064 ioc
->name
, ioc
->HostPageBuffer
, ioc
->HostPageBuffer_sz
));
2065 pci_free_consistent(ioc
->pcidev
, ioc
->HostPageBuffer_sz
,
2066 ioc
->HostPageBuffer
,
2067 ioc
->HostPageBuffer_dma
);
2068 ioc
->HostPageBuffer
= NULL
;
2069 ioc
->HostPageBuffer_sz
= 0;
2070 ioc
->alloc_total
-= ioc
->HostPageBuffer_sz
;
2074 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2076 * mpt_adapter_dispose - Free all resources associated with a MPT
2078 * @ioc: Pointer to MPT adapter structure
2080 * This routine unregisters h/w resources and frees all alloc'd memory
2081 * associated with a MPT adapter structure.
2084 mpt_adapter_dispose(MPT_ADAPTER
*ioc
)
2086 int sz_first
, sz_last
;
2091 sz_first
= ioc
->alloc_total
;
2093 mpt_adapter_disable(ioc
);
2095 if (ioc
->pci_irq
!= -1) {
2096 free_irq(ioc
->pci_irq
, ioc
);
2098 pci_disable_msi(ioc
->pcidev
);
2102 if (ioc
->memmap
!= NULL
) {
2103 iounmap(ioc
->memmap
);
2107 #if defined(CONFIG_MTRR) && 0
2108 if (ioc
->mtrr_reg
> 0) {
2109 mtrr_del(ioc
->mtrr_reg
, 0, 0);
2110 dprintk((KERN_INFO MYNAM
": %s: MTRR region de-registered\n", ioc
->name
));
2114 /* Zap the adapter lookup ptr! */
2115 list_del(&ioc
->list
);
2117 sz_last
= ioc
->alloc_total
;
2118 dprintk((KERN_INFO MYNAM
": %s: free'd %d of %d bytes\n",
2119 ioc
->name
, sz_first
-sz_last
+(int)sizeof(*ioc
), sz_first
));
2122 ioc
->alt_ioc
->alt_ioc
= NULL
;
2127 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2129 * MptDisplayIocCapabilities - Disply IOC's capacilities.
2130 * @ioc: Pointer to MPT adapter structure
2133 MptDisplayIocCapabilities(MPT_ADAPTER
*ioc
)
2137 printk(KERN_INFO
"%s: ", ioc
->name
);
2138 if (ioc
->prod_name
&& strlen(ioc
->prod_name
) > 3)
2139 printk("%s: ", ioc
->prod_name
+3);
2140 printk("Capabilities={");
2142 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_INITIATOR
) {
2143 printk("Initiator");
2147 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_TARGET
) {
2148 printk("%sTarget", i
? "," : "");
2152 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
) {
2153 printk("%sLAN", i
? "," : "");
2159 * This would probably evoke more questions than it's worth
2161 if (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_TARGET
) {
2162 printk("%sLogBusAddr", i
? "," : "");
2170 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2172 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2173 * @ioc: Pointer to MPT_ADAPTER structure
2174 * @force: Force hard KickStart of IOC
2175 * @sleepFlag: Specifies whether the process can sleep
2178 * 1 - DIAG reset and READY
2179 * 0 - READY initially OR soft reset and READY
2180 * -1 - Any failure on KickStart
2181 * -2 - Msg Unit Reset Failed
2182 * -3 - IO Unit Reset Failed
2183 * -4 - IOC owned by a PEER
2186 MakeIocReady(MPT_ADAPTER
*ioc
, int force
, int sleepFlag
)
2191 int hard_reset_done
= 0;
2196 /* Get current [raw] IOC state */
2197 ioc_state
= mpt_GetIocState(ioc
, 0);
2198 dhsprintk((KERN_INFO MYNAM
"::MakeIocReady, %s [raw] state=%08x\n", ioc
->name
, ioc_state
));
2201 * Check to see if IOC got left/stuck in doorbell handshake
2202 * grip of death. If so, hard reset the IOC.
2204 if (ioc_state
& MPI_DOORBELL_ACTIVE
) {
2206 printk(MYIOC_s_WARN_FMT
"Unexpected doorbell active!\n",
2210 /* Is it already READY? */
2211 if (!statefault
&& (ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_READY
)
2215 * Check to see if IOC is in FAULT state.
2217 if ((ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_FAULT
) {
2219 printk(MYIOC_s_WARN_FMT
"IOC is in FAULT state!!!\n",
2221 printk(KERN_WARNING
" FAULT code = %04xh\n",
2222 ioc_state
& MPI_DOORBELL_DATA_MASK
);
2226 * Hmmm... Did it get left operational?
2228 if ((ioc_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_OPERATIONAL
) {
2229 dinitprintk((MYIOC_s_INFO_FMT
"IOC operational unexpected\n",
2233 * If PCI Peer, exit.
2234 * Else, if no fault conditions are present, issue a MessageUnitReset
2235 * Else, fall through to KickStart case
2237 whoinit
= (ioc_state
& MPI_DOORBELL_WHO_INIT_MASK
) >> MPI_DOORBELL_WHO_INIT_SHIFT
;
2238 dinitprintk((KERN_INFO MYNAM
2239 ": whoinit 0x%x statefault %d force %d\n",
2240 whoinit
, statefault
, force
));
2241 if (whoinit
== MPI_WHOINIT_PCI_PEER
)
2244 if ((statefault
== 0 ) && (force
== 0)) {
2245 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
)) == 0)
2252 hard_reset_done
= KickStart(ioc
, statefault
||force
, sleepFlag
);
2253 if (hard_reset_done
< 0)
2257 * Loop here waiting for IOC to come READY.
2260 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 5; /* 5 seconds */
2262 while ((ioc_state
= mpt_GetIocState(ioc
, 1)) != MPI_IOC_STATE_READY
) {
2263 if (ioc_state
== MPI_IOC_STATE_OPERATIONAL
) {
2265 * BIOS or previous driver load left IOC in OP state.
2266 * Reset messaging FIFOs.
2268 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
)) != 0) {
2269 printk(MYIOC_s_ERR_FMT
"IOC msg unit reset failed!\n", ioc
->name
);
2272 } else if (ioc_state
== MPI_IOC_STATE_RESET
) {
2274 * Something is wrong. Try to get IOC back
2277 if ((r
= SendIocReset(ioc
, MPI_FUNCTION_IO_UNIT_RESET
, sleepFlag
)) != 0) {
2278 printk(MYIOC_s_ERR_FMT
"IO unit reset failed!\n", ioc
->name
);
2285 printk(MYIOC_s_ERR_FMT
"Wait IOC_READY state timeout(%d)!\n",
2286 ioc
->name
, (int)((ii
+5)/HZ
));
2290 if (sleepFlag
== CAN_SLEEP
) {
2291 msleep_interruptible(1);
2293 mdelay (1); /* 1 msec delay */
2298 if (statefault
< 3) {
2299 printk(MYIOC_s_INFO_FMT
"Recovered from %s\n",
2301 statefault
==1 ? "stuck handshake" : "IOC FAULT");
2304 return hard_reset_done
;
2307 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2309 * mpt_GetIocState - Get the current state of a MPT adapter.
2310 * @ioc: Pointer to MPT_ADAPTER structure
2311 * @cooked: Request raw or cooked IOC state
2313 * Returns all IOC Doorbell register bits if cooked==0, else just the
2314 * Doorbell bits in MPI_IOC_STATE_MASK.
2317 mpt_GetIocState(MPT_ADAPTER
*ioc
, int cooked
)
2322 s
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
2323 // dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
2324 sc
= s
& MPI_IOC_STATE_MASK
;
2327 ioc
->last_state
= sc
;
2329 return cooked
? sc
: s
;
2332 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2334 * GetIocFacts - Send IOCFacts request to MPT adapter.
2335 * @ioc: Pointer to MPT_ADAPTER structure
2336 * @sleepFlag: Specifies whether the process can sleep
2337 * @reason: If recovery, only update facts.
2339 * Returns 0 for success, non-zero for failure.
2342 GetIocFacts(MPT_ADAPTER
*ioc
, int sleepFlag
, int reason
)
2344 IOCFacts_t get_facts
;
2345 IOCFactsReply_t
*facts
;
2353 /* IOC *must* NOT be in RESET state! */
2354 if (ioc
->last_state
== MPI_IOC_STATE_RESET
) {
2355 printk(KERN_ERR MYNAM
": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
2361 facts
= &ioc
->facts
;
2363 /* Destination (reply area)... */
2364 reply_sz
= sizeof(*facts
);
2365 memset(facts
, 0, reply_sz
);
2367 /* Request area (get_facts on the stack right now!) */
2368 req_sz
= sizeof(get_facts
);
2369 memset(&get_facts
, 0, req_sz
);
2371 get_facts
.Function
= MPI_FUNCTION_IOC_FACTS
;
2372 /* Assert: All other get_facts fields are zero! */
2374 dinitprintk((MYIOC_s_INFO_FMT
2375 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2376 ioc
->name
, req_sz
, reply_sz
));
2378 /* No non-zero fields in the get_facts request are greater than
2379 * 1 byte in size, so we can just fire it off as is.
2381 r
= mpt_handshake_req_reply_wait(ioc
, req_sz
, (u32
*)&get_facts
,
2382 reply_sz
, (u16
*)facts
, 5 /*seconds*/, sleepFlag
);
2387 * Now byte swap (GRRR) the necessary fields before any further
2388 * inspection of reply contents.
2390 * But need to do some sanity checks on MsgLength (byte) field
2391 * to make sure we don't zero IOC's req_sz!
2393 /* Did we get a valid reply? */
2394 if (facts
->MsgLength
> offsetof(IOCFactsReply_t
, RequestFrameSize
)/sizeof(u32
)) {
2395 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
2397 * If not been here, done that, save off first WhoInit value
2399 if (ioc
->FirstWhoInit
== WHOINIT_UNKNOWN
)
2400 ioc
->FirstWhoInit
= facts
->WhoInit
;
2403 facts
->MsgVersion
= le16_to_cpu(facts
->MsgVersion
);
2404 facts
->MsgContext
= le32_to_cpu(facts
->MsgContext
);
2405 facts
->IOCExceptions
= le16_to_cpu(facts
->IOCExceptions
);
2406 facts
->IOCStatus
= le16_to_cpu(facts
->IOCStatus
);
2407 facts
->IOCLogInfo
= le32_to_cpu(facts
->IOCLogInfo
);
2408 status
= le16_to_cpu(facts
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
2409 /* CHECKME! IOCStatus, IOCLogInfo */
2411 facts
->ReplyQueueDepth
= le16_to_cpu(facts
->ReplyQueueDepth
);
2412 facts
->RequestFrameSize
= le16_to_cpu(facts
->RequestFrameSize
);
2415 * FC f/w version changed between 1.1 and 1.2
2416 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2417 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2419 if (facts
->MsgVersion
< 0x0102) {
2421 * Handle old FC f/w style, convert to new...
2423 u16 oldv
= le16_to_cpu(facts
->Reserved_0101_FWVersion
);
2424 facts
->FWVersion
.Word
=
2425 ((oldv
<<12) & 0xFF000000) |
2426 ((oldv
<<8) & 0x000FFF00);
2428 facts
->FWVersion
.Word
= le32_to_cpu(facts
->FWVersion
.Word
);
2430 facts
->ProductID
= le16_to_cpu(facts
->ProductID
);
2431 facts
->CurrentHostMfaHighAddr
=
2432 le32_to_cpu(facts
->CurrentHostMfaHighAddr
);
2433 facts
->GlobalCredits
= le16_to_cpu(facts
->GlobalCredits
);
2434 facts
->CurrentSenseBufferHighAddr
=
2435 le32_to_cpu(facts
->CurrentSenseBufferHighAddr
);
2436 facts
->CurReplyFrameSize
=
2437 le16_to_cpu(facts
->CurReplyFrameSize
);
2438 facts
->IOCCapabilities
= le32_to_cpu(facts
->IOCCapabilities
);
2441 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2442 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2443 * to 14 in MPI-1.01.0x.
2445 if (facts
->MsgLength
>= (offsetof(IOCFactsReply_t
,FWImageSize
) + 7)/4 &&
2446 facts
->MsgVersion
> 0x0100) {
2447 facts
->FWImageSize
= le32_to_cpu(facts
->FWImageSize
);
2450 sz
= facts
->FWImageSize
;
2455 facts
->FWImageSize
= sz
;
2457 if (!facts
->RequestFrameSize
) {
2458 /* Something is wrong! */
2459 printk(MYIOC_s_ERR_FMT
"IOC reported invalid 0 request size!\n",
2464 r
= sz
= facts
->BlockSize
;
2465 vv
= ((63 / (sz
* 4)) + 1) & 0x03;
2466 ioc
->NB_for_64_byte_frame
= vv
;
2472 ioc
->NBShiftFactor
= shiftFactor
;
2473 dinitprintk((MYIOC_s_INFO_FMT
"NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2474 ioc
->name
, vv
, shiftFactor
, r
));
2476 if (reason
== MPT_HOSTEVENT_IOC_BRINGUP
) {
2478 * Set values for this IOC's request & reply frame sizes,
2479 * and request & reply queue depths...
2481 ioc
->req_sz
= min(MPT_DEFAULT_FRAME_SIZE
, facts
->RequestFrameSize
* 4);
2482 ioc
->req_depth
= min_t(int, MPT_MAX_REQ_DEPTH
, facts
->GlobalCredits
);
2483 ioc
->reply_sz
= MPT_REPLY_FRAME_SIZE
;
2484 ioc
->reply_depth
= min_t(int, MPT_DEFAULT_REPLY_DEPTH
, facts
->ReplyQueueDepth
);
2486 dinitprintk((MYIOC_s_INFO_FMT
"reply_sz=%3d, reply_depth=%4d\n",
2487 ioc
->name
, ioc
->reply_sz
, ioc
->reply_depth
));
2488 dinitprintk((MYIOC_s_INFO_FMT
"req_sz =%3d, req_depth =%4d\n",
2489 ioc
->name
, ioc
->req_sz
, ioc
->req_depth
));
2491 /* Get port facts! */
2492 if ( (r
= GetPortFacts(ioc
, 0, sleepFlag
)) != 0 )
2496 printk(MYIOC_s_ERR_FMT
2497 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2498 ioc
->name
, facts
->MsgLength
, (offsetof(IOCFactsReply_t
,
2499 RequestFrameSize
)/sizeof(u32
)));
2506 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2508 * GetPortFacts - Send PortFacts request to MPT adapter.
2509 * @ioc: Pointer to MPT_ADAPTER structure
2510 * @portnum: Port number
2511 * @sleepFlag: Specifies whether the process can sleep
2513 * Returns 0 for success, non-zero for failure.
2516 GetPortFacts(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
)
2518 PortFacts_t get_pfacts
;
2519 PortFactsReply_t
*pfacts
;
2524 /* IOC *must* NOT be in RESET state! */
2525 if (ioc
->last_state
== MPI_IOC_STATE_RESET
) {
2526 printk(KERN_ERR MYNAM
": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n",
2532 pfacts
= &ioc
->pfacts
[portnum
];
2534 /* Destination (reply area)... */
2535 reply_sz
= sizeof(*pfacts
);
2536 memset(pfacts
, 0, reply_sz
);
2538 /* Request area (get_pfacts on the stack right now!) */
2539 req_sz
= sizeof(get_pfacts
);
2540 memset(&get_pfacts
, 0, req_sz
);
2542 get_pfacts
.Function
= MPI_FUNCTION_PORT_FACTS
;
2543 get_pfacts
.PortNumber
= portnum
;
2544 /* Assert: All other get_pfacts fields are zero! */
2546 dinitprintk((MYIOC_s_INFO_FMT
"Sending get PortFacts(%d) request\n",
2547 ioc
->name
, portnum
));
2549 /* No non-zero fields in the get_pfacts request are greater than
2550 * 1 byte in size, so we can just fire it off as is.
2552 ii
= mpt_handshake_req_reply_wait(ioc
, req_sz
, (u32
*)&get_pfacts
,
2553 reply_sz
, (u16
*)pfacts
, 5 /*seconds*/, sleepFlag
);
2557 /* Did we get a valid reply? */
2559 /* Now byte swap the necessary fields in the response. */
2560 pfacts
->MsgContext
= le32_to_cpu(pfacts
->MsgContext
);
2561 pfacts
->IOCStatus
= le16_to_cpu(pfacts
->IOCStatus
);
2562 pfacts
->IOCLogInfo
= le32_to_cpu(pfacts
->IOCLogInfo
);
2563 pfacts
->MaxDevices
= le16_to_cpu(pfacts
->MaxDevices
);
2564 pfacts
->PortSCSIID
= le16_to_cpu(pfacts
->PortSCSIID
);
2565 pfacts
->ProtocolFlags
= le16_to_cpu(pfacts
->ProtocolFlags
);
2566 pfacts
->MaxPostedCmdBuffers
= le16_to_cpu(pfacts
->MaxPostedCmdBuffers
);
2567 pfacts
->MaxPersistentIDs
= le16_to_cpu(pfacts
->MaxPersistentIDs
);
2568 pfacts
->MaxLanBuckets
= le16_to_cpu(pfacts
->MaxLanBuckets
);
2573 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2575 * SendIocInit - Send IOCInit request to MPT adapter.
2576 * @ioc: Pointer to MPT_ADAPTER structure
2577 * @sleepFlag: Specifies whether the process can sleep
2579 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2581 * Returns 0 for success, non-zero for failure.
2584 SendIocInit(MPT_ADAPTER
*ioc
, int sleepFlag
)
2587 MPIDefaultReply_t init_reply
;
2593 memset(&ioc_init
, 0, sizeof(ioc_init
));
2594 memset(&init_reply
, 0, sizeof(init_reply
));
2596 ioc_init
.WhoInit
= MPI_WHOINIT_HOST_DRIVER
;
2597 ioc_init
.Function
= MPI_FUNCTION_IOC_INIT
;
2599 /* If we are in a recovery mode and we uploaded the FW image,
2600 * then this pointer is not NULL. Skip the upload a second time.
2601 * Set this flag if cached_fw set for either IOC.
2603 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)
2607 ddlprintk((MYIOC_s_INFO_FMT
"upload_fw %d facts.Flags=%x\n",
2608 ioc
->name
, ioc
->upload_fw
, ioc
->facts
.Flags
));
2610 if(ioc
->bus_type
== SAS
)
2611 ioc_init
.MaxDevices
= ioc
->facts
.MaxDevices
;
2612 else if(ioc
->bus_type
== FC
)
2613 ioc_init
.MaxDevices
= MPT_MAX_FC_DEVICES
;
2615 ioc_init
.MaxDevices
= MPT_MAX_SCSI_DEVICES
;
2616 ioc_init
.MaxBuses
= MPT_MAX_BUS
;
2617 dinitprintk((MYIOC_s_INFO_FMT
"facts.MsgVersion=%x\n",
2618 ioc
->name
, ioc
->facts
.MsgVersion
));
2619 if (ioc
->facts
.MsgVersion
>= MPI_VERSION_01_05
) {
2620 // set MsgVersion and HeaderVersion host driver was built with
2621 ioc_init
.MsgVersion
= cpu_to_le16(MPI_VERSION
);
2622 ioc_init
.HeaderVersion
= cpu_to_le16(MPI_HEADER_VERSION
);
2624 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT
) {
2625 ioc_init
.HostPageBufferSGE
= ioc
->facts
.HostPageBufferSGE
;
2626 } else if(mpt_host_page_alloc(ioc
, &ioc_init
))
2629 ioc_init
.ReplyFrameSize
= cpu_to_le16(ioc
->reply_sz
); /* in BYTES */
2631 if (sizeof(dma_addr_t
) == sizeof(u64
)) {
2632 /* Save the upper 32-bits of the request
2633 * (reply) and sense buffers.
2635 ioc_init
.HostMfaHighAddr
= cpu_to_le32((u32
)((u64
)ioc
->alloc_dma
>> 32));
2636 ioc_init
.SenseBufferHighAddr
= cpu_to_le32((u32
)((u64
)ioc
->sense_buf_pool_dma
>> 32));
2638 /* Force 32-bit addressing */
2639 ioc_init
.HostMfaHighAddr
= cpu_to_le32(0);
2640 ioc_init
.SenseBufferHighAddr
= cpu_to_le32(0);
2643 ioc
->facts
.CurrentHostMfaHighAddr
= ioc_init
.HostMfaHighAddr
;
2644 ioc
->facts
.CurrentSenseBufferHighAddr
= ioc_init
.SenseBufferHighAddr
;
2645 ioc
->facts
.MaxDevices
= ioc_init
.MaxDevices
;
2646 ioc
->facts
.MaxBuses
= ioc_init
.MaxBuses
;
2648 dhsprintk((MYIOC_s_INFO_FMT
"Sending IOCInit (req @ %p)\n",
2649 ioc
->name
, &ioc_init
));
2651 r
= mpt_handshake_req_reply_wait(ioc
, sizeof(IOCInit_t
), (u32
*)&ioc_init
,
2652 sizeof(MPIDefaultReply_t
), (u16
*)&init_reply
, 10 /*seconds*/, sleepFlag
);
2654 printk(MYIOC_s_ERR_FMT
"Sending IOCInit failed(%d)!\n",ioc
->name
, r
);
2658 /* No need to byte swap the multibyte fields in the reply
2659 * since we don't even look at it's contents.
2662 dhsprintk((MYIOC_s_INFO_FMT
"Sending PortEnable (req @ %p)\n",
2663 ioc
->name
, &ioc_init
));
2665 if ((r
= SendPortEnable(ioc
, 0, sleepFlag
)) != 0) {
2666 printk(MYIOC_s_ERR_FMT
"Sending PortEnable failed(%d)!\n",ioc
->name
, r
);
2670 /* YIKES! SUPER IMPORTANT!!!
2671 * Poll IocState until _OPERATIONAL while IOC is doing
2672 * LoopInit and TargetDiscovery!
2675 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 60; /* 60 seconds */
2676 state
= mpt_GetIocState(ioc
, 1);
2677 while (state
!= MPI_IOC_STATE_OPERATIONAL
&& --cntdn
) {
2678 if (sleepFlag
== CAN_SLEEP
) {
2679 msleep_interruptible(1);
2685 printk(MYIOC_s_ERR_FMT
"Wait IOC_OP state timeout(%d)!\n",
2686 ioc
->name
, (int)((count
+5)/HZ
));
2690 state
= mpt_GetIocState(ioc
, 1);
2693 dinitprintk((MYIOC_s_INFO_FMT
"INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
2699 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2701 * SendPortEnable - Send PortEnable request to MPT adapter port.
2702 * @ioc: Pointer to MPT_ADAPTER structure
2703 * @portnum: Port number to enable
2704 * @sleepFlag: Specifies whether the process can sleep
2706 * Send PortEnable to bring IOC to OPERATIONAL state.
2708 * Returns 0 for success, non-zero for failure.
2711 SendPortEnable(MPT_ADAPTER
*ioc
, int portnum
, int sleepFlag
)
2713 PortEnable_t port_enable
;
2714 MPIDefaultReply_t reply_buf
;
2719 /* Destination... */
2720 reply_sz
= sizeof(MPIDefaultReply_t
);
2721 memset(&reply_buf
, 0, reply_sz
);
2723 req_sz
= sizeof(PortEnable_t
);
2724 memset(&port_enable
, 0, req_sz
);
2726 port_enable
.Function
= MPI_FUNCTION_PORT_ENABLE
;
2727 port_enable
.PortNumber
= portnum
;
2728 /* port_enable.ChainOffset = 0; */
2729 /* port_enable.MsgFlags = 0; */
2730 /* port_enable.MsgContext = 0; */
2732 dinitprintk((MYIOC_s_INFO_FMT
"Sending Port(%d)Enable (req @ %p)\n",
2733 ioc
->name
, portnum
, &port_enable
));
2735 /* RAID FW may take a long time to enable
2737 if (((ioc
->facts
.ProductID
& MPI_FW_HEADER_PID_PROD_MASK
)
2738 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI
) ||
2739 (ioc
->bus_type
== SAS
)) {
2740 rc
= mpt_handshake_req_reply_wait(ioc
, req_sz
,
2741 (u32
*)&port_enable
, reply_sz
, (u16
*)&reply_buf
,
2742 300 /*seconds*/, sleepFlag
);
2744 rc
= mpt_handshake_req_reply_wait(ioc
, req_sz
,
2745 (u32
*)&port_enable
, reply_sz
, (u16
*)&reply_buf
,
2746 30 /*seconds*/, sleepFlag
);
2752 * ioc: Pointer to MPT_ADAPTER structure
2753 * size - total FW bytes
2756 mpt_alloc_fw_memory(MPT_ADAPTER
*ioc
, int size
)
2759 return; /* use already allocated memory */
2760 if (ioc
->alt_ioc
&& ioc
->alt_ioc
->cached_fw
) {
2761 ioc
->cached_fw
= ioc
->alt_ioc
->cached_fw
; /* use alt_ioc's memory */
2762 ioc
->cached_fw_dma
= ioc
->alt_ioc
->cached_fw_dma
;
2764 if ( (ioc
->cached_fw
= pci_alloc_consistent(ioc
->pcidev
, size
, &ioc
->cached_fw_dma
) ) )
2765 ioc
->alloc_total
+= size
;
2769 * If alt_img is NULL, delete from ioc structure.
2770 * Else, delete a secondary image in same format.
2773 mpt_free_fw_memory(MPT_ADAPTER
*ioc
)
2777 sz
= ioc
->facts
.FWImageSize
;
2778 dinitprintk((KERN_INFO MYNAM
"free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
2779 ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, sz
, sz
));
2780 pci_free_consistent(ioc
->pcidev
, sz
,
2781 ioc
->cached_fw
, ioc
->cached_fw_dma
);
2782 ioc
->cached_fw
= NULL
;
2788 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2790 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
2791 * @ioc: Pointer to MPT_ADAPTER structure
2792 * @sleepFlag: Specifies whether the process can sleep
2794 * Returns 0 for success, >0 for handshake failure
2795 * <0 for fw upload failure.
2797 * Remark: If bound IOC and a successful FWUpload was performed
2798 * on the bound IOC, the second image is discarded
2799 * and memory is free'd. Both channels must upload to prevent
2800 * IOC from running in degraded mode.
2803 mpt_do_upload(MPT_ADAPTER
*ioc
, int sleepFlag
)
2805 u8 request
[ioc
->req_sz
];
2806 u8 reply
[sizeof(FWUploadReply_t
)];
2807 FWUpload_t
*prequest
;
2808 FWUploadReply_t
*preply
;
2809 FWUploadTCSGE_t
*ptcsge
;
2812 int ii
, sz
, reply_sz
;
2815 /* If the image size is 0, we are done.
2817 if ((sz
= ioc
->facts
.FWImageSize
) == 0)
2820 mpt_alloc_fw_memory(ioc
, sz
);
2822 dinitprintk((KERN_INFO MYNAM
": FW Image @ %p[%p], sz=%d[%x] bytes\n",
2823 ioc
->cached_fw
, (void *)(ulong
)ioc
->cached_fw_dma
, sz
, sz
));
2825 if (ioc
->cached_fw
== NULL
) {
2831 prequest
= (FWUpload_t
*)&request
;
2832 preply
= (FWUploadReply_t
*)&reply
;
2834 /* Destination... */
2835 memset(prequest
, 0, ioc
->req_sz
);
2837 reply_sz
= sizeof(reply
);
2838 memset(preply
, 0, reply_sz
);
2840 prequest
->ImageType
= MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM
;
2841 prequest
->Function
= MPI_FUNCTION_FW_UPLOAD
;
2843 ptcsge
= (FWUploadTCSGE_t
*) &prequest
->SGL
;
2844 ptcsge
->DetailsLength
= 12;
2845 ptcsge
->Flags
= MPI_SGE_FLAGS_TRANSACTION_ELEMENT
;
2846 ptcsge
->ImageSize
= cpu_to_le32(sz
);
2848 sgeoffset
= sizeof(FWUpload_t
) - sizeof(SGE_MPI_UNION
) + sizeof(FWUploadTCSGE_t
);
2850 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_READ
| sz
;
2851 mpt_add_sge(&request
[sgeoffset
], flagsLength
, ioc
->cached_fw_dma
);
2853 sgeoffset
+= sizeof(u32
) + sizeof(dma_addr_t
);
2854 dinitprintk((KERN_INFO MYNAM
": Sending FW Upload (req @ %p) sgeoffset=%d \n",
2855 prequest
, sgeoffset
));
2856 DBG_DUMP_FW_REQUEST_FRAME(prequest
)
2858 ii
= mpt_handshake_req_reply_wait(ioc
, sgeoffset
, (u32
*)prequest
,
2859 reply_sz
, (u16
*)preply
, 65 /*seconds*/, sleepFlag
);
2861 dinitprintk((KERN_INFO MYNAM
": FW Upload completed rc=%x \n", ii
));
2863 cmdStatus
= -EFAULT
;
2865 /* Handshake transfer was complete and successful.
2866 * Check the Reply Frame.
2868 int status
, transfer_sz
;
2869 status
= le16_to_cpu(preply
->IOCStatus
);
2870 if (status
== MPI_IOCSTATUS_SUCCESS
) {
2871 transfer_sz
= le32_to_cpu(preply
->ActualImageSize
);
2872 if (transfer_sz
== sz
)
2876 dinitprintk((MYIOC_s_INFO_FMT
": do_upload cmdStatus=%d \n",
2877 ioc
->name
, cmdStatus
));
2882 ddlprintk((MYIOC_s_INFO_FMT
": fw upload failed, freeing image \n",
2884 mpt_free_fw_memory(ioc
);
2890 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2892 * mpt_downloadboot - DownloadBoot code
2893 * @ioc: Pointer to MPT_ADAPTER structure
2894 * @flag: Specify which part of IOC memory is to be uploaded.
2895 * @sleepFlag: Specifies whether the process can sleep
2897 * FwDownloadBoot requires Programmed IO access.
2899 * Returns 0 for success
2900 * -1 FW Image size is 0
2901 * -2 No valid cached_fw Pointer
2902 * <0 for fw upload failure.
2905 mpt_downloadboot(MPT_ADAPTER
*ioc
, MpiFwHeader_t
*pFwHeader
, int sleepFlag
)
2907 MpiExtImageHeader_t
*pExtImage
;
2917 ddlprintk((MYIOC_s_INFO_FMT
"downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
2918 ioc
->name
, pFwHeader
->ImageSize
, pFwHeader
->ImageSize
, pFwHeader
));
2920 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
2921 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
2922 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
2923 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
2924 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
2925 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
2927 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, (MPI_DIAG_PREVENT_IOC_BOOT
| MPI_DIAG_DISABLE_ARM
));
2930 if (sleepFlag
== CAN_SLEEP
) {
2931 msleep_interruptible(1);
2936 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
2937 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_RESET_ADAPTER
);
2939 for (count
= 0; count
< 30; count
++) {
2940 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
2941 if (!(diag0val
& MPI_DIAG_RESET_ADAPTER
)) {
2942 ddlprintk((MYIOC_s_INFO_FMT
"RESET_ADAPTER cleared, count=%d\n",
2947 if (sleepFlag
== CAN_SLEEP
) {
2948 msleep_interruptible (100);
2954 if ( count
== 30 ) {
2955 ddlprintk((MYIOC_s_INFO_FMT
"downloadboot failed! "
2956 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
2957 ioc
->name
, diag0val
));
2961 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
2962 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
2963 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
2964 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
2965 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
2966 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
2968 /* Set the DiagRwEn and Disable ARM bits */
2969 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, (MPI_DIAG_RW_ENABLE
| MPI_DIAG_DISABLE_ARM
));
2971 fwSize
= (pFwHeader
->ImageSize
+ 3)/4;
2972 ptrFw
= (u32
*) pFwHeader
;
2974 /* Write the LoadStartAddress to the DiagRw Address Register
2975 * using Programmed IO
2977 if (ioc
->errata_flag_1064
)
2978 pci_enable_io_access(ioc
->pcidev
);
2980 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, pFwHeader
->LoadStartAddress
);
2981 ddlprintk((MYIOC_s_INFO_FMT
"LoadStart addr written 0x%x \n",
2982 ioc
->name
, pFwHeader
->LoadStartAddress
));
2984 ddlprintk((MYIOC_s_INFO_FMT
"Write FW Image: 0x%x bytes @ %p\n",
2985 ioc
->name
, fwSize
*4, ptrFw
));
2987 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, *ptrFw
++);
2990 nextImage
= pFwHeader
->NextImageHeaderOffset
;
2992 pExtImage
= (MpiExtImageHeader_t
*) ((char *)pFwHeader
+ nextImage
);
2994 load_addr
= pExtImage
->LoadStartAddress
;
2996 fwSize
= (pExtImage
->ImageSize
+ 3) >> 2;
2997 ptrFw
= (u32
*)pExtImage
;
2999 ddlprintk((MYIOC_s_INFO_FMT
"Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3000 ioc
->name
, fwSize
*4, fwSize
*4, ptrFw
, load_addr
));
3001 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, load_addr
);
3004 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, *ptrFw
++);
3006 nextImage
= pExtImage
->NextImageHeaderOffset
;
3009 /* Write the IopResetVectorRegAddr */
3010 ddlprintk((MYIOC_s_INFO_FMT
"Write IopResetVector Addr=%x! \n", ioc
->name
, pFwHeader
->IopResetRegAddr
));
3011 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, pFwHeader
->IopResetRegAddr
);
3013 /* Write the IopResetVectorValue */
3014 ddlprintk((MYIOC_s_INFO_FMT
"Write IopResetVector Value=%x! \n", ioc
->name
, pFwHeader
->IopResetVectorValue
));
3015 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, pFwHeader
->IopResetVectorValue
);
3017 /* Clear the internal flash bad bit - autoincrementing register,
3018 * so must do two writes.
3020 if (ioc
->bus_type
== SPI
) {
3022 * 1030 and 1035 H/W errata, workaround to access
3023 * the ClearFlashBadSignatureBit
3025 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, 0x3F000000);
3026 diagRwData
= CHIPREG_PIO_READ32(&ioc
->pio_chip
->DiagRwData
);
3027 diagRwData
|= 0x40000000;
3028 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwAddress
, 0x3F000000);
3029 CHIPREG_PIO_WRITE32(&ioc
->pio_chip
->DiagRwData
, diagRwData
);
3031 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3032 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3033 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
|
3034 MPI_DIAG_CLEAR_FLASH_BAD_SIG
);
3037 if (sleepFlag
== CAN_SLEEP
) {
3038 msleep_interruptible (1);
3044 if (ioc
->errata_flag_1064
)
3045 pci_disable_io_access(ioc
->pcidev
);
3047 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3048 ddlprintk((MYIOC_s_INFO_FMT
"downloadboot diag0val=%x, "
3049 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3050 ioc
->name
, diag0val
));
3051 diag0val
&= ~(MPI_DIAG_PREVENT_IOC_BOOT
| MPI_DIAG_DISABLE_ARM
| MPI_DIAG_RW_ENABLE
);
3052 ddlprintk((MYIOC_s_INFO_FMT
"downloadboot now diag0val=%x\n",
3053 ioc
->name
, diag0val
));
3054 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
);
3056 /* Write 0xFF to reset the sequencer */
3057 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3059 if (ioc
->bus_type
== SAS
) {
3060 ioc_state
= mpt_GetIocState(ioc
, 0);
3061 if ( (GetIocFacts(ioc
, sleepFlag
,
3062 MPT_HOSTEVENT_IOC_BRINGUP
)) != 0 ) {
3063 ddlprintk((MYIOC_s_INFO_FMT
"GetIocFacts failed: IocState=%x\n",
3064 ioc
->name
, ioc_state
));
3069 for (count
=0; count
<HZ
*20; count
++) {
3070 if ((ioc_state
= mpt_GetIocState(ioc
, 0)) & MPI_IOC_STATE_READY
) {
3071 ddlprintk((MYIOC_s_INFO_FMT
"downloadboot successful! (count=%d) IocState=%x\n",
3072 ioc
->name
, count
, ioc_state
));
3073 if (ioc
->bus_type
== SAS
) {
3076 if ((SendIocInit(ioc
, sleepFlag
)) != 0) {
3077 ddlprintk((MYIOC_s_INFO_FMT
"downloadboot: SendIocInit failed\n",
3081 ddlprintk((MYIOC_s_INFO_FMT
"downloadboot: SendIocInit successful\n",
3085 if (sleepFlag
== CAN_SLEEP
) {
3086 msleep_interruptible (10);
3091 ddlprintk((MYIOC_s_INFO_FMT
"downloadboot failed! IocState=%x\n",
3092 ioc
->name
, ioc_state
));
3096 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3098 * KickStart - Perform hard reset of MPT adapter.
3099 * @ioc: Pointer to MPT_ADAPTER structure
3100 * @force: Force hard reset
3101 * @sleepFlag: Specifies whether the process can sleep
3103 * This routine places MPT adapter in diagnostic mode via the
3104 * WriteSequence register, and then performs a hard reset of adapter
3105 * via the Diagnostic register.
3107 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3108 * or NO_SLEEP (interrupt thread, use mdelay)
3109 * force - 1 if doorbell active, board fault state
3110 * board operational, IOC_RECOVERY or
3111 * IOC_BRINGUP and there is an alt_ioc.
3115 * 1 - hard reset, READY
3116 * 0 - no reset due to History bit, READY
3117 * -1 - no reset due to History bit but not READY
3118 * OR reset but failed to come READY
3119 * -2 - no reset, could not enter DIAG mode
3120 * -3 - reset but bad FW bit
3123 KickStart(MPT_ADAPTER
*ioc
, int force
, int sleepFlag
)
3125 int hard_reset_done
= 0;
3129 dinitprintk((KERN_WARNING MYNAM
": KickStarting %s!\n", ioc
->name
));
3130 if (ioc
->bus_type
== SPI
) {
3131 /* Always issue a Msg Unit Reset first. This will clear some
3132 * SCSI bus hang conditions.
3134 SendIocReset(ioc
, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
, sleepFlag
);
3136 if (sleepFlag
== CAN_SLEEP
) {
3137 msleep_interruptible (1000);
3143 hard_reset_done
= mpt_diag_reset(ioc
, force
, sleepFlag
);
3144 if (hard_reset_done
< 0)
3145 return hard_reset_done
;
3147 dinitprintk((MYIOC_s_INFO_FMT
"Diagnostic reset successful!\n",
3150 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 2; /* 2 seconds */
3151 for (cnt
=0; cnt
<cntdn
; cnt
++) {
3152 ioc_state
= mpt_GetIocState(ioc
, 1);
3153 if ((ioc_state
== MPI_IOC_STATE_READY
) || (ioc_state
== MPI_IOC_STATE_OPERATIONAL
)) {
3154 dinitprintk((MYIOC_s_INFO_FMT
"KickStart successful! (cnt=%d)\n",
3156 return hard_reset_done
;
3158 if (sleepFlag
== CAN_SLEEP
) {
3159 msleep_interruptible (10);
3165 printk(MYIOC_s_ERR_FMT
"Failed to come READY after reset! IocState=%x\n",
3166 ioc
->name
, ioc_state
);
3170 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3172 * mpt_diag_reset - Perform hard reset of the adapter.
3173 * @ioc: Pointer to MPT_ADAPTER structure
3174 * @ignore: Set if to honor and clear to ignore
3175 * the reset history bit
3176 * @sleepflag: CAN_SLEEP if called in a non-interrupt thread,
3177 * else set to NO_SLEEP (use mdelay instead)
3179 * This routine places the adapter in diagnostic mode via the
3180 * WriteSequence register and then performs a hard reset of adapter
3181 * via the Diagnostic register. Adapter should be in ready state
3182 * upon successful completion.
3184 * Returns: 1 hard reset successful
3185 * 0 no reset performed because reset history bit set
3186 * -2 enabling diagnostic mode failed
3187 * -3 diagnostic reset failed
3190 mpt_diag_reset(MPT_ADAPTER
*ioc
, int ignore
, int sleepFlag
)
3194 int hard_reset_done
= 0;
3200 /* Clear any existing interrupts */
3201 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
3203 /* Use "Diagnostic reset" method! (only thing available!) */
3204 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3208 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
3209 dprintk((MYIOC_s_INFO_FMT
"DbG1: diag0=%08x, diag1=%08x\n",
3210 ioc
->name
, diag0val
, diag1val
));
3213 /* Do the reset if we are told to ignore the reset history
3214 * or if the reset history is 0
3216 if (ignore
|| !(diag0val
& MPI_DIAG_RESET_HISTORY
)) {
3217 while ((diag0val
& MPI_DIAG_DRWE
) == 0) {
3218 /* Write magic sequence to WriteSequence register
3219 * Loop until in diagnostic mode
3221 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3222 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3223 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3224 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3225 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3226 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3229 if (sleepFlag
== CAN_SLEEP
) {
3230 msleep_interruptible (100);
3237 printk(MYIOC_s_ERR_FMT
"Enable Diagnostic mode FAILED! (%02xh)\n",
3238 ioc
->name
, diag0val
);
3243 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3245 dprintk((MYIOC_s_INFO_FMT
"Wrote magic DiagWriteEn sequence (%x)\n",
3246 ioc
->name
, diag0val
));
3251 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
3252 dprintk((MYIOC_s_INFO_FMT
"DbG2: diag0=%08x, diag1=%08x\n",
3253 ioc
->name
, diag0val
, diag1val
));
3256 * Disable the ARM (Bug fix)
3259 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_DISABLE_ARM
);
3263 * Now hit the reset bit in the Diagnostic register
3264 * (THE BIG HAMMER!) (Clears DRWE bit).
3266 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
| MPI_DIAG_RESET_ADAPTER
);
3267 hard_reset_done
= 1;
3268 dprintk((MYIOC_s_INFO_FMT
"Diagnostic reset performed\n",
3272 * Call each currently registered protocol IOC reset handler
3273 * with pre-reset indication.
3274 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3275 * MptResetHandlers[] registered yet.
3281 for (ii
=MPT_MAX_PROTOCOL_DRIVERS
-1; ii
; ii
--) {
3282 if (MptResetHandlers
[ii
]) {
3283 dprintk((MYIOC_s_INFO_FMT
"Calling IOC pre_reset handler #%d\n",
3285 r
+= mpt_signal_reset(ii
, ioc
, MPT_IOC_PRE_RESET
);
3287 dprintk((MYIOC_s_INFO_FMT
"Calling alt-%s pre_reset handler #%d\n",
3288 ioc
->name
, ioc
->alt_ioc
->name
, ii
));
3289 r
+= mpt_signal_reset(ii
, ioc
->alt_ioc
, MPT_IOC_PRE_RESET
);
3293 /* FIXME? Examine results here? */
3296 if (ioc
->cached_fw
) {
3297 /* If the DownloadBoot operation fails, the
3298 * IOC will be left unusable. This is a fatal error
3299 * case. _diag_reset will return < 0
3301 for (count
= 0; count
< 30; count
++) {
3302 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3303 if (!(diag0val
& MPI_DIAG_RESET_ADAPTER
)) {
3308 if (sleepFlag
== CAN_SLEEP
) {
3309 msleep_interruptible (1000);
3314 if ((count
= mpt_downloadboot(ioc
,
3315 (MpiFwHeader_t
*)ioc
->cached_fw
, sleepFlag
)) < 0) {
3316 printk(KERN_WARNING MYNAM
3317 ": firmware downloadboot failure (%d)!\n", count
);
3321 /* Wait for FW to reload and for board
3322 * to go to the READY state.
3323 * Maximum wait is 60 seconds.
3324 * If fail, no error will check again
3325 * with calling program.
3327 for (count
= 0; count
< 60; count
++) {
3328 doorbell
= CHIPREG_READ32(&ioc
->chip
->Doorbell
);
3329 doorbell
&= MPI_IOC_STATE_MASK
;
3331 if (doorbell
== MPI_IOC_STATE_READY
) {
3336 if (sleepFlag
== CAN_SLEEP
) {
3337 msleep_interruptible (1000);
3345 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3348 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
3349 dprintk((MYIOC_s_INFO_FMT
"DbG3: diag0=%08x, diag1=%08x\n",
3350 ioc
->name
, diag0val
, diag1val
));
3353 /* Clear RESET_HISTORY bit! Place board in the
3354 * diagnostic mode to update the diag register.
3356 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3358 while ((diag0val
& MPI_DIAG_DRWE
) == 0) {
3359 /* Write magic sequence to WriteSequence register
3360 * Loop until in diagnostic mode
3362 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFF);
3363 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_1ST_KEY_VALUE
);
3364 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_2ND_KEY_VALUE
);
3365 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_3RD_KEY_VALUE
);
3366 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_4TH_KEY_VALUE
);
3367 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, MPI_WRSEQ_5TH_KEY_VALUE
);
3370 if (sleepFlag
== CAN_SLEEP
) {
3371 msleep_interruptible (100);
3378 printk(MYIOC_s_ERR_FMT
"Enable Diagnostic mode FAILED! (%02xh)\n",
3379 ioc
->name
, diag0val
);
3382 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3384 diag0val
&= ~MPI_DIAG_RESET_HISTORY
;
3385 CHIPREG_WRITE32(&ioc
->chip
->Diagnostic
, diag0val
);
3386 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3387 if (diag0val
& MPI_DIAG_RESET_HISTORY
) {
3388 printk(MYIOC_s_WARN_FMT
"ResetHistory bit failed to clear!\n",
3392 /* Disable Diagnostic Mode
3394 CHIPREG_WRITE32(&ioc
->chip
->WriteSequence
, 0xFFFFFFFF);
3396 /* Check FW reload status flags.
3398 diag0val
= CHIPREG_READ32(&ioc
->chip
->Diagnostic
);
3399 if (diag0val
& (MPI_DIAG_FLASH_BAD_SIG
| MPI_DIAG_RESET_ADAPTER
| MPI_DIAG_DISABLE_ARM
)) {
3400 printk(MYIOC_s_ERR_FMT
"Diagnostic reset FAILED! (%02xh)\n",
3401 ioc
->name
, diag0val
);
3407 diag1val
= CHIPREG_READ32(&ioc
->alt_ioc
->chip
->Diagnostic
);
3408 dprintk((MYIOC_s_INFO_FMT
"DbG4: diag0=%08x, diag1=%08x\n",
3409 ioc
->name
, diag0val
, diag1val
));
3413 * Reset flag that says we've enabled event notification
3415 ioc
->facts
.EventState
= 0;
3418 ioc
->alt_ioc
->facts
.EventState
= 0;
3420 return hard_reset_done
;
3423 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3425 * SendIocReset - Send IOCReset request to MPT adapter.
3426 * @ioc: Pointer to MPT_ADAPTER structure
3427 * @reset_type: reset type, expected values are
3428 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3430 * Send IOCReset request to the MPT adapter.
3432 * Returns 0 for success, non-zero for failure.
3435 SendIocReset(MPT_ADAPTER
*ioc
, u8 reset_type
, int sleepFlag
)
3441 drsprintk((KERN_INFO MYNAM
": %s: Sending IOC reset(0x%02x)!\n",
3442 ioc
->name
, reset_type
));
3443 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, reset_type
<<MPI_DOORBELL_FUNCTION_SHIFT
);
3444 if ((r
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
3447 /* FW ACK'd request, wait for READY state
3450 cntdn
= ((sleepFlag
== CAN_SLEEP
) ? HZ
: 1000) * 15; /* 15 seconds */
3452 while ((state
= mpt_GetIocState(ioc
, 1)) != MPI_IOC_STATE_READY
) {
3456 if (sleepFlag
!= CAN_SLEEP
)
3459 printk(KERN_ERR MYNAM
": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
3460 ioc
->name
, (int)((count
+5)/HZ
));
3464 if (sleepFlag
== CAN_SLEEP
) {
3465 msleep_interruptible(1);
3467 mdelay (1); /* 1 msec delay */
3472 * Cleanup all event stuff for this IOC; re-issue EventNotification
3473 * request if needed.
3475 if (ioc
->facts
.Function
)
3476 ioc
->facts
.EventState
= 0;
3481 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3483 * initChainBuffers - Allocate memory for and initialize
3484 * chain buffers, chain buffer control arrays and spinlock.
3485 * @hd: Pointer to MPT_SCSI_HOST structure
3486 * @init: If set, initialize the spin lock.
3489 initChainBuffers(MPT_ADAPTER
*ioc
)
3492 int sz
, ii
, num_chain
;
3493 int scale
, num_sge
, numSGE
;
3495 /* ReqToChain size must equal the req_depth
3498 if (ioc
->ReqToChain
== NULL
) {
3499 sz
= ioc
->req_depth
* sizeof(int);
3500 mem
= kmalloc(sz
, GFP_ATOMIC
);
3504 ioc
->ReqToChain
= (int *) mem
;
3505 dinitprintk((KERN_INFO MYNAM
": %s ReqToChain alloc @ %p, sz=%d bytes\n",
3506 ioc
->name
, mem
, sz
));
3507 mem
= kmalloc(sz
, GFP_ATOMIC
);
3511 ioc
->RequestNB
= (int *) mem
;
3512 dinitprintk((KERN_INFO MYNAM
": %s RequestNB alloc @ %p, sz=%d bytes\n",
3513 ioc
->name
, mem
, sz
));
3515 for (ii
= 0; ii
< ioc
->req_depth
; ii
++) {
3516 ioc
->ReqToChain
[ii
] = MPT_HOST_NO_CHAIN
;
3519 /* ChainToChain size must equal the total number
3520 * of chain buffers to be allocated.
3523 * Calculate the number of chain buffers needed(plus 1) per I/O
3524 * then multiply the the maximum number of simultaneous cmds
3526 * num_sge = num sge in request frame + last chain buffer
3527 * scale = num sge per chain buffer if no chain element
3529 scale
= ioc
->req_sz
/(sizeof(dma_addr_t
) + sizeof(u32
));
3530 if (sizeof(dma_addr_t
) == sizeof(u64
))
3531 num_sge
= scale
+ (ioc
->req_sz
- 60) / (sizeof(dma_addr_t
) + sizeof(u32
));
3533 num_sge
= 1+ scale
+ (ioc
->req_sz
- 64) / (sizeof(dma_addr_t
) + sizeof(u32
));
3535 if (sizeof(dma_addr_t
) == sizeof(u64
)) {
3536 numSGE
= (scale
- 1) * (ioc
->facts
.MaxChainDepth
-1) + scale
+
3537 (ioc
->req_sz
- 60) / (sizeof(dma_addr_t
) + sizeof(u32
));
3539 numSGE
= 1 + (scale
- 1) * (ioc
->facts
.MaxChainDepth
-1) + scale
+
3540 (ioc
->req_sz
- 64) / (sizeof(dma_addr_t
) + sizeof(u32
));
3542 dinitprintk((KERN_INFO MYNAM
": %s num_sge=%d numSGE=%d\n",
3543 ioc
->name
, num_sge
, numSGE
));
3545 if ( numSGE
> MPT_SCSI_SG_DEPTH
)
3546 numSGE
= MPT_SCSI_SG_DEPTH
;
3549 while (numSGE
- num_sge
> 0) {
3551 num_sge
+= (scale
- 1);
3555 dinitprintk((KERN_INFO MYNAM
": %s Now numSGE=%d num_sge=%d num_chain=%d\n",
3556 ioc
->name
, numSGE
, num_sge
, num_chain
));
3558 if (ioc
->bus_type
== SPI
)
3559 num_chain
*= MPT_SCSI_CAN_QUEUE
;
3561 num_chain
*= MPT_FC_CAN_QUEUE
;
3563 ioc
->num_chain
= num_chain
;
3565 sz
= num_chain
* sizeof(int);
3566 if (ioc
->ChainToChain
== NULL
) {
3567 mem
= kmalloc(sz
, GFP_ATOMIC
);
3571 ioc
->ChainToChain
= (int *) mem
;
3572 dinitprintk((KERN_INFO MYNAM
": %s ChainToChain alloc @ %p, sz=%d bytes\n",
3573 ioc
->name
, mem
, sz
));
3575 mem
= (u8
*) ioc
->ChainToChain
;
3577 memset(mem
, 0xFF, sz
);
3581 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3583 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
3584 * @ioc: Pointer to MPT_ADAPTER structure
3586 * This routine allocates memory for the MPT reply and request frame
3587 * pools (if necessary), and primes the IOC reply FIFO with
3590 * Returns 0 for success, non-zero for failure.
3593 PrimeIocFifos(MPT_ADAPTER
*ioc
)
3596 unsigned long flags
;
3597 dma_addr_t alloc_dma
;
3599 int i
, reply_sz
, sz
, total_size
, num_chain
;
3601 /* Prime reply FIFO... */
3603 if (ioc
->reply_frames
== NULL
) {
3604 if ( (num_chain
= initChainBuffers(ioc
)) < 0)
3607 total_size
= reply_sz
= (ioc
->reply_sz
* ioc
->reply_depth
);
3608 dinitprintk((KERN_INFO MYNAM
": %s.ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
3609 ioc
->name
, ioc
->reply_sz
, ioc
->reply_depth
));
3610 dinitprintk((KERN_INFO MYNAM
": %s.ReplyBuffer sz=%d[%x] bytes\n",
3611 ioc
->name
, reply_sz
, reply_sz
));
3613 sz
= (ioc
->req_sz
* ioc
->req_depth
);
3614 dinitprintk((KERN_INFO MYNAM
": %s.RequestBuffer sz=%d bytes, RequestDepth=%d\n",
3615 ioc
->name
, ioc
->req_sz
, ioc
->req_depth
));
3616 dinitprintk((KERN_INFO MYNAM
": %s.RequestBuffer sz=%d[%x] bytes\n",
3617 ioc
->name
, sz
, sz
));
3620 sz
= num_chain
* ioc
->req_sz
; /* chain buffer pool size */
3621 dinitprintk((KERN_INFO MYNAM
": %s.ChainBuffer sz=%d bytes, ChainDepth=%d\n",
3622 ioc
->name
, ioc
->req_sz
, num_chain
));
3623 dinitprintk((KERN_INFO MYNAM
": %s.ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
3624 ioc
->name
, sz
, sz
, num_chain
));
3627 mem
= pci_alloc_consistent(ioc
->pcidev
, total_size
, &alloc_dma
);
3629 printk(MYIOC_s_ERR_FMT
"Unable to allocate Reply, Request, Chain Buffers!\n",
3634 dinitprintk((KERN_INFO MYNAM
": %s.Total alloc @ %p[%p], sz=%d[%x] bytes\n",
3635 ioc
->name
, mem
, (void *)(ulong
)alloc_dma
, total_size
, total_size
));
3637 memset(mem
, 0, total_size
);
3638 ioc
->alloc_total
+= total_size
;
3640 ioc
->alloc_dma
= alloc_dma
;
3641 ioc
->alloc_sz
= total_size
;
3642 ioc
->reply_frames
= (MPT_FRAME_HDR
*) mem
;
3643 ioc
->reply_frames_low_dma
= (u32
) (alloc_dma
& 0xFFFFFFFF);
3645 dinitprintk((KERN_INFO MYNAM
": %s ReplyBuffers @ %p[%p]\n",
3646 ioc
->name
, ioc
->reply_frames
, (void *)(ulong
)alloc_dma
));
3648 alloc_dma
+= reply_sz
;
3651 /* Request FIFO - WE manage this! */
3653 ioc
->req_frames
= (MPT_FRAME_HDR
*) mem
;
3654 ioc
->req_frames_dma
= alloc_dma
;
3656 dinitprintk((KERN_INFO MYNAM
": %s RequestBuffers @ %p[%p]\n",
3657 ioc
->name
, mem
, (void *)(ulong
)alloc_dma
));
3659 ioc
->req_frames_low_dma
= (u32
) (alloc_dma
& 0xFFFFFFFF);
3661 #if defined(CONFIG_MTRR) && 0
3663 * Enable Write Combining MTRR for IOC's memory region.
3664 * (at least as much as we can; "size and base must be
3665 * multiples of 4 kiB"
3667 ioc
->mtrr_reg
= mtrr_add(ioc
->req_frames_dma
,
3669 MTRR_TYPE_WRCOMB
, 1);
3670 dprintk((MYIOC_s_INFO_FMT
"MTRR region registered (base:size=%08x:%x)\n",
3671 ioc
->name
, ioc
->req_frames_dma
, sz
));
3674 for (i
= 0; i
< ioc
->req_depth
; i
++) {
3675 alloc_dma
+= ioc
->req_sz
;
3679 ioc
->ChainBuffer
= mem
;
3680 ioc
->ChainBufferDMA
= alloc_dma
;
3682 dinitprintk((KERN_INFO MYNAM
" :%s ChainBuffers @ %p(%p)\n",
3683 ioc
->name
, ioc
->ChainBuffer
, (void *)(ulong
)ioc
->ChainBufferDMA
));
3685 /* Initialize the free chain Q.
3688 INIT_LIST_HEAD(&ioc
->FreeChainQ
);
3690 /* Post the chain buffers to the FreeChainQ.
3692 mem
= (u8
*)ioc
->ChainBuffer
;
3693 for (i
=0; i
< num_chain
; i
++) {
3694 mf
= (MPT_FRAME_HDR
*) mem
;
3695 list_add_tail(&mf
->u
.frame
.linkage
.list
, &ioc
->FreeChainQ
);
3699 /* Initialize Request frames linked list
3701 alloc_dma
= ioc
->req_frames_dma
;
3702 mem
= (u8
*) ioc
->req_frames
;
3704 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
3705 INIT_LIST_HEAD(&ioc
->FreeQ
);
3706 for (i
= 0; i
< ioc
->req_depth
; i
++) {
3707 mf
= (MPT_FRAME_HDR
*) mem
;
3709 /* Queue REQUESTs *internally*! */
3710 list_add_tail(&mf
->u
.frame
.linkage
.list
, &ioc
->FreeQ
);
3714 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
3716 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
3717 ioc
->sense_buf_pool
=
3718 pci_alloc_consistent(ioc
->pcidev
, sz
, &ioc
->sense_buf_pool_dma
);
3719 if (ioc
->sense_buf_pool
== NULL
) {
3720 printk(MYIOC_s_ERR_FMT
"Unable to allocate Sense Buffers!\n",
3725 ioc
->sense_buf_low_dma
= (u32
) (ioc
->sense_buf_pool_dma
& 0xFFFFFFFF);
3726 ioc
->alloc_total
+= sz
;
3727 dinitprintk((KERN_INFO MYNAM
": %s.SenseBuffers @ %p[%p]\n",
3728 ioc
->name
, ioc
->sense_buf_pool
, (void *)(ulong
)ioc
->sense_buf_pool_dma
));
3732 /* Post Reply frames to FIFO
3734 alloc_dma
= ioc
->alloc_dma
;
3735 dinitprintk((KERN_INFO MYNAM
": %s.ReplyBuffers @ %p[%p]\n",
3736 ioc
->name
, ioc
->reply_frames
, (void *)(ulong
)alloc_dma
));
3738 for (i
= 0; i
< ioc
->reply_depth
; i
++) {
3739 /* Write each address to the IOC! */
3740 CHIPREG_WRITE32(&ioc
->chip
->ReplyFifo
, alloc_dma
);
3741 alloc_dma
+= ioc
->reply_sz
;
3747 if (ioc
->alloc
!= NULL
) {
3749 pci_free_consistent(ioc
->pcidev
,
3751 ioc
->alloc
, ioc
->alloc_dma
);
3752 ioc
->reply_frames
= NULL
;
3753 ioc
->req_frames
= NULL
;
3754 ioc
->alloc_total
-= sz
;
3756 if (ioc
->sense_buf_pool
!= NULL
) {
3757 sz
= (ioc
->req_depth
* MPT_SENSE_BUFFER_ALLOC
);
3758 pci_free_consistent(ioc
->pcidev
,
3760 ioc
->sense_buf_pool
, ioc
->sense_buf_pool_dma
);
3761 ioc
->sense_buf_pool
= NULL
;
3766 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3768 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
3769 * from IOC via doorbell handshake method.
3770 * @ioc: Pointer to MPT_ADAPTER structure
3771 * @reqBytes: Size of the request in bytes
3772 * @req: Pointer to MPT request frame
3773 * @replyBytes: Expected size of the reply in bytes
3774 * @u16reply: Pointer to area where reply should be written
3775 * @maxwait: Max wait time for a reply (in seconds)
3776 * @sleepFlag: Specifies whether the process can sleep
3778 * NOTES: It is the callers responsibility to byte-swap fields in the
3779 * request which are greater than 1 byte in size. It is also the
3780 * callers responsibility to byte-swap response fields which are
3781 * greater than 1 byte in size.
3783 * Returns 0 for success, non-zero for failure.
3786 mpt_handshake_req_reply_wait(MPT_ADAPTER
*ioc
, int reqBytes
, u32
*req
,
3787 int replyBytes
, u16
*u16reply
, int maxwait
, int sleepFlag
)
3789 MPIDefaultReply_t
*mptReply
;
3794 * Get ready to cache a handshake reply
3796 ioc
->hs_reply_idx
= 0;
3797 mptReply
= (MPIDefaultReply_t
*) ioc
->hs_reply
;
3798 mptReply
->MsgLength
= 0;
3801 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
3802 * then tell IOC that we want to handshake a request of N words.
3803 * (WRITE u32val to Doorbell reg).
3805 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
3806 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
,
3807 ((MPI_FUNCTION_HANDSHAKE
<<MPI_DOORBELL_FUNCTION_SHIFT
) |
3808 ((reqBytes
/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT
)));
3811 * Wait for IOC's doorbell handshake int
3813 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
3816 dhsprintk((MYIOC_s_INFO_FMT
"HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
3817 ioc
->name
, reqBytes
, t
, failcnt
? " - MISSING DOORBELL HANDSHAKE!" : ""));
3819 /* Read doorbell and check for active bit */
3820 if (!(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & MPI_DOORBELL_ACTIVE
))
3824 * Clear doorbell int (WRITE 0 to IntStatus reg),
3825 * then wait for IOC to ACKnowledge that it's ready for
3826 * our handshake request.
3828 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
3829 if (!failcnt
&& (t
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
3834 u8
*req_as_bytes
= (u8
*) req
;
3837 * Stuff request words via doorbell handshake,
3838 * with ACK from IOC for each.
3840 for (ii
= 0; !failcnt
&& ii
< reqBytes
/4; ii
++) {
3841 u32 word
= ((req_as_bytes
[(ii
*4) + 0] << 0) |
3842 (req_as_bytes
[(ii
*4) + 1] << 8) |
3843 (req_as_bytes
[(ii
*4) + 2] << 16) |
3844 (req_as_bytes
[(ii
*4) + 3] << 24));
3846 CHIPREG_WRITE32(&ioc
->chip
->Doorbell
, word
);
3847 if ((t
= WaitForDoorbellAck(ioc
, 5, sleepFlag
)) < 0)
3851 dhsprintk((KERN_INFO MYNAM
": Handshake request frame (@%p) header\n", req
));
3852 DBG_DUMP_REQUEST_FRAME_HDR(req
)
3854 dhsprintk((MYIOC_s_INFO_FMT
"HandShake request post done, WaitCnt=%d%s\n",
3855 ioc
->name
, t
, failcnt
? " - MISSING DOORBELL ACK!" : ""));
3858 * Wait for completion of doorbell handshake reply from the IOC
3860 if (!failcnt
&& (t
= WaitForDoorbellReply(ioc
, maxwait
, sleepFlag
)) < 0)
3863 dhsprintk((MYIOC_s_INFO_FMT
"HandShake reply count=%d%s\n",
3864 ioc
->name
, t
, failcnt
? " - MISSING DOORBELL REPLY!" : ""));
3867 * Copy out the cached reply...
3869 for (ii
=0; ii
< min(replyBytes
/2,mptReply
->MsgLength
*2); ii
++)
3870 u16reply
[ii
] = ioc
->hs_reply
[ii
];
3878 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3880 * WaitForDoorbellAck - Wait for IOC to clear the IOP_DOORBELL_STATUS bit
3881 * in it's IntStatus register.
3882 * @ioc: Pointer to MPT_ADAPTER structure
3883 * @howlong: How long to wait (in seconds)
3884 * @sleepFlag: Specifies whether the process can sleep
3886 * This routine waits (up to ~2 seconds max) for IOC doorbell
3887 * handshake ACKnowledge.
3889 * Returns a negative value on failure, else wait loop count.
3892 WaitForDoorbellAck(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
3898 cntdn
= 1000 * howlong
;
3900 if (sleepFlag
== CAN_SLEEP
) {
3902 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
3903 if (! (intstat
& MPI_HIS_IOP_DOORBELL_STATUS
))
3905 msleep_interruptible (1);
3910 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
3911 if (! (intstat
& MPI_HIS_IOP_DOORBELL_STATUS
))
3919 dprintk((MYIOC_s_INFO_FMT
"WaitForDoorbell ACK (count=%d)\n",
3924 printk(MYIOC_s_ERR_FMT
"Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
3925 ioc
->name
, count
, intstat
);
3929 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3931 * WaitForDoorbellInt - Wait for IOC to set the HIS_DOORBELL_INTERRUPT bit
3932 * in it's IntStatus register.
3933 * @ioc: Pointer to MPT_ADAPTER structure
3934 * @howlong: How long to wait (in seconds)
3935 * @sleepFlag: Specifies whether the process can sleep
3937 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt.
3939 * Returns a negative value on failure, else wait loop count.
3942 WaitForDoorbellInt(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
3948 cntdn
= 1000 * howlong
;
3949 if (sleepFlag
== CAN_SLEEP
) {
3951 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
3952 if (intstat
& MPI_HIS_DOORBELL_INTERRUPT
)
3954 msleep_interruptible(1);
3959 intstat
= CHIPREG_READ32(&ioc
->chip
->IntStatus
);
3960 if (intstat
& MPI_HIS_DOORBELL_INTERRUPT
)
3968 dprintk((MYIOC_s_INFO_FMT
"WaitForDoorbell INT (cnt=%d) howlong=%d\n",
3969 ioc
->name
, count
, howlong
));
3973 printk(MYIOC_s_ERR_FMT
"Doorbell INT timeout (count=%d), IntStatus=%x!\n",
3974 ioc
->name
, count
, intstat
);
3978 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3980 * WaitForDoorbellReply - Wait for and capture a IOC handshake reply.
3981 * @ioc: Pointer to MPT_ADAPTER structure
3982 * @howlong: How long to wait (in seconds)
3983 * @sleepFlag: Specifies whether the process can sleep
3985 * This routine polls the IOC for a handshake reply, 16 bits at a time.
3986 * Reply is cached to IOC private area large enough to hold a maximum
3987 * of 128 bytes of reply data.
3989 * Returns a negative value on failure, else size of reply in WORDS.
3992 WaitForDoorbellReply(MPT_ADAPTER
*ioc
, int howlong
, int sleepFlag
)
3997 u16
*hs_reply
= ioc
->hs_reply
;
3998 volatile MPIDefaultReply_t
*mptReply
= (MPIDefaultReply_t
*) ioc
->hs_reply
;
4001 hs_reply
[0] = hs_reply
[1] = hs_reply
[7] = 0;
4004 * Get first two u16's so we can look at IOC's intended reply MsgLength
4007 if ((t
= WaitForDoorbellInt(ioc
, howlong
, sleepFlag
)) < 0) {
4010 hs_reply
[u16cnt
++] = le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4011 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4012 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4015 hs_reply
[u16cnt
++] = le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4016 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4020 dhsprintk((MYIOC_s_INFO_FMT
"WaitCnt=%d First handshake reply word=%08x%s\n",
4021 ioc
->name
, t
, le32_to_cpu(*(u32
*)hs_reply
),
4022 failcnt
? " - MISSING DOORBELL HANDSHAKE!" : ""));
4025 * If no error (and IOC said MsgLength is > 0), piece together
4026 * reply 16 bits at a time.
4028 for (u16cnt
=2; !failcnt
&& u16cnt
< (2 * mptReply
->MsgLength
); u16cnt
++) {
4029 if ((t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4031 hword
= le16_to_cpu(CHIPREG_READ32(&ioc
->chip
->Doorbell
) & 0x0000FFFF);
4032 /* don't overflow our IOC hs_reply[] buffer! */
4033 if (u16cnt
< sizeof(ioc
->hs_reply
) / sizeof(ioc
->hs_reply
[0]))
4034 hs_reply
[u16cnt
] = hword
;
4035 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4038 if (!failcnt
&& (t
= WaitForDoorbellInt(ioc
, 5, sleepFlag
)) < 0)
4040 CHIPREG_WRITE32(&ioc
->chip
->IntStatus
, 0);
4043 printk(MYIOC_s_ERR_FMT
"Handshake reply failure!\n",
4048 else if (u16cnt
!= (2 * mptReply
->MsgLength
)) {
4051 else if ((mptReply
->IOCStatus
& MPI_IOCSTATUS_MASK
) != MPI_IOCSTATUS_SUCCESS
) {
4056 dhsprintk((MYIOC_s_INFO_FMT
"Got Handshake reply:\n", ioc
->name
));
4057 DBG_DUMP_REPLY_FRAME(mptReply
)
4059 dhsprintk((MYIOC_s_INFO_FMT
"WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4060 ioc
->name
, t
, u16cnt
/2));
4064 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4066 * GetLanConfigPages - Fetch LANConfig pages.
4067 * @ioc: Pointer to MPT_ADAPTER structure
4069 * Return: 0 for success
4070 * -ENOMEM if no memory available
4071 * -EPERM if not allowed due to ISR context
4072 * -EAGAIN if no msg frames currently available
4073 * -EFAULT for non-successful reply or no reply (timeout)
4076 GetLanConfigPages(MPT_ADAPTER
*ioc
)
4078 ConfigPageHeader_t hdr
;
4080 LANPage0_t
*ppage0_alloc
;
4081 dma_addr_t page0_dma
;
4082 LANPage1_t
*ppage1_alloc
;
4083 dma_addr_t page1_dma
;
4088 /* Get LAN Page 0 header */
4089 hdr
.PageVersion
= 0;
4092 hdr
.PageType
= MPI_CONFIG_PAGETYPE_LAN
;
4093 cfg
.cfghdr
.hdr
= &hdr
;
4095 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4100 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
4103 if (hdr
.PageLength
> 0) {
4104 data_sz
= hdr
.PageLength
* 4;
4105 ppage0_alloc
= (LANPage0_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page0_dma
);
4108 memset((u8
*)ppage0_alloc
, 0, data_sz
);
4109 cfg
.physAddr
= page0_dma
;
4110 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4112 if ((rc
= mpt_config(ioc
, &cfg
)) == 0) {
4114 copy_sz
= min_t(int, sizeof(LANPage0_t
), data_sz
);
4115 memcpy(&ioc
->lan_cnfg_page0
, ppage0_alloc
, copy_sz
);
4119 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage0_alloc
, page0_dma
);
4122 * Normalize endianness of structure data,
4123 * by byte-swapping all > 1 byte fields!
4132 /* Get LAN Page 1 header */
4133 hdr
.PageVersion
= 0;
4136 hdr
.PageType
= MPI_CONFIG_PAGETYPE_LAN
;
4137 cfg
.cfghdr
.hdr
= &hdr
;
4139 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4143 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
4146 if (hdr
.PageLength
== 0)
4149 data_sz
= hdr
.PageLength
* 4;
4151 ppage1_alloc
= (LANPage1_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page1_dma
);
4153 memset((u8
*)ppage1_alloc
, 0, data_sz
);
4154 cfg
.physAddr
= page1_dma
;
4155 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4157 if ((rc
= mpt_config(ioc
, &cfg
)) == 0) {
4159 copy_sz
= min_t(int, sizeof(LANPage1_t
), data_sz
);
4160 memcpy(&ioc
->lan_cnfg_page1
, ppage1_alloc
, copy_sz
);
4163 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage1_alloc
, page1_dma
);
4166 * Normalize endianness of structure data,
4167 * by byte-swapping all > 1 byte fields!
4175 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4177 * mptbase_GetFcPortPage0 - Fetch FCPort config Page0.
4178 * @ioc: Pointer to MPT_ADAPTER structure
4179 * @portnum: IOC Port number
4181 * Return: 0 for success
4182 * -ENOMEM if no memory available
4183 * -EPERM if not allowed due to ISR context
4184 * -EAGAIN if no msg frames currently available
4185 * -EFAULT for non-successful reply or no reply (timeout)
4188 mptbase_GetFcPortPage0(MPT_ADAPTER
*ioc
, int portnum
)
4190 ConfigPageHeader_t hdr
;
4192 FCPortPage0_t
*ppage0_alloc
;
4193 FCPortPage0_t
*pp0dest
;
4194 dma_addr_t page0_dma
;
4201 /* Get FCPort Page 0 header */
4202 hdr
.PageVersion
= 0;
4205 hdr
.PageType
= MPI_CONFIG_PAGETYPE_FC_PORT
;
4206 cfg
.cfghdr
.hdr
= &hdr
;
4208 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4210 cfg
.pageAddr
= portnum
;
4213 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
4216 if (hdr
.PageLength
== 0)
4219 data_sz
= hdr
.PageLength
* 4;
4221 ppage0_alloc
= (FCPortPage0_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page0_dma
);
4225 memset((u8
*)ppage0_alloc
, 0, data_sz
);
4226 cfg
.physAddr
= page0_dma
;
4227 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4229 if ((rc
= mpt_config(ioc
, &cfg
)) == 0) {
4231 pp0dest
= &ioc
->fc_port_page0
[portnum
];
4232 copy_sz
= min_t(int, sizeof(FCPortPage0_t
), data_sz
);
4233 memcpy(pp0dest
, ppage0_alloc
, copy_sz
);
4236 * Normalize endianness of structure data,
4237 * by byte-swapping all > 1 byte fields!
4239 pp0dest
->Flags
= le32_to_cpu(pp0dest
->Flags
);
4240 pp0dest
->PortIdentifier
= le32_to_cpu(pp0dest
->PortIdentifier
);
4241 pp0dest
->WWNN
.Low
= le32_to_cpu(pp0dest
->WWNN
.Low
);
4242 pp0dest
->WWNN
.High
= le32_to_cpu(pp0dest
->WWNN
.High
);
4243 pp0dest
->WWPN
.Low
= le32_to_cpu(pp0dest
->WWPN
.Low
);
4244 pp0dest
->WWPN
.High
= le32_to_cpu(pp0dest
->WWPN
.High
);
4245 pp0dest
->SupportedServiceClass
= le32_to_cpu(pp0dest
->SupportedServiceClass
);
4246 pp0dest
->SupportedSpeeds
= le32_to_cpu(pp0dest
->SupportedSpeeds
);
4247 pp0dest
->CurrentSpeed
= le32_to_cpu(pp0dest
->CurrentSpeed
);
4248 pp0dest
->MaxFrameSize
= le32_to_cpu(pp0dest
->MaxFrameSize
);
4249 pp0dest
->FabricWWNN
.Low
= le32_to_cpu(pp0dest
->FabricWWNN
.Low
);
4250 pp0dest
->FabricWWNN
.High
= le32_to_cpu(pp0dest
->FabricWWNN
.High
);
4251 pp0dest
->FabricWWPN
.Low
= le32_to_cpu(pp0dest
->FabricWWPN
.Low
);
4252 pp0dest
->FabricWWPN
.High
= le32_to_cpu(pp0dest
->FabricWWPN
.High
);
4253 pp0dest
->DiscoveredPortsCount
= le32_to_cpu(pp0dest
->DiscoveredPortsCount
);
4254 pp0dest
->MaxInitiators
= le32_to_cpu(pp0dest
->MaxInitiators
);
4257 * if still doing discovery,
4258 * hang loose a while until finished
4260 if (pp0dest
->PortState
== MPI_FCPORTPAGE0_PORTSTATE_UNKNOWN
) {
4262 msleep_interruptible(100);
4265 printk(MYIOC_s_INFO_FMT
"Firmware discovery not"
4271 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage0_alloc
, page0_dma
);
4277 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4279 * mptbase_sas_persist_operation - Perform operation on SAS Persitent Table
4280 * @ioc: Pointer to MPT_ADAPTER structure
4281 * @sas_address: 64bit SAS Address for operation.
4282 * @target_id: specified target for operation
4283 * @bus: specified bus for operation
4284 * @persist_opcode: see below
4286 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4287 * devices not currently present.
4288 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4290 * NOTE: Don't use not this function during interrupt time.
4292 * Returns: 0 for success, non-zero error
4295 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4297 mptbase_sas_persist_operation(MPT_ADAPTER
*ioc
, u8 persist_opcode
)
4299 SasIoUnitControlRequest_t
*sasIoUnitCntrReq
;
4300 SasIoUnitControlReply_t
*sasIoUnitCntrReply
;
4301 MPT_FRAME_HDR
*mf
= NULL
;
4302 MPIHeader_t
*mpi_hdr
;
4305 /* insure garbage is not sent to fw */
4306 switch(persist_opcode
) {
4308 case MPI_SAS_OP_CLEAR_NOT_PRESENT
:
4309 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT
:
4317 printk("%s: persist_opcode=%x\n",__FUNCTION__
, persist_opcode
);
4319 /* Get a MF for this command.
4321 if ((mf
= mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
4322 printk("%s: no msg frames!\n",__FUNCTION__
);
4326 mpi_hdr
= (MPIHeader_t
*) mf
;
4327 sasIoUnitCntrReq
= (SasIoUnitControlRequest_t
*)mf
;
4328 memset(sasIoUnitCntrReq
,0,sizeof(SasIoUnitControlRequest_t
));
4329 sasIoUnitCntrReq
->Function
= MPI_FUNCTION_SAS_IO_UNIT_CONTROL
;
4330 sasIoUnitCntrReq
->MsgContext
= mpi_hdr
->MsgContext
;
4331 sasIoUnitCntrReq
->Operation
= persist_opcode
;
4333 init_timer(&ioc
->persist_timer
);
4334 ioc
->persist_timer
.data
= (unsigned long) ioc
;
4335 ioc
->persist_timer
.function
= mpt_timer_expired
;
4336 ioc
->persist_timer
.expires
= jiffies
+ HZ
*10 /* 10 sec */;
4337 ioc
->persist_wait_done
=0;
4338 add_timer(&ioc
->persist_timer
);
4339 mpt_put_msg_frame(mpt_base_index
, ioc
, mf
);
4340 wait_event(mpt_waitq
, ioc
->persist_wait_done
);
4342 sasIoUnitCntrReply
=
4343 (SasIoUnitControlReply_t
*)ioc
->persist_reply_frame
;
4344 if (le16_to_cpu(sasIoUnitCntrReply
->IOCStatus
) != MPI_IOCSTATUS_SUCCESS
) {
4345 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4347 sasIoUnitCntrReply
->IOCStatus
,
4348 sasIoUnitCntrReply
->IOCLogInfo
);
4352 printk("%s: success\n",__FUNCTION__
);
4356 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4359 mptbase_raid_process_event_data(MPT_ADAPTER
*ioc
,
4360 MpiEventDataRaid_t
* pRaidEventData
)
4369 volume
= pRaidEventData
->VolumeID
;
4370 reason
= pRaidEventData
->ReasonCode
;
4371 disk
= pRaidEventData
->PhysDiskNum
;
4372 status
= le32_to_cpu(pRaidEventData
->SettingsStatus
);
4373 flags
= (status
>> 0) & 0xff;
4374 state
= (status
>> 8) & 0xff;
4376 if (reason
== MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
) {
4380 if ((reason
>= MPI_EVENT_RAID_RC_PHYSDISK_CREATED
&&
4381 reason
<= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
) ||
4382 (reason
== MPI_EVENT_RAID_RC_SMART_DATA
)) {
4383 printk(MYIOC_s_INFO_FMT
"RAID STATUS CHANGE for PhysDisk %d\n",
4386 printk(MYIOC_s_INFO_FMT
"RAID STATUS CHANGE for VolumeID %d\n",
4391 case MPI_EVENT_RAID_RC_VOLUME_CREATED
:
4392 printk(MYIOC_s_INFO_FMT
" volume has been created\n",
4396 case MPI_EVENT_RAID_RC_VOLUME_DELETED
:
4398 printk(MYIOC_s_INFO_FMT
" volume has been deleted\n",
4402 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED
:
4403 printk(MYIOC_s_INFO_FMT
" volume settings have been changed\n",
4407 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED
:
4408 printk(MYIOC_s_INFO_FMT
" volume is now %s%s%s%s\n",
4410 state
== MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
4412 : state
== MPI_RAIDVOL0_STATUS_STATE_DEGRADED
4414 : state
== MPI_RAIDVOL0_STATUS_STATE_FAILED
4417 flags
& MPI_RAIDVOL0_STATUS_FLAG_ENABLED
4419 flags
& MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
4420 ? ", quiesced" : "",
4421 flags
& MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
4422 ? ", resync in progress" : "" );
4425 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED
:
4426 printk(MYIOC_s_INFO_FMT
" volume membership of PhysDisk %d has changed\n",
4430 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED
:
4431 printk(MYIOC_s_INFO_FMT
" PhysDisk has been created\n",
4435 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED
:
4436 printk(MYIOC_s_INFO_FMT
" PhysDisk has been deleted\n",
4440 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED
:
4441 printk(MYIOC_s_INFO_FMT
" PhysDisk settings have been changed\n",
4445 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
:
4446 printk(MYIOC_s_INFO_FMT
" PhysDisk is now %s%s%s\n",
4448 state
== MPI_PHYSDISK0_STATUS_ONLINE
4450 : state
== MPI_PHYSDISK0_STATUS_MISSING
4452 : state
== MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
4454 : state
== MPI_PHYSDISK0_STATUS_FAILED
4456 : state
== MPI_PHYSDISK0_STATUS_INITIALIZING
4458 : state
== MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
4459 ? "offline requested"
4460 : state
== MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
4461 ? "failed requested"
4462 : state
== MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
4465 flags
& MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
4466 ? ", out of sync" : "",
4467 flags
& MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
4468 ? ", quiesced" : "" );
4471 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
:
4472 printk(MYIOC_s_INFO_FMT
" Domain Validation needed for PhysDisk %d\n",
4476 case MPI_EVENT_RAID_RC_SMART_DATA
:
4477 printk(MYIOC_s_INFO_FMT
" SMART data received, ASC/ASCQ = %02xh/%02xh\n",
4478 ioc
->name
, pRaidEventData
->ASC
, pRaidEventData
->ASCQ
);
4481 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED
:
4482 printk(MYIOC_s_INFO_FMT
" replacement of PhysDisk %d has started\n",
4488 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4490 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4491 * @ioc: Pointer to MPT_ADAPTER structure
4493 * Returns: 0 for success
4494 * -ENOMEM if no memory available
4495 * -EPERM if not allowed due to ISR context
4496 * -EAGAIN if no msg frames currently available
4497 * -EFAULT for non-successful reply or no reply (timeout)
4500 GetIoUnitPage2(MPT_ADAPTER
*ioc
)
4502 ConfigPageHeader_t hdr
;
4504 IOUnitPage2_t
*ppage_alloc
;
4505 dma_addr_t page_dma
;
4509 /* Get the page header */
4510 hdr
.PageVersion
= 0;
4513 hdr
.PageType
= MPI_CONFIG_PAGETYPE_IO_UNIT
;
4514 cfg
.cfghdr
.hdr
= &hdr
;
4516 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4521 if ((rc
= mpt_config(ioc
, &cfg
)) != 0)
4524 if (hdr
.PageLength
== 0)
4527 /* Read the config page */
4528 data_sz
= hdr
.PageLength
* 4;
4530 ppage_alloc
= (IOUnitPage2_t
*) pci_alloc_consistent(ioc
->pcidev
, data_sz
, &page_dma
);
4532 memset((u8
*)ppage_alloc
, 0, data_sz
);
4533 cfg
.physAddr
= page_dma
;
4534 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4536 /* If Good, save data */
4537 if ((rc
= mpt_config(ioc
, &cfg
)) == 0)
4538 ioc
->biosVersion
= le32_to_cpu(ppage_alloc
->BiosVersion
);
4540 pci_free_consistent(ioc
->pcidev
, data_sz
, (u8
*) ppage_alloc
, page_dma
);
4546 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4547 /* mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4548 * @ioc: Pointer to a Adapter Strucutre
4549 * @portnum: IOC port number
4551 * Return: -EFAULT if read of config page header fails
4553 * If read of SCSI Port Page 0 fails,
4554 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4555 * Adapter settings: async, narrow
4557 * If read of SCSI Port Page 2 fails,
4558 * Adapter settings valid
4559 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4564 * CHECK - what type of locking mechanisms should be used????
4567 mpt_GetScsiPortSettings(MPT_ADAPTER
*ioc
, int portnum
)
4572 ConfigPageHeader_t header
;
4578 if (!ioc
->spi_data
.nvram
) {
4581 sz
= MPT_MAX_SCSI_DEVICES
* sizeof(int);
4582 mem
= kmalloc(sz
, GFP_ATOMIC
);
4586 ioc
->spi_data
.nvram
= (int *) mem
;
4588 dprintk((MYIOC_s_INFO_FMT
"SCSI device NVRAM settings @ %p, sz=%d\n",
4589 ioc
->name
, ioc
->spi_data
.nvram
, sz
));
4592 /* Invalidate NVRAM information
4594 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
4595 ioc
->spi_data
.nvram
[ii
] = MPT_HOST_NVRAM_INVALID
;
4598 /* Read SPP0 header, allocate memory, then read page.
4600 header
.PageVersion
= 0;
4601 header
.PageLength
= 0;
4602 header
.PageNumber
= 0;
4603 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_PORT
;
4604 cfg
.cfghdr
.hdr
= &header
;
4606 cfg
.pageAddr
= portnum
;
4607 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4609 cfg
.timeout
= 0; /* use default */
4610 if (mpt_config(ioc
, &cfg
) != 0)
4613 if (header
.PageLength
> 0) {
4614 pbuf
= pci_alloc_consistent(ioc
->pcidev
, header
.PageLength
* 4, &buf_dma
);
4616 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4617 cfg
.physAddr
= buf_dma
;
4618 if (mpt_config(ioc
, &cfg
) != 0) {
4619 ioc
->spi_data
.maxBusWidth
= MPT_NARROW
;
4620 ioc
->spi_data
.maxSyncOffset
= 0;
4621 ioc
->spi_data
.minSyncFactor
= MPT_ASYNC
;
4622 ioc
->spi_data
.busType
= MPT_HOST_BUS_UNKNOWN
;
4624 ddvprintk((MYIOC_s_INFO_FMT
"Unable to read PortPage0 minSyncFactor=%x\n",
4625 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
4627 /* Save the Port Page 0 data
4629 SCSIPortPage0_t
*pPP0
= (SCSIPortPage0_t
*) pbuf
;
4630 pPP0
->Capabilities
= le32_to_cpu(pPP0
->Capabilities
);
4631 pPP0
->PhysicalInterface
= le32_to_cpu(pPP0
->PhysicalInterface
);
4633 if ( (pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_QAS
) == 0 ) {
4634 ioc
->spi_data
.noQas
|= MPT_TARGET_NO_NEGO_QAS
;
4635 ddvprintk((KERN_INFO MYNAM
" :%s noQas due to Capabilities=%x\n",
4636 ioc
->name
, pPP0
->Capabilities
));
4638 ioc
->spi_data
.maxBusWidth
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_WIDE
? 1 : 0;
4639 data
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK
;
4641 ioc
->spi_data
.maxSyncOffset
= (u8
) (data
>> 16);
4642 data
= pPP0
->Capabilities
& MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK
;
4643 ioc
->spi_data
.minSyncFactor
= (u8
) (data
>> 8);
4644 ddvprintk((MYIOC_s_INFO_FMT
"PortPage0 minSyncFactor=%x\n",
4645 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
4647 ioc
->spi_data
.maxSyncOffset
= 0;
4648 ioc
->spi_data
.minSyncFactor
= MPT_ASYNC
;
4651 ioc
->spi_data
.busType
= pPP0
->PhysicalInterface
& MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK
;
4653 /* Update the minSyncFactor based on bus type.
4655 if ((ioc
->spi_data
.busType
== MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD
) ||
4656 (ioc
->spi_data
.busType
== MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE
)) {
4658 if (ioc
->spi_data
.minSyncFactor
< MPT_ULTRA
) {
4659 ioc
->spi_data
.minSyncFactor
= MPT_ULTRA
;
4660 ddvprintk((MYIOC_s_INFO_FMT
"HVD or SE detected, minSyncFactor=%x\n",
4661 ioc
->name
, ioc
->spi_data
.minSyncFactor
));
4666 pci_free_consistent(ioc
->pcidev
, header
.PageLength
* 4, pbuf
, buf_dma
);
4671 /* SCSI Port Page 2 - Read the header then the page.
4673 header
.PageVersion
= 0;
4674 header
.PageLength
= 0;
4675 header
.PageNumber
= 2;
4676 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_PORT
;
4677 cfg
.cfghdr
.hdr
= &header
;
4679 cfg
.pageAddr
= portnum
;
4680 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4682 if (mpt_config(ioc
, &cfg
) != 0)
4685 if (header
.PageLength
> 0) {
4686 /* Allocate memory and read SCSI Port Page 2
4688 pbuf
= pci_alloc_consistent(ioc
->pcidev
, header
.PageLength
* 4, &buf_dma
);
4690 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_NVRAM
;
4691 cfg
.physAddr
= buf_dma
;
4692 if (mpt_config(ioc
, &cfg
) != 0) {
4693 /* Nvram data is left with INVALID mark
4697 SCSIPortPage2_t
*pPP2
= (SCSIPortPage2_t
*) pbuf
;
4698 MpiDeviceInfo_t
*pdevice
= NULL
;
4701 * Save "Set to Avoid SCSI Bus Resets" flag
4703 ioc
->spi_data
.bus_reset
=
4704 (le32_to_cpu(pPP2
->PortFlags
) &
4705 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET
) ?
4708 /* Save the Port Page 2 data
4709 * (reformat into a 32bit quantity)
4711 data
= le32_to_cpu(pPP2
->PortFlags
) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK
;
4712 ioc
->spi_data
.PortFlags
= data
;
4713 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
4714 pdevice
= &pPP2
->DeviceSettings
[ii
];
4715 data
= (le16_to_cpu(pdevice
->DeviceFlags
) << 16) |
4716 (pdevice
->SyncFactor
<< 8) | pdevice
->Timeout
;
4717 ioc
->spi_data
.nvram
[ii
] = data
;
4721 pci_free_consistent(ioc
->pcidev
, header
.PageLength
* 4, pbuf
, buf_dma
);
4725 /* Update Adapter limits with those from NVRAM
4726 * Comment: Don't need to do this. Target performance
4727 * parameters will never exceed the adapters limits.
4733 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4734 /* mpt_readScsiDevicePageHeaders - save version and length of SDP1
4735 * @ioc: Pointer to a Adapter Strucutre
4736 * @portnum: IOC port number
4738 * Return: -EFAULT if read of config page header fails
4742 mpt_readScsiDevicePageHeaders(MPT_ADAPTER
*ioc
, int portnum
)
4745 ConfigPageHeader_t header
;
4747 /* Read the SCSI Device Page 1 header
4749 header
.PageVersion
= 0;
4750 header
.PageLength
= 0;
4751 header
.PageNumber
= 1;
4752 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_DEVICE
;
4753 cfg
.cfghdr
.hdr
= &header
;
4755 cfg
.pageAddr
= portnum
;
4756 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4759 if (mpt_config(ioc
, &cfg
) != 0)
4762 ioc
->spi_data
.sdp1version
= cfg
.cfghdr
.hdr
->PageVersion
;
4763 ioc
->spi_data
.sdp1length
= cfg
.cfghdr
.hdr
->PageLength
;
4765 header
.PageVersion
= 0;
4766 header
.PageLength
= 0;
4767 header
.PageNumber
= 0;
4768 header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_DEVICE
;
4769 if (mpt_config(ioc
, &cfg
) != 0)
4772 ioc
->spi_data
.sdp0version
= cfg
.cfghdr
.hdr
->PageVersion
;
4773 ioc
->spi_data
.sdp0length
= cfg
.cfghdr
.hdr
->PageLength
;
4775 dcprintk((MYIOC_s_INFO_FMT
"Headers: 0: version %d length %d\n",
4776 ioc
->name
, ioc
->spi_data
.sdp0version
, ioc
->spi_data
.sdp0length
));
4778 dcprintk((MYIOC_s_INFO_FMT
"Headers: 1: version %d length %d\n",
4779 ioc
->name
, ioc
->spi_data
.sdp1version
, ioc
->spi_data
.sdp1length
));
4783 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4785 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
4786 * @ioc: Pointer to a Adapter Strucutre
4787 * @portnum: IOC port number
4791 * -EFAULT if read of config page header fails or data pointer not NULL
4792 * -ENOMEM if pci_alloc failed
4795 mpt_findImVolumes(MPT_ADAPTER
*ioc
)
4799 ConfigPageIoc2RaidVol_t
*pIocRv
;
4800 dma_addr_t ioc2_dma
;
4802 ConfigPageHeader_t header
;
4809 /* Read IOCP2 header then the page.
4811 header
.PageVersion
= 0;
4812 header
.PageLength
= 0;
4813 header
.PageNumber
= 2;
4814 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
4815 cfg
.cfghdr
.hdr
= &header
;
4818 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4821 if (mpt_config(ioc
, &cfg
) != 0)
4824 if (header
.PageLength
== 0)
4827 iocpage2sz
= header
.PageLength
* 4;
4828 pIoc2
= pci_alloc_consistent(ioc
->pcidev
, iocpage2sz
, &ioc2_dma
);
4832 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4833 cfg
.physAddr
= ioc2_dma
;
4834 if (mpt_config(ioc
, &cfg
) != 0)
4837 if ( (mem
= (u8
*)ioc
->raid_data
.pIocPg2
) == NULL
) {
4838 mem
= kmalloc(iocpage2sz
, GFP_ATOMIC
);
4840 ioc
->raid_data
.pIocPg2
= (IOCPage2_t
*) mem
;
4845 memcpy(mem
, (u8
*)pIoc2
, iocpage2sz
);
4847 /* Identify RAID Volume Id's */
4848 nVols
= pIoc2
->NumActiveVolumes
;
4854 /* At least 1 RAID Volume
4856 pIocRv
= pIoc2
->RaidVolume
;
4857 ioc
->raid_data
.isRaid
= 0;
4858 for (jj
= 0; jj
< nVols
; jj
++, pIocRv
++) {
4859 vid
= pIocRv
->VolumeID
;
4860 vbus
= pIocRv
->VolumeBus
;
4861 vioc
= pIocRv
->VolumeIOC
;
4866 ioc
->raid_data
.isRaid
|= (1 << vid
);
4868 /* Error! Always bus 0
4874 /* Identify Hidden Physical Disk Id's */
4875 nPhys
= pIoc2
->NumActivePhysDisks
;
4877 /* No physical disks.
4880 mpt_read_ioc_pg_3(ioc
);
4884 pci_free_consistent(ioc
->pcidev
, iocpage2sz
, pIoc2
, ioc2_dma
);
4890 mpt_read_ioc_pg_3(MPT_ADAPTER
*ioc
)
4895 ConfigPageHeader_t header
;
4896 dma_addr_t ioc3_dma
;
4899 /* Free the old page
4901 kfree(ioc
->raid_data
.pIocPg3
);
4902 ioc
->raid_data
.pIocPg3
= NULL
;
4904 /* There is at least one physical disk.
4905 * Read and save IOC Page 3
4907 header
.PageVersion
= 0;
4908 header
.PageLength
= 0;
4909 header
.PageNumber
= 3;
4910 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
4911 cfg
.cfghdr
.hdr
= &header
;
4914 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4917 if (mpt_config(ioc
, &cfg
) != 0)
4920 if (header
.PageLength
== 0)
4923 /* Read Header good, alloc memory
4925 iocpage3sz
= header
.PageLength
* 4;
4926 pIoc3
= pci_alloc_consistent(ioc
->pcidev
, iocpage3sz
, &ioc3_dma
);
4930 /* Read the Page and save the data
4931 * into malloc'd memory.
4933 cfg
.physAddr
= ioc3_dma
;
4934 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4935 if (mpt_config(ioc
, &cfg
) == 0) {
4936 mem
= kmalloc(iocpage3sz
, GFP_ATOMIC
);
4938 memcpy(mem
, (u8
*)pIoc3
, iocpage3sz
);
4939 ioc
->raid_data
.pIocPg3
= (IOCPage3_t
*) mem
;
4943 pci_free_consistent(ioc
->pcidev
, iocpage3sz
, pIoc3
, ioc3_dma
);
4949 mpt_read_ioc_pg_4(MPT_ADAPTER
*ioc
)
4953 ConfigPageHeader_t header
;
4954 dma_addr_t ioc4_dma
;
4957 /* Read and save IOC Page 4
4959 header
.PageVersion
= 0;
4960 header
.PageLength
= 0;
4961 header
.PageNumber
= 4;
4962 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
4963 cfg
.cfghdr
.hdr
= &header
;
4966 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
4969 if (mpt_config(ioc
, &cfg
) != 0)
4972 if (header
.PageLength
== 0)
4975 if ( (pIoc4
= ioc
->spi_data
.pIocPg4
) == NULL
) {
4976 iocpage4sz
= (header
.PageLength
+ 4) * 4; /* Allow 4 additional SEP's */
4977 pIoc4
= pci_alloc_consistent(ioc
->pcidev
, iocpage4sz
, &ioc4_dma
);
4981 ioc4_dma
= ioc
->spi_data
.IocPg4_dma
;
4982 iocpage4sz
= ioc
->spi_data
.IocPg4Sz
;
4985 /* Read the Page into dma memory.
4987 cfg
.physAddr
= ioc4_dma
;
4988 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
4989 if (mpt_config(ioc
, &cfg
) == 0) {
4990 ioc
->spi_data
.pIocPg4
= (IOCPage4_t
*) pIoc4
;
4991 ioc
->spi_data
.IocPg4_dma
= ioc4_dma
;
4992 ioc
->spi_data
.IocPg4Sz
= iocpage4sz
;
4994 pci_free_consistent(ioc
->pcidev
, iocpage4sz
, pIoc4
, ioc4_dma
);
4995 ioc
->spi_data
.pIocPg4
= NULL
;
5000 mpt_read_ioc_pg_1(MPT_ADAPTER
*ioc
)
5004 ConfigPageHeader_t header
;
5005 dma_addr_t ioc1_dma
;
5009 /* Check the Coalescing Timeout in IOC Page 1
5011 header
.PageVersion
= 0;
5012 header
.PageLength
= 0;
5013 header
.PageNumber
= 1;
5014 header
.PageType
= MPI_CONFIG_PAGETYPE_IOC
;
5015 cfg
.cfghdr
.hdr
= &header
;
5018 cfg
.action
= MPI_CONFIG_ACTION_PAGE_HEADER
;
5021 if (mpt_config(ioc
, &cfg
) != 0)
5024 if (header
.PageLength
== 0)
5027 /* Read Header good, alloc memory
5029 iocpage1sz
= header
.PageLength
* 4;
5030 pIoc1
= pci_alloc_consistent(ioc
->pcidev
, iocpage1sz
, &ioc1_dma
);
5034 /* Read the Page and check coalescing timeout
5036 cfg
.physAddr
= ioc1_dma
;
5037 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5038 if (mpt_config(ioc
, &cfg
) == 0) {
5040 tmp
= le32_to_cpu(pIoc1
->Flags
) & MPI_IOCPAGE1_REPLY_COALESCING
;
5041 if (tmp
== MPI_IOCPAGE1_REPLY_COALESCING
) {
5042 tmp
= le32_to_cpu(pIoc1
->CoalescingTimeout
);
5044 dprintk((MYIOC_s_INFO_FMT
"Coalescing Enabled Timeout = %d\n",
5047 if (tmp
> MPT_COALESCING_TIMEOUT
) {
5048 pIoc1
->CoalescingTimeout
= cpu_to_le32(MPT_COALESCING_TIMEOUT
);
5050 /* Write NVRAM and current
5053 cfg
.action
= MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT
;
5054 if (mpt_config(ioc
, &cfg
) == 0) {
5055 dprintk((MYIOC_s_INFO_FMT
"Reset Current Coalescing Timeout to = %d\n",
5056 ioc
->name
, MPT_COALESCING_TIMEOUT
));
5058 cfg
.action
= MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM
;
5059 if (mpt_config(ioc
, &cfg
) == 0) {
5060 dprintk((MYIOC_s_INFO_FMT
"Reset NVRAM Coalescing Timeout to = %d\n",
5061 ioc
->name
, MPT_COALESCING_TIMEOUT
));
5063 dprintk((MYIOC_s_INFO_FMT
"Reset NVRAM Coalescing Timeout Failed\n",
5068 dprintk((MYIOC_s_WARN_FMT
"Reset of Current Coalescing Timeout Failed!\n",
5074 dprintk((MYIOC_s_WARN_FMT
"Coalescing Disabled\n", ioc
->name
));
5078 pci_free_consistent(ioc
->pcidev
, iocpage1sz
, pIoc1
, ioc1_dma
);
5083 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5085 * SendEventNotification - Send EventNotification (on or off) request
5087 * @ioc: Pointer to MPT_ADAPTER structure
5088 * @EvSwitch: Event switch flags
5091 SendEventNotification(MPT_ADAPTER
*ioc
, u8 EvSwitch
)
5093 EventNotification_t
*evnp
;
5095 evnp
= (EventNotification_t
*) mpt_get_msg_frame(mpt_base_index
, ioc
);
5097 devtverboseprintk((MYIOC_s_WARN_FMT
"Unable to allocate event request frame!\n",
5101 memset(evnp
, 0, sizeof(*evnp
));
5103 devtverboseprintk((MYIOC_s_INFO_FMT
"Sending EventNotification (%d) request %p\n", ioc
->name
, EvSwitch
, evnp
));
5105 evnp
->Function
= MPI_FUNCTION_EVENT_NOTIFICATION
;
5106 evnp
->ChainOffset
= 0;
5108 evnp
->Switch
= EvSwitch
;
5110 mpt_put_msg_frame(mpt_base_index
, ioc
, (MPT_FRAME_HDR
*)evnp
);
5115 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5117 * SendEventAck - Send EventAck request to MPT adapter.
5118 * @ioc: Pointer to MPT_ADAPTER structure
5119 * @evnp: Pointer to original EventNotification request
5122 SendEventAck(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*evnp
)
5126 if ((pAck
= (EventAck_t
*) mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
5127 printk(MYIOC_s_WARN_FMT
"Unable to allocate event ACK "
5128 "request frame for Event=%x EventContext=%x EventData=%x!\n",
5129 ioc
->name
, evnp
->Event
, le32_to_cpu(evnp
->EventContext
),
5130 le32_to_cpu(evnp
->Data
[0]));
5133 memset(pAck
, 0, sizeof(*pAck
));
5135 dprintk((MYIOC_s_INFO_FMT
"Sending EventAck\n", ioc
->name
));
5137 pAck
->Function
= MPI_FUNCTION_EVENT_ACK
;
5138 pAck
->ChainOffset
= 0;
5140 pAck
->Event
= evnp
->Event
;
5141 pAck
->EventContext
= evnp
->EventContext
;
5143 mpt_put_msg_frame(mpt_base_index
, ioc
, (MPT_FRAME_HDR
*)pAck
);
5148 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5150 * mpt_config - Generic function to issue config message
5151 * @ioc - Pointer to an adapter structure
5152 * @cfg - Pointer to a configuration structure. Struct contains
5153 * action, page address, direction, physical address
5154 * and pointer to a configuration page header
5155 * Page header is updated.
5157 * Returns 0 for success
5158 * -EPERM if not allowed due to ISR context
5159 * -EAGAIN if no msg frames currently available
5160 * -EFAULT for non-successful reply or no reply (timeout)
5163 mpt_config(MPT_ADAPTER
*ioc
, CONFIGPARMS
*pCfg
)
5166 ConfigExtendedPageHeader_t
*pExtHdr
= NULL
;
5168 unsigned long flags
;
5173 /* Prevent calling wait_event() (below), if caller happens
5174 * to be in ISR context, because that is fatal!
5176 in_isr
= in_interrupt();
5178 dcprintk((MYIOC_s_WARN_FMT
"Config request not allowed in ISR context!\n",
5183 /* Get and Populate a free Frame
5185 if ((mf
= mpt_get_msg_frame(mpt_base_index
, ioc
)) == NULL
) {
5186 dcprintk((MYIOC_s_WARN_FMT
"mpt_config: no msg frames!\n",
5190 pReq
= (Config_t
*)mf
;
5191 pReq
->Action
= pCfg
->action
;
5193 pReq
->ChainOffset
= 0;
5194 pReq
->Function
= MPI_FUNCTION_CONFIG
;
5196 /* Assume page type is not extended and clear "reserved" fields. */
5197 pReq
->ExtPageLength
= 0;
5198 pReq
->ExtPageType
= 0;
5201 for (ii
=0; ii
< 8; ii
++)
5202 pReq
->Reserved2
[ii
] = 0;
5204 pReq
->Header
.PageVersion
= pCfg
->cfghdr
.hdr
->PageVersion
;
5205 pReq
->Header
.PageLength
= pCfg
->cfghdr
.hdr
->PageLength
;
5206 pReq
->Header
.PageNumber
= pCfg
->cfghdr
.hdr
->PageNumber
;
5207 pReq
->Header
.PageType
= (pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
);
5209 if ((pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
) == MPI_CONFIG_PAGETYPE_EXTENDED
) {
5210 pExtHdr
= (ConfigExtendedPageHeader_t
*)pCfg
->cfghdr
.ehdr
;
5211 pReq
->ExtPageLength
= cpu_to_le16(pExtHdr
->ExtPageLength
);
5212 pReq
->ExtPageType
= pExtHdr
->ExtPageType
;
5213 pReq
->Header
.PageType
= MPI_CONFIG_PAGETYPE_EXTENDED
;
5215 /* Page Length must be treated as a reserved field for the extended header. */
5216 pReq
->Header
.PageLength
= 0;
5219 pReq
->PageAddress
= cpu_to_le32(pCfg
->pageAddr
);
5221 /* Add a SGE to the config request.
5224 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_WRITE
;
5226 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_READ
;
5228 if ((pCfg
->cfghdr
.hdr
->PageType
& MPI_CONFIG_PAGETYPE_MASK
) == MPI_CONFIG_PAGETYPE_EXTENDED
) {
5229 flagsLength
|= pExtHdr
->ExtPageLength
* 4;
5231 dcprintk((MYIOC_s_INFO_FMT
"Sending Config request type %d, page %d and action %d\n",
5232 ioc
->name
, pReq
->ExtPageType
, pReq
->Header
.PageNumber
, pReq
->Action
));
5235 flagsLength
|= pCfg
->cfghdr
.hdr
->PageLength
* 4;
5237 dcprintk((MYIOC_s_INFO_FMT
"Sending Config request type %d, page %d and action %d\n",
5238 ioc
->name
, pReq
->Header
.PageType
, pReq
->Header
.PageNumber
, pReq
->Action
));
5241 mpt_add_sge((char *)&pReq
->PageBufferSGE
, flagsLength
, pCfg
->physAddr
);
5243 /* Append pCfg pointer to end of mf
5245 *((void **) (((u8
*) mf
) + (ioc
->req_sz
- sizeof(void *)))) = (void *) pCfg
;
5247 /* Initalize the timer
5249 init_timer(&pCfg
->timer
);
5250 pCfg
->timer
.data
= (unsigned long) ioc
;
5251 pCfg
->timer
.function
= mpt_timer_expired
;
5252 pCfg
->wait_done
= 0;
5254 /* Set the timer; ensure 10 second minimum */
5255 if (pCfg
->timeout
< 10)
5256 pCfg
->timer
.expires
= jiffies
+ HZ
*10;
5258 pCfg
->timer
.expires
= jiffies
+ HZ
*pCfg
->timeout
;
5260 /* Add to end of Q, set timer and then issue this command */
5261 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
5262 list_add_tail(&pCfg
->linkage
, &ioc
->configQ
);
5263 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
5265 add_timer(&pCfg
->timer
);
5266 mpt_put_msg_frame(mpt_base_index
, ioc
, mf
);
5267 wait_event(mpt_waitq
, pCfg
->wait_done
);
5269 /* mf has been freed - do not access */
5276 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5278 * mpt_timer_expired - Call back for timer process.
5279 * Used only internal config functionality.
5280 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5283 mpt_timer_expired(unsigned long data
)
5285 MPT_ADAPTER
*ioc
= (MPT_ADAPTER
*) data
;
5287 dcprintk((MYIOC_s_WARN_FMT
"mpt_timer_expired! \n", ioc
->name
));
5289 /* Perform a FW reload */
5290 if (mpt_HardResetHandler(ioc
, NO_SLEEP
) < 0)
5291 printk(MYIOC_s_WARN_FMT
"Firmware Reload FAILED!\n", ioc
->name
);
5293 /* No more processing.
5294 * Hard reset clean-up will wake up
5295 * process and free all resources.
5297 dcprintk((MYIOC_s_WARN_FMT
"mpt_timer_expired complete!\n", ioc
->name
));
5302 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5304 * mpt_ioc_reset - Base cleanup for hard reset
5305 * @ioc: Pointer to the adapter structure
5306 * @reset_phase: Indicates pre- or post-reset functionality
5308 * Remark: Free's resources with internally generated commands.
5311 mpt_ioc_reset(MPT_ADAPTER
*ioc
, int reset_phase
)
5314 unsigned long flags
;
5316 dprintk((KERN_WARNING MYNAM
5317 ": IOC %s_reset routed to MPT base driver!\n",
5318 reset_phase
==MPT_IOC_SETUP_RESET
? "setup" : (
5319 reset_phase
==MPT_IOC_PRE_RESET
? "pre" : "post")));
5321 if (reset_phase
== MPT_IOC_SETUP_RESET
) {
5323 } else if (reset_phase
== MPT_IOC_PRE_RESET
) {
5324 /* If the internal config Q is not empty -
5325 * delete timer. MF resources will be freed when
5326 * the FIFO's are primed.
5328 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
5329 list_for_each_entry(pCfg
, &ioc
->configQ
, linkage
)
5330 del_timer(&pCfg
->timer
);
5331 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
5336 /* Search the configQ for internal commands.
5337 * Flush the Q, and wake up all suspended threads.
5339 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
5340 list_for_each_entry_safe(pCfg
, pNext
, &ioc
->configQ
, linkage
) {
5341 list_del(&pCfg
->linkage
);
5343 pCfg
->status
= MPT_CONFIG_ERROR
;
5344 pCfg
->wait_done
= 1;
5345 wake_up(&mpt_waitq
);
5347 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
5350 return 1; /* currently means nothing really */
5354 #ifdef CONFIG_PROC_FS /* { */
5355 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5357 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5359 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5361 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5363 * Returns 0 for success, non-zero for failure.
5366 procmpt_create(void)
5368 struct proc_dir_entry
*ent
;
5370 mpt_proc_root_dir
= proc_mkdir(MPT_PROCFS_MPTBASEDIR
, NULL
);
5371 if (mpt_proc_root_dir
== NULL
)
5374 ent
= create_proc_entry("summary", S_IFREG
|S_IRUGO
, mpt_proc_root_dir
);
5376 ent
->read_proc
= procmpt_summary_read
;
5378 ent
= create_proc_entry("version", S_IFREG
|S_IRUGO
, mpt_proc_root_dir
);
5380 ent
->read_proc
= procmpt_version_read
;
5385 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5387 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5389 * Returns 0 for success, non-zero for failure.
5392 procmpt_destroy(void)
5394 remove_proc_entry("version", mpt_proc_root_dir
);
5395 remove_proc_entry("summary", mpt_proc_root_dir
);
5396 remove_proc_entry(MPT_PROCFS_MPTBASEDIR
, NULL
);
5399 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5401 * procmpt_summary_read - Handle read request from /proc/mpt/summary
5402 * or from /proc/mpt/iocN/summary.
5403 * @buf: Pointer to area to write information
5404 * @start: Pointer to start pointer
5405 * @offset: Offset to start writing
5407 * @eof: Pointer to EOF integer
5410 * Returns number of characters written to process performing the read.
5413 procmpt_summary_read(char *buf
, char **start
, off_t offset
, int request
, int *eof
, void *data
)
5423 mpt_print_ioc_summary(ioc
, out
, &more
, 0, 1);
5427 list_for_each_entry(ioc
, &ioc_list
, list
) {
5430 mpt_print_ioc_summary(ioc
, out
, &more
, 0, 1);
5433 if ((out
-buf
) >= request
)
5440 MPT_PROC_READ_RETURN(buf
,start
,offset
,request
,eof
,len
);
5443 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5445 * procmpt_version_read - Handle read request from /proc/mpt/version.
5446 * @buf: Pointer to area to write information
5447 * @start: Pointer to start pointer
5448 * @offset: Offset to start writing
5450 * @eof: Pointer to EOF integer
5453 * Returns number of characters written to process performing the read.
5456 procmpt_version_read(char *buf
, char **start
, off_t offset
, int request
, int *eof
, void *data
)
5459 int scsi
, fc
, sas
, lan
, ctl
, targ
, dmp
;
5463 len
= sprintf(buf
, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON
);
5464 len
+= sprintf(buf
+len
, " Fusion MPT base driver\n");
5466 scsi
= fc
= sas
= lan
= ctl
= targ
= dmp
= 0;
5467 for (ii
=MPT_MAX_PROTOCOL_DRIVERS
-1; ii
; ii
--) {
5469 if (MptCallbacks
[ii
]) {
5470 switch (MptDriverClass
[ii
]) {
5472 if (!scsi
++) drvname
= "SPI host";
5475 if (!fc
++) drvname
= "FC host";
5478 if (!sas
++) drvname
= "SAS host";
5481 if (!lan
++) drvname
= "LAN";
5484 if (!targ
++) drvname
= "SCSI target";
5487 if (!ctl
++) drvname
= "ioctl";
5492 len
+= sprintf(buf
+len
, " Fusion MPT %s driver\n", drvname
);
5496 MPT_PROC_READ_RETURN(buf
,start
,offset
,request
,eof
,len
);
5499 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5501 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
5502 * @buf: Pointer to area to write information
5503 * @start: Pointer to start pointer
5504 * @offset: Offset to start writing
5506 * @eof: Pointer to EOF integer
5509 * Returns number of characters written to process performing the read.
5512 procmpt_iocinfo_read(char *buf
, char **start
, off_t offset
, int request
, int *eof
, void *data
)
5514 MPT_ADAPTER
*ioc
= data
;
5520 mpt_get_fw_exp_ver(expVer
, ioc
);
5522 len
= sprintf(buf
, "%s:", ioc
->name
);
5523 if (ioc
->facts
.Flags
& MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT
)
5524 len
+= sprintf(buf
+len
, " (f/w download boot flag set)");
5525 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
5526 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
5528 len
+= sprintf(buf
+len
, "\n ProductID = 0x%04x (%s)\n",
5529 ioc
->facts
.ProductID
,
5531 len
+= sprintf(buf
+len
, " FWVersion = 0x%08x%s", ioc
->facts
.FWVersion
.Word
, expVer
);
5532 if (ioc
->facts
.FWImageSize
)
5533 len
+= sprintf(buf
+len
, " (fw_size=%d)", ioc
->facts
.FWImageSize
);
5534 len
+= sprintf(buf
+len
, "\n MsgVersion = 0x%04x\n", ioc
->facts
.MsgVersion
);
5535 len
+= sprintf(buf
+len
, " FirstWhoInit = 0x%02x\n", ioc
->FirstWhoInit
);
5536 len
+= sprintf(buf
+len
, " EventState = 0x%02x\n", ioc
->facts
.EventState
);
5538 len
+= sprintf(buf
+len
, " CurrentHostMfaHighAddr = 0x%08x\n",
5539 ioc
->facts
.CurrentHostMfaHighAddr
);
5540 len
+= sprintf(buf
+len
, " CurrentSenseBufferHighAddr = 0x%08x\n",
5541 ioc
->facts
.CurrentSenseBufferHighAddr
);
5543 len
+= sprintf(buf
+len
, " MaxChainDepth = 0x%02x frames\n", ioc
->facts
.MaxChainDepth
);
5544 len
+= sprintf(buf
+len
, " MinBlockSize = 0x%02x bytes\n", 4*ioc
->facts
.BlockSize
);
5546 len
+= sprintf(buf
+len
, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
5547 (void *)ioc
->req_frames
, (void *)(ulong
)ioc
->req_frames_dma
);
5549 * Rounding UP to nearest 4-kB boundary here...
5551 sz
= (ioc
->req_sz
* ioc
->req_depth
) + 128;
5552 sz
= ((sz
+ 0x1000UL
- 1UL) / 0x1000) * 0x1000;
5553 len
+= sprintf(buf
+len
, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
5554 ioc
->req_sz
, ioc
->req_depth
, ioc
->req_sz
*ioc
->req_depth
, sz
);
5555 len
+= sprintf(buf
+len
, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
5556 4*ioc
->facts
.RequestFrameSize
,
5557 ioc
->facts
.GlobalCredits
);
5559 len
+= sprintf(buf
+len
, " Frames @ 0x%p (Dma @ 0x%p)\n",
5560 (void *)ioc
->alloc
, (void *)(ulong
)ioc
->alloc_dma
);
5561 sz
= (ioc
->reply_sz
* ioc
->reply_depth
) + 128;
5562 len
+= sprintf(buf
+len
, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
5563 ioc
->reply_sz
, ioc
->reply_depth
, ioc
->reply_sz
*ioc
->reply_depth
, sz
);
5564 len
+= sprintf(buf
+len
, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
5565 ioc
->facts
.CurReplyFrameSize
,
5566 ioc
->facts
.ReplyQueueDepth
);
5568 len
+= sprintf(buf
+len
, " MaxDevices = %d\n",
5569 (ioc
->facts
.MaxDevices
==0) ? 255 : ioc
->facts
.MaxDevices
);
5570 len
+= sprintf(buf
+len
, " MaxBuses = %d\n", ioc
->facts
.MaxBuses
);
5573 for (p
=0; p
< ioc
->facts
.NumberOfPorts
; p
++) {
5574 len
+= sprintf(buf
+len
, " PortNumber = %d (of %d)\n",
5576 ioc
->facts
.NumberOfPorts
);
5577 if (ioc
->bus_type
== FC
) {
5578 if (ioc
->pfacts
[p
].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
) {
5579 u8
*a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
5580 len
+= sprintf(buf
+len
, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
5581 a
[5], a
[4], a
[3], a
[2], a
[1], a
[0]);
5583 len
+= sprintf(buf
+len
, " WWN = %08X%08X:%08X%08X\n",
5584 ioc
->fc_port_page0
[p
].WWNN
.High
,
5585 ioc
->fc_port_page0
[p
].WWNN
.Low
,
5586 ioc
->fc_port_page0
[p
].WWPN
.High
,
5587 ioc
->fc_port_page0
[p
].WWPN
.Low
);
5591 MPT_PROC_READ_RETURN(buf
,start
,offset
,request
,eof
,len
);
5594 #endif /* CONFIG_PROC_FS } */
5596 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5598 mpt_get_fw_exp_ver(char *buf
, MPT_ADAPTER
*ioc
)
5601 if ((ioc
->facts
.FWVersion
.Word
>> 24) == 0x0E) {
5602 sprintf(buf
, " (Exp %02d%02d)",
5603 (ioc
->facts
.FWVersion
.Word
>> 16) & 0x00FF, /* Month */
5604 (ioc
->facts
.FWVersion
.Word
>> 8) & 0x1F); /* Day */
5607 if ((ioc
->facts
.FWVersion
.Word
>> 8) & 0x80)
5608 strcat(buf
, " [MDBG]");
5612 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5614 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
5615 * @ioc: Pointer to MPT_ADAPTER structure
5616 * @buffer: Pointer to buffer where IOC summary info should be written
5617 * @size: Pointer to number of bytes we wrote (set by this routine)
5618 * @len: Offset at which to start writing in buffer
5619 * @showlan: Display LAN stuff?
5621 * This routine writes (english readable) ASCII text, which represents
5622 * a summary of IOC information, to a buffer.
5625 mpt_print_ioc_summary(MPT_ADAPTER
*ioc
, char *buffer
, int *size
, int len
, int showlan
)
5630 mpt_get_fw_exp_ver(expVer
, ioc
);
5633 * Shorter summary of attached ioc's...
5635 y
= sprintf(buffer
+len
, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
5638 MPT_FW_REV_MAGIC_ID_STRING
, /* "FwRev=" or somesuch */
5639 ioc
->facts
.FWVersion
.Word
,
5641 ioc
->facts
.NumberOfPorts
,
5644 if (showlan
&& (ioc
->pfacts
[0].ProtocolFlags
& MPI_PORTFACTS_PROTOCOL_LAN
)) {
5645 u8
*a
= (u8
*)&ioc
->lan_cnfg_page1
.HardwareAddressLow
;
5646 y
+= sprintf(buffer
+len
+y
, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
5647 a
[5], a
[4], a
[3], a
[2], a
[1], a
[0]);
5651 y
+= sprintf(buffer
+len
+y
, ", IRQ=%d", ioc
->pci_irq
);
5653 y
+= sprintf(buffer
+len
+y
, ", IRQ=%s", __irq_itoa(ioc
->pci_irq
));
5657 y
+= sprintf(buffer
+len
+y
, " (disabled)");
5659 y
+= sprintf(buffer
+len
+y
, "\n");
5664 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5668 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5670 * mpt_HardResetHandler - Generic reset handler, issue SCSI Task
5671 * Management call based on input arg values. If TaskMgmt fails,
5672 * return associated SCSI request.
5673 * @ioc: Pointer to MPT_ADAPTER structure
5674 * @sleepFlag: Indicates if sleep or schedule must be called.
5676 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
5677 * or a non-interrupt thread. In the former, must not call schedule().
5679 * Remark: A return of -1 is a FATAL error case, as it means a
5680 * FW reload/initialization failed.
5682 * Returns 0 for SUCCESS or -1 if FAILED.
5685 mpt_HardResetHandler(MPT_ADAPTER
*ioc
, int sleepFlag
)
5688 unsigned long flags
;
5690 dtmprintk((MYIOC_s_INFO_FMT
"HardResetHandler Entered!\n", ioc
->name
));
5692 printk(MYIOC_s_INFO_FMT
"HardResetHandler Entered!\n", ioc
->name
);
5693 printk("MF count 0x%x !\n", ioc
->mfcnt
);
5696 /* Reset the adapter. Prevent more than 1 call to
5697 * mpt_do_ioc_recovery at any instant in time.
5699 spin_lock_irqsave(&ioc
->diagLock
, flags
);
5700 if ((ioc
->diagPending
) || (ioc
->alt_ioc
&& ioc
->alt_ioc
->diagPending
)){
5701 spin_unlock_irqrestore(&ioc
->diagLock
, flags
);
5704 ioc
->diagPending
= 1;
5706 spin_unlock_irqrestore(&ioc
->diagLock
, flags
);
5708 /* FIXME: If do_ioc_recovery fails, repeat....
5711 /* The SCSI driver needs to adjust timeouts on all current
5712 * commands prior to the diagnostic reset being issued.
5713 * Prevents timeouts occuring during a diagnostic reset...very bad.
5714 * For all other protocol drivers, this is a no-op.
5720 for (ii
=MPT_MAX_PROTOCOL_DRIVERS
-1; ii
; ii
--) {
5721 if (MptResetHandlers
[ii
]) {
5722 dtmprintk((MYIOC_s_INFO_FMT
"Calling IOC reset_setup handler #%d\n",
5724 r
+= mpt_signal_reset(ii
, ioc
, MPT_IOC_SETUP_RESET
);
5726 dtmprintk((MYIOC_s_INFO_FMT
"Calling alt-%s setup reset handler #%d\n",
5727 ioc
->name
, ioc
->alt_ioc
->name
, ii
));
5728 r
+= mpt_signal_reset(ii
, ioc
->alt_ioc
, MPT_IOC_SETUP_RESET
);
5734 if ((rc
= mpt_do_ioc_recovery(ioc
, MPT_HOSTEVENT_IOC_RECOVER
, sleepFlag
)) != 0) {
5735 printk(KERN_WARNING MYNAM
": WARNING - (%d) Cannot recover %s\n",
5740 ioc
->alt_ioc
->reload_fw
= 0;
5742 spin_lock_irqsave(&ioc
->diagLock
, flags
);
5743 ioc
->diagPending
= 0;
5745 ioc
->alt_ioc
->diagPending
= 0;
5746 spin_unlock_irqrestore(&ioc
->diagLock
, flags
);
5748 dtmprintk((MYIOC_s_INFO_FMT
"HardResetHandler rc = %d!\n", ioc
->name
, rc
));
5753 # define EVENT_DESCR_STR_SZ 100
5755 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5757 EventDescriptionStr(u8 event
, u32 evData0
, char *evStr
)
5762 case MPI_EVENT_NONE
:
5765 case MPI_EVENT_LOG_DATA
:
5768 case MPI_EVENT_STATE_CHANGE
:
5769 ds
= "State Change";
5771 case MPI_EVENT_UNIT_ATTENTION
:
5772 ds
= "Unit Attention";
5774 case MPI_EVENT_IOC_BUS_RESET
:
5775 ds
= "IOC Bus Reset";
5777 case MPI_EVENT_EXT_BUS_RESET
:
5778 ds
= "External Bus Reset";
5780 case MPI_EVENT_RESCAN
:
5781 ds
= "Bus Rescan Event";
5782 /* Ok, do we need to do anything here? As far as
5783 I can tell, this is when a new device gets added
5786 case MPI_EVENT_LINK_STATUS_CHANGE
:
5787 if (evData0
== MPI_EVENT_LINK_STATUS_FAILURE
)
5788 ds
= "Link Status(FAILURE) Change";
5790 ds
= "Link Status(ACTIVE) Change";
5792 case MPI_EVENT_LOOP_STATE_CHANGE
:
5793 if (evData0
== MPI_EVENT_LOOP_STATE_CHANGE_LIP
)
5794 ds
= "Loop State(LIP) Change";
5795 else if (evData0
== MPI_EVENT_LOOP_STATE_CHANGE_LPE
)
5796 ds
= "Loop State(LPE) Change"; /* ??? */
5798 ds
= "Loop State(LPB) Change"; /* ??? */
5800 case MPI_EVENT_LOGOUT
:
5803 case MPI_EVENT_EVENT_CHANGE
:
5805 ds
= "Events(ON) Change";
5807 ds
= "Events(OFF) Change";
5809 case MPI_EVENT_INTEGRATED_RAID
:
5811 u8 ReasonCode
= (u8
)(evData0
>> 16);
5812 switch (ReasonCode
) {
5813 case MPI_EVENT_RAID_RC_VOLUME_CREATED
:
5814 ds
= "Integrated Raid: Volume Created";
5816 case MPI_EVENT_RAID_RC_VOLUME_DELETED
:
5817 ds
= "Integrated Raid: Volume Deleted";
5819 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED
:
5820 ds
= "Integrated Raid: Volume Settings Changed";
5822 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED
:
5823 ds
= "Integrated Raid: Volume Status Changed";
5825 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED
:
5826 ds
= "Integrated Raid: Volume Physdisk Changed";
5828 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED
:
5829 ds
= "Integrated Raid: Physdisk Created";
5831 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED
:
5832 ds
= "Integrated Raid: Physdisk Deleted";
5834 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED
:
5835 ds
= "Integrated Raid: Physdisk Settings Changed";
5837 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED
:
5838 ds
= "Integrated Raid: Physdisk Status Changed";
5840 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
:
5841 ds
= "Integrated Raid: Domain Validation Needed";
5843 case MPI_EVENT_RAID_RC_SMART_DATA
:
5844 ds
= "Integrated Raid; Smart Data";
5846 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED
:
5847 ds
= "Integrated Raid: Replace Action Started";
5850 ds
= "Integrated Raid";
5855 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE
:
5856 ds
= "SCSI Device Status Change";
5858 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE
:
5860 u8 id
= (u8
)(evData0
);
5861 u8 ReasonCode
= (u8
)(evData0
>> 16);
5862 switch (ReasonCode
) {
5863 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED
:
5864 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
5865 "SAS Device Status Change: Added: id=%d", id
);
5867 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING
:
5868 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
5869 "SAS Device Status Change: Deleted: id=%d", id
);
5871 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA
:
5872 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
5873 "SAS Device Status Change: SMART Data: id=%d",
5876 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED
:
5877 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
5878 "SAS Device Status Change: No Persistancy "
5879 "Added: id=%d", id
);
5882 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
5883 "SAS Device Status Change: Unknown: id=%d", id
);
5888 case MPI_EVENT_ON_BUS_TIMER_EXPIRED
:
5889 ds
= "Bus Timer Expired";
5891 case MPI_EVENT_QUEUE_FULL
:
5894 case MPI_EVENT_SAS_SES
:
5895 ds
= "SAS SES Event";
5897 case MPI_EVENT_PERSISTENT_TABLE_FULL
:
5898 ds
= "Persistent Table Full";
5900 case MPI_EVENT_SAS_PHY_LINK_STATUS
:
5902 u8 LinkRates
= (u8
)(evData0
>> 8);
5903 u8 PhyNumber
= (u8
)(evData0
);
5904 LinkRates
= (LinkRates
& MPI_EVENT_SAS_PLS_LR_CURRENT_MASK
) >>
5905 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT
;
5906 switch (LinkRates
) {
5907 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN
:
5908 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
5909 "SAS PHY Link Status: Phy=%d:"
5910 " Rate Unknown",PhyNumber
);
5912 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED
:
5913 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
5914 "SAS PHY Link Status: Phy=%d:"
5915 " Phy Disabled",PhyNumber
);
5917 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION
:
5918 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
5919 "SAS PHY Link Status: Phy=%d:"
5920 " Failed Speed Nego",PhyNumber
);
5922 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE
:
5923 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
5924 "SAS PHY Link Status: Phy=%d:"
5925 " Sata OOB Completed",PhyNumber
);
5927 case MPI_EVENT_SAS_PLS_LR_RATE_1_5
:
5928 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
5929 "SAS PHY Link Status: Phy=%d:"
5930 " Rate 1.5 Gbps",PhyNumber
);
5932 case MPI_EVENT_SAS_PLS_LR_RATE_3_0
:
5933 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
5934 "SAS PHY Link Status: Phy=%d:"
5935 " Rate 3.0 Gpbs",PhyNumber
);
5938 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
5939 "SAS PHY Link Status: Phy=%d", PhyNumber
);
5944 case MPI_EVENT_SAS_DISCOVERY_ERROR
:
5945 ds
= "SAS Discovery Error";
5947 case MPI_EVENT_IR_RESYNC_UPDATE
:
5949 u8 resync_complete
= (u8
)(evData0
>> 16);
5950 snprintf(evStr
, EVENT_DESCR_STR_SZ
,
5951 "IR Resync Update: Complete = %d:",resync_complete
);
5956 u8 ReasonCode
= (u8
)(evData0
>> 16);
5957 switch (ReasonCode
) {
5958 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED
:
5959 ds
= "IR2: LD State Changed";
5961 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED
:
5962 ds
= "IR2: PD State Changed";
5964 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL
:
5965 ds
= "IR2: Bad Block Table Full";
5967 case MPI_EVENT_IR2_RC_PD_INSERTED
:
5968 ds
= "IR2: PD Inserted";
5970 case MPI_EVENT_IR2_RC_PD_REMOVED
:
5971 ds
= "IR2: PD Removed";
5973 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED
:
5974 ds
= "IR2: Foreign CFG Detected";
5976 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR
:
5977 ds
= "IR2: Rebuild Medium Error";
5985 case MPI_EVENT_SAS_DISCOVERY
:
5988 ds
= "SAS Discovery: Start";
5990 ds
= "SAS Discovery: Stop";
5993 case MPI_EVENT_LOG_ENTRY_ADDED
:
5994 ds
= "SAS Log Entry Added";
5998 * MPT base "custom" events may be added here...
6005 strncpy(evStr
, ds
, EVENT_DESCR_STR_SZ
);
6008 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6010 * ProcessEventNotification - Route a received EventNotificationReply to
6011 * all currently regeistered event handlers.
6012 * @ioc: Pointer to MPT_ADAPTER structure
6013 * @pEventReply: Pointer to EventNotification reply frame
6014 * @evHandlers: Pointer to integer, number of event handlers
6016 * Returns sum of event handlers return values.
6019 ProcessEventNotification(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*pEventReply
, int *evHandlers
)
6027 char evStr
[EVENT_DESCR_STR_SZ
];
6031 * Do platform normalization of values
6033 event
= le32_to_cpu(pEventReply
->Event
) & 0xFF;
6034 // evCtx = le32_to_cpu(pEventReply->EventContext);
6035 evDataLen
= le16_to_cpu(pEventReply
->EventDataLength
);
6037 evData0
= le32_to_cpu(pEventReply
->Data
[0]);
6040 EventDescriptionStr(event
, evData0
, evStr
);
6041 devtprintk((MYIOC_s_INFO_FMT
"MPT event:(%02Xh) : %s\n",
6046 #if defined(MPT_DEBUG) || defined(MPT_DEBUG_VERBOSE_EVENTS)
6047 printk(KERN_INFO MYNAM
": Event data:\n" KERN_INFO
);
6048 for (ii
= 0; ii
< evDataLen
; ii
++)
6049 printk(" %08x", le32_to_cpu(pEventReply
->Data
[ii
]));
6054 * Do general / base driver event processing
6057 case MPI_EVENT_EVENT_CHANGE
: /* 0A */
6059 u8 evState
= evData0
& 0xFF;
6061 /* CHECKME! What if evState unexpectedly says OFF (0)? */
6063 /* Update EventState field in cached IocFacts */
6064 if (ioc
->facts
.Function
) {
6065 ioc
->facts
.EventState
= evState
;
6069 case MPI_EVENT_INTEGRATED_RAID
:
6070 mptbase_raid_process_event_data(ioc
,
6071 (MpiEventDataRaid_t
*)pEventReply
->Data
);
6078 * Should this event be logged? Events are written sequentially.
6079 * When buffer is full, start again at the top.
6081 if (ioc
->events
&& (ioc
->eventTypes
& ( 1 << event
))) {
6084 idx
= ioc
->eventContext
% MPTCTL_EVENT_LOG_SIZE
;
6086 ioc
->events
[idx
].event
= event
;
6087 ioc
->events
[idx
].eventContext
= ioc
->eventContext
;
6089 for (ii
= 0; ii
< 2; ii
++) {
6091 ioc
->events
[idx
].data
[ii
] = le32_to_cpu(pEventReply
->Data
[ii
]);
6093 ioc
->events
[idx
].data
[ii
] = 0;
6096 ioc
->eventContext
++;
6101 * Call each currently registered protocol event handler.
6103 for (ii
=MPT_MAX_PROTOCOL_DRIVERS
-1; ii
; ii
--) {
6104 if (MptEvHandlers
[ii
]) {
6105 devtverboseprintk((MYIOC_s_INFO_FMT
"Routing Event to event handler #%d\n",
6107 r
+= (*(MptEvHandlers
[ii
]))(ioc
, pEventReply
);
6111 /* FIXME? Examine results here? */
6114 * If needed, send (a single) EventAck.
6116 if (pEventReply
->AckRequired
== MPI_EVENT_NOTIFICATION_ACK_REQUIRED
) {
6117 devtverboseprintk((MYIOC_s_WARN_FMT
6118 "EventAck required\n",ioc
->name
));
6119 if ((ii
= SendEventAck(ioc
, pEventReply
)) != 0) {
6120 devtverboseprintk((MYIOC_s_WARN_FMT
"SendEventAck returned %d\n",
6125 *evHandlers
= handlers
;
6129 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6131 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
6132 * @ioc: Pointer to MPT_ADAPTER structure
6133 * @log_info: U32 LogInfo reply word from the IOC
6135 * Refer to lsi/fc_log.h.
6138 mpt_fc_log_info(MPT_ADAPTER
*ioc
, u32 log_info
)
6140 static char *subcl_str
[8] = {
6141 "FCP Initiator", "FCP Target", "LAN", "MPI Message Layer",
6142 "FC Link", "Context Manager", "Invalid Field Offset", "State Change Info"
6144 u8 subcl
= (log_info
>> 24) & 0x7;
6146 printk(MYIOC_s_INFO_FMT
"LogInfo(0x%08x): SubCl={%s}\n",
6147 ioc
->name
, log_info
, subcl_str
[subcl
]);
6150 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6152 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
6153 * @ioc: Pointer to MPT_ADAPTER structure
6154 * @mr: Pointer to MPT reply frame
6155 * @log_info: U32 LogInfo word from the IOC
6157 * Refer to lsi/sp_log.h.
6160 mpt_spi_log_info(MPT_ADAPTER
*ioc
, u32 log_info
)
6162 u32 info
= log_info
& 0x00FF0000;
6163 char *desc
= "unknown";
6167 desc
= "bug! MID not found";
6168 if (ioc
->reload_fw
== 0)
6173 desc
= "Parity Error";
6177 desc
= "ASYNC Outbound Overrun";
6181 desc
= "SYNC Offset Error";
6189 desc
= "Msg In Overflow";
6197 desc
= "Outbound DMA Overrun";
6201 desc
= "Task Management";
6205 desc
= "Device Problem";
6209 desc
= "Invalid Phase Change";
6213 desc
= "Untagged Table Size";
6218 printk(MYIOC_s_INFO_FMT
"LogInfo(0x%08x): F/W: %s\n", ioc
->name
, log_info
, desc
);
6221 /* strings for sas loginfo */
6222 static char *originator_str
[] = {
6227 static char *iop_code_str
[] = {
6229 "Invalid SAS Address", /* 01h */
6231 "Invalid Page", /* 03h */
6233 "Task Terminated" /* 05h */
6235 static char *pl_code_str
[] = {
6237 "Open Failure", /* 01h */
6238 "Invalid Scatter Gather List", /* 02h */
6239 "Wrong Relative Offset or Frame Length", /* 03h */
6240 "Frame Transfer Error", /* 04h */
6241 "Transmit Frame Connected Low", /* 05h */
6242 "SATA Non-NCQ RW Error Bit Set", /* 06h */
6243 "SATA Read Log Receive Data Error", /* 07h */
6244 "SATA NCQ Fail All Commands After Error", /* 08h */
6245 "SATA Error in Receive Set Device Bit FIS", /* 09h */
6246 "Receive Frame Invalid Message", /* 0Ah */
6247 "Receive Context Message Valid Error", /* 0Bh */
6248 "Receive Frame Current Frame Error", /* 0Ch */
6249 "SATA Link Down", /* 0Dh */
6250 "Discovery SATA Init W IOS", /* 0Eh */
6251 "Config Invalid Page", /* 0Fh */
6252 "Discovery SATA Init Timeout", /* 10h */
6255 "IO Not Yet Executed", /* 13h */
6256 "IO Executed", /* 14h */
6257 "Persistant Reservation Out Not Affiliation Owner", /* 15h */
6258 "Open Transmit DMA Abort", /* 16h */
6268 "Enclosure Management" /* 20h */
6271 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6273 * mpt_sas_log_info - Log information returned from SAS IOC.
6274 * @ioc: Pointer to MPT_ADAPTER structure
6275 * @log_info: U32 LogInfo reply word from the IOC
6277 * Refer to lsi/mpi_log_sas.h.
6280 mpt_sas_log_info(MPT_ADAPTER
*ioc
, u32 log_info
)
6282 union loginfo_type
{
6291 union loginfo_type sas_loginfo
;
6292 char *code_desc
= NULL
;
6294 sas_loginfo
.loginfo
= log_info
;
6295 if ((sas_loginfo
.dw
.bus_type
!= 3 /*SAS*/) &&
6296 (sas_loginfo
.dw
.originator
< sizeof(originator_str
)/sizeof(char*)))
6298 if ((sas_loginfo
.dw
.originator
== 0 /*IOP*/) &&
6299 (sas_loginfo
.dw
.code
< sizeof(iop_code_str
)/sizeof(char*))) {
6300 code_desc
= iop_code_str
[sas_loginfo
.dw
.code
];
6301 }else if ((sas_loginfo
.dw
.originator
== 1 /*PL*/) &&
6302 (sas_loginfo
.dw
.code
< sizeof(pl_code_str
)/sizeof(char*) )) {
6303 code_desc
= pl_code_str
[sas_loginfo
.dw
.code
];
6306 if (code_desc
!= NULL
)
6307 printk(MYIOC_s_INFO_FMT
6308 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
6309 " SubCode(0x%04x)\n",
6312 originator_str
[sas_loginfo
.dw
.originator
],
6314 sas_loginfo
.dw
.subcode
);
6316 printk(MYIOC_s_INFO_FMT
6317 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
6318 " SubCode(0x%04x)\n",
6321 originator_str
[sas_loginfo
.dw
.originator
],
6322 sas_loginfo
.dw
.code
,
6323 sas_loginfo
.dw
.subcode
);
6326 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6328 * mpt_sp_ioc_info - IOC information returned from SCSI Parallel IOC.
6329 * @ioc: Pointer to MPT_ADAPTER structure
6330 * @ioc_status: U32 IOCStatus word from IOC
6331 * @mf: Pointer to MPT request frame
6333 * Refer to lsi/mpi.h.
6336 mpt_sp_ioc_info(MPT_ADAPTER
*ioc
, u32 ioc_status
, MPT_FRAME_HDR
*mf
)
6338 u32 status
= ioc_status
& MPI_IOCSTATUS_MASK
;
6342 case MPI_IOCSTATUS_INVALID_FUNCTION
: /* 0x0001 */
6343 desc
= "Invalid Function";
6346 case MPI_IOCSTATUS_BUSY
: /* 0x0002 */
6350 case MPI_IOCSTATUS_INVALID_SGL
: /* 0x0003 */
6351 desc
= "Invalid SGL";
6354 case MPI_IOCSTATUS_INTERNAL_ERROR
: /* 0x0004 */
6355 desc
= "Internal Error";
6358 case MPI_IOCSTATUS_RESERVED
: /* 0x0005 */
6362 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES
: /* 0x0006 */
6363 desc
= "Insufficient Resources";
6366 case MPI_IOCSTATUS_INVALID_FIELD
: /* 0x0007 */
6367 desc
= "Invalid Field";
6370 case MPI_IOCSTATUS_INVALID_STATE
: /* 0x0008 */
6371 desc
= "Invalid State";
6374 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION
: /* 0x0020 */
6375 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE
: /* 0x0021 */
6376 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE
: /* 0x0022 */
6377 case MPI_IOCSTATUS_CONFIG_INVALID_DATA
: /* 0x0023 */
6378 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS
: /* 0x0024 */
6379 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT
: /* 0x0025 */
6380 /* No message for Config IOCStatus values */
6383 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR
: /* 0x0040 */
6384 /* No message for recovered error
6385 desc = "SCSI Recovered Error";
6389 case MPI_IOCSTATUS_SCSI_INVALID_BUS
: /* 0x0041 */
6390 desc
= "SCSI Invalid Bus";
6393 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID
: /* 0x0042 */
6394 desc
= "SCSI Invalid TargetID";
6397 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE
: /* 0x0043 */
6399 SCSIIORequest_t
*pScsiReq
= (SCSIIORequest_t
*) mf
;
6400 U8 cdb
= pScsiReq
->CDB
[0];
6401 if (cdb
!= 0x12) { /* Inquiry is issued for device scanning */
6402 desc
= "SCSI Device Not There";
6407 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN
: /* 0x0044 */
6408 desc
= "SCSI Data Overrun";
6411 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN
: /* 0x0045 */
6412 /* This error is checked in scsi_io_done(). Skip.
6413 desc = "SCSI Data Underrun";
6417 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR
: /* 0x0046 */
6418 desc
= "SCSI I/O Data Error";
6421 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR
: /* 0x0047 */
6422 desc
= "SCSI Protocol Error";
6425 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED
: /* 0x0048 */
6426 desc
= "SCSI Task Terminated";
6429 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH
: /* 0x0049 */
6430 desc
= "SCSI Residual Mismatch";
6433 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED
: /* 0x004A */
6434 desc
= "SCSI Task Management Failed";
6437 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED
: /* 0x004B */
6438 desc
= "SCSI IOC Terminated";
6441 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED
: /* 0x004C */
6442 desc
= "SCSI Ext Terminated";
6450 printk(MYIOC_s_INFO_FMT
"IOCStatus(0x%04x): %s\n", ioc
->name
, status
, desc
);
6453 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6454 EXPORT_SYMBOL(mpt_attach
);
6455 EXPORT_SYMBOL(mpt_detach
);
6457 EXPORT_SYMBOL(mpt_resume
);
6458 EXPORT_SYMBOL(mpt_suspend
);
6460 EXPORT_SYMBOL(ioc_list
);
6461 EXPORT_SYMBOL(mpt_proc_root_dir
);
6462 EXPORT_SYMBOL(mpt_register
);
6463 EXPORT_SYMBOL(mpt_deregister
);
6464 EXPORT_SYMBOL(mpt_event_register
);
6465 EXPORT_SYMBOL(mpt_event_deregister
);
6466 EXPORT_SYMBOL(mpt_reset_register
);
6467 EXPORT_SYMBOL(mpt_reset_deregister
);
6468 EXPORT_SYMBOL(mpt_device_driver_register
);
6469 EXPORT_SYMBOL(mpt_device_driver_deregister
);
6470 EXPORT_SYMBOL(mpt_get_msg_frame
);
6471 EXPORT_SYMBOL(mpt_put_msg_frame
);
6472 EXPORT_SYMBOL(mpt_free_msg_frame
);
6473 EXPORT_SYMBOL(mpt_add_sge
);
6474 EXPORT_SYMBOL(mpt_send_handshake_request
);
6475 EXPORT_SYMBOL(mpt_verify_adapter
);
6476 EXPORT_SYMBOL(mpt_GetIocState
);
6477 EXPORT_SYMBOL(mpt_print_ioc_summary
);
6478 EXPORT_SYMBOL(mpt_lan_index
);
6479 EXPORT_SYMBOL(mpt_stm_index
);
6480 EXPORT_SYMBOL(mpt_HardResetHandler
);
6481 EXPORT_SYMBOL(mpt_config
);
6482 EXPORT_SYMBOL(mpt_findImVolumes
);
6483 EXPORT_SYMBOL(mpt_alloc_fw_memory
);
6484 EXPORT_SYMBOL(mpt_free_fw_memory
);
6485 EXPORT_SYMBOL(mptbase_sas_persist_operation
);
6486 EXPORT_SYMBOL(mptbase_GetFcPortPage0
);
6489 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6491 * fusion_init - Fusion MPT base driver initialization routine.
6493 * Returns 0 for success, non-zero for failure.
6500 show_mptmod_ver(my_NAME
, my_VERSION
);
6501 printk(KERN_INFO COPYRIGHT
"\n");
6503 for (i
= 0; i
< MPT_MAX_PROTOCOL_DRIVERS
; i
++) {
6504 MptCallbacks
[i
] = NULL
;
6505 MptDriverClass
[i
] = MPTUNKNOWN_DRIVER
;
6506 MptEvHandlers
[i
] = NULL
;
6507 MptResetHandlers
[i
] = NULL
;
6510 /* Register ourselves (mptbase) in order to facilitate
6511 * EventNotification handling.
6513 mpt_base_index
= mpt_register(mpt_base_reply
, MPTBASE_DRIVER
);
6515 /* Register for hard reset handling callbacks.
6517 if (mpt_reset_register(mpt_base_index
, mpt_ioc_reset
) == 0) {
6518 dprintk((KERN_INFO MYNAM
": Register for IOC reset notification\n"));
6523 #ifdef CONFIG_PROC_FS
6524 (void) procmpt_create();
6529 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6531 * fusion_exit - Perform driver unload cleanup.
6533 * This routine frees all resources associated with each MPT adapter
6534 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
6540 dexitprintk((KERN_INFO MYNAM
": fusion_exit() called!\n"));
6542 mpt_reset_deregister(mpt_base_index
);
6544 #ifdef CONFIG_PROC_FS
6549 module_init(fusion_init
);
6550 module_exit(fusion_exit
);