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) {
1136 * mpt_get_product_name - returns product string
1137 * @vendor: pci vendor id
1138 * @device: pci device id
1139 * @revision: pci revision id
1140 * @prod_name: string returned
1142 * Returns product string displayed when driver loads,
1143 * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1147 mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name)
1149 char *product_str = NULL;
1151 if (vendor == PCI_VENDOR_ID_BROCADE) {
1154 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1158 product_str = "BRE040 A0";
1161 product_str = "BRE040 A1";
1164 product_str = "BRE040";
1174 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1175 product_str = "LSIFC909 B1";
1177 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1178 product_str = "LSIFC919 B0";
1180 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1181 product_str = "LSIFC929 B0";
1183 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1184 if (revision < 0x80)
1185 product_str = "LSIFC919X A0";
1187 product_str = "LSIFC919XL A1";
1189 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1190 if (revision < 0x80)
1191 product_str = "LSIFC929X A0";
1193 product_str = "LSIFC929XL A1";
1195 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1196 product_str = "LSIFC939X A1";
1198 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1199 product_str = "LSIFC949X A1";
1201 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1205 product_str = "LSIFC949E A0";
1208 product_str = "LSIFC949E A1";
1211 product_str = "LSIFC949E";
1215 case MPI_MANUFACTPAGE_DEVID_53C1030:
1219 product_str = "LSI53C1030 A0";
1222 product_str = "LSI53C1030 B0";
1225 product_str = "LSI53C1030 B1";
1228 product_str = "LSI53C1030 B2";
1231 product_str = "LSI53C1030 C0";
1234 product_str = "LSI53C1030T A0";
1237 product_str = "LSI53C1030T A2";
1240 product_str = "LSI53C1030T A3";
1243 product_str = "LSI53C1020A A1";
1246 product_str = "LSI53C1030";
1250 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1254 product_str = "LSI53C1035 A2";
1257 product_str = "LSI53C1035 B0";
1260 product_str = "LSI53C1035";
1264 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1268 product_str = "LSISAS1064 A1";
1271 product_str = "LSISAS1064 A2";
1274 product_str = "LSISAS1064 A3";
1277 product_str = "LSISAS1064 A4";
1280 product_str = "LSISAS1064";
1284 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1288 product_str = "LSISAS1064E A0";
1291 product_str = "LSISAS1064E B0";
1294 product_str = "LSISAS1064E B1";
1297 product_str = "LSISAS1064E B2";
1300 product_str = "LSISAS1064E B3";
1303 product_str = "LSISAS1064E";
1307 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1311 product_str = "LSISAS1068 A0";
1314 product_str = "LSISAS1068 B0";
1317 product_str = "LSISAS1068 B1";
1320 product_str = "LSISAS1068";
1324 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1328 product_str = "LSISAS1068E A0";
1331 product_str = "LSISAS1068E B0";
1334 product_str = "LSISAS1068E B1";
1337 product_str = "LSISAS1068E B2";
1340 product_str = "LSISAS1068E B3";
1343 product_str = "LSISAS1068E";
1347 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1351 product_str = "LSISAS1078 A0";
1354 product_str = "LSISAS1078 B0";
1357 product_str = "LSISAS1078 C0";
1360 product_str = "LSISAS1078 C1";
1363 product_str = "LSISAS1078 C2";
1366 product_str = "LSISAS1078";
1374 sprintf(prod_name, "%s", product_str);
1377 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1379 * mpt_attach - Install a PCI intelligent MPT adapter.
1380 * @pdev: Pointer to pci_dev structure
1381 * @id: PCI device ID information
1383 * This routine performs all the steps necessary to bring the IOC of
1384 * a MPT adapter to a OPERATIONAL state. This includes registering
1385 * memory regions, registering the interrupt, and allocating request
1386 * and reply memory pools.
1388 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1391 * Returns 0 for success, non-zero for failure.
1393 * TODO: Add support for polled controllers
1396 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1400 unsigned long mem_phys;
1408 static int mpt_ids = 0;
1409 #ifdef CONFIG_PROC_FS
1410 struct proc_dir_entry *dent, *ent;
1413 if (pci_enable_device(pdev))
1416 dinitprintk((KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1418 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
1419 dprintk((KERN_INFO MYNAM
1420 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n"));
1421 } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
1422 printk(KERN_WARNING MYNAM ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");
1426 if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
1427 dprintk((KERN_INFO MYNAM
1428 ": Using 64 bit consistent mask\n"));
1430 dprintk((KERN_INFO MYNAM
1431 ": Not using 64 bit consistent mask\n"));
1433 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1435 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1438 ioc->alloc_total = sizeof(MPT_ADAPTER);
1439 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1440 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1443 ioc->diagPending = 0;
1444 spin_lock_init(&ioc->diagLock);
1445 spin_lock_init(&ioc->initializing_hba_lock);
1447 /* Initialize the event logging.
1449 ioc->eventTypes = 0; /* None */
1450 ioc->eventContext = 0;
1451 ioc->eventLogSize = 0;
1458 ioc->cached_fw = NULL;
1460 /* Initilize SCSI Config Data structure
1462 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1464 /* Initialize the running configQ head.
1466 INIT_LIST_HEAD(&ioc->configQ);
1468 /* Initialize the fc rport list head.
1470 INIT_LIST_HEAD(&ioc->fc_rports);
1472 /* Find lookup slot. */
1473 INIT_LIST_HEAD(&ioc->list);
1474 ioc->id = mpt_ids++;
1476 mem_phys = msize = 0;
1478 for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1479 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1482 /* Get I/O space! */
1483 port = pci_resource_start(pdev, ii);
1484 psize = pci_resource_len(pdev,ii);
1489 mem_phys = pci_resource_start(pdev, ii);
1490 msize = pci_resource_len(pdev,ii);
1493 ioc->mem_size = msize;
1496 /* Get logical ptr for PciMem0 space */
1497 /*mem = ioremap(mem_phys, msize);*/
1498 mem = ioremap(mem_phys, msize);
1500 printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n");
1505 dinitprintk((KERN_INFO MYNAM ": mem = %p, mem_phys = %lx\n", mem, mem_phys));
1507 dinitprintk((KERN_INFO MYNAM ": facts @ %p, pfacts[0] @ %p\n",
1508 &ioc->facts, &ioc->pfacts[0]));
1510 ioc->mem_phys = mem_phys;
1511 ioc->chip = (SYSIF_REGS __iomem *)mem;
1513 /* Save Port IO values in case we need to do downloadboot */
1515 u8 *pmem = (u8*)port;
1516 ioc->pio_mem_phys = port;
1517 ioc->pio_chip = (SYSIF_REGS __iomem *)pmem;
1520 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1521 mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name);
1523 switch (pdev->device)
1525 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1526 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1527 ioc->errata_flag_1064 = 1;
1528 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1529 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1530 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1531 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1535 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1536 if (revision < XL_929) {
1537 /* 929X Chip Fix. Set Split transactions level
1538 * for PCIX. Set MOST bits to zero.
1540 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1542 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1544 /* 929XL Chip Fix. Set MMRBC to 0x08.
1546 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1548 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1553 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1554 /* 919X Chip Fix. Set Split transactions level
1555 * for PCIX. Set MOST bits to zero.
1557 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1559 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1563 case MPI_MANUFACTPAGE_DEVID_53C1030:
1564 /* 1030 Chip Fix. Disable Split transactions
1565 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1567 if (revision < C0_1030) {
1568 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1570 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1573 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1574 ioc->bus_type = SPI;
1577 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1578 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1579 ioc->errata_flag_1064 = 1;
1581 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1582 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1583 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1584 ioc->bus_type = SAS;
1587 if (ioc->errata_flag_1064)
1588 pci_disable_io_access(pdev);
1590 sprintf(ioc->name, "ioc%d", ioc->id);
1592 spin_lock_init(&ioc->FreeQlock);
1595 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1597 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1599 /* Set lookup ptr. */
1600 list_add_tail(&ioc->list, &ioc_list);
1602 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1604 mpt_detect_bound_ports(ioc, pdev);
1606 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1608 printk(KERN_WARNING MYNAM
1609 ": WARNING - %s did not initialize properly! (%d)\n",
1612 list_del(&ioc->list);
1614 ioc->alt_ioc->alt_ioc = NULL;
1617 pci_set_drvdata(pdev, NULL);
1621 /* call per device driver probe entry point */
1622 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1623 if(MptDeviceDriverHandlers[ii] &&
1624 MptDeviceDriverHandlers[ii]->probe) {
1625 MptDeviceDriverHandlers[ii]->probe(pdev,id);
1629 #ifdef CONFIG_PROC_FS
1631 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1633 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1635 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1637 ent->read_proc = procmpt_iocinfo_read;
1640 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1642 ent->read_proc = procmpt_summary_read;
1651 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1653 * mpt_detach - Remove a PCI intelligent MPT adapter.
1654 * @pdev: Pointer to pci_dev structure
1658 mpt_detach(struct pci_dev *pdev)
1660 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1664 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
1665 remove_proc_entry(pname, NULL);
1666 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
1667 remove_proc_entry(pname, NULL);
1668 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
1669 remove_proc_entry(pname, NULL);
1671 /* call per device driver remove entry point */
1672 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1673 if(MptDeviceDriverHandlers[ii] &&
1674 MptDeviceDriverHandlers[ii]->remove) {
1675 MptDeviceDriverHandlers[ii]->remove(pdev);
1679 /* Disable interrupts! */
1680 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1683 synchronize_irq(pdev->irq);
1685 /* Clear any lingering interrupt */
1686 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1688 CHIPREG_READ32(&ioc->chip->IntStatus);
1690 mpt_adapter_dispose(ioc);
1692 pci_set_drvdata(pdev, NULL);
1695 /**************************************************************************
1699 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1701 * mpt_suspend - Fusion MPT base driver suspend routine.
1702 * @pdev: Pointer to pci_dev structure
1703 * @state: new state to enter
1706 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
1709 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1711 device_state=pci_choose_state(pdev, state);
1713 printk(MYIOC_s_INFO_FMT
1714 "pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
1715 ioc->name, pdev, pci_name(pdev), device_state);
1717 pci_save_state(pdev);
1719 /* put ioc into READY_STATE */
1720 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
1721 printk(MYIOC_s_ERR_FMT
1722 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
1725 /* disable interrupts */
1726 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1729 /* Clear any lingering interrupt */
1730 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1732 pci_disable_device(pdev);
1733 pci_set_power_state(pdev, device_state);
1738 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1740 * mpt_resume - Fusion MPT base driver resume routine.
1741 * @pdev: Pointer to pci_dev structure
1744 mpt_resume(struct pci_dev *pdev)
1746 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1747 u32 device_state = pdev->current_state;
1751 printk(MYIOC_s_INFO_FMT
1752 "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
1753 ioc->name, pdev, pci_name(pdev), device_state);
1755 pci_set_power_state(pdev, 0);
1756 pci_restore_state(pdev);
1757 err = pci_enable_device(pdev);
1761 /* enable interrupts */
1762 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
1765 printk(MYIOC_s_INFO_FMT
1766 "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1768 (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1769 CHIPREG_READ32(&ioc->chip->Doorbell));
1771 /* bring ioc to operational state */
1772 if ((recovery_state = mpt_do_ioc_recovery(ioc,
1773 MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {
1774 printk(MYIOC_s_INFO_FMT
1775 "pci-resume: Cannot recover, error:[%x]\n",
1776 ioc->name, recovery_state);
1778 printk(MYIOC_s_INFO_FMT
1779 "pci-resume: success\n", ioc->name);
1787 mpt_signal_reset(int index, MPT_ADAPTER *ioc, int reset_phase)
1789 if ((MptDriverClass[index] == MPTSPI_DRIVER &&
1790 ioc->bus_type != SPI) ||
1791 (MptDriverClass[index] == MPTFC_DRIVER &&
1792 ioc->bus_type != FC) ||
1793 (MptDriverClass[index] == MPTSAS_DRIVER &&
1794 ioc->bus_type != SAS))
1795 /* make sure we only call the relevant reset handler
1798 return (MptResetHandlers[index])(ioc, reset_phase);
1801 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1803 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1804 * @ioc: Pointer to MPT adapter structure
1805 * @reason: Event word / reason
1806 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1808 * This routine performs all the steps necessary to bring the IOC
1809 * to a OPERATIONAL state.
1811 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1816 * -1 if failed to get board READY
1817 * -2 if READY but IOCFacts Failed
1818 * -3 if READY but PrimeIOCFifos Failed
1819 * -4 if READY but IOCInit Failed
1822 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1824 int hard_reset_done = 0;
1825 int alt_ioc_ready = 0;
1831 int reset_alt_ioc_active = 0;
1832 int irq_allocated = 0;
1834 printk(KERN_INFO MYNAM ": Initiating %s %s\n",
1835 ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
1837 /* Disable reply interrupts (also blocks FreeQ) */
1838 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1842 if (ioc->alt_ioc->active)
1843 reset_alt_ioc_active = 1;
1845 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1846 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
1847 ioc->alt_ioc->active = 0;
1851 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
1854 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
1855 if (hard_reset_done == -4) {
1856 printk(KERN_WARNING MYNAM ": %s Owned by PEER..skipping!\n",
1859 if (reset_alt_ioc_active && ioc->alt_ioc) {
1860 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1861 dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1862 ioc->alt_ioc->name));
1863 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
1864 ioc->alt_ioc->active = 1;
1868 printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",
1874 /* hard_reset_done = 0 if a soft reset was performed
1875 * and 1 if a hard reset was performed.
1877 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
1878 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
1881 printk(KERN_WARNING MYNAM
1882 ": alt-%s: Not ready WARNING!\n",
1883 ioc->alt_ioc->name);
1886 for (ii=0; ii<5; ii++) {
1887 /* Get IOC facts! Allow 5 retries */
1888 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
1894 dinitprintk((MYIOC_s_INFO_FMT "Retry IocFacts failed rc=%x\n", ioc->name, rc));
1896 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1897 MptDisplayIocCapabilities(ioc);
1900 if (alt_ioc_ready) {
1901 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
1902 dinitprintk((MYIOC_s_INFO_FMT "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
1903 /* Retry - alt IOC was initialized once
1905 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
1908 dinitprintk((MYIOC_s_INFO_FMT "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
1910 reset_alt_ioc_active = 0;
1911 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1912 MptDisplayIocCapabilities(ioc->alt_ioc);
1917 * Device is reset now. It must have de-asserted the interrupt line
1918 * (if it was asserted) and it should be safe to register for the
1921 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1923 if (ioc->pcidev->irq) {
1924 if (mpt_msi_enable && !pci_enable_msi(ioc->pcidev))
1925 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
1927 rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
1928 IRQF_SHARED, ioc->name, ioc);
1930 printk(MYIOC_s_ERR_FMT "Unable to allocate "
1931 "interrupt %d!\n", ioc->name,
1934 pci_disable_msi(ioc->pcidev);
1938 ioc->pci_irq = ioc->pcidev->irq;
1939 pci_set_master(ioc->pcidev); /* ?? */
1940 pci_set_drvdata(ioc->pcidev, ioc);
1941 dprintk((KERN_INFO MYNAM ": %s installed at interrupt "
1942 "%d\n", ioc->name, ioc->pcidev->irq));
1946 /* Prime reply & request queues!
1947 * (mucho alloc's) Must be done prior to
1948 * init as upper addresses are needed for init.
1949 * If fails, continue with alt-ioc processing
1951 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
1954 /* May need to check/upload firmware & data here!
1955 * If fails, continue with alt-ioc processing
1957 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
1960 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
1961 printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
1962 ioc->alt_ioc->name, rc);
1964 reset_alt_ioc_active = 0;
1967 if (alt_ioc_ready) {
1968 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
1970 reset_alt_ioc_active = 0;
1971 printk(KERN_WARNING MYNAM
1972 ": alt-%s: (%d) init failure WARNING!\n",
1973 ioc->alt_ioc->name, rc);
1977 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
1978 if (ioc->upload_fw) {
1979 ddlprintk((MYIOC_s_INFO_FMT
1980 "firmware upload required!\n", ioc->name));
1982 /* Controller is not operational, cannot do upload
1985 rc = mpt_do_upload(ioc, sleepFlag);
1987 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
1989 * Maintain only one pointer to FW memory
1990 * so there will not be two attempt to
1991 * downloadboot onboard dual function
1992 * chips (mpt_adapter_disable,
1995 ddlprintk((MYIOC_s_INFO_FMT ": mpt_upload: alt_%s has cached_fw=%p \n",
1996 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
1997 ioc->alt_ioc->cached_fw = NULL;
2000 printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
2008 /* Enable! (reply interrupt) */
2009 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
2013 if (reset_alt_ioc_active && ioc->alt_ioc) {
2014 /* (re)Enable alt-IOC! (reply interrupt) */
2015 dinitprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
2016 ioc->alt_ioc->name));
2017 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2018 ioc->alt_ioc->active = 1;
2021 /* Enable MPT base driver management of EventNotification
2022 * and EventAck handling.
2024 if ((ret == 0) && (!ioc->facts.EventState))
2025 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
2027 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2028 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
2030 /* Add additional "reason" check before call to GetLanConfigPages
2031 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2032 * recursive scenario; GetLanConfigPages times out, timer expired
2033 * routine calls HardResetHandler, which calls into here again,
2034 * and we try GetLanConfigPages again...
2036 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2039 * Initalize link list for inactive raid volumes.
2041 init_MUTEX(&ioc->raid_data.inactive_list_mutex);
2042 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2044 if (ioc->bus_type == SAS) {
2046 /* clear persistency table */
2047 if(ioc->facts.IOCExceptions &
2048 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
2049 ret = mptbase_sas_persist_operation(ioc,
2050 MPI_SAS_OP_CLEAR_NOT_PRESENT);
2057 mpt_findImVolumes(ioc);
2059 } else if (ioc->bus_type == FC) {
2060 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
2061 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2063 * Pre-fetch the ports LAN MAC address!
2064 * (LANPage1_t stuff)
2066 (void) GetLanConfigPages(ioc);
2069 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2070 dprintk((MYIOC_s_INFO_FMT "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
2071 ioc->name, a[5], a[4], a[3], a[2], a[1], a[0] ));
2076 /* Get NVRAM and adapter maximums from SPP 0 and 2
2078 mpt_GetScsiPortSettings(ioc, 0);
2080 /* Get version and length of SDP 1
2082 mpt_readScsiDevicePageHeaders(ioc, 0);
2086 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
2087 mpt_findImVolumes(ioc);
2089 /* Check, and possibly reset, the coalescing value
2091 mpt_read_ioc_pg_1(ioc);
2093 mpt_read_ioc_pg_4(ioc);
2096 GetIoUnitPage2(ioc);
2097 mpt_get_manufacturing_pg_0(ioc);
2101 * Call each currently registered protocol IOC reset handler
2102 * with post-reset indication.
2103 * NOTE: If we're doing _IOC_BRINGUP, there can be no
2104 * MptResetHandlers[] registered yet.
2106 if (hard_reset_done) {
2108 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
2109 if ((ret == 0) && MptResetHandlers[ii]) {
2110 dprintk((MYIOC_s_INFO_FMT "Calling IOC post_reset handler #%d\n",
2112 rc += mpt_signal_reset(ii, ioc, MPT_IOC_POST_RESET);
2116 if (alt_ioc_ready && MptResetHandlers[ii]) {
2117 drsprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",
2118 ioc->name, ioc->alt_ioc->name, ii));
2119 rc += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_POST_RESET);
2123 /* FIXME? Examine results here? */
2127 if ((ret != 0) && irq_allocated) {
2128 free_irq(ioc->pci_irq, ioc);
2130 pci_disable_msi(ioc->pcidev);
2135 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2137 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2138 * @ioc: Pointer to MPT adapter structure
2139 * @pdev: Pointer to (struct pci_dev) structure
2141 * Search for PCI bus/dev_function which matches
2142 * PCI bus/dev_function (+/-1) for newly discovered 929,
2143 * 929X, 1030 or 1035.
2145 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2146 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2149 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
2151 struct pci_dev *peer=NULL;
2152 unsigned int slot = PCI_SLOT(pdev->devfn);
2153 unsigned int func = PCI_FUNC(pdev->devfn);
2154 MPT_ADAPTER *ioc_srch;
2156 dprintk((MYIOC_s_INFO_FMT "PCI device %s devfn=%x/%x,"
2157 " searching for devfn match on %x or %x\n",
2158 ioc->name, pci_name(pdev), pdev->bus->number,
2159 pdev->devfn, func-1, func+1));
2161 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
2163 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
2168 list_for_each_entry(ioc_srch, &ioc_list, list) {
2169 struct pci_dev *_pcidev = ioc_srch->pcidev;
2170 if (_pcidev == peer) {
2171 /* Paranoia checks */
2172 if (ioc->alt_ioc != NULL) {
2173 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
2174 ioc->name, ioc->alt_ioc->name);
2176 } else if (ioc_srch->alt_ioc != NULL) {
2177 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
2178 ioc_srch->name, ioc_srch->alt_ioc->name);
2181 dprintk((KERN_INFO MYNAM ": FOUND! binding %s <==> %s\n",
2182 ioc->name, ioc_srch->name));
2183 ioc_srch->alt_ioc = ioc;
2184 ioc->alt_ioc = ioc_srch;
2190 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2192 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2193 * @ioc: Pointer to MPT adapter structure
2196 mpt_adapter_disable(MPT_ADAPTER *ioc)
2201 if (ioc->cached_fw != NULL) {
2202 ddlprintk((KERN_INFO MYNAM ": mpt_adapter_disable: Pushing FW onto adapter\n"));
2203 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)ioc->cached_fw, NO_SLEEP)) < 0) {
2204 printk(KERN_WARNING MYNAM
2205 ": firmware downloadboot failure (%d)!\n", ret);
2209 /* Disable adapter interrupts! */
2210 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2212 /* Clear any lingering interrupt */
2213 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2215 if (ioc->alloc != NULL) {
2217 dexitprintk((KERN_INFO MYNAM ": %s.free @ %p, sz=%d bytes\n",
2218 ioc->name, ioc->alloc, ioc->alloc_sz));
2219 pci_free_consistent(ioc->pcidev, sz,
2220 ioc->alloc, ioc->alloc_dma);
2221 ioc->reply_frames = NULL;
2222 ioc->req_frames = NULL;
2224 ioc->alloc_total -= sz;
2227 if (ioc->sense_buf_pool != NULL) {
2228 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2229 pci_free_consistent(ioc->pcidev, sz,
2230 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2231 ioc->sense_buf_pool = NULL;
2232 ioc->alloc_total -= sz;
2235 if (ioc->events != NULL){
2236 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2239 ioc->alloc_total -= sz;
2242 if (ioc->cached_fw != NULL) {
2243 sz = ioc->facts.FWImageSize;
2244 pci_free_consistent(ioc->pcidev, sz,
2245 ioc->cached_fw, ioc->cached_fw_dma);
2246 ioc->cached_fw = NULL;
2247 ioc->alloc_total -= sz;
2250 kfree(ioc->spi_data.nvram);
2251 mpt_inactive_raid_list_free(ioc);
2252 kfree(ioc->raid_data.pIocPg2);
2253 kfree(ioc->raid_data.pIocPg3);
2254 ioc->spi_data.nvram = NULL;
2255 ioc->raid_data.pIocPg3 = NULL;
2257 if (ioc->spi_data.pIocPg4 != NULL) {
2258 sz = ioc->spi_data.IocPg4Sz;
2259 pci_free_consistent(ioc->pcidev, sz,
2260 ioc->spi_data.pIocPg4,
2261 ioc->spi_data.IocPg4_dma);
2262 ioc->spi_data.pIocPg4 = NULL;
2263 ioc->alloc_total -= sz;
2266 if (ioc->ReqToChain != NULL) {
2267 kfree(ioc->ReqToChain);
2268 kfree(ioc->RequestNB);
2269 ioc->ReqToChain = NULL;
2272 kfree(ioc->ChainToChain);
2273 ioc->ChainToChain = NULL;
2275 if (ioc->HostPageBuffer != NULL) {
2276 if((ret = mpt_host_page_access_control(ioc,
2277 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2278 printk(KERN_ERR MYNAM
2279 ": %s: host page buffers free failed (%d)!\n",
2282 dexitprintk((KERN_INFO MYNAM ": %s HostPageBuffer free @ %p, sz=%d bytes\n",
2283 ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
2284 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2285 ioc->HostPageBuffer,
2286 ioc->HostPageBuffer_dma);
2287 ioc->HostPageBuffer = NULL;
2288 ioc->HostPageBuffer_sz = 0;
2289 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2293 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2295 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2296 * @ioc: Pointer to MPT adapter structure
2298 * This routine unregisters h/w resources and frees all alloc'd memory
2299 * associated with a MPT adapter structure.
2302 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2304 int sz_first, sz_last;
2309 sz_first = ioc->alloc_total;
2311 mpt_adapter_disable(ioc);
2313 if (ioc->pci_irq != -1) {
2314 free_irq(ioc->pci_irq, ioc);
2316 pci_disable_msi(ioc->pcidev);
2320 if (ioc->memmap != NULL) {
2321 iounmap(ioc->memmap);
2325 #if defined(CONFIG_MTRR) && 0
2326 if (ioc->mtrr_reg > 0) {
2327 mtrr_del(ioc->mtrr_reg, 0, 0);
2328 dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name));
2332 /* Zap the adapter lookup ptr! */
2333 list_del(&ioc->list);
2335 sz_last = ioc->alloc_total;
2336 dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
2337 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2340 ioc->alt_ioc->alt_ioc = NULL;
2345 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2347 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2348 * @ioc: Pointer to MPT adapter structure
2351 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2355 printk(KERN_INFO "%s: ", ioc->name);
2357 printk("%s: ", ioc->prod_name);
2358 printk("Capabilities={");
2360 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2361 printk("Initiator");
2365 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2366 printk("%sTarget", i ? "," : "");
2370 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2371 printk("%sLAN", i ? "," : "");
2377 * This would probably evoke more questions than it's worth
2379 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2380 printk("%sLogBusAddr", i ? "," : "");
2388 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2390 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2391 * @ioc: Pointer to MPT_ADAPTER structure
2392 * @force: Force hard KickStart of IOC
2393 * @sleepFlag: Specifies whether the process can sleep
2396 * 1 - DIAG reset and READY
2397 * 0 - READY initially OR soft reset and READY
2398 * -1 - Any failure on KickStart
2399 * -2 - Msg Unit Reset Failed
2400 * -3 - IO Unit Reset Failed
2401 * -4 - IOC owned by a PEER
2404 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2409 int hard_reset_done = 0;
2414 /* Get current [raw] IOC state */
2415 ioc_state = mpt_GetIocState(ioc, 0);
2416 dhsprintk((KERN_INFO MYNAM "::MakeIocReady, %s [raw] state=%08x\n", ioc->name, ioc_state));
2419 * Check to see if IOC got left/stuck in doorbell handshake
2420 * grip of death. If so, hard reset the IOC.
2422 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2424 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2428 /* Is it already READY? */
2429 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
2433 * Check to see if IOC is in FAULT state.
2435 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2437 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2439 printk(KERN_WARNING " FAULT code = %04xh\n",
2440 ioc_state & MPI_DOORBELL_DATA_MASK);
2444 * Hmmm... Did it get left operational?
2446 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2447 dinitprintk((MYIOC_s_INFO_FMT "IOC operational unexpected\n",
2451 * If PCI Peer, exit.
2452 * Else, if no fault conditions are present, issue a MessageUnitReset
2453 * Else, fall through to KickStart case
2455 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2456 dinitprintk((KERN_INFO MYNAM
2457 ": whoinit 0x%x statefault %d force %d\n",
2458 whoinit, statefault, force));
2459 if (whoinit == MPI_WHOINIT_PCI_PEER)
2462 if ((statefault == 0 ) && (force == 0)) {
2463 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2470 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2471 if (hard_reset_done < 0)
2475 * Loop here waiting for IOC to come READY.
2478 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2480 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2481 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2483 * BIOS or previous driver load left IOC in OP state.
2484 * Reset messaging FIFOs.
2486 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2487 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2490 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2492 * Something is wrong. Try to get IOC back
2495 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2496 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2503 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2504 ioc->name, (int)((ii+5)/HZ));
2508 if (sleepFlag == CAN_SLEEP) {
2511 mdelay (1); /* 1 msec delay */
2516 if (statefault < 3) {
2517 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2519 statefault==1 ? "stuck handshake" : "IOC FAULT");
2522 return hard_reset_done;
2525 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2527 * mpt_GetIocState - Get the current state of a MPT adapter.
2528 * @ioc: Pointer to MPT_ADAPTER structure
2529 * @cooked: Request raw or cooked IOC state
2531 * Returns all IOC Doorbell register bits if cooked==0, else just the
2532 * Doorbell bits in MPI_IOC_STATE_MASK.
2535 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2540 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2541 // dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
2542 sc = s & MPI_IOC_STATE_MASK;
2545 ioc->last_state = sc;
2547 return cooked ? sc : s;
2550 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2552 * GetIocFacts - Send IOCFacts request to MPT adapter.
2553 * @ioc: Pointer to MPT_ADAPTER structure
2554 * @sleepFlag: Specifies whether the process can sleep
2555 * @reason: If recovery, only update facts.
2557 * Returns 0 for success, non-zero for failure.
2560 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2562 IOCFacts_t get_facts;
2563 IOCFactsReply_t *facts;
2571 /* IOC *must* NOT be in RESET state! */
2572 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2573 printk(KERN_ERR MYNAM ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
2579 facts = &ioc->facts;
2581 /* Destination (reply area)... */
2582 reply_sz = sizeof(*facts);
2583 memset(facts, 0, reply_sz);
2585 /* Request area (get_facts on the stack right now!) */
2586 req_sz = sizeof(get_facts);
2587 memset(&get_facts, 0, req_sz);
2589 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2590 /* Assert: All other get_facts fields are zero! */
2592 dinitprintk((MYIOC_s_INFO_FMT
2593 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2594 ioc->name, req_sz, reply_sz));
2596 /* No non-zero fields in the get_facts request are greater than
2597 * 1 byte in size, so we can just fire it off as is.
2599 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2600 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2605 * Now byte swap (GRRR) the necessary fields before any further
2606 * inspection of reply contents.
2608 * But need to do some sanity checks on MsgLength (byte) field
2609 * to make sure we don't zero IOC's req_sz!
2611 /* Did we get a valid reply? */
2612 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2613 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2615 * If not been here, done that, save off first WhoInit value
2617 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2618 ioc->FirstWhoInit = facts->WhoInit;
2621 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2622 facts->MsgContext = le32_to_cpu(facts->MsgContext);
2623 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2624 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2625 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2626 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
2627 /* CHECKME! IOCStatus, IOCLogInfo */
2629 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2630 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2633 * FC f/w version changed between 1.1 and 1.2
2634 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2635 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2637 if (facts->MsgVersion < 0x0102) {
2639 * Handle old FC f/w style, convert to new...
2641 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2642 facts->FWVersion.Word =
2643 ((oldv<<12) & 0xFF000000) |
2644 ((oldv<<8) & 0x000FFF00);
2646 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2648 facts->ProductID = le16_to_cpu(facts->ProductID);
2649 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
2650 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
2651 ioc->ir_firmware = 1;
2652 facts->CurrentHostMfaHighAddr =
2653 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2654 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2655 facts->CurrentSenseBufferHighAddr =
2656 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2657 facts->CurReplyFrameSize =
2658 le16_to_cpu(facts->CurReplyFrameSize);
2659 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
2662 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2663 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2664 * to 14 in MPI-1.01.0x.
2666 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2667 facts->MsgVersion > 0x0100) {
2668 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2671 sz = facts->FWImageSize;
2676 facts->FWImageSize = sz;
2678 if (!facts->RequestFrameSize) {
2679 /* Something is wrong! */
2680 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2685 r = sz = facts->BlockSize;
2686 vv = ((63 / (sz * 4)) + 1) & 0x03;
2687 ioc->NB_for_64_byte_frame = vv;
2693 ioc->NBShiftFactor = shiftFactor;
2694 dinitprintk((MYIOC_s_INFO_FMT "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2695 ioc->name, vv, shiftFactor, r));
2697 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2699 * Set values for this IOC's request & reply frame sizes,
2700 * and request & reply queue depths...
2702 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2703 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2704 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2705 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2707 dinitprintk((MYIOC_s_INFO_FMT "reply_sz=%3d, reply_depth=%4d\n",
2708 ioc->name, ioc->reply_sz, ioc->reply_depth));
2709 dinitprintk((MYIOC_s_INFO_FMT "req_sz =%3d, req_depth =%4d\n",
2710 ioc->name, ioc->req_sz, ioc->req_depth));
2712 /* Get port facts! */
2713 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2717 printk(MYIOC_s_ERR_FMT
2718 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2719 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2720 RequestFrameSize)/sizeof(u32)));
2727 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2729 * GetPortFacts - Send PortFacts request to MPT adapter.
2730 * @ioc: Pointer to MPT_ADAPTER structure
2731 * @portnum: Port number
2732 * @sleepFlag: Specifies whether the process can sleep
2734 * Returns 0 for success, non-zero for failure.
2737 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2739 PortFacts_t get_pfacts;
2740 PortFactsReply_t *pfacts;
2746 /* IOC *must* NOT be in RESET state! */
2747 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2748 printk(KERN_ERR MYNAM ": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n",
2754 pfacts = &ioc->pfacts[portnum];
2756 /* Destination (reply area)... */
2757 reply_sz = sizeof(*pfacts);
2758 memset(pfacts, 0, reply_sz);
2760 /* Request area (get_pfacts on the stack right now!) */
2761 req_sz = sizeof(get_pfacts);
2762 memset(&get_pfacts, 0, req_sz);
2764 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2765 get_pfacts.PortNumber = portnum;
2766 /* Assert: All other get_pfacts fields are zero! */
2768 dinitprintk((MYIOC_s_INFO_FMT "Sending get PortFacts(%d) request\n",
2769 ioc->name, portnum));
2771 /* No non-zero fields in the get_pfacts request are greater than
2772 * 1 byte in size, so we can just fire it off as is.
2774 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2775 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2779 /* Did we get a valid reply? */
2781 /* Now byte swap the necessary fields in the response. */
2782 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2783 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2784 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2785 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2786 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2787 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2788 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2789 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2790 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2792 max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
2794 ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
2795 ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
2798 * Place all the devices on channels
2802 if (mpt_channel_mapping) {
2803 ioc->devices_per_bus = 1;
2804 ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
2810 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2812 * SendIocInit - Send IOCInit request to MPT adapter.
2813 * @ioc: Pointer to MPT_ADAPTER structure
2814 * @sleepFlag: Specifies whether the process can sleep
2816 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2818 * Returns 0 for success, non-zero for failure.
2821 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2824 MPIDefaultReply_t init_reply;
2830 memset(&ioc_init, 0, sizeof(ioc_init));
2831 memset(&init_reply, 0, sizeof(init_reply));
2833 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2834 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2836 /* If we are in a recovery mode and we uploaded the FW image,
2837 * then this pointer is not NULL. Skip the upload a second time.
2838 * Set this flag if cached_fw set for either IOC.
2840 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
2844 ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n",
2845 ioc->name, ioc->upload_fw, ioc->facts.Flags));
2847 ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
2848 ioc_init.MaxBuses = (U8)ioc->number_of_buses;
2849 dinitprintk((MYIOC_s_INFO_FMT "facts.MsgVersion=%x\n",
2850 ioc->name, ioc->facts.MsgVersion));
2851 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
2852 // set MsgVersion and HeaderVersion host driver was built with
2853 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
2854 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
2856 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
2857 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
2858 } else if(mpt_host_page_alloc(ioc, &ioc_init))
2861 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
2863 if (sizeof(dma_addr_t) == sizeof(u64)) {
2864 /* Save the upper 32-bits of the request
2865 * (reply) and sense buffers.
2867 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
2868 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2870 /* Force 32-bit addressing */
2871 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
2872 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
2875 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
2876 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
2877 ioc->facts.MaxDevices = ioc_init.MaxDevices;
2878 ioc->facts.MaxBuses = ioc_init.MaxBuses;
2880 dhsprintk((MYIOC_s_INFO_FMT "Sending IOCInit (req @ %p)\n",
2881 ioc->name, &ioc_init));
2883 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
2884 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
2886 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
2890 /* No need to byte swap the multibyte fields in the reply
2891 * since we don't even look at its contents.
2894 dhsprintk((MYIOC_s_INFO_FMT "Sending PortEnable (req @ %p)\n",
2895 ioc->name, &ioc_init));
2897 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
2898 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
2902 /* YIKES! SUPER IMPORTANT!!!
2903 * Poll IocState until _OPERATIONAL while IOC is doing
2904 * LoopInit and TargetDiscovery!
2907 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
2908 state = mpt_GetIocState(ioc, 1);
2909 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
2910 if (sleepFlag == CAN_SLEEP) {
2917 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
2918 ioc->name, (int)((count+5)/HZ));
2922 state = mpt_GetIocState(ioc, 1);
2925 dinitprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
2928 ioc->aen_event_read_flag=0;
2932 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2934 * SendPortEnable - Send PortEnable request to MPT adapter port.
2935 * @ioc: Pointer to MPT_ADAPTER structure
2936 * @portnum: Port number to enable
2937 * @sleepFlag: Specifies whether the process can sleep
2939 * Send PortEnable to bring IOC to OPERATIONAL state.
2941 * Returns 0 for success, non-zero for failure.
2944 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2946 PortEnable_t port_enable;
2947 MPIDefaultReply_t reply_buf;
2952 /* Destination... */
2953 reply_sz = sizeof(MPIDefaultReply_t);
2954 memset(&reply_buf, 0, reply_sz);
2956 req_sz = sizeof(PortEnable_t);
2957 memset(&port_enable, 0, req_sz);
2959 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
2960 port_enable.PortNumber = portnum;
2961 /* port_enable.ChainOffset = 0; */
2962 /* port_enable.MsgFlags = 0; */
2963 /* port_enable.MsgContext = 0; */
2965 dinitprintk((MYIOC_s_INFO_FMT "Sending Port(%d)Enable (req @ %p)\n",
2966 ioc->name, portnum, &port_enable));
2968 /* RAID FW may take a long time to enable
2970 if (ioc->ir_firmware || ioc->bus_type == SAS) {
2971 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
2972 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
2973 300 /*seconds*/, sleepFlag);
2975 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
2976 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
2977 30 /*seconds*/, sleepFlag);
2983 * mpt_alloc_fw_memory - allocate firmware memory
2984 * @ioc: Pointer to MPT_ADAPTER structure
2985 * @size: total FW bytes
2987 * If memory has already been allocated, the same (cached) value
2991 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
2994 return; /* use already allocated memory */
2995 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2996 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
2997 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
2998 ioc->alloc_total += size;
2999 ioc->alt_ioc->alloc_total -= size;
3001 if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
3002 ioc->alloc_total += size;
3006 * mpt_free_fw_memory - free firmware memory
3007 * @ioc: Pointer to MPT_ADAPTER structure
3009 * If alt_img is NULL, delete from ioc structure.
3010 * Else, delete a secondary image in same format.
3013 mpt_free_fw_memory(MPT_ADAPTER *ioc)
3017 sz = ioc->facts.FWImageSize;
3018 dinitprintk((KERN_INFO MYNAM "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3019 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3020 pci_free_consistent(ioc->pcidev, sz,
3021 ioc->cached_fw, ioc->cached_fw_dma);
3022 ioc->cached_fw = NULL;
3028 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3030 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3031 * @ioc: Pointer to MPT_ADAPTER structure
3032 * @sleepFlag: Specifies whether the process can sleep
3034 * Returns 0 for success, >0 for handshake failure
3035 * <0 for fw upload failure.
3037 * Remark: If bound IOC and a successful FWUpload was performed
3038 * on the bound IOC, the second image is discarded
3039 * and memory is free'd. Both channels must upload to prevent
3040 * IOC from running in degraded mode.
3043 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3045 u8 request[ioc->req_sz];
3046 u8 reply[sizeof(FWUploadReply_t)];
3047 FWUpload_t *prequest;
3048 FWUploadReply_t *preply;
3049 FWUploadTCSGE_t *ptcsge;
3052 int ii, sz, reply_sz;
3055 /* If the image size is 0, we are done.
3057 if ((sz = ioc->facts.FWImageSize) == 0)
3060 mpt_alloc_fw_memory(ioc, sz);
3062 dinitprintk((KERN_INFO MYNAM ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3063 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3065 if (ioc->cached_fw == NULL) {
3071 prequest = (FWUpload_t *)&request;
3072 preply = (FWUploadReply_t *)&reply;
3074 /* Destination... */
3075 memset(prequest, 0, ioc->req_sz);
3077 reply_sz = sizeof(reply);
3078 memset(preply, 0, reply_sz);
3080 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
3081 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
3083 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
3084 ptcsge->DetailsLength = 12;
3085 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
3086 ptcsge->ImageSize = cpu_to_le32(sz);
3088 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
3090 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3091 mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma);
3093 sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
3094 dinitprintk((KERN_INFO MYNAM ": Sending FW Upload (req @ %p) sgeoffset=%d \n",
3095 prequest, sgeoffset));
3096 DBG_DUMP_FW_REQUEST_FRAME(prequest)
3098 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
3099 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
3101 dinitprintk((KERN_INFO MYNAM ": FW Upload completed rc=%x \n", ii));
3103 cmdStatus = -EFAULT;
3105 /* Handshake transfer was complete and successful.
3106 * Check the Reply Frame.
3108 int status, transfer_sz;
3109 status = le16_to_cpu(preply->IOCStatus);
3110 if (status == MPI_IOCSTATUS_SUCCESS) {
3111 transfer_sz = le32_to_cpu(preply->ActualImageSize);
3112 if (transfer_sz == sz)
3116 dinitprintk((MYIOC_s_INFO_FMT ": do_upload cmdStatus=%d \n",
3117 ioc->name, cmdStatus));
3122 ddlprintk((MYIOC_s_INFO_FMT ": fw upload failed, freeing image \n",
3124 mpt_free_fw_memory(ioc);
3130 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3132 * mpt_downloadboot - DownloadBoot code
3133 * @ioc: Pointer to MPT_ADAPTER structure
3134 * @pFwHeader: Pointer to firmware header info
3135 * @sleepFlag: Specifies whether the process can sleep
3137 * FwDownloadBoot requires Programmed IO access.
3139 * Returns 0 for success
3140 * -1 FW Image size is 0
3141 * -2 No valid cached_fw Pointer
3142 * <0 for fw upload failure.
3145 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3147 MpiExtImageHeader_t *pExtImage;
3157 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3158 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
3160 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3161 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3162 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3163 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3164 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3165 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3167 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
3170 if (sleepFlag == CAN_SLEEP) {
3176 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3177 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3179 for (count = 0; count < 30; count ++) {
3180 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3181 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3182 ddlprintk((MYIOC_s_INFO_FMT "RESET_ADAPTER cleared, count=%d\n",
3187 if (sleepFlag == CAN_SLEEP) {
3194 if ( count == 30 ) {
3195 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! "
3196 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3197 ioc->name, diag0val));
3201 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3202 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3203 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3204 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3205 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3206 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3208 /* Set the DiagRwEn and Disable ARM bits */
3209 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3211 fwSize = (pFwHeader->ImageSize + 3)/4;
3212 ptrFw = (u32 *) pFwHeader;
3214 /* Write the LoadStartAddress to the DiagRw Address Register
3215 * using Programmed IO
3217 if (ioc->errata_flag_1064)
3218 pci_enable_io_access(ioc->pcidev);
3220 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3221 ddlprintk((MYIOC_s_INFO_FMT "LoadStart addr written 0x%x \n",
3222 ioc->name, pFwHeader->LoadStartAddress));
3224 ddlprintk((MYIOC_s_INFO_FMT "Write FW Image: 0x%x bytes @ %p\n",
3225 ioc->name, fwSize*4, ptrFw));
3227 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3230 nextImage = pFwHeader->NextImageHeaderOffset;
3232 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3234 load_addr = pExtImage->LoadStartAddress;
3236 fwSize = (pExtImage->ImageSize + 3) >> 2;
3237 ptrFw = (u32 *)pExtImage;
3239 ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3240 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3241 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3244 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3246 nextImage = pExtImage->NextImageHeaderOffset;
3249 /* Write the IopResetVectorRegAddr */
3250 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
3251 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3253 /* Write the IopResetVectorValue */
3254 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3255 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3257 /* Clear the internal flash bad bit - autoincrementing register,
3258 * so must do two writes.
3260 if (ioc->bus_type == SPI) {
3262 * 1030 and 1035 H/W errata, workaround to access
3263 * the ClearFlashBadSignatureBit
3265 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3266 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3267 diagRwData |= 0x40000000;
3268 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3269 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3271 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3272 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3273 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3274 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3277 if (sleepFlag == CAN_SLEEP) {
3284 if (ioc->errata_flag_1064)
3285 pci_disable_io_access(ioc->pcidev);
3287 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3288 ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, "
3289 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3290 ioc->name, diag0val));
3291 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3292 ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
3293 ioc->name, diag0val));
3294 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3296 /* Write 0xFF to reset the sequencer */
3297 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3299 if (ioc->bus_type == SAS) {
3300 ioc_state = mpt_GetIocState(ioc, 0);
3301 if ( (GetIocFacts(ioc, sleepFlag,
3302 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3303 ddlprintk((MYIOC_s_INFO_FMT "GetIocFacts failed: IocState=%x\n",
3304 ioc->name, ioc_state));
3309 for (count=0; count<HZ*20; count++) {
3310 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3311 ddlprintk((MYIOC_s_INFO_FMT "downloadboot successful! (count=%d) IocState=%x\n",
3312 ioc->name, count, ioc_state));
3313 if (ioc->bus_type == SAS) {
3316 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3317 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit failed\n",
3321 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit successful\n",
3325 if (sleepFlag == CAN_SLEEP) {
3331 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! IocState=%x\n",
3332 ioc->name, ioc_state));
3336 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3338 * KickStart - Perform hard reset of MPT adapter.
3339 * @ioc: Pointer to MPT_ADAPTER structure
3340 * @force: Force hard reset
3341 * @sleepFlag: Specifies whether the process can sleep
3343 * This routine places MPT adapter in diagnostic mode via the
3344 * WriteSequence register, and then performs a hard reset of adapter
3345 * via the Diagnostic register.
3347 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3348 * or NO_SLEEP (interrupt thread, use mdelay)
3349 * force - 1 if doorbell active, board fault state
3350 * board operational, IOC_RECOVERY or
3351 * IOC_BRINGUP and there is an alt_ioc.
3355 * 1 - hard reset, READY
3356 * 0 - no reset due to History bit, READY
3357 * -1 - no reset due to History bit but not READY
3358 * OR reset but failed to come READY
3359 * -2 - no reset, could not enter DIAG mode
3360 * -3 - reset but bad FW bit
3363 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3365 int hard_reset_done = 0;
3369 dinitprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
3370 if (ioc->bus_type == SPI) {
3371 /* Always issue a Msg Unit Reset first. This will clear some
3372 * SCSI bus hang conditions.
3374 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3376 if (sleepFlag == CAN_SLEEP) {
3383 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3384 if (hard_reset_done < 0)
3385 return hard_reset_done;
3387 dinitprintk((MYIOC_s_INFO_FMT "Diagnostic reset successful!\n",
3390 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3391 for (cnt=0; cnt<cntdn; cnt++) {
3392 ioc_state = mpt_GetIocState(ioc, 1);
3393 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3394 dinitprintk((MYIOC_s_INFO_FMT "KickStart successful! (cnt=%d)\n",
3396 return hard_reset_done;
3398 if (sleepFlag == CAN_SLEEP) {
3405 printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3406 ioc->name, ioc_state);
3410 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3412 * mpt_diag_reset - Perform hard reset of the adapter.
3413 * @ioc: Pointer to MPT_ADAPTER structure
3414 * @ignore: Set if to honor and clear to ignore
3415 * the reset history bit
3416 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3417 * else set to NO_SLEEP (use mdelay instead)
3419 * This routine places the adapter in diagnostic mode via the
3420 * WriteSequence register and then performs a hard reset of adapter
3421 * via the Diagnostic register. Adapter should be in ready state
3422 * upon successful completion.
3424 * Returns: 1 hard reset successful
3425 * 0 no reset performed because reset history bit set
3426 * -2 enabling diagnostic mode failed
3427 * -3 diagnostic reset failed
3430 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3432 MPT_ADAPTER *iocp=NULL;
3435 int hard_reset_done = 0;
3441 /* Clear any existing interrupts */
3442 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3444 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3445 drsprintk((MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3446 "address=%p\n", ioc->name, __FUNCTION__,
3447 &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3448 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3449 if (sleepFlag == CAN_SLEEP)
3454 for (count = 0; count < 60; count ++) {
3455 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3456 doorbell &= MPI_IOC_STATE_MASK;
3458 drsprintk((MYIOC_s_INFO_FMT
3459 "looking for READY STATE: doorbell=%x"
3461 ioc->name, doorbell, count));
3462 if (doorbell == MPI_IOC_STATE_READY) {
3467 if (sleepFlag == CAN_SLEEP)
3475 /* Use "Diagnostic reset" method! (only thing available!) */
3476 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3480 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3481 dprintk((MYIOC_s_INFO_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3482 ioc->name, diag0val, diag1val));
3485 /* Do the reset if we are told to ignore the reset history
3486 * or if the reset history is 0
3488 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3489 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3490 /* Write magic sequence to WriteSequence register
3491 * Loop until in diagnostic mode
3493 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3494 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3495 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3496 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3497 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3498 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3501 if (sleepFlag == CAN_SLEEP) {
3509 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3510 ioc->name, diag0val);
3515 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3517 dprintk((MYIOC_s_INFO_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3518 ioc->name, diag0val));
3523 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3524 dprintk((MYIOC_s_INFO_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3525 ioc->name, diag0val, diag1val));
3528 * Disable the ARM (Bug fix)
3531 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3535 * Now hit the reset bit in the Diagnostic register
3536 * (THE BIG HAMMER!) (Clears DRWE bit).
3538 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3539 hard_reset_done = 1;
3540 dprintk((MYIOC_s_INFO_FMT "Diagnostic reset performed\n",
3544 * Call each currently registered protocol IOC reset handler
3545 * with pre-reset indication.
3546 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3547 * MptResetHandlers[] registered yet.
3553 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
3554 if (MptResetHandlers[ii]) {
3555 dprintk((MYIOC_s_INFO_FMT "Calling IOC pre_reset handler #%d\n",
3557 r += mpt_signal_reset(ii, ioc, MPT_IOC_PRE_RESET);
3559 dprintk((MYIOC_s_INFO_FMT "Calling alt-%s pre_reset handler #%d\n",
3560 ioc->name, ioc->alt_ioc->name, ii));
3561 r += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_PRE_RESET);
3565 /* FIXME? Examine results here? */
3570 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
3571 iocp = ioc->alt_ioc;
3573 /* If the DownloadBoot operation fails, the
3574 * IOC will be left unusable. This is a fatal error
3575 * case. _diag_reset will return < 0
3577 for (count = 0; count < 30; count ++) {
3578 diag0val = CHIPREG_READ32(&iocp->chip->Diagnostic);
3579 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3583 dprintk((MYIOC_s_INFO_FMT "cached_fw: diag0val=%x count=%d\n",
3584 iocp->name, diag0val, count));
3586 if (sleepFlag == CAN_SLEEP) {
3592 if ((count = mpt_downloadboot(ioc,
3593 (MpiFwHeader_t *)iocp->cached_fw, sleepFlag)) < 0) {
3594 printk(KERN_WARNING MYNAM
3595 ": firmware downloadboot failure (%d)!\n", count);
3599 /* Wait for FW to reload and for board
3600 * to go to the READY state.
3601 * Maximum wait is 60 seconds.
3602 * If fail, no error will check again
3603 * with calling program.
3605 for (count = 0; count < 60; count ++) {
3606 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3607 doorbell &= MPI_IOC_STATE_MASK;
3609 if (doorbell == MPI_IOC_STATE_READY) {
3614 if (sleepFlag == CAN_SLEEP) {
3623 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3626 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3627 dprintk((MYIOC_s_INFO_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3628 ioc->name, diag0val, diag1val));
3631 /* Clear RESET_HISTORY bit! Place board in the
3632 * diagnostic mode to update the diag register.
3634 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3636 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3637 /* Write magic sequence to WriteSequence register
3638 * Loop until in diagnostic mode
3640 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3641 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3642 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3643 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3644 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3645 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3648 if (sleepFlag == CAN_SLEEP) {
3656 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3657 ioc->name, diag0val);
3660 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3662 diag0val &= ~MPI_DIAG_RESET_HISTORY;
3663 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3664 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3665 if (diag0val & MPI_DIAG_RESET_HISTORY) {
3666 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3670 /* Disable Diagnostic Mode
3672 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3674 /* Check FW reload status flags.
3676 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3677 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3678 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3679 ioc->name, diag0val);
3685 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3686 dprintk((MYIOC_s_INFO_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3687 ioc->name, diag0val, diag1val));
3691 * Reset flag that says we've enabled event notification
3693 ioc->facts.EventState = 0;
3696 ioc->alt_ioc->facts.EventState = 0;
3698 return hard_reset_done;
3701 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3703 * SendIocReset - Send IOCReset request to MPT adapter.
3704 * @ioc: Pointer to MPT_ADAPTER structure
3705 * @reset_type: reset type, expected values are
3706 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3707 * @sleepFlag: Specifies whether the process can sleep
3709 * Send IOCReset request to the MPT adapter.
3711 * Returns 0 for success, non-zero for failure.
3714 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3720 drsprintk((KERN_INFO MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
3721 ioc->name, reset_type));
3722 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3723 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3726 /* FW ACK'd request, wait for READY state
3729 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
3731 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3735 if (sleepFlag != CAN_SLEEP)
3738 printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
3739 ioc->name, (int)((count+5)/HZ));
3743 if (sleepFlag == CAN_SLEEP) {
3746 mdelay (1); /* 1 msec delay */
3751 * Cleanup all event stuff for this IOC; re-issue EventNotification
3752 * request if needed.
3754 if (ioc->facts.Function)
3755 ioc->facts.EventState = 0;
3760 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3762 * initChainBuffers - Allocate memory for and initialize chain buffers
3763 * @ioc: Pointer to MPT_ADAPTER structure
3765 * Allocates memory for and initializes chain buffers,
3766 * chain buffer control arrays and spinlock.
3769 initChainBuffers(MPT_ADAPTER *ioc)
3772 int sz, ii, num_chain;
3773 int scale, num_sge, numSGE;
3775 /* ReqToChain size must equal the req_depth
3778 if (ioc->ReqToChain == NULL) {
3779 sz = ioc->req_depth * sizeof(int);
3780 mem = kmalloc(sz, GFP_ATOMIC);
3784 ioc->ReqToChain = (int *) mem;
3785 dinitprintk((KERN_INFO MYNAM ": %s ReqToChain alloc @ %p, sz=%d bytes\n",
3786 ioc->name, mem, sz));
3787 mem = kmalloc(sz, GFP_ATOMIC);
3791 ioc->RequestNB = (int *) mem;
3792 dinitprintk((KERN_INFO MYNAM ": %s RequestNB alloc @ %p, sz=%d bytes\n",
3793 ioc->name, mem, sz));
3795 for (ii = 0; ii < ioc->req_depth; ii++) {
3796 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
3799 /* ChainToChain size must equal the total number
3800 * of chain buffers to be allocated.
3803 * Calculate the number of chain buffers needed(plus 1) per I/O
3804 * then multiply the maximum number of simultaneous cmds
3806 * num_sge = num sge in request frame + last chain buffer
3807 * scale = num sge per chain buffer if no chain element
3809 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3810 if (sizeof(dma_addr_t) == sizeof(u64))
3811 num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3813 num_sge = 1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3815 if (sizeof(dma_addr_t) == sizeof(u64)) {
3816 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3817 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3819 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3820 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3822 dinitprintk((KERN_INFO MYNAM ": %s num_sge=%d numSGE=%d\n",
3823 ioc->name, num_sge, numSGE));
3825 if ( numSGE > MPT_SCSI_SG_DEPTH )
3826 numSGE = MPT_SCSI_SG_DEPTH;
3829 while (numSGE - num_sge > 0) {
3831 num_sge += (scale - 1);
3835 dinitprintk((KERN_INFO MYNAM ": %s Now numSGE=%d num_sge=%d num_chain=%d\n",
3836 ioc->name, numSGE, num_sge, num_chain));
3838 if (ioc->bus_type == SPI)
3839 num_chain *= MPT_SCSI_CAN_QUEUE;
3841 num_chain *= MPT_FC_CAN_QUEUE;
3843 ioc->num_chain = num_chain;
3845 sz = num_chain * sizeof(int);
3846 if (ioc->ChainToChain == NULL) {
3847 mem = kmalloc(sz, GFP_ATOMIC);
3851 ioc->ChainToChain = (int *) mem;
3852 dinitprintk((KERN_INFO MYNAM ": %s ChainToChain alloc @ %p, sz=%d bytes\n",
3853 ioc->name, mem, sz));
3855 mem = (u8 *) ioc->ChainToChain;
3857 memset(mem, 0xFF, sz);
3861 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3863 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
3864 * @ioc: Pointer to MPT_ADAPTER structure
3866 * This routine allocates memory for the MPT reply and request frame
3867 * pools (if necessary), and primes the IOC reply FIFO with
3870 * Returns 0 for success, non-zero for failure.
3873 PrimeIocFifos(MPT_ADAPTER *ioc)
3876 unsigned long flags;
3877 dma_addr_t alloc_dma;
3879 int i, reply_sz, sz, total_size, num_chain;
3881 /* Prime reply FIFO... */
3883 if (ioc->reply_frames == NULL) {
3884 if ( (num_chain = initChainBuffers(ioc)) < 0)
3887 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
3888 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
3889 ioc->name, ioc->reply_sz, ioc->reply_depth));
3890 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d[%x] bytes\n",
3891 ioc->name, reply_sz, reply_sz));
3893 sz = (ioc->req_sz * ioc->req_depth);
3894 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d bytes, RequestDepth=%d\n",
3895 ioc->name, ioc->req_sz, ioc->req_depth));
3896 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d[%x] bytes\n",
3897 ioc->name, sz, sz));
3900 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
3901 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d bytes, ChainDepth=%d\n",
3902 ioc->name, ioc->req_sz, num_chain));
3903 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
3904 ioc->name, sz, sz, num_chain));
3907 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
3909 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
3914 dinitprintk((KERN_INFO MYNAM ": %s.Total alloc @ %p[%p], sz=%d[%x] bytes\n",
3915 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
3917 memset(mem, 0, total_size);
3918 ioc->alloc_total += total_size;
3920 ioc->alloc_dma = alloc_dma;
3921 ioc->alloc_sz = total_size;
3922 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
3923 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3925 dinitprintk((KERN_INFO MYNAM ": %s ReplyBuffers @ %p[%p]\n",
3926 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3928 alloc_dma += reply_sz;
3931 /* Request FIFO - WE manage this! */
3933 ioc->req_frames = (MPT_FRAME_HDR *) mem;
3934 ioc->req_frames_dma = alloc_dma;
3936 dinitprintk((KERN_INFO MYNAM ": %s RequestBuffers @ %p[%p]\n",
3937 ioc->name, mem, (void *)(ulong)alloc_dma));
3939 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3941 #if defined(CONFIG_MTRR) && 0
3943 * Enable Write Combining MTRR for IOC's memory region.
3944 * (at least as much as we can; "size and base must be
3945 * multiples of 4 kiB"
3947 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
3949 MTRR_TYPE_WRCOMB, 1);
3950 dprintk((MYIOC_s_INFO_FMT "MTRR region registered (base:size=%08x:%x)\n",
3951 ioc->name, ioc->req_frames_dma, sz));
3954 for (i = 0; i < ioc->req_depth; i++) {
3955 alloc_dma += ioc->req_sz;
3959 ioc->ChainBuffer = mem;
3960 ioc->ChainBufferDMA = alloc_dma;
3962 dinitprintk((KERN_INFO MYNAM " :%s ChainBuffers @ %p(%p)\n",
3963 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
3965 /* Initialize the free chain Q.
3968 INIT_LIST_HEAD(&ioc->FreeChainQ);
3970 /* Post the chain buffers to the FreeChainQ.
3972 mem = (u8 *)ioc->ChainBuffer;
3973 for (i=0; i < num_chain; i++) {
3974 mf = (MPT_FRAME_HDR *) mem;
3975 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
3979 /* Initialize Request frames linked list
3981 alloc_dma = ioc->req_frames_dma;
3982 mem = (u8 *) ioc->req_frames;
3984 spin_lock_irqsave(&ioc->FreeQlock, flags);
3985 INIT_LIST_HEAD(&ioc->FreeQ);
3986 for (i = 0; i < ioc->req_depth; i++) {
3987 mf = (MPT_FRAME_HDR *) mem;
3989 /* Queue REQUESTs *internally*! */
3990 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
3994 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3996 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3997 ioc->sense_buf_pool =
3998 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
3999 if (ioc->sense_buf_pool == NULL) {
4000 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
4005 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
4006 ioc->alloc_total += sz;
4007 dinitprintk((KERN_INFO MYNAM ": %s.SenseBuffers @ %p[%p]\n",
4008 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
4012 /* Post Reply frames to FIFO
4014 alloc_dma = ioc->alloc_dma;
4015 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffers @ %p[%p]\n",
4016 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4018 for (i = 0; i < ioc->reply_depth; i++) {
4019 /* Write each address to the IOC! */
4020 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
4021 alloc_dma += ioc->reply_sz;
4027 if (ioc->alloc != NULL) {
4029 pci_free_consistent(ioc->pcidev,
4031 ioc->alloc, ioc->alloc_dma);
4032 ioc->reply_frames = NULL;
4033 ioc->req_frames = NULL;
4034 ioc->alloc_total -= sz;
4036 if (ioc->sense_buf_pool != NULL) {
4037 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4038 pci_free_consistent(ioc->pcidev,
4040 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
4041 ioc->sense_buf_pool = NULL;
4046 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4048 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4049 * from IOC via doorbell handshake method.
4050 * @ioc: Pointer to MPT_ADAPTER structure
4051 * @reqBytes: Size of the request in bytes
4052 * @req: Pointer to MPT request frame
4053 * @replyBytes: Expected size of the reply in bytes
4054 * @u16reply: Pointer to area where reply should be written
4055 * @maxwait: Max wait time for a reply (in seconds)
4056 * @sleepFlag: Specifies whether the process can sleep
4058 * NOTES: It is the callers responsibility to byte-swap fields in the
4059 * request which are greater than 1 byte in size. It is also the
4060 * callers responsibility to byte-swap response fields which are
4061 * greater than 1 byte in size.
4063 * Returns 0 for success, non-zero for failure.
4066 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
4067 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
4069 MPIDefaultReply_t *mptReply;
4074 * Get ready to cache a handshake reply
4076 ioc->hs_reply_idx = 0;
4077 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4078 mptReply->MsgLength = 0;
4081 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4082 * then tell IOC that we want to handshake a request of N words.
4083 * (WRITE u32val to Doorbell reg).
4085 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4086 CHIPREG_WRITE32(&ioc->chip->Doorbell,
4087 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
4088 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
4091 * Wait for IOC's doorbell handshake int
4093 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4096 dhsprintk((MYIOC_s_INFO_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4097 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4099 /* Read doorbell and check for active bit */
4100 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
4104 * Clear doorbell int (WRITE 0 to IntStatus reg),
4105 * then wait for IOC to ACKnowledge that it's ready for
4106 * our handshake request.
4108 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4109 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4114 u8 *req_as_bytes = (u8 *) req;
4117 * Stuff request words via doorbell handshake,
4118 * with ACK from IOC for each.
4120 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
4121 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
4122 (req_as_bytes[(ii*4) + 1] << 8) |
4123 (req_as_bytes[(ii*4) + 2] << 16) |
4124 (req_as_bytes[(ii*4) + 3] << 24));
4126 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
4127 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4131 dhsprintk((KERN_INFO MYNAM ": Handshake request frame (@%p) header\n", req));
4132 DBG_DUMP_REQUEST_FRAME_HDR(req)
4134 dhsprintk((MYIOC_s_INFO_FMT "HandShake request post done, WaitCnt=%d%s\n",
4135 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
4138 * Wait for completion of doorbell handshake reply from the IOC
4140 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
4143 dhsprintk((MYIOC_s_INFO_FMT "HandShake reply count=%d%s\n",
4144 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
4147 * Copy out the cached reply...
4149 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
4150 u16reply[ii] = ioc->hs_reply[ii];
4158 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4160 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4161 * @ioc: Pointer to MPT_ADAPTER structure
4162 * @howlong: How long to wait (in seconds)
4163 * @sleepFlag: Specifies whether the process can sleep
4165 * This routine waits (up to ~2 seconds max) for IOC doorbell
4166 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4167 * bit in its IntStatus register being clear.
4169 * Returns a negative value on failure, else wait loop count.
4172 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4178 cntdn = 1000 * howlong;
4180 if (sleepFlag == CAN_SLEEP) {
4183 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4184 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4191 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4192 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4199 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell ACK (count=%d)\n",
4204 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4205 ioc->name, count, intstat);
4209 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4211 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4212 * @ioc: Pointer to MPT_ADAPTER structure
4213 * @howlong: How long to wait (in seconds)
4214 * @sleepFlag: Specifies whether the process can sleep
4216 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4217 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4219 * Returns a negative value on failure, else wait loop count.
4222 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4228 cntdn = 1000 * howlong;
4229 if (sleepFlag == CAN_SLEEP) {
4231 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4232 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4239 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4240 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4248 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4249 ioc->name, count, howlong));
4253 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4254 ioc->name, count, intstat);
4258 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4260 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4261 * @ioc: Pointer to MPT_ADAPTER structure
4262 * @howlong: How long to wait (in seconds)
4263 * @sleepFlag: Specifies whether the process can sleep
4265 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4266 * Reply is cached to IOC private area large enough to hold a maximum
4267 * of 128 bytes of reply data.
4269 * Returns a negative value on failure, else size of reply in WORDS.
4272 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4277 u16 *hs_reply = ioc->hs_reply;
4278 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4281 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4284 * Get first two u16's so we can look at IOC's intended reply MsgLength
4287 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4290 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4291 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4292 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4295 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4296 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4300 dhsprintk((MYIOC_s_INFO_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4301 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4302 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4305 * If no error (and IOC said MsgLength is > 0), piece together
4306 * reply 16 bits at a time.
4308 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4309 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4311 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4312 /* don't overflow our IOC hs_reply[] buffer! */
4313 if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
4314 hs_reply[u16cnt] = hword;
4315 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4318 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4320 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4323 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4328 else if (u16cnt != (2 * mptReply->MsgLength)) {
4331 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4336 dhsprintk((MYIOC_s_INFO_FMT "Got Handshake reply:\n", ioc->name));
4337 DBG_DUMP_REPLY_FRAME(mptReply)
4339 dhsprintk((MYIOC_s_INFO_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4340 ioc->name, t, u16cnt/2));
4344 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4346 * GetLanConfigPages - Fetch LANConfig pages.
4347 * @ioc: Pointer to MPT_ADAPTER structure
4349 * Return: 0 for success
4350 * -ENOMEM if no memory available
4351 * -EPERM if not allowed due to ISR context
4352 * -EAGAIN if no msg frames currently available
4353 * -EFAULT for non-successful reply or no reply (timeout)
4356 GetLanConfigPages(MPT_ADAPTER *ioc)
4358 ConfigPageHeader_t hdr;
4360 LANPage0_t *ppage0_alloc;
4361 dma_addr_t page0_dma;
4362 LANPage1_t *ppage1_alloc;
4363 dma_addr_t page1_dma;
4368 /* Get LAN Page 0 header */
4369 hdr.PageVersion = 0;
4372 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4373 cfg.cfghdr.hdr = &hdr;
4375 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4380 if ((rc = mpt_config(ioc, &cfg)) != 0)
4383 if (hdr.PageLength > 0) {
4384 data_sz = hdr.PageLength * 4;
4385 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4388 memset((u8 *)ppage0_alloc, 0, data_sz);
4389 cfg.physAddr = page0_dma;
4390 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4392 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4394 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4395 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4399 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4402 * Normalize endianness of structure data,
4403 * by byte-swapping all > 1 byte fields!
4412 /* Get LAN Page 1 header */
4413 hdr.PageVersion = 0;
4416 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4417 cfg.cfghdr.hdr = &hdr;
4419 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4423 if ((rc = mpt_config(ioc, &cfg)) != 0)
4426 if (hdr.PageLength == 0)
4429 data_sz = hdr.PageLength * 4;
4431 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4433 memset((u8 *)ppage1_alloc, 0, data_sz);
4434 cfg.physAddr = page1_dma;
4435 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4437 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4439 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4440 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4443 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4446 * Normalize endianness of structure data,
4447 * by byte-swapping all > 1 byte fields!
4455 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4457 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
4458 * @ioc: Pointer to MPT_ADAPTER structure
4459 * @persist_opcode: see below
4461 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4462 * devices not currently present.
4463 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4465 * NOTE: Don't use not this function during interrupt time.
4467 * Returns 0 for success, non-zero error
4470 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4472 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4474 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
4475 SasIoUnitControlReply_t *sasIoUnitCntrReply;
4476 MPT_FRAME_HDR *mf = NULL;
4477 MPIHeader_t *mpi_hdr;
4480 /* insure garbage is not sent to fw */
4481 switch(persist_opcode) {
4483 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
4484 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
4492 printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode);
4494 /* Get a MF for this command.
4496 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4497 printk("%s: no msg frames!\n",__FUNCTION__);
4501 mpi_hdr = (MPIHeader_t *) mf;
4502 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
4503 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
4504 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
4505 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
4506 sasIoUnitCntrReq->Operation = persist_opcode;
4508 init_timer(&ioc->persist_timer);
4509 ioc->persist_timer.data = (unsigned long) ioc;
4510 ioc->persist_timer.function = mpt_timer_expired;
4511 ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
4512 ioc->persist_wait_done=0;
4513 add_timer(&ioc->persist_timer);
4514 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4515 wait_event(mpt_waitq, ioc->persist_wait_done);
4517 sasIoUnitCntrReply =
4518 (SasIoUnitControlReply_t *)ioc->persist_reply_frame;
4519 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
4520 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4522 sasIoUnitCntrReply->IOCStatus,
4523 sasIoUnitCntrReply->IOCLogInfo);
4527 printk("%s: success\n",__FUNCTION__);
4531 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4534 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
4535 MpiEventDataRaid_t * pRaidEventData)
4544 volume = pRaidEventData->VolumeID;
4545 reason = pRaidEventData->ReasonCode;
4546 disk = pRaidEventData->PhysDiskNum;
4547 status = le32_to_cpu(pRaidEventData->SettingsStatus);
4548 flags = (status >> 0) & 0xff;
4549 state = (status >> 8) & 0xff;
4551 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
4555 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
4556 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
4557 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
4558 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
4559 ioc->name, disk, volume);
4561 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
4566 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4567 printk(MYIOC_s_INFO_FMT " volume has been created\n",
4571 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4573 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
4577 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
4578 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
4582 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4583 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
4585 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
4587 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
4589 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
4592 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
4594 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
4595 ? ", quiesced" : "",
4596 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
4597 ? ", resync in progress" : "" );
4600 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
4601 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
4605 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4606 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
4610 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4611 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
4615 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
4616 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
4620 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4621 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
4623 state == MPI_PHYSDISK0_STATUS_ONLINE
4625 : state == MPI_PHYSDISK0_STATUS_MISSING
4627 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
4629 : state == MPI_PHYSDISK0_STATUS_FAILED
4631 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
4633 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
4634 ? "offline requested"
4635 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
4636 ? "failed requested"
4637 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
4640 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
4641 ? ", out of sync" : "",
4642 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
4643 ? ", quiesced" : "" );
4646 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
4647 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
4651 case MPI_EVENT_RAID_RC_SMART_DATA:
4652 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
4653 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
4656 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
4657 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
4663 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4665 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4666 * @ioc: Pointer to MPT_ADAPTER structure
4668 * Returns: 0 for success
4669 * -ENOMEM if no memory available
4670 * -EPERM if not allowed due to ISR context
4671 * -EAGAIN if no msg frames currently available
4672 * -EFAULT for non-successful reply or no reply (timeout)
4675 GetIoUnitPage2(MPT_ADAPTER *ioc)
4677 ConfigPageHeader_t hdr;
4679 IOUnitPage2_t *ppage_alloc;
4680 dma_addr_t page_dma;
4684 /* Get the page header */
4685 hdr.PageVersion = 0;
4688 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4689 cfg.cfghdr.hdr = &hdr;
4691 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4696 if ((rc = mpt_config(ioc, &cfg)) != 0)
4699 if (hdr.PageLength == 0)
4702 /* Read the config page */
4703 data_sz = hdr.PageLength * 4;
4705 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4707 memset((u8 *)ppage_alloc, 0, data_sz);
4708 cfg.physAddr = page_dma;
4709 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4711 /* If Good, save data */
4712 if ((rc = mpt_config(ioc, &cfg)) == 0)
4713 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4715 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4721 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4723 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4724 * @ioc: Pointer to a Adapter Strucutre
4725 * @portnum: IOC port number
4727 * Return: -EFAULT if read of config page header fails
4729 * If read of SCSI Port Page 0 fails,
4730 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4731 * Adapter settings: async, narrow
4733 * If read of SCSI Port Page 2 fails,
4734 * Adapter settings valid
4735 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4740 * CHECK - what type of locking mechanisms should be used????
4743 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4748 ConfigPageHeader_t header;
4754 if (!ioc->spi_data.nvram) {
4757 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4758 mem = kmalloc(sz, GFP_ATOMIC);
4762 ioc->spi_data.nvram = (int *) mem;
4764 dprintk((MYIOC_s_INFO_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4765 ioc->name, ioc->spi_data.nvram, sz));
4768 /* Invalidate NVRAM information
4770 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4771 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4774 /* Read SPP0 header, allocate memory, then read page.
4776 header.PageVersion = 0;
4777 header.PageLength = 0;
4778 header.PageNumber = 0;
4779 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4780 cfg.cfghdr.hdr = &header;
4782 cfg.pageAddr = portnum;
4783 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4785 cfg.timeout = 0; /* use default */
4786 if (mpt_config(ioc, &cfg) != 0)
4789 if (header.PageLength > 0) {
4790 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4792 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4793 cfg.physAddr = buf_dma;
4794 if (mpt_config(ioc, &cfg) != 0) {
4795 ioc->spi_data.maxBusWidth = MPT_NARROW;
4796 ioc->spi_data.maxSyncOffset = 0;
4797 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4798 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4800 ddvprintk((MYIOC_s_INFO_FMT "Unable to read PortPage0 minSyncFactor=%x\n",
4801 ioc->name, ioc->spi_data.minSyncFactor));
4803 /* Save the Port Page 0 data
4805 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
4806 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4807 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4809 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
4810 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4811 ddvprintk((KERN_INFO MYNAM " :%s noQas due to Capabilities=%x\n",
4812 ioc->name, pPP0->Capabilities));
4814 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4815 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4817 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4818 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4819 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4820 ddvprintk((MYIOC_s_INFO_FMT "PortPage0 minSyncFactor=%x\n",
4821 ioc->name, ioc->spi_data.minSyncFactor));
4823 ioc->spi_data.maxSyncOffset = 0;
4824 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4827 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4829 /* Update the minSyncFactor based on bus type.
4831 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4832 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
4834 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
4835 ioc->spi_data.minSyncFactor = MPT_ULTRA;
4836 ddvprintk((MYIOC_s_INFO_FMT "HVD or SE detected, minSyncFactor=%x\n",
4837 ioc->name, ioc->spi_data.minSyncFactor));
4842 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4847 /* SCSI Port Page 2 - Read the header then the page.
4849 header.PageVersion = 0;
4850 header.PageLength = 0;
4851 header.PageNumber = 2;
4852 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4853 cfg.cfghdr.hdr = &header;
4855 cfg.pageAddr = portnum;
4856 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4858 if (mpt_config(ioc, &cfg) != 0)
4861 if (header.PageLength > 0) {
4862 /* Allocate memory and read SCSI Port Page 2
4864 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4866 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
4867 cfg.physAddr = buf_dma;
4868 if (mpt_config(ioc, &cfg) != 0) {
4869 /* Nvram data is left with INVALID mark
4873 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
4874 MpiDeviceInfo_t *pdevice = NULL;
4877 * Save "Set to Avoid SCSI Bus Resets" flag
4879 ioc->spi_data.bus_reset =
4880 (le32_to_cpu(pPP2->PortFlags) &
4881 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
4884 /* Save the Port Page 2 data
4885 * (reformat into a 32bit quantity)
4887 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
4888 ioc->spi_data.PortFlags = data;
4889 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4890 pdevice = &pPP2->DeviceSettings[ii];
4891 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
4892 (pdevice->SyncFactor << 8) | pdevice->Timeout;
4893 ioc->spi_data.nvram[ii] = data;
4897 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4901 /* Update Adapter limits with those from NVRAM
4902 * Comment: Don't need to do this. Target performance
4903 * parameters will never exceed the adapters limits.
4909 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4911 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
4912 * @ioc: Pointer to a Adapter Strucutre
4913 * @portnum: IOC port number
4915 * Return: -EFAULT if read of config page header fails
4919 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
4922 ConfigPageHeader_t header;
4924 /* Read the SCSI Device Page 1 header
4926 header.PageVersion = 0;
4927 header.PageLength = 0;
4928 header.PageNumber = 1;
4929 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4930 cfg.cfghdr.hdr = &header;
4932 cfg.pageAddr = portnum;
4933 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4936 if (mpt_config(ioc, &cfg) != 0)
4939 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
4940 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
4942 header.PageVersion = 0;
4943 header.PageLength = 0;
4944 header.PageNumber = 0;
4945 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4946 if (mpt_config(ioc, &cfg) != 0)
4949 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
4950 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
4952 dcprintk((MYIOC_s_INFO_FMT "Headers: 0: version %d length %d\n",
4953 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
4955 dcprintk((MYIOC_s_INFO_FMT "Headers: 1: version %d length %d\n",
4956 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
4961 * mpt_inactive_raid_list_free - This clears this link list.
4962 * @ioc : pointer to per adapter structure
4965 mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
4967 struct inactive_raid_component_info *component_info, *pNext;
4969 if (list_empty(&ioc->raid_data.inactive_list))
4972 down(&ioc->raid_data.inactive_list_mutex);
4973 list_for_each_entry_safe(component_info, pNext,
4974 &ioc->raid_data.inactive_list, list) {
4975 list_del(&component_info->list);
4976 kfree(component_info);
4978 up(&ioc->raid_data.inactive_list_mutex);
4982 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
4984 * @ioc : pointer to per adapter structure
4985 * @channel : volume channel
4986 * @id : volume target id
4989 mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
4992 ConfigPageHeader_t hdr;
4993 dma_addr_t dma_handle;
4994 pRaidVolumePage0_t buffer = NULL;
4996 RaidPhysDiskPage0_t phys_disk;
4997 struct inactive_raid_component_info *component_info;
4998 int handle_inactive_volumes;
5000 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5001 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5002 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
5003 cfg.pageAddr = (channel << 8) + id;
5004 cfg.cfghdr.hdr = &hdr;
5005 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5007 if (mpt_config(ioc, &cfg) != 0)
5010 if (!hdr.PageLength)
5013 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5019 cfg.physAddr = dma_handle;
5020 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5022 if (mpt_config(ioc, &cfg) != 0)
5025 if (!buffer->NumPhysDisks)
5028 handle_inactive_volumes =
5029 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
5030 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
5031 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
5032 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
5034 if (!handle_inactive_volumes)
5037 down(&ioc->raid_data.inactive_list_mutex);
5038 for (i = 0; i < buffer->NumPhysDisks; i++) {
5039 if(mpt_raid_phys_disk_pg0(ioc,
5040 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
5043 if ((component_info = kmalloc(sizeof (*component_info),
5044 GFP_KERNEL)) == NULL)
5047 component_info->volumeID = id;
5048 component_info->volumeBus = channel;
5049 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
5050 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
5051 component_info->d.PhysDiskID = phys_disk.PhysDiskID;
5052 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
5054 list_add_tail(&component_info->list,
5055 &ioc->raid_data.inactive_list);
5057 up(&ioc->raid_data.inactive_list_mutex);
5061 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5066 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5067 * @ioc: Pointer to a Adapter Structure
5068 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5069 * @phys_disk: requested payload data returned
5073 * -EFAULT if read of config page header fails or data pointer not NULL
5074 * -ENOMEM if pci_alloc failed
5077 mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk)
5080 ConfigPageHeader_t hdr;
5081 dma_addr_t dma_handle;
5082 pRaidPhysDiskPage0_t buffer = NULL;
5085 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5086 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5088 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5089 cfg.cfghdr.hdr = &hdr;
5091 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5093 if (mpt_config(ioc, &cfg) != 0) {
5098 if (!hdr.PageLength) {
5103 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5111 cfg.physAddr = dma_handle;
5112 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5113 cfg.pageAddr = phys_disk_num;
5115 if (mpt_config(ioc, &cfg) != 0) {
5121 memcpy(phys_disk, buffer, sizeof(*buffer));
5122 phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
5127 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5134 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5135 * @ioc: Pointer to a Adapter Strucutre
5136 * @portnum: IOC port number
5140 * -EFAULT if read of config page header fails or data pointer not NULL
5141 * -ENOMEM if pci_alloc failed
5144 mpt_findImVolumes(MPT_ADAPTER *ioc)
5148 dma_addr_t ioc2_dma;
5150 ConfigPageHeader_t header;
5155 if (!ioc->ir_firmware)
5158 /* Free the old page
5160 kfree(ioc->raid_data.pIocPg2);
5161 ioc->raid_data.pIocPg2 = NULL;
5162 mpt_inactive_raid_list_free(ioc);
5164 /* Read IOCP2 header then the page.
5166 header.PageVersion = 0;
5167 header.PageLength = 0;
5168 header.PageNumber = 2;
5169 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5170 cfg.cfghdr.hdr = &header;
5173 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5176 if (mpt_config(ioc, &cfg) != 0)
5179 if (header.PageLength == 0)
5182 iocpage2sz = header.PageLength * 4;
5183 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
5187 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5188 cfg.physAddr = ioc2_dma;
5189 if (mpt_config(ioc, &cfg) != 0)
5192 mem = kmalloc(iocpage2sz, GFP_KERNEL);
5196 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
5197 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
5199 mpt_read_ioc_pg_3(ioc);
5201 for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
5202 mpt_inactive_raid_volumes(ioc,
5203 pIoc2->RaidVolume[i].VolumeBus,
5204 pIoc2->RaidVolume[i].VolumeID);
5207 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
5213 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
5218 ConfigPageHeader_t header;
5219 dma_addr_t ioc3_dma;
5222 /* Free the old page
5224 kfree(ioc->raid_data.pIocPg3);
5225 ioc->raid_data.pIocPg3 = NULL;
5227 /* There is at least one physical disk.
5228 * Read and save IOC Page 3
5230 header.PageVersion = 0;
5231 header.PageLength = 0;
5232 header.PageNumber = 3;
5233 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5234 cfg.cfghdr.hdr = &header;
5237 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5240 if (mpt_config(ioc, &cfg) != 0)
5243 if (header.PageLength == 0)
5246 /* Read Header good, alloc memory
5248 iocpage3sz = header.PageLength * 4;
5249 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
5253 /* Read the Page and save the data
5254 * into malloc'd memory.
5256 cfg.physAddr = ioc3_dma;
5257 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5258 if (mpt_config(ioc, &cfg) == 0) {
5259 mem = kmalloc(iocpage3sz, GFP_KERNEL);
5261 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
5262 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
5266 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
5272 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
5276 ConfigPageHeader_t header;
5277 dma_addr_t ioc4_dma;
5280 /* Read and save IOC Page 4
5282 header.PageVersion = 0;
5283 header.PageLength = 0;
5284 header.PageNumber = 4;
5285 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5286 cfg.cfghdr.hdr = &header;
5289 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5292 if (mpt_config(ioc, &cfg) != 0)
5295 if (header.PageLength == 0)
5298 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
5299 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
5300 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
5303 ioc->alloc_total += iocpage4sz;
5305 ioc4_dma = ioc->spi_data.IocPg4_dma;
5306 iocpage4sz = ioc->spi_data.IocPg4Sz;
5309 /* Read the Page into dma memory.
5311 cfg.physAddr = ioc4_dma;
5312 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5313 if (mpt_config(ioc, &cfg) == 0) {
5314 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
5315 ioc->spi_data.IocPg4_dma = ioc4_dma;
5316 ioc->spi_data.IocPg4Sz = iocpage4sz;
5318 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
5319 ioc->spi_data.pIocPg4 = NULL;
5320 ioc->alloc_total -= iocpage4sz;
5325 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
5329 ConfigPageHeader_t header;
5330 dma_addr_t ioc1_dma;
5334 /* Check the Coalescing Timeout in IOC Page 1
5336 header.PageVersion = 0;
5337 header.PageLength = 0;
5338 header.PageNumber = 1;
5339 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5340 cfg.cfghdr.hdr = &header;
5343 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5346 if (mpt_config(ioc, &cfg) != 0)
5349 if (header.PageLength == 0)
5352 /* Read Header good, alloc memory
5354 iocpage1sz = header.PageLength * 4;
5355 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
5359 /* Read the Page and check coalescing timeout
5361 cfg.physAddr = ioc1_dma;
5362 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5363 if (mpt_config(ioc, &cfg) == 0) {
5365 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
5366 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
5367 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
5369 dprintk((MYIOC_s_INFO_FMT "Coalescing Enabled Timeout = %d\n",
5372 if (tmp > MPT_COALESCING_TIMEOUT) {
5373 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
5375 /* Write NVRAM and current
5378 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5379 if (mpt_config(ioc, &cfg) == 0) {
5380 dprintk((MYIOC_s_INFO_FMT "Reset Current Coalescing Timeout to = %d\n",
5381 ioc->name, MPT_COALESCING_TIMEOUT));
5383 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
5384 if (mpt_config(ioc, &cfg) == 0) {
5385 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout to = %d\n",
5386 ioc->name, MPT_COALESCING_TIMEOUT));
5388 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout Failed\n",
5393 dprintk((MYIOC_s_WARN_FMT "Reset of Current Coalescing Timeout Failed!\n",
5399 dprintk((MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
5403 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
5409 mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
5412 ConfigPageHeader_t hdr;
5414 ManufacturingPage0_t *pbuf = NULL;
5416 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5417 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5419 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
5420 cfg.cfghdr.hdr = &hdr;
5422 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5425 if (mpt_config(ioc, &cfg) != 0)
5428 if (!cfg.cfghdr.hdr->PageLength)
5431 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5432 pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
5436 cfg.physAddr = buf_dma;
5438 if (mpt_config(ioc, &cfg) != 0)
5441 memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name));
5442 memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
5443 memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
5448 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
5451 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5453 * SendEventNotification - Send EventNotification (on or off) request to adapter
5454 * @ioc: Pointer to MPT_ADAPTER structure
5455 * @EvSwitch: Event switch flags
5458 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
5460 EventNotification_t *evnp;
5462 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
5464 devtverboseprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
5468 memset(evnp, 0, sizeof(*evnp));
5470 devtverboseprintk((MYIOC_s_INFO_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
5472 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
5473 evnp->ChainOffset = 0;
5475 evnp->Switch = EvSwitch;
5477 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
5482 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5484 * SendEventAck - Send EventAck request to MPT adapter.
5485 * @ioc: Pointer to MPT_ADAPTER structure
5486 * @evnp: Pointer to original EventNotification request
5489 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
5493 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5494 dfailprintk((MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
5495 ioc->name,__FUNCTION__));
5499 devtverboseprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name));
5501 pAck->Function = MPI_FUNCTION_EVENT_ACK;
5502 pAck->ChainOffset = 0;
5503 pAck->Reserved[0] = pAck->Reserved[1] = 0;
5505 pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
5506 pAck->Event = evnp->Event;
5507 pAck->EventContext = evnp->EventContext;
5509 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
5514 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5516 * mpt_config - Generic function to issue config message
5517 * @ioc: Pointer to an adapter structure
5518 * @pCfg: Pointer to a configuration structure. Struct contains
5519 * action, page address, direction, physical address
5520 * and pointer to a configuration page header
5521 * Page header is updated.
5523 * Returns 0 for success
5524 * -EPERM if not allowed due to ISR context
5525 * -EAGAIN if no msg frames currently available
5526 * -EFAULT for non-successful reply or no reply (timeout)
5529 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5532 ConfigExtendedPageHeader_t *pExtHdr = NULL;
5534 unsigned long flags;
5539 /* Prevent calling wait_event() (below), if caller happens
5540 * to be in ISR context, because that is fatal!
5542 in_isr = in_interrupt();
5544 dcprintk((MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
5549 /* Get and Populate a free Frame
5551 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5552 dcprintk((MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
5556 pReq = (Config_t *)mf;
5557 pReq->Action = pCfg->action;
5559 pReq->ChainOffset = 0;
5560 pReq->Function = MPI_FUNCTION_CONFIG;
5562 /* Assume page type is not extended and clear "reserved" fields. */
5563 pReq->ExtPageLength = 0;
5564 pReq->ExtPageType = 0;
5567 for (ii=0; ii < 8; ii++)
5568 pReq->Reserved2[ii] = 0;
5570 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
5571 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
5572 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
5573 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
5575 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5576 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
5577 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
5578 pReq->ExtPageType = pExtHdr->ExtPageType;
5579 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
5581 /* Page Length must be treated as a reserved field for the extended header. */
5582 pReq->Header.PageLength = 0;
5585 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
5587 /* Add a SGE to the config request.
5590 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
5592 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
5594 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5595 flagsLength |= pExtHdr->ExtPageLength * 4;
5597 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
5598 ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action));
5601 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
5603 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
5604 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
5607 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
5609 /* Append pCfg pointer to end of mf
5611 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5613 /* Initalize the timer
5615 init_timer(&pCfg->timer);
5616 pCfg->timer.data = (unsigned long) ioc;
5617 pCfg->timer.function = mpt_timer_expired;
5618 pCfg->wait_done = 0;
5620 /* Set the timer; ensure 10 second minimum */
5621 if (pCfg->timeout < 10)
5622 pCfg->timer.expires = jiffies + HZ*10;
5624 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5626 /* Add to end of Q, set timer and then issue this command */
5627 spin_lock_irqsave(&ioc->FreeQlock, flags);
5628 list_add_tail(&pCfg->linkage, &ioc->configQ);
5629 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5631 add_timer(&pCfg->timer);
5632 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5633 wait_event(mpt_waitq, pCfg->wait_done);
5635 /* mf has been freed - do not access */
5642 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5644 * mpt_timer_expired - Callback for timer process.
5645 * Used only internal config functionality.
5646 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5649 mpt_timer_expired(unsigned long data)
5651 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
5653 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired! \n", ioc->name));
5655 /* Perform a FW reload */
5656 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
5657 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
5659 /* No more processing.
5660 * Hard reset clean-up will wake up
5661 * process and free all resources.
5663 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired complete!\n", ioc->name));
5668 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5670 * mpt_ioc_reset - Base cleanup for hard reset
5671 * @ioc: Pointer to the adapter structure
5672 * @reset_phase: Indicates pre- or post-reset functionality
5674 * Remark: Frees resources with internally generated commands.
5677 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
5680 unsigned long flags;
5682 dprintk((KERN_WARNING MYNAM
5683 ": IOC %s_reset routed to MPT base driver!\n",
5684 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
5685 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
5687 if (reset_phase == MPT_IOC_SETUP_RESET) {
5689 } else if (reset_phase == MPT_IOC_PRE_RESET) {
5690 /* If the internal config Q is not empty -
5691 * delete timer. MF resources will be freed when
5692 * the FIFO's are primed.
5694 spin_lock_irqsave(&ioc->FreeQlock, flags);
5695 list_for_each_entry(pCfg, &ioc->configQ, linkage)
5696 del_timer(&pCfg->timer);
5697 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5702 /* Search the configQ for internal commands.
5703 * Flush the Q, and wake up all suspended threads.
5705 spin_lock_irqsave(&ioc->FreeQlock, flags);
5706 list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
5707 list_del(&pCfg->linkage);
5709 pCfg->status = MPT_CONFIG_ERROR;
5710 pCfg->wait_done = 1;
5711 wake_up(&mpt_waitq);
5713 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5716 return 1; /* currently means nothing really */
5720 #ifdef CONFIG_PROC_FS /* { */
5721 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5723 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5725 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5727 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5729 * Returns 0 for success, non-zero for failure.
5732 procmpt_create(void)
5734 struct proc_dir_entry *ent;
5736 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
5737 if (mpt_proc_root_dir == NULL)
5740 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5742 ent->read_proc = procmpt_summary_read;
5744 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5746 ent->read_proc = procmpt_version_read;
5751 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5753 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5755 * Returns 0 for success, non-zero for failure.
5758 procmpt_destroy(void)
5760 remove_proc_entry("version", mpt_proc_root_dir);
5761 remove_proc_entry("summary", mpt_proc_root_dir);
5762 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
5765 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5767 * procmpt_summary_read - Handle read request of a summary file
5768 * @buf: Pointer to area to write information
5769 * @start: Pointer to start pointer
5770 * @offset: Offset to start writing
5771 * @request: Amount of read data requested
5772 * @eof: Pointer to EOF integer
5775 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
5776 * Returns number of characters written to process performing the read.
5779 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5789 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5793 list_for_each_entry(ioc, &ioc_list, list) {
5796 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5799 if ((out-buf) >= request)
5806 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5809 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5811 * procmpt_version_read - Handle read request from /proc/mpt/version.
5812 * @buf: Pointer to area to write information
5813 * @start: Pointer to start pointer
5814 * @offset: Offset to start writing
5815 * @request: Amount of read data requested
5816 * @eof: Pointer to EOF integer
5819 * Returns number of characters written to process performing the read.
5822 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5825 int scsi, fc, sas, lan, ctl, targ, dmp;
5829 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
5830 len += sprintf(buf+len, " Fusion MPT base driver\n");
5832 scsi = fc = sas = lan = ctl = targ = dmp = 0;
5833 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5835 if (MptCallbacks[ii]) {
5836 switch (MptDriverClass[ii]) {
5838 if (!scsi++) drvname = "SPI host";
5841 if (!fc++) drvname = "FC host";
5844 if (!sas++) drvname = "SAS host";
5847 if (!lan++) drvname = "LAN";
5850 if (!targ++) drvname = "SCSI target";
5853 if (!ctl++) drvname = "ioctl";
5858 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
5862 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5865 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5867 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
5868 * @buf: Pointer to area to write information
5869 * @start: Pointer to start pointer
5870 * @offset: Offset to start writing
5871 * @request: Amount of read data requested
5872 * @eof: Pointer to EOF integer
5875 * Returns number of characters written to process performing the read.
5878 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5880 MPT_ADAPTER *ioc = data;
5886 mpt_get_fw_exp_ver(expVer, ioc);
5888 len = sprintf(buf, "%s:", ioc->name);
5889 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
5890 len += sprintf(buf+len, " (f/w download boot flag set)");
5891 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
5892 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
5894 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
5895 ioc->facts.ProductID,
5897 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
5898 if (ioc->facts.FWImageSize)
5899 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
5900 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
5901 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
5902 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
5904 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
5905 ioc->facts.CurrentHostMfaHighAddr);
5906 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
5907 ioc->facts.CurrentSenseBufferHighAddr);
5909 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
5910 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
5912 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
5913 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
5915 * Rounding UP to nearest 4-kB boundary here...
5917 sz = (ioc->req_sz * ioc->req_depth) + 128;
5918 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
5919 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
5920 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
5921 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
5922 4*ioc->facts.RequestFrameSize,
5923 ioc->facts.GlobalCredits);
5925 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
5926 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
5927 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
5928 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
5929 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
5930 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
5931 ioc->facts.CurReplyFrameSize,
5932 ioc->facts.ReplyQueueDepth);
5934 len += sprintf(buf+len, " MaxDevices = %d\n",
5935 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
5936 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
5939 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
5940 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
5942 ioc->facts.NumberOfPorts);
5943 if (ioc->bus_type == FC) {
5944 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
5945 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5946 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
5947 a[5], a[4], a[3], a[2], a[1], a[0]);
5949 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
5950 ioc->fc_port_page0[p].WWNN.High,
5951 ioc->fc_port_page0[p].WWNN.Low,
5952 ioc->fc_port_page0[p].WWPN.High,
5953 ioc->fc_port_page0[p].WWPN.Low);
5957 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5960 #endif /* CONFIG_PROC_FS } */
5962 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5964 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
5967 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
5968 sprintf(buf, " (Exp %02d%02d)",
5969 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
5970 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
5973 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
5974 strcat(buf, " [MDBG]");
5978 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5980 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
5981 * @ioc: Pointer to MPT_ADAPTER structure
5982 * @buffer: Pointer to buffer where IOC summary info should be written
5983 * @size: Pointer to number of bytes we wrote (set by this routine)
5984 * @len: Offset at which to start writing in buffer
5985 * @showlan: Display LAN stuff?
5987 * This routine writes (english readable) ASCII text, which represents
5988 * a summary of IOC information, to a buffer.
5991 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
5996 mpt_get_fw_exp_ver(expVer, ioc);
5999 * Shorter summary of attached ioc's...
6001 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6004 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
6005 ioc->facts.FWVersion.Word,
6007 ioc->facts.NumberOfPorts,
6010 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6011 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6012 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6013 a[5], a[4], a[3], a[2], a[1], a[0]);
6016 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
6019 y += sprintf(buffer+len+y, " (disabled)");
6021 y += sprintf(buffer+len+y, "\n");
6026 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6030 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6032 * mpt_HardResetHandler - Generic reset handler
6033 * @ioc: Pointer to MPT_ADAPTER structure
6034 * @sleepFlag: Indicates if sleep or schedule must be called.
6036 * Issues SCSI Task Management call based on input arg values.
6037 * If TaskMgmt fails, returns associated SCSI request.
6039 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
6040 * or a non-interrupt thread. In the former, must not call schedule().
6042 * Note: A return of -1 is a FATAL error case, as it means a
6043 * FW reload/initialization failed.
6045 * Returns 0 for SUCCESS or -1 if FAILED.
6048 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6051 unsigned long flags;
6053 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name));
6055 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
6056 printk("MF count 0x%x !\n", ioc->mfcnt);
6059 /* Reset the adapter. Prevent more than 1 call to
6060 * mpt_do_ioc_recovery at any instant in time.
6062 spin_lock_irqsave(&ioc->diagLock, flags);
6063 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
6064 spin_unlock_irqrestore(&ioc->diagLock, flags);
6067 ioc->diagPending = 1;
6069 spin_unlock_irqrestore(&ioc->diagLock, flags);
6071 /* FIXME: If do_ioc_recovery fails, repeat....
6074 /* The SCSI driver needs to adjust timeouts on all current
6075 * commands prior to the diagnostic reset being issued.
6076 * Prevents timeouts occurring during a diagnostic reset...very bad.
6077 * For all other protocol drivers, this is a no-op.
6083 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
6084 if (MptResetHandlers[ii]) {
6085 dtmprintk((MYIOC_s_INFO_FMT "Calling IOC reset_setup handler #%d\n",
6087 r += mpt_signal_reset(ii, ioc, MPT_IOC_SETUP_RESET);
6089 dtmprintk((MYIOC_s_INFO_FMT "Calling alt-%s setup reset handler #%d\n",
6090 ioc->name, ioc->alt_ioc->name, ii));
6091 r += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_SETUP_RESET);
6097 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
6098 printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
6103 ioc->alt_ioc->reload_fw = 0;
6105 spin_lock_irqsave(&ioc->diagLock, flags);
6106 ioc->diagPending = 0;
6108 ioc->alt_ioc->diagPending = 0;
6109 spin_unlock_irqrestore(&ioc->diagLock, flags);
6111 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
6116 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6118 EventDescriptionStr(u8 event, u32 evData0, char *evStr)
6123 case MPI_EVENT_NONE:
6126 case MPI_EVENT_LOG_DATA:
6129 case MPI_EVENT_STATE_CHANGE:
6130 ds = "State Change";
6132 case MPI_EVENT_UNIT_ATTENTION:
6133 ds = "Unit Attention";
6135 case MPI_EVENT_IOC_BUS_RESET:
6136 ds = "IOC Bus Reset";
6138 case MPI_EVENT_EXT_BUS_RESET:
6139 ds = "External Bus Reset";
6141 case MPI_EVENT_RESCAN:
6142 ds = "Bus Rescan Event";
6144 case MPI_EVENT_LINK_STATUS_CHANGE:
6145 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
6146 ds = "Link Status(FAILURE) Change";
6148 ds = "Link Status(ACTIVE) Change";
6150 case MPI_EVENT_LOOP_STATE_CHANGE:
6151 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
6152 ds = "Loop State(LIP) Change";
6153 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
6154 ds = "Loop State(LPE) Change"; /* ??? */
6156 ds = "Loop State(LPB) Change"; /* ??? */
6158 case MPI_EVENT_LOGOUT:
6161 case MPI_EVENT_EVENT_CHANGE:
6167 case MPI_EVENT_INTEGRATED_RAID:
6169 u8 ReasonCode = (u8)(evData0 >> 16);
6170 switch (ReasonCode) {
6171 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
6172 ds = "Integrated Raid: Volume Created";
6174 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
6175 ds = "Integrated Raid: Volume Deleted";
6177 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
6178 ds = "Integrated Raid: Volume Settings Changed";
6180 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
6181 ds = "Integrated Raid: Volume Status Changed";
6183 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
6184 ds = "Integrated Raid: Volume Physdisk Changed";
6186 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
6187 ds = "Integrated Raid: Physdisk Created";
6189 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
6190 ds = "Integrated Raid: Physdisk Deleted";
6192 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
6193 ds = "Integrated Raid: Physdisk Settings Changed";
6195 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
6196 ds = "Integrated Raid: Physdisk Status Changed";
6198 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
6199 ds = "Integrated Raid: Domain Validation Needed";
6201 case MPI_EVENT_RAID_RC_SMART_DATA :
6202 ds = "Integrated Raid; Smart Data";
6204 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
6205 ds = "Integrated Raid: Replace Action Started";
6208 ds = "Integrated Raid";
6213 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
6214 ds = "SCSI Device Status Change";
6216 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
6218 u8 id = (u8)(evData0);
6219 u8 channel = (u8)(evData0 >> 8);
6220 u8 ReasonCode = (u8)(evData0 >> 16);
6221 switch (ReasonCode) {
6222 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
6223 snprintf(evStr, EVENT_DESCR_STR_SZ,
6224 "SAS Device Status Change: Added: "
6225 "id=%d channel=%d", id, channel);
6227 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
6228 snprintf(evStr, EVENT_DESCR_STR_SZ,
6229 "SAS Device Status Change: Deleted: "
6230 "id=%d channel=%d", id, channel);
6232 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
6233 snprintf(evStr, EVENT_DESCR_STR_SZ,
6234 "SAS Device Status Change: SMART Data: "
6235 "id=%d channel=%d", id, channel);
6237 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
6238 snprintf(evStr, EVENT_DESCR_STR_SZ,
6239 "SAS Device Status Change: No Persistancy: "
6240 "id=%d channel=%d", id, channel);
6242 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
6243 snprintf(evStr, EVENT_DESCR_STR_SZ,
6244 "SAS Device Status Change: Unsupported Device "
6245 "Discovered : id=%d channel=%d", id, channel);
6247 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
6248 snprintf(evStr, EVENT_DESCR_STR_SZ,
6249 "SAS Device Status Change: Internal Device "
6250 "Reset : id=%d channel=%d", id, channel);
6252 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
6253 snprintf(evStr, EVENT_DESCR_STR_SZ,
6254 "SAS Device Status Change: Internal Task "
6255 "Abort : id=%d channel=%d", id, channel);
6257 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
6258 snprintf(evStr, EVENT_DESCR_STR_SZ,
6259 "SAS Device Status Change: Internal Abort "
6260 "Task Set : id=%d channel=%d", id, channel);
6262 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
6263 snprintf(evStr, EVENT_DESCR_STR_SZ,
6264 "SAS Device Status Change: Internal Clear "
6265 "Task Set : id=%d channel=%d", id, channel);
6267 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
6268 snprintf(evStr, EVENT_DESCR_STR_SZ,
6269 "SAS Device Status Change: Internal Query "
6270 "Task : id=%d channel=%d", id, channel);
6273 snprintf(evStr, EVENT_DESCR_STR_SZ,
6274 "SAS Device Status Change: Unknown: "
6275 "id=%d channel=%d", id, channel);
6280 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
6281 ds = "Bus Timer Expired";
6283 case MPI_EVENT_QUEUE_FULL:
6285 u16 curr_depth = (u16)(evData0 >> 16);
6286 u8 channel = (u8)(evData0 >> 8);
6287 u8 id = (u8)(evData0);
6289 snprintf(evStr, EVENT_DESCR_STR_SZ,
6290 "Queue Full: channel=%d id=%d depth=%d",
6291 channel, id, curr_depth);
6294 case MPI_EVENT_SAS_SES:
6295 ds = "SAS SES Event";
6297 case MPI_EVENT_PERSISTENT_TABLE_FULL:
6298 ds = "Persistent Table Full";
6300 case MPI_EVENT_SAS_PHY_LINK_STATUS:
6302 u8 LinkRates = (u8)(evData0 >> 8);
6303 u8 PhyNumber = (u8)(evData0);
6304 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
6305 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
6306 switch (LinkRates) {
6307 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
6308 snprintf(evStr, EVENT_DESCR_STR_SZ,
6309 "SAS PHY Link Status: Phy=%d:"
6310 " Rate Unknown",PhyNumber);
6312 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
6313 snprintf(evStr, EVENT_DESCR_STR_SZ,
6314 "SAS PHY Link Status: Phy=%d:"
6315 " Phy Disabled",PhyNumber);
6317 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
6318 snprintf(evStr, EVENT_DESCR_STR_SZ,
6319 "SAS PHY Link Status: Phy=%d:"
6320 " Failed Speed Nego",PhyNumber);
6322 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
6323 snprintf(evStr, EVENT_DESCR_STR_SZ,
6324 "SAS PHY Link Status: Phy=%d:"
6325 " Sata OOB Completed",PhyNumber);
6327 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
6328 snprintf(evStr, EVENT_DESCR_STR_SZ,
6329 "SAS PHY Link Status: Phy=%d:"
6330 " Rate 1.5 Gbps",PhyNumber);
6332 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
6333 snprintf(evStr, EVENT_DESCR_STR_SZ,
6334 "SAS PHY Link Status: Phy=%d:"
6335 " Rate 3.0 Gpbs",PhyNumber);
6338 snprintf(evStr, EVENT_DESCR_STR_SZ,
6339 "SAS PHY Link Status: Phy=%d", PhyNumber);
6344 case MPI_EVENT_SAS_DISCOVERY_ERROR:
6345 ds = "SAS Discovery Error";
6347 case MPI_EVENT_IR_RESYNC_UPDATE:
6349 u8 resync_complete = (u8)(evData0 >> 16);
6350 snprintf(evStr, EVENT_DESCR_STR_SZ,
6351 "IR Resync Update: Complete = %d:",resync_complete);
6356 u8 ReasonCode = (u8)(evData0 >> 16);
6357 switch (ReasonCode) {
6358 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
6359 ds = "IR2: LD State Changed";
6361 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
6362 ds = "IR2: PD State Changed";
6364 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
6365 ds = "IR2: Bad Block Table Full";
6367 case MPI_EVENT_IR2_RC_PD_INSERTED:
6368 ds = "IR2: PD Inserted";
6370 case MPI_EVENT_IR2_RC_PD_REMOVED:
6371 ds = "IR2: PD Removed";
6373 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
6374 ds = "IR2: Foreign CFG Detected";
6376 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
6377 ds = "IR2: Rebuild Medium Error";
6385 case MPI_EVENT_SAS_DISCOVERY:
6388 ds = "SAS Discovery: Start";
6390 ds = "SAS Discovery: Stop";
6393 case MPI_EVENT_LOG_ENTRY_ADDED:
6394 ds = "SAS Log Entry Added";
6397 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
6399 u8 phy_num = (u8)(evData0);
6400 u8 port_num = (u8)(evData0 >> 8);
6401 u8 port_width = (u8)(evData0 >> 16);
6402 u8 primative = (u8)(evData0 >> 24);
6403 snprintf(evStr, EVENT_DESCR_STR_SZ,
6404 "SAS Broadcase Primative: phy=%d port=%d "
6405 "width=%d primative=0x%02x",
6406 phy_num, port_num, port_width, primative);
6410 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
6412 u8 reason = (u8)(evData0);
6413 u8 port_num = (u8)(evData0 >> 8);
6414 u16 handle = le16_to_cpu(evData0 >> 16);
6416 snprintf(evStr, EVENT_DESCR_STR_SZ,
6417 "SAS Initiator Device Status Change: reason=0x%02x "
6418 "port=%d handle=0x%04x",
6419 reason, port_num, handle);
6423 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
6425 u8 max_init = (u8)(evData0);
6426 u8 current_init = (u8)(evData0 >> 8);
6428 snprintf(evStr, EVENT_DESCR_STR_SZ,
6429 "SAS Initiator Device Table Overflow: max initiators=%02d "
6430 "current initators=%02d",
6431 max_init, current_init);
6434 case MPI_EVENT_SAS_SMP_ERROR:
6436 u8 status = (u8)(evData0);
6437 u8 port_num = (u8)(evData0 >> 8);
6438 u8 result = (u8)(evData0 >> 16);
6440 if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
6441 snprintf(evStr, EVENT_DESCR_STR_SZ,
6442 "SAS SMP Error: port=%d result=0x%02x",
6444 else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
6445 snprintf(evStr, EVENT_DESCR_STR_SZ,
6446 "SAS SMP Error: port=%d : CRC Error",
6448 else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
6449 snprintf(evStr, EVENT_DESCR_STR_SZ,
6450 "SAS SMP Error: port=%d : Timeout",
6452 else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
6453 snprintf(evStr, EVENT_DESCR_STR_SZ,
6454 "SAS SMP Error: port=%d : No Destination",
6456 else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
6457 snprintf(evStr, EVENT_DESCR_STR_SZ,
6458 "SAS SMP Error: port=%d : Bad Destination",
6461 snprintf(evStr, EVENT_DESCR_STR_SZ,
6462 "SAS SMP Error: port=%d : status=0x%02x",
6468 * MPT base "custom" events may be added here...
6475 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
6478 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6480 * ProcessEventNotification - Route EventNotificationReply to all event handlers
6481 * @ioc: Pointer to MPT_ADAPTER structure
6482 * @pEventReply: Pointer to EventNotification reply frame
6483 * @evHandlers: Pointer to integer, number of event handlers
6485 * Routes a received EventNotificationReply to all currently registered
6487 * Returns sum of event handlers return values.
6490 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
6498 char evStr[EVENT_DESCR_STR_SZ];
6502 * Do platform normalization of values
6504 event = le32_to_cpu(pEventReply->Event) & 0xFF;
6505 // evCtx = le32_to_cpu(pEventReply->EventContext);
6506 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
6508 evData0 = le32_to_cpu(pEventReply->Data[0]);
6511 EventDescriptionStr(event, evData0, evStr);
6512 devtprintk((MYIOC_s_INFO_FMT "MPT event:(%02Xh) : %s\n",
6517 #if defined(MPT_DEBUG) || defined(MPT_DEBUG_VERBOSE_EVENTS)
6518 printk(KERN_INFO MYNAM ": Event data:\n" KERN_INFO);
6519 for (ii = 0; ii < evDataLen; ii++)
6520 printk(" %08x", le32_to_cpu(pEventReply->Data[ii]));
6525 * Do general / base driver event processing
6528 case MPI_EVENT_EVENT_CHANGE: /* 0A */
6530 u8 evState = evData0 & 0xFF;
6532 /* CHECKME! What if evState unexpectedly says OFF (0)? */
6534 /* Update EventState field in cached IocFacts */
6535 if (ioc->facts.Function) {
6536 ioc->facts.EventState = evState;
6540 case MPI_EVENT_INTEGRATED_RAID:
6541 mptbase_raid_process_event_data(ioc,
6542 (MpiEventDataRaid_t *)pEventReply->Data);
6549 * Should this event be logged? Events are written sequentially.
6550 * When buffer is full, start again at the top.
6552 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
6555 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
6557 ioc->events[idx].event = event;
6558 ioc->events[idx].eventContext = ioc->eventContext;
6560 for (ii = 0; ii < 2; ii++) {
6562 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
6564 ioc->events[idx].data[ii] = 0;
6567 ioc->eventContext++;
6572 * Call each currently registered protocol event handler.
6574 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
6575 if (MptEvHandlers[ii]) {
6576 devtverboseprintk((MYIOC_s_INFO_FMT "Routing Event to event handler #%d\n",
6578 r += (*(MptEvHandlers[ii]))(ioc, pEventReply);
6582 /* FIXME? Examine results here? */
6585 * If needed, send (a single) EventAck.
6587 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
6588 devtverboseprintk((MYIOC_s_WARN_FMT
6589 "EventAck required\n",ioc->name));
6590 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
6591 devtverboseprintk((MYIOC_s_WARN_FMT "SendEventAck returned %d\n",
6596 *evHandlers = handlers;
6600 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6602 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
6603 * @ioc: Pointer to MPT_ADAPTER structure
6604 * @log_info: U32 LogInfo reply word from the IOC
6606 * Refer to lsi/mpi_log_fc.h.
6609 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
6611 char *desc = "unknown";
6613 switch (log_info & 0xFF000000) {
6614 case MPI_IOCLOGINFO_FC_INIT_BASE:
6615 desc = "FCP Initiator";
6617 case MPI_IOCLOGINFO_FC_TARGET_BASE:
6618 desc = "FCP Target";
6620 case MPI_IOCLOGINFO_FC_LAN_BASE:
6623 case MPI_IOCLOGINFO_FC_MSG_BASE:
6624 desc = "MPI Message Layer";
6626 case MPI_IOCLOGINFO_FC_LINK_BASE:
6629 case MPI_IOCLOGINFO_FC_CTX_BASE:
6630 desc = "Context Manager";
6632 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
6633 desc = "Invalid Field Offset";
6635 case MPI_IOCLOGINFO_FC_STATE_CHANGE:
6636 desc = "State Change Info";
6640 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
6641 ioc->name, log_info, desc, (log_info & 0xFFFFFF));
6644 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6646 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
6647 * @ioc: Pointer to MPT_ADAPTER structure
6648 * @mr: Pointer to MPT reply frame
6649 * @log_info: U32 LogInfo word from the IOC
6651 * Refer to lsi/sp_log.h.
6654 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
6656 u32 info = log_info & 0x00FF0000;
6657 char *desc = "unknown";
6661 desc = "bug! MID not found";
6662 if (ioc->reload_fw == 0)
6667 desc = "Parity Error";
6671 desc = "ASYNC Outbound Overrun";
6675 desc = "SYNC Offset Error";
6683 desc = "Msg In Overflow";
6691 desc = "Outbound DMA Overrun";
6695 desc = "Task Management";
6699 desc = "Device Problem";
6703 desc = "Invalid Phase Change";
6707 desc = "Untagged Table Size";
6712 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
6715 /* strings for sas loginfo */
6716 static char *originator_str[] = {
6721 static char *iop_code_str[] = {
6723 "Invalid SAS Address", /* 01h */
6725 "Invalid Page", /* 03h */
6726 "Diag Message Error", /* 04h */
6727 "Task Terminated", /* 05h */
6728 "Enclosure Management", /* 06h */
6729 "Target Mode" /* 07h */
6731 static char *pl_code_str[] = {
6733 "Open Failure", /* 01h */
6734 "Invalid Scatter Gather List", /* 02h */
6735 "Wrong Relative Offset or Frame Length", /* 03h */
6736 "Frame Transfer Error", /* 04h */
6737 "Transmit Frame Connected Low", /* 05h */
6738 "SATA Non-NCQ RW Error Bit Set", /* 06h */
6739 "SATA Read Log Receive Data Error", /* 07h */
6740 "SATA NCQ Fail All Commands After Error", /* 08h */
6741 "SATA Error in Receive Set Device Bit FIS", /* 09h */
6742 "Receive Frame Invalid Message", /* 0Ah */
6743 "Receive Context Message Valid Error", /* 0Bh */
6744 "Receive Frame Current Frame Error", /* 0Ch */
6745 "SATA Link Down", /* 0Dh */
6746 "Discovery SATA Init W IOS", /* 0Eh */
6747 "Config Invalid Page", /* 0Fh */
6748 "Discovery SATA Init Timeout", /* 10h */
6751 "IO Not Yet Executed", /* 13h */
6752 "IO Executed", /* 14h */
6753 "Persistent Reservation Out Not Affiliation "
6755 "Open Transmit DMA Abort", /* 16h */
6756 "IO Device Missing Delay Retry", /* 17h */
6757 "IO Cancelled Due to Recieve Error", /* 18h */
6765 "Enclosure Management" /* 20h */
6767 static char *ir_code_str[] = {
6768 "Raid Action Error", /* 00h */
6778 static char *raid_sub_code_str[] = {
6780 "Volume Creation Failed: Data Passed too "
6782 "Volume Creation Failed: Duplicate Volumes "
6783 "Attempted", /* 02h */
6784 "Volume Creation Failed: Max Number "
6785 "Supported Volumes Exceeded", /* 03h */
6786 "Volume Creation Failed: DMA Error", /* 04h */
6787 "Volume Creation Failed: Invalid Volume Type", /* 05h */
6788 "Volume Creation Failed: Error Reading "
6789 "MFG Page 4", /* 06h */
6790 "Volume Creation Failed: Creating Internal "
6791 "Structures", /* 07h */
6800 "Activation failed: Already Active Volume", /* 10h */
6801 "Activation failed: Unsupported Volume Type", /* 11h */
6802 "Activation failed: Too Many Active Volumes", /* 12h */
6803 "Activation failed: Volume ID in Use", /* 13h */
6804 "Activation failed: Reported Failure", /* 14h */
6805 "Activation failed: Importing a Volume", /* 15h */
6816 "Phys Disk failed: Too Many Phys Disks", /* 20h */
6817 "Phys Disk failed: Data Passed too Large", /* 21h */
6818 "Phys Disk failed: DMA Error", /* 22h */
6819 "Phys Disk failed: Invalid <channel:id>", /* 23h */
6820 "Phys Disk failed: Creating Phys Disk Config "
6833 "Compatibility Error: IR Disabled", /* 30h */
6834 "Compatibility Error: Inquiry Comand Failed", /* 31h */
6835 "Compatibility Error: Device not Direct Access "
6836 "Device ", /* 32h */
6837 "Compatibility Error: Removable Device Found", /* 33h */
6838 "Compatibility Error: Device SCSI Version not "
6839 "2 or Higher", /* 34h */
6840 "Compatibility Error: SATA Device, 48 BIT LBA "
6841 "not Supported", /* 35h */
6842 "Compatibility Error: Device doesn't have "
6843 "512 Byte Block Sizes", /* 36h */
6844 "Compatibility Error: Volume Type Check Failed", /* 37h */
6845 "Compatibility Error: Volume Type is "
6846 "Unsupported by FW", /* 38h */
6847 "Compatibility Error: Disk Drive too Small for "
6848 "use in Volume", /* 39h */
6849 "Compatibility Error: Phys Disk for Create "
6850 "Volume not Found", /* 3Ah */
6851 "Compatibility Error: Too Many or too Few "
6852 "Disks for Volume Type", /* 3Bh */
6853 "Compatibility Error: Disk stripe Sizes "
6854 "Must be 64KB", /* 3Ch */
6855 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
6858 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6860 * mpt_sas_log_info - Log information returned from SAS IOC.
6861 * @ioc: Pointer to MPT_ADAPTER structure
6862 * @log_info: U32 LogInfo reply word from the IOC
6864 * Refer to lsi/mpi_log_sas.h.
6867 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
6869 union loginfo_type {
6878 union loginfo_type sas_loginfo;
6879 char *originator_desc = NULL;
6880 char *code_desc = NULL;
6881 char *sub_code_desc = NULL;
6883 sas_loginfo.loginfo = log_info;
6884 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
6885 (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
6888 originator_desc = originator_str[sas_loginfo.dw.originator];
6890 switch (sas_loginfo.dw.originator) {
6893 if (sas_loginfo.dw.code <
6894 sizeof(iop_code_str)/sizeof(char*))
6895 code_desc = iop_code_str[sas_loginfo.dw.code];
6898 if (sas_loginfo.dw.code <
6899 sizeof(pl_code_str)/sizeof(char*))
6900 code_desc = pl_code_str[sas_loginfo.dw.code];
6903 if (sas_loginfo.dw.code >=
6904 sizeof(ir_code_str)/sizeof(char*))
6906 code_desc = ir_code_str[sas_loginfo.dw.code];
6907 if (sas_loginfo.dw.subcode >=
6908 sizeof(raid_sub_code_str)/sizeof(char*))
6910 if (sas_loginfo.dw.code == 0)
6912 raid_sub_code_str[sas_loginfo.dw.subcode];
6918 if (sub_code_desc != NULL)
6919 printk(MYIOC_s_INFO_FMT
6920 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
6922 ioc->name, log_info, originator_desc, code_desc,
6924 else if (code_desc != NULL)
6925 printk(MYIOC_s_INFO_FMT
6926 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
6927 " SubCode(0x%04x)\n",
6928 ioc->name, log_info, originator_desc, code_desc,
6929 sas_loginfo.dw.subcode);
6931 printk(MYIOC_s_INFO_FMT
6932 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
6933 " SubCode(0x%04x)\n",
6934 ioc->name, log_info, originator_desc,
6935 sas_loginfo.dw.code, sas_loginfo.dw.subcode);
6938 #ifdef MPT_DEBUG_REPLY
6939 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6941 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
6942 * @ioc: Pointer to MPT_ADAPTER structure
6943 * @ioc_status: U32 IOCStatus word from IOC
6944 * @mf: Pointer to MPT request frame
6946 * Refer to lsi/mpi.h.
6949 mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
6951 Config_t *pReq = (Config_t *)mf;
6952 char extend_desc[EVENT_DESCR_STR_SZ];
6957 if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
6958 page_type = pReq->ExtPageType;
6960 page_type = pReq->Header.PageType;
6963 * ignore invalid page messages for GET_NEXT_HANDLE
6965 form = le32_to_cpu(pReq->PageAddress);
6966 if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
6967 if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
6968 page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
6969 page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
6970 if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
6971 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
6974 if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
6975 if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
6976 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
6980 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
6981 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
6982 page_type, pReq->Header.PageNumber, pReq->Action, form);
6984 switch (ioc_status) {
6986 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
6987 desc = "Config Page Invalid Action";
6990 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
6991 desc = "Config Page Invalid Type";
6994 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
6995 desc = "Config Page Invalid Page";
6998 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
6999 desc = "Config Page Invalid Data";
7002 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7003 desc = "Config Page No Defaults";
7006 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7007 desc = "Config Page Can't Commit";
7014 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s: %s\n",
7015 ioc->name, ioc_status, desc, extend_desc);
7019 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
7020 * @ioc: Pointer to MPT_ADAPTER structure
7021 * @ioc_status: U32 IOCStatus word from IOC
7022 * @mf: Pointer to MPT request frame
7024 * Refer to lsi/mpi.h.
7027 mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7029 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
7034 /****************************************************************************/
7035 /* Common IOCStatus values for all replies */
7036 /****************************************************************************/
7038 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
7039 desc = "Invalid Function";
7042 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
7046 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
7047 desc = "Invalid SGL";
7050 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
7051 desc = "Internal Error";
7054 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
7058 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
7059 desc = "Insufficient Resources";
7062 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
7063 desc = "Invalid Field";
7066 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
7067 desc = "Invalid State";
7070 /****************************************************************************/
7071 /* Config IOCStatus values */
7072 /****************************************************************************/
7074 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7075 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7076 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7077 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7078 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7079 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7080 mpt_iocstatus_info_config(ioc, status, mf);
7083 /****************************************************************************/
7084 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
7086 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
7088 /****************************************************************************/
7090 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
7091 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
7092 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
7093 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
7094 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
7095 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
7096 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
7097 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
7098 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
7099 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
7100 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
7101 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
7102 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
7105 /****************************************************************************/
7106 /* SCSI Target values */
7107 /****************************************************************************/
7109 case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
7110 desc = "Target: Priority IO";
7113 case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
7114 desc = "Target: Invalid Port";
7117 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
7118 desc = "Target Invalid IO Index:";
7121 case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
7122 desc = "Target: Aborted";
7125 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
7126 desc = "Target: No Conn Retryable";
7129 case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
7130 desc = "Target: No Connection";
7133 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
7134 desc = "Target: Transfer Count Mismatch";
7137 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
7138 desc = "Target: STS Data not Sent";
7141 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
7142 desc = "Target: Data Offset Error";
7145 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
7146 desc = "Target: Too Much Write Data";
7149 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
7150 desc = "Target: IU Too Short";
7153 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
7154 desc = "Target: ACK NAK Timeout";
7157 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
7158 desc = "Target: Nak Received";
7161 /****************************************************************************/
7162 /* Fibre Channel Direct Access values */
7163 /****************************************************************************/
7165 case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
7166 desc = "FC: Aborted";
7169 case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
7170 desc = "FC: RX ID Invalid";
7173 case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
7174 desc = "FC: DID Invalid";
7177 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
7178 desc = "FC: Node Logged Out";
7181 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
7182 desc = "FC: Exchange Canceled";
7185 /****************************************************************************/
7187 /****************************************************************************/
7189 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
7190 desc = "LAN: Device not Found";
7193 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
7194 desc = "LAN: Device Failure";
7197 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
7198 desc = "LAN: Transmit Error";
7201 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
7202 desc = "LAN: Transmit Aborted";
7205 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
7206 desc = "LAN: Receive Error";
7209 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
7210 desc = "LAN: Receive Aborted";
7213 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
7214 desc = "LAN: Partial Packet";
7217 case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
7218 desc = "LAN: Canceled";
7221 /****************************************************************************/
7222 /* Serial Attached SCSI values */
7223 /****************************************************************************/
7225 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
7226 desc = "SAS: SMP Request Failed";
7229 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
7230 desc = "SAS: SMP Data Overrun";
7241 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s\n", ioc->name, status, desc);
7245 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7246 EXPORT_SYMBOL(mpt_attach);
7247 EXPORT_SYMBOL(mpt_detach);
7249 EXPORT_SYMBOL(mpt_resume);
7250 EXPORT_SYMBOL(mpt_suspend);
7252 EXPORT_SYMBOL(ioc_list);
7253 EXPORT_SYMBOL(mpt_proc_root_dir);
7254 EXPORT_SYMBOL(mpt_register);
7255 EXPORT_SYMBOL(mpt_deregister);
7256 EXPORT_SYMBOL(mpt_event_register);
7257 EXPORT_SYMBOL(mpt_event_deregister);
7258 EXPORT_SYMBOL(mpt_reset_register);
7259 EXPORT_SYMBOL(mpt_reset_deregister);
7260 EXPORT_SYMBOL(mpt_device_driver_register);
7261 EXPORT_SYMBOL(mpt_device_driver_deregister);
7262 EXPORT_SYMBOL(mpt_get_msg_frame);
7263 EXPORT_SYMBOL(mpt_put_msg_frame);
7264 EXPORT_SYMBOL(mpt_free_msg_frame);
7265 EXPORT_SYMBOL(mpt_add_sge);
7266 EXPORT_SYMBOL(mpt_send_handshake_request);
7267 EXPORT_SYMBOL(mpt_verify_adapter);
7268 EXPORT_SYMBOL(mpt_GetIocState);
7269 EXPORT_SYMBOL(mpt_print_ioc_summary);
7270 EXPORT_SYMBOL(mpt_lan_index);
7271 EXPORT_SYMBOL(mpt_stm_index);
7272 EXPORT_SYMBOL(mpt_HardResetHandler);
7273 EXPORT_SYMBOL(mpt_config);
7274 EXPORT_SYMBOL(mpt_findImVolumes);
7275 EXPORT_SYMBOL(mpt_alloc_fw_memory);
7276 EXPORT_SYMBOL(mpt_free_fw_memory);
7277 EXPORT_SYMBOL(mptbase_sas_persist_operation);
7278 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
7280 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7282 * fusion_init - Fusion MPT base driver initialization routine.
7284 * Returns 0 for success, non-zero for failure.
7291 show_mptmod_ver(my_NAME, my_VERSION);
7292 printk(KERN_INFO COPYRIGHT "\n");
7294 for (i = 0; i < MPT_MAX_PROTOCOL_DRIVERS; i++) {
7295 MptCallbacks[i] = NULL;
7296 MptDriverClass[i] = MPTUNKNOWN_DRIVER;
7297 MptEvHandlers[i] = NULL;
7298 MptResetHandlers[i] = NULL;
7301 /* Register ourselves (mptbase) in order to facilitate
7302 * EventNotification handling.
7304 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
7306 /* Register for hard reset handling callbacks.
7308 if (mpt_reset_register(mpt_base_index, mpt_ioc_reset) == 0) {
7309 dprintk((KERN_INFO MYNAM ": Register for IOC reset notification\n"));
7314 #ifdef CONFIG_PROC_FS
7315 (void) procmpt_create();
7320 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7322 * fusion_exit - Perform driver unload cleanup.
7324 * This routine frees all resources associated with each MPT adapter
7325 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
7331 dexitprintk((KERN_INFO MYNAM ": fusion_exit() called!\n"));
7333 mpt_reset_deregister(mpt_base_index);
7335 #ifdef CONFIG_PROC_FS
7340 module_init(fusion_init);
7341 module_exit(fusion_exit);