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);
1608 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1610 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1611 * @ioc: Pointer to MPT adapter structure
1612 * @reason: Event word / reason
1613 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1615 * This routine performs all the steps necessary to bring the IOC
1616 * to a OPERATIONAL state.
1618 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1623 * -1 if failed to get board READY
1624 * -2 if READY but IOCFacts Failed
1625 * -3 if READY but PrimeIOCFifos Failed
1626 * -4 if READY but IOCInit Failed
1629 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1631 int hard_reset_done = 0;
1632 int alt_ioc_ready = 0;
1638 int reset_alt_ioc_active = 0;
1640 printk(KERN_INFO MYNAM ": Initiating %s %s\n",
1641 ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
1643 /* Disable reply interrupts (also blocks FreeQ) */
1644 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1648 if (ioc->alt_ioc->active)
1649 reset_alt_ioc_active = 1;
1651 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1652 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
1653 ioc->alt_ioc->active = 0;
1657 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
1660 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
1661 if (hard_reset_done == -4) {
1662 printk(KERN_WARNING MYNAM ": %s Owned by PEER..skipping!\n",
1665 if (reset_alt_ioc_active && ioc->alt_ioc) {
1666 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1667 dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1668 ioc->alt_ioc->name));
1669 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
1670 ioc->alt_ioc->active = 1;
1674 printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",
1680 /* hard_reset_done = 0 if a soft reset was performed
1681 * and 1 if a hard reset was performed.
1683 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
1684 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
1687 printk(KERN_WARNING MYNAM
1688 ": alt-%s: Not ready WARNING!\n",
1689 ioc->alt_ioc->name);
1692 for (ii=0; ii<5; ii++) {
1693 /* Get IOC facts! Allow 5 retries */
1694 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
1700 dinitprintk((MYIOC_s_INFO_FMT "Retry IocFacts failed rc=%x\n", ioc->name, rc));
1702 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1703 MptDisplayIocCapabilities(ioc);
1706 if (alt_ioc_ready) {
1707 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
1708 dinitprintk((MYIOC_s_INFO_FMT "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
1709 /* Retry - alt IOC was initialized once
1711 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
1714 dinitprintk((MYIOC_s_INFO_FMT "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
1716 reset_alt_ioc_active = 0;
1717 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1718 MptDisplayIocCapabilities(ioc->alt_ioc);
1722 /* Prime reply & request queues!
1723 * (mucho alloc's) Must be done prior to
1724 * init as upper addresses are needed for init.
1725 * If fails, continue with alt-ioc processing
1727 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
1730 /* May need to check/upload firmware & data here!
1731 * If fails, continue with alt-ioc processing
1733 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
1736 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
1737 printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
1738 ioc->alt_ioc->name, rc);
1740 reset_alt_ioc_active = 0;
1743 if (alt_ioc_ready) {
1744 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
1746 reset_alt_ioc_active = 0;
1747 printk(KERN_WARNING MYNAM
1748 ": alt-%s: (%d) init failure WARNING!\n",
1749 ioc->alt_ioc->name, rc);
1753 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
1754 if (ioc->upload_fw) {
1755 ddlprintk((MYIOC_s_INFO_FMT
1756 "firmware upload required!\n", ioc->name));
1758 /* Controller is not operational, cannot do upload
1761 rc = mpt_do_upload(ioc, sleepFlag);
1763 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
1765 * Maintain only one pointer to FW memory
1766 * so there will not be two attempt to
1767 * downloadboot onboard dual function
1768 * chips (mpt_adapter_disable,
1771 ioc->cached_fw = NULL;
1772 ddlprintk((MYIOC_s_INFO_FMT ": mpt_upload: alt_%s has cached_fw=%p \n",
1773 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
1776 printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
1784 /* Enable! (reply interrupt) */
1785 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
1789 if (reset_alt_ioc_active && ioc->alt_ioc) {
1790 /* (re)Enable alt-IOC! (reply interrupt) */
1791 dinitprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1792 ioc->alt_ioc->name));
1793 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
1794 ioc->alt_ioc->active = 1;
1797 /* Enable MPT base driver management of EventNotification
1798 * and EventAck handling.
1800 if ((ret == 0) && (!ioc->facts.EventState))
1801 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
1803 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
1804 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
1806 /* Add additional "reason" check before call to GetLanConfigPages
1807 * (combined with GetIoUnitPage2 call). This prevents a somewhat
1808 * recursive scenario; GetLanConfigPages times out, timer expired
1809 * routine calls HardResetHandler, which calls into here again,
1810 * and we try GetLanConfigPages again...
1812 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1813 if (ioc->bus_type == SAS) {
1815 /* clear persistency table */
1816 if(ioc->facts.IOCExceptions &
1817 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
1818 ret = mptbase_sas_persist_operation(ioc,
1819 MPI_SAS_OP_CLEAR_NOT_PRESENT);
1826 mpt_findImVolumes(ioc);
1828 } else if (ioc->bus_type == FC) {
1830 * Pre-fetch FC port WWN and stuff...
1831 * (FCPortPage0_t stuff)
1833 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1834 (void) mptbase_GetFcPortPage0(ioc, ii);
1837 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
1838 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
1840 * Pre-fetch the ports LAN MAC address!
1841 * (LANPage1_t stuff)
1843 (void) GetLanConfigPages(ioc);
1846 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
1847 dprintk((MYIOC_s_INFO_FMT "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
1848 ioc->name, a[5], a[4], a[3], a[2], a[1], a[0] ));
1853 /* Get NVRAM and adapter maximums from SPP 0 and 2
1855 mpt_GetScsiPortSettings(ioc, 0);
1857 /* Get version and length of SDP 1
1859 mpt_readScsiDevicePageHeaders(ioc, 0);
1863 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
1864 mpt_findImVolumes(ioc);
1866 /* Check, and possibly reset, the coalescing value
1868 mpt_read_ioc_pg_1(ioc);
1870 mpt_read_ioc_pg_4(ioc);
1873 GetIoUnitPage2(ioc);
1877 * Call each currently registered protocol IOC reset handler
1878 * with post-reset indication.
1879 * NOTE: If we're doing _IOC_BRINGUP, there can be no
1880 * MptResetHandlers[] registered yet.
1882 if (hard_reset_done) {
1884 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
1885 if ((ret == 0) && MptResetHandlers[ii]) {
1886 dprintk((MYIOC_s_INFO_FMT "Calling IOC post_reset handler #%d\n",
1888 rc += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_POST_RESET);
1892 if (alt_ioc_ready && MptResetHandlers[ii]) {
1893 drsprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",
1894 ioc->name, ioc->alt_ioc->name, ii));
1895 rc += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_POST_RESET);
1899 /* FIXME? Examine results here? */
1905 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1907 * mpt_detect_bound_ports - Search for PCI bus/dev_function
1908 * which matches PCI bus/dev_function (+/-1) for newly discovered 929,
1909 * 929X, 1030 or 1035.
1910 * @ioc: Pointer to MPT adapter structure
1911 * @pdev: Pointer to (struct pci_dev) structure
1913 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
1914 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
1917 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
1919 struct pci_dev *peer=NULL;
1920 unsigned int slot = PCI_SLOT(pdev->devfn);
1921 unsigned int func = PCI_FUNC(pdev->devfn);
1922 MPT_ADAPTER *ioc_srch;
1924 dprintk((MYIOC_s_INFO_FMT "PCI device %s devfn=%x/%x,"
1925 " searching for devfn match on %x or %x\n",
1926 ioc->name, pci_name(pdev), pdev->bus->number,
1927 pdev->devfn, func-1, func+1));
1929 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
1931 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
1936 list_for_each_entry(ioc_srch, &ioc_list, list) {
1937 struct pci_dev *_pcidev = ioc_srch->pcidev;
1938 if (_pcidev == peer) {
1939 /* Paranoia checks */
1940 if (ioc->alt_ioc != NULL) {
1941 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1942 ioc->name, ioc->alt_ioc->name);
1944 } else if (ioc_srch->alt_ioc != NULL) {
1945 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1946 ioc_srch->name, ioc_srch->alt_ioc->name);
1949 dprintk((KERN_INFO MYNAM ": FOUND! binding %s <==> %s\n",
1950 ioc->name, ioc_srch->name));
1951 ioc_srch->alt_ioc = ioc;
1952 ioc->alt_ioc = ioc_srch;
1958 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1960 * mpt_adapter_disable - Disable misbehaving MPT adapter.
1961 * @this: Pointer to MPT adapter structure
1964 mpt_adapter_disable(MPT_ADAPTER *ioc)
1969 if (ioc->cached_fw != NULL) {
1970 ddlprintk((KERN_INFO MYNAM ": mpt_adapter_disable: Pushing FW onto adapter\n"));
1971 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)ioc->cached_fw, NO_SLEEP)) < 0) {
1972 printk(KERN_WARNING MYNAM
1973 ": firmware downloadboot failure (%d)!\n", ret);
1977 /* Disable adapter interrupts! */
1978 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1980 /* Clear any lingering interrupt */
1981 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1983 if (ioc->alloc != NULL) {
1985 dexitprintk((KERN_INFO MYNAM ": %s.free @ %p, sz=%d bytes\n",
1986 ioc->name, ioc->alloc, ioc->alloc_sz));
1987 pci_free_consistent(ioc->pcidev, sz,
1988 ioc->alloc, ioc->alloc_dma);
1989 ioc->reply_frames = NULL;
1990 ioc->req_frames = NULL;
1992 ioc->alloc_total -= sz;
1995 if (ioc->sense_buf_pool != NULL) {
1996 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
1997 pci_free_consistent(ioc->pcidev, sz,
1998 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
1999 ioc->sense_buf_pool = NULL;
2000 ioc->alloc_total -= sz;
2003 if (ioc->events != NULL){
2004 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2007 ioc->alloc_total -= sz;
2010 if (ioc->cached_fw != NULL) {
2011 sz = ioc->facts.FWImageSize;
2012 pci_free_consistent(ioc->pcidev, sz,
2013 ioc->cached_fw, ioc->cached_fw_dma);
2014 ioc->cached_fw = NULL;
2015 ioc->alloc_total -= sz;
2018 kfree(ioc->spi_data.nvram);
2019 kfree(ioc->raid_data.pIocPg3);
2020 ioc->spi_data.nvram = NULL;
2021 ioc->raid_data.pIocPg3 = NULL;
2023 if (ioc->spi_data.pIocPg4 != NULL) {
2024 sz = ioc->spi_data.IocPg4Sz;
2025 pci_free_consistent(ioc->pcidev, sz,
2026 ioc->spi_data.pIocPg4,
2027 ioc->spi_data.IocPg4_dma);
2028 ioc->spi_data.pIocPg4 = NULL;
2029 ioc->alloc_total -= sz;
2032 if (ioc->ReqToChain != NULL) {
2033 kfree(ioc->ReqToChain);
2034 kfree(ioc->RequestNB);
2035 ioc->ReqToChain = NULL;
2038 kfree(ioc->ChainToChain);
2039 ioc->ChainToChain = NULL;
2041 if (ioc->HostPageBuffer != NULL) {
2042 if((ret = mpt_host_page_access_control(ioc,
2043 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2044 printk(KERN_ERR MYNAM
2045 ": %s: host page buffers free failed (%d)!\n",
2048 dexitprintk((KERN_INFO MYNAM ": %s HostPageBuffer free @ %p, sz=%d bytes\n",
2049 ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
2050 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2051 ioc->HostPageBuffer,
2052 ioc->HostPageBuffer_dma);
2053 ioc->HostPageBuffer = NULL;
2054 ioc->HostPageBuffer_sz = 0;
2055 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2059 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2061 * mpt_adapter_dispose - Free all resources associated with a MPT
2063 * @ioc: Pointer to MPT adapter structure
2065 * This routine unregisters h/w resources and frees all alloc'd memory
2066 * associated with a MPT adapter structure.
2069 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2071 int sz_first, sz_last;
2076 sz_first = ioc->alloc_total;
2078 mpt_adapter_disable(ioc);
2080 if (ioc->pci_irq != -1) {
2081 free_irq(ioc->pci_irq, ioc);
2083 pci_disable_msi(ioc->pcidev);
2087 if (ioc->memmap != NULL) {
2088 iounmap(ioc->memmap);
2092 #if defined(CONFIG_MTRR) && 0
2093 if (ioc->mtrr_reg > 0) {
2094 mtrr_del(ioc->mtrr_reg, 0, 0);
2095 dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name));
2099 /* Zap the adapter lookup ptr! */
2100 list_del(&ioc->list);
2102 sz_last = ioc->alloc_total;
2103 dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
2104 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2107 ioc->alt_ioc->alt_ioc = NULL;
2112 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2114 * MptDisplayIocCapabilities - Disply IOC's capacilities.
2115 * @ioc: Pointer to MPT adapter structure
2118 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2122 printk(KERN_INFO "%s: ", ioc->name);
2123 if (ioc->prod_name && strlen(ioc->prod_name) > 3)
2124 printk("%s: ", ioc->prod_name+3);
2125 printk("Capabilities={");
2127 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2128 printk("Initiator");
2132 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2133 printk("%sTarget", i ? "," : "");
2137 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2138 printk("%sLAN", i ? "," : "");
2144 * This would probably evoke more questions than it's worth
2146 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2147 printk("%sLogBusAddr", i ? "," : "");
2155 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2157 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2158 * @ioc: Pointer to MPT_ADAPTER structure
2159 * @force: Force hard KickStart of IOC
2160 * @sleepFlag: Specifies whether the process can sleep
2163 * 1 - DIAG reset and READY
2164 * 0 - READY initially OR soft reset and READY
2165 * -1 - Any failure on KickStart
2166 * -2 - Msg Unit Reset Failed
2167 * -3 - IO Unit Reset Failed
2168 * -4 - IOC owned by a PEER
2171 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2176 int hard_reset_done = 0;
2181 /* Get current [raw] IOC state */
2182 ioc_state = mpt_GetIocState(ioc, 0);
2183 dhsprintk((KERN_INFO MYNAM "::MakeIocReady, %s [raw] state=%08x\n", ioc->name, ioc_state));
2186 * Check to see if IOC got left/stuck in doorbell handshake
2187 * grip of death. If so, hard reset the IOC.
2189 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2191 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2195 /* Is it already READY? */
2196 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
2200 * Check to see if IOC is in FAULT state.
2202 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2204 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2206 printk(KERN_WARNING " FAULT code = %04xh\n",
2207 ioc_state & MPI_DOORBELL_DATA_MASK);
2211 * Hmmm... Did it get left operational?
2213 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2214 dinitprintk((MYIOC_s_INFO_FMT "IOC operational unexpected\n",
2218 * If PCI Peer, exit.
2219 * Else, if no fault conditions are present, issue a MessageUnitReset
2220 * Else, fall through to KickStart case
2222 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2223 dinitprintk((KERN_INFO MYNAM
2224 ": whoinit 0x%x statefault %d force %d\n",
2225 whoinit, statefault, force));
2226 if (whoinit == MPI_WHOINIT_PCI_PEER)
2229 if ((statefault == 0 ) && (force == 0)) {
2230 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2237 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2238 if (hard_reset_done < 0)
2242 * Loop here waiting for IOC to come READY.
2245 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2247 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2248 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2250 * BIOS or previous driver load left IOC in OP state.
2251 * Reset messaging FIFOs.
2253 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2254 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2257 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2259 * Something is wrong. Try to get IOC back
2262 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2263 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2270 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2271 ioc->name, (int)((ii+5)/HZ));
2275 if (sleepFlag == CAN_SLEEP) {
2276 msleep_interruptible(1);
2278 mdelay (1); /* 1 msec delay */
2283 if (statefault < 3) {
2284 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2286 statefault==1 ? "stuck handshake" : "IOC FAULT");
2289 return hard_reset_done;
2292 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2294 * mpt_GetIocState - Get the current state of a MPT adapter.
2295 * @ioc: Pointer to MPT_ADAPTER structure
2296 * @cooked: Request raw or cooked IOC state
2298 * Returns all IOC Doorbell register bits if cooked==0, else just the
2299 * Doorbell bits in MPI_IOC_STATE_MASK.
2302 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2307 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2308 // dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
2309 sc = s & MPI_IOC_STATE_MASK;
2312 ioc->last_state = sc;
2314 return cooked ? sc : s;
2317 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2319 * GetIocFacts - Send IOCFacts request to MPT adapter.
2320 * @ioc: Pointer to MPT_ADAPTER structure
2321 * @sleepFlag: Specifies whether the process can sleep
2322 * @reason: If recovery, only update facts.
2324 * Returns 0 for success, non-zero for failure.
2327 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2329 IOCFacts_t get_facts;
2330 IOCFactsReply_t *facts;
2338 /* IOC *must* NOT be in RESET state! */
2339 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2340 printk(KERN_ERR MYNAM ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
2346 facts = &ioc->facts;
2348 /* Destination (reply area)... */
2349 reply_sz = sizeof(*facts);
2350 memset(facts, 0, reply_sz);
2352 /* Request area (get_facts on the stack right now!) */
2353 req_sz = sizeof(get_facts);
2354 memset(&get_facts, 0, req_sz);
2356 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2357 /* Assert: All other get_facts fields are zero! */
2359 dinitprintk((MYIOC_s_INFO_FMT
2360 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2361 ioc->name, req_sz, reply_sz));
2363 /* No non-zero fields in the get_facts request are greater than
2364 * 1 byte in size, so we can just fire it off as is.
2366 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2367 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2372 * Now byte swap (GRRR) the necessary fields before any further
2373 * inspection of reply contents.
2375 * But need to do some sanity checks on MsgLength (byte) field
2376 * to make sure we don't zero IOC's req_sz!
2378 /* Did we get a valid reply? */
2379 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2380 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2382 * If not been here, done that, save off first WhoInit value
2384 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2385 ioc->FirstWhoInit = facts->WhoInit;
2388 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2389 facts->MsgContext = le32_to_cpu(facts->MsgContext);
2390 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2391 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2392 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2393 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
2394 /* CHECKME! IOCStatus, IOCLogInfo */
2396 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2397 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2400 * FC f/w version changed between 1.1 and 1.2
2401 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2402 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2404 if (facts->MsgVersion < 0x0102) {
2406 * Handle old FC f/w style, convert to new...
2408 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2409 facts->FWVersion.Word =
2410 ((oldv<<12) & 0xFF000000) |
2411 ((oldv<<8) & 0x000FFF00);
2413 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2415 facts->ProductID = le16_to_cpu(facts->ProductID);
2416 facts->CurrentHostMfaHighAddr =
2417 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2418 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2419 facts->CurrentSenseBufferHighAddr =
2420 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2421 facts->CurReplyFrameSize =
2422 le16_to_cpu(facts->CurReplyFrameSize);
2423 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
2426 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2427 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2428 * to 14 in MPI-1.01.0x.
2430 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2431 facts->MsgVersion > 0x0100) {
2432 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2435 sz = facts->FWImageSize;
2440 facts->FWImageSize = sz;
2442 if (!facts->RequestFrameSize) {
2443 /* Something is wrong! */
2444 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2449 r = sz = facts->BlockSize;
2450 vv = ((63 / (sz * 4)) + 1) & 0x03;
2451 ioc->NB_for_64_byte_frame = vv;
2457 ioc->NBShiftFactor = shiftFactor;
2458 dinitprintk((MYIOC_s_INFO_FMT "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2459 ioc->name, vv, shiftFactor, r));
2461 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2463 * Set values for this IOC's request & reply frame sizes,
2464 * and request & reply queue depths...
2466 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2467 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2468 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2469 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2471 dinitprintk((MYIOC_s_INFO_FMT "reply_sz=%3d, reply_depth=%4d\n",
2472 ioc->name, ioc->reply_sz, ioc->reply_depth));
2473 dinitprintk((MYIOC_s_INFO_FMT "req_sz =%3d, req_depth =%4d\n",
2474 ioc->name, ioc->req_sz, ioc->req_depth));
2476 /* Get port facts! */
2477 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2481 printk(MYIOC_s_ERR_FMT
2482 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2483 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2484 RequestFrameSize)/sizeof(u32)));
2491 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2493 * GetPortFacts - Send PortFacts request to MPT adapter.
2494 * @ioc: Pointer to MPT_ADAPTER structure
2495 * @portnum: Port number
2496 * @sleepFlag: Specifies whether the process can sleep
2498 * Returns 0 for success, non-zero for failure.
2501 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2503 PortFacts_t get_pfacts;
2504 PortFactsReply_t *pfacts;
2509 /* IOC *must* NOT be in RESET state! */
2510 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2511 printk(KERN_ERR MYNAM ": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n",
2517 pfacts = &ioc->pfacts[portnum];
2519 /* Destination (reply area)... */
2520 reply_sz = sizeof(*pfacts);
2521 memset(pfacts, 0, reply_sz);
2523 /* Request area (get_pfacts on the stack right now!) */
2524 req_sz = sizeof(get_pfacts);
2525 memset(&get_pfacts, 0, req_sz);
2527 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2528 get_pfacts.PortNumber = portnum;
2529 /* Assert: All other get_pfacts fields are zero! */
2531 dinitprintk((MYIOC_s_INFO_FMT "Sending get PortFacts(%d) request\n",
2532 ioc->name, portnum));
2534 /* No non-zero fields in the get_pfacts request are greater than
2535 * 1 byte in size, so we can just fire it off as is.
2537 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2538 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2542 /* Did we get a valid reply? */
2544 /* Now byte swap the necessary fields in the response. */
2545 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2546 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2547 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2548 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2549 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2550 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2551 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2552 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2553 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2558 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2560 * SendIocInit - Send IOCInit request to MPT adapter.
2561 * @ioc: Pointer to MPT_ADAPTER structure
2562 * @sleepFlag: Specifies whether the process can sleep
2564 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2566 * Returns 0 for success, non-zero for failure.
2569 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2572 MPIDefaultReply_t init_reply;
2578 memset(&ioc_init, 0, sizeof(ioc_init));
2579 memset(&init_reply, 0, sizeof(init_reply));
2581 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2582 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2584 /* If we are in a recovery mode and we uploaded the FW image,
2585 * then this pointer is not NULL. Skip the upload a second time.
2586 * Set this flag if cached_fw set for either IOC.
2588 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
2592 ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n",
2593 ioc->name, ioc->upload_fw, ioc->facts.Flags));
2595 if(ioc->bus_type == SAS)
2596 ioc_init.MaxDevices = ioc->facts.MaxDevices;
2597 else if(ioc->bus_type == FC)
2598 ioc_init.MaxDevices = MPT_MAX_FC_DEVICES;
2600 ioc_init.MaxDevices = MPT_MAX_SCSI_DEVICES;
2601 ioc_init.MaxBuses = MPT_MAX_BUS;
2602 dinitprintk((MYIOC_s_INFO_FMT "facts.MsgVersion=%x\n",
2603 ioc->name, ioc->facts.MsgVersion));
2604 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
2605 // set MsgVersion and HeaderVersion host driver was built with
2606 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
2607 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
2609 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
2610 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
2611 } else if(mpt_host_page_alloc(ioc, &ioc_init))
2614 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
2616 if (sizeof(dma_addr_t) == sizeof(u64)) {
2617 /* Save the upper 32-bits of the request
2618 * (reply) and sense buffers.
2620 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
2621 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2623 /* Force 32-bit addressing */
2624 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
2625 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
2628 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
2629 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
2630 ioc->facts.MaxDevices = ioc_init.MaxDevices;
2631 ioc->facts.MaxBuses = ioc_init.MaxBuses;
2633 dhsprintk((MYIOC_s_INFO_FMT "Sending IOCInit (req @ %p)\n",
2634 ioc->name, &ioc_init));
2636 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
2637 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
2639 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
2643 /* No need to byte swap the multibyte fields in the reply
2644 * since we don't even look at it's contents.
2647 dhsprintk((MYIOC_s_INFO_FMT "Sending PortEnable (req @ %p)\n",
2648 ioc->name, &ioc_init));
2650 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
2651 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
2655 /* YIKES! SUPER IMPORTANT!!!
2656 * Poll IocState until _OPERATIONAL while IOC is doing
2657 * LoopInit and TargetDiscovery!
2660 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
2661 state = mpt_GetIocState(ioc, 1);
2662 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
2663 if (sleepFlag == CAN_SLEEP) {
2664 msleep_interruptible(1);
2670 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
2671 ioc->name, (int)((count+5)/HZ));
2675 state = mpt_GetIocState(ioc, 1);
2678 dinitprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
2684 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2686 * SendPortEnable - Send PortEnable request to MPT adapter port.
2687 * @ioc: Pointer to MPT_ADAPTER structure
2688 * @portnum: Port number to enable
2689 * @sleepFlag: Specifies whether the process can sleep
2691 * Send PortEnable to bring IOC to OPERATIONAL state.
2693 * Returns 0 for success, non-zero for failure.
2696 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2698 PortEnable_t port_enable;
2699 MPIDefaultReply_t reply_buf;
2704 /* Destination... */
2705 reply_sz = sizeof(MPIDefaultReply_t);
2706 memset(&reply_buf, 0, reply_sz);
2708 req_sz = sizeof(PortEnable_t);
2709 memset(&port_enable, 0, req_sz);
2711 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
2712 port_enable.PortNumber = portnum;
2713 /* port_enable.ChainOffset = 0; */
2714 /* port_enable.MsgFlags = 0; */
2715 /* port_enable.MsgContext = 0; */
2717 dinitprintk((MYIOC_s_INFO_FMT "Sending Port(%d)Enable (req @ %p)\n",
2718 ioc->name, portnum, &port_enable));
2720 /* RAID FW may take a long time to enable
2722 if (((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
2723 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI) ||
2724 (ioc->bus_type == SAS)) {
2725 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
2726 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
2727 300 /*seconds*/, sleepFlag);
2729 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
2730 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
2731 30 /*seconds*/, sleepFlag);
2737 * ioc: Pointer to MPT_ADAPTER structure
2738 * size - total FW bytes
2741 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
2744 return; /* use already allocated memory */
2745 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2746 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
2747 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
2749 if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
2750 ioc->alloc_total += size;
2754 * If alt_img is NULL, delete from ioc structure.
2755 * Else, delete a secondary image in same format.
2758 mpt_free_fw_memory(MPT_ADAPTER *ioc)
2762 sz = ioc->facts.FWImageSize;
2763 dinitprintk((KERN_INFO MYNAM "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
2764 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2765 pci_free_consistent(ioc->pcidev, sz,
2766 ioc->cached_fw, ioc->cached_fw_dma);
2767 ioc->cached_fw = NULL;
2773 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2775 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
2776 * @ioc: Pointer to MPT_ADAPTER structure
2777 * @sleepFlag: Specifies whether the process can sleep
2779 * Returns 0 for success, >0 for handshake failure
2780 * <0 for fw upload failure.
2782 * Remark: If bound IOC and a successful FWUpload was performed
2783 * on the bound IOC, the second image is discarded
2784 * and memory is free'd. Both channels must upload to prevent
2785 * IOC from running in degraded mode.
2788 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
2790 u8 request[ioc->req_sz];
2791 u8 reply[sizeof(FWUploadReply_t)];
2792 FWUpload_t *prequest;
2793 FWUploadReply_t *preply;
2794 FWUploadTCSGE_t *ptcsge;
2797 int ii, sz, reply_sz;
2800 /* If the image size is 0, we are done.
2802 if ((sz = ioc->facts.FWImageSize) == 0)
2805 mpt_alloc_fw_memory(ioc, sz);
2807 dinitprintk((KERN_INFO MYNAM ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
2808 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2810 if (ioc->cached_fw == NULL) {
2816 prequest = (FWUpload_t *)&request;
2817 preply = (FWUploadReply_t *)&reply;
2819 /* Destination... */
2820 memset(prequest, 0, ioc->req_sz);
2822 reply_sz = sizeof(reply);
2823 memset(preply, 0, reply_sz);
2825 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
2826 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
2828 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
2829 ptcsge->DetailsLength = 12;
2830 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
2831 ptcsge->ImageSize = cpu_to_le32(sz);
2833 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
2835 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
2836 mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma);
2838 sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
2839 dinitprintk((KERN_INFO MYNAM ": Sending FW Upload (req @ %p) sgeoffset=%d \n",
2840 prequest, sgeoffset));
2841 DBG_DUMP_FW_REQUEST_FRAME(prequest)
2843 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
2844 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
2846 dinitprintk((KERN_INFO MYNAM ": FW Upload completed rc=%x \n", ii));
2848 cmdStatus = -EFAULT;
2850 /* Handshake transfer was complete and successful.
2851 * Check the Reply Frame.
2853 int status, transfer_sz;
2854 status = le16_to_cpu(preply->IOCStatus);
2855 if (status == MPI_IOCSTATUS_SUCCESS) {
2856 transfer_sz = le32_to_cpu(preply->ActualImageSize);
2857 if (transfer_sz == sz)
2861 dinitprintk((MYIOC_s_INFO_FMT ": do_upload cmdStatus=%d \n",
2862 ioc->name, cmdStatus));
2867 ddlprintk((MYIOC_s_INFO_FMT ": fw upload failed, freeing image \n",
2869 mpt_free_fw_memory(ioc);
2875 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2877 * mpt_downloadboot - DownloadBoot code
2878 * @ioc: Pointer to MPT_ADAPTER structure
2879 * @flag: Specify which part of IOC memory is to be uploaded.
2880 * @sleepFlag: Specifies whether the process can sleep
2882 * FwDownloadBoot requires Programmed IO access.
2884 * Returns 0 for success
2885 * -1 FW Image size is 0
2886 * -2 No valid cached_fw Pointer
2887 * <0 for fw upload failure.
2890 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
2892 MpiExtImageHeader_t *pExtImage;
2902 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
2903 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
2905 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2906 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2907 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2908 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2909 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2910 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2912 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
2915 if (sleepFlag == CAN_SLEEP) {
2916 msleep_interruptible(1);
2921 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2922 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
2924 for (count = 0; count < 30; count ++) {
2925 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2926 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
2927 ddlprintk((MYIOC_s_INFO_FMT "RESET_ADAPTER cleared, count=%d\n",
2932 if (sleepFlag == CAN_SLEEP) {
2933 msleep_interruptible (100);
2939 if ( count == 30 ) {
2940 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! "
2941 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
2942 ioc->name, diag0val));
2946 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2947 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2948 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2949 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2950 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2951 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2953 /* Set the DiagRwEn and Disable ARM bits */
2954 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
2956 fwSize = (pFwHeader->ImageSize + 3)/4;
2957 ptrFw = (u32 *) pFwHeader;
2959 /* Write the LoadStartAddress to the DiagRw Address Register
2960 * using Programmed IO
2962 if (ioc->errata_flag_1064)
2963 pci_enable_io_access(ioc->pcidev);
2965 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
2966 ddlprintk((MYIOC_s_INFO_FMT "LoadStart addr written 0x%x \n",
2967 ioc->name, pFwHeader->LoadStartAddress));
2969 ddlprintk((MYIOC_s_INFO_FMT "Write FW Image: 0x%x bytes @ %p\n",
2970 ioc->name, fwSize*4, ptrFw));
2972 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
2975 nextImage = pFwHeader->NextImageHeaderOffset;
2977 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
2979 load_addr = pExtImage->LoadStartAddress;
2981 fwSize = (pExtImage->ImageSize + 3) >> 2;
2982 ptrFw = (u32 *)pExtImage;
2984 ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
2985 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
2986 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
2989 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
2991 nextImage = pExtImage->NextImageHeaderOffset;
2994 /* Write the IopResetVectorRegAddr */
2995 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
2996 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
2998 /* Write the IopResetVectorValue */
2999 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3000 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3002 /* Clear the internal flash bad bit - autoincrementing register,
3003 * so must do two writes.
3005 if (ioc->bus_type == SPI) {
3007 * 1030 and 1035 H/W errata, workaround to access
3008 * the ClearFlashBadSignatureBit
3010 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3011 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3012 diagRwData |= 0x40000000;
3013 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3014 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3016 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3017 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3018 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3019 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3022 if (sleepFlag == CAN_SLEEP) {
3023 msleep_interruptible (1);
3029 if (ioc->errata_flag_1064)
3030 pci_disable_io_access(ioc->pcidev);
3032 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3033 ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, "
3034 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3035 ioc->name, diag0val));
3036 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3037 ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
3038 ioc->name, diag0val));
3039 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3041 /* Write 0xFF to reset the sequencer */
3042 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3044 if (ioc->bus_type == SAS) {
3045 ioc_state = mpt_GetIocState(ioc, 0);
3046 if ( (GetIocFacts(ioc, sleepFlag,
3047 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3048 ddlprintk((MYIOC_s_INFO_FMT "GetIocFacts failed: IocState=%x\n",
3049 ioc->name, ioc_state));
3054 for (count=0; count<HZ*20; count++) {
3055 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3056 ddlprintk((MYIOC_s_INFO_FMT "downloadboot successful! (count=%d) IocState=%x\n",
3057 ioc->name, count, ioc_state));
3058 if (ioc->bus_type == SAS) {
3061 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3062 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit failed\n",
3066 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit successful\n",
3070 if (sleepFlag == CAN_SLEEP) {
3071 msleep_interruptible (10);
3076 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! IocState=%x\n",
3077 ioc->name, ioc_state));
3081 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3083 * KickStart - Perform hard reset of MPT adapter.
3084 * @ioc: Pointer to MPT_ADAPTER structure
3085 * @force: Force hard reset
3086 * @sleepFlag: Specifies whether the process can sleep
3088 * This routine places MPT adapter in diagnostic mode via the
3089 * WriteSequence register, and then performs a hard reset of adapter
3090 * via the Diagnostic register.
3092 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3093 * or NO_SLEEP (interrupt thread, use mdelay)
3094 * force - 1 if doorbell active, board fault state
3095 * board operational, IOC_RECOVERY or
3096 * IOC_BRINGUP and there is an alt_ioc.
3100 * 1 - hard reset, READY
3101 * 0 - no reset due to History bit, READY
3102 * -1 - no reset due to History bit but not READY
3103 * OR reset but failed to come READY
3104 * -2 - no reset, could not enter DIAG mode
3105 * -3 - reset but bad FW bit
3108 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3110 int hard_reset_done = 0;
3114 dinitprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
3115 if (ioc->bus_type == SPI) {
3116 /* Always issue a Msg Unit Reset first. This will clear some
3117 * SCSI bus hang conditions.
3119 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3121 if (sleepFlag == CAN_SLEEP) {
3122 msleep_interruptible (1000);
3128 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3129 if (hard_reset_done < 0)
3130 return hard_reset_done;
3132 dinitprintk((MYIOC_s_INFO_FMT "Diagnostic reset successful!\n",
3135 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3136 for (cnt=0; cnt<cntdn; cnt++) {
3137 ioc_state = mpt_GetIocState(ioc, 1);
3138 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3139 dinitprintk((MYIOC_s_INFO_FMT "KickStart successful! (cnt=%d)\n",
3141 return hard_reset_done;
3143 if (sleepFlag == CAN_SLEEP) {
3144 msleep_interruptible (10);
3150 printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3151 ioc->name, ioc_state);
3155 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3157 * mpt_diag_reset - Perform hard reset of the adapter.
3158 * @ioc: Pointer to MPT_ADAPTER structure
3159 * @ignore: Set if to honor and clear to ignore
3160 * the reset history bit
3161 * @sleepflag: CAN_SLEEP if called in a non-interrupt thread,
3162 * else set to NO_SLEEP (use mdelay instead)
3164 * This routine places the adapter in diagnostic mode via the
3165 * WriteSequence register and then performs a hard reset of adapter
3166 * via the Diagnostic register. Adapter should be in ready state
3167 * upon successful completion.
3169 * Returns: 1 hard reset successful
3170 * 0 no reset performed because reset history bit set
3171 * -2 enabling diagnostic mode failed
3172 * -3 diagnostic reset failed
3175 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3179 int hard_reset_done = 0;
3185 /* Clear any existing interrupts */
3186 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3188 /* Use "Diagnostic reset" method! (only thing available!) */
3189 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3193 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3194 dprintk((MYIOC_s_INFO_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3195 ioc->name, diag0val, diag1val));
3198 /* Do the reset if we are told to ignore the reset history
3199 * or if the reset history is 0
3201 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3202 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3203 /* Write magic sequence to WriteSequence register
3204 * Loop until in diagnostic mode
3206 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3207 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3208 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3209 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3210 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3211 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3214 if (sleepFlag == CAN_SLEEP) {
3215 msleep_interruptible (100);
3222 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3223 ioc->name, diag0val);
3228 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3230 dprintk((MYIOC_s_INFO_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3231 ioc->name, diag0val));
3236 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3237 dprintk((MYIOC_s_INFO_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3238 ioc->name, diag0val, diag1val));
3241 * Disable the ARM (Bug fix)
3244 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3248 * Now hit the reset bit in the Diagnostic register
3249 * (THE BIG HAMMER!) (Clears DRWE bit).
3251 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3252 hard_reset_done = 1;
3253 dprintk((MYIOC_s_INFO_FMT "Diagnostic reset performed\n",
3257 * Call each currently registered protocol IOC reset handler
3258 * with pre-reset indication.
3259 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3260 * MptResetHandlers[] registered yet.
3266 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
3267 if (MptResetHandlers[ii]) {
3268 dprintk((MYIOC_s_INFO_FMT "Calling IOC pre_reset handler #%d\n",
3270 r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_PRE_RESET);
3272 dprintk((MYIOC_s_INFO_FMT "Calling alt-%s pre_reset handler #%d\n",
3273 ioc->name, ioc->alt_ioc->name, ii));
3274 r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_PRE_RESET);
3278 /* FIXME? Examine results here? */
3281 if (ioc->cached_fw) {
3282 /* If the DownloadBoot operation fails, the
3283 * IOC will be left unusable. This is a fatal error
3284 * case. _diag_reset will return < 0
3286 for (count = 0; count < 30; count ++) {
3287 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3288 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3293 if (sleepFlag == CAN_SLEEP) {
3294 msleep_interruptible (1000);
3299 if ((count = mpt_downloadboot(ioc,
3300 (MpiFwHeader_t *)ioc->cached_fw, sleepFlag)) < 0) {
3301 printk(KERN_WARNING MYNAM
3302 ": firmware downloadboot failure (%d)!\n", count);
3306 /* Wait for FW to reload and for board
3307 * to go to the READY state.
3308 * Maximum wait is 60 seconds.
3309 * If fail, no error will check again
3310 * with calling program.
3312 for (count = 0; count < 60; count ++) {
3313 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3314 doorbell &= MPI_IOC_STATE_MASK;
3316 if (doorbell == MPI_IOC_STATE_READY) {
3321 if (sleepFlag == CAN_SLEEP) {
3322 msleep_interruptible (1000);
3330 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3333 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3334 dprintk((MYIOC_s_INFO_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3335 ioc->name, diag0val, diag1val));
3338 /* Clear RESET_HISTORY bit! Place board in the
3339 * diagnostic mode to update the diag register.
3341 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3343 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3344 /* Write magic sequence to WriteSequence register
3345 * Loop until in diagnostic mode
3347 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3348 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3349 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3350 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3351 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3352 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3355 if (sleepFlag == CAN_SLEEP) {
3356 msleep_interruptible (100);
3363 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3364 ioc->name, diag0val);
3367 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3369 diag0val &= ~MPI_DIAG_RESET_HISTORY;
3370 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3371 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3372 if (diag0val & MPI_DIAG_RESET_HISTORY) {
3373 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3377 /* Disable Diagnostic Mode
3379 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3381 /* Check FW reload status flags.
3383 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3384 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3385 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3386 ioc->name, diag0val);
3392 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3393 dprintk((MYIOC_s_INFO_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3394 ioc->name, diag0val, diag1val));
3398 * Reset flag that says we've enabled event notification
3400 ioc->facts.EventState = 0;
3403 ioc->alt_ioc->facts.EventState = 0;
3405 return hard_reset_done;
3408 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3410 * SendIocReset - Send IOCReset request to MPT adapter.
3411 * @ioc: Pointer to MPT_ADAPTER structure
3412 * @reset_type: reset type, expected values are
3413 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3415 * Send IOCReset request to the MPT adapter.
3417 * Returns 0 for success, non-zero for failure.
3420 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3426 drsprintk((KERN_INFO MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
3427 ioc->name, reset_type));
3428 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3429 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3432 /* FW ACK'd request, wait for READY state
3435 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
3437 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3441 if (sleepFlag != CAN_SLEEP)
3444 printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
3445 ioc->name, (int)((count+5)/HZ));
3449 if (sleepFlag == CAN_SLEEP) {
3450 msleep_interruptible(1);
3452 mdelay (1); /* 1 msec delay */
3457 * Cleanup all event stuff for this IOC; re-issue EventNotification
3458 * request if needed.
3460 if (ioc->facts.Function)
3461 ioc->facts.EventState = 0;
3466 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3468 * initChainBuffers - Allocate memory for and initialize
3469 * chain buffers, chain buffer control arrays and spinlock.
3470 * @hd: Pointer to MPT_SCSI_HOST structure
3471 * @init: If set, initialize the spin lock.
3474 initChainBuffers(MPT_ADAPTER *ioc)
3477 int sz, ii, num_chain;
3478 int scale, num_sge, numSGE;
3480 /* ReqToChain size must equal the req_depth
3483 if (ioc->ReqToChain == NULL) {
3484 sz = ioc->req_depth * sizeof(int);
3485 mem = kmalloc(sz, GFP_ATOMIC);
3489 ioc->ReqToChain = (int *) mem;
3490 dinitprintk((KERN_INFO MYNAM ": %s ReqToChain alloc @ %p, sz=%d bytes\n",
3491 ioc->name, mem, sz));
3492 mem = kmalloc(sz, GFP_ATOMIC);
3496 ioc->RequestNB = (int *) mem;
3497 dinitprintk((KERN_INFO MYNAM ": %s RequestNB alloc @ %p, sz=%d bytes\n",
3498 ioc->name, mem, sz));
3500 for (ii = 0; ii < ioc->req_depth; ii++) {
3501 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
3504 /* ChainToChain size must equal the total number
3505 * of chain buffers to be allocated.
3508 * Calculate the number of chain buffers needed(plus 1) per I/O
3509 * then multiply the the maximum number of simultaneous cmds
3511 * num_sge = num sge in request frame + last chain buffer
3512 * scale = num sge per chain buffer if no chain element
3514 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3515 if (sizeof(dma_addr_t) == sizeof(u64))
3516 num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3518 num_sge = 1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3520 if (sizeof(dma_addr_t) == sizeof(u64)) {
3521 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3522 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3524 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3525 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3527 dinitprintk((KERN_INFO MYNAM ": %s num_sge=%d numSGE=%d\n",
3528 ioc->name, num_sge, numSGE));
3530 if ( numSGE > MPT_SCSI_SG_DEPTH )
3531 numSGE = MPT_SCSI_SG_DEPTH;
3534 while (numSGE - num_sge > 0) {
3536 num_sge += (scale - 1);
3540 dinitprintk((KERN_INFO MYNAM ": %s Now numSGE=%d num_sge=%d num_chain=%d\n",
3541 ioc->name, numSGE, num_sge, num_chain));
3543 if (ioc->bus_type == SPI)
3544 num_chain *= MPT_SCSI_CAN_QUEUE;
3546 num_chain *= MPT_FC_CAN_QUEUE;
3548 ioc->num_chain = num_chain;
3550 sz = num_chain * sizeof(int);
3551 if (ioc->ChainToChain == NULL) {
3552 mem = kmalloc(sz, GFP_ATOMIC);
3556 ioc->ChainToChain = (int *) mem;
3557 dinitprintk((KERN_INFO MYNAM ": %s ChainToChain alloc @ %p, sz=%d bytes\n",
3558 ioc->name, mem, sz));
3560 mem = (u8 *) ioc->ChainToChain;
3562 memset(mem, 0xFF, sz);
3566 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3568 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
3569 * @ioc: Pointer to MPT_ADAPTER structure
3571 * This routine allocates memory for the MPT reply and request frame
3572 * pools (if necessary), and primes the IOC reply FIFO with
3575 * Returns 0 for success, non-zero for failure.
3578 PrimeIocFifos(MPT_ADAPTER *ioc)
3581 unsigned long flags;
3582 dma_addr_t alloc_dma;
3584 int i, reply_sz, sz, total_size, num_chain;
3586 /* Prime reply FIFO... */
3588 if (ioc->reply_frames == NULL) {
3589 if ( (num_chain = initChainBuffers(ioc)) < 0)
3592 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
3593 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
3594 ioc->name, ioc->reply_sz, ioc->reply_depth));
3595 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d[%x] bytes\n",
3596 ioc->name, reply_sz, reply_sz));
3598 sz = (ioc->req_sz * ioc->req_depth);
3599 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d bytes, RequestDepth=%d\n",
3600 ioc->name, ioc->req_sz, ioc->req_depth));
3601 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d[%x] bytes\n",
3602 ioc->name, sz, sz));
3605 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
3606 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d bytes, ChainDepth=%d\n",
3607 ioc->name, ioc->req_sz, num_chain));
3608 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
3609 ioc->name, sz, sz, num_chain));
3612 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
3614 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
3619 dinitprintk((KERN_INFO MYNAM ": %s.Total alloc @ %p[%p], sz=%d[%x] bytes\n",
3620 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
3622 memset(mem, 0, total_size);
3623 ioc->alloc_total += total_size;
3625 ioc->alloc_dma = alloc_dma;
3626 ioc->alloc_sz = total_size;
3627 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
3628 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3630 dinitprintk((KERN_INFO MYNAM ": %s ReplyBuffers @ %p[%p]\n",
3631 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3633 alloc_dma += reply_sz;
3636 /* Request FIFO - WE manage this! */
3638 ioc->req_frames = (MPT_FRAME_HDR *) mem;
3639 ioc->req_frames_dma = alloc_dma;
3641 dinitprintk((KERN_INFO MYNAM ": %s RequestBuffers @ %p[%p]\n",
3642 ioc->name, mem, (void *)(ulong)alloc_dma));
3644 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3646 #if defined(CONFIG_MTRR) && 0
3648 * Enable Write Combining MTRR for IOC's memory region.
3649 * (at least as much as we can; "size and base must be
3650 * multiples of 4 kiB"
3652 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
3654 MTRR_TYPE_WRCOMB, 1);
3655 dprintk((MYIOC_s_INFO_FMT "MTRR region registered (base:size=%08x:%x)\n",
3656 ioc->name, ioc->req_frames_dma, sz));
3659 for (i = 0; i < ioc->req_depth; i++) {
3660 alloc_dma += ioc->req_sz;
3664 ioc->ChainBuffer = mem;
3665 ioc->ChainBufferDMA = alloc_dma;
3667 dinitprintk((KERN_INFO MYNAM " :%s ChainBuffers @ %p(%p)\n",
3668 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
3670 /* Initialize the free chain Q.
3673 INIT_LIST_HEAD(&ioc->FreeChainQ);
3675 /* Post the chain buffers to the FreeChainQ.
3677 mem = (u8 *)ioc->ChainBuffer;
3678 for (i=0; i < num_chain; i++) {
3679 mf = (MPT_FRAME_HDR *) mem;
3680 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
3684 /* Initialize Request frames linked list
3686 alloc_dma = ioc->req_frames_dma;
3687 mem = (u8 *) ioc->req_frames;
3689 spin_lock_irqsave(&ioc->FreeQlock, flags);
3690 INIT_LIST_HEAD(&ioc->FreeQ);
3691 for (i = 0; i < ioc->req_depth; i++) {
3692 mf = (MPT_FRAME_HDR *) mem;
3694 /* Queue REQUESTs *internally*! */
3695 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
3699 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3701 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3702 ioc->sense_buf_pool =
3703 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
3704 if (ioc->sense_buf_pool == NULL) {
3705 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
3710 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
3711 ioc->alloc_total += sz;
3712 dinitprintk((KERN_INFO MYNAM ": %s.SenseBuffers @ %p[%p]\n",
3713 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
3717 /* Post Reply frames to FIFO
3719 alloc_dma = ioc->alloc_dma;
3720 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffers @ %p[%p]\n",
3721 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3723 for (i = 0; i < ioc->reply_depth; i++) {
3724 /* Write each address to the IOC! */
3725 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
3726 alloc_dma += ioc->reply_sz;
3732 if (ioc->alloc != NULL) {
3734 pci_free_consistent(ioc->pcidev,
3736 ioc->alloc, ioc->alloc_dma);
3737 ioc->reply_frames = NULL;
3738 ioc->req_frames = NULL;
3739 ioc->alloc_total -= sz;
3741 if (ioc->sense_buf_pool != NULL) {
3742 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3743 pci_free_consistent(ioc->pcidev,
3745 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
3746 ioc->sense_buf_pool = NULL;
3751 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3753 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
3754 * from IOC via doorbell handshake method.
3755 * @ioc: Pointer to MPT_ADAPTER structure
3756 * @reqBytes: Size of the request in bytes
3757 * @req: Pointer to MPT request frame
3758 * @replyBytes: Expected size of the reply in bytes
3759 * @u16reply: Pointer to area where reply should be written
3760 * @maxwait: Max wait time for a reply (in seconds)
3761 * @sleepFlag: Specifies whether the process can sleep
3763 * NOTES: It is the callers responsibility to byte-swap fields in the
3764 * request which are greater than 1 byte in size. It is also the
3765 * callers responsibility to byte-swap response fields which are
3766 * greater than 1 byte in size.
3768 * Returns 0 for success, non-zero for failure.
3771 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
3772 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
3774 MPIDefaultReply_t *mptReply;
3779 * Get ready to cache a handshake reply
3781 ioc->hs_reply_idx = 0;
3782 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
3783 mptReply->MsgLength = 0;
3786 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
3787 * then tell IOC that we want to handshake a request of N words.
3788 * (WRITE u32val to Doorbell reg).
3790 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3791 CHIPREG_WRITE32(&ioc->chip->Doorbell,
3792 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
3793 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
3796 * Wait for IOC's doorbell handshake int
3798 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3801 dhsprintk((MYIOC_s_INFO_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
3802 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
3804 /* Read doorbell and check for active bit */
3805 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
3809 * Clear doorbell int (WRITE 0 to IntStatus reg),
3810 * then wait for IOC to ACKnowledge that it's ready for
3811 * our handshake request.
3813 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3814 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3819 u8 *req_as_bytes = (u8 *) req;
3822 * Stuff request words via doorbell handshake,
3823 * with ACK from IOC for each.
3825 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
3826 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
3827 (req_as_bytes[(ii*4) + 1] << 8) |
3828 (req_as_bytes[(ii*4) + 2] << 16) |
3829 (req_as_bytes[(ii*4) + 3] << 24));
3831 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
3832 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3836 dhsprintk((KERN_INFO MYNAM ": Handshake request frame (@%p) header\n", req));
3837 DBG_DUMP_REQUEST_FRAME_HDR(req)
3839 dhsprintk((MYIOC_s_INFO_FMT "HandShake request post done, WaitCnt=%d%s\n",
3840 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
3843 * Wait for completion of doorbell handshake reply from the IOC
3845 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
3848 dhsprintk((MYIOC_s_INFO_FMT "HandShake reply count=%d%s\n",
3849 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
3852 * Copy out the cached reply...
3854 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
3855 u16reply[ii] = ioc->hs_reply[ii];
3863 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3865 * WaitForDoorbellAck - Wait for IOC to clear the IOP_DOORBELL_STATUS bit
3866 * in it's IntStatus register.
3867 * @ioc: Pointer to MPT_ADAPTER structure
3868 * @howlong: How long to wait (in seconds)
3869 * @sleepFlag: Specifies whether the process can sleep
3871 * This routine waits (up to ~2 seconds max) for IOC doorbell
3872 * handshake ACKnowledge.
3874 * Returns a negative value on failure, else wait loop count.
3877 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3883 cntdn = 1000 * howlong;
3885 if (sleepFlag == CAN_SLEEP) {
3887 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3888 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3890 msleep_interruptible (1);
3895 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3896 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3904 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell ACK (count=%d)\n",
3909 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
3910 ioc->name, count, intstat);
3914 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3916 * WaitForDoorbellInt - Wait for IOC to set the HIS_DOORBELL_INTERRUPT bit
3917 * in it's IntStatus register.
3918 * @ioc: Pointer to MPT_ADAPTER structure
3919 * @howlong: How long to wait (in seconds)
3920 * @sleepFlag: Specifies whether the process can sleep
3922 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt.
3924 * Returns a negative value on failure, else wait loop count.
3927 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3933 cntdn = 1000 * howlong;
3934 if (sleepFlag == CAN_SLEEP) {
3936 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3937 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
3939 msleep_interruptible(1);
3944 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3945 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
3953 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
3954 ioc->name, count, howlong));
3958 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
3959 ioc->name, count, intstat);
3963 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3965 * WaitForDoorbellReply - Wait for and capture a IOC handshake reply.
3966 * @ioc: Pointer to MPT_ADAPTER structure
3967 * @howlong: How long to wait (in seconds)
3968 * @sleepFlag: Specifies whether the process can sleep
3970 * This routine polls the IOC for a handshake reply, 16 bits at a time.
3971 * Reply is cached to IOC private area large enough to hold a maximum
3972 * of 128 bytes of reply data.
3974 * Returns a negative value on failure, else size of reply in WORDS.
3977 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3982 u16 *hs_reply = ioc->hs_reply;
3983 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
3986 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
3989 * Get first two u16's so we can look at IOC's intended reply MsgLength
3992 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
3995 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
3996 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3997 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4000 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4001 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4005 dhsprintk((MYIOC_s_INFO_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4006 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4007 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4010 * If no error (and IOC said MsgLength is > 0), piece together
4011 * reply 16 bits at a time.
4013 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4014 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4016 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4017 /* don't overflow our IOC hs_reply[] buffer! */
4018 if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
4019 hs_reply[u16cnt] = hword;
4020 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4023 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4025 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4028 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4033 else if (u16cnt != (2 * mptReply->MsgLength)) {
4036 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4041 dhsprintk((MYIOC_s_INFO_FMT "Got Handshake reply:\n", ioc->name));
4042 DBG_DUMP_REPLY_FRAME(mptReply)
4044 dhsprintk((MYIOC_s_INFO_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4045 ioc->name, t, u16cnt/2));
4049 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4051 * GetLanConfigPages - Fetch LANConfig pages.
4052 * @ioc: Pointer to MPT_ADAPTER structure
4054 * Return: 0 for success
4055 * -ENOMEM if no memory available
4056 * -EPERM if not allowed due to ISR context
4057 * -EAGAIN if no msg frames currently available
4058 * -EFAULT for non-successful reply or no reply (timeout)
4061 GetLanConfigPages(MPT_ADAPTER *ioc)
4063 ConfigPageHeader_t hdr;
4065 LANPage0_t *ppage0_alloc;
4066 dma_addr_t page0_dma;
4067 LANPage1_t *ppage1_alloc;
4068 dma_addr_t page1_dma;
4073 /* Get LAN Page 0 header */
4074 hdr.PageVersion = 0;
4077 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4078 cfg.cfghdr.hdr = &hdr;
4080 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4085 if ((rc = mpt_config(ioc, &cfg)) != 0)
4088 if (hdr.PageLength > 0) {
4089 data_sz = hdr.PageLength * 4;
4090 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4093 memset((u8 *)ppage0_alloc, 0, data_sz);
4094 cfg.physAddr = page0_dma;
4095 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4097 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4099 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4100 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4104 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4107 * Normalize endianness of structure data,
4108 * by byte-swapping all > 1 byte fields!
4117 /* Get LAN Page 1 header */
4118 hdr.PageVersion = 0;
4121 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4122 cfg.cfghdr.hdr = &hdr;
4124 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4128 if ((rc = mpt_config(ioc, &cfg)) != 0)
4131 if (hdr.PageLength == 0)
4134 data_sz = hdr.PageLength * 4;
4136 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4138 memset((u8 *)ppage1_alloc, 0, data_sz);
4139 cfg.physAddr = page1_dma;
4140 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4142 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4144 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4145 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4148 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4151 * Normalize endianness of structure data,
4152 * by byte-swapping all > 1 byte fields!
4160 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4162 * mptbase_GetFcPortPage0 - Fetch FCPort config Page0.
4163 * @ioc: Pointer to MPT_ADAPTER structure
4164 * @portnum: IOC Port number
4166 * Return: 0 for success
4167 * -ENOMEM if no memory available
4168 * -EPERM if not allowed due to ISR context
4169 * -EAGAIN if no msg frames currently available
4170 * -EFAULT for non-successful reply or no reply (timeout)
4173 mptbase_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
4175 ConfigPageHeader_t hdr;
4177 FCPortPage0_t *ppage0_alloc;
4178 FCPortPage0_t *pp0dest;
4179 dma_addr_t page0_dma;
4186 /* Get FCPort Page 0 header */
4187 hdr.PageVersion = 0;
4190 hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
4191 cfg.cfghdr.hdr = &hdr;
4193 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4195 cfg.pageAddr = portnum;
4198 if ((rc = mpt_config(ioc, &cfg)) != 0)
4201 if (hdr.PageLength == 0)
4204 data_sz = hdr.PageLength * 4;
4206 ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4210 memset((u8 *)ppage0_alloc, 0, data_sz);
4211 cfg.physAddr = page0_dma;
4212 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4214 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4216 pp0dest = &ioc->fc_port_page0[portnum];
4217 copy_sz = min_t(int, sizeof(FCPortPage0_t), data_sz);
4218 memcpy(pp0dest, ppage0_alloc, copy_sz);
4221 * Normalize endianness of structure data,
4222 * by byte-swapping all > 1 byte fields!
4224 pp0dest->Flags = le32_to_cpu(pp0dest->Flags);
4225 pp0dest->PortIdentifier = le32_to_cpu(pp0dest->PortIdentifier);
4226 pp0dest->WWNN.Low = le32_to_cpu(pp0dest->WWNN.Low);
4227 pp0dest->WWNN.High = le32_to_cpu(pp0dest->WWNN.High);
4228 pp0dest->WWPN.Low = le32_to_cpu(pp0dest->WWPN.Low);
4229 pp0dest->WWPN.High = le32_to_cpu(pp0dest->WWPN.High);
4230 pp0dest->SupportedServiceClass = le32_to_cpu(pp0dest->SupportedServiceClass);
4231 pp0dest->SupportedSpeeds = le32_to_cpu(pp0dest->SupportedSpeeds);
4232 pp0dest->CurrentSpeed = le32_to_cpu(pp0dest->CurrentSpeed);
4233 pp0dest->MaxFrameSize = le32_to_cpu(pp0dest->MaxFrameSize);
4234 pp0dest->FabricWWNN.Low = le32_to_cpu(pp0dest->FabricWWNN.Low);
4235 pp0dest->FabricWWNN.High = le32_to_cpu(pp0dest->FabricWWNN.High);
4236 pp0dest->FabricWWPN.Low = le32_to_cpu(pp0dest->FabricWWPN.Low);
4237 pp0dest->FabricWWPN.High = le32_to_cpu(pp0dest->FabricWWPN.High);
4238 pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount);
4239 pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators);
4242 * if still doing discovery,
4243 * hang loose a while until finished
4245 if (pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_UNKNOWN) {
4247 msleep_interruptible(100);
4250 printk(MYIOC_s_INFO_FMT "Firmware discovery not"
4256 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4262 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4264 * mptbase_sas_persist_operation - Perform operation on SAS Persitent Table
4265 * @ioc: Pointer to MPT_ADAPTER structure
4266 * @sas_address: 64bit SAS Address for operation.
4267 * @target_id: specified target for operation
4268 * @bus: specified bus for operation
4269 * @persist_opcode: see below
4271 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4272 * devices not currently present.
4273 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4275 * NOTE: Don't use not this function during interrupt time.
4277 * Returns: 0 for success, non-zero error
4280 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4282 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4284 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
4285 SasIoUnitControlReply_t *sasIoUnitCntrReply;
4286 MPT_FRAME_HDR *mf = NULL;
4287 MPIHeader_t *mpi_hdr;
4290 /* insure garbage is not sent to fw */
4291 switch(persist_opcode) {
4293 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
4294 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
4302 printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode);
4304 /* Get a MF for this command.
4306 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4307 printk("%s: no msg frames!\n",__FUNCTION__);
4311 mpi_hdr = (MPIHeader_t *) mf;
4312 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
4313 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
4314 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
4315 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
4316 sasIoUnitCntrReq->Operation = persist_opcode;
4318 init_timer(&ioc->persist_timer);
4319 ioc->persist_timer.data = (unsigned long) ioc;
4320 ioc->persist_timer.function = mpt_timer_expired;
4321 ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
4322 ioc->persist_wait_done=0;
4323 add_timer(&ioc->persist_timer);
4324 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4325 wait_event(mpt_waitq, ioc->persist_wait_done);
4327 sasIoUnitCntrReply =
4328 (SasIoUnitControlReply_t *)ioc->persist_reply_frame;
4329 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
4330 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4332 sasIoUnitCntrReply->IOCStatus,
4333 sasIoUnitCntrReply->IOCLogInfo);
4337 printk("%s: success\n",__FUNCTION__);
4341 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4344 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
4345 MpiEventDataRaid_t * pRaidEventData)
4354 volume = pRaidEventData->VolumeID;
4355 reason = pRaidEventData->ReasonCode;
4356 disk = pRaidEventData->PhysDiskNum;
4357 status = le32_to_cpu(pRaidEventData->SettingsStatus);
4358 flags = (status >> 0) & 0xff;
4359 state = (status >> 8) & 0xff;
4361 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
4365 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
4366 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
4367 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
4368 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d\n",
4371 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
4376 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4377 printk(MYIOC_s_INFO_FMT " volume has been created\n",
4381 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4383 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
4387 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
4388 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
4392 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4393 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
4395 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
4397 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
4399 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
4402 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
4404 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
4405 ? ", quiesced" : "",
4406 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
4407 ? ", resync in progress" : "" );
4410 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
4411 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
4415 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4416 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
4420 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4421 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
4425 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
4426 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
4430 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4431 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
4433 state == MPI_PHYSDISK0_STATUS_ONLINE
4435 : state == MPI_PHYSDISK0_STATUS_MISSING
4437 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
4439 : state == MPI_PHYSDISK0_STATUS_FAILED
4441 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
4443 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
4444 ? "offline requested"
4445 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
4446 ? "failed requested"
4447 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
4450 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
4451 ? ", out of sync" : "",
4452 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
4453 ? ", quiesced" : "" );
4456 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
4457 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
4461 case MPI_EVENT_RAID_RC_SMART_DATA:
4462 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
4463 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
4466 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
4467 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
4473 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4475 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4476 * @ioc: Pointer to MPT_ADAPTER structure
4478 * Returns: 0 for success
4479 * -ENOMEM if no memory available
4480 * -EPERM if not allowed due to ISR context
4481 * -EAGAIN if no msg frames currently available
4482 * -EFAULT for non-successful reply or no reply (timeout)
4485 GetIoUnitPage2(MPT_ADAPTER *ioc)
4487 ConfigPageHeader_t hdr;
4489 IOUnitPage2_t *ppage_alloc;
4490 dma_addr_t page_dma;
4494 /* Get the page header */
4495 hdr.PageVersion = 0;
4498 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4499 cfg.cfghdr.hdr = &hdr;
4501 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4506 if ((rc = mpt_config(ioc, &cfg)) != 0)
4509 if (hdr.PageLength == 0)
4512 /* Read the config page */
4513 data_sz = hdr.PageLength * 4;
4515 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4517 memset((u8 *)ppage_alloc, 0, data_sz);
4518 cfg.physAddr = page_dma;
4519 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4521 /* If Good, save data */
4522 if ((rc = mpt_config(ioc, &cfg)) == 0)
4523 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4525 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4531 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4532 /* mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4533 * @ioc: Pointer to a Adapter Strucutre
4534 * @portnum: IOC port number
4536 * Return: -EFAULT if read of config page header fails
4538 * If read of SCSI Port Page 0 fails,
4539 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4540 * Adapter settings: async, narrow
4542 * If read of SCSI Port Page 2 fails,
4543 * Adapter settings valid
4544 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4549 * CHECK - what type of locking mechanisms should be used????
4552 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4557 ConfigPageHeader_t header;
4563 if (!ioc->spi_data.nvram) {
4566 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4567 mem = kmalloc(sz, GFP_ATOMIC);
4571 ioc->spi_data.nvram = (int *) mem;
4573 dprintk((MYIOC_s_INFO_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4574 ioc->name, ioc->spi_data.nvram, sz));
4577 /* Invalidate NVRAM information
4579 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4580 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4583 /* Read SPP0 header, allocate memory, then read page.
4585 header.PageVersion = 0;
4586 header.PageLength = 0;
4587 header.PageNumber = 0;
4588 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4589 cfg.cfghdr.hdr = &header;
4591 cfg.pageAddr = portnum;
4592 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4594 cfg.timeout = 0; /* use default */
4595 if (mpt_config(ioc, &cfg) != 0)
4598 if (header.PageLength > 0) {
4599 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4601 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4602 cfg.physAddr = buf_dma;
4603 if (mpt_config(ioc, &cfg) != 0) {
4604 ioc->spi_data.maxBusWidth = MPT_NARROW;
4605 ioc->spi_data.maxSyncOffset = 0;
4606 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4607 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4609 ddvprintk((MYIOC_s_INFO_FMT "Unable to read PortPage0 minSyncFactor=%x\n",
4610 ioc->name, ioc->spi_data.minSyncFactor));
4612 /* Save the Port Page 0 data
4614 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
4615 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4616 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4618 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
4619 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4620 ddvprintk((KERN_INFO MYNAM " :%s noQas due to Capabilities=%x\n",
4621 ioc->name, pPP0->Capabilities));
4623 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4624 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4626 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4627 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4628 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4629 ddvprintk((MYIOC_s_INFO_FMT "PortPage0 minSyncFactor=%x\n",
4630 ioc->name, ioc->spi_data.minSyncFactor));
4632 ioc->spi_data.maxSyncOffset = 0;
4633 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4636 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4638 /* Update the minSyncFactor based on bus type.
4640 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4641 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
4643 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
4644 ioc->spi_data.minSyncFactor = MPT_ULTRA;
4645 ddvprintk((MYIOC_s_INFO_FMT "HVD or SE detected, minSyncFactor=%x\n",
4646 ioc->name, ioc->spi_data.minSyncFactor));
4651 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4656 /* SCSI Port Page 2 - Read the header then the page.
4658 header.PageVersion = 0;
4659 header.PageLength = 0;
4660 header.PageNumber = 2;
4661 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4662 cfg.cfghdr.hdr = &header;
4664 cfg.pageAddr = portnum;
4665 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4667 if (mpt_config(ioc, &cfg) != 0)
4670 if (header.PageLength > 0) {
4671 /* Allocate memory and read SCSI Port Page 2
4673 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4675 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
4676 cfg.physAddr = buf_dma;
4677 if (mpt_config(ioc, &cfg) != 0) {
4678 /* Nvram data is left with INVALID mark
4682 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
4683 MpiDeviceInfo_t *pdevice = NULL;
4686 * Save "Set to Avoid SCSI Bus Resets" flag
4688 ioc->spi_data.bus_reset =
4689 (le32_to_cpu(pPP2->PortFlags) &
4690 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
4693 /* Save the Port Page 2 data
4694 * (reformat into a 32bit quantity)
4696 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
4697 ioc->spi_data.PortFlags = data;
4698 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4699 pdevice = &pPP2->DeviceSettings[ii];
4700 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
4701 (pdevice->SyncFactor << 8) | pdevice->Timeout;
4702 ioc->spi_data.nvram[ii] = data;
4706 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4710 /* Update Adapter limits with those from NVRAM
4711 * Comment: Don't need to do this. Target performance
4712 * parameters will never exceed the adapters limits.
4718 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4719 /* mpt_readScsiDevicePageHeaders - save version and length of SDP1
4720 * @ioc: Pointer to a Adapter Strucutre
4721 * @portnum: IOC port number
4723 * Return: -EFAULT if read of config page header fails
4727 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
4730 ConfigPageHeader_t header;
4732 /* Read the SCSI Device Page 1 header
4734 header.PageVersion = 0;
4735 header.PageLength = 0;
4736 header.PageNumber = 1;
4737 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4738 cfg.cfghdr.hdr = &header;
4740 cfg.pageAddr = portnum;
4741 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4744 if (mpt_config(ioc, &cfg) != 0)
4747 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
4748 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
4750 header.PageVersion = 0;
4751 header.PageLength = 0;
4752 header.PageNumber = 0;
4753 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4754 if (mpt_config(ioc, &cfg) != 0)
4757 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
4758 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
4760 dcprintk((MYIOC_s_INFO_FMT "Headers: 0: version %d length %d\n",
4761 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
4763 dcprintk((MYIOC_s_INFO_FMT "Headers: 1: version %d length %d\n",
4764 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
4768 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4770 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
4771 * @ioc: Pointer to a Adapter Strucutre
4772 * @portnum: IOC port number
4776 * -EFAULT if read of config page header fails or data pointer not NULL
4777 * -ENOMEM if pci_alloc failed
4780 mpt_findImVolumes(MPT_ADAPTER *ioc)
4784 ConfigPageIoc2RaidVol_t *pIocRv;
4785 dma_addr_t ioc2_dma;
4787 ConfigPageHeader_t header;
4794 /* Read IOCP2 header then the page.
4796 header.PageVersion = 0;
4797 header.PageLength = 0;
4798 header.PageNumber = 2;
4799 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4800 cfg.cfghdr.hdr = &header;
4803 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4806 if (mpt_config(ioc, &cfg) != 0)
4809 if (header.PageLength == 0)
4812 iocpage2sz = header.PageLength * 4;
4813 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
4817 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4818 cfg.physAddr = ioc2_dma;
4819 if (mpt_config(ioc, &cfg) != 0)
4822 if ( (mem = (u8 *)ioc->raid_data.pIocPg2) == NULL ) {
4823 mem = kmalloc(iocpage2sz, GFP_ATOMIC);
4825 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
4830 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
4832 /* Identify RAID Volume Id's */
4833 nVols = pIoc2->NumActiveVolumes;
4839 /* At least 1 RAID Volume
4841 pIocRv = pIoc2->RaidVolume;
4842 ioc->raid_data.isRaid = 0;
4843 for (jj = 0; jj < nVols; jj++, pIocRv++) {
4844 vid = pIocRv->VolumeID;
4845 vbus = pIocRv->VolumeBus;
4846 vioc = pIocRv->VolumeIOC;
4851 ioc->raid_data.isRaid |= (1 << vid);
4853 /* Error! Always bus 0
4859 /* Identify Hidden Physical Disk Id's */
4860 nPhys = pIoc2->NumActivePhysDisks;
4862 /* No physical disks.
4865 mpt_read_ioc_pg_3(ioc);
4869 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
4875 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
4880 ConfigPageHeader_t header;
4881 dma_addr_t ioc3_dma;
4884 /* Free the old page
4886 kfree(ioc->raid_data.pIocPg3);
4887 ioc->raid_data.pIocPg3 = NULL;
4889 /* There is at least one physical disk.
4890 * Read and save IOC Page 3
4892 header.PageVersion = 0;
4893 header.PageLength = 0;
4894 header.PageNumber = 3;
4895 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4896 cfg.cfghdr.hdr = &header;
4899 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4902 if (mpt_config(ioc, &cfg) != 0)
4905 if (header.PageLength == 0)
4908 /* Read Header good, alloc memory
4910 iocpage3sz = header.PageLength * 4;
4911 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
4915 /* Read the Page and save the data
4916 * into malloc'd memory.
4918 cfg.physAddr = ioc3_dma;
4919 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4920 if (mpt_config(ioc, &cfg) == 0) {
4921 mem = kmalloc(iocpage3sz, GFP_ATOMIC);
4923 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
4924 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
4928 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
4934 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
4938 ConfigPageHeader_t header;
4939 dma_addr_t ioc4_dma;
4942 /* Read and save IOC Page 4
4944 header.PageVersion = 0;
4945 header.PageLength = 0;
4946 header.PageNumber = 4;
4947 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4948 cfg.cfghdr.hdr = &header;
4951 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4954 if (mpt_config(ioc, &cfg) != 0)
4957 if (header.PageLength == 0)
4960 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
4961 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
4962 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
4966 ioc4_dma = ioc->spi_data.IocPg4_dma;
4967 iocpage4sz = ioc->spi_data.IocPg4Sz;
4970 /* Read the Page into dma memory.
4972 cfg.physAddr = ioc4_dma;
4973 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4974 if (mpt_config(ioc, &cfg) == 0) {
4975 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
4976 ioc->spi_data.IocPg4_dma = ioc4_dma;
4977 ioc->spi_data.IocPg4Sz = iocpage4sz;
4979 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
4980 ioc->spi_data.pIocPg4 = NULL;
4985 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
4989 ConfigPageHeader_t header;
4990 dma_addr_t ioc1_dma;
4994 /* Check the Coalescing Timeout in IOC Page 1
4996 header.PageVersion = 0;
4997 header.PageLength = 0;
4998 header.PageNumber = 1;
4999 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5000 cfg.cfghdr.hdr = &header;
5003 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5006 if (mpt_config(ioc, &cfg) != 0)
5009 if (header.PageLength == 0)
5012 /* Read Header good, alloc memory
5014 iocpage1sz = header.PageLength * 4;
5015 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
5019 /* Read the Page and check coalescing timeout
5021 cfg.physAddr = ioc1_dma;
5022 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5023 if (mpt_config(ioc, &cfg) == 0) {
5025 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
5026 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
5027 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
5029 dprintk((MYIOC_s_INFO_FMT "Coalescing Enabled Timeout = %d\n",
5032 if (tmp > MPT_COALESCING_TIMEOUT) {
5033 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
5035 /* Write NVRAM and current
5038 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5039 if (mpt_config(ioc, &cfg) == 0) {
5040 dprintk((MYIOC_s_INFO_FMT "Reset Current Coalescing Timeout to = %d\n",
5041 ioc->name, MPT_COALESCING_TIMEOUT));
5043 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
5044 if (mpt_config(ioc, &cfg) == 0) {
5045 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout to = %d\n",
5046 ioc->name, MPT_COALESCING_TIMEOUT));
5048 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout Failed\n",
5053 dprintk((MYIOC_s_WARN_FMT "Reset of Current Coalescing Timeout Failed!\n",
5059 dprintk((MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
5063 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
5068 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5070 * SendEventNotification - Send EventNotification (on or off) request
5072 * @ioc: Pointer to MPT_ADAPTER structure
5073 * @EvSwitch: Event switch flags
5076 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
5078 EventNotification_t *evnp;
5080 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
5082 devtverboseprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
5086 memset(evnp, 0, sizeof(*evnp));
5088 devtverboseprintk((MYIOC_s_INFO_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
5090 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
5091 evnp->ChainOffset = 0;
5093 evnp->Switch = EvSwitch;
5095 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
5100 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5102 * SendEventAck - Send EventAck request to MPT adapter.
5103 * @ioc: Pointer to MPT_ADAPTER structure
5104 * @evnp: Pointer to original EventNotification request
5107 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
5111 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5112 printk(MYIOC_s_WARN_FMT "Unable to allocate event ACK "
5113 "request frame for Event=%x EventContext=%x EventData=%x!\n",
5114 ioc->name, evnp->Event, le32_to_cpu(evnp->EventContext),
5115 le32_to_cpu(evnp->Data[0]));
5118 memset(pAck, 0, sizeof(*pAck));
5120 dprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name));
5122 pAck->Function = MPI_FUNCTION_EVENT_ACK;
5123 pAck->ChainOffset = 0;
5125 pAck->Event = evnp->Event;
5126 pAck->EventContext = evnp->EventContext;
5128 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
5133 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5135 * mpt_config - Generic function to issue config message
5136 * @ioc - Pointer to an adapter structure
5137 * @cfg - Pointer to a configuration structure. Struct contains
5138 * action, page address, direction, physical address
5139 * and pointer to a configuration page header
5140 * Page header is updated.
5142 * Returns 0 for success
5143 * -EPERM if not allowed due to ISR context
5144 * -EAGAIN if no msg frames currently available
5145 * -EFAULT for non-successful reply or no reply (timeout)
5148 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5151 ConfigExtendedPageHeader_t *pExtHdr = NULL;
5153 unsigned long flags;
5158 /* Prevent calling wait_event() (below), if caller happens
5159 * to be in ISR context, because that is fatal!
5161 in_isr = in_interrupt();
5163 dcprintk((MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
5168 /* Get and Populate a free Frame
5170 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5171 dcprintk((MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
5175 pReq = (Config_t *)mf;
5176 pReq->Action = pCfg->action;
5178 pReq->ChainOffset = 0;
5179 pReq->Function = MPI_FUNCTION_CONFIG;
5181 /* Assume page type is not extended and clear "reserved" fields. */
5182 pReq->ExtPageLength = 0;
5183 pReq->ExtPageType = 0;
5186 for (ii=0; ii < 8; ii++)
5187 pReq->Reserved2[ii] = 0;
5189 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
5190 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
5191 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
5192 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
5194 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5195 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
5196 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
5197 pReq->ExtPageType = pExtHdr->ExtPageType;
5198 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
5200 /* Page Length must be treated as a reserved field for the extended header. */
5201 pReq->Header.PageLength = 0;
5204 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
5206 /* Add a SGE to the config request.
5209 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
5211 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
5213 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5214 flagsLength |= pExtHdr->ExtPageLength * 4;
5216 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
5217 ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action));
5220 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
5222 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
5223 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
5226 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
5228 /* Append pCfg pointer to end of mf
5230 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5232 /* Initalize the timer
5234 init_timer(&pCfg->timer);
5235 pCfg->timer.data = (unsigned long) ioc;
5236 pCfg->timer.function = mpt_timer_expired;
5237 pCfg->wait_done = 0;
5239 /* Set the timer; ensure 10 second minimum */
5240 if (pCfg->timeout < 10)
5241 pCfg->timer.expires = jiffies + HZ*10;
5243 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5245 /* Add to end of Q, set timer and then issue this command */
5246 spin_lock_irqsave(&ioc->FreeQlock, flags);
5247 list_add_tail(&pCfg->linkage, &ioc->configQ);
5248 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5250 add_timer(&pCfg->timer);
5251 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5252 wait_event(mpt_waitq, pCfg->wait_done);
5254 /* mf has been freed - do not access */
5261 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5263 * mpt_timer_expired - Call back for timer process.
5264 * Used only internal config functionality.
5265 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5268 mpt_timer_expired(unsigned long data)
5270 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
5272 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired! \n", ioc->name));
5274 /* Perform a FW reload */
5275 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
5276 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
5278 /* No more processing.
5279 * Hard reset clean-up will wake up
5280 * process and free all resources.
5282 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired complete!\n", ioc->name));
5287 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5289 * mpt_ioc_reset - Base cleanup for hard reset
5290 * @ioc: Pointer to the adapter structure
5291 * @reset_phase: Indicates pre- or post-reset functionality
5293 * Remark: Free's resources with internally generated commands.
5296 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
5299 unsigned long flags;
5301 dprintk((KERN_WARNING MYNAM
5302 ": IOC %s_reset routed to MPT base driver!\n",
5303 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
5304 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
5306 if (reset_phase == MPT_IOC_SETUP_RESET) {
5308 } else if (reset_phase == MPT_IOC_PRE_RESET) {
5309 /* If the internal config Q is not empty -
5310 * delete timer. MF resources will be freed when
5311 * the FIFO's are primed.
5313 spin_lock_irqsave(&ioc->FreeQlock, flags);
5314 list_for_each_entry(pCfg, &ioc->configQ, linkage)
5315 del_timer(&pCfg->timer);
5316 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5321 /* Search the configQ for internal commands.
5322 * Flush the Q, and wake up all suspended threads.
5324 spin_lock_irqsave(&ioc->FreeQlock, flags);
5325 list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
5326 list_del(&pCfg->linkage);
5328 pCfg->status = MPT_CONFIG_ERROR;
5329 pCfg->wait_done = 1;
5330 wake_up(&mpt_waitq);
5332 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5335 return 1; /* currently means nothing really */
5339 #ifdef CONFIG_PROC_FS /* { */
5340 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5342 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5344 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5346 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5348 * Returns 0 for success, non-zero for failure.
5351 procmpt_create(void)
5353 struct proc_dir_entry *ent;
5355 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
5356 if (mpt_proc_root_dir == NULL)
5359 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5361 ent->read_proc = procmpt_summary_read;
5363 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5365 ent->read_proc = procmpt_version_read;
5370 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5372 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5374 * Returns 0 for success, non-zero for failure.
5377 procmpt_destroy(void)
5379 remove_proc_entry("version", mpt_proc_root_dir);
5380 remove_proc_entry("summary", mpt_proc_root_dir);
5381 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
5384 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5386 * procmpt_summary_read - Handle read request from /proc/mpt/summary
5387 * or from /proc/mpt/iocN/summary.
5388 * @buf: Pointer to area to write information
5389 * @start: Pointer to start pointer
5390 * @offset: Offset to start writing
5392 * @eof: Pointer to EOF integer
5395 * Returns number of characters written to process performing the read.
5398 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5408 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5412 list_for_each_entry(ioc, &ioc_list, list) {
5415 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5418 if ((out-buf) >= request)
5425 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5428 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5430 * procmpt_version_read - Handle read request from /proc/mpt/version.
5431 * @buf: Pointer to area to write information
5432 * @start: Pointer to start pointer
5433 * @offset: Offset to start writing
5435 * @eof: Pointer to EOF integer
5438 * Returns number of characters written to process performing the read.
5441 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5444 int scsi, fc, sas, lan, ctl, targ, dmp;
5448 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
5449 len += sprintf(buf+len, " Fusion MPT base driver\n");
5451 scsi = fc = sas = lan = ctl = targ = dmp = 0;
5452 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5454 if (MptCallbacks[ii]) {
5455 switch (MptDriverClass[ii]) {
5457 if (!scsi++) drvname = "SPI host";
5460 if (!fc++) drvname = "FC host";
5463 if (!sas++) drvname = "SAS host";
5466 if (!lan++) drvname = "LAN";
5469 if (!targ++) drvname = "SCSI target";
5472 if (!ctl++) drvname = "ioctl";
5477 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
5481 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5484 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5486 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
5487 * @buf: Pointer to area to write information
5488 * @start: Pointer to start pointer
5489 * @offset: Offset to start writing
5491 * @eof: Pointer to EOF integer
5494 * Returns number of characters written to process performing the read.
5497 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5499 MPT_ADAPTER *ioc = data;
5505 mpt_get_fw_exp_ver(expVer, ioc);
5507 len = sprintf(buf, "%s:", ioc->name);
5508 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
5509 len += sprintf(buf+len, " (f/w download boot flag set)");
5510 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
5511 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
5513 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
5514 ioc->facts.ProductID,
5516 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
5517 if (ioc->facts.FWImageSize)
5518 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
5519 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
5520 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
5521 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
5523 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
5524 ioc->facts.CurrentHostMfaHighAddr);
5525 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
5526 ioc->facts.CurrentSenseBufferHighAddr);
5528 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
5529 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
5531 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
5532 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
5534 * Rounding UP to nearest 4-kB boundary here...
5536 sz = (ioc->req_sz * ioc->req_depth) + 128;
5537 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
5538 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
5539 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
5540 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
5541 4*ioc->facts.RequestFrameSize,
5542 ioc->facts.GlobalCredits);
5544 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
5545 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
5546 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
5547 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
5548 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
5549 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
5550 ioc->facts.CurReplyFrameSize,
5551 ioc->facts.ReplyQueueDepth);
5553 len += sprintf(buf+len, " MaxDevices = %d\n",
5554 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
5555 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
5558 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
5559 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
5561 ioc->facts.NumberOfPorts);
5562 if (ioc->bus_type == FC) {
5563 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
5564 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5565 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
5566 a[5], a[4], a[3], a[2], a[1], a[0]);
5568 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
5569 ioc->fc_port_page0[p].WWNN.High,
5570 ioc->fc_port_page0[p].WWNN.Low,
5571 ioc->fc_port_page0[p].WWPN.High,
5572 ioc->fc_port_page0[p].WWPN.Low);
5576 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5579 #endif /* CONFIG_PROC_FS } */
5581 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5583 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
5586 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
5587 sprintf(buf, " (Exp %02d%02d)",
5588 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
5589 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
5592 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
5593 strcat(buf, " [MDBG]");
5597 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5599 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
5600 * @ioc: Pointer to MPT_ADAPTER structure
5601 * @buffer: Pointer to buffer where IOC summary info should be written
5602 * @size: Pointer to number of bytes we wrote (set by this routine)
5603 * @len: Offset at which to start writing in buffer
5604 * @showlan: Display LAN stuff?
5606 * This routine writes (english readable) ASCII text, which represents
5607 * a summary of IOC information, to a buffer.
5610 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
5615 mpt_get_fw_exp_ver(expVer, ioc);
5618 * Shorter summary of attached ioc's...
5620 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
5623 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
5624 ioc->facts.FWVersion.Word,
5626 ioc->facts.NumberOfPorts,
5629 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
5630 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5631 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
5632 a[5], a[4], a[3], a[2], a[1], a[0]);
5636 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
5638 y += sprintf(buffer+len+y, ", IRQ=%s", __irq_itoa(ioc->pci_irq));
5642 y += sprintf(buffer+len+y, " (disabled)");
5644 y += sprintf(buffer+len+y, "\n");
5649 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5653 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5655 * mpt_HardResetHandler - Generic reset handler, issue SCSI Task
5656 * Management call based on input arg values. If TaskMgmt fails,
5657 * return associated SCSI request.
5658 * @ioc: Pointer to MPT_ADAPTER structure
5659 * @sleepFlag: Indicates if sleep or schedule must be called.
5661 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
5662 * or a non-interrupt thread. In the former, must not call schedule().
5664 * Remark: A return of -1 is a FATAL error case, as it means a
5665 * FW reload/initialization failed.
5667 * Returns 0 for SUCCESS or -1 if FAILED.
5670 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
5673 unsigned long flags;
5675 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name));
5677 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
5678 printk("MF count 0x%x !\n", ioc->mfcnt);
5681 /* Reset the adapter. Prevent more than 1 call to
5682 * mpt_do_ioc_recovery at any instant in time.
5684 spin_lock_irqsave(&ioc->diagLock, flags);
5685 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
5686 spin_unlock_irqrestore(&ioc->diagLock, flags);
5689 ioc->diagPending = 1;
5691 spin_unlock_irqrestore(&ioc->diagLock, flags);
5693 /* FIXME: If do_ioc_recovery fails, repeat....
5696 /* The SCSI driver needs to adjust timeouts on all current
5697 * commands prior to the diagnostic reset being issued.
5698 * Prevents timeouts occuring during a diagnostic reset...very bad.
5699 * For all other protocol drivers, this is a no-op.
5705 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5706 if (MptResetHandlers[ii]) {
5707 dtmprintk((MYIOC_s_INFO_FMT "Calling IOC reset_setup handler #%d\n",
5709 r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_SETUP_RESET);
5711 dtmprintk((MYIOC_s_INFO_FMT "Calling alt-%s setup reset handler #%d\n",
5712 ioc->name, ioc->alt_ioc->name, ii));
5713 r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_SETUP_RESET);
5719 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
5720 printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
5725 ioc->alt_ioc->reload_fw = 0;
5727 spin_lock_irqsave(&ioc->diagLock, flags);
5728 ioc->diagPending = 0;
5730 ioc->alt_ioc->diagPending = 0;
5731 spin_unlock_irqrestore(&ioc->diagLock, flags);
5733 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
5738 # define EVENT_DESCR_STR_SZ 100
5740 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5742 EventDescriptionStr(u8 event, u32 evData0, char *evStr)
5747 case MPI_EVENT_NONE:
5750 case MPI_EVENT_LOG_DATA:
5753 case MPI_EVENT_STATE_CHANGE:
5754 ds = "State Change";
5756 case MPI_EVENT_UNIT_ATTENTION:
5757 ds = "Unit Attention";
5759 case MPI_EVENT_IOC_BUS_RESET:
5760 ds = "IOC Bus Reset";
5762 case MPI_EVENT_EXT_BUS_RESET:
5763 ds = "External Bus Reset";
5765 case MPI_EVENT_RESCAN:
5766 ds = "Bus Rescan Event";
5767 /* Ok, do we need to do anything here? As far as
5768 I can tell, this is when a new device gets added
5771 case MPI_EVENT_LINK_STATUS_CHANGE:
5772 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
5773 ds = "Link Status(FAILURE) Change";
5775 ds = "Link Status(ACTIVE) Change";
5777 case MPI_EVENT_LOOP_STATE_CHANGE:
5778 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
5779 ds = "Loop State(LIP) Change";
5780 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
5781 ds = "Loop State(LPE) Change"; /* ??? */
5783 ds = "Loop State(LPB) Change"; /* ??? */
5785 case MPI_EVENT_LOGOUT:
5788 case MPI_EVENT_EVENT_CHANGE:
5790 ds = "Events(ON) Change";
5792 ds = "Events(OFF) Change";
5794 case MPI_EVENT_INTEGRATED_RAID:
5796 u8 ReasonCode = (u8)(evData0 >> 16);
5797 switch (ReasonCode) {
5798 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
5799 ds = "Integrated Raid: Volume Created";
5801 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
5802 ds = "Integrated Raid: Volume Deleted";
5804 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
5805 ds = "Integrated Raid: Volume Settings Changed";
5807 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
5808 ds = "Integrated Raid: Volume Status Changed";
5810 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
5811 ds = "Integrated Raid: Volume Physdisk Changed";
5813 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
5814 ds = "Integrated Raid: Physdisk Created";
5816 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
5817 ds = "Integrated Raid: Physdisk Deleted";
5819 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
5820 ds = "Integrated Raid: Physdisk Settings Changed";
5822 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
5823 ds = "Integrated Raid: Physdisk Status Changed";
5825 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
5826 ds = "Integrated Raid: Domain Validation Needed";
5828 case MPI_EVENT_RAID_RC_SMART_DATA :
5829 ds = "Integrated Raid; Smart Data";
5831 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
5832 ds = "Integrated Raid: Replace Action Started";
5835 ds = "Integrated Raid";
5840 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
5841 ds = "SCSI Device Status Change";
5843 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
5845 u8 id = (u8)(evData0);
5846 u8 ReasonCode = (u8)(evData0 >> 16);
5847 switch (ReasonCode) {
5848 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
5849 snprintf(evStr, EVENT_DESCR_STR_SZ,
5850 "SAS Device Status Change: Added: id=%d", id);
5852 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
5853 snprintf(evStr, EVENT_DESCR_STR_SZ,
5854 "SAS Device Status Change: Deleted: id=%d", id);
5856 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
5857 snprintf(evStr, EVENT_DESCR_STR_SZ,
5858 "SAS Device Status Change: SMART Data: id=%d",
5861 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
5862 snprintf(evStr, EVENT_DESCR_STR_SZ,
5863 "SAS Device Status Change: No Persistancy "
5864 "Added: id=%d", id);
5867 snprintf(evStr, EVENT_DESCR_STR_SZ,
5868 "SAS Device Status Change: Unknown: id=%d", id);
5873 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
5874 ds = "Bus Timer Expired";
5876 case MPI_EVENT_QUEUE_FULL:
5879 case MPI_EVENT_SAS_SES:
5880 ds = "SAS SES Event";
5882 case MPI_EVENT_PERSISTENT_TABLE_FULL:
5883 ds = "Persistent Table Full";
5885 case MPI_EVENT_SAS_PHY_LINK_STATUS:
5887 u8 LinkRates = (u8)(evData0 >> 8);
5888 u8 PhyNumber = (u8)(evData0);
5889 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
5890 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
5891 switch (LinkRates) {
5892 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
5893 snprintf(evStr, EVENT_DESCR_STR_SZ,
5894 "SAS PHY Link Status: Phy=%d:"
5895 " Rate Unknown",PhyNumber);
5897 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
5898 snprintf(evStr, EVENT_DESCR_STR_SZ,
5899 "SAS PHY Link Status: Phy=%d:"
5900 " Phy Disabled",PhyNumber);
5902 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
5903 snprintf(evStr, EVENT_DESCR_STR_SZ,
5904 "SAS PHY Link Status: Phy=%d:"
5905 " Failed Speed Nego",PhyNumber);
5907 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
5908 snprintf(evStr, EVENT_DESCR_STR_SZ,
5909 "SAS PHY Link Status: Phy=%d:"
5910 " Sata OOB Completed",PhyNumber);
5912 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
5913 snprintf(evStr, EVENT_DESCR_STR_SZ,
5914 "SAS PHY Link Status: Phy=%d:"
5915 " Rate 1.5 Gbps",PhyNumber);
5917 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
5918 snprintf(evStr, EVENT_DESCR_STR_SZ,
5919 "SAS PHY Link Status: Phy=%d:"
5920 " Rate 3.0 Gpbs",PhyNumber);
5923 snprintf(evStr, EVENT_DESCR_STR_SZ,
5924 "SAS PHY Link Status: Phy=%d", PhyNumber);
5929 case MPI_EVENT_SAS_DISCOVERY_ERROR:
5930 ds = "SAS Discovery Error";
5932 case MPI_EVENT_IR_RESYNC_UPDATE:
5934 u8 resync_complete = (u8)(evData0 >> 16);
5935 snprintf(evStr, EVENT_DESCR_STR_SZ,
5936 "IR Resync Update: Complete = %d:",resync_complete);
5941 u8 ReasonCode = (u8)(evData0 >> 16);
5942 switch (ReasonCode) {
5943 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
5944 ds = "IR2: LD State Changed";
5946 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
5947 ds = "IR2: PD State Changed";
5949 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
5950 ds = "IR2: Bad Block Table Full";
5952 case MPI_EVENT_IR2_RC_PD_INSERTED:
5953 ds = "IR2: PD Inserted";
5955 case MPI_EVENT_IR2_RC_PD_REMOVED:
5956 ds = "IR2: PD Removed";
5958 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
5959 ds = "IR2: Foreign CFG Detected";
5961 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
5962 ds = "IR2: Rebuild Medium Error";
5970 case MPI_EVENT_SAS_DISCOVERY:
5973 ds = "SAS Discovery: Start";
5975 ds = "SAS Discovery: Stop";
5978 case MPI_EVENT_LOG_ENTRY_ADDED:
5979 ds = "SAS Log Entry Added";
5983 * MPT base "custom" events may be added here...
5990 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
5993 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5995 * ProcessEventNotification - Route a received EventNotificationReply to
5996 * all currently regeistered event handlers.
5997 * @ioc: Pointer to MPT_ADAPTER structure
5998 * @pEventReply: Pointer to EventNotification reply frame
5999 * @evHandlers: Pointer to integer, number of event handlers
6001 * Returns sum of event handlers return values.
6004 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
6012 char evStr[EVENT_DESCR_STR_SZ];
6016 * Do platform normalization of values
6018 event = le32_to_cpu(pEventReply->Event) & 0xFF;
6019 // evCtx = le32_to_cpu(pEventReply->EventContext);
6020 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
6022 evData0 = le32_to_cpu(pEventReply->Data[0]);
6025 EventDescriptionStr(event, evData0, evStr);
6026 devtprintk((MYIOC_s_INFO_FMT "MPT event:(%02Xh) : %s\n",
6031 #if defined(MPT_DEBUG) || defined(MPT_DEBUG_VERBOSE_EVENTS)
6032 printk(KERN_INFO MYNAM ": Event data:\n" KERN_INFO);
6033 for (ii = 0; ii < evDataLen; ii++)
6034 printk(" %08x", le32_to_cpu(pEventReply->Data[ii]));
6039 * Do general / base driver event processing
6042 case MPI_EVENT_EVENT_CHANGE: /* 0A */
6044 u8 evState = evData0 & 0xFF;
6046 /* CHECKME! What if evState unexpectedly says OFF (0)? */
6048 /* Update EventState field in cached IocFacts */
6049 if (ioc->facts.Function) {
6050 ioc->facts.EventState = evState;
6054 case MPI_EVENT_INTEGRATED_RAID:
6055 mptbase_raid_process_event_data(ioc,
6056 (MpiEventDataRaid_t *)pEventReply->Data);
6063 * Should this event be logged? Events are written sequentially.
6064 * When buffer is full, start again at the top.
6066 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
6069 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
6071 ioc->events[idx].event = event;
6072 ioc->events[idx].eventContext = ioc->eventContext;
6074 for (ii = 0; ii < 2; ii++) {
6076 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
6078 ioc->events[idx].data[ii] = 0;
6081 ioc->eventContext++;
6086 * Call each currently registered protocol event handler.
6088 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
6089 if (MptEvHandlers[ii]) {
6090 devtverboseprintk((MYIOC_s_INFO_FMT "Routing Event to event handler #%d\n",
6092 r += (*(MptEvHandlers[ii]))(ioc, pEventReply);
6096 /* FIXME? Examine results here? */
6099 * If needed, send (a single) EventAck.
6101 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
6102 devtverboseprintk((MYIOC_s_WARN_FMT
6103 "EventAck required\n",ioc->name));
6104 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
6105 devtverboseprintk((MYIOC_s_WARN_FMT "SendEventAck returned %d\n",
6110 *evHandlers = handlers;
6114 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6116 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
6117 * @ioc: Pointer to MPT_ADAPTER structure
6118 * @log_info: U32 LogInfo reply word from the IOC
6120 * Refer to lsi/fc_log.h.
6123 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
6125 static char *subcl_str[8] = {
6126 "FCP Initiator", "FCP Target", "LAN", "MPI Message Layer",
6127 "FC Link", "Context Manager", "Invalid Field Offset", "State Change Info"
6129 u8 subcl = (log_info >> 24) & 0x7;
6131 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubCl={%s}\n",
6132 ioc->name, log_info, subcl_str[subcl]);
6135 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6137 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
6138 * @ioc: Pointer to MPT_ADAPTER structure
6139 * @mr: Pointer to MPT reply frame
6140 * @log_info: U32 LogInfo word from the IOC
6142 * Refer to lsi/sp_log.h.
6145 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
6147 u32 info = log_info & 0x00FF0000;
6148 char *desc = "unknown";
6152 desc = "bug! MID not found";
6153 if (ioc->reload_fw == 0)
6158 desc = "Parity Error";
6162 desc = "ASYNC Outbound Overrun";
6166 desc = "SYNC Offset Error";
6174 desc = "Msg In Overflow";
6182 desc = "Outbound DMA Overrun";
6186 desc = "Task Management";
6190 desc = "Device Problem";
6194 desc = "Invalid Phase Change";
6198 desc = "Untagged Table Size";
6203 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
6206 /* strings for sas loginfo */
6207 static char *originator_str[] = {
6212 static char *iop_code_str[] = {
6214 "Invalid SAS Address", /* 01h */
6216 "Invalid Page", /* 03h */
6218 "Task Terminated" /* 05h */
6220 static char *pl_code_str[] = {
6222 "Open Failure", /* 01h */
6223 "Invalid Scatter Gather List", /* 02h */
6224 "Wrong Relative Offset or Frame Length", /* 03h */
6225 "Frame Transfer Error", /* 04h */
6226 "Transmit Frame Connected Low", /* 05h */
6227 "SATA Non-NCQ RW Error Bit Set", /* 06h */
6228 "SATA Read Log Receive Data Error", /* 07h */
6229 "SATA NCQ Fail All Commands After Error", /* 08h */
6230 "SATA Error in Receive Set Device Bit FIS", /* 09h */
6231 "Receive Frame Invalid Message", /* 0Ah */
6232 "Receive Context Message Valid Error", /* 0Bh */
6233 "Receive Frame Current Frame Error", /* 0Ch */
6234 "SATA Link Down", /* 0Dh */
6235 "Discovery SATA Init W IOS", /* 0Eh */
6236 "Config Invalid Page", /* 0Fh */
6237 "Discovery SATA Init Timeout", /* 10h */
6240 "IO Not Yet Executed", /* 13h */
6241 "IO Executed", /* 14h */
6242 "Persistant Reservation Out Not Affiliation Owner", /* 15h */
6243 "Open Transmit DMA Abort", /* 16h */
6253 "Enclosure Management" /* 20h */
6256 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6258 * mpt_sas_log_info - Log information returned from SAS IOC.
6259 * @ioc: Pointer to MPT_ADAPTER structure
6260 * @log_info: U32 LogInfo reply word from the IOC
6262 * Refer to lsi/mpi_log_sas.h.
6265 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
6267 union loginfo_type {
6276 union loginfo_type sas_loginfo;
6277 char *code_desc = NULL;
6279 sas_loginfo.loginfo = log_info;
6280 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
6281 (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
6283 if ((sas_loginfo.dw.originator == 0 /*IOP*/) &&
6284 (sas_loginfo.dw.code < sizeof(iop_code_str)/sizeof(char*))) {
6285 code_desc = iop_code_str[sas_loginfo.dw.code];
6286 }else if ((sas_loginfo.dw.originator == 1 /*PL*/) &&
6287 (sas_loginfo.dw.code < sizeof(pl_code_str)/sizeof(char*) )) {
6288 code_desc = pl_code_str[sas_loginfo.dw.code];
6291 if (code_desc != NULL)
6292 printk(MYIOC_s_INFO_FMT
6293 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
6294 " SubCode(0x%04x)\n",
6297 originator_str[sas_loginfo.dw.originator],
6299 sas_loginfo.dw.subcode);
6301 printk(MYIOC_s_INFO_FMT
6302 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
6303 " SubCode(0x%04x)\n",
6306 originator_str[sas_loginfo.dw.originator],
6307 sas_loginfo.dw.code,
6308 sas_loginfo.dw.subcode);
6311 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6313 * mpt_sp_ioc_info - IOC information returned from SCSI Parallel IOC.
6314 * @ioc: Pointer to MPT_ADAPTER structure
6315 * @ioc_status: U32 IOCStatus word from IOC
6316 * @mf: Pointer to MPT request frame
6318 * Refer to lsi/mpi.h.
6321 mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
6323 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
6327 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
6328 desc = "Invalid Function";
6331 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
6335 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
6336 desc = "Invalid SGL";
6339 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
6340 desc = "Internal Error";
6343 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
6347 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
6348 desc = "Insufficient Resources";
6351 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
6352 desc = "Invalid Field";
6355 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
6356 desc = "Invalid State";
6359 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
6360 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
6361 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
6362 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
6363 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
6364 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
6365 /* No message for Config IOCStatus values */
6368 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
6369 /* No message for recovered error
6370 desc = "SCSI Recovered Error";
6374 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
6375 desc = "SCSI Invalid Bus";
6378 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
6379 desc = "SCSI Invalid TargetID";
6382 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
6384 SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
6385 U8 cdb = pScsiReq->CDB[0];
6386 if (cdb != 0x12) { /* Inquiry is issued for device scanning */
6387 desc = "SCSI Device Not There";
6392 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
6393 desc = "SCSI Data Overrun";
6396 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
6397 /* This error is checked in scsi_io_done(). Skip.
6398 desc = "SCSI Data Underrun";
6402 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
6403 desc = "SCSI I/O Data Error";
6406 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
6407 desc = "SCSI Protocol Error";
6410 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
6411 desc = "SCSI Task Terminated";
6414 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
6415 desc = "SCSI Residual Mismatch";
6418 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
6419 desc = "SCSI Task Management Failed";
6422 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
6423 desc = "SCSI IOC Terminated";
6426 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
6427 desc = "SCSI Ext Terminated";
6435 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04x): %s\n", ioc->name, status, desc);
6438 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6439 EXPORT_SYMBOL(mpt_attach);
6440 EXPORT_SYMBOL(mpt_detach);
6442 EXPORT_SYMBOL(mpt_resume);
6443 EXPORT_SYMBOL(mpt_suspend);
6445 EXPORT_SYMBOL(ioc_list);
6446 EXPORT_SYMBOL(mpt_proc_root_dir);
6447 EXPORT_SYMBOL(mpt_register);
6448 EXPORT_SYMBOL(mpt_deregister);
6449 EXPORT_SYMBOL(mpt_event_register);
6450 EXPORT_SYMBOL(mpt_event_deregister);
6451 EXPORT_SYMBOL(mpt_reset_register);
6452 EXPORT_SYMBOL(mpt_reset_deregister);
6453 EXPORT_SYMBOL(mpt_device_driver_register);
6454 EXPORT_SYMBOL(mpt_device_driver_deregister);
6455 EXPORT_SYMBOL(mpt_get_msg_frame);
6456 EXPORT_SYMBOL(mpt_put_msg_frame);
6457 EXPORT_SYMBOL(mpt_free_msg_frame);
6458 EXPORT_SYMBOL(mpt_add_sge);
6459 EXPORT_SYMBOL(mpt_send_handshake_request);
6460 EXPORT_SYMBOL(mpt_verify_adapter);
6461 EXPORT_SYMBOL(mpt_GetIocState);
6462 EXPORT_SYMBOL(mpt_print_ioc_summary);
6463 EXPORT_SYMBOL(mpt_lan_index);
6464 EXPORT_SYMBOL(mpt_stm_index);
6465 EXPORT_SYMBOL(mpt_HardResetHandler);
6466 EXPORT_SYMBOL(mpt_config);
6467 EXPORT_SYMBOL(mpt_findImVolumes);
6468 EXPORT_SYMBOL(mpt_alloc_fw_memory);
6469 EXPORT_SYMBOL(mpt_free_fw_memory);
6470 EXPORT_SYMBOL(mptbase_sas_persist_operation);
6471 EXPORT_SYMBOL(mptbase_GetFcPortPage0);
6474 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6476 * fusion_init - Fusion MPT base driver initialization routine.
6478 * Returns 0 for success, non-zero for failure.
6485 show_mptmod_ver(my_NAME, my_VERSION);
6486 printk(KERN_INFO COPYRIGHT "\n");
6488 for (i = 0; i < MPT_MAX_PROTOCOL_DRIVERS; i++) {
6489 MptCallbacks[i] = NULL;
6490 MptDriverClass[i] = MPTUNKNOWN_DRIVER;
6491 MptEvHandlers[i] = NULL;
6492 MptResetHandlers[i] = NULL;
6495 /* Register ourselves (mptbase) in order to facilitate
6496 * EventNotification handling.
6498 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
6500 /* Register for hard reset handling callbacks.
6502 if (mpt_reset_register(mpt_base_index, mpt_ioc_reset) == 0) {
6503 dprintk((KERN_INFO MYNAM ": Register for IOC reset notification\n"));
6508 #ifdef CONFIG_PROC_FS
6509 (void) procmpt_create();
6514 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6516 * fusion_exit - Perform driver unload cleanup.
6518 * This routine frees all resources associated with each MPT adapter
6519 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
6525 dexitprintk((KERN_INFO MYNAM ": fusion_exit() called!\n"));
6527 mpt_reset_deregister(mpt_base_index);
6529 #ifdef CONFIG_PROC_FS
6534 module_init(fusion_init);
6535 module_exit(fusion_exit);