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 void mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc);
165 static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
166 static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
167 static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
168 static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
170 #ifdef CONFIG_PROC_FS
171 static int procmpt_summary_read(char *buf, char **start, off_t offset,
172 int request, int *eof, void *data);
173 static int procmpt_version_read(char *buf, char **start, off_t offset,
174 int request, int *eof, void *data);
175 static int procmpt_iocinfo_read(char *buf, char **start, off_t offset,
176 int request, int *eof, void *data);
178 static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
180 //int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
181 static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers);
182 #ifdef MPT_DEBUG_REPLY
183 static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
185 static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
186 static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
187 static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
188 static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
189 static void mpt_inactive_raid_list_free(MPT_ADAPTER *ioc);
191 /* module entry point */
192 static int __init fusion_init (void);
193 static void __exit fusion_exit (void);
195 #define CHIPREG_READ32(addr) readl_relaxed(addr)
196 #define CHIPREG_READ32_dmasync(addr) readl(addr)
197 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
198 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
199 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
202 pci_disable_io_access(struct pci_dev *pdev)
206 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
208 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
212 pci_enable_io_access(struct pci_dev *pdev)
216 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
218 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
222 * Process turbo (context) reply...
225 mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
227 MPT_FRAME_HDR *mf = NULL;
228 MPT_FRAME_HDR *mr = NULL;
232 dmfprintk((MYIOC_s_INFO_FMT "Got TURBO reply req_idx=%08x\n",
235 switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
236 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
237 req_idx = pa & 0x0000FFFF;
238 cb_idx = (pa & 0x00FF0000) >> 16;
239 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
241 case MPI_CONTEXT_REPLY_TYPE_LAN:
242 cb_idx = mpt_lan_index;
244 * Blind set of mf to NULL here was fatal
245 * after lan_reply says "freeme"
246 * Fix sort of combined with an optimization here;
247 * added explicit check for case where lan_reply
248 * was just returning 1 and doing nothing else.
249 * For this case skip the callback, but set up
250 * proper mf value first here:-)
252 if ((pa & 0x58000000) == 0x58000000) {
253 req_idx = pa & 0x0000FFFF;
254 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
255 mpt_free_msg_frame(ioc, mf);
260 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
262 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
263 cb_idx = mpt_stm_index;
264 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
271 /* Check for (valid) IO callback! */
272 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
273 MptCallbacks[cb_idx] == NULL) {
274 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
275 __FUNCTION__, ioc->name, cb_idx);
279 if (MptCallbacks[cb_idx](ioc, mf, mr))
280 mpt_free_msg_frame(ioc, mf);
286 mpt_reply(MPT_ADAPTER *ioc, u32 pa)
297 /* non-TURBO reply! Hmmm, something may be up...
298 * Newest turbo reply mechanism; get address
299 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
302 /* Map DMA address of reply header to cpu address.
303 * pa is 32 bits - but the dma address may be 32 or 64 bits
304 * get offset based only only the low addresses
307 reply_dma_low = (pa <<= 1);
308 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
309 (reply_dma_low - ioc->reply_frames_low_dma));
311 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
312 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
313 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
315 dmfprintk((MYIOC_s_INFO_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
316 ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
317 DBG_DUMP_REPLY_FRAME(mr)
319 /* Check/log IOC log info
321 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
322 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
323 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
324 if (ioc->bus_type == FC)
325 mpt_fc_log_info(ioc, log_info);
326 else if (ioc->bus_type == SPI)
327 mpt_spi_log_info(ioc, log_info);
328 else if (ioc->bus_type == SAS)
329 mpt_sas_log_info(ioc, log_info);
332 #ifdef MPT_DEBUG_REPLY
333 if (ioc_stat & MPI_IOCSTATUS_MASK)
334 mpt_iocstatus_info(ioc, (u32)ioc_stat, mf);
337 /* Check for (valid) IO callback! */
338 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
339 MptCallbacks[cb_idx] == NULL) {
340 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
341 __FUNCTION__, ioc->name, cb_idx);
346 freeme = MptCallbacks[cb_idx](ioc, mf, mr);
349 /* Flush (non-TURBO) reply with a WRITE! */
350 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
353 mpt_free_msg_frame(ioc, mf);
357 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
359 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
360 * @irq: irq number (not used)
361 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
363 * This routine is registered via the request_irq() kernel API call,
364 * and handles all interrupts generated from a specific MPT adapter
365 * (also referred to as a IO Controller or IOC).
366 * This routine must clear the interrupt from the adapter and does
367 * so by reading the reply FIFO. Multiple replies may be processed
368 * per single call to this routine.
370 * This routine handles register-level access of the adapter but
371 * dispatches (calls) a protocol-specific callback routine to handle
372 * the protocol-specific details of the MPT request completion.
375 mpt_interrupt(int irq, void *bus_id)
377 MPT_ADAPTER *ioc = bus_id;
378 u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
380 if (pa == 0xFFFFFFFF)
384 * Drain the reply FIFO!
387 if (pa & MPI_ADDRESS_REPLY_A_BIT)
390 mpt_turbo_reply(ioc, pa);
391 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
392 } while (pa != 0xFFFFFFFF);
397 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
399 * mpt_base_reply - MPT base driver's callback routine
400 * @ioc: Pointer to MPT_ADAPTER structure
401 * @mf: Pointer to original MPT request frame
402 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
404 * MPT base driver's callback routine; all base driver
405 * "internal" request/reply processing is routed here.
406 * Currently used for EventNotification and EventAck handling.
408 * Returns 1 indicating original alloc'd request frame ptr
409 * should be freed, or 0 if it shouldn't.
412 mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
417 dmfprintk((MYIOC_s_INFO_FMT "mpt_base_reply() called\n", ioc->name));
419 #if defined(MPT_DEBUG_MSG_FRAME)
420 if (!(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) {
421 dmfprintk((KERN_INFO MYNAM ": Original request frame (@%p) header\n", mf));
422 DBG_DUMP_REQUEST_FRAME_HDR(mf)
426 func = reply->u.hdr.Function;
427 dmfprintk((MYIOC_s_INFO_FMT "mpt_base_reply, Function=%02Xh\n",
430 if (func == MPI_FUNCTION_EVENT_NOTIFICATION) {
431 EventNotificationReply_t *pEvReply = (EventNotificationReply_t *) reply;
435 results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
436 if (results != evHandlers) {
437 /* CHECKME! Any special handling needed here? */
438 devtverboseprintk((MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
439 ioc->name, evHandlers, results));
443 * Hmmm... It seems that EventNotificationReply is an exception
444 * to the rule of one reply per request.
446 if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) {
449 devtverboseprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
450 ioc->name, pEvReply));
453 #ifdef CONFIG_PROC_FS
454 // LogEvent(ioc, pEvReply);
457 } else if (func == MPI_FUNCTION_EVENT_ACK) {
458 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n",
460 } else if (func == MPI_FUNCTION_CONFIG) {
464 dcprintk((MYIOC_s_INFO_FMT "config_complete (mf=%p,mr=%p)\n",
465 ioc->name, mf, reply));
467 pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *)));
470 /* disable timer and remove from linked list */
471 del_timer(&pCfg->timer);
473 spin_lock_irqsave(&ioc->FreeQlock, flags);
474 list_del(&pCfg->linkage);
475 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
478 * If IOC Status is SUCCESS, save the header
479 * and set the status code to GOOD.
481 pCfg->status = MPT_CONFIG_ERROR;
483 ConfigReply_t *pReply = (ConfigReply_t *)reply;
486 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
487 dcprintk((KERN_NOTICE " IOCStatus=%04xh, IOCLogInfo=%08xh\n",
488 status, le32_to_cpu(pReply->IOCLogInfo)));
490 pCfg->status = status;
491 if (status == MPI_IOCSTATUS_SUCCESS) {
492 if ((pReply->Header.PageType &
493 MPI_CONFIG_PAGETYPE_MASK) ==
494 MPI_CONFIG_PAGETYPE_EXTENDED) {
495 pCfg->cfghdr.ehdr->ExtPageLength =
496 le16_to_cpu(pReply->ExtPageLength);
497 pCfg->cfghdr.ehdr->ExtPageType =
500 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
502 /* If this is a regular header, save PageLength. */
503 /* LMP Do this better so not using a reserved field! */
504 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
505 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
506 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
511 * Wake up the original calling thread
516 } else if (func == MPI_FUNCTION_SAS_IO_UNIT_CONTROL) {
517 /* we should be always getting a reply frame */
518 memcpy(ioc->persist_reply_frame, reply,
519 min(MPT_DEFAULT_FRAME_SIZE,
520 4*reply->u.reply.MsgLength));
521 del_timer(&ioc->persist_timer);
522 ioc->persist_wait_done = 1;
525 printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
530 * Conditionally tell caller to free the original
531 * EventNotification/EventAck/unexpected request frame!
536 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
538 * mpt_register - Register protocol-specific main callback handler.
539 * @cbfunc: callback function pointer
540 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
542 * This routine is called by a protocol-specific driver (SCSI host,
543 * LAN, SCSI target) to register its reply callback routine. Each
544 * protocol-specific driver must do this before it will be able to
545 * use any IOC resources, such as obtaining request frames.
547 * NOTES: The SCSI protocol driver currently calls this routine thrice
548 * in order to register separate callbacks; one for "normal" SCSI IO;
549 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
551 * Returns a positive integer valued "handle" in the
552 * range (and S.O.D. order) {N,...,7,6,5,...,1} if successful.
553 * Any non-positive return value (including zero!) should be considered
554 * an error by the caller.
557 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
564 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
565 * (slot/handle 0 is reserved!)
567 for (i = MPT_MAX_PROTOCOL_DRIVERS-1; i; i--) {
568 if (MptCallbacks[i] == NULL) {
569 MptCallbacks[i] = cbfunc;
570 MptDriverClass[i] = dclass;
571 MptEvHandlers[i] = NULL;
580 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
582 * mpt_deregister - Deregister a protocol drivers resources.
583 * @cb_idx: previously registered callback handle
585 * Each protocol-specific driver should call this routine when its
586 * module is unloaded.
589 mpt_deregister(int cb_idx)
591 if ((cb_idx >= 0) && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
592 MptCallbacks[cb_idx] = NULL;
593 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
594 MptEvHandlers[cb_idx] = NULL;
600 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
602 * mpt_event_register - Register protocol-specific event callback
604 * @cb_idx: previously registered (via mpt_register) callback handle
605 * @ev_cbfunc: callback function
607 * This routine can be called by one or more protocol-specific drivers
608 * if/when they choose to be notified of MPT events.
610 * Returns 0 for success.
613 mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc)
615 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
618 MptEvHandlers[cb_idx] = ev_cbfunc;
622 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
624 * mpt_event_deregister - Deregister protocol-specific event callback
626 * @cb_idx: previously registered callback handle
628 * Each protocol-specific driver should call this routine
629 * when it does not (or can no longer) handle events,
630 * or when its module is unloaded.
633 mpt_event_deregister(int cb_idx)
635 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
638 MptEvHandlers[cb_idx] = NULL;
641 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
643 * mpt_reset_register - Register protocol-specific IOC reset handler.
644 * @cb_idx: previously registered (via mpt_register) callback handle
645 * @reset_func: reset function
647 * This routine can be called by one or more protocol-specific drivers
648 * if/when they choose to be notified of IOC resets.
650 * Returns 0 for success.
653 mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func)
655 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
658 MptResetHandlers[cb_idx] = reset_func;
662 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
664 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
665 * @cb_idx: previously registered callback handle
667 * Each protocol-specific driver should call this routine
668 * when it does not (or can no longer) handle IOC reset handling,
669 * or when its module is unloaded.
672 mpt_reset_deregister(int cb_idx)
674 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
677 MptResetHandlers[cb_idx] = NULL;
680 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
682 * mpt_device_driver_register - Register device driver hooks
683 * @dd_cbfunc: driver callbacks struct
684 * @cb_idx: MPT protocol driver index
687 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx)
690 const struct pci_device_id *id;
692 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
695 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
697 /* call per pci device probe entry point */
698 list_for_each_entry(ioc, &ioc_list, list) {
699 id = ioc->pcidev->driver ?
700 ioc->pcidev->driver->id_table : NULL;
701 if (dd_cbfunc->probe)
702 dd_cbfunc->probe(ioc->pcidev, id);
708 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
710 * mpt_device_driver_deregister - DeRegister device driver hooks
711 * @cb_idx: MPT protocol driver index
714 mpt_device_driver_deregister(int cb_idx)
716 struct mpt_pci_driver *dd_cbfunc;
719 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
722 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
724 list_for_each_entry(ioc, &ioc_list, list) {
725 if (dd_cbfunc->remove)
726 dd_cbfunc->remove(ioc->pcidev);
729 MptDeviceDriverHandlers[cb_idx] = NULL;
733 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
735 * mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024)
736 * allocated per MPT adapter.
737 * @handle: Handle of registered MPT protocol driver
738 * @ioc: Pointer to MPT adapter structure
740 * Returns pointer to a MPT request frame or %NULL if none are available
741 * or IOC is not active.
744 mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc)
748 u16 req_idx; /* Request index */
750 /* validate handle and ioc identifier */
754 printk(KERN_WARNING "IOC Not Active! mpt_get_msg_frame returning NULL!\n");
757 /* If interrupts are not attached, do not return a request frame */
761 spin_lock_irqsave(&ioc->FreeQlock, flags);
762 if (!list_empty(&ioc->FreeQ)) {
765 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
766 u.frame.linkage.list);
767 list_del(&mf->u.frame.linkage.list);
768 mf->u.frame.linkage.arg1 = 0;
769 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
770 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
772 req_idx = req_offset / ioc->req_sz;
773 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
774 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
775 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame; /* Default, will be changed if necessary in SG generation */
782 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
786 printk(KERN_WARNING "IOC Active. No free Msg Frames! Count 0x%x Max 0x%x\n", ioc->mfcnt, ioc->req_depth);
788 if (mfcounter == PRINT_MF_COUNT)
789 printk(KERN_INFO "MF Count 0x%x Max 0x%x \n", ioc->mfcnt, ioc->req_depth);
792 dmfprintk((KERN_INFO MYNAM ": %s: mpt_get_msg_frame(%d,%d), got mf=%p\n",
793 ioc->name, handle, ioc->id, mf));
797 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
799 * mpt_put_msg_frame - Send a protocol specific MPT request frame
801 * @handle: Handle of registered MPT protocol driver
802 * @ioc: Pointer to MPT adapter structure
803 * @mf: Pointer to MPT request frame
805 * This routine posts a MPT request frame to the request post FIFO of a
806 * specific MPT adapter.
809 mpt_put_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
813 u16 req_idx; /* Request index */
815 /* ensure values are reset properly! */
816 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
817 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
819 req_idx = req_offset / ioc->req_sz;
820 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
821 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
823 #ifdef MPT_DEBUG_MSG_FRAME
825 u32 *m = mf->u.frame.hwhdr.__hdr;
828 printk(KERN_INFO MYNAM ": %s: About to Put msg frame @ %p:\n" KERN_INFO " ",
830 n = ioc->req_sz/4 - 1;
833 for (ii=0; ii<=n; ii++) {
834 if (ii && ((ii%8)==0))
835 printk("\n" KERN_INFO " ");
836 printk(" %08x", le32_to_cpu(m[ii]));
842 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
843 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]));
844 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
847 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
849 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
850 * @handle: Handle of registered MPT protocol driver
851 * @ioc: Pointer to MPT adapter structure
852 * @mf: Pointer to MPT request frame
854 * This routine places a MPT request frame back on the MPT adapter's
858 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
862 /* Put Request back on FreeQ! */
863 spin_lock_irqsave(&ioc->FreeQlock, flags);
864 mf->u.frame.linkage.arg1 = 0xdeadbeaf; /* signature to know if this mf is freed */
865 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
869 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
872 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
874 * mpt_add_sge - Place a simple SGE at address pAddr.
875 * @pAddr: virtual address for SGE
876 * @flagslength: SGE flags and data transfer length
877 * @dma_addr: Physical address
879 * This routine places a MPT request frame back on the MPT adapter's
883 mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
885 if (sizeof(dma_addr_t) == sizeof(u64)) {
886 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
887 u32 tmp = dma_addr & 0xFFFFFFFF;
889 pSge->FlagsLength = cpu_to_le32(flagslength);
890 pSge->Address.Low = cpu_to_le32(tmp);
891 tmp = (u32) ((u64)dma_addr >> 32);
892 pSge->Address.High = cpu_to_le32(tmp);
895 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
896 pSge->FlagsLength = cpu_to_le32(flagslength);
897 pSge->Address = cpu_to_le32(dma_addr);
901 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
903 * mpt_send_handshake_request - Send MPT request via doorbell handshake method.
904 * @handle: Handle of registered MPT protocol driver
905 * @ioc: Pointer to MPT adapter structure
906 * @reqBytes: Size of the request in bytes
907 * @req: Pointer to MPT request frame
908 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
910 * This routine is used exclusively to send MptScsiTaskMgmt
911 * requests since they are required to be sent via doorbell handshake.
913 * NOTE: It is the callers responsibility to byte-swap fields in the
914 * request which are greater than 1 byte in size.
916 * Returns 0 for success, non-zero for failure.
919 mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
925 /* State is known to be good upon entering
926 * this function so issue the bus reset
931 * Emulate what mpt_put_msg_frame() does /wrt to sanity
932 * setting cb_idx/req_idx. But ONLY if this request
933 * is in proper (pre-alloc'd) request buffer range...
935 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
936 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
937 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
938 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
939 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;
942 /* Make sure there are no doorbells */
943 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
945 CHIPREG_WRITE32(&ioc->chip->Doorbell,
946 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
947 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
949 /* Wait for IOC doorbell int */
950 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
954 /* Read doorbell and check for active bit */
955 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
958 dhsprintk((KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
961 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
963 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
967 /* Send request via doorbell handshake */
968 req_as_bytes = (u8 *) req;
969 for (ii = 0; ii < reqBytes/4; ii++) {
972 word = ((req_as_bytes[(ii*4) + 0] << 0) |
973 (req_as_bytes[(ii*4) + 1] << 8) |
974 (req_as_bytes[(ii*4) + 2] << 16) |
975 (req_as_bytes[(ii*4) + 3] << 24));
976 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
977 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
983 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
988 /* Make sure there are no doorbells */
989 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
994 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
996 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
997 * @ioc: Pointer to MPT adapter structure
998 * @access_control_value: define bits below
999 * @sleepFlag: Specifies whether the process can sleep
1001 * Provides mechanism for the host driver to control the IOC's
1002 * Host Page Buffer access.
1004 * Access Control Value - bits[15:12]
1006 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1007 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1008 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1010 * Returns 0 for success, non-zero for failure.
1014 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1018 /* return if in use */
1019 if (CHIPREG_READ32(&ioc->chip->Doorbell)
1020 & MPI_DOORBELL_ACTIVE)
1023 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1025 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1026 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1027 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1028 (access_control_value<<12)));
1030 /* Wait for IOC to clear Doorbell Status bit */
1031 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1037 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1039 * mpt_host_page_alloc - allocate system memory for the fw
1040 * @ioc: Pointer to pointer to IOC adapter
1041 * @ioc_init: Pointer to ioc init config page
1043 * If we already allocated memory in past, then resend the same pointer.
1044 * Returns 0 for success, non-zero for failure.
1047 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1051 u32 host_page_buffer_sz=0;
1053 if(!ioc->HostPageBuffer) {
1055 host_page_buffer_sz =
1056 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1058 if(!host_page_buffer_sz)
1059 return 0; /* fw doesn't need any host buffers */
1061 /* spin till we get enough memory */
1062 while(host_page_buffer_sz > 0) {
1064 if((ioc->HostPageBuffer = pci_alloc_consistent(
1066 host_page_buffer_sz,
1067 &ioc->HostPageBuffer_dma)) != NULL) {
1069 dinitprintk((MYIOC_s_INFO_FMT
1070 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1071 ioc->name, ioc->HostPageBuffer,
1072 (u32)ioc->HostPageBuffer_dma,
1073 host_page_buffer_sz));
1074 ioc->alloc_total += host_page_buffer_sz;
1075 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1079 host_page_buffer_sz -= (4*1024);
1083 if(!ioc->HostPageBuffer) {
1084 printk(MYIOC_s_ERR_FMT
1085 "Failed to alloc memory for host_page_buffer!\n",
1090 psge = (char *)&ioc_init->HostPageBufferSGE;
1091 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1092 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1093 MPI_SGE_FLAGS_32_BIT_ADDRESSING |
1094 MPI_SGE_FLAGS_HOST_TO_IOC |
1095 MPI_SGE_FLAGS_END_OF_BUFFER;
1096 if (sizeof(dma_addr_t) == sizeof(u64)) {
1097 flags_length |= MPI_SGE_FLAGS_64_BIT_ADDRESSING;
1099 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1100 flags_length |= ioc->HostPageBuffer_sz;
1101 mpt_add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1102 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1107 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1109 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1110 * @iocid: IOC unique identifier (integer)
1111 * @iocpp: Pointer to pointer to IOC adapter
1113 * Given a unique IOC identifier, set pointer to the associated MPT
1114 * adapter structure.
1116 * Returns iocid and sets iocpp if iocid is found.
1117 * Returns -1 if iocid is not found.
1120 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1124 list_for_each_entry(ioc,&ioc_list,list) {
1125 if (ioc->id == iocid) {
1135 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1137 * mpt_attach - Install a PCI intelligent MPT adapter.
1138 * @pdev: Pointer to pci_dev structure
1139 * @id: PCI device ID information
1141 * This routine performs all the steps necessary to bring the IOC of
1142 * a MPT adapter to a OPERATIONAL state. This includes registering
1143 * memory regions, registering the interrupt, and allocating request
1144 * and reply memory pools.
1146 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1149 * Returns 0 for success, non-zero for failure.
1151 * TODO: Add support for polled controllers
1154 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1158 unsigned long mem_phys;
1166 static int mpt_ids = 0;
1167 #ifdef CONFIG_PROC_FS
1168 struct proc_dir_entry *dent, *ent;
1171 if (pci_enable_device(pdev))
1174 dinitprintk((KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1176 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
1177 dprintk((KERN_INFO MYNAM
1178 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n"));
1179 } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
1180 printk(KERN_WARNING MYNAM ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");
1184 if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
1185 dprintk((KERN_INFO MYNAM
1186 ": Using 64 bit consistent mask\n"));
1188 dprintk((KERN_INFO MYNAM
1189 ": Not using 64 bit consistent mask\n"));
1191 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1193 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1196 ioc->alloc_total = sizeof(MPT_ADAPTER);
1197 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1198 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1201 ioc->diagPending = 0;
1202 spin_lock_init(&ioc->diagLock);
1203 spin_lock_init(&ioc->initializing_hba_lock);
1205 /* Initialize the event logging.
1207 ioc->eventTypes = 0; /* None */
1208 ioc->eventContext = 0;
1209 ioc->eventLogSize = 0;
1216 ioc->cached_fw = NULL;
1218 /* Initilize SCSI Config Data structure
1220 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1222 /* Initialize the running configQ head.
1224 INIT_LIST_HEAD(&ioc->configQ);
1226 /* Initialize the fc rport list head.
1228 INIT_LIST_HEAD(&ioc->fc_rports);
1230 /* Find lookup slot. */
1231 INIT_LIST_HEAD(&ioc->list);
1232 ioc->id = mpt_ids++;
1234 mem_phys = msize = 0;
1236 for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1237 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1240 /* Get I/O space! */
1241 port = pci_resource_start(pdev, ii);
1242 psize = pci_resource_len(pdev,ii);
1247 mem_phys = pci_resource_start(pdev, ii);
1248 msize = pci_resource_len(pdev,ii);
1251 ioc->mem_size = msize;
1254 /* Get logical ptr for PciMem0 space */
1255 /*mem = ioremap(mem_phys, msize);*/
1256 mem = ioremap(mem_phys, msize);
1258 printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n");
1263 dinitprintk((KERN_INFO MYNAM ": mem = %p, mem_phys = %lx\n", mem, mem_phys));
1265 dinitprintk((KERN_INFO MYNAM ": facts @ %p, pfacts[0] @ %p\n",
1266 &ioc->facts, &ioc->pfacts[0]));
1268 ioc->mem_phys = mem_phys;
1269 ioc->chip = (SYSIF_REGS __iomem *)mem;
1271 /* Save Port IO values in case we need to do downloadboot */
1273 u8 *pmem = (u8*)port;
1274 ioc->pio_mem_phys = port;
1275 ioc->pio_chip = (SYSIF_REGS __iomem *)pmem;
1278 if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC909) {
1279 ioc->prod_name = "LSIFC909";
1282 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929) {
1283 ioc->prod_name = "LSIFC929";
1286 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919) {
1287 ioc->prod_name = "LSIFC919";
1290 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929X) {
1291 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1293 if (revision < XL_929) {
1294 ioc->prod_name = "LSIFC929X";
1295 /* 929X Chip Fix. Set Split transactions level
1296 * for PCIX. Set MOST bits to zero.
1298 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1300 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1302 ioc->prod_name = "LSIFC929XL";
1303 /* 929XL Chip Fix. Set MMRBC to 0x08.
1305 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1307 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1310 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919X) {
1311 ioc->prod_name = "LSIFC919X";
1313 /* 919X Chip Fix. Set Split transactions level
1314 * for PCIX. Set MOST bits to zero.
1316 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1318 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1320 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC939X) {
1321 ioc->prod_name = "LSIFC939X";
1323 ioc->errata_flag_1064 = 1;
1325 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC949X) {
1326 ioc->prod_name = "LSIFC949X";
1328 ioc->errata_flag_1064 = 1;
1330 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC949E) {
1331 ioc->prod_name = "LSIFC949E";
1334 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {
1335 ioc->prod_name = "LSI53C1030";
1336 ioc->bus_type = SPI;
1337 /* 1030 Chip Fix. Disable Split transactions
1338 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1340 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1341 if (revision < C0_1030) {
1342 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1344 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1347 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_1030_53C1035) {
1348 ioc->prod_name = "LSI53C1035";
1349 ioc->bus_type = SPI;
1351 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064) {
1352 ioc->prod_name = "LSISAS1064";
1353 ioc->bus_type = SAS;
1354 ioc->errata_flag_1064 = 1;
1356 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068) {
1357 ioc->prod_name = "LSISAS1068";
1358 ioc->bus_type = SAS;
1359 ioc->errata_flag_1064 = 1;
1361 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064E) {
1362 ioc->prod_name = "LSISAS1064E";
1363 ioc->bus_type = SAS;
1365 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068E) {
1366 ioc->prod_name = "LSISAS1068E";
1367 ioc->bus_type = SAS;
1369 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
1370 ioc->prod_name = "LSISAS1078";
1371 ioc->bus_type = SAS;
1374 if (ioc->errata_flag_1064)
1375 pci_disable_io_access(pdev);
1377 sprintf(ioc->name, "ioc%d", ioc->id);
1379 spin_lock_init(&ioc->FreeQlock);
1382 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1384 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1386 /* Set lookup ptr. */
1387 list_add_tail(&ioc->list, &ioc_list);
1389 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1391 mpt_detect_bound_ports(ioc, pdev);
1393 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1395 printk(KERN_WARNING MYNAM
1396 ": WARNING - %s did not initialize properly! (%d)\n",
1399 list_del(&ioc->list);
1401 ioc->alt_ioc->alt_ioc = NULL;
1404 pci_set_drvdata(pdev, NULL);
1408 /* call per device driver probe entry point */
1409 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1410 if(MptDeviceDriverHandlers[ii] &&
1411 MptDeviceDriverHandlers[ii]->probe) {
1412 MptDeviceDriverHandlers[ii]->probe(pdev,id);
1416 #ifdef CONFIG_PROC_FS
1418 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1420 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1422 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1424 ent->read_proc = procmpt_iocinfo_read;
1427 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1429 ent->read_proc = procmpt_summary_read;
1438 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1440 * mpt_detach - Remove a PCI intelligent MPT adapter.
1441 * @pdev: Pointer to pci_dev structure
1445 mpt_detach(struct pci_dev *pdev)
1447 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1451 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
1452 remove_proc_entry(pname, NULL);
1453 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
1454 remove_proc_entry(pname, NULL);
1455 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
1456 remove_proc_entry(pname, NULL);
1458 /* call per device driver remove entry point */
1459 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1460 if(MptDeviceDriverHandlers[ii] &&
1461 MptDeviceDriverHandlers[ii]->remove) {
1462 MptDeviceDriverHandlers[ii]->remove(pdev);
1466 /* Disable interrupts! */
1467 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1470 synchronize_irq(pdev->irq);
1472 /* Clear any lingering interrupt */
1473 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1475 CHIPREG_READ32(&ioc->chip->IntStatus);
1477 mpt_adapter_dispose(ioc);
1479 pci_set_drvdata(pdev, NULL);
1482 /**************************************************************************
1486 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1488 * mpt_suspend - Fusion MPT base driver suspend routine.
1489 * @pdev: Pointer to pci_dev structure
1490 * @state: new state to enter
1493 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
1496 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1498 device_state=pci_choose_state(pdev, state);
1500 printk(MYIOC_s_INFO_FMT
1501 "pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
1502 ioc->name, pdev, pci_name(pdev), device_state);
1504 pci_save_state(pdev);
1506 /* put ioc into READY_STATE */
1507 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
1508 printk(MYIOC_s_ERR_FMT
1509 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
1512 /* disable interrupts */
1513 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1516 /* Clear any lingering interrupt */
1517 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1519 pci_disable_device(pdev);
1520 pci_set_power_state(pdev, device_state);
1525 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1527 * mpt_resume - Fusion MPT base driver resume routine.
1528 * @pdev: Pointer to pci_dev structure
1531 mpt_resume(struct pci_dev *pdev)
1533 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1534 u32 device_state = pdev->current_state;
1538 printk(MYIOC_s_INFO_FMT
1539 "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
1540 ioc->name, pdev, pci_name(pdev), device_state);
1542 pci_set_power_state(pdev, 0);
1543 pci_restore_state(pdev);
1544 err = pci_enable_device(pdev);
1548 /* enable interrupts */
1549 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
1552 printk(MYIOC_s_INFO_FMT
1553 "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1555 (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1556 CHIPREG_READ32(&ioc->chip->Doorbell));
1558 /* bring ioc to operational state */
1559 if ((recovery_state = mpt_do_ioc_recovery(ioc,
1560 MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {
1561 printk(MYIOC_s_INFO_FMT
1562 "pci-resume: Cannot recover, error:[%x]\n",
1563 ioc->name, recovery_state);
1565 printk(MYIOC_s_INFO_FMT
1566 "pci-resume: success\n", ioc->name);
1574 mpt_signal_reset(int index, MPT_ADAPTER *ioc, int reset_phase)
1576 if ((MptDriverClass[index] == MPTSPI_DRIVER &&
1577 ioc->bus_type != SPI) ||
1578 (MptDriverClass[index] == MPTFC_DRIVER &&
1579 ioc->bus_type != FC) ||
1580 (MptDriverClass[index] == MPTSAS_DRIVER &&
1581 ioc->bus_type != SAS))
1582 /* make sure we only call the relevant reset handler
1585 return (MptResetHandlers[index])(ioc, reset_phase);
1588 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1590 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1591 * @ioc: Pointer to MPT adapter structure
1592 * @reason: Event word / reason
1593 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1595 * This routine performs all the steps necessary to bring the IOC
1596 * to a OPERATIONAL state.
1598 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1603 * -1 if failed to get board READY
1604 * -2 if READY but IOCFacts Failed
1605 * -3 if READY but PrimeIOCFifos Failed
1606 * -4 if READY but IOCInit Failed
1609 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1611 int hard_reset_done = 0;
1612 int alt_ioc_ready = 0;
1618 int reset_alt_ioc_active = 0;
1619 int irq_allocated = 0;
1621 printk(KERN_INFO MYNAM ": Initiating %s %s\n",
1622 ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
1624 /* Disable reply interrupts (also blocks FreeQ) */
1625 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1629 if (ioc->alt_ioc->active)
1630 reset_alt_ioc_active = 1;
1632 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1633 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
1634 ioc->alt_ioc->active = 0;
1638 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
1641 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
1642 if (hard_reset_done == -4) {
1643 printk(KERN_WARNING MYNAM ": %s Owned by PEER..skipping!\n",
1646 if (reset_alt_ioc_active && ioc->alt_ioc) {
1647 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1648 dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1649 ioc->alt_ioc->name));
1650 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
1651 ioc->alt_ioc->active = 1;
1655 printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",
1661 /* hard_reset_done = 0 if a soft reset was performed
1662 * and 1 if a hard reset was performed.
1664 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
1665 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
1668 printk(KERN_WARNING MYNAM
1669 ": alt-%s: Not ready WARNING!\n",
1670 ioc->alt_ioc->name);
1673 for (ii=0; ii<5; ii++) {
1674 /* Get IOC facts! Allow 5 retries */
1675 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
1681 dinitprintk((MYIOC_s_INFO_FMT "Retry IocFacts failed rc=%x\n", ioc->name, rc));
1683 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1684 MptDisplayIocCapabilities(ioc);
1687 if (alt_ioc_ready) {
1688 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
1689 dinitprintk((MYIOC_s_INFO_FMT "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
1690 /* Retry - alt IOC was initialized once
1692 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
1695 dinitprintk((MYIOC_s_INFO_FMT "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
1697 reset_alt_ioc_active = 0;
1698 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1699 MptDisplayIocCapabilities(ioc->alt_ioc);
1704 * Device is reset now. It must have de-asserted the interrupt line
1705 * (if it was asserted) and it should be safe to register for the
1708 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1710 if (ioc->pcidev->irq) {
1711 if (mpt_msi_enable && !pci_enable_msi(ioc->pcidev))
1712 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
1714 rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
1715 IRQF_SHARED, ioc->name, ioc);
1717 printk(MYIOC_s_ERR_FMT "Unable to allocate "
1718 "interrupt %d!\n", ioc->name,
1721 pci_disable_msi(ioc->pcidev);
1725 ioc->pci_irq = ioc->pcidev->irq;
1726 pci_set_master(ioc->pcidev); /* ?? */
1727 pci_set_drvdata(ioc->pcidev, ioc);
1728 dprintk((KERN_INFO MYNAM ": %s installed at interrupt "
1729 "%d\n", ioc->name, ioc->pcidev->irq));
1733 /* Prime reply & request queues!
1734 * (mucho alloc's) Must be done prior to
1735 * init as upper addresses are needed for init.
1736 * If fails, continue with alt-ioc processing
1738 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
1741 /* May need to check/upload firmware & data here!
1742 * If fails, continue with alt-ioc processing
1744 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
1747 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
1748 printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
1749 ioc->alt_ioc->name, rc);
1751 reset_alt_ioc_active = 0;
1754 if (alt_ioc_ready) {
1755 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
1757 reset_alt_ioc_active = 0;
1758 printk(KERN_WARNING MYNAM
1759 ": alt-%s: (%d) init failure WARNING!\n",
1760 ioc->alt_ioc->name, rc);
1764 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
1765 if (ioc->upload_fw) {
1766 ddlprintk((MYIOC_s_INFO_FMT
1767 "firmware upload required!\n", ioc->name));
1769 /* Controller is not operational, cannot do upload
1772 rc = mpt_do_upload(ioc, sleepFlag);
1774 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
1776 * Maintain only one pointer to FW memory
1777 * so there will not be two attempt to
1778 * downloadboot onboard dual function
1779 * chips (mpt_adapter_disable,
1782 ddlprintk((MYIOC_s_INFO_FMT ": mpt_upload: alt_%s has cached_fw=%p \n",
1783 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
1784 ioc->alt_ioc->cached_fw = NULL;
1787 printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
1795 /* Enable! (reply interrupt) */
1796 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
1800 if (reset_alt_ioc_active && ioc->alt_ioc) {
1801 /* (re)Enable alt-IOC! (reply interrupt) */
1802 dinitprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1803 ioc->alt_ioc->name));
1804 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
1805 ioc->alt_ioc->active = 1;
1808 /* Enable MPT base driver management of EventNotification
1809 * and EventAck handling.
1811 if ((ret == 0) && (!ioc->facts.EventState))
1812 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
1814 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
1815 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
1817 /* Add additional "reason" check before call to GetLanConfigPages
1818 * (combined with GetIoUnitPage2 call). This prevents a somewhat
1819 * recursive scenario; GetLanConfigPages times out, timer expired
1820 * routine calls HardResetHandler, which calls into here again,
1821 * and we try GetLanConfigPages again...
1823 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1826 * Initalize link list for inactive raid volumes.
1828 init_MUTEX(&ioc->raid_data.inactive_list_mutex);
1829 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
1831 if (ioc->bus_type == SAS) {
1833 /* clear persistency table */
1834 if(ioc->facts.IOCExceptions &
1835 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
1836 ret = mptbase_sas_persist_operation(ioc,
1837 MPI_SAS_OP_CLEAR_NOT_PRESENT);
1844 mpt_findImVolumes(ioc);
1846 } else if (ioc->bus_type == FC) {
1847 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
1848 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
1850 * Pre-fetch the ports LAN MAC address!
1851 * (LANPage1_t stuff)
1853 (void) GetLanConfigPages(ioc);
1856 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
1857 dprintk((MYIOC_s_INFO_FMT "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
1858 ioc->name, a[5], a[4], a[3], a[2], a[1], a[0] ));
1863 /* Get NVRAM and adapter maximums from SPP 0 and 2
1865 mpt_GetScsiPortSettings(ioc, 0);
1867 /* Get version and length of SDP 1
1869 mpt_readScsiDevicePageHeaders(ioc, 0);
1873 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
1874 mpt_findImVolumes(ioc);
1876 /* Check, and possibly reset, the coalescing value
1878 mpt_read_ioc_pg_1(ioc);
1880 mpt_read_ioc_pg_4(ioc);
1883 GetIoUnitPage2(ioc);
1884 mpt_get_manufacturing_pg_0(ioc);
1888 * Call each currently registered protocol IOC reset handler
1889 * with post-reset indication.
1890 * NOTE: If we're doing _IOC_BRINGUP, there can be no
1891 * MptResetHandlers[] registered yet.
1893 if (hard_reset_done) {
1895 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
1896 if ((ret == 0) && MptResetHandlers[ii]) {
1897 dprintk((MYIOC_s_INFO_FMT "Calling IOC post_reset handler #%d\n",
1899 rc += mpt_signal_reset(ii, ioc, MPT_IOC_POST_RESET);
1903 if (alt_ioc_ready && MptResetHandlers[ii]) {
1904 drsprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",
1905 ioc->name, ioc->alt_ioc->name, ii));
1906 rc += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_POST_RESET);
1910 /* FIXME? Examine results here? */
1914 if ((ret != 0) && irq_allocated) {
1915 free_irq(ioc->pci_irq, ioc);
1917 pci_disable_msi(ioc->pcidev);
1922 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1924 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
1925 * @ioc: Pointer to MPT adapter structure
1926 * @pdev: Pointer to (struct pci_dev) structure
1928 * Search for PCI bus/dev_function which matches
1929 * PCI bus/dev_function (+/-1) for newly discovered 929,
1930 * 929X, 1030 or 1035.
1932 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
1933 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
1936 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
1938 struct pci_dev *peer=NULL;
1939 unsigned int slot = PCI_SLOT(pdev->devfn);
1940 unsigned int func = PCI_FUNC(pdev->devfn);
1941 MPT_ADAPTER *ioc_srch;
1943 dprintk((MYIOC_s_INFO_FMT "PCI device %s devfn=%x/%x,"
1944 " searching for devfn match on %x or %x\n",
1945 ioc->name, pci_name(pdev), pdev->bus->number,
1946 pdev->devfn, func-1, func+1));
1948 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
1950 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
1955 list_for_each_entry(ioc_srch, &ioc_list, list) {
1956 struct pci_dev *_pcidev = ioc_srch->pcidev;
1957 if (_pcidev == peer) {
1958 /* Paranoia checks */
1959 if (ioc->alt_ioc != NULL) {
1960 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1961 ioc->name, ioc->alt_ioc->name);
1963 } else if (ioc_srch->alt_ioc != NULL) {
1964 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1965 ioc_srch->name, ioc_srch->alt_ioc->name);
1968 dprintk((KERN_INFO MYNAM ": FOUND! binding %s <==> %s\n",
1969 ioc->name, ioc_srch->name));
1970 ioc_srch->alt_ioc = ioc;
1971 ioc->alt_ioc = ioc_srch;
1977 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1979 * mpt_adapter_disable - Disable misbehaving MPT adapter.
1980 * @ioc: Pointer to MPT adapter structure
1983 mpt_adapter_disable(MPT_ADAPTER *ioc)
1988 if (ioc->cached_fw != NULL) {
1989 ddlprintk((KERN_INFO MYNAM ": mpt_adapter_disable: Pushing FW onto adapter\n"));
1990 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)ioc->cached_fw, NO_SLEEP)) < 0) {
1991 printk(KERN_WARNING MYNAM
1992 ": firmware downloadboot failure (%d)!\n", ret);
1996 /* Disable adapter interrupts! */
1997 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1999 /* Clear any lingering interrupt */
2000 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2002 if (ioc->alloc != NULL) {
2004 dexitprintk((KERN_INFO MYNAM ": %s.free @ %p, sz=%d bytes\n",
2005 ioc->name, ioc->alloc, ioc->alloc_sz));
2006 pci_free_consistent(ioc->pcidev, sz,
2007 ioc->alloc, ioc->alloc_dma);
2008 ioc->reply_frames = NULL;
2009 ioc->req_frames = NULL;
2011 ioc->alloc_total -= sz;
2014 if (ioc->sense_buf_pool != NULL) {
2015 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2016 pci_free_consistent(ioc->pcidev, sz,
2017 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2018 ioc->sense_buf_pool = NULL;
2019 ioc->alloc_total -= sz;
2022 if (ioc->events != NULL){
2023 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2026 ioc->alloc_total -= sz;
2029 if (ioc->cached_fw != NULL) {
2030 sz = ioc->facts.FWImageSize;
2031 pci_free_consistent(ioc->pcidev, sz,
2032 ioc->cached_fw, ioc->cached_fw_dma);
2033 ioc->cached_fw = NULL;
2034 ioc->alloc_total -= sz;
2037 kfree(ioc->spi_data.nvram);
2038 mpt_inactive_raid_list_free(ioc);
2039 kfree(ioc->raid_data.pIocPg2);
2040 kfree(ioc->raid_data.pIocPg3);
2041 ioc->spi_data.nvram = NULL;
2042 ioc->raid_data.pIocPg3 = NULL;
2044 if (ioc->spi_data.pIocPg4 != NULL) {
2045 sz = ioc->spi_data.IocPg4Sz;
2046 pci_free_consistent(ioc->pcidev, sz,
2047 ioc->spi_data.pIocPg4,
2048 ioc->spi_data.IocPg4_dma);
2049 ioc->spi_data.pIocPg4 = NULL;
2050 ioc->alloc_total -= sz;
2053 if (ioc->ReqToChain != NULL) {
2054 kfree(ioc->ReqToChain);
2055 kfree(ioc->RequestNB);
2056 ioc->ReqToChain = NULL;
2059 kfree(ioc->ChainToChain);
2060 ioc->ChainToChain = NULL;
2062 if (ioc->HostPageBuffer != NULL) {
2063 if((ret = mpt_host_page_access_control(ioc,
2064 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2065 printk(KERN_ERR MYNAM
2066 ": %s: host page buffers free failed (%d)!\n",
2069 dexitprintk((KERN_INFO MYNAM ": %s HostPageBuffer free @ %p, sz=%d bytes\n",
2070 ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
2071 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2072 ioc->HostPageBuffer,
2073 ioc->HostPageBuffer_dma);
2074 ioc->HostPageBuffer = NULL;
2075 ioc->HostPageBuffer_sz = 0;
2076 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2080 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2082 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2083 * @ioc: Pointer to MPT adapter structure
2085 * This routine unregisters h/w resources and frees all alloc'd memory
2086 * associated with a MPT adapter structure.
2089 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2091 int sz_first, sz_last;
2096 sz_first = ioc->alloc_total;
2098 mpt_adapter_disable(ioc);
2100 if (ioc->pci_irq != -1) {
2101 free_irq(ioc->pci_irq, ioc);
2103 pci_disable_msi(ioc->pcidev);
2107 if (ioc->memmap != NULL) {
2108 iounmap(ioc->memmap);
2112 #if defined(CONFIG_MTRR) && 0
2113 if (ioc->mtrr_reg > 0) {
2114 mtrr_del(ioc->mtrr_reg, 0, 0);
2115 dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name));
2119 /* Zap the adapter lookup ptr! */
2120 list_del(&ioc->list);
2122 sz_last = ioc->alloc_total;
2123 dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
2124 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2127 ioc->alt_ioc->alt_ioc = NULL;
2132 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2134 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2135 * @ioc: Pointer to MPT adapter structure
2138 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2142 printk(KERN_INFO "%s: ", ioc->name);
2143 if (ioc->prod_name && strlen(ioc->prod_name) > 3)
2144 printk("%s: ", ioc->prod_name+3);
2145 printk("Capabilities={");
2147 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2148 printk("Initiator");
2152 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2153 printk("%sTarget", i ? "," : "");
2157 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2158 printk("%sLAN", i ? "," : "");
2164 * This would probably evoke more questions than it's worth
2166 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2167 printk("%sLogBusAddr", i ? "," : "");
2175 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2177 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2178 * @ioc: Pointer to MPT_ADAPTER structure
2179 * @force: Force hard KickStart of IOC
2180 * @sleepFlag: Specifies whether the process can sleep
2183 * 1 - DIAG reset and READY
2184 * 0 - READY initially OR soft reset and READY
2185 * -1 - Any failure on KickStart
2186 * -2 - Msg Unit Reset Failed
2187 * -3 - IO Unit Reset Failed
2188 * -4 - IOC owned by a PEER
2191 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2196 int hard_reset_done = 0;
2201 /* Get current [raw] IOC state */
2202 ioc_state = mpt_GetIocState(ioc, 0);
2203 dhsprintk((KERN_INFO MYNAM "::MakeIocReady, %s [raw] state=%08x\n", ioc->name, ioc_state));
2206 * Check to see if IOC got left/stuck in doorbell handshake
2207 * grip of death. If so, hard reset the IOC.
2209 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2211 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2215 /* Is it already READY? */
2216 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
2220 * Check to see if IOC is in FAULT state.
2222 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2224 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2226 printk(KERN_WARNING " FAULT code = %04xh\n",
2227 ioc_state & MPI_DOORBELL_DATA_MASK);
2231 * Hmmm... Did it get left operational?
2233 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2234 dinitprintk((MYIOC_s_INFO_FMT "IOC operational unexpected\n",
2238 * If PCI Peer, exit.
2239 * Else, if no fault conditions are present, issue a MessageUnitReset
2240 * Else, fall through to KickStart case
2242 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2243 dinitprintk((KERN_INFO MYNAM
2244 ": whoinit 0x%x statefault %d force %d\n",
2245 whoinit, statefault, force));
2246 if (whoinit == MPI_WHOINIT_PCI_PEER)
2249 if ((statefault == 0 ) && (force == 0)) {
2250 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2257 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2258 if (hard_reset_done < 0)
2262 * Loop here waiting for IOC to come READY.
2265 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2267 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2268 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2270 * BIOS or previous driver load left IOC in OP state.
2271 * Reset messaging FIFOs.
2273 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2274 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2277 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2279 * Something is wrong. Try to get IOC back
2282 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2283 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2290 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2291 ioc->name, (int)((ii+5)/HZ));
2295 if (sleepFlag == CAN_SLEEP) {
2298 mdelay (1); /* 1 msec delay */
2303 if (statefault < 3) {
2304 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2306 statefault==1 ? "stuck handshake" : "IOC FAULT");
2309 return hard_reset_done;
2312 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2314 * mpt_GetIocState - Get the current state of a MPT adapter.
2315 * @ioc: Pointer to MPT_ADAPTER structure
2316 * @cooked: Request raw or cooked IOC state
2318 * Returns all IOC Doorbell register bits if cooked==0, else just the
2319 * Doorbell bits in MPI_IOC_STATE_MASK.
2322 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2327 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2328 // dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
2329 sc = s & MPI_IOC_STATE_MASK;
2332 ioc->last_state = sc;
2334 return cooked ? sc : s;
2337 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2339 * GetIocFacts - Send IOCFacts request to MPT adapter.
2340 * @ioc: Pointer to MPT_ADAPTER structure
2341 * @sleepFlag: Specifies whether the process can sleep
2342 * @reason: If recovery, only update facts.
2344 * Returns 0 for success, non-zero for failure.
2347 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2349 IOCFacts_t get_facts;
2350 IOCFactsReply_t *facts;
2358 /* IOC *must* NOT be in RESET state! */
2359 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2360 printk(KERN_ERR MYNAM ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
2366 facts = &ioc->facts;
2368 /* Destination (reply area)... */
2369 reply_sz = sizeof(*facts);
2370 memset(facts, 0, reply_sz);
2372 /* Request area (get_facts on the stack right now!) */
2373 req_sz = sizeof(get_facts);
2374 memset(&get_facts, 0, req_sz);
2376 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2377 /* Assert: All other get_facts fields are zero! */
2379 dinitprintk((MYIOC_s_INFO_FMT
2380 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2381 ioc->name, req_sz, reply_sz));
2383 /* No non-zero fields in the get_facts request are greater than
2384 * 1 byte in size, so we can just fire it off as is.
2386 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2387 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2392 * Now byte swap (GRRR) the necessary fields before any further
2393 * inspection of reply contents.
2395 * But need to do some sanity checks on MsgLength (byte) field
2396 * to make sure we don't zero IOC's req_sz!
2398 /* Did we get a valid reply? */
2399 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2400 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2402 * If not been here, done that, save off first WhoInit value
2404 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2405 ioc->FirstWhoInit = facts->WhoInit;
2408 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2409 facts->MsgContext = le32_to_cpu(facts->MsgContext);
2410 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2411 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2412 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2413 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
2414 /* CHECKME! IOCStatus, IOCLogInfo */
2416 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2417 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2420 * FC f/w version changed between 1.1 and 1.2
2421 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2422 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2424 if (facts->MsgVersion < 0x0102) {
2426 * Handle old FC f/w style, convert to new...
2428 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2429 facts->FWVersion.Word =
2430 ((oldv<<12) & 0xFF000000) |
2431 ((oldv<<8) & 0x000FFF00);
2433 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2435 facts->ProductID = le16_to_cpu(facts->ProductID);
2436 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
2437 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
2438 ioc->ir_firmware = 1;
2439 facts->CurrentHostMfaHighAddr =
2440 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2441 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2442 facts->CurrentSenseBufferHighAddr =
2443 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2444 facts->CurReplyFrameSize =
2445 le16_to_cpu(facts->CurReplyFrameSize);
2446 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
2449 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2450 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2451 * to 14 in MPI-1.01.0x.
2453 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2454 facts->MsgVersion > 0x0100) {
2455 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2458 sz = facts->FWImageSize;
2463 facts->FWImageSize = sz;
2465 if (!facts->RequestFrameSize) {
2466 /* Something is wrong! */
2467 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2472 r = sz = facts->BlockSize;
2473 vv = ((63 / (sz * 4)) + 1) & 0x03;
2474 ioc->NB_for_64_byte_frame = vv;
2480 ioc->NBShiftFactor = shiftFactor;
2481 dinitprintk((MYIOC_s_INFO_FMT "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2482 ioc->name, vv, shiftFactor, r));
2484 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2486 * Set values for this IOC's request & reply frame sizes,
2487 * and request & reply queue depths...
2489 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2490 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2491 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2492 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2494 dinitprintk((MYIOC_s_INFO_FMT "reply_sz=%3d, reply_depth=%4d\n",
2495 ioc->name, ioc->reply_sz, ioc->reply_depth));
2496 dinitprintk((MYIOC_s_INFO_FMT "req_sz =%3d, req_depth =%4d\n",
2497 ioc->name, ioc->req_sz, ioc->req_depth));
2499 /* Get port facts! */
2500 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2504 printk(MYIOC_s_ERR_FMT
2505 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2506 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2507 RequestFrameSize)/sizeof(u32)));
2514 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2516 * GetPortFacts - Send PortFacts request to MPT adapter.
2517 * @ioc: Pointer to MPT_ADAPTER structure
2518 * @portnum: Port number
2519 * @sleepFlag: Specifies whether the process can sleep
2521 * Returns 0 for success, non-zero for failure.
2524 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2526 PortFacts_t get_pfacts;
2527 PortFactsReply_t *pfacts;
2533 /* IOC *must* NOT be in RESET state! */
2534 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2535 printk(KERN_ERR MYNAM ": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n",
2541 pfacts = &ioc->pfacts[portnum];
2543 /* Destination (reply area)... */
2544 reply_sz = sizeof(*pfacts);
2545 memset(pfacts, 0, reply_sz);
2547 /* Request area (get_pfacts on the stack right now!) */
2548 req_sz = sizeof(get_pfacts);
2549 memset(&get_pfacts, 0, req_sz);
2551 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2552 get_pfacts.PortNumber = portnum;
2553 /* Assert: All other get_pfacts fields are zero! */
2555 dinitprintk((MYIOC_s_INFO_FMT "Sending get PortFacts(%d) request\n",
2556 ioc->name, portnum));
2558 /* No non-zero fields in the get_pfacts request are greater than
2559 * 1 byte in size, so we can just fire it off as is.
2561 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2562 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2566 /* Did we get a valid reply? */
2568 /* Now byte swap the necessary fields in the response. */
2569 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2570 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2571 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2572 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2573 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2574 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2575 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2576 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2577 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2579 max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
2581 ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
2582 ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
2585 * Place all the devices on channels
2589 if (mpt_channel_mapping) {
2590 ioc->devices_per_bus = 1;
2591 ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
2597 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2599 * SendIocInit - Send IOCInit request to MPT adapter.
2600 * @ioc: Pointer to MPT_ADAPTER structure
2601 * @sleepFlag: Specifies whether the process can sleep
2603 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2605 * Returns 0 for success, non-zero for failure.
2608 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2611 MPIDefaultReply_t init_reply;
2617 memset(&ioc_init, 0, sizeof(ioc_init));
2618 memset(&init_reply, 0, sizeof(init_reply));
2620 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2621 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2623 /* If we are in a recovery mode and we uploaded the FW image,
2624 * then this pointer is not NULL. Skip the upload a second time.
2625 * Set this flag if cached_fw set for either IOC.
2627 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
2631 ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n",
2632 ioc->name, ioc->upload_fw, ioc->facts.Flags));
2634 ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
2635 ioc_init.MaxBuses = (U8)ioc->number_of_buses;
2636 dinitprintk((MYIOC_s_INFO_FMT "facts.MsgVersion=%x\n",
2637 ioc->name, ioc->facts.MsgVersion));
2638 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
2639 // set MsgVersion and HeaderVersion host driver was built with
2640 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
2641 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
2643 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
2644 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
2645 } else if(mpt_host_page_alloc(ioc, &ioc_init))
2648 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
2650 if (sizeof(dma_addr_t) == sizeof(u64)) {
2651 /* Save the upper 32-bits of the request
2652 * (reply) and sense buffers.
2654 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
2655 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2657 /* Force 32-bit addressing */
2658 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
2659 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
2662 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
2663 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
2664 ioc->facts.MaxDevices = ioc_init.MaxDevices;
2665 ioc->facts.MaxBuses = ioc_init.MaxBuses;
2667 dhsprintk((MYIOC_s_INFO_FMT "Sending IOCInit (req @ %p)\n",
2668 ioc->name, &ioc_init));
2670 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
2671 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
2673 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
2677 /* No need to byte swap the multibyte fields in the reply
2678 * since we don't even look at its contents.
2681 dhsprintk((MYIOC_s_INFO_FMT "Sending PortEnable (req @ %p)\n",
2682 ioc->name, &ioc_init));
2684 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
2685 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
2689 /* YIKES! SUPER IMPORTANT!!!
2690 * Poll IocState until _OPERATIONAL while IOC is doing
2691 * LoopInit and TargetDiscovery!
2694 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
2695 state = mpt_GetIocState(ioc, 1);
2696 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
2697 if (sleepFlag == CAN_SLEEP) {
2704 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
2705 ioc->name, (int)((count+5)/HZ));
2709 state = mpt_GetIocState(ioc, 1);
2712 dinitprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
2715 ioc->aen_event_read_flag=0;
2719 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2721 * SendPortEnable - Send PortEnable request to MPT adapter port.
2722 * @ioc: Pointer to MPT_ADAPTER structure
2723 * @portnum: Port number to enable
2724 * @sleepFlag: Specifies whether the process can sleep
2726 * Send PortEnable to bring IOC to OPERATIONAL state.
2728 * Returns 0 for success, non-zero for failure.
2731 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2733 PortEnable_t port_enable;
2734 MPIDefaultReply_t reply_buf;
2739 /* Destination... */
2740 reply_sz = sizeof(MPIDefaultReply_t);
2741 memset(&reply_buf, 0, reply_sz);
2743 req_sz = sizeof(PortEnable_t);
2744 memset(&port_enable, 0, req_sz);
2746 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
2747 port_enable.PortNumber = portnum;
2748 /* port_enable.ChainOffset = 0; */
2749 /* port_enable.MsgFlags = 0; */
2750 /* port_enable.MsgContext = 0; */
2752 dinitprintk((MYIOC_s_INFO_FMT "Sending Port(%d)Enable (req @ %p)\n",
2753 ioc->name, portnum, &port_enable));
2755 /* RAID FW may take a long time to enable
2757 if (ioc->ir_firmware || ioc->bus_type == SAS) {
2758 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
2759 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
2760 300 /*seconds*/, sleepFlag);
2762 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
2763 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
2764 30 /*seconds*/, sleepFlag);
2770 * mpt_alloc_fw_memory - allocate firmware memory
2771 * @ioc: Pointer to MPT_ADAPTER structure
2772 * @size: total FW bytes
2774 * If memory has already been allocated, the same (cached) value
2778 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
2781 return; /* use already allocated memory */
2782 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2783 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
2784 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
2785 ioc->alloc_total += size;
2786 ioc->alt_ioc->alloc_total -= size;
2788 if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
2789 ioc->alloc_total += size;
2793 * mpt_free_fw_memory - free firmware memory
2794 * @ioc: Pointer to MPT_ADAPTER structure
2796 * If alt_img is NULL, delete from ioc structure.
2797 * Else, delete a secondary image in same format.
2800 mpt_free_fw_memory(MPT_ADAPTER *ioc)
2804 sz = ioc->facts.FWImageSize;
2805 dinitprintk((KERN_INFO MYNAM "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
2806 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2807 pci_free_consistent(ioc->pcidev, sz,
2808 ioc->cached_fw, ioc->cached_fw_dma);
2809 ioc->cached_fw = NULL;
2815 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2817 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
2818 * @ioc: Pointer to MPT_ADAPTER structure
2819 * @sleepFlag: Specifies whether the process can sleep
2821 * Returns 0 for success, >0 for handshake failure
2822 * <0 for fw upload failure.
2824 * Remark: If bound IOC and a successful FWUpload was performed
2825 * on the bound IOC, the second image is discarded
2826 * and memory is free'd. Both channels must upload to prevent
2827 * IOC from running in degraded mode.
2830 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
2832 u8 request[ioc->req_sz];
2833 u8 reply[sizeof(FWUploadReply_t)];
2834 FWUpload_t *prequest;
2835 FWUploadReply_t *preply;
2836 FWUploadTCSGE_t *ptcsge;
2839 int ii, sz, reply_sz;
2842 /* If the image size is 0, we are done.
2844 if ((sz = ioc->facts.FWImageSize) == 0)
2847 mpt_alloc_fw_memory(ioc, sz);
2849 dinitprintk((KERN_INFO MYNAM ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
2850 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2852 if (ioc->cached_fw == NULL) {
2858 prequest = (FWUpload_t *)&request;
2859 preply = (FWUploadReply_t *)&reply;
2861 /* Destination... */
2862 memset(prequest, 0, ioc->req_sz);
2864 reply_sz = sizeof(reply);
2865 memset(preply, 0, reply_sz);
2867 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
2868 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
2870 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
2871 ptcsge->DetailsLength = 12;
2872 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
2873 ptcsge->ImageSize = cpu_to_le32(sz);
2875 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
2877 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
2878 mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma);
2880 sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
2881 dinitprintk((KERN_INFO MYNAM ": Sending FW Upload (req @ %p) sgeoffset=%d \n",
2882 prequest, sgeoffset));
2883 DBG_DUMP_FW_REQUEST_FRAME(prequest)
2885 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
2886 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
2888 dinitprintk((KERN_INFO MYNAM ": FW Upload completed rc=%x \n", ii));
2890 cmdStatus = -EFAULT;
2892 /* Handshake transfer was complete and successful.
2893 * Check the Reply Frame.
2895 int status, transfer_sz;
2896 status = le16_to_cpu(preply->IOCStatus);
2897 if (status == MPI_IOCSTATUS_SUCCESS) {
2898 transfer_sz = le32_to_cpu(preply->ActualImageSize);
2899 if (transfer_sz == sz)
2903 dinitprintk((MYIOC_s_INFO_FMT ": do_upload cmdStatus=%d \n",
2904 ioc->name, cmdStatus));
2909 ddlprintk((MYIOC_s_INFO_FMT ": fw upload failed, freeing image \n",
2911 mpt_free_fw_memory(ioc);
2917 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2919 * mpt_downloadboot - DownloadBoot code
2920 * @ioc: Pointer to MPT_ADAPTER structure
2921 * @pFwHeader: Pointer to firmware header info
2922 * @sleepFlag: Specifies whether the process can sleep
2924 * FwDownloadBoot requires Programmed IO access.
2926 * Returns 0 for success
2927 * -1 FW Image size is 0
2928 * -2 No valid cached_fw Pointer
2929 * <0 for fw upload failure.
2932 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
2934 MpiExtImageHeader_t *pExtImage;
2944 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
2945 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
2947 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2948 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2949 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2950 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2951 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2952 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2954 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
2957 if (sleepFlag == CAN_SLEEP) {
2963 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2964 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
2966 for (count = 0; count < 30; count ++) {
2967 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2968 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
2969 ddlprintk((MYIOC_s_INFO_FMT "RESET_ADAPTER cleared, count=%d\n",
2974 if (sleepFlag == CAN_SLEEP) {
2981 if ( count == 30 ) {
2982 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! "
2983 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
2984 ioc->name, diag0val));
2988 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2989 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2990 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2991 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2992 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2993 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2995 /* Set the DiagRwEn and Disable ARM bits */
2996 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
2998 fwSize = (pFwHeader->ImageSize + 3)/4;
2999 ptrFw = (u32 *) pFwHeader;
3001 /* Write the LoadStartAddress to the DiagRw Address Register
3002 * using Programmed IO
3004 if (ioc->errata_flag_1064)
3005 pci_enable_io_access(ioc->pcidev);
3007 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3008 ddlprintk((MYIOC_s_INFO_FMT "LoadStart addr written 0x%x \n",
3009 ioc->name, pFwHeader->LoadStartAddress));
3011 ddlprintk((MYIOC_s_INFO_FMT "Write FW Image: 0x%x bytes @ %p\n",
3012 ioc->name, fwSize*4, ptrFw));
3014 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3017 nextImage = pFwHeader->NextImageHeaderOffset;
3019 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3021 load_addr = pExtImage->LoadStartAddress;
3023 fwSize = (pExtImage->ImageSize + 3) >> 2;
3024 ptrFw = (u32 *)pExtImage;
3026 ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3027 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3028 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3031 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3033 nextImage = pExtImage->NextImageHeaderOffset;
3036 /* Write the IopResetVectorRegAddr */
3037 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
3038 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3040 /* Write the IopResetVectorValue */
3041 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3042 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3044 /* Clear the internal flash bad bit - autoincrementing register,
3045 * so must do two writes.
3047 if (ioc->bus_type == SPI) {
3049 * 1030 and 1035 H/W errata, workaround to access
3050 * the ClearFlashBadSignatureBit
3052 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3053 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3054 diagRwData |= 0x40000000;
3055 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3056 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3058 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3059 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3060 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3061 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3064 if (sleepFlag == CAN_SLEEP) {
3071 if (ioc->errata_flag_1064)
3072 pci_disable_io_access(ioc->pcidev);
3074 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3075 ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, "
3076 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3077 ioc->name, diag0val));
3078 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3079 ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
3080 ioc->name, diag0val));
3081 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3083 /* Write 0xFF to reset the sequencer */
3084 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3086 if (ioc->bus_type == SAS) {
3087 ioc_state = mpt_GetIocState(ioc, 0);
3088 if ( (GetIocFacts(ioc, sleepFlag,
3089 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3090 ddlprintk((MYIOC_s_INFO_FMT "GetIocFacts failed: IocState=%x\n",
3091 ioc->name, ioc_state));
3096 for (count=0; count<HZ*20; count++) {
3097 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3098 ddlprintk((MYIOC_s_INFO_FMT "downloadboot successful! (count=%d) IocState=%x\n",
3099 ioc->name, count, ioc_state));
3100 if (ioc->bus_type == SAS) {
3103 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3104 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit failed\n",
3108 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit successful\n",
3112 if (sleepFlag == CAN_SLEEP) {
3118 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! IocState=%x\n",
3119 ioc->name, ioc_state));
3123 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3125 * KickStart - Perform hard reset of MPT adapter.
3126 * @ioc: Pointer to MPT_ADAPTER structure
3127 * @force: Force hard reset
3128 * @sleepFlag: Specifies whether the process can sleep
3130 * This routine places MPT adapter in diagnostic mode via the
3131 * WriteSequence register, and then performs a hard reset of adapter
3132 * via the Diagnostic register.
3134 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3135 * or NO_SLEEP (interrupt thread, use mdelay)
3136 * force - 1 if doorbell active, board fault state
3137 * board operational, IOC_RECOVERY or
3138 * IOC_BRINGUP and there is an alt_ioc.
3142 * 1 - hard reset, READY
3143 * 0 - no reset due to History bit, READY
3144 * -1 - no reset due to History bit but not READY
3145 * OR reset but failed to come READY
3146 * -2 - no reset, could not enter DIAG mode
3147 * -3 - reset but bad FW bit
3150 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3152 int hard_reset_done = 0;
3156 dinitprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
3157 if (ioc->bus_type == SPI) {
3158 /* Always issue a Msg Unit Reset first. This will clear some
3159 * SCSI bus hang conditions.
3161 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3163 if (sleepFlag == CAN_SLEEP) {
3170 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3171 if (hard_reset_done < 0)
3172 return hard_reset_done;
3174 dinitprintk((MYIOC_s_INFO_FMT "Diagnostic reset successful!\n",
3177 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3178 for (cnt=0; cnt<cntdn; cnt++) {
3179 ioc_state = mpt_GetIocState(ioc, 1);
3180 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3181 dinitprintk((MYIOC_s_INFO_FMT "KickStart successful! (cnt=%d)\n",
3183 return hard_reset_done;
3185 if (sleepFlag == CAN_SLEEP) {
3192 printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3193 ioc->name, ioc_state);
3197 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3199 * mpt_diag_reset - Perform hard reset of the adapter.
3200 * @ioc: Pointer to MPT_ADAPTER structure
3201 * @ignore: Set if to honor and clear to ignore
3202 * the reset history bit
3203 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3204 * else set to NO_SLEEP (use mdelay instead)
3206 * This routine places the adapter in diagnostic mode via the
3207 * WriteSequence register and then performs a hard reset of adapter
3208 * via the Diagnostic register. Adapter should be in ready state
3209 * upon successful completion.
3211 * Returns: 1 hard reset successful
3212 * 0 no reset performed because reset history bit set
3213 * -2 enabling diagnostic mode failed
3214 * -3 diagnostic reset failed
3217 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3219 MPT_ADAPTER *iocp=NULL;
3222 int hard_reset_done = 0;
3228 /* Clear any existing interrupts */
3229 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3231 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3232 drsprintk((MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3233 "address=%p\n", ioc->name, __FUNCTION__,
3234 &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3235 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3236 if (sleepFlag == CAN_SLEEP)
3241 for (count = 0; count < 60; count ++) {
3242 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3243 doorbell &= MPI_IOC_STATE_MASK;
3245 drsprintk((MYIOC_s_INFO_FMT
3246 "looking for READY STATE: doorbell=%x"
3248 ioc->name, doorbell, count));
3249 if (doorbell == MPI_IOC_STATE_READY) {
3254 if (sleepFlag == CAN_SLEEP)
3262 /* Use "Diagnostic reset" method! (only thing available!) */
3263 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3267 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3268 dprintk((MYIOC_s_INFO_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3269 ioc->name, diag0val, diag1val));
3272 /* Do the reset if we are told to ignore the reset history
3273 * or if the reset history is 0
3275 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3276 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3277 /* Write magic sequence to WriteSequence register
3278 * Loop until in diagnostic mode
3280 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3281 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3282 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3283 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3284 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3285 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3288 if (sleepFlag == CAN_SLEEP) {
3296 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3297 ioc->name, diag0val);
3302 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3304 dprintk((MYIOC_s_INFO_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3305 ioc->name, diag0val));
3310 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3311 dprintk((MYIOC_s_INFO_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3312 ioc->name, diag0val, diag1val));
3315 * Disable the ARM (Bug fix)
3318 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3322 * Now hit the reset bit in the Diagnostic register
3323 * (THE BIG HAMMER!) (Clears DRWE bit).
3325 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3326 hard_reset_done = 1;
3327 dprintk((MYIOC_s_INFO_FMT "Diagnostic reset performed\n",
3331 * Call each currently registered protocol IOC reset handler
3332 * with pre-reset indication.
3333 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3334 * MptResetHandlers[] registered yet.
3340 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
3341 if (MptResetHandlers[ii]) {
3342 dprintk((MYIOC_s_INFO_FMT "Calling IOC pre_reset handler #%d\n",
3344 r += mpt_signal_reset(ii, ioc, MPT_IOC_PRE_RESET);
3346 dprintk((MYIOC_s_INFO_FMT "Calling alt-%s pre_reset handler #%d\n",
3347 ioc->name, ioc->alt_ioc->name, ii));
3348 r += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_PRE_RESET);
3352 /* FIXME? Examine results here? */
3357 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
3358 iocp = ioc->alt_ioc;
3360 /* If the DownloadBoot operation fails, the
3361 * IOC will be left unusable. This is a fatal error
3362 * case. _diag_reset will return < 0
3364 for (count = 0; count < 30; count ++) {
3365 diag0val = CHIPREG_READ32(&iocp->chip->Diagnostic);
3366 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3370 dprintk((MYIOC_s_INFO_FMT "cached_fw: diag0val=%x count=%d\n",
3371 iocp->name, diag0val, count));
3373 if (sleepFlag == CAN_SLEEP) {
3379 if ((count = mpt_downloadboot(ioc,
3380 (MpiFwHeader_t *)iocp->cached_fw, sleepFlag)) < 0) {
3381 printk(KERN_WARNING MYNAM
3382 ": firmware downloadboot failure (%d)!\n", count);
3386 /* Wait for FW to reload and for board
3387 * to go to the READY state.
3388 * Maximum wait is 60 seconds.
3389 * If fail, no error will check again
3390 * with calling program.
3392 for (count = 0; count < 60; count ++) {
3393 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3394 doorbell &= MPI_IOC_STATE_MASK;
3396 if (doorbell == MPI_IOC_STATE_READY) {
3401 if (sleepFlag == CAN_SLEEP) {
3410 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3413 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3414 dprintk((MYIOC_s_INFO_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3415 ioc->name, diag0val, diag1val));
3418 /* Clear RESET_HISTORY bit! Place board in the
3419 * diagnostic mode to update the diag register.
3421 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3423 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3424 /* Write magic sequence to WriteSequence register
3425 * Loop until in diagnostic mode
3427 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3428 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3429 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3430 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3431 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3432 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3435 if (sleepFlag == CAN_SLEEP) {
3443 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3444 ioc->name, diag0val);
3447 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3449 diag0val &= ~MPI_DIAG_RESET_HISTORY;
3450 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3451 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3452 if (diag0val & MPI_DIAG_RESET_HISTORY) {
3453 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3457 /* Disable Diagnostic Mode
3459 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3461 /* Check FW reload status flags.
3463 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3464 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3465 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3466 ioc->name, diag0val);
3472 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3473 dprintk((MYIOC_s_INFO_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3474 ioc->name, diag0val, diag1val));
3478 * Reset flag that says we've enabled event notification
3480 ioc->facts.EventState = 0;
3483 ioc->alt_ioc->facts.EventState = 0;
3485 return hard_reset_done;
3488 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3490 * SendIocReset - Send IOCReset request to MPT adapter.
3491 * @ioc: Pointer to MPT_ADAPTER structure
3492 * @reset_type: reset type, expected values are
3493 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3494 * @sleepFlag: Specifies whether the process can sleep
3496 * Send IOCReset request to the MPT adapter.
3498 * Returns 0 for success, non-zero for failure.
3501 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3507 drsprintk((KERN_INFO MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
3508 ioc->name, reset_type));
3509 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3510 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3513 /* FW ACK'd request, wait for READY state
3516 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
3518 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3522 if (sleepFlag != CAN_SLEEP)
3525 printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
3526 ioc->name, (int)((count+5)/HZ));
3530 if (sleepFlag == CAN_SLEEP) {
3533 mdelay (1); /* 1 msec delay */
3538 * Cleanup all event stuff for this IOC; re-issue EventNotification
3539 * request if needed.
3541 if (ioc->facts.Function)
3542 ioc->facts.EventState = 0;
3547 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3549 * initChainBuffers - Allocate memory for and initialize chain buffers
3550 * @ioc: Pointer to MPT_ADAPTER structure
3552 * Allocates memory for and initializes chain buffers,
3553 * chain buffer control arrays and spinlock.
3556 initChainBuffers(MPT_ADAPTER *ioc)
3559 int sz, ii, num_chain;
3560 int scale, num_sge, numSGE;
3562 /* ReqToChain size must equal the req_depth
3565 if (ioc->ReqToChain == NULL) {
3566 sz = ioc->req_depth * sizeof(int);
3567 mem = kmalloc(sz, GFP_ATOMIC);
3571 ioc->ReqToChain = (int *) mem;
3572 dinitprintk((KERN_INFO MYNAM ": %s ReqToChain alloc @ %p, sz=%d bytes\n",
3573 ioc->name, mem, sz));
3574 mem = kmalloc(sz, GFP_ATOMIC);
3578 ioc->RequestNB = (int *) mem;
3579 dinitprintk((KERN_INFO MYNAM ": %s RequestNB alloc @ %p, sz=%d bytes\n",
3580 ioc->name, mem, sz));
3582 for (ii = 0; ii < ioc->req_depth; ii++) {
3583 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
3586 /* ChainToChain size must equal the total number
3587 * of chain buffers to be allocated.
3590 * Calculate the number of chain buffers needed(plus 1) per I/O
3591 * then multiply the maximum number of simultaneous cmds
3593 * num_sge = num sge in request frame + last chain buffer
3594 * scale = num sge per chain buffer if no chain element
3596 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3597 if (sizeof(dma_addr_t) == sizeof(u64))
3598 num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3600 num_sge = 1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3602 if (sizeof(dma_addr_t) == sizeof(u64)) {
3603 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3604 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3606 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3607 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3609 dinitprintk((KERN_INFO MYNAM ": %s num_sge=%d numSGE=%d\n",
3610 ioc->name, num_sge, numSGE));
3612 if ( numSGE > MPT_SCSI_SG_DEPTH )
3613 numSGE = MPT_SCSI_SG_DEPTH;
3616 while (numSGE - num_sge > 0) {
3618 num_sge += (scale - 1);
3622 dinitprintk((KERN_INFO MYNAM ": %s Now numSGE=%d num_sge=%d num_chain=%d\n",
3623 ioc->name, numSGE, num_sge, num_chain));
3625 if (ioc->bus_type == SPI)
3626 num_chain *= MPT_SCSI_CAN_QUEUE;
3628 num_chain *= MPT_FC_CAN_QUEUE;
3630 ioc->num_chain = num_chain;
3632 sz = num_chain * sizeof(int);
3633 if (ioc->ChainToChain == NULL) {
3634 mem = kmalloc(sz, GFP_ATOMIC);
3638 ioc->ChainToChain = (int *) mem;
3639 dinitprintk((KERN_INFO MYNAM ": %s ChainToChain alloc @ %p, sz=%d bytes\n",
3640 ioc->name, mem, sz));
3642 mem = (u8 *) ioc->ChainToChain;
3644 memset(mem, 0xFF, sz);
3648 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3650 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
3651 * @ioc: Pointer to MPT_ADAPTER structure
3653 * This routine allocates memory for the MPT reply and request frame
3654 * pools (if necessary), and primes the IOC reply FIFO with
3657 * Returns 0 for success, non-zero for failure.
3660 PrimeIocFifos(MPT_ADAPTER *ioc)
3663 unsigned long flags;
3664 dma_addr_t alloc_dma;
3666 int i, reply_sz, sz, total_size, num_chain;
3668 /* Prime reply FIFO... */
3670 if (ioc->reply_frames == NULL) {
3671 if ( (num_chain = initChainBuffers(ioc)) < 0)
3674 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
3675 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
3676 ioc->name, ioc->reply_sz, ioc->reply_depth));
3677 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d[%x] bytes\n",
3678 ioc->name, reply_sz, reply_sz));
3680 sz = (ioc->req_sz * ioc->req_depth);
3681 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d bytes, RequestDepth=%d\n",
3682 ioc->name, ioc->req_sz, ioc->req_depth));
3683 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d[%x] bytes\n",
3684 ioc->name, sz, sz));
3687 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
3688 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d bytes, ChainDepth=%d\n",
3689 ioc->name, ioc->req_sz, num_chain));
3690 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
3691 ioc->name, sz, sz, num_chain));
3694 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
3696 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
3701 dinitprintk((KERN_INFO MYNAM ": %s.Total alloc @ %p[%p], sz=%d[%x] bytes\n",
3702 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
3704 memset(mem, 0, total_size);
3705 ioc->alloc_total += total_size;
3707 ioc->alloc_dma = alloc_dma;
3708 ioc->alloc_sz = total_size;
3709 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
3710 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3712 dinitprintk((KERN_INFO MYNAM ": %s ReplyBuffers @ %p[%p]\n",
3713 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3715 alloc_dma += reply_sz;
3718 /* Request FIFO - WE manage this! */
3720 ioc->req_frames = (MPT_FRAME_HDR *) mem;
3721 ioc->req_frames_dma = alloc_dma;
3723 dinitprintk((KERN_INFO MYNAM ": %s RequestBuffers @ %p[%p]\n",
3724 ioc->name, mem, (void *)(ulong)alloc_dma));
3726 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3728 #if defined(CONFIG_MTRR) && 0
3730 * Enable Write Combining MTRR for IOC's memory region.
3731 * (at least as much as we can; "size and base must be
3732 * multiples of 4 kiB"
3734 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
3736 MTRR_TYPE_WRCOMB, 1);
3737 dprintk((MYIOC_s_INFO_FMT "MTRR region registered (base:size=%08x:%x)\n",
3738 ioc->name, ioc->req_frames_dma, sz));
3741 for (i = 0; i < ioc->req_depth; i++) {
3742 alloc_dma += ioc->req_sz;
3746 ioc->ChainBuffer = mem;
3747 ioc->ChainBufferDMA = alloc_dma;
3749 dinitprintk((KERN_INFO MYNAM " :%s ChainBuffers @ %p(%p)\n",
3750 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
3752 /* Initialize the free chain Q.
3755 INIT_LIST_HEAD(&ioc->FreeChainQ);
3757 /* Post the chain buffers to the FreeChainQ.
3759 mem = (u8 *)ioc->ChainBuffer;
3760 for (i=0; i < num_chain; i++) {
3761 mf = (MPT_FRAME_HDR *) mem;
3762 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
3766 /* Initialize Request frames linked list
3768 alloc_dma = ioc->req_frames_dma;
3769 mem = (u8 *) ioc->req_frames;
3771 spin_lock_irqsave(&ioc->FreeQlock, flags);
3772 INIT_LIST_HEAD(&ioc->FreeQ);
3773 for (i = 0; i < ioc->req_depth; i++) {
3774 mf = (MPT_FRAME_HDR *) mem;
3776 /* Queue REQUESTs *internally*! */
3777 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
3781 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3783 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3784 ioc->sense_buf_pool =
3785 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
3786 if (ioc->sense_buf_pool == NULL) {
3787 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
3792 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
3793 ioc->alloc_total += sz;
3794 dinitprintk((KERN_INFO MYNAM ": %s.SenseBuffers @ %p[%p]\n",
3795 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
3799 /* Post Reply frames to FIFO
3801 alloc_dma = ioc->alloc_dma;
3802 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffers @ %p[%p]\n",
3803 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3805 for (i = 0; i < ioc->reply_depth; i++) {
3806 /* Write each address to the IOC! */
3807 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
3808 alloc_dma += ioc->reply_sz;
3814 if (ioc->alloc != NULL) {
3816 pci_free_consistent(ioc->pcidev,
3818 ioc->alloc, ioc->alloc_dma);
3819 ioc->reply_frames = NULL;
3820 ioc->req_frames = NULL;
3821 ioc->alloc_total -= sz;
3823 if (ioc->sense_buf_pool != NULL) {
3824 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3825 pci_free_consistent(ioc->pcidev,
3827 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
3828 ioc->sense_buf_pool = NULL;
3833 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3835 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
3836 * from IOC via doorbell handshake method.
3837 * @ioc: Pointer to MPT_ADAPTER structure
3838 * @reqBytes: Size of the request in bytes
3839 * @req: Pointer to MPT request frame
3840 * @replyBytes: Expected size of the reply in bytes
3841 * @u16reply: Pointer to area where reply should be written
3842 * @maxwait: Max wait time for a reply (in seconds)
3843 * @sleepFlag: Specifies whether the process can sleep
3845 * NOTES: It is the callers responsibility to byte-swap fields in the
3846 * request which are greater than 1 byte in size. It is also the
3847 * callers responsibility to byte-swap response fields which are
3848 * greater than 1 byte in size.
3850 * Returns 0 for success, non-zero for failure.
3853 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
3854 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
3856 MPIDefaultReply_t *mptReply;
3861 * Get ready to cache a handshake reply
3863 ioc->hs_reply_idx = 0;
3864 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
3865 mptReply->MsgLength = 0;
3868 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
3869 * then tell IOC that we want to handshake a request of N words.
3870 * (WRITE u32val to Doorbell reg).
3872 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3873 CHIPREG_WRITE32(&ioc->chip->Doorbell,
3874 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
3875 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
3878 * Wait for IOC's doorbell handshake int
3880 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3883 dhsprintk((MYIOC_s_INFO_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
3884 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
3886 /* Read doorbell and check for active bit */
3887 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
3891 * Clear doorbell int (WRITE 0 to IntStatus reg),
3892 * then wait for IOC to ACKnowledge that it's ready for
3893 * our handshake request.
3895 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3896 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3901 u8 *req_as_bytes = (u8 *) req;
3904 * Stuff request words via doorbell handshake,
3905 * with ACK from IOC for each.
3907 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
3908 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
3909 (req_as_bytes[(ii*4) + 1] << 8) |
3910 (req_as_bytes[(ii*4) + 2] << 16) |
3911 (req_as_bytes[(ii*4) + 3] << 24));
3913 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
3914 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3918 dhsprintk((KERN_INFO MYNAM ": Handshake request frame (@%p) header\n", req));
3919 DBG_DUMP_REQUEST_FRAME_HDR(req)
3921 dhsprintk((MYIOC_s_INFO_FMT "HandShake request post done, WaitCnt=%d%s\n",
3922 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
3925 * Wait for completion of doorbell handshake reply from the IOC
3927 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
3930 dhsprintk((MYIOC_s_INFO_FMT "HandShake reply count=%d%s\n",
3931 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
3934 * Copy out the cached reply...
3936 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
3937 u16reply[ii] = ioc->hs_reply[ii];
3945 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3947 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
3948 * @ioc: Pointer to MPT_ADAPTER structure
3949 * @howlong: How long to wait (in seconds)
3950 * @sleepFlag: Specifies whether the process can sleep
3952 * This routine waits (up to ~2 seconds max) for IOC doorbell
3953 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
3954 * bit in its IntStatus register being clear.
3956 * Returns a negative value on failure, else wait loop count.
3959 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3965 cntdn = 1000 * howlong;
3967 if (sleepFlag == CAN_SLEEP) {
3970 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3971 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3978 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3979 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3986 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell ACK (count=%d)\n",
3991 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
3992 ioc->name, count, intstat);
3996 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3998 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
3999 * @ioc: Pointer to MPT_ADAPTER structure
4000 * @howlong: How long to wait (in seconds)
4001 * @sleepFlag: Specifies whether the process can sleep
4003 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4004 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4006 * Returns a negative value on failure, else wait loop count.
4009 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4015 cntdn = 1000 * howlong;
4016 if (sleepFlag == CAN_SLEEP) {
4018 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4019 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4026 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4027 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4035 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4036 ioc->name, count, howlong));
4040 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4041 ioc->name, count, intstat);
4045 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4047 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4048 * @ioc: Pointer to MPT_ADAPTER structure
4049 * @howlong: How long to wait (in seconds)
4050 * @sleepFlag: Specifies whether the process can sleep
4052 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4053 * Reply is cached to IOC private area large enough to hold a maximum
4054 * of 128 bytes of reply data.
4056 * Returns a negative value on failure, else size of reply in WORDS.
4059 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4064 u16 *hs_reply = ioc->hs_reply;
4065 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4068 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4071 * Get first two u16's so we can look at IOC's intended reply MsgLength
4074 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4077 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4078 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4079 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4082 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4083 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4087 dhsprintk((MYIOC_s_INFO_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4088 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4089 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4092 * If no error (and IOC said MsgLength is > 0), piece together
4093 * reply 16 bits at a time.
4095 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4096 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4098 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4099 /* don't overflow our IOC hs_reply[] buffer! */
4100 if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
4101 hs_reply[u16cnt] = hword;
4102 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4105 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4107 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4110 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4115 else if (u16cnt != (2 * mptReply->MsgLength)) {
4118 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4123 dhsprintk((MYIOC_s_INFO_FMT "Got Handshake reply:\n", ioc->name));
4124 DBG_DUMP_REPLY_FRAME(mptReply)
4126 dhsprintk((MYIOC_s_INFO_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4127 ioc->name, t, u16cnt/2));
4131 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4133 * GetLanConfigPages - Fetch LANConfig pages.
4134 * @ioc: Pointer to MPT_ADAPTER structure
4136 * Return: 0 for success
4137 * -ENOMEM if no memory available
4138 * -EPERM if not allowed due to ISR context
4139 * -EAGAIN if no msg frames currently available
4140 * -EFAULT for non-successful reply or no reply (timeout)
4143 GetLanConfigPages(MPT_ADAPTER *ioc)
4145 ConfigPageHeader_t hdr;
4147 LANPage0_t *ppage0_alloc;
4148 dma_addr_t page0_dma;
4149 LANPage1_t *ppage1_alloc;
4150 dma_addr_t page1_dma;
4155 /* Get LAN Page 0 header */
4156 hdr.PageVersion = 0;
4159 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4160 cfg.cfghdr.hdr = &hdr;
4162 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4167 if ((rc = mpt_config(ioc, &cfg)) != 0)
4170 if (hdr.PageLength > 0) {
4171 data_sz = hdr.PageLength * 4;
4172 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4175 memset((u8 *)ppage0_alloc, 0, data_sz);
4176 cfg.physAddr = page0_dma;
4177 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4179 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4181 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4182 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4186 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4189 * Normalize endianness of structure data,
4190 * by byte-swapping all > 1 byte fields!
4199 /* Get LAN Page 1 header */
4200 hdr.PageVersion = 0;
4203 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4204 cfg.cfghdr.hdr = &hdr;
4206 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4210 if ((rc = mpt_config(ioc, &cfg)) != 0)
4213 if (hdr.PageLength == 0)
4216 data_sz = hdr.PageLength * 4;
4218 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4220 memset((u8 *)ppage1_alloc, 0, data_sz);
4221 cfg.physAddr = page1_dma;
4222 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4224 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4226 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4227 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4230 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4233 * Normalize endianness of structure data,
4234 * by byte-swapping all > 1 byte fields!
4242 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4244 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
4245 * @ioc: Pointer to MPT_ADAPTER structure
4246 * @persist_opcode: see below
4248 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4249 * devices not currently present.
4250 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4252 * NOTE: Don't use not this function during interrupt time.
4254 * Returns 0 for success, non-zero error
4257 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4259 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4261 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
4262 SasIoUnitControlReply_t *sasIoUnitCntrReply;
4263 MPT_FRAME_HDR *mf = NULL;
4264 MPIHeader_t *mpi_hdr;
4267 /* insure garbage is not sent to fw */
4268 switch(persist_opcode) {
4270 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
4271 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
4279 printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode);
4281 /* Get a MF for this command.
4283 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4284 printk("%s: no msg frames!\n",__FUNCTION__);
4288 mpi_hdr = (MPIHeader_t *) mf;
4289 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
4290 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
4291 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
4292 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
4293 sasIoUnitCntrReq->Operation = persist_opcode;
4295 init_timer(&ioc->persist_timer);
4296 ioc->persist_timer.data = (unsigned long) ioc;
4297 ioc->persist_timer.function = mpt_timer_expired;
4298 ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
4299 ioc->persist_wait_done=0;
4300 add_timer(&ioc->persist_timer);
4301 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4302 wait_event(mpt_waitq, ioc->persist_wait_done);
4304 sasIoUnitCntrReply =
4305 (SasIoUnitControlReply_t *)ioc->persist_reply_frame;
4306 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
4307 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4309 sasIoUnitCntrReply->IOCStatus,
4310 sasIoUnitCntrReply->IOCLogInfo);
4314 printk("%s: success\n",__FUNCTION__);
4318 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4321 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
4322 MpiEventDataRaid_t * pRaidEventData)
4331 volume = pRaidEventData->VolumeID;
4332 reason = pRaidEventData->ReasonCode;
4333 disk = pRaidEventData->PhysDiskNum;
4334 status = le32_to_cpu(pRaidEventData->SettingsStatus);
4335 flags = (status >> 0) & 0xff;
4336 state = (status >> 8) & 0xff;
4338 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
4342 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
4343 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
4344 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
4345 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
4346 ioc->name, disk, volume);
4348 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
4353 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4354 printk(MYIOC_s_INFO_FMT " volume has been created\n",
4358 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4360 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
4364 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
4365 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
4369 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4370 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
4372 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
4374 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
4376 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
4379 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
4381 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
4382 ? ", quiesced" : "",
4383 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
4384 ? ", resync in progress" : "" );
4387 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
4388 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
4392 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4393 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
4397 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4398 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
4402 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
4403 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
4407 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4408 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
4410 state == MPI_PHYSDISK0_STATUS_ONLINE
4412 : state == MPI_PHYSDISK0_STATUS_MISSING
4414 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
4416 : state == MPI_PHYSDISK0_STATUS_FAILED
4418 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
4420 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
4421 ? "offline requested"
4422 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
4423 ? "failed requested"
4424 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
4427 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
4428 ? ", out of sync" : "",
4429 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
4430 ? ", quiesced" : "" );
4433 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
4434 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
4438 case MPI_EVENT_RAID_RC_SMART_DATA:
4439 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
4440 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
4443 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
4444 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
4450 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4452 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4453 * @ioc: Pointer to MPT_ADAPTER structure
4455 * Returns: 0 for success
4456 * -ENOMEM if no memory available
4457 * -EPERM if not allowed due to ISR context
4458 * -EAGAIN if no msg frames currently available
4459 * -EFAULT for non-successful reply or no reply (timeout)
4462 GetIoUnitPage2(MPT_ADAPTER *ioc)
4464 ConfigPageHeader_t hdr;
4466 IOUnitPage2_t *ppage_alloc;
4467 dma_addr_t page_dma;
4471 /* Get the page header */
4472 hdr.PageVersion = 0;
4475 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4476 cfg.cfghdr.hdr = &hdr;
4478 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4483 if ((rc = mpt_config(ioc, &cfg)) != 0)
4486 if (hdr.PageLength == 0)
4489 /* Read the config page */
4490 data_sz = hdr.PageLength * 4;
4492 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4494 memset((u8 *)ppage_alloc, 0, data_sz);
4495 cfg.physAddr = page_dma;
4496 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4498 /* If Good, save data */
4499 if ((rc = mpt_config(ioc, &cfg)) == 0)
4500 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4502 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4508 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4510 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4511 * @ioc: Pointer to a Adapter Strucutre
4512 * @portnum: IOC port number
4514 * Return: -EFAULT if read of config page header fails
4516 * If read of SCSI Port Page 0 fails,
4517 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4518 * Adapter settings: async, narrow
4520 * If read of SCSI Port Page 2 fails,
4521 * Adapter settings valid
4522 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4527 * CHECK - what type of locking mechanisms should be used????
4530 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4535 ConfigPageHeader_t header;
4541 if (!ioc->spi_data.nvram) {
4544 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4545 mem = kmalloc(sz, GFP_ATOMIC);
4549 ioc->spi_data.nvram = (int *) mem;
4551 dprintk((MYIOC_s_INFO_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4552 ioc->name, ioc->spi_data.nvram, sz));
4555 /* Invalidate NVRAM information
4557 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4558 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4561 /* Read SPP0 header, allocate memory, then read page.
4563 header.PageVersion = 0;
4564 header.PageLength = 0;
4565 header.PageNumber = 0;
4566 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4567 cfg.cfghdr.hdr = &header;
4569 cfg.pageAddr = portnum;
4570 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4572 cfg.timeout = 0; /* use default */
4573 if (mpt_config(ioc, &cfg) != 0)
4576 if (header.PageLength > 0) {
4577 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4579 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4580 cfg.physAddr = buf_dma;
4581 if (mpt_config(ioc, &cfg) != 0) {
4582 ioc->spi_data.maxBusWidth = MPT_NARROW;
4583 ioc->spi_data.maxSyncOffset = 0;
4584 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4585 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4587 ddvprintk((MYIOC_s_INFO_FMT "Unable to read PortPage0 minSyncFactor=%x\n",
4588 ioc->name, ioc->spi_data.minSyncFactor));
4590 /* Save the Port Page 0 data
4592 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
4593 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4594 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4596 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
4597 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4598 ddvprintk((KERN_INFO MYNAM " :%s noQas due to Capabilities=%x\n",
4599 ioc->name, pPP0->Capabilities));
4601 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4602 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4604 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4605 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4606 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4607 ddvprintk((MYIOC_s_INFO_FMT "PortPage0 minSyncFactor=%x\n",
4608 ioc->name, ioc->spi_data.minSyncFactor));
4610 ioc->spi_data.maxSyncOffset = 0;
4611 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4614 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4616 /* Update the minSyncFactor based on bus type.
4618 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4619 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
4621 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
4622 ioc->spi_data.minSyncFactor = MPT_ULTRA;
4623 ddvprintk((MYIOC_s_INFO_FMT "HVD or SE detected, minSyncFactor=%x\n",
4624 ioc->name, ioc->spi_data.minSyncFactor));
4629 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4634 /* SCSI Port Page 2 - Read the header then the page.
4636 header.PageVersion = 0;
4637 header.PageLength = 0;
4638 header.PageNumber = 2;
4639 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4640 cfg.cfghdr.hdr = &header;
4642 cfg.pageAddr = portnum;
4643 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4645 if (mpt_config(ioc, &cfg) != 0)
4648 if (header.PageLength > 0) {
4649 /* Allocate memory and read SCSI Port Page 2
4651 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4653 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
4654 cfg.physAddr = buf_dma;
4655 if (mpt_config(ioc, &cfg) != 0) {
4656 /* Nvram data is left with INVALID mark
4660 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
4661 MpiDeviceInfo_t *pdevice = NULL;
4664 * Save "Set to Avoid SCSI Bus Resets" flag
4666 ioc->spi_data.bus_reset =
4667 (le32_to_cpu(pPP2->PortFlags) &
4668 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
4671 /* Save the Port Page 2 data
4672 * (reformat into a 32bit quantity)
4674 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
4675 ioc->spi_data.PortFlags = data;
4676 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4677 pdevice = &pPP2->DeviceSettings[ii];
4678 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
4679 (pdevice->SyncFactor << 8) | pdevice->Timeout;
4680 ioc->spi_data.nvram[ii] = data;
4684 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4688 /* Update Adapter limits with those from NVRAM
4689 * Comment: Don't need to do this. Target performance
4690 * parameters will never exceed the adapters limits.
4696 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4698 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
4699 * @ioc: Pointer to a Adapter Strucutre
4700 * @portnum: IOC port number
4702 * Return: -EFAULT if read of config page header fails
4706 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
4709 ConfigPageHeader_t header;
4711 /* Read the SCSI Device Page 1 header
4713 header.PageVersion = 0;
4714 header.PageLength = 0;
4715 header.PageNumber = 1;
4716 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4717 cfg.cfghdr.hdr = &header;
4719 cfg.pageAddr = portnum;
4720 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4723 if (mpt_config(ioc, &cfg) != 0)
4726 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
4727 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
4729 header.PageVersion = 0;
4730 header.PageLength = 0;
4731 header.PageNumber = 0;
4732 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4733 if (mpt_config(ioc, &cfg) != 0)
4736 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
4737 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
4739 dcprintk((MYIOC_s_INFO_FMT "Headers: 0: version %d length %d\n",
4740 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
4742 dcprintk((MYIOC_s_INFO_FMT "Headers: 1: version %d length %d\n",
4743 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
4748 * mpt_inactive_raid_list_free - This clears this link list.
4749 * @ioc : pointer to per adapter structure
4752 mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
4754 struct inactive_raid_component_info *component_info, *pNext;
4756 if (list_empty(&ioc->raid_data.inactive_list))
4759 down(&ioc->raid_data.inactive_list_mutex);
4760 list_for_each_entry_safe(component_info, pNext,
4761 &ioc->raid_data.inactive_list, list) {
4762 list_del(&component_info->list);
4763 kfree(component_info);
4765 up(&ioc->raid_data.inactive_list_mutex);
4769 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
4771 * @ioc : pointer to per adapter structure
4772 * @channel : volume channel
4773 * @id : volume target id
4776 mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
4779 ConfigPageHeader_t hdr;
4780 dma_addr_t dma_handle;
4781 pRaidVolumePage0_t buffer = NULL;
4783 RaidPhysDiskPage0_t phys_disk;
4784 struct inactive_raid_component_info *component_info;
4785 int handle_inactive_volumes;
4787 memset(&cfg, 0 , sizeof(CONFIGPARMS));
4788 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
4789 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
4790 cfg.pageAddr = (channel << 8) + id;
4791 cfg.cfghdr.hdr = &hdr;
4792 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4794 if (mpt_config(ioc, &cfg) != 0)
4797 if (!hdr.PageLength)
4800 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
4806 cfg.physAddr = dma_handle;
4807 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4809 if (mpt_config(ioc, &cfg) != 0)
4812 if (!buffer->NumPhysDisks)
4815 handle_inactive_volumes =
4816 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
4817 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
4818 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
4819 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
4821 if (!handle_inactive_volumes)
4824 down(&ioc->raid_data.inactive_list_mutex);
4825 for (i = 0; i < buffer->NumPhysDisks; i++) {
4826 if(mpt_raid_phys_disk_pg0(ioc,
4827 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
4830 if ((component_info = kmalloc(sizeof (*component_info),
4831 GFP_KERNEL)) == NULL)
4834 component_info->volumeID = id;
4835 component_info->volumeBus = channel;
4836 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
4837 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
4838 component_info->d.PhysDiskID = phys_disk.PhysDiskID;
4839 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
4841 list_add_tail(&component_info->list,
4842 &ioc->raid_data.inactive_list);
4844 up(&ioc->raid_data.inactive_list_mutex);
4848 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
4853 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
4854 * @ioc: Pointer to a Adapter Structure
4855 * @phys_disk_num: io unit unique phys disk num generated by the ioc
4856 * @phys_disk: requested payload data returned
4860 * -EFAULT if read of config page header fails or data pointer not NULL
4861 * -ENOMEM if pci_alloc failed
4864 mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk)
4867 ConfigPageHeader_t hdr;
4868 dma_addr_t dma_handle;
4869 pRaidPhysDiskPage0_t buffer = NULL;
4872 memset(&cfg, 0 , sizeof(CONFIGPARMS));
4873 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
4875 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
4876 cfg.cfghdr.hdr = &hdr;
4878 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4880 if (mpt_config(ioc, &cfg) != 0) {
4885 if (!hdr.PageLength) {
4890 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
4898 cfg.physAddr = dma_handle;
4899 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4900 cfg.pageAddr = phys_disk_num;
4902 if (mpt_config(ioc, &cfg) != 0) {
4908 memcpy(phys_disk, buffer, sizeof(*buffer));
4909 phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
4914 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
4921 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
4922 * @ioc: Pointer to a Adapter Strucutre
4923 * @portnum: IOC port number
4927 * -EFAULT if read of config page header fails or data pointer not NULL
4928 * -ENOMEM if pci_alloc failed
4931 mpt_findImVolumes(MPT_ADAPTER *ioc)
4935 dma_addr_t ioc2_dma;
4937 ConfigPageHeader_t header;
4942 if (!ioc->ir_firmware)
4945 /* Free the old page
4947 kfree(ioc->raid_data.pIocPg2);
4948 ioc->raid_data.pIocPg2 = NULL;
4949 mpt_inactive_raid_list_free(ioc);
4951 /* Read IOCP2 header then the page.
4953 header.PageVersion = 0;
4954 header.PageLength = 0;
4955 header.PageNumber = 2;
4956 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4957 cfg.cfghdr.hdr = &header;
4960 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4963 if (mpt_config(ioc, &cfg) != 0)
4966 if (header.PageLength == 0)
4969 iocpage2sz = header.PageLength * 4;
4970 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
4974 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4975 cfg.physAddr = ioc2_dma;
4976 if (mpt_config(ioc, &cfg) != 0)
4979 mem = kmalloc(iocpage2sz, GFP_KERNEL);
4983 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
4984 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
4986 mpt_read_ioc_pg_3(ioc);
4988 for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
4989 mpt_inactive_raid_volumes(ioc,
4990 pIoc2->RaidVolume[i].VolumeBus,
4991 pIoc2->RaidVolume[i].VolumeID);
4994 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
5000 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
5005 ConfigPageHeader_t header;
5006 dma_addr_t ioc3_dma;
5009 /* Free the old page
5011 kfree(ioc->raid_data.pIocPg3);
5012 ioc->raid_data.pIocPg3 = NULL;
5014 /* There is at least one physical disk.
5015 * Read and save IOC Page 3
5017 header.PageVersion = 0;
5018 header.PageLength = 0;
5019 header.PageNumber = 3;
5020 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5021 cfg.cfghdr.hdr = &header;
5024 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5027 if (mpt_config(ioc, &cfg) != 0)
5030 if (header.PageLength == 0)
5033 /* Read Header good, alloc memory
5035 iocpage3sz = header.PageLength * 4;
5036 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
5040 /* Read the Page and save the data
5041 * into malloc'd memory.
5043 cfg.physAddr = ioc3_dma;
5044 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5045 if (mpt_config(ioc, &cfg) == 0) {
5046 mem = kmalloc(iocpage3sz, GFP_KERNEL);
5048 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
5049 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
5053 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
5059 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
5063 ConfigPageHeader_t header;
5064 dma_addr_t ioc4_dma;
5067 /* Read and save IOC Page 4
5069 header.PageVersion = 0;
5070 header.PageLength = 0;
5071 header.PageNumber = 4;
5072 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5073 cfg.cfghdr.hdr = &header;
5076 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5079 if (mpt_config(ioc, &cfg) != 0)
5082 if (header.PageLength == 0)
5085 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
5086 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
5087 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
5090 ioc->alloc_total += iocpage4sz;
5092 ioc4_dma = ioc->spi_data.IocPg4_dma;
5093 iocpage4sz = ioc->spi_data.IocPg4Sz;
5096 /* Read the Page into dma memory.
5098 cfg.physAddr = ioc4_dma;
5099 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5100 if (mpt_config(ioc, &cfg) == 0) {
5101 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
5102 ioc->spi_data.IocPg4_dma = ioc4_dma;
5103 ioc->spi_data.IocPg4Sz = iocpage4sz;
5105 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
5106 ioc->spi_data.pIocPg4 = NULL;
5107 ioc->alloc_total -= iocpage4sz;
5112 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
5116 ConfigPageHeader_t header;
5117 dma_addr_t ioc1_dma;
5121 /* Check the Coalescing Timeout in IOC Page 1
5123 header.PageVersion = 0;
5124 header.PageLength = 0;
5125 header.PageNumber = 1;
5126 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5127 cfg.cfghdr.hdr = &header;
5130 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5133 if (mpt_config(ioc, &cfg) != 0)
5136 if (header.PageLength == 0)
5139 /* Read Header good, alloc memory
5141 iocpage1sz = header.PageLength * 4;
5142 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
5146 /* Read the Page and check coalescing timeout
5148 cfg.physAddr = ioc1_dma;
5149 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5150 if (mpt_config(ioc, &cfg) == 0) {
5152 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
5153 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
5154 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
5156 dprintk((MYIOC_s_INFO_FMT "Coalescing Enabled Timeout = %d\n",
5159 if (tmp > MPT_COALESCING_TIMEOUT) {
5160 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
5162 /* Write NVRAM and current
5165 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5166 if (mpt_config(ioc, &cfg) == 0) {
5167 dprintk((MYIOC_s_INFO_FMT "Reset Current Coalescing Timeout to = %d\n",
5168 ioc->name, MPT_COALESCING_TIMEOUT));
5170 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
5171 if (mpt_config(ioc, &cfg) == 0) {
5172 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout to = %d\n",
5173 ioc->name, MPT_COALESCING_TIMEOUT));
5175 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout Failed\n",
5180 dprintk((MYIOC_s_WARN_FMT "Reset of Current Coalescing Timeout Failed!\n",
5186 dprintk((MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
5190 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
5196 mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
5199 ConfigPageHeader_t hdr;
5201 ManufacturingPage0_t *pbuf = NULL;
5203 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5204 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5206 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
5207 cfg.cfghdr.hdr = &hdr;
5209 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5212 if (mpt_config(ioc, &cfg) != 0)
5215 if (!cfg.cfghdr.hdr->PageLength)
5218 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5219 pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
5223 cfg.physAddr = buf_dma;
5225 if (mpt_config(ioc, &cfg) != 0)
5228 memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name));
5229 memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
5230 memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
5235 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
5238 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5240 * SendEventNotification - Send EventNotification (on or off) request to adapter
5241 * @ioc: Pointer to MPT_ADAPTER structure
5242 * @EvSwitch: Event switch flags
5245 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
5247 EventNotification_t *evnp;
5249 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
5251 devtverboseprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
5255 memset(evnp, 0, sizeof(*evnp));
5257 devtverboseprintk((MYIOC_s_INFO_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
5259 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
5260 evnp->ChainOffset = 0;
5262 evnp->Switch = EvSwitch;
5264 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
5269 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5271 * SendEventAck - Send EventAck request to MPT adapter.
5272 * @ioc: Pointer to MPT_ADAPTER structure
5273 * @evnp: Pointer to original EventNotification request
5276 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
5280 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5281 dfailprintk((MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
5282 ioc->name,__FUNCTION__));
5286 devtverboseprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name));
5288 pAck->Function = MPI_FUNCTION_EVENT_ACK;
5289 pAck->ChainOffset = 0;
5290 pAck->Reserved[0] = pAck->Reserved[1] = 0;
5292 pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
5293 pAck->Event = evnp->Event;
5294 pAck->EventContext = evnp->EventContext;
5296 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
5301 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5303 * mpt_config - Generic function to issue config message
5304 * @ioc: Pointer to an adapter structure
5305 * @pCfg: Pointer to a configuration structure. Struct contains
5306 * action, page address, direction, physical address
5307 * and pointer to a configuration page header
5308 * Page header is updated.
5310 * Returns 0 for success
5311 * -EPERM if not allowed due to ISR context
5312 * -EAGAIN if no msg frames currently available
5313 * -EFAULT for non-successful reply or no reply (timeout)
5316 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5319 ConfigExtendedPageHeader_t *pExtHdr = NULL;
5321 unsigned long flags;
5326 /* Prevent calling wait_event() (below), if caller happens
5327 * to be in ISR context, because that is fatal!
5329 in_isr = in_interrupt();
5331 dcprintk((MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
5336 /* Get and Populate a free Frame
5338 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5339 dcprintk((MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
5343 pReq = (Config_t *)mf;
5344 pReq->Action = pCfg->action;
5346 pReq->ChainOffset = 0;
5347 pReq->Function = MPI_FUNCTION_CONFIG;
5349 /* Assume page type is not extended and clear "reserved" fields. */
5350 pReq->ExtPageLength = 0;
5351 pReq->ExtPageType = 0;
5354 for (ii=0; ii < 8; ii++)
5355 pReq->Reserved2[ii] = 0;
5357 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
5358 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
5359 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
5360 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
5362 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5363 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
5364 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
5365 pReq->ExtPageType = pExtHdr->ExtPageType;
5366 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
5368 /* Page Length must be treated as a reserved field for the extended header. */
5369 pReq->Header.PageLength = 0;
5372 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
5374 /* Add a SGE to the config request.
5377 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
5379 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
5381 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5382 flagsLength |= pExtHdr->ExtPageLength * 4;
5384 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
5385 ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action));
5388 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
5390 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
5391 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
5394 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
5396 /* Append pCfg pointer to end of mf
5398 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5400 /* Initalize the timer
5402 init_timer(&pCfg->timer);
5403 pCfg->timer.data = (unsigned long) ioc;
5404 pCfg->timer.function = mpt_timer_expired;
5405 pCfg->wait_done = 0;
5407 /* Set the timer; ensure 10 second minimum */
5408 if (pCfg->timeout < 10)
5409 pCfg->timer.expires = jiffies + HZ*10;
5411 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5413 /* Add to end of Q, set timer and then issue this command */
5414 spin_lock_irqsave(&ioc->FreeQlock, flags);
5415 list_add_tail(&pCfg->linkage, &ioc->configQ);
5416 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5418 add_timer(&pCfg->timer);
5419 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5420 wait_event(mpt_waitq, pCfg->wait_done);
5422 /* mf has been freed - do not access */
5429 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5431 * mpt_timer_expired - Callback for timer process.
5432 * Used only internal config functionality.
5433 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5436 mpt_timer_expired(unsigned long data)
5438 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
5440 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired! \n", ioc->name));
5442 /* Perform a FW reload */
5443 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
5444 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
5446 /* No more processing.
5447 * Hard reset clean-up will wake up
5448 * process and free all resources.
5450 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired complete!\n", ioc->name));
5455 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5457 * mpt_ioc_reset - Base cleanup for hard reset
5458 * @ioc: Pointer to the adapter structure
5459 * @reset_phase: Indicates pre- or post-reset functionality
5461 * Remark: Frees resources with internally generated commands.
5464 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
5467 unsigned long flags;
5469 dprintk((KERN_WARNING MYNAM
5470 ": IOC %s_reset routed to MPT base driver!\n",
5471 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
5472 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
5474 if (reset_phase == MPT_IOC_SETUP_RESET) {
5476 } else if (reset_phase == MPT_IOC_PRE_RESET) {
5477 /* If the internal config Q is not empty -
5478 * delete timer. MF resources will be freed when
5479 * the FIFO's are primed.
5481 spin_lock_irqsave(&ioc->FreeQlock, flags);
5482 list_for_each_entry(pCfg, &ioc->configQ, linkage)
5483 del_timer(&pCfg->timer);
5484 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5489 /* Search the configQ for internal commands.
5490 * Flush the Q, and wake up all suspended threads.
5492 spin_lock_irqsave(&ioc->FreeQlock, flags);
5493 list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
5494 list_del(&pCfg->linkage);
5496 pCfg->status = MPT_CONFIG_ERROR;
5497 pCfg->wait_done = 1;
5498 wake_up(&mpt_waitq);
5500 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5503 return 1; /* currently means nothing really */
5507 #ifdef CONFIG_PROC_FS /* { */
5508 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5510 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5512 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5514 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5516 * Returns 0 for success, non-zero for failure.
5519 procmpt_create(void)
5521 struct proc_dir_entry *ent;
5523 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
5524 if (mpt_proc_root_dir == NULL)
5527 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5529 ent->read_proc = procmpt_summary_read;
5531 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5533 ent->read_proc = procmpt_version_read;
5538 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5540 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5542 * Returns 0 for success, non-zero for failure.
5545 procmpt_destroy(void)
5547 remove_proc_entry("version", mpt_proc_root_dir);
5548 remove_proc_entry("summary", mpt_proc_root_dir);
5549 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
5552 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5554 * procmpt_summary_read - Handle read request of a summary file
5555 * @buf: Pointer to area to write information
5556 * @start: Pointer to start pointer
5557 * @offset: Offset to start writing
5558 * @request: Amount of read data requested
5559 * @eof: Pointer to EOF integer
5562 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
5563 * Returns number of characters written to process performing the read.
5566 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5576 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5580 list_for_each_entry(ioc, &ioc_list, list) {
5583 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5586 if ((out-buf) >= request)
5593 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5596 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5598 * procmpt_version_read - Handle read request from /proc/mpt/version.
5599 * @buf: Pointer to area to write information
5600 * @start: Pointer to start pointer
5601 * @offset: Offset to start writing
5602 * @request: Amount of read data requested
5603 * @eof: Pointer to EOF integer
5606 * Returns number of characters written to process performing the read.
5609 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5612 int scsi, fc, sas, lan, ctl, targ, dmp;
5616 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
5617 len += sprintf(buf+len, " Fusion MPT base driver\n");
5619 scsi = fc = sas = lan = ctl = targ = dmp = 0;
5620 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5622 if (MptCallbacks[ii]) {
5623 switch (MptDriverClass[ii]) {
5625 if (!scsi++) drvname = "SPI host";
5628 if (!fc++) drvname = "FC host";
5631 if (!sas++) drvname = "SAS host";
5634 if (!lan++) drvname = "LAN";
5637 if (!targ++) drvname = "SCSI target";
5640 if (!ctl++) drvname = "ioctl";
5645 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
5649 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5652 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5654 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
5655 * @buf: Pointer to area to write information
5656 * @start: Pointer to start pointer
5657 * @offset: Offset to start writing
5658 * @request: Amount of read data requested
5659 * @eof: Pointer to EOF integer
5662 * Returns number of characters written to process performing the read.
5665 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5667 MPT_ADAPTER *ioc = data;
5673 mpt_get_fw_exp_ver(expVer, ioc);
5675 len = sprintf(buf, "%s:", ioc->name);
5676 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
5677 len += sprintf(buf+len, " (f/w download boot flag set)");
5678 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
5679 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
5681 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
5682 ioc->facts.ProductID,
5684 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
5685 if (ioc->facts.FWImageSize)
5686 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
5687 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
5688 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
5689 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
5691 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
5692 ioc->facts.CurrentHostMfaHighAddr);
5693 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
5694 ioc->facts.CurrentSenseBufferHighAddr);
5696 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
5697 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
5699 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
5700 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
5702 * Rounding UP to nearest 4-kB boundary here...
5704 sz = (ioc->req_sz * ioc->req_depth) + 128;
5705 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
5706 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
5707 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
5708 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
5709 4*ioc->facts.RequestFrameSize,
5710 ioc->facts.GlobalCredits);
5712 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
5713 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
5714 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
5715 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
5716 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
5717 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
5718 ioc->facts.CurReplyFrameSize,
5719 ioc->facts.ReplyQueueDepth);
5721 len += sprintf(buf+len, " MaxDevices = %d\n",
5722 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
5723 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
5726 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
5727 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
5729 ioc->facts.NumberOfPorts);
5730 if (ioc->bus_type == FC) {
5731 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
5732 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5733 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
5734 a[5], a[4], a[3], a[2], a[1], a[0]);
5736 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
5737 ioc->fc_port_page0[p].WWNN.High,
5738 ioc->fc_port_page0[p].WWNN.Low,
5739 ioc->fc_port_page0[p].WWPN.High,
5740 ioc->fc_port_page0[p].WWPN.Low);
5744 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5747 #endif /* CONFIG_PROC_FS } */
5749 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5751 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
5754 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
5755 sprintf(buf, " (Exp %02d%02d)",
5756 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
5757 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
5760 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
5761 strcat(buf, " [MDBG]");
5765 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5767 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
5768 * @ioc: Pointer to MPT_ADAPTER structure
5769 * @buffer: Pointer to buffer where IOC summary info should be written
5770 * @size: Pointer to number of bytes we wrote (set by this routine)
5771 * @len: Offset at which to start writing in buffer
5772 * @showlan: Display LAN stuff?
5774 * This routine writes (english readable) ASCII text, which represents
5775 * a summary of IOC information, to a buffer.
5778 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
5783 mpt_get_fw_exp_ver(expVer, ioc);
5786 * Shorter summary of attached ioc's...
5788 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
5791 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
5792 ioc->facts.FWVersion.Word,
5794 ioc->facts.NumberOfPorts,
5797 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
5798 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5799 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
5800 a[5], a[4], a[3], a[2], a[1], a[0]);
5803 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
5806 y += sprintf(buffer+len+y, " (disabled)");
5808 y += sprintf(buffer+len+y, "\n");
5813 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5817 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5819 * mpt_HardResetHandler - Generic reset handler
5820 * @ioc: Pointer to MPT_ADAPTER structure
5821 * @sleepFlag: Indicates if sleep or schedule must be called.
5823 * Issues SCSI Task Management call based on input arg values.
5824 * If TaskMgmt fails, returns associated SCSI request.
5826 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
5827 * or a non-interrupt thread. In the former, must not call schedule().
5829 * Note: A return of -1 is a FATAL error case, as it means a
5830 * FW reload/initialization failed.
5832 * Returns 0 for SUCCESS or -1 if FAILED.
5835 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
5838 unsigned long flags;
5840 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name));
5842 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
5843 printk("MF count 0x%x !\n", ioc->mfcnt);
5846 /* Reset the adapter. Prevent more than 1 call to
5847 * mpt_do_ioc_recovery at any instant in time.
5849 spin_lock_irqsave(&ioc->diagLock, flags);
5850 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
5851 spin_unlock_irqrestore(&ioc->diagLock, flags);
5854 ioc->diagPending = 1;
5856 spin_unlock_irqrestore(&ioc->diagLock, flags);
5858 /* FIXME: If do_ioc_recovery fails, repeat....
5861 /* The SCSI driver needs to adjust timeouts on all current
5862 * commands prior to the diagnostic reset being issued.
5863 * Prevents timeouts occurring during a diagnostic reset...very bad.
5864 * For all other protocol drivers, this is a no-op.
5870 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5871 if (MptResetHandlers[ii]) {
5872 dtmprintk((MYIOC_s_INFO_FMT "Calling IOC reset_setup handler #%d\n",
5874 r += mpt_signal_reset(ii, ioc, MPT_IOC_SETUP_RESET);
5876 dtmprintk((MYIOC_s_INFO_FMT "Calling alt-%s setup reset handler #%d\n",
5877 ioc->name, ioc->alt_ioc->name, ii));
5878 r += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_SETUP_RESET);
5884 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
5885 printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
5890 ioc->alt_ioc->reload_fw = 0;
5892 spin_lock_irqsave(&ioc->diagLock, flags);
5893 ioc->diagPending = 0;
5895 ioc->alt_ioc->diagPending = 0;
5896 spin_unlock_irqrestore(&ioc->diagLock, flags);
5898 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
5903 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5905 EventDescriptionStr(u8 event, u32 evData0, char *evStr)
5910 case MPI_EVENT_NONE:
5913 case MPI_EVENT_LOG_DATA:
5916 case MPI_EVENT_STATE_CHANGE:
5917 ds = "State Change";
5919 case MPI_EVENT_UNIT_ATTENTION:
5920 ds = "Unit Attention";
5922 case MPI_EVENT_IOC_BUS_RESET:
5923 ds = "IOC Bus Reset";
5925 case MPI_EVENT_EXT_BUS_RESET:
5926 ds = "External Bus Reset";
5928 case MPI_EVENT_RESCAN:
5929 ds = "Bus Rescan Event";
5931 case MPI_EVENT_LINK_STATUS_CHANGE:
5932 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
5933 ds = "Link Status(FAILURE) Change";
5935 ds = "Link Status(ACTIVE) Change";
5937 case MPI_EVENT_LOOP_STATE_CHANGE:
5938 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
5939 ds = "Loop State(LIP) Change";
5940 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
5941 ds = "Loop State(LPE) Change"; /* ??? */
5943 ds = "Loop State(LPB) Change"; /* ??? */
5945 case MPI_EVENT_LOGOUT:
5948 case MPI_EVENT_EVENT_CHANGE:
5954 case MPI_EVENT_INTEGRATED_RAID:
5956 u8 ReasonCode = (u8)(evData0 >> 16);
5957 switch (ReasonCode) {
5958 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
5959 ds = "Integrated Raid: Volume Created";
5961 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
5962 ds = "Integrated Raid: Volume Deleted";
5964 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
5965 ds = "Integrated Raid: Volume Settings Changed";
5967 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
5968 ds = "Integrated Raid: Volume Status Changed";
5970 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
5971 ds = "Integrated Raid: Volume Physdisk Changed";
5973 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
5974 ds = "Integrated Raid: Physdisk Created";
5976 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
5977 ds = "Integrated Raid: Physdisk Deleted";
5979 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
5980 ds = "Integrated Raid: Physdisk Settings Changed";
5982 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
5983 ds = "Integrated Raid: Physdisk Status Changed";
5985 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
5986 ds = "Integrated Raid: Domain Validation Needed";
5988 case MPI_EVENT_RAID_RC_SMART_DATA :
5989 ds = "Integrated Raid; Smart Data";
5991 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
5992 ds = "Integrated Raid: Replace Action Started";
5995 ds = "Integrated Raid";
6000 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
6001 ds = "SCSI Device Status Change";
6003 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
6005 u8 id = (u8)(evData0);
6006 u8 channel = (u8)(evData0 >> 8);
6007 u8 ReasonCode = (u8)(evData0 >> 16);
6008 switch (ReasonCode) {
6009 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
6010 snprintf(evStr, EVENT_DESCR_STR_SZ,
6011 "SAS Device Status Change: Added: "
6012 "id=%d channel=%d", id, channel);
6014 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
6015 snprintf(evStr, EVENT_DESCR_STR_SZ,
6016 "SAS Device Status Change: Deleted: "
6017 "id=%d channel=%d", id, channel);
6019 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
6020 snprintf(evStr, EVENT_DESCR_STR_SZ,
6021 "SAS Device Status Change: SMART Data: "
6022 "id=%d channel=%d", id, channel);
6024 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
6025 snprintf(evStr, EVENT_DESCR_STR_SZ,
6026 "SAS Device Status Change: No Persistancy: "
6027 "id=%d channel=%d", id, channel);
6029 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
6030 snprintf(evStr, EVENT_DESCR_STR_SZ,
6031 "SAS Device Status Change: Unsupported Device "
6032 "Discovered : id=%d channel=%d", id, channel);
6034 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
6035 snprintf(evStr, EVENT_DESCR_STR_SZ,
6036 "SAS Device Status Change: Internal Device "
6037 "Reset : id=%d channel=%d", id, channel);
6039 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
6040 snprintf(evStr, EVENT_DESCR_STR_SZ,
6041 "SAS Device Status Change: Internal Task "
6042 "Abort : id=%d channel=%d", id, channel);
6044 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
6045 snprintf(evStr, EVENT_DESCR_STR_SZ,
6046 "SAS Device Status Change: Internal Abort "
6047 "Task Set : id=%d channel=%d", id, channel);
6049 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
6050 snprintf(evStr, EVENT_DESCR_STR_SZ,
6051 "SAS Device Status Change: Internal Clear "
6052 "Task Set : id=%d channel=%d", id, channel);
6054 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
6055 snprintf(evStr, EVENT_DESCR_STR_SZ,
6056 "SAS Device Status Change: Internal Query "
6057 "Task : id=%d channel=%d", id, channel);
6060 snprintf(evStr, EVENT_DESCR_STR_SZ,
6061 "SAS Device Status Change: Unknown: "
6062 "id=%d channel=%d", id, channel);
6067 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
6068 ds = "Bus Timer Expired";
6070 case MPI_EVENT_QUEUE_FULL:
6072 u16 curr_depth = (u16)(evData0 >> 16);
6073 u8 channel = (u8)(evData0 >> 8);
6074 u8 id = (u8)(evData0);
6076 snprintf(evStr, EVENT_DESCR_STR_SZ,
6077 "Queue Full: channel=%d id=%d depth=%d",
6078 channel, id, curr_depth);
6081 case MPI_EVENT_SAS_SES:
6082 ds = "SAS SES Event";
6084 case MPI_EVENT_PERSISTENT_TABLE_FULL:
6085 ds = "Persistent Table Full";
6087 case MPI_EVENT_SAS_PHY_LINK_STATUS:
6089 u8 LinkRates = (u8)(evData0 >> 8);
6090 u8 PhyNumber = (u8)(evData0);
6091 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
6092 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
6093 switch (LinkRates) {
6094 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
6095 snprintf(evStr, EVENT_DESCR_STR_SZ,
6096 "SAS PHY Link Status: Phy=%d:"
6097 " Rate Unknown",PhyNumber);
6099 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
6100 snprintf(evStr, EVENT_DESCR_STR_SZ,
6101 "SAS PHY Link Status: Phy=%d:"
6102 " Phy Disabled",PhyNumber);
6104 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
6105 snprintf(evStr, EVENT_DESCR_STR_SZ,
6106 "SAS PHY Link Status: Phy=%d:"
6107 " Failed Speed Nego",PhyNumber);
6109 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
6110 snprintf(evStr, EVENT_DESCR_STR_SZ,
6111 "SAS PHY Link Status: Phy=%d:"
6112 " Sata OOB Completed",PhyNumber);
6114 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
6115 snprintf(evStr, EVENT_DESCR_STR_SZ,
6116 "SAS PHY Link Status: Phy=%d:"
6117 " Rate 1.5 Gbps",PhyNumber);
6119 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
6120 snprintf(evStr, EVENT_DESCR_STR_SZ,
6121 "SAS PHY Link Status: Phy=%d:"
6122 " Rate 3.0 Gpbs",PhyNumber);
6125 snprintf(evStr, EVENT_DESCR_STR_SZ,
6126 "SAS PHY Link Status: Phy=%d", PhyNumber);
6131 case MPI_EVENT_SAS_DISCOVERY_ERROR:
6132 ds = "SAS Discovery Error";
6134 case MPI_EVENT_IR_RESYNC_UPDATE:
6136 u8 resync_complete = (u8)(evData0 >> 16);
6137 snprintf(evStr, EVENT_DESCR_STR_SZ,
6138 "IR Resync Update: Complete = %d:",resync_complete);
6143 u8 ReasonCode = (u8)(evData0 >> 16);
6144 switch (ReasonCode) {
6145 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
6146 ds = "IR2: LD State Changed";
6148 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
6149 ds = "IR2: PD State Changed";
6151 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
6152 ds = "IR2: Bad Block Table Full";
6154 case MPI_EVENT_IR2_RC_PD_INSERTED:
6155 ds = "IR2: PD Inserted";
6157 case MPI_EVENT_IR2_RC_PD_REMOVED:
6158 ds = "IR2: PD Removed";
6160 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
6161 ds = "IR2: Foreign CFG Detected";
6163 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
6164 ds = "IR2: Rebuild Medium Error";
6172 case MPI_EVENT_SAS_DISCOVERY:
6175 ds = "SAS Discovery: Start";
6177 ds = "SAS Discovery: Stop";
6180 case MPI_EVENT_LOG_ENTRY_ADDED:
6181 ds = "SAS Log Entry Added";
6184 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
6186 u8 phy_num = (u8)(evData0);
6187 u8 port_num = (u8)(evData0 >> 8);
6188 u8 port_width = (u8)(evData0 >> 16);
6189 u8 primative = (u8)(evData0 >> 24);
6190 snprintf(evStr, EVENT_DESCR_STR_SZ,
6191 "SAS Broadcase Primative: phy=%d port=%d "
6192 "width=%d primative=0x%02x",
6193 phy_num, port_num, port_width, primative);
6197 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
6199 u8 reason = (u8)(evData0);
6200 u8 port_num = (u8)(evData0 >> 8);
6201 u16 handle = le16_to_cpu(evData0 >> 16);
6203 snprintf(evStr, EVENT_DESCR_STR_SZ,
6204 "SAS Initiator Device Status Change: reason=0x%02x "
6205 "port=%d handle=0x%04x",
6206 reason, port_num, handle);
6210 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
6212 u8 max_init = (u8)(evData0);
6213 u8 current_init = (u8)(evData0 >> 8);
6215 snprintf(evStr, EVENT_DESCR_STR_SZ,
6216 "SAS Initiator Device Table Overflow: max initiators=%02d "
6217 "current initators=%02d",
6218 max_init, current_init);
6221 case MPI_EVENT_SAS_SMP_ERROR:
6223 u8 status = (u8)(evData0);
6224 u8 port_num = (u8)(evData0 >> 8);
6225 u8 result = (u8)(evData0 >> 16);
6227 if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
6228 snprintf(evStr, EVENT_DESCR_STR_SZ,
6229 "SAS SMP Error: port=%d result=0x%02x",
6231 else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
6232 snprintf(evStr, EVENT_DESCR_STR_SZ,
6233 "SAS SMP Error: port=%d : CRC Error",
6235 else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
6236 snprintf(evStr, EVENT_DESCR_STR_SZ,
6237 "SAS SMP Error: port=%d : Timeout",
6239 else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
6240 snprintf(evStr, EVENT_DESCR_STR_SZ,
6241 "SAS SMP Error: port=%d : No Destination",
6243 else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
6244 snprintf(evStr, EVENT_DESCR_STR_SZ,
6245 "SAS SMP Error: port=%d : Bad Destination",
6248 snprintf(evStr, EVENT_DESCR_STR_SZ,
6249 "SAS SMP Error: port=%d : status=0x%02x",
6255 * MPT base "custom" events may be added here...
6262 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
6265 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6267 * ProcessEventNotification - Route EventNotificationReply to all event handlers
6268 * @ioc: Pointer to MPT_ADAPTER structure
6269 * @pEventReply: Pointer to EventNotification reply frame
6270 * @evHandlers: Pointer to integer, number of event handlers
6272 * Routes a received EventNotificationReply to all currently registered
6274 * Returns sum of event handlers return values.
6277 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
6285 char evStr[EVENT_DESCR_STR_SZ];
6289 * Do platform normalization of values
6291 event = le32_to_cpu(pEventReply->Event) & 0xFF;
6292 // evCtx = le32_to_cpu(pEventReply->EventContext);
6293 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
6295 evData0 = le32_to_cpu(pEventReply->Data[0]);
6298 EventDescriptionStr(event, evData0, evStr);
6299 devtprintk((MYIOC_s_INFO_FMT "MPT event:(%02Xh) : %s\n",
6304 #if defined(MPT_DEBUG) || defined(MPT_DEBUG_VERBOSE_EVENTS)
6305 printk(KERN_INFO MYNAM ": Event data:\n" KERN_INFO);
6306 for (ii = 0; ii < evDataLen; ii++)
6307 printk(" %08x", le32_to_cpu(pEventReply->Data[ii]));
6312 * Do general / base driver event processing
6315 case MPI_EVENT_EVENT_CHANGE: /* 0A */
6317 u8 evState = evData0 & 0xFF;
6319 /* CHECKME! What if evState unexpectedly says OFF (0)? */
6321 /* Update EventState field in cached IocFacts */
6322 if (ioc->facts.Function) {
6323 ioc->facts.EventState = evState;
6327 case MPI_EVENT_INTEGRATED_RAID:
6328 mptbase_raid_process_event_data(ioc,
6329 (MpiEventDataRaid_t *)pEventReply->Data);
6336 * Should this event be logged? Events are written sequentially.
6337 * When buffer is full, start again at the top.
6339 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
6342 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
6344 ioc->events[idx].event = event;
6345 ioc->events[idx].eventContext = ioc->eventContext;
6347 for (ii = 0; ii < 2; ii++) {
6349 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
6351 ioc->events[idx].data[ii] = 0;
6354 ioc->eventContext++;
6359 * Call each currently registered protocol event handler.
6361 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
6362 if (MptEvHandlers[ii]) {
6363 devtverboseprintk((MYIOC_s_INFO_FMT "Routing Event to event handler #%d\n",
6365 r += (*(MptEvHandlers[ii]))(ioc, pEventReply);
6369 /* FIXME? Examine results here? */
6372 * If needed, send (a single) EventAck.
6374 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
6375 devtverboseprintk((MYIOC_s_WARN_FMT
6376 "EventAck required\n",ioc->name));
6377 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
6378 devtverboseprintk((MYIOC_s_WARN_FMT "SendEventAck returned %d\n",
6383 *evHandlers = handlers;
6387 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6389 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
6390 * @ioc: Pointer to MPT_ADAPTER structure
6391 * @log_info: U32 LogInfo reply word from the IOC
6393 * Refer to lsi/mpi_log_fc.h.
6396 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
6398 char *desc = "unknown";
6400 switch (log_info & 0xFF000000) {
6401 case MPI_IOCLOGINFO_FC_INIT_BASE:
6402 desc = "FCP Initiator";
6404 case MPI_IOCLOGINFO_FC_TARGET_BASE:
6405 desc = "FCP Target";
6407 case MPI_IOCLOGINFO_FC_LAN_BASE:
6410 case MPI_IOCLOGINFO_FC_MSG_BASE:
6411 desc = "MPI Message Layer";
6413 case MPI_IOCLOGINFO_FC_LINK_BASE:
6416 case MPI_IOCLOGINFO_FC_CTX_BASE:
6417 desc = "Context Manager";
6419 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
6420 desc = "Invalid Field Offset";
6422 case MPI_IOCLOGINFO_FC_STATE_CHANGE:
6423 desc = "State Change Info";
6427 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
6428 ioc->name, log_info, desc, (log_info & 0xFFFFFF));
6431 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6433 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
6434 * @ioc: Pointer to MPT_ADAPTER structure
6435 * @mr: Pointer to MPT reply frame
6436 * @log_info: U32 LogInfo word from the IOC
6438 * Refer to lsi/sp_log.h.
6441 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
6443 u32 info = log_info & 0x00FF0000;
6444 char *desc = "unknown";
6448 desc = "bug! MID not found";
6449 if (ioc->reload_fw == 0)
6454 desc = "Parity Error";
6458 desc = "ASYNC Outbound Overrun";
6462 desc = "SYNC Offset Error";
6470 desc = "Msg In Overflow";
6478 desc = "Outbound DMA Overrun";
6482 desc = "Task Management";
6486 desc = "Device Problem";
6490 desc = "Invalid Phase Change";
6494 desc = "Untagged Table Size";
6499 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
6502 /* strings for sas loginfo */
6503 static char *originator_str[] = {
6508 static char *iop_code_str[] = {
6510 "Invalid SAS Address", /* 01h */
6512 "Invalid Page", /* 03h */
6513 "Diag Message Error", /* 04h */
6514 "Task Terminated", /* 05h */
6515 "Enclosure Management", /* 06h */
6516 "Target Mode" /* 07h */
6518 static char *pl_code_str[] = {
6520 "Open Failure", /* 01h */
6521 "Invalid Scatter Gather List", /* 02h */
6522 "Wrong Relative Offset or Frame Length", /* 03h */
6523 "Frame Transfer Error", /* 04h */
6524 "Transmit Frame Connected Low", /* 05h */
6525 "SATA Non-NCQ RW Error Bit Set", /* 06h */
6526 "SATA Read Log Receive Data Error", /* 07h */
6527 "SATA NCQ Fail All Commands After Error", /* 08h */
6528 "SATA Error in Receive Set Device Bit FIS", /* 09h */
6529 "Receive Frame Invalid Message", /* 0Ah */
6530 "Receive Context Message Valid Error", /* 0Bh */
6531 "Receive Frame Current Frame Error", /* 0Ch */
6532 "SATA Link Down", /* 0Dh */
6533 "Discovery SATA Init W IOS", /* 0Eh */
6534 "Config Invalid Page", /* 0Fh */
6535 "Discovery SATA Init Timeout", /* 10h */
6538 "IO Not Yet Executed", /* 13h */
6539 "IO Executed", /* 14h */
6540 "Persistent Reservation Out Not Affiliation "
6542 "Open Transmit DMA Abort", /* 16h */
6543 "IO Device Missing Delay Retry", /* 17h */
6544 "IO Cancelled Due to Recieve Error", /* 18h */
6552 "Enclosure Management" /* 20h */
6554 static char *ir_code_str[] = {
6555 "Raid Action Error", /* 00h */
6565 static char *raid_sub_code_str[] = {
6567 "Volume Creation Failed: Data Passed too "
6569 "Volume Creation Failed: Duplicate Volumes "
6570 "Attempted", /* 02h */
6571 "Volume Creation Failed: Max Number "
6572 "Supported Volumes Exceeded", /* 03h */
6573 "Volume Creation Failed: DMA Error", /* 04h */
6574 "Volume Creation Failed: Invalid Volume Type", /* 05h */
6575 "Volume Creation Failed: Error Reading "
6576 "MFG Page 4", /* 06h */
6577 "Volume Creation Failed: Creating Internal "
6578 "Structures", /* 07h */
6587 "Activation failed: Already Active Volume", /* 10h */
6588 "Activation failed: Unsupported Volume Type", /* 11h */
6589 "Activation failed: Too Many Active Volumes", /* 12h */
6590 "Activation failed: Volume ID in Use", /* 13h */
6591 "Activation failed: Reported Failure", /* 14h */
6592 "Activation failed: Importing a Volume", /* 15h */
6603 "Phys Disk failed: Too Many Phys Disks", /* 20h */
6604 "Phys Disk failed: Data Passed too Large", /* 21h */
6605 "Phys Disk failed: DMA Error", /* 22h */
6606 "Phys Disk failed: Invalid <channel:id>", /* 23h */
6607 "Phys Disk failed: Creating Phys Disk Config "
6620 "Compatibility Error: IR Disabled", /* 30h */
6621 "Compatibility Error: Inquiry Comand Failed", /* 31h */
6622 "Compatibility Error: Device not Direct Access "
6623 "Device ", /* 32h */
6624 "Compatibility Error: Removable Device Found", /* 33h */
6625 "Compatibility Error: Device SCSI Version not "
6626 "2 or Higher", /* 34h */
6627 "Compatibility Error: SATA Device, 48 BIT LBA "
6628 "not Supported", /* 35h */
6629 "Compatibility Error: Device doesn't have "
6630 "512 Byte Block Sizes", /* 36h */
6631 "Compatibility Error: Volume Type Check Failed", /* 37h */
6632 "Compatibility Error: Volume Type is "
6633 "Unsupported by FW", /* 38h */
6634 "Compatibility Error: Disk Drive too Small for "
6635 "use in Volume", /* 39h */
6636 "Compatibility Error: Phys Disk for Create "
6637 "Volume not Found", /* 3Ah */
6638 "Compatibility Error: Too Many or too Few "
6639 "Disks for Volume Type", /* 3Bh */
6640 "Compatibility Error: Disk stripe Sizes "
6641 "Must be 64KB", /* 3Ch */
6642 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
6645 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6647 * mpt_sas_log_info - Log information returned from SAS IOC.
6648 * @ioc: Pointer to MPT_ADAPTER structure
6649 * @log_info: U32 LogInfo reply word from the IOC
6651 * Refer to lsi/mpi_log_sas.h.
6654 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
6656 union loginfo_type {
6665 union loginfo_type sas_loginfo;
6666 char *originator_desc = NULL;
6667 char *code_desc = NULL;
6668 char *sub_code_desc = NULL;
6670 sas_loginfo.loginfo = log_info;
6671 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
6672 (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
6675 originator_desc = originator_str[sas_loginfo.dw.originator];
6677 switch (sas_loginfo.dw.originator) {
6680 if (sas_loginfo.dw.code <
6681 sizeof(iop_code_str)/sizeof(char*))
6682 code_desc = iop_code_str[sas_loginfo.dw.code];
6685 if (sas_loginfo.dw.code <
6686 sizeof(pl_code_str)/sizeof(char*))
6687 code_desc = pl_code_str[sas_loginfo.dw.code];
6690 if (sas_loginfo.dw.code >=
6691 sizeof(ir_code_str)/sizeof(char*))
6693 code_desc = ir_code_str[sas_loginfo.dw.code];
6694 if (sas_loginfo.dw.subcode >=
6695 sizeof(raid_sub_code_str)/sizeof(char*))
6697 if (sas_loginfo.dw.code == 0)
6699 raid_sub_code_str[sas_loginfo.dw.subcode];
6705 if (sub_code_desc != NULL)
6706 printk(MYIOC_s_INFO_FMT
6707 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
6709 ioc->name, log_info, originator_desc, code_desc,
6711 else if (code_desc != NULL)
6712 printk(MYIOC_s_INFO_FMT
6713 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
6714 " SubCode(0x%04x)\n",
6715 ioc->name, log_info, originator_desc, code_desc,
6716 sas_loginfo.dw.subcode);
6718 printk(MYIOC_s_INFO_FMT
6719 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
6720 " SubCode(0x%04x)\n",
6721 ioc->name, log_info, originator_desc,
6722 sas_loginfo.dw.code, sas_loginfo.dw.subcode);
6725 #ifdef MPT_DEBUG_REPLY
6726 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6728 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
6729 * @ioc: Pointer to MPT_ADAPTER structure
6730 * @ioc_status: U32 IOCStatus word from IOC
6731 * @mf: Pointer to MPT request frame
6733 * Refer to lsi/mpi.h.
6736 mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
6738 Config_t *pReq = (Config_t *)mf;
6739 char extend_desc[EVENT_DESCR_STR_SZ];
6744 if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
6745 page_type = pReq->ExtPageType;
6747 page_type = pReq->Header.PageType;
6750 * ignore invalid page messages for GET_NEXT_HANDLE
6752 form = le32_to_cpu(pReq->PageAddress);
6753 if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
6754 if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
6755 page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
6756 page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
6757 if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
6758 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
6761 if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
6762 if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
6763 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
6767 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
6768 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
6769 page_type, pReq->Header.PageNumber, pReq->Action, form);
6771 switch (ioc_status) {
6773 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
6774 desc = "Config Page Invalid Action";
6777 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
6778 desc = "Config Page Invalid Type";
6781 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
6782 desc = "Config Page Invalid Page";
6785 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
6786 desc = "Config Page Invalid Data";
6789 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
6790 desc = "Config Page No Defaults";
6793 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
6794 desc = "Config Page Can't Commit";
6801 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s: %s\n",
6802 ioc->name, ioc_status, desc, extend_desc);
6806 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
6807 * @ioc: Pointer to MPT_ADAPTER structure
6808 * @ioc_status: U32 IOCStatus word from IOC
6809 * @mf: Pointer to MPT request frame
6811 * Refer to lsi/mpi.h.
6814 mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
6816 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
6821 /****************************************************************************/
6822 /* Common IOCStatus values for all replies */
6823 /****************************************************************************/
6825 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
6826 desc = "Invalid Function";
6829 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
6833 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
6834 desc = "Invalid SGL";
6837 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
6838 desc = "Internal Error";
6841 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
6845 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
6846 desc = "Insufficient Resources";
6849 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
6850 desc = "Invalid Field";
6853 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
6854 desc = "Invalid State";
6857 /****************************************************************************/
6858 /* Config IOCStatus values */
6859 /****************************************************************************/
6861 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
6862 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
6863 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
6864 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
6865 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
6866 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
6867 mpt_iocstatus_info_config(ioc, status, mf);
6870 /****************************************************************************/
6871 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
6873 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
6875 /****************************************************************************/
6877 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
6878 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
6879 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
6880 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
6881 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
6882 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
6883 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
6884 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
6885 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
6886 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
6887 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
6888 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
6889 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
6892 /****************************************************************************/
6893 /* SCSI Target values */
6894 /****************************************************************************/
6896 case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
6897 desc = "Target: Priority IO";
6900 case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
6901 desc = "Target: Invalid Port";
6904 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
6905 desc = "Target Invalid IO Index:";
6908 case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
6909 desc = "Target: Aborted";
6912 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
6913 desc = "Target: No Conn Retryable";
6916 case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
6917 desc = "Target: No Connection";
6920 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
6921 desc = "Target: Transfer Count Mismatch";
6924 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
6925 desc = "Target: STS Data not Sent";
6928 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
6929 desc = "Target: Data Offset Error";
6932 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
6933 desc = "Target: Too Much Write Data";
6936 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
6937 desc = "Target: IU Too Short";
6940 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
6941 desc = "Target: ACK NAK Timeout";
6944 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
6945 desc = "Target: Nak Received";
6948 /****************************************************************************/
6949 /* Fibre Channel Direct Access values */
6950 /****************************************************************************/
6952 case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
6953 desc = "FC: Aborted";
6956 case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
6957 desc = "FC: RX ID Invalid";
6960 case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
6961 desc = "FC: DID Invalid";
6964 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
6965 desc = "FC: Node Logged Out";
6968 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
6969 desc = "FC: Exchange Canceled";
6972 /****************************************************************************/
6974 /****************************************************************************/
6976 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
6977 desc = "LAN: Device not Found";
6980 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
6981 desc = "LAN: Device Failure";
6984 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
6985 desc = "LAN: Transmit Error";
6988 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
6989 desc = "LAN: Transmit Aborted";
6992 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
6993 desc = "LAN: Receive Error";
6996 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
6997 desc = "LAN: Receive Aborted";
7000 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
7001 desc = "LAN: Partial Packet";
7004 case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
7005 desc = "LAN: Canceled";
7008 /****************************************************************************/
7009 /* Serial Attached SCSI values */
7010 /****************************************************************************/
7012 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
7013 desc = "SAS: SMP Request Failed";
7016 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
7017 desc = "SAS: SMP Data Overrun";
7028 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s\n", ioc->name, status, desc);
7032 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7033 EXPORT_SYMBOL(mpt_attach);
7034 EXPORT_SYMBOL(mpt_detach);
7036 EXPORT_SYMBOL(mpt_resume);
7037 EXPORT_SYMBOL(mpt_suspend);
7039 EXPORT_SYMBOL(ioc_list);
7040 EXPORT_SYMBOL(mpt_proc_root_dir);
7041 EXPORT_SYMBOL(mpt_register);
7042 EXPORT_SYMBOL(mpt_deregister);
7043 EXPORT_SYMBOL(mpt_event_register);
7044 EXPORT_SYMBOL(mpt_event_deregister);
7045 EXPORT_SYMBOL(mpt_reset_register);
7046 EXPORT_SYMBOL(mpt_reset_deregister);
7047 EXPORT_SYMBOL(mpt_device_driver_register);
7048 EXPORT_SYMBOL(mpt_device_driver_deregister);
7049 EXPORT_SYMBOL(mpt_get_msg_frame);
7050 EXPORT_SYMBOL(mpt_put_msg_frame);
7051 EXPORT_SYMBOL(mpt_free_msg_frame);
7052 EXPORT_SYMBOL(mpt_add_sge);
7053 EXPORT_SYMBOL(mpt_send_handshake_request);
7054 EXPORT_SYMBOL(mpt_verify_adapter);
7055 EXPORT_SYMBOL(mpt_GetIocState);
7056 EXPORT_SYMBOL(mpt_print_ioc_summary);
7057 EXPORT_SYMBOL(mpt_lan_index);
7058 EXPORT_SYMBOL(mpt_stm_index);
7059 EXPORT_SYMBOL(mpt_HardResetHandler);
7060 EXPORT_SYMBOL(mpt_config);
7061 EXPORT_SYMBOL(mpt_findImVolumes);
7062 EXPORT_SYMBOL(mpt_alloc_fw_memory);
7063 EXPORT_SYMBOL(mpt_free_fw_memory);
7064 EXPORT_SYMBOL(mptbase_sas_persist_operation);
7065 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
7067 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7069 * fusion_init - Fusion MPT base driver initialization routine.
7071 * Returns 0 for success, non-zero for failure.
7078 show_mptmod_ver(my_NAME, my_VERSION);
7079 printk(KERN_INFO COPYRIGHT "\n");
7081 for (i = 0; i < MPT_MAX_PROTOCOL_DRIVERS; i++) {
7082 MptCallbacks[i] = NULL;
7083 MptDriverClass[i] = MPTUNKNOWN_DRIVER;
7084 MptEvHandlers[i] = NULL;
7085 MptResetHandlers[i] = NULL;
7088 /* Register ourselves (mptbase) in order to facilitate
7089 * EventNotification handling.
7091 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
7093 /* Register for hard reset handling callbacks.
7095 if (mpt_reset_register(mpt_base_index, mpt_ioc_reset) == 0) {
7096 dprintk((KERN_INFO MYNAM ": Register for IOC reset notification\n"));
7101 #ifdef CONFIG_PROC_FS
7102 (void) procmpt_create();
7107 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7109 * fusion_exit - Perform driver unload cleanup.
7111 * This routine frees all resources associated with each MPT adapter
7112 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
7118 dexitprintk((KERN_INFO MYNAM ": fusion_exit() called!\n"));
7120 mpt_reset_deregister(mpt_base_index);
7122 #ifdef CONFIG_PROC_FS
7127 module_init(fusion_init);
7128 module_exit(fusion_exit);