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-2007 LSI Logic Corporation
9 * (mailto:DL-MPTFusionLinux@lsi.com)
12 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; version 2 of the License.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
24 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
25 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
26 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
27 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
28 solely responsible for determining the appropriateness of using and
29 distributing the Program and assumes all risks associated with its
30 exercise of rights under this Agreement, including but not limited to
31 the risks and costs of program errors, damage to or loss of data,
32 programs or equipment, and unavailability or interruption of operations.
34 DISCLAIMER OF LIABILITY
35 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
36 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
38 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
39 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
40 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
41 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
43 You should have received a copy of the GNU General Public License
44 along with this program; if not, write to the Free Software
45 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
47 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
49 #include <linux/kernel.h>
50 #include <linux/module.h>
51 #include <linux/errno.h>
52 #include <linux/init.h>
53 #include <linux/slab.h>
54 #include <linux/types.h>
55 #include <linux/pci.h>
56 #include <linux/kdev_t.h>
57 #include <linux/blkdev.h>
58 #include <linux/delay.h>
59 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
60 #include <linux/dma-mapping.h>
67 #include "lsi/mpi_log_fc.h"
69 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
70 #define my_NAME "Fusion MPT base driver"
71 #define my_VERSION MPT_LINUX_VERSION_COMMON
72 #define MYNAM "mptbase"
74 MODULE_AUTHOR(MODULEAUTHOR);
75 MODULE_DESCRIPTION(my_NAME);
76 MODULE_LICENSE("GPL");
77 MODULE_VERSION(my_VERSION);
82 static int mpt_msi_enable;
83 module_param(mpt_msi_enable, int, 0);
84 MODULE_PARM_DESC(mpt_msi_enable, " MSI Support Enable (default=0)");
86 static int mpt_channel_mapping;
87 module_param(mpt_channel_mapping, int, 0);
88 MODULE_PARM_DESC(mpt_channel_mapping, " Mapping id's to channels (default=0)");
91 static int mfcounter = 0;
92 #define PRINT_MF_COUNT 20000
95 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
99 int mpt_lan_index = -1;
100 int mpt_stm_index = -1;
102 struct proc_dir_entry *mpt_proc_root_dir;
104 #define WHOINIT_UNKNOWN 0xAA
106 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
110 /* Adapter link list */
112 /* Callback lookup table */
113 static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
114 /* Protocol driver class lookup table */
115 static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
116 /* Event handler lookup table */
117 static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
118 /* Reset handler lookup table */
119 static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
120 static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
122 static int mpt_base_index = -1;
123 static int last_drv_idx = -1;
125 static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq);
127 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
131 static irqreturn_t mpt_interrupt(int irq, void *bus_id);
132 static int mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
133 static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
134 u32 *req, int replyBytes, u16 *u16reply, int maxwait,
136 static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
137 static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
138 static void mpt_adapter_disable(MPT_ADAPTER *ioc);
139 static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
141 static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
142 static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
143 static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
144 static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
145 static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
146 static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
147 static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
148 static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
149 static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
150 static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
151 static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
152 static int PrimeIocFifos(MPT_ADAPTER *ioc);
153 static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
154 static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
155 static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
156 static int GetLanConfigPages(MPT_ADAPTER *ioc);
157 static int GetIoUnitPage2(MPT_ADAPTER *ioc);
158 int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
159 static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
160 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
161 static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
162 static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
163 static void mpt_timer_expired(unsigned long data);
164 static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
165 static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
166 static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
167 static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
169 #ifdef CONFIG_PROC_FS
170 static int procmpt_summary_read(char *buf, char **start, off_t offset,
171 int request, int *eof, void *data);
172 static int procmpt_version_read(char *buf, char **start, off_t offset,
173 int request, int *eof, void *data);
174 static int procmpt_iocinfo_read(char *buf, char **start, off_t offset,
175 int request, int *eof, void *data);
177 static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
179 //int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
180 static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers);
181 #ifdef MPT_DEBUG_REPLY
182 static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
184 static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
185 static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
186 static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
187 static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
188 static void mpt_inactive_raid_list_free(MPT_ADAPTER *ioc);
190 /* module entry point */
191 static int __init fusion_init (void);
192 static void __exit fusion_exit (void);
194 #define CHIPREG_READ32(addr) readl_relaxed(addr)
195 #define CHIPREG_READ32_dmasync(addr) readl(addr)
196 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
197 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
198 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
201 pci_disable_io_access(struct pci_dev *pdev)
205 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
207 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
211 pci_enable_io_access(struct pci_dev *pdev)
215 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
217 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
221 * Process turbo (context) reply...
224 mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
226 MPT_FRAME_HDR *mf = NULL;
227 MPT_FRAME_HDR *mr = NULL;
231 dmfprintk((MYIOC_s_INFO_FMT "Got TURBO reply req_idx=%08x\n",
234 switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
235 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
236 req_idx = pa & 0x0000FFFF;
237 cb_idx = (pa & 0x00FF0000) >> 16;
238 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
240 case MPI_CONTEXT_REPLY_TYPE_LAN:
241 cb_idx = mpt_lan_index;
243 * Blind set of mf to NULL here was fatal
244 * after lan_reply says "freeme"
245 * Fix sort of combined with an optimization here;
246 * added explicit check for case where lan_reply
247 * was just returning 1 and doing nothing else.
248 * For this case skip the callback, but set up
249 * proper mf value first here:-)
251 if ((pa & 0x58000000) == 0x58000000) {
252 req_idx = pa & 0x0000FFFF;
253 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
254 mpt_free_msg_frame(ioc, mf);
259 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
261 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
262 cb_idx = mpt_stm_index;
263 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
270 /* Check for (valid) IO callback! */
271 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
272 MptCallbacks[cb_idx] == NULL) {
273 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
274 __FUNCTION__, ioc->name, cb_idx);
278 if (MptCallbacks[cb_idx](ioc, mf, mr))
279 mpt_free_msg_frame(ioc, mf);
285 mpt_reply(MPT_ADAPTER *ioc, u32 pa)
296 /* non-TURBO reply! Hmmm, something may be up...
297 * Newest turbo reply mechanism; get address
298 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
301 /* Map DMA address of reply header to cpu address.
302 * pa is 32 bits - but the dma address may be 32 or 64 bits
303 * get offset based only only the low addresses
306 reply_dma_low = (pa <<= 1);
307 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
308 (reply_dma_low - ioc->reply_frames_low_dma));
310 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
311 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
312 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
314 dmfprintk((MYIOC_s_INFO_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
315 ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
316 DBG_DUMP_REPLY_FRAME(mr)
318 /* Check/log IOC log info
320 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
321 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
322 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
323 if (ioc->bus_type == FC)
324 mpt_fc_log_info(ioc, log_info);
325 else if (ioc->bus_type == SPI)
326 mpt_spi_log_info(ioc, log_info);
327 else if (ioc->bus_type == SAS)
328 mpt_sas_log_info(ioc, log_info);
331 #ifdef MPT_DEBUG_REPLY
332 if (ioc_stat & MPI_IOCSTATUS_MASK)
333 mpt_iocstatus_info(ioc, (u32)ioc_stat, mf);
336 /* Check for (valid) IO callback! */
337 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
338 MptCallbacks[cb_idx] == NULL) {
339 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
340 __FUNCTION__, ioc->name, cb_idx);
345 freeme = MptCallbacks[cb_idx](ioc, mf, mr);
348 /* Flush (non-TURBO) reply with a WRITE! */
349 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
352 mpt_free_msg_frame(ioc, mf);
356 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
358 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
359 * @irq: irq number (not used)
360 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
362 * This routine is registered via the request_irq() kernel API call,
363 * and handles all interrupts generated from a specific MPT adapter
364 * (also referred to as a IO Controller or IOC).
365 * This routine must clear the interrupt from the adapter and does
366 * so by reading the reply FIFO. Multiple replies may be processed
367 * per single call to this routine.
369 * This routine handles register-level access of the adapter but
370 * dispatches (calls) a protocol-specific callback routine to handle
371 * the protocol-specific details of the MPT request completion.
374 mpt_interrupt(int irq, void *bus_id)
376 MPT_ADAPTER *ioc = bus_id;
377 u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
379 if (pa == 0xFFFFFFFF)
383 * Drain the reply FIFO!
386 if (pa & MPI_ADDRESS_REPLY_A_BIT)
389 mpt_turbo_reply(ioc, pa);
390 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
391 } while (pa != 0xFFFFFFFF);
396 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
398 * mpt_base_reply - MPT base driver's callback routine
399 * @ioc: Pointer to MPT_ADAPTER structure
400 * @mf: Pointer to original MPT request frame
401 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
403 * MPT base driver's callback routine; all base driver
404 * "internal" request/reply processing is routed here.
405 * Currently used for EventNotification and EventAck handling.
407 * Returns 1 indicating original alloc'd request frame ptr
408 * should be freed, or 0 if it shouldn't.
411 mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
416 dmfprintk((MYIOC_s_INFO_FMT "mpt_base_reply() called\n", ioc->name));
418 #if defined(MPT_DEBUG_MSG_FRAME)
419 if (!(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) {
420 dmfprintk((KERN_INFO MYNAM ": Original request frame (@%p) header\n", mf));
421 DBG_DUMP_REQUEST_FRAME_HDR(mf)
425 func = reply->u.hdr.Function;
426 dmfprintk((MYIOC_s_INFO_FMT "mpt_base_reply, Function=%02Xh\n",
429 if (func == MPI_FUNCTION_EVENT_NOTIFICATION) {
430 EventNotificationReply_t *pEvReply = (EventNotificationReply_t *) reply;
434 results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
435 if (results != evHandlers) {
436 /* CHECKME! Any special handling needed here? */
437 devtverboseprintk((MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
438 ioc->name, evHandlers, results));
442 * Hmmm... It seems that EventNotificationReply is an exception
443 * to the rule of one reply per request.
445 if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) {
448 devtverboseprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
449 ioc->name, pEvReply));
452 #ifdef CONFIG_PROC_FS
453 // LogEvent(ioc, pEvReply);
456 } else if (func == MPI_FUNCTION_EVENT_ACK) {
457 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n",
459 } else if (func == MPI_FUNCTION_CONFIG) {
463 dcprintk((MYIOC_s_INFO_FMT "config_complete (mf=%p,mr=%p)\n",
464 ioc->name, mf, reply));
466 pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *)));
469 /* disable timer and remove from linked list */
470 del_timer(&pCfg->timer);
472 spin_lock_irqsave(&ioc->FreeQlock, flags);
473 list_del(&pCfg->linkage);
474 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
477 * If IOC Status is SUCCESS, save the header
478 * and set the status code to GOOD.
480 pCfg->status = MPT_CONFIG_ERROR;
482 ConfigReply_t *pReply = (ConfigReply_t *)reply;
485 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
486 dcprintk((KERN_NOTICE " IOCStatus=%04xh, IOCLogInfo=%08xh\n",
487 status, le32_to_cpu(pReply->IOCLogInfo)));
489 pCfg->status = status;
490 if (status == MPI_IOCSTATUS_SUCCESS) {
491 if ((pReply->Header.PageType &
492 MPI_CONFIG_PAGETYPE_MASK) ==
493 MPI_CONFIG_PAGETYPE_EXTENDED) {
494 pCfg->cfghdr.ehdr->ExtPageLength =
495 le16_to_cpu(pReply->ExtPageLength);
496 pCfg->cfghdr.ehdr->ExtPageType =
499 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
501 /* If this is a regular header, save PageLength. */
502 /* LMP Do this better so not using a reserved field! */
503 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
504 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
505 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
510 * Wake up the original calling thread
515 } else if (func == MPI_FUNCTION_SAS_IO_UNIT_CONTROL) {
516 /* we should be always getting a reply frame */
517 memcpy(ioc->persist_reply_frame, reply,
518 min(MPT_DEFAULT_FRAME_SIZE,
519 4*reply->u.reply.MsgLength));
520 del_timer(&ioc->persist_timer);
521 ioc->persist_wait_done = 1;
524 printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
529 * Conditionally tell caller to free the original
530 * EventNotification/EventAck/unexpected request frame!
535 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
537 * mpt_register - Register protocol-specific main callback handler.
538 * @cbfunc: callback function pointer
539 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
541 * This routine is called by a protocol-specific driver (SCSI host,
542 * LAN, SCSI target) to register its reply callback routine. Each
543 * protocol-specific driver must do this before it will be able to
544 * use any IOC resources, such as obtaining request frames.
546 * NOTES: The SCSI protocol driver currently calls this routine thrice
547 * in order to register separate callbacks; one for "normal" SCSI IO;
548 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
550 * Returns a positive integer valued "handle" in the
551 * range (and S.O.D. order) {N,...,7,6,5,...,1} if successful.
552 * Any non-positive return value (including zero!) should be considered
553 * an error by the caller.
556 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
563 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
564 * (slot/handle 0 is reserved!)
566 for (i = MPT_MAX_PROTOCOL_DRIVERS-1; i; i--) {
567 if (MptCallbacks[i] == NULL) {
568 MptCallbacks[i] = cbfunc;
569 MptDriverClass[i] = dclass;
570 MptEvHandlers[i] = NULL;
579 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
581 * mpt_deregister - Deregister a protocol drivers resources.
582 * @cb_idx: previously registered callback handle
584 * Each protocol-specific driver should call this routine when its
585 * module is unloaded.
588 mpt_deregister(int cb_idx)
590 if ((cb_idx >= 0) && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
591 MptCallbacks[cb_idx] = NULL;
592 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
593 MptEvHandlers[cb_idx] = NULL;
599 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
601 * mpt_event_register - Register protocol-specific event callback
603 * @cb_idx: previously registered (via mpt_register) callback handle
604 * @ev_cbfunc: callback function
606 * This routine can be called by one or more protocol-specific drivers
607 * if/when they choose to be notified of MPT events.
609 * Returns 0 for success.
612 mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc)
614 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
617 MptEvHandlers[cb_idx] = ev_cbfunc;
621 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
623 * mpt_event_deregister - Deregister protocol-specific event callback
625 * @cb_idx: previously registered callback handle
627 * Each protocol-specific driver should call this routine
628 * when it does not (or can no longer) handle events,
629 * or when its module is unloaded.
632 mpt_event_deregister(int cb_idx)
634 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
637 MptEvHandlers[cb_idx] = NULL;
640 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
642 * mpt_reset_register - Register protocol-specific IOC reset handler.
643 * @cb_idx: previously registered (via mpt_register) callback handle
644 * @reset_func: reset function
646 * This routine can be called by one or more protocol-specific drivers
647 * if/when they choose to be notified of IOC resets.
649 * Returns 0 for success.
652 mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func)
654 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
657 MptResetHandlers[cb_idx] = reset_func;
661 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
663 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
664 * @cb_idx: previously registered callback handle
666 * Each protocol-specific driver should call this routine
667 * when it does not (or can no longer) handle IOC reset handling,
668 * or when its module is unloaded.
671 mpt_reset_deregister(int cb_idx)
673 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
676 MptResetHandlers[cb_idx] = NULL;
679 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
681 * mpt_device_driver_register - Register device driver hooks
682 * @dd_cbfunc: driver callbacks struct
683 * @cb_idx: MPT protocol driver index
686 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx)
689 const struct pci_device_id *id;
691 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
694 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
696 /* call per pci device probe entry point */
697 list_for_each_entry(ioc, &ioc_list, list) {
698 id = ioc->pcidev->driver ?
699 ioc->pcidev->driver->id_table : NULL;
700 if (dd_cbfunc->probe)
701 dd_cbfunc->probe(ioc->pcidev, id);
707 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
709 * mpt_device_driver_deregister - DeRegister device driver hooks
710 * @cb_idx: MPT protocol driver index
713 mpt_device_driver_deregister(int cb_idx)
715 struct mpt_pci_driver *dd_cbfunc;
718 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
721 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
723 list_for_each_entry(ioc, &ioc_list, list) {
724 if (dd_cbfunc->remove)
725 dd_cbfunc->remove(ioc->pcidev);
728 MptDeviceDriverHandlers[cb_idx] = NULL;
732 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
734 * mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024)
735 * allocated per MPT adapter.
736 * @handle: Handle of registered MPT protocol driver
737 * @ioc: Pointer to MPT adapter structure
739 * Returns pointer to a MPT request frame or %NULL if none are available
740 * or IOC is not active.
743 mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc)
747 u16 req_idx; /* Request index */
749 /* validate handle and ioc identifier */
753 printk(KERN_WARNING "IOC Not Active! mpt_get_msg_frame returning NULL!\n");
756 /* If interrupts are not attached, do not return a request frame */
760 spin_lock_irqsave(&ioc->FreeQlock, flags);
761 if (!list_empty(&ioc->FreeQ)) {
764 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
765 u.frame.linkage.list);
766 list_del(&mf->u.frame.linkage.list);
767 mf->u.frame.linkage.arg1 = 0;
768 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
769 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
771 req_idx = req_offset / ioc->req_sz;
772 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
773 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
774 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame; /* Default, will be changed if necessary in SG generation */
781 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
785 printk(KERN_WARNING "IOC Active. No free Msg Frames! Count 0x%x Max 0x%x\n", ioc->mfcnt, ioc->req_depth);
787 if (mfcounter == PRINT_MF_COUNT)
788 printk(KERN_INFO "MF Count 0x%x Max 0x%x \n", ioc->mfcnt, ioc->req_depth);
791 dmfprintk((KERN_INFO MYNAM ": %s: mpt_get_msg_frame(%d,%d), got mf=%p\n",
792 ioc->name, handle, ioc->id, mf));
796 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
798 * mpt_put_msg_frame - Send a protocol specific MPT request frame
800 * @handle: Handle of registered MPT protocol driver
801 * @ioc: Pointer to MPT adapter structure
802 * @mf: Pointer to MPT request frame
804 * This routine posts a MPT request frame to the request post FIFO of a
805 * specific MPT adapter.
808 mpt_put_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
812 u16 req_idx; /* Request index */
814 /* ensure values are reset properly! */
815 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
816 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
818 req_idx = req_offset / ioc->req_sz;
819 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
820 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
822 #ifdef MPT_DEBUG_MSG_FRAME
824 u32 *m = mf->u.frame.hwhdr.__hdr;
827 printk(KERN_INFO MYNAM ": %s: About to Put msg frame @ %p:\n" KERN_INFO " ",
829 n = ioc->req_sz/4 - 1;
832 for (ii=0; ii<=n; ii++) {
833 if (ii && ((ii%8)==0))
834 printk("\n" KERN_INFO " ");
835 printk(" %08x", le32_to_cpu(m[ii]));
841 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
842 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]));
843 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
846 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
848 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
849 * @handle: Handle of registered MPT protocol driver
850 * @ioc: Pointer to MPT adapter structure
851 * @mf: Pointer to MPT request frame
853 * This routine places a MPT request frame back on the MPT adapter's
857 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
861 /* Put Request back on FreeQ! */
862 spin_lock_irqsave(&ioc->FreeQlock, flags);
863 mf->u.frame.linkage.arg1 = 0xdeadbeaf; /* signature to know if this mf is freed */
864 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
868 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
871 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
873 * mpt_add_sge - Place a simple SGE at address pAddr.
874 * @pAddr: virtual address for SGE
875 * @flagslength: SGE flags and data transfer length
876 * @dma_addr: Physical address
878 * This routine places a MPT request frame back on the MPT adapter's
882 mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
884 if (sizeof(dma_addr_t) == sizeof(u64)) {
885 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
886 u32 tmp = dma_addr & 0xFFFFFFFF;
888 pSge->FlagsLength = cpu_to_le32(flagslength);
889 pSge->Address.Low = cpu_to_le32(tmp);
890 tmp = (u32) ((u64)dma_addr >> 32);
891 pSge->Address.High = cpu_to_le32(tmp);
894 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
895 pSge->FlagsLength = cpu_to_le32(flagslength);
896 pSge->Address = cpu_to_le32(dma_addr);
900 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
902 * mpt_send_handshake_request - Send MPT request via doorbell handshake method.
903 * @handle: Handle of registered MPT protocol driver
904 * @ioc: Pointer to MPT adapter structure
905 * @reqBytes: Size of the request in bytes
906 * @req: Pointer to MPT request frame
907 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
909 * This routine is used exclusively to send MptScsiTaskMgmt
910 * requests since they are required to be sent via doorbell handshake.
912 * NOTE: It is the callers responsibility to byte-swap fields in the
913 * request which are greater than 1 byte in size.
915 * Returns 0 for success, non-zero for failure.
918 mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
924 /* State is known to be good upon entering
925 * this function so issue the bus reset
930 * Emulate what mpt_put_msg_frame() does /wrt to sanity
931 * setting cb_idx/req_idx. But ONLY if this request
932 * is in proper (pre-alloc'd) request buffer range...
934 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
935 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
936 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
937 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
938 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;
941 /* Make sure there are no doorbells */
942 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
944 CHIPREG_WRITE32(&ioc->chip->Doorbell,
945 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
946 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
948 /* Wait for IOC doorbell int */
949 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
953 /* Read doorbell and check for active bit */
954 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
957 dhsprintk((KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
960 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
962 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
966 /* Send request via doorbell handshake */
967 req_as_bytes = (u8 *) req;
968 for (ii = 0; ii < reqBytes/4; ii++) {
971 word = ((req_as_bytes[(ii*4) + 0] << 0) |
972 (req_as_bytes[(ii*4) + 1] << 8) |
973 (req_as_bytes[(ii*4) + 2] << 16) |
974 (req_as_bytes[(ii*4) + 3] << 24));
975 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
976 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
982 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
987 /* Make sure there are no doorbells */
988 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
993 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
995 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
996 * @ioc: Pointer to MPT adapter structure
997 * @access_control_value: define bits below
998 * @sleepFlag: Specifies whether the process can sleep
1000 * Provides mechanism for the host driver to control the IOC's
1001 * Host Page Buffer access.
1003 * Access Control Value - bits[15:12]
1005 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1006 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1007 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1009 * Returns 0 for success, non-zero for failure.
1013 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1017 /* return if in use */
1018 if (CHIPREG_READ32(&ioc->chip->Doorbell)
1019 & MPI_DOORBELL_ACTIVE)
1022 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1024 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1025 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1026 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1027 (access_control_value<<12)));
1029 /* Wait for IOC to clear Doorbell Status bit */
1030 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1036 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1038 * mpt_host_page_alloc - allocate system memory for the fw
1039 * @ioc: Pointer to pointer to IOC adapter
1040 * @ioc_init: Pointer to ioc init config page
1042 * If we already allocated memory in past, then resend the same pointer.
1043 * Returns 0 for success, non-zero for failure.
1046 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1050 u32 host_page_buffer_sz=0;
1052 if(!ioc->HostPageBuffer) {
1054 host_page_buffer_sz =
1055 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1057 if(!host_page_buffer_sz)
1058 return 0; /* fw doesn't need any host buffers */
1060 /* spin till we get enough memory */
1061 while(host_page_buffer_sz > 0) {
1063 if((ioc->HostPageBuffer = pci_alloc_consistent(
1065 host_page_buffer_sz,
1066 &ioc->HostPageBuffer_dma)) != NULL) {
1068 dinitprintk((MYIOC_s_INFO_FMT
1069 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1070 ioc->name, ioc->HostPageBuffer,
1071 (u32)ioc->HostPageBuffer_dma,
1072 host_page_buffer_sz));
1073 ioc->alloc_total += host_page_buffer_sz;
1074 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1078 host_page_buffer_sz -= (4*1024);
1082 if(!ioc->HostPageBuffer) {
1083 printk(MYIOC_s_ERR_FMT
1084 "Failed to alloc memory for host_page_buffer!\n",
1089 psge = (char *)&ioc_init->HostPageBufferSGE;
1090 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1091 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1092 MPI_SGE_FLAGS_32_BIT_ADDRESSING |
1093 MPI_SGE_FLAGS_HOST_TO_IOC |
1094 MPI_SGE_FLAGS_END_OF_BUFFER;
1095 if (sizeof(dma_addr_t) == sizeof(u64)) {
1096 flags_length |= MPI_SGE_FLAGS_64_BIT_ADDRESSING;
1098 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1099 flags_length |= ioc->HostPageBuffer_sz;
1100 mpt_add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1101 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1106 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1108 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1109 * @iocid: IOC unique identifier (integer)
1110 * @iocpp: Pointer to pointer to IOC adapter
1112 * Given a unique IOC identifier, set pointer to the associated MPT
1113 * adapter structure.
1115 * Returns iocid and sets iocpp if iocid is found.
1116 * Returns -1 if iocid is not found.
1119 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1123 list_for_each_entry(ioc,&ioc_list,list) {
1124 if (ioc->id == iocid) {
1134 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1136 * mpt_attach - Install a PCI intelligent MPT adapter.
1137 * @pdev: Pointer to pci_dev structure
1138 * @id: PCI device ID information
1140 * This routine performs all the steps necessary to bring the IOC of
1141 * a MPT adapter to a OPERATIONAL state. This includes registering
1142 * memory regions, registering the interrupt, and allocating request
1143 * and reply memory pools.
1145 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1148 * Returns 0 for success, non-zero for failure.
1150 * TODO: Add support for polled controllers
1153 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1157 unsigned long mem_phys;
1165 static int mpt_ids = 0;
1166 #ifdef CONFIG_PROC_FS
1167 struct proc_dir_entry *dent, *ent;
1170 if (pci_enable_device(pdev))
1173 dinitprintk((KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1175 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
1176 dprintk((KERN_INFO MYNAM
1177 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n"));
1178 } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
1179 printk(KERN_WARNING MYNAM ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");
1183 if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
1184 dprintk((KERN_INFO MYNAM
1185 ": Using 64 bit consistent mask\n"));
1187 dprintk((KERN_INFO MYNAM
1188 ": Not using 64 bit consistent mask\n"));
1190 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1192 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1195 ioc->alloc_total = sizeof(MPT_ADAPTER);
1196 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1197 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1200 ioc->diagPending = 0;
1201 spin_lock_init(&ioc->diagLock);
1202 spin_lock_init(&ioc->initializing_hba_lock);
1204 /* Initialize the event logging.
1206 ioc->eventTypes = 0; /* None */
1207 ioc->eventContext = 0;
1208 ioc->eventLogSize = 0;
1215 ioc->cached_fw = NULL;
1217 /* Initilize SCSI Config Data structure
1219 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1221 /* Initialize the running configQ head.
1223 INIT_LIST_HEAD(&ioc->configQ);
1225 /* Initialize the fc rport list head.
1227 INIT_LIST_HEAD(&ioc->fc_rports);
1229 /* Find lookup slot. */
1230 INIT_LIST_HEAD(&ioc->list);
1231 ioc->id = mpt_ids++;
1233 mem_phys = msize = 0;
1235 for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1236 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1239 /* Get I/O space! */
1240 port = pci_resource_start(pdev, ii);
1241 psize = pci_resource_len(pdev,ii);
1246 mem_phys = pci_resource_start(pdev, ii);
1247 msize = pci_resource_len(pdev,ii);
1250 ioc->mem_size = msize;
1253 /* Get logical ptr for PciMem0 space */
1254 /*mem = ioremap(mem_phys, msize);*/
1255 mem = ioremap(mem_phys, msize);
1257 printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n");
1262 dinitprintk((KERN_INFO MYNAM ": mem = %p, mem_phys = %lx\n", mem, mem_phys));
1264 dinitprintk((KERN_INFO MYNAM ": facts @ %p, pfacts[0] @ %p\n",
1265 &ioc->facts, &ioc->pfacts[0]));
1267 ioc->mem_phys = mem_phys;
1268 ioc->chip = (SYSIF_REGS __iomem *)mem;
1270 /* Save Port IO values in case we need to do downloadboot */
1272 u8 *pmem = (u8*)port;
1273 ioc->pio_mem_phys = port;
1274 ioc->pio_chip = (SYSIF_REGS __iomem *)pmem;
1277 if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC909) {
1278 ioc->prod_name = "LSIFC909";
1281 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929) {
1282 ioc->prod_name = "LSIFC929";
1285 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919) {
1286 ioc->prod_name = "LSIFC919";
1289 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929X) {
1290 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1292 if (revision < XL_929) {
1293 ioc->prod_name = "LSIFC929X";
1294 /* 929X Chip Fix. Set Split transactions level
1295 * for PCIX. Set MOST bits to zero.
1297 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1299 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1301 ioc->prod_name = "LSIFC929XL";
1302 /* 929XL Chip Fix. Set MMRBC to 0x08.
1304 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1306 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1309 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919X) {
1310 ioc->prod_name = "LSIFC919X";
1312 /* 919X Chip Fix. Set Split transactions level
1313 * for PCIX. Set MOST bits to zero.
1315 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1317 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1319 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC939X) {
1320 ioc->prod_name = "LSIFC939X";
1322 ioc->errata_flag_1064 = 1;
1324 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC949X) {
1325 ioc->prod_name = "LSIFC949X";
1327 ioc->errata_flag_1064 = 1;
1329 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC949E) {
1330 ioc->prod_name = "LSIFC949E";
1333 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {
1334 ioc->prod_name = "LSI53C1030";
1335 ioc->bus_type = SPI;
1336 /* 1030 Chip Fix. Disable Split transactions
1337 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1339 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1340 if (revision < C0_1030) {
1341 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1343 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1346 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_1030_53C1035) {
1347 ioc->prod_name = "LSI53C1035";
1348 ioc->bus_type = SPI;
1350 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064) {
1351 ioc->prod_name = "LSISAS1064";
1352 ioc->bus_type = SAS;
1353 ioc->errata_flag_1064 = 1;
1355 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068) {
1356 ioc->prod_name = "LSISAS1068";
1357 ioc->bus_type = SAS;
1358 ioc->errata_flag_1064 = 1;
1360 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064E) {
1361 ioc->prod_name = "LSISAS1064E";
1362 ioc->bus_type = SAS;
1364 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068E) {
1365 ioc->prod_name = "LSISAS1068E";
1366 ioc->bus_type = SAS;
1368 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
1369 ioc->prod_name = "LSISAS1078";
1370 ioc->bus_type = SAS;
1373 if (ioc->errata_flag_1064)
1374 pci_disable_io_access(pdev);
1376 sprintf(ioc->name, "ioc%d", ioc->id);
1378 spin_lock_init(&ioc->FreeQlock);
1381 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1383 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1385 /* Set lookup ptr. */
1386 list_add_tail(&ioc->list, &ioc_list);
1388 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1390 mpt_detect_bound_ports(ioc, pdev);
1392 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1394 printk(KERN_WARNING MYNAM
1395 ": WARNING - %s did not initialize properly! (%d)\n",
1398 list_del(&ioc->list);
1400 ioc->alt_ioc->alt_ioc = NULL;
1403 pci_set_drvdata(pdev, NULL);
1407 /* call per device driver probe entry point */
1408 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1409 if(MptDeviceDriverHandlers[ii] &&
1410 MptDeviceDriverHandlers[ii]->probe) {
1411 MptDeviceDriverHandlers[ii]->probe(pdev,id);
1415 #ifdef CONFIG_PROC_FS
1417 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1419 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1421 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1423 ent->read_proc = procmpt_iocinfo_read;
1426 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1428 ent->read_proc = procmpt_summary_read;
1437 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1439 * mpt_detach - Remove a PCI intelligent MPT adapter.
1440 * @pdev: Pointer to pci_dev structure
1444 mpt_detach(struct pci_dev *pdev)
1446 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1450 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
1451 remove_proc_entry(pname, NULL);
1452 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
1453 remove_proc_entry(pname, NULL);
1454 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
1455 remove_proc_entry(pname, NULL);
1457 /* call per device driver remove entry point */
1458 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1459 if(MptDeviceDriverHandlers[ii] &&
1460 MptDeviceDriverHandlers[ii]->remove) {
1461 MptDeviceDriverHandlers[ii]->remove(pdev);
1465 /* Disable interrupts! */
1466 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1469 synchronize_irq(pdev->irq);
1471 /* Clear any lingering interrupt */
1472 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1474 CHIPREG_READ32(&ioc->chip->IntStatus);
1476 mpt_adapter_dispose(ioc);
1478 pci_set_drvdata(pdev, NULL);
1481 /**************************************************************************
1485 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1487 * mpt_suspend - Fusion MPT base driver suspend routine.
1488 * @pdev: Pointer to pci_dev structure
1489 * @state: new state to enter
1492 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
1495 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1497 device_state=pci_choose_state(pdev, state);
1499 printk(MYIOC_s_INFO_FMT
1500 "pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
1501 ioc->name, pdev, pci_name(pdev), device_state);
1503 pci_save_state(pdev);
1505 /* put ioc into READY_STATE */
1506 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
1507 printk(MYIOC_s_ERR_FMT
1508 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
1511 /* disable interrupts */
1512 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1515 /* Clear any lingering interrupt */
1516 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1518 pci_disable_device(pdev);
1519 pci_set_power_state(pdev, device_state);
1524 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1526 * mpt_resume - Fusion MPT base driver resume routine.
1527 * @pdev: Pointer to pci_dev structure
1530 mpt_resume(struct pci_dev *pdev)
1532 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1533 u32 device_state = pdev->current_state;
1537 printk(MYIOC_s_INFO_FMT
1538 "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
1539 ioc->name, pdev, pci_name(pdev), device_state);
1541 pci_set_power_state(pdev, 0);
1542 pci_restore_state(pdev);
1543 err = pci_enable_device(pdev);
1547 /* enable interrupts */
1548 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
1551 printk(MYIOC_s_INFO_FMT
1552 "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1554 (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1555 CHIPREG_READ32(&ioc->chip->Doorbell));
1557 /* bring ioc to operational state */
1558 if ((recovery_state = mpt_do_ioc_recovery(ioc,
1559 MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {
1560 printk(MYIOC_s_INFO_FMT
1561 "pci-resume: Cannot recover, error:[%x]\n",
1562 ioc->name, recovery_state);
1564 printk(MYIOC_s_INFO_FMT
1565 "pci-resume: success\n", ioc->name);
1573 mpt_signal_reset(int index, MPT_ADAPTER *ioc, int reset_phase)
1575 if ((MptDriverClass[index] == MPTSPI_DRIVER &&
1576 ioc->bus_type != SPI) ||
1577 (MptDriverClass[index] == MPTFC_DRIVER &&
1578 ioc->bus_type != FC) ||
1579 (MptDriverClass[index] == MPTSAS_DRIVER &&
1580 ioc->bus_type != SAS))
1581 /* make sure we only call the relevant reset handler
1584 return (MptResetHandlers[index])(ioc, reset_phase);
1587 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1589 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1590 * @ioc: Pointer to MPT adapter structure
1591 * @reason: Event word / reason
1592 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1594 * This routine performs all the steps necessary to bring the IOC
1595 * to a OPERATIONAL state.
1597 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1602 * -1 if failed to get board READY
1603 * -2 if READY but IOCFacts Failed
1604 * -3 if READY but PrimeIOCFifos Failed
1605 * -4 if READY but IOCInit Failed
1608 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1610 int hard_reset_done = 0;
1611 int alt_ioc_ready = 0;
1617 int reset_alt_ioc_active = 0;
1618 int irq_allocated = 0;
1620 printk(KERN_INFO MYNAM ": Initiating %s %s\n",
1621 ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
1623 /* Disable reply interrupts (also blocks FreeQ) */
1624 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1628 if (ioc->alt_ioc->active)
1629 reset_alt_ioc_active = 1;
1631 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1632 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
1633 ioc->alt_ioc->active = 0;
1637 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
1640 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
1641 if (hard_reset_done == -4) {
1642 printk(KERN_WARNING MYNAM ": %s Owned by PEER..skipping!\n",
1645 if (reset_alt_ioc_active && ioc->alt_ioc) {
1646 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1647 dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1648 ioc->alt_ioc->name));
1649 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
1650 ioc->alt_ioc->active = 1;
1654 printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",
1660 /* hard_reset_done = 0 if a soft reset was performed
1661 * and 1 if a hard reset was performed.
1663 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
1664 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
1667 printk(KERN_WARNING MYNAM
1668 ": alt-%s: Not ready WARNING!\n",
1669 ioc->alt_ioc->name);
1672 for (ii=0; ii<5; ii++) {
1673 /* Get IOC facts! Allow 5 retries */
1674 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
1680 dinitprintk((MYIOC_s_INFO_FMT "Retry IocFacts failed rc=%x\n", ioc->name, rc));
1682 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1683 MptDisplayIocCapabilities(ioc);
1686 if (alt_ioc_ready) {
1687 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
1688 dinitprintk((MYIOC_s_INFO_FMT "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
1689 /* Retry - alt IOC was initialized once
1691 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
1694 dinitprintk((MYIOC_s_INFO_FMT "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
1696 reset_alt_ioc_active = 0;
1697 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1698 MptDisplayIocCapabilities(ioc->alt_ioc);
1703 * Device is reset now. It must have de-asserted the interrupt line
1704 * (if it was asserted) and it should be safe to register for the
1707 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1709 if (ioc->pcidev->irq) {
1710 if (mpt_msi_enable && !pci_enable_msi(ioc->pcidev))
1711 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
1713 rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
1714 IRQF_SHARED, ioc->name, ioc);
1716 printk(MYIOC_s_ERR_FMT "Unable to allocate "
1717 "interrupt %d!\n", ioc->name,
1720 pci_disable_msi(ioc->pcidev);
1724 ioc->pci_irq = ioc->pcidev->irq;
1725 pci_set_master(ioc->pcidev); /* ?? */
1726 pci_set_drvdata(ioc->pcidev, ioc);
1727 dprintk((KERN_INFO MYNAM ": %s installed at interrupt "
1728 "%d\n", ioc->name, ioc->pcidev->irq));
1732 /* Prime reply & request queues!
1733 * (mucho alloc's) Must be done prior to
1734 * init as upper addresses are needed for init.
1735 * If fails, continue with alt-ioc processing
1737 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
1740 /* May need to check/upload firmware & data here!
1741 * If fails, continue with alt-ioc processing
1743 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
1746 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
1747 printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
1748 ioc->alt_ioc->name, rc);
1750 reset_alt_ioc_active = 0;
1753 if (alt_ioc_ready) {
1754 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
1756 reset_alt_ioc_active = 0;
1757 printk(KERN_WARNING MYNAM
1758 ": alt-%s: (%d) init failure WARNING!\n",
1759 ioc->alt_ioc->name, rc);
1763 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
1764 if (ioc->upload_fw) {
1765 ddlprintk((MYIOC_s_INFO_FMT
1766 "firmware upload required!\n", ioc->name));
1768 /* Controller is not operational, cannot do upload
1771 rc = mpt_do_upload(ioc, sleepFlag);
1773 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
1775 * Maintain only one pointer to FW memory
1776 * so there will not be two attempt to
1777 * downloadboot onboard dual function
1778 * chips (mpt_adapter_disable,
1781 ddlprintk((MYIOC_s_INFO_FMT ": mpt_upload: alt_%s has cached_fw=%p \n",
1782 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
1783 ioc->alt_ioc->cached_fw = NULL;
1786 printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
1794 /* Enable! (reply interrupt) */
1795 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
1799 if (reset_alt_ioc_active && ioc->alt_ioc) {
1800 /* (re)Enable alt-IOC! (reply interrupt) */
1801 dinitprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1802 ioc->alt_ioc->name));
1803 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
1804 ioc->alt_ioc->active = 1;
1807 /* Enable MPT base driver management of EventNotification
1808 * and EventAck handling.
1810 if ((ret == 0) && (!ioc->facts.EventState))
1811 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
1813 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
1814 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
1816 /* Add additional "reason" check before call to GetLanConfigPages
1817 * (combined with GetIoUnitPage2 call). This prevents a somewhat
1818 * recursive scenario; GetLanConfigPages times out, timer expired
1819 * routine calls HardResetHandler, which calls into here again,
1820 * and we try GetLanConfigPages again...
1822 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1825 * Initalize link list for inactive raid volumes.
1827 init_MUTEX(&ioc->raid_data.inactive_list_mutex);
1828 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
1830 if (ioc->bus_type == SAS) {
1832 /* clear persistency table */
1833 if(ioc->facts.IOCExceptions &
1834 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
1835 ret = mptbase_sas_persist_operation(ioc,
1836 MPI_SAS_OP_CLEAR_NOT_PRESENT);
1843 mpt_findImVolumes(ioc);
1845 } else if (ioc->bus_type == FC) {
1846 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
1847 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
1849 * Pre-fetch the ports LAN MAC address!
1850 * (LANPage1_t stuff)
1852 (void) GetLanConfigPages(ioc);
1855 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
1856 dprintk((MYIOC_s_INFO_FMT "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
1857 ioc->name, a[5], a[4], a[3], a[2], a[1], a[0] ));
1862 /* Get NVRAM and adapter maximums from SPP 0 and 2
1864 mpt_GetScsiPortSettings(ioc, 0);
1866 /* Get version and length of SDP 1
1868 mpt_readScsiDevicePageHeaders(ioc, 0);
1872 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
1873 mpt_findImVolumes(ioc);
1875 /* Check, and possibly reset, the coalescing value
1877 mpt_read_ioc_pg_1(ioc);
1879 mpt_read_ioc_pg_4(ioc);
1882 GetIoUnitPage2(ioc);
1886 * Call each currently registered protocol IOC reset handler
1887 * with post-reset indication.
1888 * NOTE: If we're doing _IOC_BRINGUP, there can be no
1889 * MptResetHandlers[] registered yet.
1891 if (hard_reset_done) {
1893 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
1894 if ((ret == 0) && MptResetHandlers[ii]) {
1895 dprintk((MYIOC_s_INFO_FMT "Calling IOC post_reset handler #%d\n",
1897 rc += mpt_signal_reset(ii, ioc, MPT_IOC_POST_RESET);
1901 if (alt_ioc_ready && MptResetHandlers[ii]) {
1902 drsprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",
1903 ioc->name, ioc->alt_ioc->name, ii));
1904 rc += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_POST_RESET);
1908 /* FIXME? Examine results here? */
1912 if ((ret != 0) && irq_allocated) {
1913 free_irq(ioc->pci_irq, ioc);
1915 pci_disable_msi(ioc->pcidev);
1920 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1922 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
1923 * @ioc: Pointer to MPT adapter structure
1924 * @pdev: Pointer to (struct pci_dev) structure
1926 * Search for PCI bus/dev_function which matches
1927 * PCI bus/dev_function (+/-1) for newly discovered 929,
1928 * 929X, 1030 or 1035.
1930 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
1931 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
1934 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
1936 struct pci_dev *peer=NULL;
1937 unsigned int slot = PCI_SLOT(pdev->devfn);
1938 unsigned int func = PCI_FUNC(pdev->devfn);
1939 MPT_ADAPTER *ioc_srch;
1941 dprintk((MYIOC_s_INFO_FMT "PCI device %s devfn=%x/%x,"
1942 " searching for devfn match on %x or %x\n",
1943 ioc->name, pci_name(pdev), pdev->bus->number,
1944 pdev->devfn, func-1, func+1));
1946 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
1948 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
1953 list_for_each_entry(ioc_srch, &ioc_list, list) {
1954 struct pci_dev *_pcidev = ioc_srch->pcidev;
1955 if (_pcidev == peer) {
1956 /* Paranoia checks */
1957 if (ioc->alt_ioc != NULL) {
1958 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1959 ioc->name, ioc->alt_ioc->name);
1961 } else if (ioc_srch->alt_ioc != NULL) {
1962 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1963 ioc_srch->name, ioc_srch->alt_ioc->name);
1966 dprintk((KERN_INFO MYNAM ": FOUND! binding %s <==> %s\n",
1967 ioc->name, ioc_srch->name));
1968 ioc_srch->alt_ioc = ioc;
1969 ioc->alt_ioc = ioc_srch;
1975 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1977 * mpt_adapter_disable - Disable misbehaving MPT adapter.
1978 * @ioc: Pointer to MPT adapter structure
1981 mpt_adapter_disable(MPT_ADAPTER *ioc)
1986 if (ioc->cached_fw != NULL) {
1987 ddlprintk((KERN_INFO MYNAM ": mpt_adapter_disable: Pushing FW onto adapter\n"));
1988 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)ioc->cached_fw, NO_SLEEP)) < 0) {
1989 printk(KERN_WARNING MYNAM
1990 ": firmware downloadboot failure (%d)!\n", ret);
1994 /* Disable adapter interrupts! */
1995 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1997 /* Clear any lingering interrupt */
1998 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2000 if (ioc->alloc != NULL) {
2002 dexitprintk((KERN_INFO MYNAM ": %s.free @ %p, sz=%d bytes\n",
2003 ioc->name, ioc->alloc, ioc->alloc_sz));
2004 pci_free_consistent(ioc->pcidev, sz,
2005 ioc->alloc, ioc->alloc_dma);
2006 ioc->reply_frames = NULL;
2007 ioc->req_frames = NULL;
2009 ioc->alloc_total -= sz;
2012 if (ioc->sense_buf_pool != NULL) {
2013 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2014 pci_free_consistent(ioc->pcidev, sz,
2015 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2016 ioc->sense_buf_pool = NULL;
2017 ioc->alloc_total -= sz;
2020 if (ioc->events != NULL){
2021 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2024 ioc->alloc_total -= sz;
2027 if (ioc->cached_fw != NULL) {
2028 sz = ioc->facts.FWImageSize;
2029 pci_free_consistent(ioc->pcidev, sz,
2030 ioc->cached_fw, ioc->cached_fw_dma);
2031 ioc->cached_fw = NULL;
2032 ioc->alloc_total -= sz;
2035 kfree(ioc->spi_data.nvram);
2036 mpt_inactive_raid_list_free(ioc);
2037 kfree(ioc->raid_data.pIocPg2);
2038 kfree(ioc->raid_data.pIocPg3);
2039 ioc->spi_data.nvram = NULL;
2040 ioc->raid_data.pIocPg3 = NULL;
2042 if (ioc->spi_data.pIocPg4 != NULL) {
2043 sz = ioc->spi_data.IocPg4Sz;
2044 pci_free_consistent(ioc->pcidev, sz,
2045 ioc->spi_data.pIocPg4,
2046 ioc->spi_data.IocPg4_dma);
2047 ioc->spi_data.pIocPg4 = NULL;
2048 ioc->alloc_total -= sz;
2051 if (ioc->ReqToChain != NULL) {
2052 kfree(ioc->ReqToChain);
2053 kfree(ioc->RequestNB);
2054 ioc->ReqToChain = NULL;
2057 kfree(ioc->ChainToChain);
2058 ioc->ChainToChain = NULL;
2060 if (ioc->HostPageBuffer != NULL) {
2061 if((ret = mpt_host_page_access_control(ioc,
2062 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2063 printk(KERN_ERR MYNAM
2064 ": %s: host page buffers free failed (%d)!\n",
2067 dexitprintk((KERN_INFO MYNAM ": %s HostPageBuffer free @ %p, sz=%d bytes\n",
2068 ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
2069 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2070 ioc->HostPageBuffer,
2071 ioc->HostPageBuffer_dma);
2072 ioc->HostPageBuffer = NULL;
2073 ioc->HostPageBuffer_sz = 0;
2074 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2078 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2080 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2081 * @ioc: Pointer to MPT adapter structure
2083 * This routine unregisters h/w resources and frees all alloc'd memory
2084 * associated with a MPT adapter structure.
2087 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2089 int sz_first, sz_last;
2094 sz_first = ioc->alloc_total;
2096 mpt_adapter_disable(ioc);
2098 if (ioc->pci_irq != -1) {
2099 free_irq(ioc->pci_irq, ioc);
2101 pci_disable_msi(ioc->pcidev);
2105 if (ioc->memmap != NULL) {
2106 iounmap(ioc->memmap);
2110 #if defined(CONFIG_MTRR) && 0
2111 if (ioc->mtrr_reg > 0) {
2112 mtrr_del(ioc->mtrr_reg, 0, 0);
2113 dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name));
2117 /* Zap the adapter lookup ptr! */
2118 list_del(&ioc->list);
2120 sz_last = ioc->alloc_total;
2121 dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
2122 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2125 ioc->alt_ioc->alt_ioc = NULL;
2130 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2132 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2133 * @ioc: Pointer to MPT adapter structure
2136 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2140 printk(KERN_INFO "%s: ", ioc->name);
2141 if (ioc->prod_name && strlen(ioc->prod_name) > 3)
2142 printk("%s: ", ioc->prod_name+3);
2143 printk("Capabilities={");
2145 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2146 printk("Initiator");
2150 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2151 printk("%sTarget", i ? "," : "");
2155 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2156 printk("%sLAN", i ? "," : "");
2162 * This would probably evoke more questions than it's worth
2164 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2165 printk("%sLogBusAddr", i ? "," : "");
2173 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2175 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2176 * @ioc: Pointer to MPT_ADAPTER structure
2177 * @force: Force hard KickStart of IOC
2178 * @sleepFlag: Specifies whether the process can sleep
2181 * 1 - DIAG reset and READY
2182 * 0 - READY initially OR soft reset and READY
2183 * -1 - Any failure on KickStart
2184 * -2 - Msg Unit Reset Failed
2185 * -3 - IO Unit Reset Failed
2186 * -4 - IOC owned by a PEER
2189 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2194 int hard_reset_done = 0;
2199 /* Get current [raw] IOC state */
2200 ioc_state = mpt_GetIocState(ioc, 0);
2201 dhsprintk((KERN_INFO MYNAM "::MakeIocReady, %s [raw] state=%08x\n", ioc->name, ioc_state));
2204 * Check to see if IOC got left/stuck in doorbell handshake
2205 * grip of death. If so, hard reset the IOC.
2207 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2209 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2213 /* Is it already READY? */
2214 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
2218 * Check to see if IOC is in FAULT state.
2220 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2222 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2224 printk(KERN_WARNING " FAULT code = %04xh\n",
2225 ioc_state & MPI_DOORBELL_DATA_MASK);
2229 * Hmmm... Did it get left operational?
2231 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2232 dinitprintk((MYIOC_s_INFO_FMT "IOC operational unexpected\n",
2236 * If PCI Peer, exit.
2237 * Else, if no fault conditions are present, issue a MessageUnitReset
2238 * Else, fall through to KickStart case
2240 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2241 dinitprintk((KERN_INFO MYNAM
2242 ": whoinit 0x%x statefault %d force %d\n",
2243 whoinit, statefault, force));
2244 if (whoinit == MPI_WHOINIT_PCI_PEER)
2247 if ((statefault == 0 ) && (force == 0)) {
2248 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2255 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2256 if (hard_reset_done < 0)
2260 * Loop here waiting for IOC to come READY.
2263 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2265 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2266 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2268 * BIOS or previous driver load left IOC in OP state.
2269 * Reset messaging FIFOs.
2271 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2272 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2275 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2277 * Something is wrong. Try to get IOC back
2280 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2281 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2288 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2289 ioc->name, (int)((ii+5)/HZ));
2293 if (sleepFlag == CAN_SLEEP) {
2296 mdelay (1); /* 1 msec delay */
2301 if (statefault < 3) {
2302 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2304 statefault==1 ? "stuck handshake" : "IOC FAULT");
2307 return hard_reset_done;
2310 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2312 * mpt_GetIocState - Get the current state of a MPT adapter.
2313 * @ioc: Pointer to MPT_ADAPTER structure
2314 * @cooked: Request raw or cooked IOC state
2316 * Returns all IOC Doorbell register bits if cooked==0, else just the
2317 * Doorbell bits in MPI_IOC_STATE_MASK.
2320 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2325 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2326 // dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
2327 sc = s & MPI_IOC_STATE_MASK;
2330 ioc->last_state = sc;
2332 return cooked ? sc : s;
2335 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2337 * GetIocFacts - Send IOCFacts request to MPT adapter.
2338 * @ioc: Pointer to MPT_ADAPTER structure
2339 * @sleepFlag: Specifies whether the process can sleep
2340 * @reason: If recovery, only update facts.
2342 * Returns 0 for success, non-zero for failure.
2345 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2347 IOCFacts_t get_facts;
2348 IOCFactsReply_t *facts;
2356 /* IOC *must* NOT be in RESET state! */
2357 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2358 printk(KERN_ERR MYNAM ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
2364 facts = &ioc->facts;
2366 /* Destination (reply area)... */
2367 reply_sz = sizeof(*facts);
2368 memset(facts, 0, reply_sz);
2370 /* Request area (get_facts on the stack right now!) */
2371 req_sz = sizeof(get_facts);
2372 memset(&get_facts, 0, req_sz);
2374 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2375 /* Assert: All other get_facts fields are zero! */
2377 dinitprintk((MYIOC_s_INFO_FMT
2378 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2379 ioc->name, req_sz, reply_sz));
2381 /* No non-zero fields in the get_facts request are greater than
2382 * 1 byte in size, so we can just fire it off as is.
2384 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2385 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2390 * Now byte swap (GRRR) the necessary fields before any further
2391 * inspection of reply contents.
2393 * But need to do some sanity checks on MsgLength (byte) field
2394 * to make sure we don't zero IOC's req_sz!
2396 /* Did we get a valid reply? */
2397 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2398 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2400 * If not been here, done that, save off first WhoInit value
2402 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2403 ioc->FirstWhoInit = facts->WhoInit;
2406 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2407 facts->MsgContext = le32_to_cpu(facts->MsgContext);
2408 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2409 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2410 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2411 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
2412 /* CHECKME! IOCStatus, IOCLogInfo */
2414 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2415 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2418 * FC f/w version changed between 1.1 and 1.2
2419 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2420 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2422 if (facts->MsgVersion < 0x0102) {
2424 * Handle old FC f/w style, convert to new...
2426 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2427 facts->FWVersion.Word =
2428 ((oldv<<12) & 0xFF000000) |
2429 ((oldv<<8) & 0x000FFF00);
2431 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2433 facts->ProductID = le16_to_cpu(facts->ProductID);
2434 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
2435 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
2436 ioc->ir_firmware = 1;
2437 facts->CurrentHostMfaHighAddr =
2438 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2439 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2440 facts->CurrentSenseBufferHighAddr =
2441 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2442 facts->CurReplyFrameSize =
2443 le16_to_cpu(facts->CurReplyFrameSize);
2444 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
2447 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2448 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2449 * to 14 in MPI-1.01.0x.
2451 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2452 facts->MsgVersion > 0x0100) {
2453 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2456 sz = facts->FWImageSize;
2461 facts->FWImageSize = sz;
2463 if (!facts->RequestFrameSize) {
2464 /* Something is wrong! */
2465 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2470 r = sz = facts->BlockSize;
2471 vv = ((63 / (sz * 4)) + 1) & 0x03;
2472 ioc->NB_for_64_byte_frame = vv;
2478 ioc->NBShiftFactor = shiftFactor;
2479 dinitprintk((MYIOC_s_INFO_FMT "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2480 ioc->name, vv, shiftFactor, r));
2482 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2484 * Set values for this IOC's request & reply frame sizes,
2485 * and request & reply queue depths...
2487 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2488 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2489 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2490 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2492 dinitprintk((MYIOC_s_INFO_FMT "reply_sz=%3d, reply_depth=%4d\n",
2493 ioc->name, ioc->reply_sz, ioc->reply_depth));
2494 dinitprintk((MYIOC_s_INFO_FMT "req_sz =%3d, req_depth =%4d\n",
2495 ioc->name, ioc->req_sz, ioc->req_depth));
2497 /* Get port facts! */
2498 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2502 printk(MYIOC_s_ERR_FMT
2503 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2504 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2505 RequestFrameSize)/sizeof(u32)));
2512 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2514 * GetPortFacts - Send PortFacts request to MPT adapter.
2515 * @ioc: Pointer to MPT_ADAPTER structure
2516 * @portnum: Port number
2517 * @sleepFlag: Specifies whether the process can sleep
2519 * Returns 0 for success, non-zero for failure.
2522 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2524 PortFacts_t get_pfacts;
2525 PortFactsReply_t *pfacts;
2531 /* IOC *must* NOT be in RESET state! */
2532 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2533 printk(KERN_ERR MYNAM ": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n",
2539 pfacts = &ioc->pfacts[portnum];
2541 /* Destination (reply area)... */
2542 reply_sz = sizeof(*pfacts);
2543 memset(pfacts, 0, reply_sz);
2545 /* Request area (get_pfacts on the stack right now!) */
2546 req_sz = sizeof(get_pfacts);
2547 memset(&get_pfacts, 0, req_sz);
2549 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2550 get_pfacts.PortNumber = portnum;
2551 /* Assert: All other get_pfacts fields are zero! */
2553 dinitprintk((MYIOC_s_INFO_FMT "Sending get PortFacts(%d) request\n",
2554 ioc->name, portnum));
2556 /* No non-zero fields in the get_pfacts request are greater than
2557 * 1 byte in size, so we can just fire it off as is.
2559 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2560 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2564 /* Did we get a valid reply? */
2566 /* Now byte swap the necessary fields in the response. */
2567 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2568 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2569 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2570 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2571 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2572 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2573 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2574 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2575 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2577 max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
2579 ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
2580 ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
2583 * Place all the devices on channels
2587 if (mpt_channel_mapping) {
2588 ioc->devices_per_bus = 1;
2589 ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
2595 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2597 * SendIocInit - Send IOCInit request to MPT adapter.
2598 * @ioc: Pointer to MPT_ADAPTER structure
2599 * @sleepFlag: Specifies whether the process can sleep
2601 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2603 * Returns 0 for success, non-zero for failure.
2606 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2609 MPIDefaultReply_t init_reply;
2615 memset(&ioc_init, 0, sizeof(ioc_init));
2616 memset(&init_reply, 0, sizeof(init_reply));
2618 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2619 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2621 /* If we are in a recovery mode and we uploaded the FW image,
2622 * then this pointer is not NULL. Skip the upload a second time.
2623 * Set this flag if cached_fw set for either IOC.
2625 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
2629 ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n",
2630 ioc->name, ioc->upload_fw, ioc->facts.Flags));
2632 ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
2633 ioc_init.MaxBuses = (U8)ioc->number_of_buses;
2634 dinitprintk((MYIOC_s_INFO_FMT "facts.MsgVersion=%x\n",
2635 ioc->name, ioc->facts.MsgVersion));
2636 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
2637 // set MsgVersion and HeaderVersion host driver was built with
2638 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
2639 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
2641 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
2642 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
2643 } else if(mpt_host_page_alloc(ioc, &ioc_init))
2646 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
2648 if (sizeof(dma_addr_t) == sizeof(u64)) {
2649 /* Save the upper 32-bits of the request
2650 * (reply) and sense buffers.
2652 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
2653 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2655 /* Force 32-bit addressing */
2656 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
2657 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
2660 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
2661 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
2662 ioc->facts.MaxDevices = ioc_init.MaxDevices;
2663 ioc->facts.MaxBuses = ioc_init.MaxBuses;
2665 dhsprintk((MYIOC_s_INFO_FMT "Sending IOCInit (req @ %p)\n",
2666 ioc->name, &ioc_init));
2668 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
2669 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
2671 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
2675 /* No need to byte swap the multibyte fields in the reply
2676 * since we don't even look at its contents.
2679 dhsprintk((MYIOC_s_INFO_FMT "Sending PortEnable (req @ %p)\n",
2680 ioc->name, &ioc_init));
2682 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
2683 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
2687 /* YIKES! SUPER IMPORTANT!!!
2688 * Poll IocState until _OPERATIONAL while IOC is doing
2689 * LoopInit and TargetDiscovery!
2692 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
2693 state = mpt_GetIocState(ioc, 1);
2694 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
2695 if (sleepFlag == CAN_SLEEP) {
2702 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
2703 ioc->name, (int)((count+5)/HZ));
2707 state = mpt_GetIocState(ioc, 1);
2710 dinitprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
2713 ioc->aen_event_read_flag=0;
2717 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2719 * SendPortEnable - Send PortEnable request to MPT adapter port.
2720 * @ioc: Pointer to MPT_ADAPTER structure
2721 * @portnum: Port number to enable
2722 * @sleepFlag: Specifies whether the process can sleep
2724 * Send PortEnable to bring IOC to OPERATIONAL state.
2726 * Returns 0 for success, non-zero for failure.
2729 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2731 PortEnable_t port_enable;
2732 MPIDefaultReply_t reply_buf;
2737 /* Destination... */
2738 reply_sz = sizeof(MPIDefaultReply_t);
2739 memset(&reply_buf, 0, reply_sz);
2741 req_sz = sizeof(PortEnable_t);
2742 memset(&port_enable, 0, req_sz);
2744 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
2745 port_enable.PortNumber = portnum;
2746 /* port_enable.ChainOffset = 0; */
2747 /* port_enable.MsgFlags = 0; */
2748 /* port_enable.MsgContext = 0; */
2750 dinitprintk((MYIOC_s_INFO_FMT "Sending Port(%d)Enable (req @ %p)\n",
2751 ioc->name, portnum, &port_enable));
2753 /* RAID FW may take a long time to enable
2755 if (ioc->ir_firmware || ioc->bus_type == SAS) {
2756 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
2757 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
2758 300 /*seconds*/, sleepFlag);
2760 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
2761 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
2762 30 /*seconds*/, sleepFlag);
2768 * mpt_alloc_fw_memory - allocate firmware memory
2769 * @ioc: Pointer to MPT_ADAPTER structure
2770 * @size: total FW bytes
2772 * If memory has already been allocated, the same (cached) value
2776 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
2779 return; /* use already allocated memory */
2780 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2781 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
2782 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
2783 ioc->alloc_total += size;
2784 ioc->alt_ioc->alloc_total -= size;
2786 if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
2787 ioc->alloc_total += size;
2791 * mpt_free_fw_memory - free firmware memory
2792 * @ioc: Pointer to MPT_ADAPTER structure
2794 * If alt_img is NULL, delete from ioc structure.
2795 * Else, delete a secondary image in same format.
2798 mpt_free_fw_memory(MPT_ADAPTER *ioc)
2802 sz = ioc->facts.FWImageSize;
2803 dinitprintk((KERN_INFO MYNAM "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
2804 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2805 pci_free_consistent(ioc->pcidev, sz,
2806 ioc->cached_fw, ioc->cached_fw_dma);
2807 ioc->cached_fw = NULL;
2813 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2815 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
2816 * @ioc: Pointer to MPT_ADAPTER structure
2817 * @sleepFlag: Specifies whether the process can sleep
2819 * Returns 0 for success, >0 for handshake failure
2820 * <0 for fw upload failure.
2822 * Remark: If bound IOC and a successful FWUpload was performed
2823 * on the bound IOC, the second image is discarded
2824 * and memory is free'd. Both channels must upload to prevent
2825 * IOC from running in degraded mode.
2828 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
2830 u8 request[ioc->req_sz];
2831 u8 reply[sizeof(FWUploadReply_t)];
2832 FWUpload_t *prequest;
2833 FWUploadReply_t *preply;
2834 FWUploadTCSGE_t *ptcsge;
2837 int ii, sz, reply_sz;
2840 /* If the image size is 0, we are done.
2842 if ((sz = ioc->facts.FWImageSize) == 0)
2845 mpt_alloc_fw_memory(ioc, sz);
2847 dinitprintk((KERN_INFO MYNAM ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
2848 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2850 if (ioc->cached_fw == NULL) {
2856 prequest = (FWUpload_t *)&request;
2857 preply = (FWUploadReply_t *)&reply;
2859 /* Destination... */
2860 memset(prequest, 0, ioc->req_sz);
2862 reply_sz = sizeof(reply);
2863 memset(preply, 0, reply_sz);
2865 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
2866 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
2868 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
2869 ptcsge->DetailsLength = 12;
2870 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
2871 ptcsge->ImageSize = cpu_to_le32(sz);
2873 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
2875 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
2876 mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma);
2878 sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
2879 dinitprintk((KERN_INFO MYNAM ": Sending FW Upload (req @ %p) sgeoffset=%d \n",
2880 prequest, sgeoffset));
2881 DBG_DUMP_FW_REQUEST_FRAME(prequest)
2883 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
2884 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
2886 dinitprintk((KERN_INFO MYNAM ": FW Upload completed rc=%x \n", ii));
2888 cmdStatus = -EFAULT;
2890 /* Handshake transfer was complete and successful.
2891 * Check the Reply Frame.
2893 int status, transfer_sz;
2894 status = le16_to_cpu(preply->IOCStatus);
2895 if (status == MPI_IOCSTATUS_SUCCESS) {
2896 transfer_sz = le32_to_cpu(preply->ActualImageSize);
2897 if (transfer_sz == sz)
2901 dinitprintk((MYIOC_s_INFO_FMT ": do_upload cmdStatus=%d \n",
2902 ioc->name, cmdStatus));
2907 ddlprintk((MYIOC_s_INFO_FMT ": fw upload failed, freeing image \n",
2909 mpt_free_fw_memory(ioc);
2915 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2917 * mpt_downloadboot - DownloadBoot code
2918 * @ioc: Pointer to MPT_ADAPTER structure
2919 * @pFwHeader: Pointer to firmware header info
2920 * @sleepFlag: Specifies whether the process can sleep
2922 * FwDownloadBoot requires Programmed IO access.
2924 * Returns 0 for success
2925 * -1 FW Image size is 0
2926 * -2 No valid cached_fw Pointer
2927 * <0 for fw upload failure.
2930 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
2932 MpiExtImageHeader_t *pExtImage;
2942 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
2943 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
2945 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2946 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2947 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2948 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2949 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2950 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2952 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
2955 if (sleepFlag == CAN_SLEEP) {
2961 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2962 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
2964 for (count = 0; count < 30; count ++) {
2965 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2966 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
2967 ddlprintk((MYIOC_s_INFO_FMT "RESET_ADAPTER cleared, count=%d\n",
2972 if (sleepFlag == CAN_SLEEP) {
2979 if ( count == 30 ) {
2980 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! "
2981 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
2982 ioc->name, diag0val));
2986 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2987 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2988 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2989 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2990 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2991 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2993 /* Set the DiagRwEn and Disable ARM bits */
2994 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
2996 fwSize = (pFwHeader->ImageSize + 3)/4;
2997 ptrFw = (u32 *) pFwHeader;
2999 /* Write the LoadStartAddress to the DiagRw Address Register
3000 * using Programmed IO
3002 if (ioc->errata_flag_1064)
3003 pci_enable_io_access(ioc->pcidev);
3005 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3006 ddlprintk((MYIOC_s_INFO_FMT "LoadStart addr written 0x%x \n",
3007 ioc->name, pFwHeader->LoadStartAddress));
3009 ddlprintk((MYIOC_s_INFO_FMT "Write FW Image: 0x%x bytes @ %p\n",
3010 ioc->name, fwSize*4, ptrFw));
3012 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3015 nextImage = pFwHeader->NextImageHeaderOffset;
3017 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3019 load_addr = pExtImage->LoadStartAddress;
3021 fwSize = (pExtImage->ImageSize + 3) >> 2;
3022 ptrFw = (u32 *)pExtImage;
3024 ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3025 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3026 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3029 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3031 nextImage = pExtImage->NextImageHeaderOffset;
3034 /* Write the IopResetVectorRegAddr */
3035 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
3036 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3038 /* Write the IopResetVectorValue */
3039 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3040 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3042 /* Clear the internal flash bad bit - autoincrementing register,
3043 * so must do two writes.
3045 if (ioc->bus_type == SPI) {
3047 * 1030 and 1035 H/W errata, workaround to access
3048 * the ClearFlashBadSignatureBit
3050 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3051 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3052 diagRwData |= 0x40000000;
3053 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3054 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3056 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3057 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3058 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3059 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3062 if (sleepFlag == CAN_SLEEP) {
3069 if (ioc->errata_flag_1064)
3070 pci_disable_io_access(ioc->pcidev);
3072 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3073 ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, "
3074 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3075 ioc->name, diag0val));
3076 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3077 ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
3078 ioc->name, diag0val));
3079 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3081 /* Write 0xFF to reset the sequencer */
3082 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3084 if (ioc->bus_type == SAS) {
3085 ioc_state = mpt_GetIocState(ioc, 0);
3086 if ( (GetIocFacts(ioc, sleepFlag,
3087 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3088 ddlprintk((MYIOC_s_INFO_FMT "GetIocFacts failed: IocState=%x\n",
3089 ioc->name, ioc_state));
3094 for (count=0; count<HZ*20; count++) {
3095 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3096 ddlprintk((MYIOC_s_INFO_FMT "downloadboot successful! (count=%d) IocState=%x\n",
3097 ioc->name, count, ioc_state));
3098 if (ioc->bus_type == SAS) {
3101 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3102 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit failed\n",
3106 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit successful\n",
3110 if (sleepFlag == CAN_SLEEP) {
3116 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! IocState=%x\n",
3117 ioc->name, ioc_state));
3121 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3123 * KickStart - Perform hard reset of MPT adapter.
3124 * @ioc: Pointer to MPT_ADAPTER structure
3125 * @force: Force hard reset
3126 * @sleepFlag: Specifies whether the process can sleep
3128 * This routine places MPT adapter in diagnostic mode via the
3129 * WriteSequence register, and then performs a hard reset of adapter
3130 * via the Diagnostic register.
3132 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3133 * or NO_SLEEP (interrupt thread, use mdelay)
3134 * force - 1 if doorbell active, board fault state
3135 * board operational, IOC_RECOVERY or
3136 * IOC_BRINGUP and there is an alt_ioc.
3140 * 1 - hard reset, READY
3141 * 0 - no reset due to History bit, READY
3142 * -1 - no reset due to History bit but not READY
3143 * OR reset but failed to come READY
3144 * -2 - no reset, could not enter DIAG mode
3145 * -3 - reset but bad FW bit
3148 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3150 int hard_reset_done = 0;
3154 dinitprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
3155 if (ioc->bus_type == SPI) {
3156 /* Always issue a Msg Unit Reset first. This will clear some
3157 * SCSI bus hang conditions.
3159 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3161 if (sleepFlag == CAN_SLEEP) {
3168 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3169 if (hard_reset_done < 0)
3170 return hard_reset_done;
3172 dinitprintk((MYIOC_s_INFO_FMT "Diagnostic reset successful!\n",
3175 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3176 for (cnt=0; cnt<cntdn; cnt++) {
3177 ioc_state = mpt_GetIocState(ioc, 1);
3178 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3179 dinitprintk((MYIOC_s_INFO_FMT "KickStart successful! (cnt=%d)\n",
3181 return hard_reset_done;
3183 if (sleepFlag == CAN_SLEEP) {
3190 printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3191 ioc->name, ioc_state);
3195 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3197 * mpt_diag_reset - Perform hard reset of the adapter.
3198 * @ioc: Pointer to MPT_ADAPTER structure
3199 * @ignore: Set if to honor and clear to ignore
3200 * the reset history bit
3201 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3202 * else set to NO_SLEEP (use mdelay instead)
3204 * This routine places the adapter in diagnostic mode via the
3205 * WriteSequence register and then performs a hard reset of adapter
3206 * via the Diagnostic register. Adapter should be in ready state
3207 * upon successful completion.
3209 * Returns: 1 hard reset successful
3210 * 0 no reset performed because reset history bit set
3211 * -2 enabling diagnostic mode failed
3212 * -3 diagnostic reset failed
3215 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3217 MPT_ADAPTER *iocp=NULL;
3220 int hard_reset_done = 0;
3226 /* Clear any existing interrupts */
3227 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3229 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3230 drsprintk((MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3231 "address=%p\n", ioc->name, __FUNCTION__,
3232 &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3233 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3234 if (sleepFlag == CAN_SLEEP)
3239 for (count = 0; count < 60; count ++) {
3240 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3241 doorbell &= MPI_IOC_STATE_MASK;
3243 drsprintk((MYIOC_s_INFO_FMT
3244 "looking for READY STATE: doorbell=%x"
3246 ioc->name, doorbell, count));
3247 if (doorbell == MPI_IOC_STATE_READY) {
3252 if (sleepFlag == CAN_SLEEP)
3260 /* Use "Diagnostic reset" method! (only thing available!) */
3261 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3265 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3266 dprintk((MYIOC_s_INFO_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3267 ioc->name, diag0val, diag1val));
3270 /* Do the reset if we are told to ignore the reset history
3271 * or if the reset history is 0
3273 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3274 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3275 /* Write magic sequence to WriteSequence register
3276 * Loop until in diagnostic mode
3278 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3279 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3280 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3281 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3282 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3283 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3286 if (sleepFlag == CAN_SLEEP) {
3294 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3295 ioc->name, diag0val);
3300 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3302 dprintk((MYIOC_s_INFO_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3303 ioc->name, diag0val));
3308 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3309 dprintk((MYIOC_s_INFO_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3310 ioc->name, diag0val, diag1val));
3313 * Disable the ARM (Bug fix)
3316 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3320 * Now hit the reset bit in the Diagnostic register
3321 * (THE BIG HAMMER!) (Clears DRWE bit).
3323 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3324 hard_reset_done = 1;
3325 dprintk((MYIOC_s_INFO_FMT "Diagnostic reset performed\n",
3329 * Call each currently registered protocol IOC reset handler
3330 * with pre-reset indication.
3331 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3332 * MptResetHandlers[] registered yet.
3338 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
3339 if (MptResetHandlers[ii]) {
3340 dprintk((MYIOC_s_INFO_FMT "Calling IOC pre_reset handler #%d\n",
3342 r += mpt_signal_reset(ii, ioc, MPT_IOC_PRE_RESET);
3344 dprintk((MYIOC_s_INFO_FMT "Calling alt-%s pre_reset handler #%d\n",
3345 ioc->name, ioc->alt_ioc->name, ii));
3346 r += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_PRE_RESET);
3350 /* FIXME? Examine results here? */
3355 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
3356 iocp = ioc->alt_ioc;
3358 /* If the DownloadBoot operation fails, the
3359 * IOC will be left unusable. This is a fatal error
3360 * case. _diag_reset will return < 0
3362 for (count = 0; count < 30; count ++) {
3363 diag0val = CHIPREG_READ32(&iocp->chip->Diagnostic);
3364 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3368 dprintk((MYIOC_s_INFO_FMT "cached_fw: diag0val=%x count=%d\n",
3369 iocp->name, diag0val, count));
3371 if (sleepFlag == CAN_SLEEP) {
3377 if ((count = mpt_downloadboot(ioc,
3378 (MpiFwHeader_t *)iocp->cached_fw, sleepFlag)) < 0) {
3379 printk(KERN_WARNING MYNAM
3380 ": firmware downloadboot failure (%d)!\n", count);
3384 /* Wait for FW to reload and for board
3385 * to go to the READY state.
3386 * Maximum wait is 60 seconds.
3387 * If fail, no error will check again
3388 * with calling program.
3390 for (count = 0; count < 60; count ++) {
3391 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3392 doorbell &= MPI_IOC_STATE_MASK;
3394 if (doorbell == MPI_IOC_STATE_READY) {
3399 if (sleepFlag == CAN_SLEEP) {
3408 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3411 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3412 dprintk((MYIOC_s_INFO_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3413 ioc->name, diag0val, diag1val));
3416 /* Clear RESET_HISTORY bit! Place board in the
3417 * diagnostic mode to update the diag register.
3419 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3421 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3422 /* Write magic sequence to WriteSequence register
3423 * Loop until in diagnostic mode
3425 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3426 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3427 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3428 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3429 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3430 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3433 if (sleepFlag == CAN_SLEEP) {
3441 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3442 ioc->name, diag0val);
3445 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3447 diag0val &= ~MPI_DIAG_RESET_HISTORY;
3448 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3449 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3450 if (diag0val & MPI_DIAG_RESET_HISTORY) {
3451 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3455 /* Disable Diagnostic Mode
3457 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3459 /* Check FW reload status flags.
3461 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3462 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3463 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3464 ioc->name, diag0val);
3470 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3471 dprintk((MYIOC_s_INFO_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3472 ioc->name, diag0val, diag1val));
3476 * Reset flag that says we've enabled event notification
3478 ioc->facts.EventState = 0;
3481 ioc->alt_ioc->facts.EventState = 0;
3483 return hard_reset_done;
3486 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3488 * SendIocReset - Send IOCReset request to MPT adapter.
3489 * @ioc: Pointer to MPT_ADAPTER structure
3490 * @reset_type: reset type, expected values are
3491 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3492 * @sleepFlag: Specifies whether the process can sleep
3494 * Send IOCReset request to the MPT adapter.
3496 * Returns 0 for success, non-zero for failure.
3499 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3505 drsprintk((KERN_INFO MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
3506 ioc->name, reset_type));
3507 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3508 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3511 /* FW ACK'd request, wait for READY state
3514 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
3516 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3520 if (sleepFlag != CAN_SLEEP)
3523 printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
3524 ioc->name, (int)((count+5)/HZ));
3528 if (sleepFlag == CAN_SLEEP) {
3531 mdelay (1); /* 1 msec delay */
3536 * Cleanup all event stuff for this IOC; re-issue EventNotification
3537 * request if needed.
3539 if (ioc->facts.Function)
3540 ioc->facts.EventState = 0;
3545 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3547 * initChainBuffers - Allocate memory for and initialize chain buffers
3548 * @ioc: Pointer to MPT_ADAPTER structure
3550 * Allocates memory for and initializes chain buffers,
3551 * chain buffer control arrays and spinlock.
3554 initChainBuffers(MPT_ADAPTER *ioc)
3557 int sz, ii, num_chain;
3558 int scale, num_sge, numSGE;
3560 /* ReqToChain size must equal the req_depth
3563 if (ioc->ReqToChain == NULL) {
3564 sz = ioc->req_depth * sizeof(int);
3565 mem = kmalloc(sz, GFP_ATOMIC);
3569 ioc->ReqToChain = (int *) mem;
3570 dinitprintk((KERN_INFO MYNAM ": %s ReqToChain alloc @ %p, sz=%d bytes\n",
3571 ioc->name, mem, sz));
3572 mem = kmalloc(sz, GFP_ATOMIC);
3576 ioc->RequestNB = (int *) mem;
3577 dinitprintk((KERN_INFO MYNAM ": %s RequestNB alloc @ %p, sz=%d bytes\n",
3578 ioc->name, mem, sz));
3580 for (ii = 0; ii < ioc->req_depth; ii++) {
3581 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
3584 /* ChainToChain size must equal the total number
3585 * of chain buffers to be allocated.
3588 * Calculate the number of chain buffers needed(plus 1) per I/O
3589 * then multiply the maximum number of simultaneous cmds
3591 * num_sge = num sge in request frame + last chain buffer
3592 * scale = num sge per chain buffer if no chain element
3594 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3595 if (sizeof(dma_addr_t) == sizeof(u64))
3596 num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3598 num_sge = 1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3600 if (sizeof(dma_addr_t) == sizeof(u64)) {
3601 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3602 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3604 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3605 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3607 dinitprintk((KERN_INFO MYNAM ": %s num_sge=%d numSGE=%d\n",
3608 ioc->name, num_sge, numSGE));
3610 if ( numSGE > MPT_SCSI_SG_DEPTH )
3611 numSGE = MPT_SCSI_SG_DEPTH;
3614 while (numSGE - num_sge > 0) {
3616 num_sge += (scale - 1);
3620 dinitprintk((KERN_INFO MYNAM ": %s Now numSGE=%d num_sge=%d num_chain=%d\n",
3621 ioc->name, numSGE, num_sge, num_chain));
3623 if (ioc->bus_type == SPI)
3624 num_chain *= MPT_SCSI_CAN_QUEUE;
3626 num_chain *= MPT_FC_CAN_QUEUE;
3628 ioc->num_chain = num_chain;
3630 sz = num_chain * sizeof(int);
3631 if (ioc->ChainToChain == NULL) {
3632 mem = kmalloc(sz, GFP_ATOMIC);
3636 ioc->ChainToChain = (int *) mem;
3637 dinitprintk((KERN_INFO MYNAM ": %s ChainToChain alloc @ %p, sz=%d bytes\n",
3638 ioc->name, mem, sz));
3640 mem = (u8 *) ioc->ChainToChain;
3642 memset(mem, 0xFF, sz);
3646 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3648 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
3649 * @ioc: Pointer to MPT_ADAPTER structure
3651 * This routine allocates memory for the MPT reply and request frame
3652 * pools (if necessary), and primes the IOC reply FIFO with
3655 * Returns 0 for success, non-zero for failure.
3658 PrimeIocFifos(MPT_ADAPTER *ioc)
3661 unsigned long flags;
3662 dma_addr_t alloc_dma;
3664 int i, reply_sz, sz, total_size, num_chain;
3666 /* Prime reply FIFO... */
3668 if (ioc->reply_frames == NULL) {
3669 if ( (num_chain = initChainBuffers(ioc)) < 0)
3672 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
3673 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
3674 ioc->name, ioc->reply_sz, ioc->reply_depth));
3675 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d[%x] bytes\n",
3676 ioc->name, reply_sz, reply_sz));
3678 sz = (ioc->req_sz * ioc->req_depth);
3679 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d bytes, RequestDepth=%d\n",
3680 ioc->name, ioc->req_sz, ioc->req_depth));
3681 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d[%x] bytes\n",
3682 ioc->name, sz, sz));
3685 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
3686 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d bytes, ChainDepth=%d\n",
3687 ioc->name, ioc->req_sz, num_chain));
3688 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
3689 ioc->name, sz, sz, num_chain));
3692 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
3694 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
3699 dinitprintk((KERN_INFO MYNAM ": %s.Total alloc @ %p[%p], sz=%d[%x] bytes\n",
3700 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
3702 memset(mem, 0, total_size);
3703 ioc->alloc_total += total_size;
3705 ioc->alloc_dma = alloc_dma;
3706 ioc->alloc_sz = total_size;
3707 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
3708 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3710 dinitprintk((KERN_INFO MYNAM ": %s ReplyBuffers @ %p[%p]\n",
3711 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3713 alloc_dma += reply_sz;
3716 /* Request FIFO - WE manage this! */
3718 ioc->req_frames = (MPT_FRAME_HDR *) mem;
3719 ioc->req_frames_dma = alloc_dma;
3721 dinitprintk((KERN_INFO MYNAM ": %s RequestBuffers @ %p[%p]\n",
3722 ioc->name, mem, (void *)(ulong)alloc_dma));
3724 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3726 #if defined(CONFIG_MTRR) && 0
3728 * Enable Write Combining MTRR for IOC's memory region.
3729 * (at least as much as we can; "size and base must be
3730 * multiples of 4 kiB"
3732 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
3734 MTRR_TYPE_WRCOMB, 1);
3735 dprintk((MYIOC_s_INFO_FMT "MTRR region registered (base:size=%08x:%x)\n",
3736 ioc->name, ioc->req_frames_dma, sz));
3739 for (i = 0; i < ioc->req_depth; i++) {
3740 alloc_dma += ioc->req_sz;
3744 ioc->ChainBuffer = mem;
3745 ioc->ChainBufferDMA = alloc_dma;
3747 dinitprintk((KERN_INFO MYNAM " :%s ChainBuffers @ %p(%p)\n",
3748 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
3750 /* Initialize the free chain Q.
3753 INIT_LIST_HEAD(&ioc->FreeChainQ);
3755 /* Post the chain buffers to the FreeChainQ.
3757 mem = (u8 *)ioc->ChainBuffer;
3758 for (i=0; i < num_chain; i++) {
3759 mf = (MPT_FRAME_HDR *) mem;
3760 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
3764 /* Initialize Request frames linked list
3766 alloc_dma = ioc->req_frames_dma;
3767 mem = (u8 *) ioc->req_frames;
3769 spin_lock_irqsave(&ioc->FreeQlock, flags);
3770 INIT_LIST_HEAD(&ioc->FreeQ);
3771 for (i = 0; i < ioc->req_depth; i++) {
3772 mf = (MPT_FRAME_HDR *) mem;
3774 /* Queue REQUESTs *internally*! */
3775 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
3779 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3781 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3782 ioc->sense_buf_pool =
3783 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
3784 if (ioc->sense_buf_pool == NULL) {
3785 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
3790 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
3791 ioc->alloc_total += sz;
3792 dinitprintk((KERN_INFO MYNAM ": %s.SenseBuffers @ %p[%p]\n",
3793 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
3797 /* Post Reply frames to FIFO
3799 alloc_dma = ioc->alloc_dma;
3800 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffers @ %p[%p]\n",
3801 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3803 for (i = 0; i < ioc->reply_depth; i++) {
3804 /* Write each address to the IOC! */
3805 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
3806 alloc_dma += ioc->reply_sz;
3812 if (ioc->alloc != NULL) {
3814 pci_free_consistent(ioc->pcidev,
3816 ioc->alloc, ioc->alloc_dma);
3817 ioc->reply_frames = NULL;
3818 ioc->req_frames = NULL;
3819 ioc->alloc_total -= sz;
3821 if (ioc->sense_buf_pool != NULL) {
3822 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3823 pci_free_consistent(ioc->pcidev,
3825 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
3826 ioc->sense_buf_pool = NULL;
3831 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3833 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
3834 * from IOC via doorbell handshake method.
3835 * @ioc: Pointer to MPT_ADAPTER structure
3836 * @reqBytes: Size of the request in bytes
3837 * @req: Pointer to MPT request frame
3838 * @replyBytes: Expected size of the reply in bytes
3839 * @u16reply: Pointer to area where reply should be written
3840 * @maxwait: Max wait time for a reply (in seconds)
3841 * @sleepFlag: Specifies whether the process can sleep
3843 * NOTES: It is the callers responsibility to byte-swap fields in the
3844 * request which are greater than 1 byte in size. It is also the
3845 * callers responsibility to byte-swap response fields which are
3846 * greater than 1 byte in size.
3848 * Returns 0 for success, non-zero for failure.
3851 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
3852 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
3854 MPIDefaultReply_t *mptReply;
3859 * Get ready to cache a handshake reply
3861 ioc->hs_reply_idx = 0;
3862 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
3863 mptReply->MsgLength = 0;
3866 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
3867 * then tell IOC that we want to handshake a request of N words.
3868 * (WRITE u32val to Doorbell reg).
3870 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3871 CHIPREG_WRITE32(&ioc->chip->Doorbell,
3872 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
3873 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
3876 * Wait for IOC's doorbell handshake int
3878 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3881 dhsprintk((MYIOC_s_INFO_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
3882 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
3884 /* Read doorbell and check for active bit */
3885 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
3889 * Clear doorbell int (WRITE 0 to IntStatus reg),
3890 * then wait for IOC to ACKnowledge that it's ready for
3891 * our handshake request.
3893 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3894 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3899 u8 *req_as_bytes = (u8 *) req;
3902 * Stuff request words via doorbell handshake,
3903 * with ACK from IOC for each.
3905 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
3906 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
3907 (req_as_bytes[(ii*4) + 1] << 8) |
3908 (req_as_bytes[(ii*4) + 2] << 16) |
3909 (req_as_bytes[(ii*4) + 3] << 24));
3911 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
3912 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3916 dhsprintk((KERN_INFO MYNAM ": Handshake request frame (@%p) header\n", req));
3917 DBG_DUMP_REQUEST_FRAME_HDR(req)
3919 dhsprintk((MYIOC_s_INFO_FMT "HandShake request post done, WaitCnt=%d%s\n",
3920 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
3923 * Wait for completion of doorbell handshake reply from the IOC
3925 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
3928 dhsprintk((MYIOC_s_INFO_FMT "HandShake reply count=%d%s\n",
3929 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
3932 * Copy out the cached reply...
3934 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
3935 u16reply[ii] = ioc->hs_reply[ii];
3943 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3945 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
3946 * @ioc: Pointer to MPT_ADAPTER structure
3947 * @howlong: How long to wait (in seconds)
3948 * @sleepFlag: Specifies whether the process can sleep
3950 * This routine waits (up to ~2 seconds max) for IOC doorbell
3951 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
3952 * bit in its IntStatus register being clear.
3954 * Returns a negative value on failure, else wait loop count.
3957 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3963 cntdn = 1000 * howlong;
3965 if (sleepFlag == CAN_SLEEP) {
3968 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3969 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3976 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3977 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3984 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell ACK (count=%d)\n",
3989 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
3990 ioc->name, count, intstat);
3994 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3996 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
3997 * @ioc: Pointer to MPT_ADAPTER structure
3998 * @howlong: How long to wait (in seconds)
3999 * @sleepFlag: Specifies whether the process can sleep
4001 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4002 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4004 * Returns a negative value on failure, else wait loop count.
4007 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4013 cntdn = 1000 * howlong;
4014 if (sleepFlag == CAN_SLEEP) {
4016 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4017 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4024 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4025 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4033 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4034 ioc->name, count, howlong));
4038 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4039 ioc->name, count, intstat);
4043 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4045 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4046 * @ioc: Pointer to MPT_ADAPTER structure
4047 * @howlong: How long to wait (in seconds)
4048 * @sleepFlag: Specifies whether the process can sleep
4050 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4051 * Reply is cached to IOC private area large enough to hold a maximum
4052 * of 128 bytes of reply data.
4054 * Returns a negative value on failure, else size of reply in WORDS.
4057 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4062 u16 *hs_reply = ioc->hs_reply;
4063 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4066 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4069 * Get first two u16's so we can look at IOC's intended reply MsgLength
4072 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4075 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4076 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4077 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4080 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4081 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4085 dhsprintk((MYIOC_s_INFO_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4086 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4087 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4090 * If no error (and IOC said MsgLength is > 0), piece together
4091 * reply 16 bits at a time.
4093 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4094 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4096 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4097 /* don't overflow our IOC hs_reply[] buffer! */
4098 if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
4099 hs_reply[u16cnt] = hword;
4100 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4103 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4105 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4108 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4113 else if (u16cnt != (2 * mptReply->MsgLength)) {
4116 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4121 dhsprintk((MYIOC_s_INFO_FMT "Got Handshake reply:\n", ioc->name));
4122 DBG_DUMP_REPLY_FRAME(mptReply)
4124 dhsprintk((MYIOC_s_INFO_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4125 ioc->name, t, u16cnt/2));
4129 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4131 * GetLanConfigPages - Fetch LANConfig pages.
4132 * @ioc: Pointer to MPT_ADAPTER structure
4134 * Return: 0 for success
4135 * -ENOMEM if no memory available
4136 * -EPERM if not allowed due to ISR context
4137 * -EAGAIN if no msg frames currently available
4138 * -EFAULT for non-successful reply or no reply (timeout)
4141 GetLanConfigPages(MPT_ADAPTER *ioc)
4143 ConfigPageHeader_t hdr;
4145 LANPage0_t *ppage0_alloc;
4146 dma_addr_t page0_dma;
4147 LANPage1_t *ppage1_alloc;
4148 dma_addr_t page1_dma;
4153 /* Get LAN Page 0 header */
4154 hdr.PageVersion = 0;
4157 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4158 cfg.cfghdr.hdr = &hdr;
4160 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4165 if ((rc = mpt_config(ioc, &cfg)) != 0)
4168 if (hdr.PageLength > 0) {
4169 data_sz = hdr.PageLength * 4;
4170 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4173 memset((u8 *)ppage0_alloc, 0, data_sz);
4174 cfg.physAddr = page0_dma;
4175 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4177 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4179 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4180 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4184 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4187 * Normalize endianness of structure data,
4188 * by byte-swapping all > 1 byte fields!
4197 /* Get LAN Page 1 header */
4198 hdr.PageVersion = 0;
4201 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4202 cfg.cfghdr.hdr = &hdr;
4204 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4208 if ((rc = mpt_config(ioc, &cfg)) != 0)
4211 if (hdr.PageLength == 0)
4214 data_sz = hdr.PageLength * 4;
4216 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4218 memset((u8 *)ppage1_alloc, 0, data_sz);
4219 cfg.physAddr = page1_dma;
4220 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4222 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4224 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4225 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4228 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4231 * Normalize endianness of structure data,
4232 * by byte-swapping all > 1 byte fields!
4240 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4242 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
4243 * @ioc: Pointer to MPT_ADAPTER structure
4244 * @persist_opcode: see below
4246 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4247 * devices not currently present.
4248 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4250 * NOTE: Don't use not this function during interrupt time.
4252 * Returns 0 for success, non-zero error
4255 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4257 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4259 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
4260 SasIoUnitControlReply_t *sasIoUnitCntrReply;
4261 MPT_FRAME_HDR *mf = NULL;
4262 MPIHeader_t *mpi_hdr;
4265 /* insure garbage is not sent to fw */
4266 switch(persist_opcode) {
4268 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
4269 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
4277 printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode);
4279 /* Get a MF for this command.
4281 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4282 printk("%s: no msg frames!\n",__FUNCTION__);
4286 mpi_hdr = (MPIHeader_t *) mf;
4287 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
4288 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
4289 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
4290 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
4291 sasIoUnitCntrReq->Operation = persist_opcode;
4293 init_timer(&ioc->persist_timer);
4294 ioc->persist_timer.data = (unsigned long) ioc;
4295 ioc->persist_timer.function = mpt_timer_expired;
4296 ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
4297 ioc->persist_wait_done=0;
4298 add_timer(&ioc->persist_timer);
4299 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4300 wait_event(mpt_waitq, ioc->persist_wait_done);
4302 sasIoUnitCntrReply =
4303 (SasIoUnitControlReply_t *)ioc->persist_reply_frame;
4304 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
4305 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4307 sasIoUnitCntrReply->IOCStatus,
4308 sasIoUnitCntrReply->IOCLogInfo);
4312 printk("%s: success\n",__FUNCTION__);
4316 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4319 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
4320 MpiEventDataRaid_t * pRaidEventData)
4329 volume = pRaidEventData->VolumeID;
4330 reason = pRaidEventData->ReasonCode;
4331 disk = pRaidEventData->PhysDiskNum;
4332 status = le32_to_cpu(pRaidEventData->SettingsStatus);
4333 flags = (status >> 0) & 0xff;
4334 state = (status >> 8) & 0xff;
4336 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
4340 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
4341 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
4342 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
4343 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
4344 ioc->name, disk, volume);
4346 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
4351 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4352 printk(MYIOC_s_INFO_FMT " volume has been created\n",
4356 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4358 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
4362 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
4363 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
4367 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4368 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
4370 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
4372 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
4374 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
4377 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
4379 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
4380 ? ", quiesced" : "",
4381 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
4382 ? ", resync in progress" : "" );
4385 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
4386 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
4390 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4391 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
4395 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4396 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
4400 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
4401 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
4405 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4406 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
4408 state == MPI_PHYSDISK0_STATUS_ONLINE
4410 : state == MPI_PHYSDISK0_STATUS_MISSING
4412 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
4414 : state == MPI_PHYSDISK0_STATUS_FAILED
4416 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
4418 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
4419 ? "offline requested"
4420 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
4421 ? "failed requested"
4422 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
4425 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
4426 ? ", out of sync" : "",
4427 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
4428 ? ", quiesced" : "" );
4431 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
4432 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
4436 case MPI_EVENT_RAID_RC_SMART_DATA:
4437 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
4438 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
4441 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
4442 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
4448 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4450 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4451 * @ioc: Pointer to MPT_ADAPTER structure
4453 * Returns: 0 for success
4454 * -ENOMEM if no memory available
4455 * -EPERM if not allowed due to ISR context
4456 * -EAGAIN if no msg frames currently available
4457 * -EFAULT for non-successful reply or no reply (timeout)
4460 GetIoUnitPage2(MPT_ADAPTER *ioc)
4462 ConfigPageHeader_t hdr;
4464 IOUnitPage2_t *ppage_alloc;
4465 dma_addr_t page_dma;
4469 /* Get the page header */
4470 hdr.PageVersion = 0;
4473 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4474 cfg.cfghdr.hdr = &hdr;
4476 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4481 if ((rc = mpt_config(ioc, &cfg)) != 0)
4484 if (hdr.PageLength == 0)
4487 /* Read the config page */
4488 data_sz = hdr.PageLength * 4;
4490 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4492 memset((u8 *)ppage_alloc, 0, data_sz);
4493 cfg.physAddr = page_dma;
4494 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4496 /* If Good, save data */
4497 if ((rc = mpt_config(ioc, &cfg)) == 0)
4498 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4500 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4506 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4508 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4509 * @ioc: Pointer to a Adapter Strucutre
4510 * @portnum: IOC port number
4512 * Return: -EFAULT if read of config page header fails
4514 * If read of SCSI Port Page 0 fails,
4515 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4516 * Adapter settings: async, narrow
4518 * If read of SCSI Port Page 2 fails,
4519 * Adapter settings valid
4520 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4525 * CHECK - what type of locking mechanisms should be used????
4528 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4533 ConfigPageHeader_t header;
4539 if (!ioc->spi_data.nvram) {
4542 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4543 mem = kmalloc(sz, GFP_ATOMIC);
4547 ioc->spi_data.nvram = (int *) mem;
4549 dprintk((MYIOC_s_INFO_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4550 ioc->name, ioc->spi_data.nvram, sz));
4553 /* Invalidate NVRAM information
4555 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4556 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4559 /* Read SPP0 header, allocate memory, then read page.
4561 header.PageVersion = 0;
4562 header.PageLength = 0;
4563 header.PageNumber = 0;
4564 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4565 cfg.cfghdr.hdr = &header;
4567 cfg.pageAddr = portnum;
4568 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4570 cfg.timeout = 0; /* use default */
4571 if (mpt_config(ioc, &cfg) != 0)
4574 if (header.PageLength > 0) {
4575 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4577 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4578 cfg.physAddr = buf_dma;
4579 if (mpt_config(ioc, &cfg) != 0) {
4580 ioc->spi_data.maxBusWidth = MPT_NARROW;
4581 ioc->spi_data.maxSyncOffset = 0;
4582 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4583 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4585 ddvprintk((MYIOC_s_INFO_FMT "Unable to read PortPage0 minSyncFactor=%x\n",
4586 ioc->name, ioc->spi_data.minSyncFactor));
4588 /* Save the Port Page 0 data
4590 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
4591 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4592 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4594 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
4595 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4596 ddvprintk((KERN_INFO MYNAM " :%s noQas due to Capabilities=%x\n",
4597 ioc->name, pPP0->Capabilities));
4599 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4600 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4602 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4603 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4604 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4605 ddvprintk((MYIOC_s_INFO_FMT "PortPage0 minSyncFactor=%x\n",
4606 ioc->name, ioc->spi_data.minSyncFactor));
4608 ioc->spi_data.maxSyncOffset = 0;
4609 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4612 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4614 /* Update the minSyncFactor based on bus type.
4616 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4617 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
4619 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
4620 ioc->spi_data.minSyncFactor = MPT_ULTRA;
4621 ddvprintk((MYIOC_s_INFO_FMT "HVD or SE detected, minSyncFactor=%x\n",
4622 ioc->name, ioc->spi_data.minSyncFactor));
4627 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4632 /* SCSI Port Page 2 - Read the header then the page.
4634 header.PageVersion = 0;
4635 header.PageLength = 0;
4636 header.PageNumber = 2;
4637 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4638 cfg.cfghdr.hdr = &header;
4640 cfg.pageAddr = portnum;
4641 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4643 if (mpt_config(ioc, &cfg) != 0)
4646 if (header.PageLength > 0) {
4647 /* Allocate memory and read SCSI Port Page 2
4649 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4651 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
4652 cfg.physAddr = buf_dma;
4653 if (mpt_config(ioc, &cfg) != 0) {
4654 /* Nvram data is left with INVALID mark
4658 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
4659 MpiDeviceInfo_t *pdevice = NULL;
4662 * Save "Set to Avoid SCSI Bus Resets" flag
4664 ioc->spi_data.bus_reset =
4665 (le32_to_cpu(pPP2->PortFlags) &
4666 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
4669 /* Save the Port Page 2 data
4670 * (reformat into a 32bit quantity)
4672 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
4673 ioc->spi_data.PortFlags = data;
4674 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4675 pdevice = &pPP2->DeviceSettings[ii];
4676 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
4677 (pdevice->SyncFactor << 8) | pdevice->Timeout;
4678 ioc->spi_data.nvram[ii] = data;
4682 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4686 /* Update Adapter limits with those from NVRAM
4687 * Comment: Don't need to do this. Target performance
4688 * parameters will never exceed the adapters limits.
4694 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4696 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
4697 * @ioc: Pointer to a Adapter Strucutre
4698 * @portnum: IOC port number
4700 * Return: -EFAULT if read of config page header fails
4704 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
4707 ConfigPageHeader_t header;
4709 /* Read the SCSI Device Page 1 header
4711 header.PageVersion = 0;
4712 header.PageLength = 0;
4713 header.PageNumber = 1;
4714 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4715 cfg.cfghdr.hdr = &header;
4717 cfg.pageAddr = portnum;
4718 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4721 if (mpt_config(ioc, &cfg) != 0)
4724 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
4725 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
4727 header.PageVersion = 0;
4728 header.PageLength = 0;
4729 header.PageNumber = 0;
4730 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4731 if (mpt_config(ioc, &cfg) != 0)
4734 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
4735 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
4737 dcprintk((MYIOC_s_INFO_FMT "Headers: 0: version %d length %d\n",
4738 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
4740 dcprintk((MYIOC_s_INFO_FMT "Headers: 1: version %d length %d\n",
4741 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
4746 * mpt_inactive_raid_list_free - This clears this link list.
4747 * @ioc : pointer to per adapter structure
4750 mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
4752 struct inactive_raid_component_info *component_info, *pNext;
4754 if (list_empty(&ioc->raid_data.inactive_list))
4757 down(&ioc->raid_data.inactive_list_mutex);
4758 list_for_each_entry_safe(component_info, pNext,
4759 &ioc->raid_data.inactive_list, list) {
4760 list_del(&component_info->list);
4761 kfree(component_info);
4763 up(&ioc->raid_data.inactive_list_mutex);
4767 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
4769 * @ioc : pointer to per adapter structure
4770 * @channel : volume channel
4771 * @id : volume target id
4774 mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
4777 ConfigPageHeader_t hdr;
4778 dma_addr_t dma_handle;
4779 pRaidVolumePage0_t buffer = NULL;
4781 RaidPhysDiskPage0_t phys_disk;
4782 struct inactive_raid_component_info *component_info;
4783 int handle_inactive_volumes;
4785 memset(&cfg, 0 , sizeof(CONFIGPARMS));
4786 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
4787 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
4788 cfg.pageAddr = (channel << 8) + id;
4789 cfg.cfghdr.hdr = &hdr;
4790 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4792 if (mpt_config(ioc, &cfg) != 0)
4795 if (!hdr.PageLength)
4798 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
4804 cfg.physAddr = dma_handle;
4805 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4807 if (mpt_config(ioc, &cfg) != 0)
4810 if (!buffer->NumPhysDisks)
4813 handle_inactive_volumes =
4814 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
4815 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
4816 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
4817 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
4819 if (!handle_inactive_volumes)
4822 down(&ioc->raid_data.inactive_list_mutex);
4823 for (i = 0; i < buffer->NumPhysDisks; i++) {
4824 if(mpt_raid_phys_disk_pg0(ioc,
4825 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
4828 if ((component_info = kmalloc(sizeof (*component_info),
4829 GFP_KERNEL)) == NULL)
4832 component_info->volumeID = id;
4833 component_info->volumeBus = channel;
4834 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
4835 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
4836 component_info->d.PhysDiskID = phys_disk.PhysDiskID;
4837 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
4839 list_add_tail(&component_info->list,
4840 &ioc->raid_data.inactive_list);
4842 up(&ioc->raid_data.inactive_list_mutex);
4846 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
4851 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
4852 * @ioc: Pointer to a Adapter Structure
4853 * @phys_disk_num: io unit unique phys disk num generated by the ioc
4854 * @phys_disk: requested payload data returned
4858 * -EFAULT if read of config page header fails or data pointer not NULL
4859 * -ENOMEM if pci_alloc failed
4862 mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk)
4865 ConfigPageHeader_t hdr;
4866 dma_addr_t dma_handle;
4867 pRaidPhysDiskPage0_t buffer = NULL;
4870 memset(&cfg, 0 , sizeof(CONFIGPARMS));
4871 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
4873 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
4874 cfg.cfghdr.hdr = &hdr;
4876 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4878 if (mpt_config(ioc, &cfg) != 0) {
4883 if (!hdr.PageLength) {
4888 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
4896 cfg.physAddr = dma_handle;
4897 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4898 cfg.pageAddr = phys_disk_num;
4900 if (mpt_config(ioc, &cfg) != 0) {
4906 memcpy(phys_disk, buffer, sizeof(*buffer));
4907 phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
4912 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
4919 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
4920 * @ioc: Pointer to a Adapter Strucutre
4921 * @portnum: IOC port number
4925 * -EFAULT if read of config page header fails or data pointer not NULL
4926 * -ENOMEM if pci_alloc failed
4929 mpt_findImVolumes(MPT_ADAPTER *ioc)
4933 dma_addr_t ioc2_dma;
4935 ConfigPageHeader_t header;
4940 if (!ioc->ir_firmware)
4943 /* Free the old page
4945 kfree(ioc->raid_data.pIocPg2);
4946 ioc->raid_data.pIocPg2 = NULL;
4947 mpt_inactive_raid_list_free(ioc);
4949 /* Read IOCP2 header then the page.
4951 header.PageVersion = 0;
4952 header.PageLength = 0;
4953 header.PageNumber = 2;
4954 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4955 cfg.cfghdr.hdr = &header;
4958 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4961 if (mpt_config(ioc, &cfg) != 0)
4964 if (header.PageLength == 0)
4967 iocpage2sz = header.PageLength * 4;
4968 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
4972 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4973 cfg.physAddr = ioc2_dma;
4974 if (mpt_config(ioc, &cfg) != 0)
4977 mem = kmalloc(iocpage2sz, GFP_KERNEL);
4981 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
4982 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
4984 mpt_read_ioc_pg_3(ioc);
4986 for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
4987 mpt_inactive_raid_volumes(ioc,
4988 pIoc2->RaidVolume[i].VolumeBus,
4989 pIoc2->RaidVolume[i].VolumeID);
4992 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
4998 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
5003 ConfigPageHeader_t header;
5004 dma_addr_t ioc3_dma;
5007 /* Free the old page
5009 kfree(ioc->raid_data.pIocPg3);
5010 ioc->raid_data.pIocPg3 = NULL;
5012 /* There is at least one physical disk.
5013 * Read and save IOC Page 3
5015 header.PageVersion = 0;
5016 header.PageLength = 0;
5017 header.PageNumber = 3;
5018 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5019 cfg.cfghdr.hdr = &header;
5022 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5025 if (mpt_config(ioc, &cfg) != 0)
5028 if (header.PageLength == 0)
5031 /* Read Header good, alloc memory
5033 iocpage3sz = header.PageLength * 4;
5034 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
5038 /* Read the Page and save the data
5039 * into malloc'd memory.
5041 cfg.physAddr = ioc3_dma;
5042 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5043 if (mpt_config(ioc, &cfg) == 0) {
5044 mem = kmalloc(iocpage3sz, GFP_KERNEL);
5046 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
5047 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
5051 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
5057 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
5061 ConfigPageHeader_t header;
5062 dma_addr_t ioc4_dma;
5065 /* Read and save IOC Page 4
5067 header.PageVersion = 0;
5068 header.PageLength = 0;
5069 header.PageNumber = 4;
5070 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5071 cfg.cfghdr.hdr = &header;
5074 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5077 if (mpt_config(ioc, &cfg) != 0)
5080 if (header.PageLength == 0)
5083 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
5084 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
5085 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
5088 ioc->alloc_total += iocpage4sz;
5090 ioc4_dma = ioc->spi_data.IocPg4_dma;
5091 iocpage4sz = ioc->spi_data.IocPg4Sz;
5094 /* Read the Page into dma memory.
5096 cfg.physAddr = ioc4_dma;
5097 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5098 if (mpt_config(ioc, &cfg) == 0) {
5099 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
5100 ioc->spi_data.IocPg4_dma = ioc4_dma;
5101 ioc->spi_data.IocPg4Sz = iocpage4sz;
5103 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
5104 ioc->spi_data.pIocPg4 = NULL;
5105 ioc->alloc_total -= iocpage4sz;
5110 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
5114 ConfigPageHeader_t header;
5115 dma_addr_t ioc1_dma;
5119 /* Check the Coalescing Timeout in IOC Page 1
5121 header.PageVersion = 0;
5122 header.PageLength = 0;
5123 header.PageNumber = 1;
5124 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5125 cfg.cfghdr.hdr = &header;
5128 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5131 if (mpt_config(ioc, &cfg) != 0)
5134 if (header.PageLength == 0)
5137 /* Read Header good, alloc memory
5139 iocpage1sz = header.PageLength * 4;
5140 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
5144 /* Read the Page and check coalescing timeout
5146 cfg.physAddr = ioc1_dma;
5147 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5148 if (mpt_config(ioc, &cfg) == 0) {
5150 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
5151 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
5152 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
5154 dprintk((MYIOC_s_INFO_FMT "Coalescing Enabled Timeout = %d\n",
5157 if (tmp > MPT_COALESCING_TIMEOUT) {
5158 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
5160 /* Write NVRAM and current
5163 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5164 if (mpt_config(ioc, &cfg) == 0) {
5165 dprintk((MYIOC_s_INFO_FMT "Reset Current Coalescing Timeout to = %d\n",
5166 ioc->name, MPT_COALESCING_TIMEOUT));
5168 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
5169 if (mpt_config(ioc, &cfg) == 0) {
5170 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout to = %d\n",
5171 ioc->name, MPT_COALESCING_TIMEOUT));
5173 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout Failed\n",
5178 dprintk((MYIOC_s_WARN_FMT "Reset of Current Coalescing Timeout Failed!\n",
5184 dprintk((MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
5188 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
5193 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5195 * SendEventNotification - Send EventNotification (on or off) request to adapter
5196 * @ioc: Pointer to MPT_ADAPTER structure
5197 * @EvSwitch: Event switch flags
5200 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
5202 EventNotification_t *evnp;
5204 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
5206 devtverboseprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
5210 memset(evnp, 0, sizeof(*evnp));
5212 devtverboseprintk((MYIOC_s_INFO_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
5214 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
5215 evnp->ChainOffset = 0;
5217 evnp->Switch = EvSwitch;
5219 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
5224 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5226 * SendEventAck - Send EventAck request to MPT adapter.
5227 * @ioc: Pointer to MPT_ADAPTER structure
5228 * @evnp: Pointer to original EventNotification request
5231 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
5235 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5236 dfailprintk((MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
5237 ioc->name,__FUNCTION__));
5241 devtverboseprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name));
5243 pAck->Function = MPI_FUNCTION_EVENT_ACK;
5244 pAck->ChainOffset = 0;
5245 pAck->Reserved[0] = pAck->Reserved[1] = 0;
5247 pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
5248 pAck->Event = evnp->Event;
5249 pAck->EventContext = evnp->EventContext;
5251 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
5256 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5258 * mpt_config - Generic function to issue config message
5259 * @ioc: Pointer to an adapter structure
5260 * @pCfg: Pointer to a configuration structure. Struct contains
5261 * action, page address, direction, physical address
5262 * and pointer to a configuration page header
5263 * Page header is updated.
5265 * Returns 0 for success
5266 * -EPERM if not allowed due to ISR context
5267 * -EAGAIN if no msg frames currently available
5268 * -EFAULT for non-successful reply or no reply (timeout)
5271 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5274 ConfigExtendedPageHeader_t *pExtHdr = NULL;
5276 unsigned long flags;
5281 /* Prevent calling wait_event() (below), if caller happens
5282 * to be in ISR context, because that is fatal!
5284 in_isr = in_interrupt();
5286 dcprintk((MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
5291 /* Get and Populate a free Frame
5293 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5294 dcprintk((MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
5298 pReq = (Config_t *)mf;
5299 pReq->Action = pCfg->action;
5301 pReq->ChainOffset = 0;
5302 pReq->Function = MPI_FUNCTION_CONFIG;
5304 /* Assume page type is not extended and clear "reserved" fields. */
5305 pReq->ExtPageLength = 0;
5306 pReq->ExtPageType = 0;
5309 for (ii=0; ii < 8; ii++)
5310 pReq->Reserved2[ii] = 0;
5312 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
5313 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
5314 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
5315 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
5317 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5318 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
5319 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
5320 pReq->ExtPageType = pExtHdr->ExtPageType;
5321 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
5323 /* Page Length must be treated as a reserved field for the extended header. */
5324 pReq->Header.PageLength = 0;
5327 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
5329 /* Add a SGE to the config request.
5332 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
5334 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
5336 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5337 flagsLength |= pExtHdr->ExtPageLength * 4;
5339 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
5340 ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action));
5343 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
5345 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
5346 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
5349 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
5351 /* Append pCfg pointer to end of mf
5353 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5355 /* Initalize the timer
5357 init_timer(&pCfg->timer);
5358 pCfg->timer.data = (unsigned long) ioc;
5359 pCfg->timer.function = mpt_timer_expired;
5360 pCfg->wait_done = 0;
5362 /* Set the timer; ensure 10 second minimum */
5363 if (pCfg->timeout < 10)
5364 pCfg->timer.expires = jiffies + HZ*10;
5366 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5368 /* Add to end of Q, set timer and then issue this command */
5369 spin_lock_irqsave(&ioc->FreeQlock, flags);
5370 list_add_tail(&pCfg->linkage, &ioc->configQ);
5371 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5373 add_timer(&pCfg->timer);
5374 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5375 wait_event(mpt_waitq, pCfg->wait_done);
5377 /* mf has been freed - do not access */
5384 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5386 * mpt_timer_expired - Callback for timer process.
5387 * Used only internal config functionality.
5388 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5391 mpt_timer_expired(unsigned long data)
5393 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
5395 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired! \n", ioc->name));
5397 /* Perform a FW reload */
5398 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
5399 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
5401 /* No more processing.
5402 * Hard reset clean-up will wake up
5403 * process and free all resources.
5405 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired complete!\n", ioc->name));
5410 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5412 * mpt_ioc_reset - Base cleanup for hard reset
5413 * @ioc: Pointer to the adapter structure
5414 * @reset_phase: Indicates pre- or post-reset functionality
5416 * Remark: Frees resources with internally generated commands.
5419 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
5422 unsigned long flags;
5424 dprintk((KERN_WARNING MYNAM
5425 ": IOC %s_reset routed to MPT base driver!\n",
5426 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
5427 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
5429 if (reset_phase == MPT_IOC_SETUP_RESET) {
5431 } else if (reset_phase == MPT_IOC_PRE_RESET) {
5432 /* If the internal config Q is not empty -
5433 * delete timer. MF resources will be freed when
5434 * the FIFO's are primed.
5436 spin_lock_irqsave(&ioc->FreeQlock, flags);
5437 list_for_each_entry(pCfg, &ioc->configQ, linkage)
5438 del_timer(&pCfg->timer);
5439 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5444 /* Search the configQ for internal commands.
5445 * Flush the Q, and wake up all suspended threads.
5447 spin_lock_irqsave(&ioc->FreeQlock, flags);
5448 list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
5449 list_del(&pCfg->linkage);
5451 pCfg->status = MPT_CONFIG_ERROR;
5452 pCfg->wait_done = 1;
5453 wake_up(&mpt_waitq);
5455 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5458 return 1; /* currently means nothing really */
5462 #ifdef CONFIG_PROC_FS /* { */
5463 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5465 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5467 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5469 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5471 * Returns 0 for success, non-zero for failure.
5474 procmpt_create(void)
5476 struct proc_dir_entry *ent;
5478 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
5479 if (mpt_proc_root_dir == NULL)
5482 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5484 ent->read_proc = procmpt_summary_read;
5486 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5488 ent->read_proc = procmpt_version_read;
5493 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5495 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5497 * Returns 0 for success, non-zero for failure.
5500 procmpt_destroy(void)
5502 remove_proc_entry("version", mpt_proc_root_dir);
5503 remove_proc_entry("summary", mpt_proc_root_dir);
5504 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
5507 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5509 * procmpt_summary_read - Handle read request of a summary file
5510 * @buf: Pointer to area to write information
5511 * @start: Pointer to start pointer
5512 * @offset: Offset to start writing
5513 * @request: Amount of read data requested
5514 * @eof: Pointer to EOF integer
5517 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
5518 * Returns number of characters written to process performing the read.
5521 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5531 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5535 list_for_each_entry(ioc, &ioc_list, list) {
5538 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5541 if ((out-buf) >= request)
5548 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5551 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5553 * procmpt_version_read - Handle read request from /proc/mpt/version.
5554 * @buf: Pointer to area to write information
5555 * @start: Pointer to start pointer
5556 * @offset: Offset to start writing
5557 * @request: Amount of read data requested
5558 * @eof: Pointer to EOF integer
5561 * Returns number of characters written to process performing the read.
5564 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5567 int scsi, fc, sas, lan, ctl, targ, dmp;
5571 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
5572 len += sprintf(buf+len, " Fusion MPT base driver\n");
5574 scsi = fc = sas = lan = ctl = targ = dmp = 0;
5575 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5577 if (MptCallbacks[ii]) {
5578 switch (MptDriverClass[ii]) {
5580 if (!scsi++) drvname = "SPI host";
5583 if (!fc++) drvname = "FC host";
5586 if (!sas++) drvname = "SAS host";
5589 if (!lan++) drvname = "LAN";
5592 if (!targ++) drvname = "SCSI target";
5595 if (!ctl++) drvname = "ioctl";
5600 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
5604 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5607 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5609 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
5610 * @buf: Pointer to area to write information
5611 * @start: Pointer to start pointer
5612 * @offset: Offset to start writing
5613 * @request: Amount of read data requested
5614 * @eof: Pointer to EOF integer
5617 * Returns number of characters written to process performing the read.
5620 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5622 MPT_ADAPTER *ioc = data;
5628 mpt_get_fw_exp_ver(expVer, ioc);
5630 len = sprintf(buf, "%s:", ioc->name);
5631 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
5632 len += sprintf(buf+len, " (f/w download boot flag set)");
5633 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
5634 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
5636 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
5637 ioc->facts.ProductID,
5639 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
5640 if (ioc->facts.FWImageSize)
5641 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
5642 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
5643 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
5644 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
5646 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
5647 ioc->facts.CurrentHostMfaHighAddr);
5648 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
5649 ioc->facts.CurrentSenseBufferHighAddr);
5651 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
5652 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
5654 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
5655 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
5657 * Rounding UP to nearest 4-kB boundary here...
5659 sz = (ioc->req_sz * ioc->req_depth) + 128;
5660 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
5661 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
5662 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
5663 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
5664 4*ioc->facts.RequestFrameSize,
5665 ioc->facts.GlobalCredits);
5667 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
5668 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
5669 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
5670 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
5671 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
5672 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
5673 ioc->facts.CurReplyFrameSize,
5674 ioc->facts.ReplyQueueDepth);
5676 len += sprintf(buf+len, " MaxDevices = %d\n",
5677 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
5678 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
5681 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
5682 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
5684 ioc->facts.NumberOfPorts);
5685 if (ioc->bus_type == FC) {
5686 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
5687 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5688 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
5689 a[5], a[4], a[3], a[2], a[1], a[0]);
5691 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
5692 ioc->fc_port_page0[p].WWNN.High,
5693 ioc->fc_port_page0[p].WWNN.Low,
5694 ioc->fc_port_page0[p].WWPN.High,
5695 ioc->fc_port_page0[p].WWPN.Low);
5699 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5702 #endif /* CONFIG_PROC_FS } */
5704 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5706 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
5709 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
5710 sprintf(buf, " (Exp %02d%02d)",
5711 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
5712 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
5715 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
5716 strcat(buf, " [MDBG]");
5720 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5722 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
5723 * @ioc: Pointer to MPT_ADAPTER structure
5724 * @buffer: Pointer to buffer where IOC summary info should be written
5725 * @size: Pointer to number of bytes we wrote (set by this routine)
5726 * @len: Offset at which to start writing in buffer
5727 * @showlan: Display LAN stuff?
5729 * This routine writes (english readable) ASCII text, which represents
5730 * a summary of IOC information, to a buffer.
5733 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
5738 mpt_get_fw_exp_ver(expVer, ioc);
5741 * Shorter summary of attached ioc's...
5743 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
5746 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
5747 ioc->facts.FWVersion.Word,
5749 ioc->facts.NumberOfPorts,
5752 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
5753 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5754 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
5755 a[5], a[4], a[3], a[2], a[1], a[0]);
5758 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
5761 y += sprintf(buffer+len+y, " (disabled)");
5763 y += sprintf(buffer+len+y, "\n");
5768 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5772 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5774 * mpt_HardResetHandler - Generic reset handler
5775 * @ioc: Pointer to MPT_ADAPTER structure
5776 * @sleepFlag: Indicates if sleep or schedule must be called.
5778 * Issues SCSI Task Management call based on input arg values.
5779 * If TaskMgmt fails, returns associated SCSI request.
5781 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
5782 * or a non-interrupt thread. In the former, must not call schedule().
5784 * Note: A return of -1 is a FATAL error case, as it means a
5785 * FW reload/initialization failed.
5787 * Returns 0 for SUCCESS or -1 if FAILED.
5790 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
5793 unsigned long flags;
5795 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name));
5797 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
5798 printk("MF count 0x%x !\n", ioc->mfcnt);
5801 /* Reset the adapter. Prevent more than 1 call to
5802 * mpt_do_ioc_recovery at any instant in time.
5804 spin_lock_irqsave(&ioc->diagLock, flags);
5805 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
5806 spin_unlock_irqrestore(&ioc->diagLock, flags);
5809 ioc->diagPending = 1;
5811 spin_unlock_irqrestore(&ioc->diagLock, flags);
5813 /* FIXME: If do_ioc_recovery fails, repeat....
5816 /* The SCSI driver needs to adjust timeouts on all current
5817 * commands prior to the diagnostic reset being issued.
5818 * Prevents timeouts occurring during a diagnostic reset...very bad.
5819 * For all other protocol drivers, this is a no-op.
5825 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5826 if (MptResetHandlers[ii]) {
5827 dtmprintk((MYIOC_s_INFO_FMT "Calling IOC reset_setup handler #%d\n",
5829 r += mpt_signal_reset(ii, ioc, MPT_IOC_SETUP_RESET);
5831 dtmprintk((MYIOC_s_INFO_FMT "Calling alt-%s setup reset handler #%d\n",
5832 ioc->name, ioc->alt_ioc->name, ii));
5833 r += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_SETUP_RESET);
5839 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
5840 printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
5845 ioc->alt_ioc->reload_fw = 0;
5847 spin_lock_irqsave(&ioc->diagLock, flags);
5848 ioc->diagPending = 0;
5850 ioc->alt_ioc->diagPending = 0;
5851 spin_unlock_irqrestore(&ioc->diagLock, flags);
5853 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
5858 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5860 EventDescriptionStr(u8 event, u32 evData0, char *evStr)
5865 case MPI_EVENT_NONE:
5868 case MPI_EVENT_LOG_DATA:
5871 case MPI_EVENT_STATE_CHANGE:
5872 ds = "State Change";
5874 case MPI_EVENT_UNIT_ATTENTION:
5875 ds = "Unit Attention";
5877 case MPI_EVENT_IOC_BUS_RESET:
5878 ds = "IOC Bus Reset";
5880 case MPI_EVENT_EXT_BUS_RESET:
5881 ds = "External Bus Reset";
5883 case MPI_EVENT_RESCAN:
5884 ds = "Bus Rescan Event";
5886 case MPI_EVENT_LINK_STATUS_CHANGE:
5887 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
5888 ds = "Link Status(FAILURE) Change";
5890 ds = "Link Status(ACTIVE) Change";
5892 case MPI_EVENT_LOOP_STATE_CHANGE:
5893 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
5894 ds = "Loop State(LIP) Change";
5895 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
5896 ds = "Loop State(LPE) Change"; /* ??? */
5898 ds = "Loop State(LPB) Change"; /* ??? */
5900 case MPI_EVENT_LOGOUT:
5903 case MPI_EVENT_EVENT_CHANGE:
5909 case MPI_EVENT_INTEGRATED_RAID:
5911 u8 ReasonCode = (u8)(evData0 >> 16);
5912 switch (ReasonCode) {
5913 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
5914 ds = "Integrated Raid: Volume Created";
5916 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
5917 ds = "Integrated Raid: Volume Deleted";
5919 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
5920 ds = "Integrated Raid: Volume Settings Changed";
5922 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
5923 ds = "Integrated Raid: Volume Status Changed";
5925 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
5926 ds = "Integrated Raid: Volume Physdisk Changed";
5928 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
5929 ds = "Integrated Raid: Physdisk Created";
5931 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
5932 ds = "Integrated Raid: Physdisk Deleted";
5934 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
5935 ds = "Integrated Raid: Physdisk Settings Changed";
5937 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
5938 ds = "Integrated Raid: Physdisk Status Changed";
5940 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
5941 ds = "Integrated Raid: Domain Validation Needed";
5943 case MPI_EVENT_RAID_RC_SMART_DATA :
5944 ds = "Integrated Raid; Smart Data";
5946 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
5947 ds = "Integrated Raid: Replace Action Started";
5950 ds = "Integrated Raid";
5955 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
5956 ds = "SCSI Device Status Change";
5958 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
5960 u8 id = (u8)(evData0);
5961 u8 channel = (u8)(evData0 >> 8);
5962 u8 ReasonCode = (u8)(evData0 >> 16);
5963 switch (ReasonCode) {
5964 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
5965 snprintf(evStr, EVENT_DESCR_STR_SZ,
5966 "SAS Device Status Change: Added: "
5967 "id=%d channel=%d", id, channel);
5969 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
5970 snprintf(evStr, EVENT_DESCR_STR_SZ,
5971 "SAS Device Status Change: Deleted: "
5972 "id=%d channel=%d", id, channel);
5974 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
5975 snprintf(evStr, EVENT_DESCR_STR_SZ,
5976 "SAS Device Status Change: SMART Data: "
5977 "id=%d channel=%d", id, channel);
5979 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
5980 snprintf(evStr, EVENT_DESCR_STR_SZ,
5981 "SAS Device Status Change: No Persistancy: "
5982 "id=%d channel=%d", id, channel);
5984 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
5985 snprintf(evStr, EVENT_DESCR_STR_SZ,
5986 "SAS Device Status Change: Unsupported Device "
5987 "Discovered : id=%d channel=%d", id, channel);
5989 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
5990 snprintf(evStr, EVENT_DESCR_STR_SZ,
5991 "SAS Device Status Change: Internal Device "
5992 "Reset : id=%d channel=%d", id, channel);
5994 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
5995 snprintf(evStr, EVENT_DESCR_STR_SZ,
5996 "SAS Device Status Change: Internal Task "
5997 "Abort : id=%d channel=%d", id, channel);
5999 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
6000 snprintf(evStr, EVENT_DESCR_STR_SZ,
6001 "SAS Device Status Change: Internal Abort "
6002 "Task Set : id=%d channel=%d", id, channel);
6004 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
6005 snprintf(evStr, EVENT_DESCR_STR_SZ,
6006 "SAS Device Status Change: Internal Clear "
6007 "Task Set : id=%d channel=%d", id, channel);
6009 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
6010 snprintf(evStr, EVENT_DESCR_STR_SZ,
6011 "SAS Device Status Change: Internal Query "
6012 "Task : id=%d channel=%d", id, channel);
6015 snprintf(evStr, EVENT_DESCR_STR_SZ,
6016 "SAS Device Status Change: Unknown: "
6017 "id=%d channel=%d", id, channel);
6022 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
6023 ds = "Bus Timer Expired";
6025 case MPI_EVENT_QUEUE_FULL:
6027 u16 curr_depth = (u16)(evData0 >> 16);
6028 u8 channel = (u8)(evData0 >> 8);
6029 u8 id = (u8)(evData0);
6031 snprintf(evStr, EVENT_DESCR_STR_SZ,
6032 "Queue Full: channel=%d id=%d depth=%d",
6033 channel, id, curr_depth);
6036 case MPI_EVENT_SAS_SES:
6037 ds = "SAS SES Event";
6039 case MPI_EVENT_PERSISTENT_TABLE_FULL:
6040 ds = "Persistent Table Full";
6042 case MPI_EVENT_SAS_PHY_LINK_STATUS:
6044 u8 LinkRates = (u8)(evData0 >> 8);
6045 u8 PhyNumber = (u8)(evData0);
6046 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
6047 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
6048 switch (LinkRates) {
6049 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
6050 snprintf(evStr, EVENT_DESCR_STR_SZ,
6051 "SAS PHY Link Status: Phy=%d:"
6052 " Rate Unknown",PhyNumber);
6054 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
6055 snprintf(evStr, EVENT_DESCR_STR_SZ,
6056 "SAS PHY Link Status: Phy=%d:"
6057 " Phy Disabled",PhyNumber);
6059 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
6060 snprintf(evStr, EVENT_DESCR_STR_SZ,
6061 "SAS PHY Link Status: Phy=%d:"
6062 " Failed Speed Nego",PhyNumber);
6064 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
6065 snprintf(evStr, EVENT_DESCR_STR_SZ,
6066 "SAS PHY Link Status: Phy=%d:"
6067 " Sata OOB Completed",PhyNumber);
6069 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
6070 snprintf(evStr, EVENT_DESCR_STR_SZ,
6071 "SAS PHY Link Status: Phy=%d:"
6072 " Rate 1.5 Gbps",PhyNumber);
6074 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
6075 snprintf(evStr, EVENT_DESCR_STR_SZ,
6076 "SAS PHY Link Status: Phy=%d:"
6077 " Rate 3.0 Gpbs",PhyNumber);
6080 snprintf(evStr, EVENT_DESCR_STR_SZ,
6081 "SAS PHY Link Status: Phy=%d", PhyNumber);
6086 case MPI_EVENT_SAS_DISCOVERY_ERROR:
6087 ds = "SAS Discovery Error";
6089 case MPI_EVENT_IR_RESYNC_UPDATE:
6091 u8 resync_complete = (u8)(evData0 >> 16);
6092 snprintf(evStr, EVENT_DESCR_STR_SZ,
6093 "IR Resync Update: Complete = %d:",resync_complete);
6098 u8 ReasonCode = (u8)(evData0 >> 16);
6099 switch (ReasonCode) {
6100 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
6101 ds = "IR2: LD State Changed";
6103 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
6104 ds = "IR2: PD State Changed";
6106 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
6107 ds = "IR2: Bad Block Table Full";
6109 case MPI_EVENT_IR2_RC_PD_INSERTED:
6110 ds = "IR2: PD Inserted";
6112 case MPI_EVENT_IR2_RC_PD_REMOVED:
6113 ds = "IR2: PD Removed";
6115 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
6116 ds = "IR2: Foreign CFG Detected";
6118 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
6119 ds = "IR2: Rebuild Medium Error";
6127 case MPI_EVENT_SAS_DISCOVERY:
6130 ds = "SAS Discovery: Start";
6132 ds = "SAS Discovery: Stop";
6135 case MPI_EVENT_LOG_ENTRY_ADDED:
6136 ds = "SAS Log Entry Added";
6139 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
6141 u8 phy_num = (u8)(evData0);
6142 u8 port_num = (u8)(evData0 >> 8);
6143 u8 port_width = (u8)(evData0 >> 16);
6144 u8 primative = (u8)(evData0 >> 24);
6145 snprintf(evStr, EVENT_DESCR_STR_SZ,
6146 "SAS Broadcase Primative: phy=%d port=%d "
6147 "width=%d primative=0x%02x",
6148 phy_num, port_num, port_width, primative);
6152 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
6154 u8 reason = (u8)(evData0);
6155 u8 port_num = (u8)(evData0 >> 8);
6156 u16 handle = le16_to_cpu(evData0 >> 16);
6158 snprintf(evStr, EVENT_DESCR_STR_SZ,
6159 "SAS Initiator Device Status Change: reason=0x%02x "
6160 "port=%d handle=0x%04x",
6161 reason, port_num, handle);
6165 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
6167 u8 max_init = (u8)(evData0);
6168 u8 current_init = (u8)(evData0 >> 8);
6170 snprintf(evStr, EVENT_DESCR_STR_SZ,
6171 "SAS Initiator Device Table Overflow: max initiators=%02d "
6172 "current initators=%02d",
6173 max_init, current_init);
6176 case MPI_EVENT_SAS_SMP_ERROR:
6178 u8 status = (u8)(evData0);
6179 u8 port_num = (u8)(evData0 >> 8);
6180 u8 result = (u8)(evData0 >> 16);
6182 if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
6183 snprintf(evStr, EVENT_DESCR_STR_SZ,
6184 "SAS SMP Error: port=%d result=0x%02x",
6186 else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
6187 snprintf(evStr, EVENT_DESCR_STR_SZ,
6188 "SAS SMP Error: port=%d : CRC Error",
6190 else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
6191 snprintf(evStr, EVENT_DESCR_STR_SZ,
6192 "SAS SMP Error: port=%d : Timeout",
6194 else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
6195 snprintf(evStr, EVENT_DESCR_STR_SZ,
6196 "SAS SMP Error: port=%d : No Destination",
6198 else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
6199 snprintf(evStr, EVENT_DESCR_STR_SZ,
6200 "SAS SMP Error: port=%d : Bad Destination",
6203 snprintf(evStr, EVENT_DESCR_STR_SZ,
6204 "SAS SMP Error: port=%d : status=0x%02x",
6210 * MPT base "custom" events may be added here...
6217 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
6220 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6222 * ProcessEventNotification - Route EventNotificationReply to all event handlers
6223 * @ioc: Pointer to MPT_ADAPTER structure
6224 * @pEventReply: Pointer to EventNotification reply frame
6225 * @evHandlers: Pointer to integer, number of event handlers
6227 * Routes a received EventNotificationReply to all currently registered
6229 * Returns sum of event handlers return values.
6232 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
6240 char evStr[EVENT_DESCR_STR_SZ];
6244 * Do platform normalization of values
6246 event = le32_to_cpu(pEventReply->Event) & 0xFF;
6247 // evCtx = le32_to_cpu(pEventReply->EventContext);
6248 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
6250 evData0 = le32_to_cpu(pEventReply->Data[0]);
6253 EventDescriptionStr(event, evData0, evStr);
6254 devtprintk((MYIOC_s_INFO_FMT "MPT event:(%02Xh) : %s\n",
6259 #if defined(MPT_DEBUG) || defined(MPT_DEBUG_VERBOSE_EVENTS)
6260 printk(KERN_INFO MYNAM ": Event data:\n" KERN_INFO);
6261 for (ii = 0; ii < evDataLen; ii++)
6262 printk(" %08x", le32_to_cpu(pEventReply->Data[ii]));
6267 * Do general / base driver event processing
6270 case MPI_EVENT_EVENT_CHANGE: /* 0A */
6272 u8 evState = evData0 & 0xFF;
6274 /* CHECKME! What if evState unexpectedly says OFF (0)? */
6276 /* Update EventState field in cached IocFacts */
6277 if (ioc->facts.Function) {
6278 ioc->facts.EventState = evState;
6282 case MPI_EVENT_INTEGRATED_RAID:
6283 mptbase_raid_process_event_data(ioc,
6284 (MpiEventDataRaid_t *)pEventReply->Data);
6291 * Should this event be logged? Events are written sequentially.
6292 * When buffer is full, start again at the top.
6294 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
6297 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
6299 ioc->events[idx].event = event;
6300 ioc->events[idx].eventContext = ioc->eventContext;
6302 for (ii = 0; ii < 2; ii++) {
6304 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
6306 ioc->events[idx].data[ii] = 0;
6309 ioc->eventContext++;
6314 * Call each currently registered protocol event handler.
6316 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
6317 if (MptEvHandlers[ii]) {
6318 devtverboseprintk((MYIOC_s_INFO_FMT "Routing Event to event handler #%d\n",
6320 r += (*(MptEvHandlers[ii]))(ioc, pEventReply);
6324 /* FIXME? Examine results here? */
6327 * If needed, send (a single) EventAck.
6329 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
6330 devtverboseprintk((MYIOC_s_WARN_FMT
6331 "EventAck required\n",ioc->name));
6332 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
6333 devtverboseprintk((MYIOC_s_WARN_FMT "SendEventAck returned %d\n",
6338 *evHandlers = handlers;
6342 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6344 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
6345 * @ioc: Pointer to MPT_ADAPTER structure
6346 * @log_info: U32 LogInfo reply word from the IOC
6348 * Refer to lsi/mpi_log_fc.h.
6351 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
6353 char *desc = "unknown";
6355 switch (log_info & 0xFF000000) {
6356 case MPI_IOCLOGINFO_FC_INIT_BASE:
6357 desc = "FCP Initiator";
6359 case MPI_IOCLOGINFO_FC_TARGET_BASE:
6360 desc = "FCP Target";
6362 case MPI_IOCLOGINFO_FC_LAN_BASE:
6365 case MPI_IOCLOGINFO_FC_MSG_BASE:
6366 desc = "MPI Message Layer";
6368 case MPI_IOCLOGINFO_FC_LINK_BASE:
6371 case MPI_IOCLOGINFO_FC_CTX_BASE:
6372 desc = "Context Manager";
6374 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
6375 desc = "Invalid Field Offset";
6377 case MPI_IOCLOGINFO_FC_STATE_CHANGE:
6378 desc = "State Change Info";
6382 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
6383 ioc->name, log_info, desc, (log_info & 0xFFFFFF));
6386 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6388 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
6389 * @ioc: Pointer to MPT_ADAPTER structure
6390 * @mr: Pointer to MPT reply frame
6391 * @log_info: U32 LogInfo word from the IOC
6393 * Refer to lsi/sp_log.h.
6396 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
6398 u32 info = log_info & 0x00FF0000;
6399 char *desc = "unknown";
6403 desc = "bug! MID not found";
6404 if (ioc->reload_fw == 0)
6409 desc = "Parity Error";
6413 desc = "ASYNC Outbound Overrun";
6417 desc = "SYNC Offset Error";
6425 desc = "Msg In Overflow";
6433 desc = "Outbound DMA Overrun";
6437 desc = "Task Management";
6441 desc = "Device Problem";
6445 desc = "Invalid Phase Change";
6449 desc = "Untagged Table Size";
6454 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
6457 /* strings for sas loginfo */
6458 static char *originator_str[] = {
6463 static char *iop_code_str[] = {
6465 "Invalid SAS Address", /* 01h */
6467 "Invalid Page", /* 03h */
6468 "Diag Message Error", /* 04h */
6469 "Task Terminated", /* 05h */
6470 "Enclosure Management", /* 06h */
6471 "Target Mode" /* 07h */
6473 static char *pl_code_str[] = {
6475 "Open Failure", /* 01h */
6476 "Invalid Scatter Gather List", /* 02h */
6477 "Wrong Relative Offset or Frame Length", /* 03h */
6478 "Frame Transfer Error", /* 04h */
6479 "Transmit Frame Connected Low", /* 05h */
6480 "SATA Non-NCQ RW Error Bit Set", /* 06h */
6481 "SATA Read Log Receive Data Error", /* 07h */
6482 "SATA NCQ Fail All Commands After Error", /* 08h */
6483 "SATA Error in Receive Set Device Bit FIS", /* 09h */
6484 "Receive Frame Invalid Message", /* 0Ah */
6485 "Receive Context Message Valid Error", /* 0Bh */
6486 "Receive Frame Current Frame Error", /* 0Ch */
6487 "SATA Link Down", /* 0Dh */
6488 "Discovery SATA Init W IOS", /* 0Eh */
6489 "Config Invalid Page", /* 0Fh */
6490 "Discovery SATA Init Timeout", /* 10h */
6493 "IO Not Yet Executed", /* 13h */
6494 "IO Executed", /* 14h */
6495 "Persistent Reservation Out Not Affiliation "
6497 "Open Transmit DMA Abort", /* 16h */
6498 "IO Device Missing Delay Retry", /* 17h */
6499 "IO Cancelled Due to Recieve Error", /* 18h */
6507 "Enclosure Management" /* 20h */
6509 static char *ir_code_str[] = {
6510 "Raid Action Error", /* 00h */
6520 static char *raid_sub_code_str[] = {
6522 "Volume Creation Failed: Data Passed too "
6524 "Volume Creation Failed: Duplicate Volumes "
6525 "Attempted", /* 02h */
6526 "Volume Creation Failed: Max Number "
6527 "Supported Volumes Exceeded", /* 03h */
6528 "Volume Creation Failed: DMA Error", /* 04h */
6529 "Volume Creation Failed: Invalid Volume Type", /* 05h */
6530 "Volume Creation Failed: Error Reading "
6531 "MFG Page 4", /* 06h */
6532 "Volume Creation Failed: Creating Internal "
6533 "Structures", /* 07h */
6542 "Activation failed: Already Active Volume", /* 10h */
6543 "Activation failed: Unsupported Volume Type", /* 11h */
6544 "Activation failed: Too Many Active Volumes", /* 12h */
6545 "Activation failed: Volume ID in Use", /* 13h */
6546 "Activation failed: Reported Failure", /* 14h */
6547 "Activation failed: Importing a Volume", /* 15h */
6558 "Phys Disk failed: Too Many Phys Disks", /* 20h */
6559 "Phys Disk failed: Data Passed too Large", /* 21h */
6560 "Phys Disk failed: DMA Error", /* 22h */
6561 "Phys Disk failed: Invalid <channel:id>", /* 23h */
6562 "Phys Disk failed: Creating Phys Disk Config "
6575 "Compatibility Error: IR Disabled", /* 30h */
6576 "Compatibility Error: Inquiry Comand Failed", /* 31h */
6577 "Compatibility Error: Device not Direct Access "
6578 "Device ", /* 32h */
6579 "Compatibility Error: Removable Device Found", /* 33h */
6580 "Compatibility Error: Device SCSI Version not "
6581 "2 or Higher", /* 34h */
6582 "Compatibility Error: SATA Device, 48 BIT LBA "
6583 "not Supported", /* 35h */
6584 "Compatibility Error: Device doesn't have "
6585 "512 Byte Block Sizes", /* 36h */
6586 "Compatibility Error: Volume Type Check Failed", /* 37h */
6587 "Compatibility Error: Volume Type is "
6588 "Unsupported by FW", /* 38h */
6589 "Compatibility Error: Disk Drive too Small for "
6590 "use in Volume", /* 39h */
6591 "Compatibility Error: Phys Disk for Create "
6592 "Volume not Found", /* 3Ah */
6593 "Compatibility Error: Too Many or too Few "
6594 "Disks for Volume Type", /* 3Bh */
6595 "Compatibility Error: Disk stripe Sizes "
6596 "Must be 64KB", /* 3Ch */
6597 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
6600 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6602 * mpt_sas_log_info - Log information returned from SAS IOC.
6603 * @ioc: Pointer to MPT_ADAPTER structure
6604 * @log_info: U32 LogInfo reply word from the IOC
6606 * Refer to lsi/mpi_log_sas.h.
6609 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
6611 union loginfo_type {
6620 union loginfo_type sas_loginfo;
6621 char *originator_desc = NULL;
6622 char *code_desc = NULL;
6623 char *sub_code_desc = NULL;
6625 sas_loginfo.loginfo = log_info;
6626 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
6627 (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
6630 originator_desc = originator_str[sas_loginfo.dw.originator];
6632 switch (sas_loginfo.dw.originator) {
6635 if (sas_loginfo.dw.code <
6636 sizeof(iop_code_str)/sizeof(char*))
6637 code_desc = iop_code_str[sas_loginfo.dw.code];
6640 if (sas_loginfo.dw.code <
6641 sizeof(pl_code_str)/sizeof(char*))
6642 code_desc = pl_code_str[sas_loginfo.dw.code];
6645 if (sas_loginfo.dw.code >=
6646 sizeof(ir_code_str)/sizeof(char*))
6648 code_desc = ir_code_str[sas_loginfo.dw.code];
6649 if (sas_loginfo.dw.subcode >=
6650 sizeof(raid_sub_code_str)/sizeof(char*))
6652 if (sas_loginfo.dw.code == 0)
6654 raid_sub_code_str[sas_loginfo.dw.subcode];
6660 if (sub_code_desc != NULL)
6661 printk(MYIOC_s_INFO_FMT
6662 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
6664 ioc->name, log_info, originator_desc, code_desc,
6666 else if (code_desc != NULL)
6667 printk(MYIOC_s_INFO_FMT
6668 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
6669 " SubCode(0x%04x)\n",
6670 ioc->name, log_info, originator_desc, code_desc,
6671 sas_loginfo.dw.subcode);
6673 printk(MYIOC_s_INFO_FMT
6674 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
6675 " SubCode(0x%04x)\n",
6676 ioc->name, log_info, originator_desc,
6677 sas_loginfo.dw.code, sas_loginfo.dw.subcode);
6680 #ifdef MPT_DEBUG_REPLY
6681 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6683 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
6684 * @ioc: Pointer to MPT_ADAPTER structure
6685 * @ioc_status: U32 IOCStatus word from IOC
6686 * @mf: Pointer to MPT request frame
6688 * Refer to lsi/mpi.h.
6691 mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
6693 Config_t *pReq = (Config_t *)mf;
6694 char extend_desc[EVENT_DESCR_STR_SZ];
6699 if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
6700 page_type = pReq->ExtPageType;
6702 page_type = pReq->Header.PageType;
6705 * ignore invalid page messages for GET_NEXT_HANDLE
6707 form = le32_to_cpu(pReq->PageAddress);
6708 if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
6709 if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
6710 page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
6711 page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
6712 if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
6713 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
6716 if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
6717 if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
6718 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
6722 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
6723 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
6724 page_type, pReq->Header.PageNumber, pReq->Action, form);
6726 switch (ioc_status) {
6728 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
6729 desc = "Config Page Invalid Action";
6732 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
6733 desc = "Config Page Invalid Type";
6736 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
6737 desc = "Config Page Invalid Page";
6740 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
6741 desc = "Config Page Invalid Data";
6744 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
6745 desc = "Config Page No Defaults";
6748 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
6749 desc = "Config Page Can't Commit";
6756 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s: %s\n",
6757 ioc->name, ioc_status, desc, extend_desc);
6761 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
6762 * @ioc: Pointer to MPT_ADAPTER structure
6763 * @ioc_status: U32 IOCStatus word from IOC
6764 * @mf: Pointer to MPT request frame
6766 * Refer to lsi/mpi.h.
6769 mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
6771 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
6776 /****************************************************************************/
6777 /* Common IOCStatus values for all replies */
6778 /****************************************************************************/
6780 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
6781 desc = "Invalid Function";
6784 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
6788 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
6789 desc = "Invalid SGL";
6792 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
6793 desc = "Internal Error";
6796 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
6800 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
6801 desc = "Insufficient Resources";
6804 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
6805 desc = "Invalid Field";
6808 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
6809 desc = "Invalid State";
6812 /****************************************************************************/
6813 /* Config IOCStatus values */
6814 /****************************************************************************/
6816 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
6817 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
6818 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
6819 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
6820 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
6821 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
6822 mpt_iocstatus_info_config(ioc, status, mf);
6825 /****************************************************************************/
6826 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
6828 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
6830 /****************************************************************************/
6832 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
6833 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
6834 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
6835 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
6836 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
6837 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
6838 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
6839 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
6840 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
6841 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
6842 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
6843 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
6844 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
6847 /****************************************************************************/
6848 /* SCSI Target values */
6849 /****************************************************************************/
6851 case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
6852 desc = "Target: Priority IO";
6855 case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
6856 desc = "Target: Invalid Port";
6859 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
6860 desc = "Target Invalid IO Index:";
6863 case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
6864 desc = "Target: Aborted";
6867 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
6868 desc = "Target: No Conn Retryable";
6871 case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
6872 desc = "Target: No Connection";
6875 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
6876 desc = "Target: Transfer Count Mismatch";
6879 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
6880 desc = "Target: STS Data not Sent";
6883 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
6884 desc = "Target: Data Offset Error";
6887 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
6888 desc = "Target: Too Much Write Data";
6891 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
6892 desc = "Target: IU Too Short";
6895 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
6896 desc = "Target: ACK NAK Timeout";
6899 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
6900 desc = "Target: Nak Received";
6903 /****************************************************************************/
6904 /* Fibre Channel Direct Access values */
6905 /****************************************************************************/
6907 case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
6908 desc = "FC: Aborted";
6911 case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
6912 desc = "FC: RX ID Invalid";
6915 case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
6916 desc = "FC: DID Invalid";
6919 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
6920 desc = "FC: Node Logged Out";
6923 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
6924 desc = "FC: Exchange Canceled";
6927 /****************************************************************************/
6929 /****************************************************************************/
6931 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
6932 desc = "LAN: Device not Found";
6935 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
6936 desc = "LAN: Device Failure";
6939 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
6940 desc = "LAN: Transmit Error";
6943 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
6944 desc = "LAN: Transmit Aborted";
6947 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
6948 desc = "LAN: Receive Error";
6951 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
6952 desc = "LAN: Receive Aborted";
6955 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
6956 desc = "LAN: Partial Packet";
6959 case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
6960 desc = "LAN: Canceled";
6963 /****************************************************************************/
6964 /* Serial Attached SCSI values */
6965 /****************************************************************************/
6967 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
6968 desc = "SAS: SMP Request Failed";
6971 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
6972 desc = "SAS: SMP Data Overrun";
6983 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s\n", ioc->name, status, desc);
6987 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6988 EXPORT_SYMBOL(mpt_attach);
6989 EXPORT_SYMBOL(mpt_detach);
6991 EXPORT_SYMBOL(mpt_resume);
6992 EXPORT_SYMBOL(mpt_suspend);
6994 EXPORT_SYMBOL(ioc_list);
6995 EXPORT_SYMBOL(mpt_proc_root_dir);
6996 EXPORT_SYMBOL(mpt_register);
6997 EXPORT_SYMBOL(mpt_deregister);
6998 EXPORT_SYMBOL(mpt_event_register);
6999 EXPORT_SYMBOL(mpt_event_deregister);
7000 EXPORT_SYMBOL(mpt_reset_register);
7001 EXPORT_SYMBOL(mpt_reset_deregister);
7002 EXPORT_SYMBOL(mpt_device_driver_register);
7003 EXPORT_SYMBOL(mpt_device_driver_deregister);
7004 EXPORT_SYMBOL(mpt_get_msg_frame);
7005 EXPORT_SYMBOL(mpt_put_msg_frame);
7006 EXPORT_SYMBOL(mpt_free_msg_frame);
7007 EXPORT_SYMBOL(mpt_add_sge);
7008 EXPORT_SYMBOL(mpt_send_handshake_request);
7009 EXPORT_SYMBOL(mpt_verify_adapter);
7010 EXPORT_SYMBOL(mpt_GetIocState);
7011 EXPORT_SYMBOL(mpt_print_ioc_summary);
7012 EXPORT_SYMBOL(mpt_lan_index);
7013 EXPORT_SYMBOL(mpt_stm_index);
7014 EXPORT_SYMBOL(mpt_HardResetHandler);
7015 EXPORT_SYMBOL(mpt_config);
7016 EXPORT_SYMBOL(mpt_findImVolumes);
7017 EXPORT_SYMBOL(mpt_alloc_fw_memory);
7018 EXPORT_SYMBOL(mpt_free_fw_memory);
7019 EXPORT_SYMBOL(mptbase_sas_persist_operation);
7020 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
7022 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7024 * fusion_init - Fusion MPT base driver initialization routine.
7026 * Returns 0 for success, non-zero for failure.
7033 show_mptmod_ver(my_NAME, my_VERSION);
7034 printk(KERN_INFO COPYRIGHT "\n");
7036 for (i = 0; i < MPT_MAX_PROTOCOL_DRIVERS; i++) {
7037 MptCallbacks[i] = NULL;
7038 MptDriverClass[i] = MPTUNKNOWN_DRIVER;
7039 MptEvHandlers[i] = NULL;
7040 MptResetHandlers[i] = NULL;
7043 /* Register ourselves (mptbase) in order to facilitate
7044 * EventNotification handling.
7046 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
7048 /* Register for hard reset handling callbacks.
7050 if (mpt_reset_register(mpt_base_index, mpt_ioc_reset) == 0) {
7051 dprintk((KERN_INFO MYNAM ": Register for IOC reset notification\n"));
7056 #ifdef CONFIG_PROC_FS
7057 (void) procmpt_create();
7062 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7064 * fusion_exit - Perform driver unload cleanup.
7066 * This routine frees all resources associated with each MPT adapter
7067 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
7073 dexitprintk((KERN_INFO MYNAM ": fusion_exit() called!\n"));
7075 mpt_reset_deregister(mpt_base_index);
7077 #ifdef CONFIG_PROC_FS
7082 module_init(fusion_init);
7083 module_exit(fusion_exit);