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)");
90 static int mpt_debug_level;
91 static int mpt_set_debug_level(const char *val, struct kernel_param *kp);
92 module_param_call(mpt_debug_level, mpt_set_debug_level, param_get_int,
93 &mpt_debug_level, 0600);
94 MODULE_PARM_DESC(mpt_debug_level, " debug level - refer to mptdebug.h - (default=0)");
97 static int mfcounter = 0;
98 #define PRINT_MF_COUNT 20000
101 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
105 int mpt_lan_index = -1;
106 int mpt_stm_index = -1;
108 struct proc_dir_entry *mpt_proc_root_dir;
110 #define WHOINIT_UNKNOWN 0xAA
112 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
116 /* Adapter link list */
118 /* Callback lookup table */
119 static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
120 /* Protocol driver class lookup table */
121 static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
122 /* Event handler lookup table */
123 static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
124 /* Reset handler lookup table */
125 static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
126 static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
128 static int mpt_base_index = -1;
129 static int last_drv_idx = -1;
131 static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq);
133 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
137 static irqreturn_t mpt_interrupt(int irq, void *bus_id);
138 static int mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
139 static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
140 u32 *req, int replyBytes, u16 *u16reply, int maxwait,
142 static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
143 static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
144 static void mpt_adapter_disable(MPT_ADAPTER *ioc);
145 static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
147 static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
148 static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
149 static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
150 static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
151 static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
152 static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
153 static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
154 static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
155 static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
156 static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
157 static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
158 static int PrimeIocFifos(MPT_ADAPTER *ioc);
159 static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
160 static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
161 static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
162 static int GetLanConfigPages(MPT_ADAPTER *ioc);
163 static int GetIoUnitPage2(MPT_ADAPTER *ioc);
164 int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
165 static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
166 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
167 static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
168 static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
169 static void mpt_timer_expired(unsigned long data);
170 static void mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc);
171 static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
172 static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
173 static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
174 static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
176 #ifdef CONFIG_PROC_FS
177 static int procmpt_summary_read(char *buf, char **start, off_t offset,
178 int request, int *eof, void *data);
179 static int procmpt_version_read(char *buf, char **start, off_t offset,
180 int request, int *eof, void *data);
181 static int procmpt_iocinfo_read(char *buf, char **start, off_t offset,
182 int request, int *eof, void *data);
184 static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
186 //int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
187 static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers);
188 static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
189 static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
190 static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
191 static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
192 static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
193 static void mpt_inactive_raid_list_free(MPT_ADAPTER *ioc);
195 /* module entry point */
196 static int __init fusion_init (void);
197 static void __exit fusion_exit (void);
199 #define CHIPREG_READ32(addr) readl_relaxed(addr)
200 #define CHIPREG_READ32_dmasync(addr) readl(addr)
201 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
202 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
203 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
206 pci_disable_io_access(struct pci_dev *pdev)
210 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
212 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
216 pci_enable_io_access(struct pci_dev *pdev)
220 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
222 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
225 static int mpt_set_debug_level(const char *val, struct kernel_param *kp)
227 int ret = param_set_int(val, kp);
233 list_for_each_entry(ioc, &ioc_list, list)
234 ioc->debug_level = mpt_debug_level;
239 * Process turbo (context) reply...
242 mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
244 MPT_FRAME_HDR *mf = NULL;
245 MPT_FRAME_HDR *mr = NULL;
249 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got TURBO reply req_idx=%08x\n",
252 switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
253 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
254 req_idx = pa & 0x0000FFFF;
255 cb_idx = (pa & 0x00FF0000) >> 16;
256 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
258 case MPI_CONTEXT_REPLY_TYPE_LAN:
259 cb_idx = mpt_lan_index;
261 * Blind set of mf to NULL here was fatal
262 * after lan_reply says "freeme"
263 * Fix sort of combined with an optimization here;
264 * added explicit check for case where lan_reply
265 * was just returning 1 and doing nothing else.
266 * For this case skip the callback, but set up
267 * proper mf value first here:-)
269 if ((pa & 0x58000000) == 0x58000000) {
270 req_idx = pa & 0x0000FFFF;
271 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
272 mpt_free_msg_frame(ioc, mf);
277 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
279 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
280 cb_idx = mpt_stm_index;
281 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
288 /* Check for (valid) IO callback! */
289 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
290 MptCallbacks[cb_idx] == NULL) {
291 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
292 __FUNCTION__, ioc->name, cb_idx);
296 if (MptCallbacks[cb_idx](ioc, mf, mr))
297 mpt_free_msg_frame(ioc, mf);
303 mpt_reply(MPT_ADAPTER *ioc, u32 pa)
314 /* non-TURBO reply! Hmmm, something may be up...
315 * Newest turbo reply mechanism; get address
316 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
319 /* Map DMA address of reply header to cpu address.
320 * pa is 32 bits - but the dma address may be 32 or 64 bits
321 * get offset based only only the low addresses
324 reply_dma_low = (pa <<= 1);
325 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
326 (reply_dma_low - ioc->reply_frames_low_dma));
328 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
329 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
330 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
332 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
333 ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
334 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mr)
336 /* Check/log IOC log info
338 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
339 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
340 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
341 if (ioc->bus_type == FC)
342 mpt_fc_log_info(ioc, log_info);
343 else if (ioc->bus_type == SPI)
344 mpt_spi_log_info(ioc, log_info);
345 else if (ioc->bus_type == SAS)
346 mpt_sas_log_info(ioc, log_info);
349 if (ioc_stat & MPI_IOCSTATUS_MASK)
350 mpt_iocstatus_info(ioc, (u32)ioc_stat, mf);
352 /* Check for (valid) IO callback! */
353 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
354 MptCallbacks[cb_idx] == NULL) {
355 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
356 __FUNCTION__, ioc->name, cb_idx);
361 freeme = MptCallbacks[cb_idx](ioc, mf, mr);
364 /* Flush (non-TURBO) reply with a WRITE! */
365 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
368 mpt_free_msg_frame(ioc, mf);
372 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
374 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
375 * @irq: irq number (not used)
376 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
378 * This routine is registered via the request_irq() kernel API call,
379 * and handles all interrupts generated from a specific MPT adapter
380 * (also referred to as a IO Controller or IOC).
381 * This routine must clear the interrupt from the adapter and does
382 * so by reading the reply FIFO. Multiple replies may be processed
383 * per single call to this routine.
385 * This routine handles register-level access of the adapter but
386 * dispatches (calls) a protocol-specific callback routine to handle
387 * the protocol-specific details of the MPT request completion.
390 mpt_interrupt(int irq, void *bus_id)
392 MPT_ADAPTER *ioc = bus_id;
393 u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
395 if (pa == 0xFFFFFFFF)
399 * Drain the reply FIFO!
402 if (pa & MPI_ADDRESS_REPLY_A_BIT)
405 mpt_turbo_reply(ioc, pa);
406 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
407 } while (pa != 0xFFFFFFFF);
412 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
414 * mpt_base_reply - MPT base driver's callback routine
415 * @ioc: Pointer to MPT_ADAPTER structure
416 * @mf: Pointer to original MPT request frame
417 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
419 * MPT base driver's callback routine; all base driver
420 * "internal" request/reply processing is routed here.
421 * Currently used for EventNotification and EventAck handling.
423 * Returns 1 indicating original alloc'd request frame ptr
424 * should be freed, or 0 if it shouldn't.
427 mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
432 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply() called\n", ioc->name));
433 #ifdef CONFIG_FUSION_LOGGING
434 if ((ioc->debug_level & MPT_DEBUG_MSG_FRAME) &&
435 !(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) {
436 dmfprintk(ioc, printk(KERN_INFO MYNAM ": Original request frame (@%p) header\n", mf));
437 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)mf)
441 func = reply->u.hdr.Function;
442 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply, Function=%02Xh\n",
445 if (func == MPI_FUNCTION_EVENT_NOTIFICATION) {
446 EventNotificationReply_t *pEvReply = (EventNotificationReply_t *) reply;
450 results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
451 if (results != evHandlers) {
452 /* CHECKME! Any special handling needed here? */
453 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
454 ioc->name, evHandlers, results));
458 * Hmmm... It seems that EventNotificationReply is an exception
459 * to the rule of one reply per request.
461 if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) {
464 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
465 ioc->name, pEvReply));
468 #ifdef CONFIG_PROC_FS
469 // LogEvent(ioc, pEvReply);
472 } else if (func == MPI_FUNCTION_EVENT_ACK) {
473 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply, EventAck reply received\n",
475 } else if (func == MPI_FUNCTION_CONFIG) {
479 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "config_complete (mf=%p,mr=%p)\n",
480 ioc->name, mf, reply));
482 pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *)));
485 /* disable timer and remove from linked list */
486 del_timer(&pCfg->timer);
488 spin_lock_irqsave(&ioc->FreeQlock, flags);
489 list_del(&pCfg->linkage);
490 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
493 * If IOC Status is SUCCESS, save the header
494 * and set the status code to GOOD.
496 pCfg->status = MPT_CONFIG_ERROR;
498 ConfigReply_t *pReply = (ConfigReply_t *)reply;
501 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
502 dcprintk(ioc, printk(KERN_NOTICE " IOCStatus=%04xh, IOCLogInfo=%08xh\n",
503 status, le32_to_cpu(pReply->IOCLogInfo)));
505 pCfg->status = status;
506 if (status == MPI_IOCSTATUS_SUCCESS) {
507 if ((pReply->Header.PageType &
508 MPI_CONFIG_PAGETYPE_MASK) ==
509 MPI_CONFIG_PAGETYPE_EXTENDED) {
510 pCfg->cfghdr.ehdr->ExtPageLength =
511 le16_to_cpu(pReply->ExtPageLength);
512 pCfg->cfghdr.ehdr->ExtPageType =
515 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
517 /* If this is a regular header, save PageLength. */
518 /* LMP Do this better so not using a reserved field! */
519 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
520 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
521 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
526 * Wake up the original calling thread
531 } else if (func == MPI_FUNCTION_SAS_IO_UNIT_CONTROL) {
532 /* we should be always getting a reply frame */
533 memcpy(ioc->persist_reply_frame, reply,
534 min(MPT_DEFAULT_FRAME_SIZE,
535 4*reply->u.reply.MsgLength));
536 del_timer(&ioc->persist_timer);
537 ioc->persist_wait_done = 1;
540 printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
545 * Conditionally tell caller to free the original
546 * EventNotification/EventAck/unexpected request frame!
551 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
553 * mpt_register - Register protocol-specific main callback handler.
554 * @cbfunc: callback function pointer
555 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
557 * This routine is called by a protocol-specific driver (SCSI host,
558 * LAN, SCSI target) to register its reply callback routine. Each
559 * protocol-specific driver must do this before it will be able to
560 * use any IOC resources, such as obtaining request frames.
562 * NOTES: The SCSI protocol driver currently calls this routine thrice
563 * in order to register separate callbacks; one for "normal" SCSI IO;
564 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
566 * Returns a positive integer valued "handle" in the
567 * range (and S.O.D. order) {N,...,7,6,5,...,1} if successful.
568 * Any non-positive return value (including zero!) should be considered
569 * an error by the caller.
572 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
579 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
580 * (slot/handle 0 is reserved!)
582 for (i = MPT_MAX_PROTOCOL_DRIVERS-1; i; i--) {
583 if (MptCallbacks[i] == NULL) {
584 MptCallbacks[i] = cbfunc;
585 MptDriverClass[i] = dclass;
586 MptEvHandlers[i] = NULL;
595 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
597 * mpt_deregister - Deregister a protocol drivers resources.
598 * @cb_idx: previously registered callback handle
600 * Each protocol-specific driver should call this routine when its
601 * module is unloaded.
604 mpt_deregister(int cb_idx)
606 if ((cb_idx >= 0) && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
607 MptCallbacks[cb_idx] = NULL;
608 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
609 MptEvHandlers[cb_idx] = NULL;
615 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
617 * mpt_event_register - Register protocol-specific event callback
619 * @cb_idx: previously registered (via mpt_register) callback handle
620 * @ev_cbfunc: callback function
622 * This routine can be called by one or more protocol-specific drivers
623 * if/when they choose to be notified of MPT events.
625 * Returns 0 for success.
628 mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc)
630 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
633 MptEvHandlers[cb_idx] = ev_cbfunc;
637 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
639 * mpt_event_deregister - Deregister protocol-specific event callback
641 * @cb_idx: previously registered callback handle
643 * Each protocol-specific driver should call this routine
644 * when it does not (or can no longer) handle events,
645 * or when its module is unloaded.
648 mpt_event_deregister(int cb_idx)
650 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
653 MptEvHandlers[cb_idx] = NULL;
656 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
658 * mpt_reset_register - Register protocol-specific IOC reset handler.
659 * @cb_idx: previously registered (via mpt_register) callback handle
660 * @reset_func: reset function
662 * This routine can be called by one or more protocol-specific drivers
663 * if/when they choose to be notified of IOC resets.
665 * Returns 0 for success.
668 mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func)
670 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
673 MptResetHandlers[cb_idx] = reset_func;
677 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
679 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
680 * @cb_idx: previously registered callback handle
682 * Each protocol-specific driver should call this routine
683 * when it does not (or can no longer) handle IOC reset handling,
684 * or when its module is unloaded.
687 mpt_reset_deregister(int cb_idx)
689 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
692 MptResetHandlers[cb_idx] = NULL;
695 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
697 * mpt_device_driver_register - Register device driver hooks
698 * @dd_cbfunc: driver callbacks struct
699 * @cb_idx: MPT protocol driver index
702 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx)
705 const struct pci_device_id *id;
707 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
710 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
712 /* call per pci device probe entry point */
713 list_for_each_entry(ioc, &ioc_list, list) {
714 id = ioc->pcidev->driver ?
715 ioc->pcidev->driver->id_table : NULL;
716 if (dd_cbfunc->probe)
717 dd_cbfunc->probe(ioc->pcidev, id);
723 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
725 * mpt_device_driver_deregister - DeRegister device driver hooks
726 * @cb_idx: MPT protocol driver index
729 mpt_device_driver_deregister(int cb_idx)
731 struct mpt_pci_driver *dd_cbfunc;
734 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
737 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
739 list_for_each_entry(ioc, &ioc_list, list) {
740 if (dd_cbfunc->remove)
741 dd_cbfunc->remove(ioc->pcidev);
744 MptDeviceDriverHandlers[cb_idx] = NULL;
748 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
750 * mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024)
751 * allocated per MPT adapter.
752 * @handle: Handle of registered MPT protocol driver
753 * @ioc: Pointer to MPT adapter structure
755 * Returns pointer to a MPT request frame or %NULL if none are available
756 * or IOC is not active.
759 mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc)
763 u16 req_idx; /* Request index */
765 /* validate handle and ioc identifier */
769 printk(KERN_WARNING "IOC Not Active! mpt_get_msg_frame returning NULL!\n");
772 /* If interrupts are not attached, do not return a request frame */
776 spin_lock_irqsave(&ioc->FreeQlock, flags);
777 if (!list_empty(&ioc->FreeQ)) {
780 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
781 u.frame.linkage.list);
782 list_del(&mf->u.frame.linkage.list);
783 mf->u.frame.linkage.arg1 = 0;
784 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
785 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
787 req_idx = req_offset / ioc->req_sz;
788 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
789 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
790 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame; /* Default, will be changed if necessary in SG generation */
797 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
801 printk(KERN_WARNING "IOC Active. No free Msg Frames! Count 0x%x Max 0x%x\n", ioc->mfcnt, ioc->req_depth);
803 if (mfcounter == PRINT_MF_COUNT)
804 printk(KERN_INFO "MF Count 0x%x Max 0x%x \n", ioc->mfcnt, ioc->req_depth);
807 dmfprintk(ioc, printk(KERN_INFO MYNAM ": %s: mpt_get_msg_frame(%d,%d), got mf=%p\n",
808 ioc->name, handle, ioc->id, mf));
812 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
814 * mpt_put_msg_frame - Send a protocol specific MPT request frame
816 * @handle: Handle of registered MPT protocol driver
817 * @ioc: Pointer to MPT adapter structure
818 * @mf: Pointer to MPT request frame
820 * This routine posts a MPT request frame to the request post FIFO of a
821 * specific MPT adapter.
824 mpt_put_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
828 u16 req_idx; /* Request index */
830 /* ensure values are reset properly! */
831 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
832 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
834 req_idx = req_offset / ioc->req_sz;
835 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
836 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
838 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
840 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
841 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx, ioc->RequestNB[req_idx]));
842 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
845 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
847 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
848 * @handle: Handle of registered MPT protocol driver
849 * @ioc: Pointer to MPT adapter structure
850 * @mf: Pointer to MPT request frame
852 * This routine places a MPT request frame back on the MPT adapter's
856 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
860 /* Put Request back on FreeQ! */
861 spin_lock_irqsave(&ioc->FreeQlock, flags);
862 mf->u.frame.linkage.arg1 = 0xdeadbeaf; /* signature to know if this mf is freed */
863 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
867 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
870 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
872 * mpt_add_sge - Place a simple SGE at address pAddr.
873 * @pAddr: virtual address for SGE
874 * @flagslength: SGE flags and data transfer length
875 * @dma_addr: Physical address
877 * This routine places a MPT request frame back on the MPT adapter's
881 mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
883 if (sizeof(dma_addr_t) == sizeof(u64)) {
884 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
885 u32 tmp = dma_addr & 0xFFFFFFFF;
887 pSge->FlagsLength = cpu_to_le32(flagslength);
888 pSge->Address.Low = cpu_to_le32(tmp);
889 tmp = (u32) ((u64)dma_addr >> 32);
890 pSge->Address.High = cpu_to_le32(tmp);
893 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
894 pSge->FlagsLength = cpu_to_le32(flagslength);
895 pSge->Address = cpu_to_le32(dma_addr);
899 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
901 * mpt_send_handshake_request - Send MPT request via doorbell handshake method.
902 * @handle: Handle of registered MPT protocol driver
903 * @ioc: Pointer to MPT adapter structure
904 * @reqBytes: Size of the request in bytes
905 * @req: Pointer to MPT request frame
906 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
908 * This routine is used exclusively to send MptScsiTaskMgmt
909 * requests since they are required to be sent via doorbell handshake.
911 * NOTE: It is the callers responsibility to byte-swap fields in the
912 * request which are greater than 1 byte in size.
914 * Returns 0 for success, non-zero for failure.
917 mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
923 /* State is known to be good upon entering
924 * this function so issue the bus reset
929 * Emulate what mpt_put_msg_frame() does /wrt to sanity
930 * setting cb_idx/req_idx. But ONLY if this request
931 * is in proper (pre-alloc'd) request buffer range...
933 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
934 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
935 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
936 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
937 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;
940 /* Make sure there are no doorbells */
941 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
943 CHIPREG_WRITE32(&ioc->chip->Doorbell,
944 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
945 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
947 /* Wait for IOC doorbell int */
948 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
952 /* Read doorbell and check for active bit */
953 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
956 dhsprintk(ioc, printk(KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
959 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
961 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
965 /* Send request via doorbell handshake */
966 req_as_bytes = (u8 *) req;
967 for (ii = 0; ii < reqBytes/4; ii++) {
970 word = ((req_as_bytes[(ii*4) + 0] << 0) |
971 (req_as_bytes[(ii*4) + 1] << 8) |
972 (req_as_bytes[(ii*4) + 2] << 16) |
973 (req_as_bytes[(ii*4) + 3] << 24));
974 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
975 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
981 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
986 /* Make sure there are no doorbells */
987 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
992 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
994 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
995 * @ioc: Pointer to MPT adapter structure
996 * @access_control_value: define bits below
997 * @sleepFlag: Specifies whether the process can sleep
999 * Provides mechanism for the host driver to control the IOC's
1000 * Host Page Buffer access.
1002 * Access Control Value - bits[15:12]
1004 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1005 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1006 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1008 * Returns 0 for success, non-zero for failure.
1012 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1016 /* return if in use */
1017 if (CHIPREG_READ32(&ioc->chip->Doorbell)
1018 & MPI_DOORBELL_ACTIVE)
1021 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1023 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1024 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1025 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1026 (access_control_value<<12)));
1028 /* Wait for IOC to clear Doorbell Status bit */
1029 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1035 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1037 * mpt_host_page_alloc - allocate system memory for the fw
1038 * @ioc: Pointer to pointer to IOC adapter
1039 * @ioc_init: Pointer to ioc init config page
1041 * If we already allocated memory in past, then resend the same pointer.
1042 * Returns 0 for success, non-zero for failure.
1045 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1049 u32 host_page_buffer_sz=0;
1051 if(!ioc->HostPageBuffer) {
1053 host_page_buffer_sz =
1054 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1056 if(!host_page_buffer_sz)
1057 return 0; /* fw doesn't need any host buffers */
1059 /* spin till we get enough memory */
1060 while(host_page_buffer_sz > 0) {
1062 if((ioc->HostPageBuffer = pci_alloc_consistent(
1064 host_page_buffer_sz,
1065 &ioc->HostPageBuffer_dma)) != NULL) {
1067 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1068 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1069 ioc->name, ioc->HostPageBuffer,
1070 (u32)ioc->HostPageBuffer_dma,
1071 host_page_buffer_sz));
1072 ioc->alloc_total += host_page_buffer_sz;
1073 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1077 host_page_buffer_sz -= (4*1024);
1081 if(!ioc->HostPageBuffer) {
1082 printk(MYIOC_s_ERR_FMT
1083 "Failed to alloc memory for host_page_buffer!\n",
1088 psge = (char *)&ioc_init->HostPageBufferSGE;
1089 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1090 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1091 MPI_SGE_FLAGS_32_BIT_ADDRESSING |
1092 MPI_SGE_FLAGS_HOST_TO_IOC |
1093 MPI_SGE_FLAGS_END_OF_BUFFER;
1094 if (sizeof(dma_addr_t) == sizeof(u64)) {
1095 flags_length |= MPI_SGE_FLAGS_64_BIT_ADDRESSING;
1097 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1098 flags_length |= ioc->HostPageBuffer_sz;
1099 mpt_add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1100 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1105 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1107 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1108 * @iocid: IOC unique identifier (integer)
1109 * @iocpp: Pointer to pointer to IOC adapter
1111 * Given a unique IOC identifier, set pointer to the associated MPT
1112 * adapter structure.
1114 * Returns iocid and sets iocpp if iocid is found.
1115 * Returns -1 if iocid is not found.
1118 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1122 list_for_each_entry(ioc,&ioc_list,list) {
1123 if (ioc->id == iocid) {
1134 * mpt_get_product_name - returns product string
1135 * @vendor: pci vendor id
1136 * @device: pci device id
1137 * @revision: pci revision id
1138 * @prod_name: string returned
1140 * Returns product string displayed when driver loads,
1141 * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1145 mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name)
1147 char *product_str = NULL;
1149 if (vendor == PCI_VENDOR_ID_BROCADE) {
1152 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1156 product_str = "BRE040 A0";
1159 product_str = "BRE040 A1";
1162 product_str = "BRE040";
1172 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1173 product_str = "LSIFC909 B1";
1175 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1176 product_str = "LSIFC919 B0";
1178 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1179 product_str = "LSIFC929 B0";
1181 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1182 if (revision < 0x80)
1183 product_str = "LSIFC919X A0";
1185 product_str = "LSIFC919XL A1";
1187 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1188 if (revision < 0x80)
1189 product_str = "LSIFC929X A0";
1191 product_str = "LSIFC929XL A1";
1193 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1194 product_str = "LSIFC939X A1";
1196 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1197 product_str = "LSIFC949X A1";
1199 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1203 product_str = "LSIFC949E A0";
1206 product_str = "LSIFC949E A1";
1209 product_str = "LSIFC949E";
1213 case MPI_MANUFACTPAGE_DEVID_53C1030:
1217 product_str = "LSI53C1030 A0";
1220 product_str = "LSI53C1030 B0";
1223 product_str = "LSI53C1030 B1";
1226 product_str = "LSI53C1030 B2";
1229 product_str = "LSI53C1030 C0";
1232 product_str = "LSI53C1030T A0";
1235 product_str = "LSI53C1030T A2";
1238 product_str = "LSI53C1030T A3";
1241 product_str = "LSI53C1020A A1";
1244 product_str = "LSI53C1030";
1248 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1252 product_str = "LSI53C1035 A2";
1255 product_str = "LSI53C1035 B0";
1258 product_str = "LSI53C1035";
1262 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1266 product_str = "LSISAS1064 A1";
1269 product_str = "LSISAS1064 A2";
1272 product_str = "LSISAS1064 A3";
1275 product_str = "LSISAS1064 A4";
1278 product_str = "LSISAS1064";
1282 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1286 product_str = "LSISAS1064E A0";
1289 product_str = "LSISAS1064E B0";
1292 product_str = "LSISAS1064E B1";
1295 product_str = "LSISAS1064E B2";
1298 product_str = "LSISAS1064E B3";
1301 product_str = "LSISAS1064E";
1305 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1309 product_str = "LSISAS1068 A0";
1312 product_str = "LSISAS1068 B0";
1315 product_str = "LSISAS1068 B1";
1318 product_str = "LSISAS1068";
1322 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1326 product_str = "LSISAS1068E A0";
1329 product_str = "LSISAS1068E B0";
1332 product_str = "LSISAS1068E B1";
1335 product_str = "LSISAS1068E B2";
1338 product_str = "LSISAS1068E B3";
1341 product_str = "LSISAS1068E";
1345 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1349 product_str = "LSISAS1078 A0";
1352 product_str = "LSISAS1078 B0";
1355 product_str = "LSISAS1078 C0";
1358 product_str = "LSISAS1078 C1";
1361 product_str = "LSISAS1078 C2";
1364 product_str = "LSISAS1078";
1372 sprintf(prod_name, "%s", product_str);
1375 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1377 * mpt_attach - Install a PCI intelligent MPT adapter.
1378 * @pdev: Pointer to pci_dev structure
1379 * @id: PCI device ID information
1381 * This routine performs all the steps necessary to bring the IOC of
1382 * a MPT adapter to a OPERATIONAL state. This includes registering
1383 * memory regions, registering the interrupt, and allocating request
1384 * and reply memory pools.
1386 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1389 * Returns 0 for success, non-zero for failure.
1391 * TODO: Add support for polled controllers
1394 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1398 unsigned long mem_phys;
1406 static int mpt_ids = 0;
1407 #ifdef CONFIG_PROC_FS
1408 struct proc_dir_entry *dent, *ent;
1411 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1413 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1417 ioc->debug_level = mpt_debug_level;
1418 if (mpt_debug_level)
1419 printk(KERN_INFO MYNAM ": mpt_debug_level=%xh\n", mpt_debug_level);
1421 if (pci_enable_device(pdev))
1424 dinitprintk(ioc, printk(KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1426 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
1427 dprintk(ioc, printk(KERN_INFO MYNAM
1428 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n"));
1429 } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
1430 printk(KERN_WARNING MYNAM ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");
1434 if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
1435 dprintk(ioc, printk(KERN_INFO MYNAM
1436 ": Using 64 bit consistent mask\n"));
1438 dprintk(ioc, printk(KERN_INFO MYNAM
1439 ": Not using 64 bit consistent mask\n"));
1442 ioc->alloc_total = sizeof(MPT_ADAPTER);
1443 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1444 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1447 ioc->diagPending = 0;
1448 spin_lock_init(&ioc->diagLock);
1449 spin_lock_init(&ioc->initializing_hba_lock);
1451 /* Initialize the event logging.
1453 ioc->eventTypes = 0; /* None */
1454 ioc->eventContext = 0;
1455 ioc->eventLogSize = 0;
1462 ioc->cached_fw = NULL;
1464 /* Initilize SCSI Config Data structure
1466 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1468 /* Initialize the running configQ head.
1470 INIT_LIST_HEAD(&ioc->configQ);
1472 /* Initialize the fc rport list head.
1474 INIT_LIST_HEAD(&ioc->fc_rports);
1476 /* Find lookup slot. */
1477 INIT_LIST_HEAD(&ioc->list);
1478 ioc->id = mpt_ids++;
1480 mem_phys = msize = 0;
1482 for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1483 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1486 /* Get I/O space! */
1487 port = pci_resource_start(pdev, ii);
1488 psize = pci_resource_len(pdev,ii);
1493 mem_phys = pci_resource_start(pdev, ii);
1494 msize = pci_resource_len(pdev,ii);
1497 ioc->mem_size = msize;
1500 /* Get logical ptr for PciMem0 space */
1501 /*mem = ioremap(mem_phys, msize);*/
1502 mem = ioremap(mem_phys, msize);
1504 printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n");
1509 dinitprintk(ioc, printk(KERN_INFO MYNAM ": mem = %p, mem_phys = %lx\n", mem, mem_phys));
1511 dinitprintk(ioc, printk(KERN_INFO MYNAM ": facts @ %p, pfacts[0] @ %p\n",
1512 &ioc->facts, &ioc->pfacts[0]));
1514 ioc->mem_phys = mem_phys;
1515 ioc->chip = (SYSIF_REGS __iomem *)mem;
1517 /* Save Port IO values in case we need to do downloadboot */
1519 u8 *pmem = (u8*)port;
1520 ioc->pio_mem_phys = port;
1521 ioc->pio_chip = (SYSIF_REGS __iomem *)pmem;
1524 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1525 mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name);
1527 switch (pdev->device)
1529 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1530 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1531 ioc->errata_flag_1064 = 1;
1532 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1533 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1534 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1535 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1539 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1540 if (revision < XL_929) {
1541 /* 929X Chip Fix. Set Split transactions level
1542 * for PCIX. Set MOST bits to zero.
1544 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1546 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1548 /* 929XL Chip Fix. Set MMRBC to 0x08.
1550 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1552 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1557 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1558 /* 919X Chip Fix. Set Split transactions level
1559 * for PCIX. Set MOST bits to zero.
1561 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1563 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1567 case MPI_MANUFACTPAGE_DEVID_53C1030:
1568 /* 1030 Chip Fix. Disable Split transactions
1569 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1571 if (revision < C0_1030) {
1572 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1574 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1577 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1578 ioc->bus_type = SPI;
1581 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1582 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1583 ioc->errata_flag_1064 = 1;
1585 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1586 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1587 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1588 ioc->bus_type = SAS;
1591 if (ioc->errata_flag_1064)
1592 pci_disable_io_access(pdev);
1594 sprintf(ioc->name, "ioc%d", ioc->id);
1596 spin_lock_init(&ioc->FreeQlock);
1599 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1601 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1603 /* Set lookup ptr. */
1604 list_add_tail(&ioc->list, &ioc_list);
1606 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1608 mpt_detect_bound_ports(ioc, pdev);
1610 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1612 printk(KERN_WARNING MYNAM
1613 ": WARNING - %s did not initialize properly! (%d)\n",
1616 list_del(&ioc->list);
1618 ioc->alt_ioc->alt_ioc = NULL;
1621 pci_set_drvdata(pdev, NULL);
1625 /* call per device driver probe entry point */
1626 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1627 if(MptDeviceDriverHandlers[ii] &&
1628 MptDeviceDriverHandlers[ii]->probe) {
1629 MptDeviceDriverHandlers[ii]->probe(pdev,id);
1633 #ifdef CONFIG_PROC_FS
1635 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1637 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1639 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1641 ent->read_proc = procmpt_iocinfo_read;
1644 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1646 ent->read_proc = procmpt_summary_read;
1655 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1657 * mpt_detach - Remove a PCI intelligent MPT adapter.
1658 * @pdev: Pointer to pci_dev structure
1662 mpt_detach(struct pci_dev *pdev)
1664 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1668 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
1669 remove_proc_entry(pname, NULL);
1670 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
1671 remove_proc_entry(pname, NULL);
1672 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
1673 remove_proc_entry(pname, NULL);
1675 /* call per device driver remove entry point */
1676 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1677 if(MptDeviceDriverHandlers[ii] &&
1678 MptDeviceDriverHandlers[ii]->remove) {
1679 MptDeviceDriverHandlers[ii]->remove(pdev);
1683 /* Disable interrupts! */
1684 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1687 synchronize_irq(pdev->irq);
1689 /* Clear any lingering interrupt */
1690 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1692 CHIPREG_READ32(&ioc->chip->IntStatus);
1694 mpt_adapter_dispose(ioc);
1696 pci_set_drvdata(pdev, NULL);
1699 /**************************************************************************
1703 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1705 * mpt_suspend - Fusion MPT base driver suspend routine.
1706 * @pdev: Pointer to pci_dev structure
1707 * @state: new state to enter
1710 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
1713 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1715 device_state=pci_choose_state(pdev, state);
1717 printk(MYIOC_s_INFO_FMT
1718 "pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
1719 ioc->name, pdev, pci_name(pdev), device_state);
1721 pci_save_state(pdev);
1723 /* put ioc into READY_STATE */
1724 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
1725 printk(MYIOC_s_ERR_FMT
1726 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
1729 /* disable interrupts */
1730 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1733 /* Clear any lingering interrupt */
1734 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1736 pci_disable_device(pdev);
1737 pci_set_power_state(pdev, device_state);
1742 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1744 * mpt_resume - Fusion MPT base driver resume routine.
1745 * @pdev: Pointer to pci_dev structure
1748 mpt_resume(struct pci_dev *pdev)
1750 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1751 u32 device_state = pdev->current_state;
1755 printk(MYIOC_s_INFO_FMT
1756 "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
1757 ioc->name, pdev, pci_name(pdev), device_state);
1759 pci_set_power_state(pdev, 0);
1760 pci_restore_state(pdev);
1761 err = pci_enable_device(pdev);
1765 /* enable interrupts */
1766 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
1769 printk(MYIOC_s_INFO_FMT
1770 "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1772 (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1773 CHIPREG_READ32(&ioc->chip->Doorbell));
1775 /* bring ioc to operational state */
1776 if ((recovery_state = mpt_do_ioc_recovery(ioc,
1777 MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {
1778 printk(MYIOC_s_INFO_FMT
1779 "pci-resume: Cannot recover, error:[%x]\n",
1780 ioc->name, recovery_state);
1782 printk(MYIOC_s_INFO_FMT
1783 "pci-resume: success\n", ioc->name);
1791 mpt_signal_reset(int index, MPT_ADAPTER *ioc, int reset_phase)
1793 if ((MptDriverClass[index] == MPTSPI_DRIVER &&
1794 ioc->bus_type != SPI) ||
1795 (MptDriverClass[index] == MPTFC_DRIVER &&
1796 ioc->bus_type != FC) ||
1797 (MptDriverClass[index] == MPTSAS_DRIVER &&
1798 ioc->bus_type != SAS))
1799 /* make sure we only call the relevant reset handler
1802 return (MptResetHandlers[index])(ioc, reset_phase);
1805 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1807 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1808 * @ioc: Pointer to MPT adapter structure
1809 * @reason: Event word / reason
1810 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1812 * This routine performs all the steps necessary to bring the IOC
1813 * to a OPERATIONAL state.
1815 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1820 * -1 if failed to get board READY
1821 * -2 if READY but IOCFacts Failed
1822 * -3 if READY but PrimeIOCFifos Failed
1823 * -4 if READY but IOCInit Failed
1826 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1828 int hard_reset_done = 0;
1829 int alt_ioc_ready = 0;
1835 int reset_alt_ioc_active = 0;
1836 int irq_allocated = 0;
1839 printk(KERN_INFO MYNAM ": Initiating %s %s\n",
1840 ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
1842 /* Disable reply interrupts (also blocks FreeQ) */
1843 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1847 if (ioc->alt_ioc->active)
1848 reset_alt_ioc_active = 1;
1850 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1851 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
1852 ioc->alt_ioc->active = 0;
1856 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
1859 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
1860 if (hard_reset_done == -4) {
1861 printk(KERN_WARNING MYNAM ": %s Owned by PEER..skipping!\n",
1864 if (reset_alt_ioc_active && ioc->alt_ioc) {
1865 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1866 dprintk(ioc, printk(KERN_INFO MYNAM
1867 ": alt-%s reply irq re-enabled\n",
1868 ioc->alt_ioc->name));
1869 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
1870 ioc->alt_ioc->active = 1;
1874 printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",
1880 /* hard_reset_done = 0 if a soft reset was performed
1881 * and 1 if a hard reset was performed.
1883 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
1884 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
1887 printk(KERN_WARNING MYNAM
1888 ": alt-%s: Not ready WARNING!\n",
1889 ioc->alt_ioc->name);
1892 for (ii=0; ii<5; ii++) {
1893 /* Get IOC facts! Allow 5 retries */
1894 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
1900 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Retry IocFacts failed rc=%x\n", ioc->name, rc));
1902 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1903 MptDisplayIocCapabilities(ioc);
1906 if (alt_ioc_ready) {
1907 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
1908 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1909 "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
1910 /* Retry - alt IOC was initialized once
1912 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
1915 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1916 "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
1918 reset_alt_ioc_active = 0;
1919 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1920 MptDisplayIocCapabilities(ioc->alt_ioc);
1925 * Device is reset now. It must have de-asserted the interrupt line
1926 * (if it was asserted) and it should be safe to register for the
1929 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1931 if (ioc->pcidev->irq) {
1932 if (mpt_msi_enable && !pci_enable_msi(ioc->pcidev))
1933 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
1935 rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
1936 IRQF_SHARED, ioc->name, ioc);
1938 printk(MYIOC_s_ERR_FMT "Unable to allocate "
1939 "interrupt %d!\n", ioc->name,
1942 pci_disable_msi(ioc->pcidev);
1946 ioc->pci_irq = ioc->pcidev->irq;
1947 pci_set_master(ioc->pcidev); /* ?? */
1948 pci_set_drvdata(ioc->pcidev, ioc);
1949 dprintk(ioc, printk(KERN_INFO MYNAM ": %s installed at interrupt "
1950 "%d\n", ioc->name, ioc->pcidev->irq));
1954 /* Prime reply & request queues!
1955 * (mucho alloc's) Must be done prior to
1956 * init as upper addresses are needed for init.
1957 * If fails, continue with alt-ioc processing
1959 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
1962 /* May need to check/upload firmware & data here!
1963 * If fails, continue with alt-ioc processing
1965 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
1968 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
1969 printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
1970 ioc->alt_ioc->name, rc);
1972 reset_alt_ioc_active = 0;
1975 if (alt_ioc_ready) {
1976 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
1978 reset_alt_ioc_active = 0;
1979 printk(KERN_WARNING MYNAM
1980 ": alt-%s: (%d) init failure WARNING!\n",
1981 ioc->alt_ioc->name, rc);
1985 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
1986 if (ioc->upload_fw) {
1987 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1988 "firmware upload required!\n", ioc->name));
1990 /* Controller is not operational, cannot do upload
1993 rc = mpt_do_upload(ioc, sleepFlag);
1995 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
1997 * Maintain only one pointer to FW memory
1998 * so there will not be two attempt to
1999 * downloadboot onboard dual function
2000 * chips (mpt_adapter_disable,
2003 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2004 ": mpt_upload: alt_%s has cached_fw=%p \n",
2005 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
2006 ioc->alt_ioc->cached_fw = NULL;
2009 printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
2017 /* Enable! (reply interrupt) */
2018 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
2022 if (reset_alt_ioc_active && ioc->alt_ioc) {
2023 /* (re)Enable alt-IOC! (reply interrupt) */
2024 dinitprintk(ioc, printk(KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
2025 ioc->alt_ioc->name));
2026 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2027 ioc->alt_ioc->active = 1;
2030 /* Enable MPT base driver management of EventNotification
2031 * and EventAck handling.
2033 if ((ret == 0) && (!ioc->facts.EventState))
2034 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
2036 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2037 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
2039 /* Add additional "reason" check before call to GetLanConfigPages
2040 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2041 * recursive scenario; GetLanConfigPages times out, timer expired
2042 * routine calls HardResetHandler, which calls into here again,
2043 * and we try GetLanConfigPages again...
2045 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2048 * Initalize link list for inactive raid volumes.
2050 init_MUTEX(&ioc->raid_data.inactive_list_mutex);
2051 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2053 if (ioc->bus_type == SAS) {
2055 /* clear persistency table */
2056 if(ioc->facts.IOCExceptions &
2057 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
2058 ret = mptbase_sas_persist_operation(ioc,
2059 MPI_SAS_OP_CLEAR_NOT_PRESENT);
2066 mpt_findImVolumes(ioc);
2068 } else if (ioc->bus_type == FC) {
2069 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
2070 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2072 * Pre-fetch the ports LAN MAC address!
2073 * (LANPage1_t stuff)
2075 (void) GetLanConfigPages(ioc);
2076 a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2077 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2078 "LanAddr = %02X:%02X:%02X:"
2080 ioc->name, a[5], a[4],
2081 a[3], a[2], a[1], a[0] ));
2085 /* Get NVRAM and adapter maximums from SPP 0 and 2
2087 mpt_GetScsiPortSettings(ioc, 0);
2089 /* Get version and length of SDP 1
2091 mpt_readScsiDevicePageHeaders(ioc, 0);
2095 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
2096 mpt_findImVolumes(ioc);
2098 /* Check, and possibly reset, the coalescing value
2100 mpt_read_ioc_pg_1(ioc);
2102 mpt_read_ioc_pg_4(ioc);
2105 GetIoUnitPage2(ioc);
2106 mpt_get_manufacturing_pg_0(ioc);
2110 * Call each currently registered protocol IOC reset handler
2111 * with post-reset indication.
2112 * NOTE: If we're doing _IOC_BRINGUP, there can be no
2113 * MptResetHandlers[] registered yet.
2115 if (hard_reset_done) {
2117 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
2118 if ((ret == 0) && MptResetHandlers[ii]) {
2119 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2120 "Calling IOC post_reset handler #%d\n",
2122 rc += mpt_signal_reset(ii, ioc, MPT_IOC_POST_RESET);
2126 if (alt_ioc_ready && MptResetHandlers[ii]) {
2127 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2128 "Calling alt-%s post_reset handler #%d\n",
2129 ioc->name, ioc->alt_ioc->name, ii));
2130 rc += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_POST_RESET);
2134 /* FIXME? Examine results here? */
2138 if ((ret != 0) && irq_allocated) {
2139 free_irq(ioc->pci_irq, ioc);
2141 pci_disable_msi(ioc->pcidev);
2146 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2148 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2149 * @ioc: Pointer to MPT adapter structure
2150 * @pdev: Pointer to (struct pci_dev) structure
2152 * Search for PCI bus/dev_function which matches
2153 * PCI bus/dev_function (+/-1) for newly discovered 929,
2154 * 929X, 1030 or 1035.
2156 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2157 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2160 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
2162 struct pci_dev *peer=NULL;
2163 unsigned int slot = PCI_SLOT(pdev->devfn);
2164 unsigned int func = PCI_FUNC(pdev->devfn);
2165 MPT_ADAPTER *ioc_srch;
2167 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PCI device %s devfn=%x/%x,"
2168 " searching for devfn match on %x or %x\n",
2169 ioc->name, pci_name(pdev), pdev->bus->number,
2170 pdev->devfn, func-1, func+1));
2172 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
2174 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
2179 list_for_each_entry(ioc_srch, &ioc_list, list) {
2180 struct pci_dev *_pcidev = ioc_srch->pcidev;
2181 if (_pcidev == peer) {
2182 /* Paranoia checks */
2183 if (ioc->alt_ioc != NULL) {
2184 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
2185 ioc->name, ioc->alt_ioc->name);
2187 } else if (ioc_srch->alt_ioc != NULL) {
2188 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
2189 ioc_srch->name, ioc_srch->alt_ioc->name);
2192 dprintk(ioc, printk(KERN_INFO MYNAM ": FOUND! binding %s <==> %s\n",
2193 ioc->name, ioc_srch->name));
2194 ioc_srch->alt_ioc = ioc;
2195 ioc->alt_ioc = ioc_srch;
2201 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2203 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2204 * @ioc: Pointer to MPT adapter structure
2207 mpt_adapter_disable(MPT_ADAPTER *ioc)
2212 if (ioc->cached_fw != NULL) {
2213 ddlprintk(ioc, printk(KERN_INFO MYNAM ": mpt_adapter_disable: Pushing FW onto adapter\n"));
2214 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)ioc->cached_fw, NO_SLEEP)) < 0) {
2215 printk(KERN_WARNING MYNAM
2216 ": firmware downloadboot failure (%d)!\n", ret);
2220 /* Disable adapter interrupts! */
2221 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2223 /* Clear any lingering interrupt */
2224 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2226 if (ioc->alloc != NULL) {
2228 dexitprintk(ioc, printk(KERN_INFO MYNAM ": %s.free @ %p, sz=%d bytes\n",
2229 ioc->name, ioc->alloc, ioc->alloc_sz));
2230 pci_free_consistent(ioc->pcidev, sz,
2231 ioc->alloc, ioc->alloc_dma);
2232 ioc->reply_frames = NULL;
2233 ioc->req_frames = NULL;
2235 ioc->alloc_total -= sz;
2238 if (ioc->sense_buf_pool != NULL) {
2239 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2240 pci_free_consistent(ioc->pcidev, sz,
2241 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2242 ioc->sense_buf_pool = NULL;
2243 ioc->alloc_total -= sz;
2246 if (ioc->events != NULL){
2247 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2250 ioc->alloc_total -= sz;
2253 if (ioc->cached_fw != NULL) {
2254 sz = ioc->facts.FWImageSize;
2255 pci_free_consistent(ioc->pcidev, sz,
2256 ioc->cached_fw, ioc->cached_fw_dma);
2257 ioc->cached_fw = NULL;
2258 ioc->alloc_total -= sz;
2261 kfree(ioc->spi_data.nvram);
2262 mpt_inactive_raid_list_free(ioc);
2263 kfree(ioc->raid_data.pIocPg2);
2264 kfree(ioc->raid_data.pIocPg3);
2265 ioc->spi_data.nvram = NULL;
2266 ioc->raid_data.pIocPg3 = NULL;
2268 if (ioc->spi_data.pIocPg4 != NULL) {
2269 sz = ioc->spi_data.IocPg4Sz;
2270 pci_free_consistent(ioc->pcidev, sz,
2271 ioc->spi_data.pIocPg4,
2272 ioc->spi_data.IocPg4_dma);
2273 ioc->spi_data.pIocPg4 = NULL;
2274 ioc->alloc_total -= sz;
2277 if (ioc->ReqToChain != NULL) {
2278 kfree(ioc->ReqToChain);
2279 kfree(ioc->RequestNB);
2280 ioc->ReqToChain = NULL;
2283 kfree(ioc->ChainToChain);
2284 ioc->ChainToChain = NULL;
2286 if (ioc->HostPageBuffer != NULL) {
2287 if((ret = mpt_host_page_access_control(ioc,
2288 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2289 printk(KERN_ERR MYNAM
2290 ": %s: host page buffers free failed (%d)!\n",
2293 dexitprintk(ioc, printk(KERN_INFO MYNAM ": %s HostPageBuffer free @ %p, sz=%d bytes\n",
2294 ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
2295 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2296 ioc->HostPageBuffer,
2297 ioc->HostPageBuffer_dma);
2298 ioc->HostPageBuffer = NULL;
2299 ioc->HostPageBuffer_sz = 0;
2300 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2304 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2306 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2307 * @ioc: Pointer to MPT adapter structure
2309 * This routine unregisters h/w resources and frees all alloc'd memory
2310 * associated with a MPT adapter structure.
2313 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2315 int sz_first, sz_last;
2320 sz_first = ioc->alloc_total;
2322 mpt_adapter_disable(ioc);
2324 if (ioc->pci_irq != -1) {
2325 free_irq(ioc->pci_irq, ioc);
2327 pci_disable_msi(ioc->pcidev);
2331 if (ioc->memmap != NULL) {
2332 iounmap(ioc->memmap);
2336 #if defined(CONFIG_MTRR) && 0
2337 if (ioc->mtrr_reg > 0) {
2338 mtrr_del(ioc->mtrr_reg, 0, 0);
2339 dprintk(ioc, printk(KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name));
2343 /* Zap the adapter lookup ptr! */
2344 list_del(&ioc->list);
2346 sz_last = ioc->alloc_total;
2347 dprintk(ioc, printk(KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
2348 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2351 ioc->alt_ioc->alt_ioc = NULL;
2356 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2358 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2359 * @ioc: Pointer to MPT adapter structure
2362 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2366 printk(KERN_INFO "%s: ", ioc->name);
2368 printk("%s: ", ioc->prod_name);
2369 printk("Capabilities={");
2371 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2372 printk("Initiator");
2376 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2377 printk("%sTarget", i ? "," : "");
2381 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2382 printk("%sLAN", i ? "," : "");
2388 * This would probably evoke more questions than it's worth
2390 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2391 printk("%sLogBusAddr", i ? "," : "");
2399 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2401 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2402 * @ioc: Pointer to MPT_ADAPTER structure
2403 * @force: Force hard KickStart of IOC
2404 * @sleepFlag: Specifies whether the process can sleep
2407 * 1 - DIAG reset and READY
2408 * 0 - READY initially OR soft reset and READY
2409 * -1 - Any failure on KickStart
2410 * -2 - Msg Unit Reset Failed
2411 * -3 - IO Unit Reset Failed
2412 * -4 - IOC owned by a PEER
2415 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2420 int hard_reset_done = 0;
2425 /* Get current [raw] IOC state */
2426 ioc_state = mpt_GetIocState(ioc, 0);
2427 dhsprintk(ioc, printk(KERN_INFO MYNAM "::MakeIocReady, %s [raw] state=%08x\n", ioc->name, ioc_state));
2430 * Check to see if IOC got left/stuck in doorbell handshake
2431 * grip of death. If so, hard reset the IOC.
2433 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2435 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2439 /* Is it already READY? */
2440 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
2444 * Check to see if IOC is in FAULT state.
2446 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2448 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2450 printk(KERN_WARNING " FAULT code = %04xh\n",
2451 ioc_state & MPI_DOORBELL_DATA_MASK);
2455 * Hmmm... Did it get left operational?
2457 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2458 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC operational unexpected\n",
2462 * If PCI Peer, exit.
2463 * Else, if no fault conditions are present, issue a MessageUnitReset
2464 * Else, fall through to KickStart case
2466 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2467 dinitprintk(ioc, printk(KERN_INFO MYNAM
2468 ": whoinit 0x%x statefault %d force %d\n",
2469 whoinit, statefault, force));
2470 if (whoinit == MPI_WHOINIT_PCI_PEER)
2473 if ((statefault == 0 ) && (force == 0)) {
2474 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2481 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2482 if (hard_reset_done < 0)
2486 * Loop here waiting for IOC to come READY.
2489 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2491 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2492 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2494 * BIOS or previous driver load left IOC in OP state.
2495 * Reset messaging FIFOs.
2497 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2498 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2501 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2503 * Something is wrong. Try to get IOC back
2506 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2507 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2514 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2515 ioc->name, (int)((ii+5)/HZ));
2519 if (sleepFlag == CAN_SLEEP) {
2522 mdelay (1); /* 1 msec delay */
2527 if (statefault < 3) {
2528 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2530 statefault==1 ? "stuck handshake" : "IOC FAULT");
2533 return hard_reset_done;
2536 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2538 * mpt_GetIocState - Get the current state of a MPT adapter.
2539 * @ioc: Pointer to MPT_ADAPTER structure
2540 * @cooked: Request raw or cooked IOC state
2542 * Returns all IOC Doorbell register bits if cooked==0, else just the
2543 * Doorbell bits in MPI_IOC_STATE_MASK.
2546 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2551 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2552 // dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
2553 sc = s & MPI_IOC_STATE_MASK;
2556 ioc->last_state = sc;
2558 return cooked ? sc : s;
2561 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2563 * GetIocFacts - Send IOCFacts request to MPT adapter.
2564 * @ioc: Pointer to MPT_ADAPTER structure
2565 * @sleepFlag: Specifies whether the process can sleep
2566 * @reason: If recovery, only update facts.
2568 * Returns 0 for success, non-zero for failure.
2571 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2573 IOCFacts_t get_facts;
2574 IOCFactsReply_t *facts;
2582 /* IOC *must* NOT be in RESET state! */
2583 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2584 printk(KERN_ERR MYNAM ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
2590 facts = &ioc->facts;
2592 /* Destination (reply area)... */
2593 reply_sz = sizeof(*facts);
2594 memset(facts, 0, reply_sz);
2596 /* Request area (get_facts on the stack right now!) */
2597 req_sz = sizeof(get_facts);
2598 memset(&get_facts, 0, req_sz);
2600 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2601 /* Assert: All other get_facts fields are zero! */
2603 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2604 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2605 ioc->name, req_sz, reply_sz));
2607 /* No non-zero fields in the get_facts request are greater than
2608 * 1 byte in size, so we can just fire it off as is.
2610 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2611 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2616 * Now byte swap (GRRR) the necessary fields before any further
2617 * inspection of reply contents.
2619 * But need to do some sanity checks on MsgLength (byte) field
2620 * to make sure we don't zero IOC's req_sz!
2622 /* Did we get a valid reply? */
2623 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2624 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2626 * If not been here, done that, save off first WhoInit value
2628 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2629 ioc->FirstWhoInit = facts->WhoInit;
2632 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2633 facts->MsgContext = le32_to_cpu(facts->MsgContext);
2634 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2635 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2636 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2637 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
2638 /* CHECKME! IOCStatus, IOCLogInfo */
2640 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2641 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2644 * FC f/w version changed between 1.1 and 1.2
2645 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2646 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2648 if (facts->MsgVersion < 0x0102) {
2650 * Handle old FC f/w style, convert to new...
2652 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2653 facts->FWVersion.Word =
2654 ((oldv<<12) & 0xFF000000) |
2655 ((oldv<<8) & 0x000FFF00);
2657 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2659 facts->ProductID = le16_to_cpu(facts->ProductID);
2660 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
2661 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
2662 ioc->ir_firmware = 1;
2663 facts->CurrentHostMfaHighAddr =
2664 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2665 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2666 facts->CurrentSenseBufferHighAddr =
2667 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2668 facts->CurReplyFrameSize =
2669 le16_to_cpu(facts->CurReplyFrameSize);
2670 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
2673 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2674 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2675 * to 14 in MPI-1.01.0x.
2677 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2678 facts->MsgVersion > 0x0100) {
2679 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2682 sz = facts->FWImageSize;
2687 facts->FWImageSize = sz;
2689 if (!facts->RequestFrameSize) {
2690 /* Something is wrong! */
2691 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2696 r = sz = facts->BlockSize;
2697 vv = ((63 / (sz * 4)) + 1) & 0x03;
2698 ioc->NB_for_64_byte_frame = vv;
2704 ioc->NBShiftFactor = shiftFactor;
2705 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2706 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2707 ioc->name, vv, shiftFactor, r));
2709 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2711 * Set values for this IOC's request & reply frame sizes,
2712 * and request & reply queue depths...
2714 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2715 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2716 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2717 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2719 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "reply_sz=%3d, reply_depth=%4d\n",
2720 ioc->name, ioc->reply_sz, ioc->reply_depth));
2721 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "req_sz =%3d, req_depth =%4d\n",
2722 ioc->name, ioc->req_sz, ioc->req_depth));
2724 /* Get port facts! */
2725 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2729 printk(MYIOC_s_ERR_FMT
2730 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2731 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2732 RequestFrameSize)/sizeof(u32)));
2739 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2741 * GetPortFacts - Send PortFacts request to MPT adapter.
2742 * @ioc: Pointer to MPT_ADAPTER structure
2743 * @portnum: Port number
2744 * @sleepFlag: Specifies whether the process can sleep
2746 * Returns 0 for success, non-zero for failure.
2749 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2751 PortFacts_t get_pfacts;
2752 PortFactsReply_t *pfacts;
2758 /* IOC *must* NOT be in RESET state! */
2759 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2760 printk(KERN_ERR MYNAM ": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n",
2766 pfacts = &ioc->pfacts[portnum];
2768 /* Destination (reply area)... */
2769 reply_sz = sizeof(*pfacts);
2770 memset(pfacts, 0, reply_sz);
2772 /* Request area (get_pfacts on the stack right now!) */
2773 req_sz = sizeof(get_pfacts);
2774 memset(&get_pfacts, 0, req_sz);
2776 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2777 get_pfacts.PortNumber = portnum;
2778 /* Assert: All other get_pfacts fields are zero! */
2780 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending get PortFacts(%d) request\n",
2781 ioc->name, portnum));
2783 /* No non-zero fields in the get_pfacts request are greater than
2784 * 1 byte in size, so we can just fire it off as is.
2786 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2787 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2791 /* Did we get a valid reply? */
2793 /* Now byte swap the necessary fields in the response. */
2794 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2795 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2796 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2797 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2798 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2799 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2800 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2801 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2802 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2804 max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
2806 ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
2807 ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
2810 * Place all the devices on channels
2814 if (mpt_channel_mapping) {
2815 ioc->devices_per_bus = 1;
2816 ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
2822 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2824 * SendIocInit - Send IOCInit request to MPT adapter.
2825 * @ioc: Pointer to MPT_ADAPTER structure
2826 * @sleepFlag: Specifies whether the process can sleep
2828 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2830 * Returns 0 for success, non-zero for failure.
2833 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2836 MPIDefaultReply_t init_reply;
2842 memset(&ioc_init, 0, sizeof(ioc_init));
2843 memset(&init_reply, 0, sizeof(init_reply));
2845 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2846 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2848 /* If we are in a recovery mode and we uploaded the FW image,
2849 * then this pointer is not NULL. Skip the upload a second time.
2850 * Set this flag if cached_fw set for either IOC.
2852 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
2856 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "upload_fw %d facts.Flags=%x\n",
2857 ioc->name, ioc->upload_fw, ioc->facts.Flags));
2859 ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
2860 ioc_init.MaxBuses = (U8)ioc->number_of_buses;
2861 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n",
2862 ioc->name, ioc->facts.MsgVersion));
2863 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
2864 // set MsgVersion and HeaderVersion host driver was built with
2865 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
2866 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
2868 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
2869 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
2870 } else if(mpt_host_page_alloc(ioc, &ioc_init))
2873 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
2875 if (sizeof(dma_addr_t) == sizeof(u64)) {
2876 /* Save the upper 32-bits of the request
2877 * (reply) and sense buffers.
2879 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
2880 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2882 /* Force 32-bit addressing */
2883 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
2884 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
2887 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
2888 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
2889 ioc->facts.MaxDevices = ioc_init.MaxDevices;
2890 ioc->facts.MaxBuses = ioc_init.MaxBuses;
2892 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOCInit (req @ %p)\n",
2893 ioc->name, &ioc_init));
2895 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
2896 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
2898 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
2902 /* No need to byte swap the multibyte fields in the reply
2903 * since we don't even look at its contents.
2906 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending PortEnable (req @ %p)\n",
2907 ioc->name, &ioc_init));
2909 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
2910 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
2914 /* YIKES! SUPER IMPORTANT!!!
2915 * Poll IocState until _OPERATIONAL while IOC is doing
2916 * LoopInit and TargetDiscovery!
2919 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
2920 state = mpt_GetIocState(ioc, 1);
2921 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
2922 if (sleepFlag == CAN_SLEEP) {
2929 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
2930 ioc->name, (int)((count+5)/HZ));
2934 state = mpt_GetIocState(ioc, 1);
2937 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
2940 ioc->aen_event_read_flag=0;
2944 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2946 * SendPortEnable - Send PortEnable request to MPT adapter port.
2947 * @ioc: Pointer to MPT_ADAPTER structure
2948 * @portnum: Port number to enable
2949 * @sleepFlag: Specifies whether the process can sleep
2951 * Send PortEnable to bring IOC to OPERATIONAL state.
2953 * Returns 0 for success, non-zero for failure.
2956 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2958 PortEnable_t port_enable;
2959 MPIDefaultReply_t reply_buf;
2964 /* Destination... */
2965 reply_sz = sizeof(MPIDefaultReply_t);
2966 memset(&reply_buf, 0, reply_sz);
2968 req_sz = sizeof(PortEnable_t);
2969 memset(&port_enable, 0, req_sz);
2971 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
2972 port_enable.PortNumber = portnum;
2973 /* port_enable.ChainOffset = 0; */
2974 /* port_enable.MsgFlags = 0; */
2975 /* port_enable.MsgContext = 0; */
2977 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Port(%d)Enable (req @ %p)\n",
2978 ioc->name, portnum, &port_enable));
2980 /* RAID FW may take a long time to enable
2982 if (ioc->ir_firmware || ioc->bus_type == SAS) {
2983 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
2984 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
2985 300 /*seconds*/, sleepFlag);
2987 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
2988 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
2989 30 /*seconds*/, sleepFlag);
2995 * mpt_alloc_fw_memory - allocate firmware memory
2996 * @ioc: Pointer to MPT_ADAPTER structure
2997 * @size: total FW bytes
2999 * If memory has already been allocated, the same (cached) value
3003 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
3006 return; /* use already allocated memory */
3007 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
3008 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
3009 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
3010 ioc->alloc_total += size;
3011 ioc->alt_ioc->alloc_total -= size;
3013 if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
3014 ioc->alloc_total += size;
3018 * mpt_free_fw_memory - free firmware memory
3019 * @ioc: Pointer to MPT_ADAPTER structure
3021 * If alt_img is NULL, delete from ioc structure.
3022 * Else, delete a secondary image in same format.
3025 mpt_free_fw_memory(MPT_ADAPTER *ioc)
3029 sz = ioc->facts.FWImageSize;
3030 dinitprintk(ioc, printk(KERN_INFO MYNAM "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3031 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3032 pci_free_consistent(ioc->pcidev, sz,
3033 ioc->cached_fw, ioc->cached_fw_dma);
3034 ioc->cached_fw = NULL;
3040 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3042 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3043 * @ioc: Pointer to MPT_ADAPTER structure
3044 * @sleepFlag: Specifies whether the process can sleep
3046 * Returns 0 for success, >0 for handshake failure
3047 * <0 for fw upload failure.
3049 * Remark: If bound IOC and a successful FWUpload was performed
3050 * on the bound IOC, the second image is discarded
3051 * and memory is free'd. Both channels must upload to prevent
3052 * IOC from running in degraded mode.
3055 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3057 u8 request[ioc->req_sz];
3058 u8 reply[sizeof(FWUploadReply_t)];
3059 FWUpload_t *prequest;
3060 FWUploadReply_t *preply;
3061 FWUploadTCSGE_t *ptcsge;
3064 int ii, sz, reply_sz;
3067 /* If the image size is 0, we are done.
3069 if ((sz = ioc->facts.FWImageSize) == 0)
3072 mpt_alloc_fw_memory(ioc, sz);
3074 dinitprintk(ioc, printk(KERN_INFO MYNAM ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3075 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3077 if (ioc->cached_fw == NULL) {
3083 prequest = (FWUpload_t *)&request;
3084 preply = (FWUploadReply_t *)&reply;
3086 /* Destination... */
3087 memset(prequest, 0, ioc->req_sz);
3089 reply_sz = sizeof(reply);
3090 memset(preply, 0, reply_sz);
3092 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
3093 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
3095 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
3096 ptcsge->DetailsLength = 12;
3097 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
3098 ptcsge->ImageSize = cpu_to_le32(sz);
3100 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
3102 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3103 mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma);
3105 sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
3106 dinitprintk(ioc, printk(KERN_INFO MYNAM ": Sending FW Upload (req @ %p) sgeoffset=%d \n",
3107 prequest, sgeoffset));
3108 DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest)
3110 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
3111 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
3113 dinitprintk(ioc, printk(KERN_INFO MYNAM ": FW Upload completed rc=%x \n", ii));
3115 cmdStatus = -EFAULT;
3117 /* Handshake transfer was complete and successful.
3118 * Check the Reply Frame.
3120 int status, transfer_sz;
3121 status = le16_to_cpu(preply->IOCStatus);
3122 if (status == MPI_IOCSTATUS_SUCCESS) {
3123 transfer_sz = le32_to_cpu(preply->ActualImageSize);
3124 if (transfer_sz == sz)
3128 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n",
3129 ioc->name, cmdStatus));
3134 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": fw upload failed, freeing image \n",
3136 mpt_free_fw_memory(ioc);
3142 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3144 * mpt_downloadboot - DownloadBoot code
3145 * @ioc: Pointer to MPT_ADAPTER structure
3146 * @pFwHeader: Pointer to firmware header info
3147 * @sleepFlag: Specifies whether the process can sleep
3149 * FwDownloadBoot requires Programmed IO access.
3151 * Returns 0 for success
3152 * -1 FW Image size is 0
3153 * -2 No valid cached_fw Pointer
3154 * <0 for fw upload failure.
3157 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3159 MpiExtImageHeader_t *pExtImage;
3169 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3170 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
3172 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3173 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3174 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3175 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3176 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3177 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3179 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
3182 if (sleepFlag == CAN_SLEEP) {
3188 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3189 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3191 for (count = 0; count < 30; count ++) {
3192 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3193 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3194 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESET_ADAPTER cleared, count=%d\n",
3199 if (sleepFlag == CAN_SLEEP) {
3206 if ( count == 30 ) {
3207 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot failed! "
3208 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3209 ioc->name, diag0val));
3213 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3214 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3215 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3216 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3217 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3218 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3220 /* Set the DiagRwEn and Disable ARM bits */
3221 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3223 fwSize = (pFwHeader->ImageSize + 3)/4;
3224 ptrFw = (u32 *) pFwHeader;
3226 /* Write the LoadStartAddress to the DiagRw Address Register
3227 * using Programmed IO
3229 if (ioc->errata_flag_1064)
3230 pci_enable_io_access(ioc->pcidev);
3232 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3233 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "LoadStart addr written 0x%x \n",
3234 ioc->name, pFwHeader->LoadStartAddress));
3236 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write FW Image: 0x%x bytes @ %p\n",
3237 ioc->name, fwSize*4, ptrFw));
3239 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3242 nextImage = pFwHeader->NextImageHeaderOffset;
3244 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3246 load_addr = pExtImage->LoadStartAddress;
3248 fwSize = (pExtImage->ImageSize + 3) >> 2;
3249 ptrFw = (u32 *)pExtImage;
3251 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3252 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3253 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3256 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3258 nextImage = pExtImage->NextImageHeaderOffset;
3261 /* Write the IopResetVectorRegAddr */
3262 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
3263 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3265 /* Write the IopResetVectorValue */
3266 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3267 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3269 /* Clear the internal flash bad bit - autoincrementing register,
3270 * so must do two writes.
3272 if (ioc->bus_type == SPI) {
3274 * 1030 and 1035 H/W errata, workaround to access
3275 * the ClearFlashBadSignatureBit
3277 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3278 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3279 diagRwData |= 0x40000000;
3280 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3281 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3283 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3284 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3285 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3286 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3289 if (sleepFlag == CAN_SLEEP) {
3296 if (ioc->errata_flag_1064)
3297 pci_disable_io_access(ioc->pcidev);
3299 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3300 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot diag0val=%x, "
3301 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3302 ioc->name, diag0val));
3303 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3304 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot now diag0val=%x\n",
3305 ioc->name, diag0val));
3306 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3308 /* Write 0xFF to reset the sequencer */
3309 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3311 if (ioc->bus_type == SAS) {
3312 ioc_state = mpt_GetIocState(ioc, 0);
3313 if ( (GetIocFacts(ioc, sleepFlag,
3314 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3315 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "GetIocFacts failed: IocState=%x\n",
3316 ioc->name, ioc_state));
3321 for (count=0; count<HZ*20; count++) {
3322 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3323 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3324 "downloadboot successful! (count=%d) IocState=%x\n",
3325 ioc->name, count, ioc_state));
3326 if (ioc->bus_type == SAS) {
3329 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3330 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3331 "downloadboot: SendIocInit failed\n",
3335 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3336 "downloadboot: SendIocInit successful\n",
3340 if (sleepFlag == CAN_SLEEP) {
3346 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3347 "downloadboot failed! IocState=%x\n",ioc->name, ioc_state));
3351 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3353 * KickStart - Perform hard reset of MPT adapter.
3354 * @ioc: Pointer to MPT_ADAPTER structure
3355 * @force: Force hard reset
3356 * @sleepFlag: Specifies whether the process can sleep
3358 * This routine places MPT adapter in diagnostic mode via the
3359 * WriteSequence register, and then performs a hard reset of adapter
3360 * via the Diagnostic register.
3362 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3363 * or NO_SLEEP (interrupt thread, use mdelay)
3364 * force - 1 if doorbell active, board fault state
3365 * board operational, IOC_RECOVERY or
3366 * IOC_BRINGUP and there is an alt_ioc.
3370 * 1 - hard reset, READY
3371 * 0 - no reset due to History bit, READY
3372 * -1 - no reset due to History bit but not READY
3373 * OR reset but failed to come READY
3374 * -2 - no reset, could not enter DIAG mode
3375 * -3 - reset but bad FW bit
3378 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3380 int hard_reset_done = 0;
3384 dinitprintk(ioc, printk(KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
3385 if (ioc->bus_type == SPI) {
3386 /* Always issue a Msg Unit Reset first. This will clear some
3387 * SCSI bus hang conditions.
3389 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3391 if (sleepFlag == CAN_SLEEP) {
3398 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3399 if (hard_reset_done < 0)
3400 return hard_reset_done;
3402 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n",
3405 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3406 for (cnt=0; cnt<cntdn; cnt++) {
3407 ioc_state = mpt_GetIocState(ioc, 1);
3408 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3409 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStart successful! (cnt=%d)\n",
3411 return hard_reset_done;
3413 if (sleepFlag == CAN_SLEEP) {
3420 printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3421 ioc->name, ioc_state);
3425 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3427 * mpt_diag_reset - Perform hard reset of the adapter.
3428 * @ioc: Pointer to MPT_ADAPTER structure
3429 * @ignore: Set if to honor and clear to ignore
3430 * the reset history bit
3431 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3432 * else set to NO_SLEEP (use mdelay instead)
3434 * This routine places the adapter in diagnostic mode via the
3435 * WriteSequence register and then performs a hard reset of adapter
3436 * via the Diagnostic register. Adapter should be in ready state
3437 * upon successful completion.
3439 * Returns: 1 hard reset successful
3440 * 0 no reset performed because reset history bit set
3441 * -2 enabling diagnostic mode failed
3442 * -3 diagnostic reset failed
3445 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3447 MPT_ADAPTER *iocp=NULL;
3450 int hard_reset_done = 0;
3454 /* Clear any existing interrupts */
3455 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3457 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3458 drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3459 "address=%p\n", ioc->name, __FUNCTION__,
3460 &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3461 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3462 if (sleepFlag == CAN_SLEEP)
3467 for (count = 0; count < 60; count ++) {
3468 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3469 doorbell &= MPI_IOC_STATE_MASK;
3471 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3472 "looking for READY STATE: doorbell=%x"
3474 ioc->name, doorbell, count));
3475 if (doorbell == MPI_IOC_STATE_READY) {
3480 if (sleepFlag == CAN_SLEEP)
3488 /* Use "Diagnostic reset" method! (only thing available!) */
3489 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3491 if (ioc->debug_level & MPT_DEBUG) {
3493 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3494 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3495 ioc->name, diag0val, diag1val));
3498 /* Do the reset if we are told to ignore the reset history
3499 * or if the reset history is 0
3501 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3502 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3503 /* Write magic sequence to WriteSequence register
3504 * Loop until in diagnostic mode
3506 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3507 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3508 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3509 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3510 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3511 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3514 if (sleepFlag == CAN_SLEEP) {
3522 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3523 ioc->name, diag0val);
3528 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3530 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3531 ioc->name, diag0val));
3534 if (ioc->debug_level & MPT_DEBUG) {
3536 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3537 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3538 ioc->name, diag0val, diag1val));
3541 * Disable the ARM (Bug fix)
3544 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3548 * Now hit the reset bit in the Diagnostic register
3549 * (THE BIG HAMMER!) (Clears DRWE bit).
3551 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3552 hard_reset_done = 1;
3553 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset performed\n",
3557 * Call each currently registered protocol IOC reset handler
3558 * with pre-reset indication.
3559 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3560 * MptResetHandlers[] registered yet.
3566 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
3567 if (MptResetHandlers[ii]) {
3568 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3569 "Calling IOC pre_reset handler #%d\n",
3571 r += mpt_signal_reset(ii, ioc, MPT_IOC_PRE_RESET);
3573 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3574 "Calling alt-%s pre_reset handler #%d\n",
3575 ioc->name, ioc->alt_ioc->name, ii));
3576 r += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_PRE_RESET);
3580 /* FIXME? Examine results here? */
3585 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
3586 iocp = ioc->alt_ioc;
3588 /* If the DownloadBoot operation fails, the
3589 * IOC will be left unusable. This is a fatal error
3590 * case. _diag_reset will return < 0
3592 for (count = 0; count < 30; count ++) {
3593 diag0val = CHIPREG_READ32(&iocp->chip->Diagnostic);
3594 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3598 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n",
3599 iocp->name, diag0val, count));
3601 if (sleepFlag == CAN_SLEEP) {
3607 if ((count = mpt_downloadboot(ioc,
3608 (MpiFwHeader_t *)iocp->cached_fw, sleepFlag)) < 0) {
3609 printk(KERN_WARNING MYNAM
3610 ": firmware downloadboot failure (%d)!\n", count);
3614 /* Wait for FW to reload and for board
3615 * to go to the READY state.
3616 * Maximum wait is 60 seconds.
3617 * If fail, no error will check again
3618 * with calling program.
3620 for (count = 0; count < 60; count ++) {
3621 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3622 doorbell &= MPI_IOC_STATE_MASK;
3624 if (doorbell == MPI_IOC_STATE_READY) {
3629 if (sleepFlag == CAN_SLEEP) {
3638 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3639 if (ioc->debug_level & MPT_DEBUG) {
3641 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3642 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3643 ioc->name, diag0val, diag1val));
3646 /* Clear RESET_HISTORY bit! Place board in the
3647 * diagnostic mode to update the diag register.
3649 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3651 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3652 /* Write magic sequence to WriteSequence register
3653 * Loop until in diagnostic mode
3655 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3656 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3657 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3658 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3659 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3660 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3663 if (sleepFlag == CAN_SLEEP) {
3671 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3672 ioc->name, diag0val);
3675 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3677 diag0val &= ~MPI_DIAG_RESET_HISTORY;
3678 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3679 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3680 if (diag0val & MPI_DIAG_RESET_HISTORY) {
3681 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3685 /* Disable Diagnostic Mode
3687 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3689 /* Check FW reload status flags.
3691 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3692 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3693 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3694 ioc->name, diag0val);
3698 if (ioc->debug_level & MPT_DEBUG) {
3700 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3701 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3702 ioc->name, diag0val, diag1val));
3706 * Reset flag that says we've enabled event notification
3708 ioc->facts.EventState = 0;
3711 ioc->alt_ioc->facts.EventState = 0;
3713 return hard_reset_done;
3716 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3718 * SendIocReset - Send IOCReset request to MPT adapter.
3719 * @ioc: Pointer to MPT_ADAPTER structure
3720 * @reset_type: reset type, expected values are
3721 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3722 * @sleepFlag: Specifies whether the process can sleep
3724 * Send IOCReset request to the MPT adapter.
3726 * Returns 0 for success, non-zero for failure.
3729 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3735 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOC reset(0x%02x)!\n",
3736 ioc->name, reset_type));
3737 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3738 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3741 /* FW ACK'd request, wait for READY state
3744 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
3746 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3750 if (sleepFlag != CAN_SLEEP)
3753 printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
3754 ioc->name, (int)((count+5)/HZ));
3758 if (sleepFlag == CAN_SLEEP) {
3761 mdelay (1); /* 1 msec delay */
3766 * Cleanup all event stuff for this IOC; re-issue EventNotification
3767 * request if needed.
3769 if (ioc->facts.Function)
3770 ioc->facts.EventState = 0;
3775 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3777 * initChainBuffers - Allocate memory for and initialize chain buffers
3778 * @ioc: Pointer to MPT_ADAPTER structure
3780 * Allocates memory for and initializes chain buffers,
3781 * chain buffer control arrays and spinlock.
3784 initChainBuffers(MPT_ADAPTER *ioc)
3787 int sz, ii, num_chain;
3788 int scale, num_sge, numSGE;
3790 /* ReqToChain size must equal the req_depth
3793 if (ioc->ReqToChain == NULL) {
3794 sz = ioc->req_depth * sizeof(int);
3795 mem = kmalloc(sz, GFP_ATOMIC);
3799 ioc->ReqToChain = (int *) mem;
3800 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReqToChain alloc @ %p, sz=%d bytes\n",
3801 ioc->name, mem, sz));
3802 mem = kmalloc(sz, GFP_ATOMIC);
3806 ioc->RequestNB = (int *) mem;
3807 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestNB alloc @ %p, sz=%d bytes\n",
3808 ioc->name, mem, sz));
3810 for (ii = 0; ii < ioc->req_depth; ii++) {
3811 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
3814 /* ChainToChain size must equal the total number
3815 * of chain buffers to be allocated.
3818 * Calculate the number of chain buffers needed(plus 1) per I/O
3819 * then multiply the maximum number of simultaneous cmds
3821 * num_sge = num sge in request frame + last chain buffer
3822 * scale = num sge per chain buffer if no chain element
3824 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3825 if (sizeof(dma_addr_t) == sizeof(u64))
3826 num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3828 num_sge = 1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3830 if (sizeof(dma_addr_t) == sizeof(u64)) {
3831 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3832 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3834 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3835 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3837 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n",
3838 ioc->name, num_sge, numSGE));
3840 if ( numSGE > MPT_SCSI_SG_DEPTH )
3841 numSGE = MPT_SCSI_SG_DEPTH;
3844 while (numSGE - num_sge > 0) {
3846 num_sge += (scale - 1);
3850 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Now numSGE=%d num_sge=%d num_chain=%d\n",
3851 ioc->name, numSGE, num_sge, num_chain));
3853 if (ioc->bus_type == SPI)
3854 num_chain *= MPT_SCSI_CAN_QUEUE;
3856 num_chain *= MPT_FC_CAN_QUEUE;
3858 ioc->num_chain = num_chain;
3860 sz = num_chain * sizeof(int);
3861 if (ioc->ChainToChain == NULL) {
3862 mem = kmalloc(sz, GFP_ATOMIC);
3866 ioc->ChainToChain = (int *) mem;
3867 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainToChain alloc @ %p, sz=%d bytes\n",
3868 ioc->name, mem, sz));
3870 mem = (u8 *) ioc->ChainToChain;
3872 memset(mem, 0xFF, sz);
3876 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3878 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
3879 * @ioc: Pointer to MPT_ADAPTER structure
3881 * This routine allocates memory for the MPT reply and request frame
3882 * pools (if necessary), and primes the IOC reply FIFO with
3885 * Returns 0 for success, non-zero for failure.
3888 PrimeIocFifos(MPT_ADAPTER *ioc)
3891 unsigned long flags;
3892 dma_addr_t alloc_dma;
3894 int i, reply_sz, sz, total_size, num_chain;
3896 /* Prime reply FIFO... */
3898 if (ioc->reply_frames == NULL) {
3899 if ( (num_chain = initChainBuffers(ioc)) < 0)
3902 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
3903 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
3904 ioc->name, ioc->reply_sz, ioc->reply_depth));
3905 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d[%x] bytes\n",
3906 ioc->name, reply_sz, reply_sz));
3908 sz = (ioc->req_sz * ioc->req_depth);
3909 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d bytes, RequestDepth=%d\n",
3910 ioc->name, ioc->req_sz, ioc->req_depth));
3911 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d[%x] bytes\n",
3912 ioc->name, sz, sz));
3915 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
3916 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d bytes, ChainDepth=%d\n",
3917 ioc->name, ioc->req_sz, num_chain));
3918 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
3919 ioc->name, sz, sz, num_chain));
3922 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
3924 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
3929 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Total alloc @ %p[%p], sz=%d[%x] bytes\n",
3930 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
3932 memset(mem, 0, total_size);
3933 ioc->alloc_total += total_size;
3935 ioc->alloc_dma = alloc_dma;
3936 ioc->alloc_sz = total_size;
3937 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
3938 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3940 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
3941 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3943 alloc_dma += reply_sz;
3946 /* Request FIFO - WE manage this! */
3948 ioc->req_frames = (MPT_FRAME_HDR *) mem;
3949 ioc->req_frames_dma = alloc_dma;
3951 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffers @ %p[%p]\n",
3952 ioc->name, mem, (void *)(ulong)alloc_dma));
3954 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3956 #if defined(CONFIG_MTRR) && 0
3958 * Enable Write Combining MTRR for IOC's memory region.
3959 * (at least as much as we can; "size and base must be
3960 * multiples of 4 kiB"
3962 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
3964 MTRR_TYPE_WRCOMB, 1);
3965 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MTRR region registered (base:size=%08x:%x)\n",
3966 ioc->name, ioc->req_frames_dma, sz));
3969 for (i = 0; i < ioc->req_depth; i++) {
3970 alloc_dma += ioc->req_sz;
3974 ioc->ChainBuffer = mem;
3975 ioc->ChainBufferDMA = alloc_dma;
3977 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffers @ %p(%p)\n",
3978 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
3980 /* Initialize the free chain Q.
3983 INIT_LIST_HEAD(&ioc->FreeChainQ);
3985 /* Post the chain buffers to the FreeChainQ.
3987 mem = (u8 *)ioc->ChainBuffer;
3988 for (i=0; i < num_chain; i++) {
3989 mf = (MPT_FRAME_HDR *) mem;
3990 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
3994 /* Initialize Request frames linked list
3996 alloc_dma = ioc->req_frames_dma;
3997 mem = (u8 *) ioc->req_frames;
3999 spin_lock_irqsave(&ioc->FreeQlock, flags);
4000 INIT_LIST_HEAD(&ioc->FreeQ);
4001 for (i = 0; i < ioc->req_depth; i++) {
4002 mf = (MPT_FRAME_HDR *) mem;
4004 /* Queue REQUESTs *internally*! */
4005 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
4009 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4011 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4012 ioc->sense_buf_pool =
4013 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
4014 if (ioc->sense_buf_pool == NULL) {
4015 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
4020 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
4021 ioc->alloc_total += sz;
4022 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SenseBuffers @ %p[%p]\n",
4023 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
4027 /* Post Reply frames to FIFO
4029 alloc_dma = ioc->alloc_dma;
4030 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4031 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4033 for (i = 0; i < ioc->reply_depth; i++) {
4034 /* Write each address to the IOC! */
4035 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
4036 alloc_dma += ioc->reply_sz;
4042 if (ioc->alloc != NULL) {
4044 pci_free_consistent(ioc->pcidev,
4046 ioc->alloc, ioc->alloc_dma);
4047 ioc->reply_frames = NULL;
4048 ioc->req_frames = NULL;
4049 ioc->alloc_total -= sz;
4051 if (ioc->sense_buf_pool != NULL) {
4052 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4053 pci_free_consistent(ioc->pcidev,
4055 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
4056 ioc->sense_buf_pool = NULL;
4061 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4063 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4064 * from IOC via doorbell handshake method.
4065 * @ioc: Pointer to MPT_ADAPTER structure
4066 * @reqBytes: Size of the request in bytes
4067 * @req: Pointer to MPT request frame
4068 * @replyBytes: Expected size of the reply in bytes
4069 * @u16reply: Pointer to area where reply should be written
4070 * @maxwait: Max wait time for a reply (in seconds)
4071 * @sleepFlag: Specifies whether the process can sleep
4073 * NOTES: It is the callers responsibility to byte-swap fields in the
4074 * request which are greater than 1 byte in size. It is also the
4075 * callers responsibility to byte-swap response fields which are
4076 * greater than 1 byte in size.
4078 * Returns 0 for success, non-zero for failure.
4081 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
4082 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
4084 MPIDefaultReply_t *mptReply;
4089 * Get ready to cache a handshake reply
4091 ioc->hs_reply_idx = 0;
4092 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4093 mptReply->MsgLength = 0;
4096 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4097 * then tell IOC that we want to handshake a request of N words.
4098 * (WRITE u32val to Doorbell reg).
4100 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4101 CHIPREG_WRITE32(&ioc->chip->Doorbell,
4102 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
4103 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
4106 * Wait for IOC's doorbell handshake int
4108 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4111 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4112 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4114 /* Read doorbell and check for active bit */
4115 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
4119 * Clear doorbell int (WRITE 0 to IntStatus reg),
4120 * then wait for IOC to ACKnowledge that it's ready for
4121 * our handshake request.
4123 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4124 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4129 u8 *req_as_bytes = (u8 *) req;
4132 * Stuff request words via doorbell handshake,
4133 * with ACK from IOC for each.
4135 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
4136 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
4137 (req_as_bytes[(ii*4) + 1] << 8) |
4138 (req_as_bytes[(ii*4) + 2] << 16) |
4139 (req_as_bytes[(ii*4) + 3] << 24));
4141 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
4142 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4146 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req));
4147 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req)
4149 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n",
4150 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
4153 * Wait for completion of doorbell handshake reply from the IOC
4155 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
4158 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake reply count=%d%s\n",
4159 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
4162 * Copy out the cached reply...
4164 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
4165 u16reply[ii] = ioc->hs_reply[ii];
4173 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4175 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4176 * @ioc: Pointer to MPT_ADAPTER structure
4177 * @howlong: How long to wait (in seconds)
4178 * @sleepFlag: Specifies whether the process can sleep
4180 * This routine waits (up to ~2 seconds max) for IOC doorbell
4181 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4182 * bit in its IntStatus register being clear.
4184 * Returns a negative value on failure, else wait loop count.
4187 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4193 cntdn = 1000 * howlong;
4195 if (sleepFlag == CAN_SLEEP) {
4198 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4199 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4206 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4207 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4214 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell ACK (count=%d)\n",
4219 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4220 ioc->name, count, intstat);
4224 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4226 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4227 * @ioc: Pointer to MPT_ADAPTER structure
4228 * @howlong: How long to wait (in seconds)
4229 * @sleepFlag: Specifies whether the process can sleep
4231 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4232 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4234 * Returns a negative value on failure, else wait loop count.
4237 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4243 cntdn = 1000 * howlong;
4244 if (sleepFlag == CAN_SLEEP) {
4246 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4247 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4254 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4255 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4263 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4264 ioc->name, count, howlong));
4268 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4269 ioc->name, count, intstat);
4273 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4275 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4276 * @ioc: Pointer to MPT_ADAPTER structure
4277 * @howlong: How long to wait (in seconds)
4278 * @sleepFlag: Specifies whether the process can sleep
4280 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4281 * Reply is cached to IOC private area large enough to hold a maximum
4282 * of 128 bytes of reply data.
4284 * Returns a negative value on failure, else size of reply in WORDS.
4287 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4292 u16 *hs_reply = ioc->hs_reply;
4293 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4296 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4299 * Get first two u16's so we can look at IOC's intended reply MsgLength
4302 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4305 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4306 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4307 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4310 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4311 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4315 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4316 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4317 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4320 * If no error (and IOC said MsgLength is > 0), piece together
4321 * reply 16 bits at a time.
4323 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4324 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4326 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4327 /* don't overflow our IOC hs_reply[] buffer! */
4328 if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
4329 hs_reply[u16cnt] = hword;
4330 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4333 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4335 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4338 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4343 else if (u16cnt != (2 * mptReply->MsgLength)) {
4346 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4351 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name));
4352 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply)
4354 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4355 ioc->name, t, u16cnt/2));
4359 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4361 * GetLanConfigPages - Fetch LANConfig pages.
4362 * @ioc: Pointer to MPT_ADAPTER structure
4364 * Return: 0 for success
4365 * -ENOMEM if no memory available
4366 * -EPERM if not allowed due to ISR context
4367 * -EAGAIN if no msg frames currently available
4368 * -EFAULT for non-successful reply or no reply (timeout)
4371 GetLanConfigPages(MPT_ADAPTER *ioc)
4373 ConfigPageHeader_t hdr;
4375 LANPage0_t *ppage0_alloc;
4376 dma_addr_t page0_dma;
4377 LANPage1_t *ppage1_alloc;
4378 dma_addr_t page1_dma;
4383 /* Get LAN Page 0 header */
4384 hdr.PageVersion = 0;
4387 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4388 cfg.cfghdr.hdr = &hdr;
4390 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4395 if ((rc = mpt_config(ioc, &cfg)) != 0)
4398 if (hdr.PageLength > 0) {
4399 data_sz = hdr.PageLength * 4;
4400 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4403 memset((u8 *)ppage0_alloc, 0, data_sz);
4404 cfg.physAddr = page0_dma;
4405 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4407 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4409 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4410 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4414 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4417 * Normalize endianness of structure data,
4418 * by byte-swapping all > 1 byte fields!
4427 /* Get LAN Page 1 header */
4428 hdr.PageVersion = 0;
4431 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4432 cfg.cfghdr.hdr = &hdr;
4434 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4438 if ((rc = mpt_config(ioc, &cfg)) != 0)
4441 if (hdr.PageLength == 0)
4444 data_sz = hdr.PageLength * 4;
4446 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4448 memset((u8 *)ppage1_alloc, 0, data_sz);
4449 cfg.physAddr = page1_dma;
4450 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4452 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4454 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4455 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4458 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4461 * Normalize endianness of structure data,
4462 * by byte-swapping all > 1 byte fields!
4470 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4472 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
4473 * @ioc: Pointer to MPT_ADAPTER structure
4474 * @persist_opcode: see below
4476 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4477 * devices not currently present.
4478 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4480 * NOTE: Don't use not this function during interrupt time.
4482 * Returns 0 for success, non-zero error
4485 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4487 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4489 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
4490 SasIoUnitControlReply_t *sasIoUnitCntrReply;
4491 MPT_FRAME_HDR *mf = NULL;
4492 MPIHeader_t *mpi_hdr;
4495 /* insure garbage is not sent to fw */
4496 switch(persist_opcode) {
4498 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
4499 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
4507 printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode);
4509 /* Get a MF for this command.
4511 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4512 printk("%s: no msg frames!\n",__FUNCTION__);
4516 mpi_hdr = (MPIHeader_t *) mf;
4517 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
4518 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
4519 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
4520 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
4521 sasIoUnitCntrReq->Operation = persist_opcode;
4523 init_timer(&ioc->persist_timer);
4524 ioc->persist_timer.data = (unsigned long) ioc;
4525 ioc->persist_timer.function = mpt_timer_expired;
4526 ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
4527 ioc->persist_wait_done=0;
4528 add_timer(&ioc->persist_timer);
4529 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4530 wait_event(mpt_waitq, ioc->persist_wait_done);
4532 sasIoUnitCntrReply =
4533 (SasIoUnitControlReply_t *)ioc->persist_reply_frame;
4534 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
4535 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4537 sasIoUnitCntrReply->IOCStatus,
4538 sasIoUnitCntrReply->IOCLogInfo);
4542 printk("%s: success\n",__FUNCTION__);
4546 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4549 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
4550 MpiEventDataRaid_t * pRaidEventData)
4559 volume = pRaidEventData->VolumeID;
4560 reason = pRaidEventData->ReasonCode;
4561 disk = pRaidEventData->PhysDiskNum;
4562 status = le32_to_cpu(pRaidEventData->SettingsStatus);
4563 flags = (status >> 0) & 0xff;
4564 state = (status >> 8) & 0xff;
4566 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
4570 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
4571 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
4572 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
4573 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
4574 ioc->name, disk, volume);
4576 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
4581 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4582 printk(MYIOC_s_INFO_FMT " volume has been created\n",
4586 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4588 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
4592 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
4593 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
4597 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4598 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
4600 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
4602 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
4604 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
4607 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
4609 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
4610 ? ", quiesced" : "",
4611 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
4612 ? ", resync in progress" : "" );
4615 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
4616 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
4620 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4621 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
4625 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4626 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
4630 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
4631 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
4635 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4636 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
4638 state == MPI_PHYSDISK0_STATUS_ONLINE
4640 : state == MPI_PHYSDISK0_STATUS_MISSING
4642 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
4644 : state == MPI_PHYSDISK0_STATUS_FAILED
4646 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
4648 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
4649 ? "offline requested"
4650 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
4651 ? "failed requested"
4652 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
4655 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
4656 ? ", out of sync" : "",
4657 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
4658 ? ", quiesced" : "" );
4661 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
4662 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
4666 case MPI_EVENT_RAID_RC_SMART_DATA:
4667 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
4668 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
4671 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
4672 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
4678 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4680 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4681 * @ioc: Pointer to MPT_ADAPTER structure
4683 * Returns: 0 for success
4684 * -ENOMEM if no memory available
4685 * -EPERM if not allowed due to ISR context
4686 * -EAGAIN if no msg frames currently available
4687 * -EFAULT for non-successful reply or no reply (timeout)
4690 GetIoUnitPage2(MPT_ADAPTER *ioc)
4692 ConfigPageHeader_t hdr;
4694 IOUnitPage2_t *ppage_alloc;
4695 dma_addr_t page_dma;
4699 /* Get the page header */
4700 hdr.PageVersion = 0;
4703 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4704 cfg.cfghdr.hdr = &hdr;
4706 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4711 if ((rc = mpt_config(ioc, &cfg)) != 0)
4714 if (hdr.PageLength == 0)
4717 /* Read the config page */
4718 data_sz = hdr.PageLength * 4;
4720 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4722 memset((u8 *)ppage_alloc, 0, data_sz);
4723 cfg.physAddr = page_dma;
4724 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4726 /* If Good, save data */
4727 if ((rc = mpt_config(ioc, &cfg)) == 0)
4728 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4730 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4736 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4738 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4739 * @ioc: Pointer to a Adapter Strucutre
4740 * @portnum: IOC port number
4742 * Return: -EFAULT if read of config page header fails
4744 * If read of SCSI Port Page 0 fails,
4745 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4746 * Adapter settings: async, narrow
4748 * If read of SCSI Port Page 2 fails,
4749 * Adapter settings valid
4750 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4755 * CHECK - what type of locking mechanisms should be used????
4758 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4763 ConfigPageHeader_t header;
4769 if (!ioc->spi_data.nvram) {
4772 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4773 mem = kmalloc(sz, GFP_ATOMIC);
4777 ioc->spi_data.nvram = (int *) mem;
4779 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4780 ioc->name, ioc->spi_data.nvram, sz));
4783 /* Invalidate NVRAM information
4785 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4786 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4789 /* Read SPP0 header, allocate memory, then read page.
4791 header.PageVersion = 0;
4792 header.PageLength = 0;
4793 header.PageNumber = 0;
4794 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4795 cfg.cfghdr.hdr = &header;
4797 cfg.pageAddr = portnum;
4798 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4800 cfg.timeout = 0; /* use default */
4801 if (mpt_config(ioc, &cfg) != 0)
4804 if (header.PageLength > 0) {
4805 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4807 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4808 cfg.physAddr = buf_dma;
4809 if (mpt_config(ioc, &cfg) != 0) {
4810 ioc->spi_data.maxBusWidth = MPT_NARROW;
4811 ioc->spi_data.maxSyncOffset = 0;
4812 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4813 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4815 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4816 "Unable to read PortPage0 minSyncFactor=%x\n",
4817 ioc->name, ioc->spi_data.minSyncFactor));
4819 /* Save the Port Page 0 data
4821 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
4822 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4823 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4825 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
4826 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4827 ddvprintk(ioc, printk(KERN_INFO MYNAM
4828 " :%s noQas due to Capabilities=%x\n",
4829 ioc->name, pPP0->Capabilities));
4831 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4832 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4834 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4835 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4836 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4837 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4838 "PortPage0 minSyncFactor=%x\n",
4839 ioc->name, ioc->spi_data.minSyncFactor));
4841 ioc->spi_data.maxSyncOffset = 0;
4842 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4845 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4847 /* Update the minSyncFactor based on bus type.
4849 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4850 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
4852 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
4853 ioc->spi_data.minSyncFactor = MPT_ULTRA;
4854 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4855 "HVD or SE detected, minSyncFactor=%x\n",
4856 ioc->name, ioc->spi_data.minSyncFactor));
4861 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4866 /* SCSI Port Page 2 - Read the header then the page.
4868 header.PageVersion = 0;
4869 header.PageLength = 0;
4870 header.PageNumber = 2;
4871 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4872 cfg.cfghdr.hdr = &header;
4874 cfg.pageAddr = portnum;
4875 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4877 if (mpt_config(ioc, &cfg) != 0)
4880 if (header.PageLength > 0) {
4881 /* Allocate memory and read SCSI Port Page 2
4883 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4885 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
4886 cfg.physAddr = buf_dma;
4887 if (mpt_config(ioc, &cfg) != 0) {
4888 /* Nvram data is left with INVALID mark
4891 } else if (ioc->pcidev->vendor == PCI_VENDOR_ID_ATTO) {
4893 /* This is an ATTO adapter, read Page2 accordingly
4895 ATTO_SCSIPortPage2_t *pPP2 = (ATTO_SCSIPortPage2_t *) pbuf;
4896 ATTODeviceInfo_t *pdevice = NULL;
4899 /* Save the Port Page 2 data
4900 * (reformat into a 32bit quantity)
4902 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4903 pdevice = &pPP2->DeviceSettings[ii];
4904 ATTOFlags = le16_to_cpu(pdevice->ATTOFlags);
4907 /* Translate ATTO device flags to LSI format
4909 if (ATTOFlags & ATTOFLAG_DISC)
4910 data |= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE);
4911 if (ATTOFlags & ATTOFLAG_ID_ENB)
4912 data |= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE);
4913 if (ATTOFlags & ATTOFLAG_LUN_ENB)
4914 data |= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE);
4915 if (ATTOFlags & ATTOFLAG_TAGGED)
4916 data |= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE);
4917 if (!(ATTOFlags & ATTOFLAG_WIDE_ENB))
4918 data |= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE);
4920 data = (data << 16) | (pdevice->Period << 8) | 10;
4921 ioc->spi_data.nvram[ii] = data;
4924 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
4925 MpiDeviceInfo_t *pdevice = NULL;
4928 * Save "Set to Avoid SCSI Bus Resets" flag
4930 ioc->spi_data.bus_reset =
4931 (le32_to_cpu(pPP2->PortFlags) &
4932 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
4935 /* Save the Port Page 2 data
4936 * (reformat into a 32bit quantity)
4938 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
4939 ioc->spi_data.PortFlags = data;
4940 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4941 pdevice = &pPP2->DeviceSettings[ii];
4942 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
4943 (pdevice->SyncFactor << 8) | pdevice->Timeout;
4944 ioc->spi_data.nvram[ii] = data;
4948 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4952 /* Update Adapter limits with those from NVRAM
4953 * Comment: Don't need to do this. Target performance
4954 * parameters will never exceed the adapters limits.
4960 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4962 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
4963 * @ioc: Pointer to a Adapter Strucutre
4964 * @portnum: IOC port number
4966 * Return: -EFAULT if read of config page header fails
4970 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
4973 ConfigPageHeader_t header;
4975 /* Read the SCSI Device Page 1 header
4977 header.PageVersion = 0;
4978 header.PageLength = 0;
4979 header.PageNumber = 1;
4980 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4981 cfg.cfghdr.hdr = &header;
4983 cfg.pageAddr = portnum;
4984 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4987 if (mpt_config(ioc, &cfg) != 0)
4990 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
4991 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
4993 header.PageVersion = 0;
4994 header.PageLength = 0;
4995 header.PageNumber = 0;
4996 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4997 if (mpt_config(ioc, &cfg) != 0)
5000 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
5001 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
5003 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 0: version %d length %d\n",
5004 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
5006 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 1: version %d length %d\n",
5007 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
5012 * mpt_inactive_raid_list_free - This clears this link list.
5013 * @ioc : pointer to per adapter structure
5016 mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
5018 struct inactive_raid_component_info *component_info, *pNext;
5020 if (list_empty(&ioc->raid_data.inactive_list))
5023 down(&ioc->raid_data.inactive_list_mutex);
5024 list_for_each_entry_safe(component_info, pNext,
5025 &ioc->raid_data.inactive_list, list) {
5026 list_del(&component_info->list);
5027 kfree(component_info);
5029 up(&ioc->raid_data.inactive_list_mutex);
5033 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5035 * @ioc : pointer to per adapter structure
5036 * @channel : volume channel
5037 * @id : volume target id
5040 mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
5043 ConfigPageHeader_t hdr;
5044 dma_addr_t dma_handle;
5045 pRaidVolumePage0_t buffer = NULL;
5047 RaidPhysDiskPage0_t phys_disk;
5048 struct inactive_raid_component_info *component_info;
5049 int handle_inactive_volumes;
5051 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5052 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5053 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
5054 cfg.pageAddr = (channel << 8) + id;
5055 cfg.cfghdr.hdr = &hdr;
5056 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5058 if (mpt_config(ioc, &cfg) != 0)
5061 if (!hdr.PageLength)
5064 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5070 cfg.physAddr = dma_handle;
5071 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5073 if (mpt_config(ioc, &cfg) != 0)
5076 if (!buffer->NumPhysDisks)
5079 handle_inactive_volumes =
5080 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
5081 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
5082 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
5083 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
5085 if (!handle_inactive_volumes)
5088 down(&ioc->raid_data.inactive_list_mutex);
5089 for (i = 0; i < buffer->NumPhysDisks; i++) {
5090 if(mpt_raid_phys_disk_pg0(ioc,
5091 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
5094 if ((component_info = kmalloc(sizeof (*component_info),
5095 GFP_KERNEL)) == NULL)
5098 component_info->volumeID = id;
5099 component_info->volumeBus = channel;
5100 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
5101 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
5102 component_info->d.PhysDiskID = phys_disk.PhysDiskID;
5103 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
5105 list_add_tail(&component_info->list,
5106 &ioc->raid_data.inactive_list);
5108 up(&ioc->raid_data.inactive_list_mutex);
5112 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5117 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5118 * @ioc: Pointer to a Adapter Structure
5119 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5120 * @phys_disk: requested payload data returned
5124 * -EFAULT if read of config page header fails or data pointer not NULL
5125 * -ENOMEM if pci_alloc failed
5128 mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk)
5131 ConfigPageHeader_t hdr;
5132 dma_addr_t dma_handle;
5133 pRaidPhysDiskPage0_t buffer = NULL;
5136 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5137 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5139 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5140 cfg.cfghdr.hdr = &hdr;
5142 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5144 if (mpt_config(ioc, &cfg) != 0) {
5149 if (!hdr.PageLength) {
5154 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5162 cfg.physAddr = dma_handle;
5163 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5164 cfg.pageAddr = phys_disk_num;
5166 if (mpt_config(ioc, &cfg) != 0) {
5172 memcpy(phys_disk, buffer, sizeof(*buffer));
5173 phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
5178 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5185 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5186 * @ioc: Pointer to a Adapter Strucutre
5187 * @portnum: IOC port number
5191 * -EFAULT if read of config page header fails or data pointer not NULL
5192 * -ENOMEM if pci_alloc failed
5195 mpt_findImVolumes(MPT_ADAPTER *ioc)
5199 dma_addr_t ioc2_dma;
5201 ConfigPageHeader_t header;
5206 if (!ioc->ir_firmware)
5209 /* Free the old page
5211 kfree(ioc->raid_data.pIocPg2);
5212 ioc->raid_data.pIocPg2 = NULL;
5213 mpt_inactive_raid_list_free(ioc);
5215 /* Read IOCP2 header then the page.
5217 header.PageVersion = 0;
5218 header.PageLength = 0;
5219 header.PageNumber = 2;
5220 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5221 cfg.cfghdr.hdr = &header;
5224 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5227 if (mpt_config(ioc, &cfg) != 0)
5230 if (header.PageLength == 0)
5233 iocpage2sz = header.PageLength * 4;
5234 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
5238 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5239 cfg.physAddr = ioc2_dma;
5240 if (mpt_config(ioc, &cfg) != 0)
5243 mem = kmalloc(iocpage2sz, GFP_KERNEL);
5247 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
5248 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
5250 mpt_read_ioc_pg_3(ioc);
5252 for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
5253 mpt_inactive_raid_volumes(ioc,
5254 pIoc2->RaidVolume[i].VolumeBus,
5255 pIoc2->RaidVolume[i].VolumeID);
5258 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
5264 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
5269 ConfigPageHeader_t header;
5270 dma_addr_t ioc3_dma;
5273 /* Free the old page
5275 kfree(ioc->raid_data.pIocPg3);
5276 ioc->raid_data.pIocPg3 = NULL;
5278 /* There is at least one physical disk.
5279 * Read and save IOC Page 3
5281 header.PageVersion = 0;
5282 header.PageLength = 0;
5283 header.PageNumber = 3;
5284 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5285 cfg.cfghdr.hdr = &header;
5288 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5291 if (mpt_config(ioc, &cfg) != 0)
5294 if (header.PageLength == 0)
5297 /* Read Header good, alloc memory
5299 iocpage3sz = header.PageLength * 4;
5300 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
5304 /* Read the Page and save the data
5305 * into malloc'd memory.
5307 cfg.physAddr = ioc3_dma;
5308 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5309 if (mpt_config(ioc, &cfg) == 0) {
5310 mem = kmalloc(iocpage3sz, GFP_KERNEL);
5312 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
5313 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
5317 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
5323 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
5327 ConfigPageHeader_t header;
5328 dma_addr_t ioc4_dma;
5331 /* Read and save IOC Page 4
5333 header.PageVersion = 0;
5334 header.PageLength = 0;
5335 header.PageNumber = 4;
5336 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5337 cfg.cfghdr.hdr = &header;
5340 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5343 if (mpt_config(ioc, &cfg) != 0)
5346 if (header.PageLength == 0)
5349 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
5350 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
5351 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
5354 ioc->alloc_total += iocpage4sz;
5356 ioc4_dma = ioc->spi_data.IocPg4_dma;
5357 iocpage4sz = ioc->spi_data.IocPg4Sz;
5360 /* Read the Page into dma memory.
5362 cfg.physAddr = ioc4_dma;
5363 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5364 if (mpt_config(ioc, &cfg) == 0) {
5365 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
5366 ioc->spi_data.IocPg4_dma = ioc4_dma;
5367 ioc->spi_data.IocPg4Sz = iocpage4sz;
5369 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
5370 ioc->spi_data.pIocPg4 = NULL;
5371 ioc->alloc_total -= iocpage4sz;
5376 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
5380 ConfigPageHeader_t header;
5381 dma_addr_t ioc1_dma;
5385 /* Check the Coalescing Timeout in IOC Page 1
5387 header.PageVersion = 0;
5388 header.PageLength = 0;
5389 header.PageNumber = 1;
5390 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5391 cfg.cfghdr.hdr = &header;
5394 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5397 if (mpt_config(ioc, &cfg) != 0)
5400 if (header.PageLength == 0)
5403 /* Read Header good, alloc memory
5405 iocpage1sz = header.PageLength * 4;
5406 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
5410 /* Read the Page and check coalescing timeout
5412 cfg.physAddr = ioc1_dma;
5413 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5414 if (mpt_config(ioc, &cfg) == 0) {
5416 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
5417 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
5418 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
5420 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Coalescing Enabled Timeout = %d\n",
5423 if (tmp > MPT_COALESCING_TIMEOUT) {
5424 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
5426 /* Write NVRAM and current
5429 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5430 if (mpt_config(ioc, &cfg) == 0) {
5431 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Reset Current Coalescing Timeout to = %d\n",
5432 ioc->name, MPT_COALESCING_TIMEOUT));
5434 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
5435 if (mpt_config(ioc, &cfg) == 0) {
5436 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5437 "Reset NVRAM Coalescing Timeout to = %d\n",
5438 ioc->name, MPT_COALESCING_TIMEOUT));
5440 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5441 "Reset NVRAM Coalescing Timeout Failed\n",
5446 dprintk(ioc, printk(MYIOC_s_WARN_FMT
5447 "Reset of Current Coalescing Timeout Failed!\n",
5453 dprintk(ioc, printk(MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
5457 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
5463 mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
5466 ConfigPageHeader_t hdr;
5468 ManufacturingPage0_t *pbuf = NULL;
5470 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5471 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5473 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
5474 cfg.cfghdr.hdr = &hdr;
5476 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5479 if (mpt_config(ioc, &cfg) != 0)
5482 if (!cfg.cfghdr.hdr->PageLength)
5485 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5486 pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
5490 cfg.physAddr = buf_dma;
5492 if (mpt_config(ioc, &cfg) != 0)
5495 memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name));
5496 memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
5497 memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
5502 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
5505 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5507 * SendEventNotification - Send EventNotification (on or off) request to adapter
5508 * @ioc: Pointer to MPT_ADAPTER structure
5509 * @EvSwitch: Event switch flags
5512 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
5514 EventNotification_t *evnp;
5516 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
5518 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
5522 memset(evnp, 0, sizeof(*evnp));
5524 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
5526 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
5527 evnp->ChainOffset = 0;
5529 evnp->Switch = EvSwitch;
5531 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
5536 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5538 * SendEventAck - Send EventAck request to MPT adapter.
5539 * @ioc: Pointer to MPT_ADAPTER structure
5540 * @evnp: Pointer to original EventNotification request
5543 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
5547 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5548 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
5549 ioc->name,__FUNCTION__));
5553 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventAck\n", ioc->name));
5555 pAck->Function = MPI_FUNCTION_EVENT_ACK;
5556 pAck->ChainOffset = 0;
5557 pAck->Reserved[0] = pAck->Reserved[1] = 0;
5559 pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
5560 pAck->Event = evnp->Event;
5561 pAck->EventContext = evnp->EventContext;
5563 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
5568 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5570 * mpt_config - Generic function to issue config message
5571 * @ioc: Pointer to an adapter structure
5572 * @pCfg: Pointer to a configuration structure. Struct contains
5573 * action, page address, direction, physical address
5574 * and pointer to a configuration page header
5575 * Page header is updated.
5577 * Returns 0 for success
5578 * -EPERM if not allowed due to ISR context
5579 * -EAGAIN if no msg frames currently available
5580 * -EFAULT for non-successful reply or no reply (timeout)
5583 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5586 ConfigExtendedPageHeader_t *pExtHdr = NULL;
5588 unsigned long flags;
5593 /* Prevent calling wait_event() (below), if caller happens
5594 * to be in ISR context, because that is fatal!
5596 in_isr = in_interrupt();
5598 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
5603 /* Get and Populate a free Frame
5605 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5606 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
5610 pReq = (Config_t *)mf;
5611 pReq->Action = pCfg->action;
5613 pReq->ChainOffset = 0;
5614 pReq->Function = MPI_FUNCTION_CONFIG;
5616 /* Assume page type is not extended and clear "reserved" fields. */
5617 pReq->ExtPageLength = 0;
5618 pReq->ExtPageType = 0;
5621 for (ii=0; ii < 8; ii++)
5622 pReq->Reserved2[ii] = 0;
5624 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
5625 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
5626 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
5627 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
5629 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5630 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
5631 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
5632 pReq->ExtPageType = pExtHdr->ExtPageType;
5633 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
5635 /* Page Length must be treated as a reserved field for the extended header. */
5636 pReq->Header.PageLength = 0;
5639 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
5641 /* Add a SGE to the config request.
5644 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
5646 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
5648 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5649 flagsLength |= pExtHdr->ExtPageLength * 4;
5651 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n",
5652 ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action));
5655 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
5657 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n",
5658 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
5661 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
5663 /* Append pCfg pointer to end of mf
5665 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5667 /* Initalize the timer
5669 init_timer(&pCfg->timer);
5670 pCfg->timer.data = (unsigned long) ioc;
5671 pCfg->timer.function = mpt_timer_expired;
5672 pCfg->wait_done = 0;
5674 /* Set the timer; ensure 10 second minimum */
5675 if (pCfg->timeout < 10)
5676 pCfg->timer.expires = jiffies + HZ*10;
5678 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5680 /* Add to end of Q, set timer and then issue this command */
5681 spin_lock_irqsave(&ioc->FreeQlock, flags);
5682 list_add_tail(&pCfg->linkage, &ioc->configQ);
5683 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5685 add_timer(&pCfg->timer);
5686 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5687 wait_event(mpt_waitq, pCfg->wait_done);
5689 /* mf has been freed - do not access */
5696 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5698 * mpt_timer_expired - Callback for timer process.
5699 * Used only internal config functionality.
5700 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5703 mpt_timer_expired(unsigned long data)
5705 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
5707 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired! \n", ioc->name));
5709 /* Perform a FW reload */
5710 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
5711 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
5713 /* No more processing.
5714 * Hard reset clean-up will wake up
5715 * process and free all resources.
5717 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired complete!\n", ioc->name));
5722 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5724 * mpt_ioc_reset - Base cleanup for hard reset
5725 * @ioc: Pointer to the adapter structure
5726 * @reset_phase: Indicates pre- or post-reset functionality
5728 * Remark: Frees resources with internally generated commands.
5731 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
5734 unsigned long flags;
5736 dprintk(ioc, printk(KERN_DEBUG MYNAM
5737 ": IOC %s_reset routed to MPT base driver!\n",
5738 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
5739 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
5741 if (reset_phase == MPT_IOC_SETUP_RESET) {
5743 } else if (reset_phase == MPT_IOC_PRE_RESET) {
5744 /* If the internal config Q is not empty -
5745 * delete timer. MF resources will be freed when
5746 * the FIFO's are primed.
5748 spin_lock_irqsave(&ioc->FreeQlock, flags);
5749 list_for_each_entry(pCfg, &ioc->configQ, linkage)
5750 del_timer(&pCfg->timer);
5751 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5756 /* Search the configQ for internal commands.
5757 * Flush the Q, and wake up all suspended threads.
5759 spin_lock_irqsave(&ioc->FreeQlock, flags);
5760 list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
5761 list_del(&pCfg->linkage);
5763 pCfg->status = MPT_CONFIG_ERROR;
5764 pCfg->wait_done = 1;
5765 wake_up(&mpt_waitq);
5767 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5770 return 1; /* currently means nothing really */
5774 #ifdef CONFIG_PROC_FS /* { */
5775 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5777 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5779 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5781 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5783 * Returns 0 for success, non-zero for failure.
5786 procmpt_create(void)
5788 struct proc_dir_entry *ent;
5790 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
5791 if (mpt_proc_root_dir == NULL)
5794 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5796 ent->read_proc = procmpt_summary_read;
5798 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5800 ent->read_proc = procmpt_version_read;
5805 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5807 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5809 * Returns 0 for success, non-zero for failure.
5812 procmpt_destroy(void)
5814 remove_proc_entry("version", mpt_proc_root_dir);
5815 remove_proc_entry("summary", mpt_proc_root_dir);
5816 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
5819 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5821 * procmpt_summary_read - Handle read request of a summary file
5822 * @buf: Pointer to area to write information
5823 * @start: Pointer to start pointer
5824 * @offset: Offset to start writing
5825 * @request: Amount of read data requested
5826 * @eof: Pointer to EOF integer
5829 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
5830 * Returns number of characters written to process performing the read.
5833 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5843 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5847 list_for_each_entry(ioc, &ioc_list, list) {
5850 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5853 if ((out-buf) >= request)
5860 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5863 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5865 * procmpt_version_read - Handle read request from /proc/mpt/version.
5866 * @buf: Pointer to area to write information
5867 * @start: Pointer to start pointer
5868 * @offset: Offset to start writing
5869 * @request: Amount of read data requested
5870 * @eof: Pointer to EOF integer
5873 * Returns number of characters written to process performing the read.
5876 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5879 int scsi, fc, sas, lan, ctl, targ, dmp;
5883 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
5884 len += sprintf(buf+len, " Fusion MPT base driver\n");
5886 scsi = fc = sas = lan = ctl = targ = dmp = 0;
5887 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5889 if (MptCallbacks[ii]) {
5890 switch (MptDriverClass[ii]) {
5892 if (!scsi++) drvname = "SPI host";
5895 if (!fc++) drvname = "FC host";
5898 if (!sas++) drvname = "SAS host";
5901 if (!lan++) drvname = "LAN";
5904 if (!targ++) drvname = "SCSI target";
5907 if (!ctl++) drvname = "ioctl";
5912 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
5916 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5919 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5921 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
5922 * @buf: Pointer to area to write information
5923 * @start: Pointer to start pointer
5924 * @offset: Offset to start writing
5925 * @request: Amount of read data requested
5926 * @eof: Pointer to EOF integer
5929 * Returns number of characters written to process performing the read.
5932 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5934 MPT_ADAPTER *ioc = data;
5940 mpt_get_fw_exp_ver(expVer, ioc);
5942 len = sprintf(buf, "%s:", ioc->name);
5943 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
5944 len += sprintf(buf+len, " (f/w download boot flag set)");
5945 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
5946 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
5948 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
5949 ioc->facts.ProductID,
5951 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
5952 if (ioc->facts.FWImageSize)
5953 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
5954 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
5955 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
5956 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
5958 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
5959 ioc->facts.CurrentHostMfaHighAddr);
5960 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
5961 ioc->facts.CurrentSenseBufferHighAddr);
5963 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
5964 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
5966 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
5967 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
5969 * Rounding UP to nearest 4-kB boundary here...
5971 sz = (ioc->req_sz * ioc->req_depth) + 128;
5972 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
5973 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
5974 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
5975 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
5976 4*ioc->facts.RequestFrameSize,
5977 ioc->facts.GlobalCredits);
5979 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
5980 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
5981 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
5982 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
5983 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
5984 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
5985 ioc->facts.CurReplyFrameSize,
5986 ioc->facts.ReplyQueueDepth);
5988 len += sprintf(buf+len, " MaxDevices = %d\n",
5989 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
5990 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
5993 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
5994 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
5996 ioc->facts.NumberOfPorts);
5997 if (ioc->bus_type == FC) {
5998 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
5999 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6000 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6001 a[5], a[4], a[3], a[2], a[1], a[0]);
6003 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
6004 ioc->fc_port_page0[p].WWNN.High,
6005 ioc->fc_port_page0[p].WWNN.Low,
6006 ioc->fc_port_page0[p].WWPN.High,
6007 ioc->fc_port_page0[p].WWPN.Low);
6011 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6014 #endif /* CONFIG_PROC_FS } */
6016 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6018 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
6021 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
6022 sprintf(buf, " (Exp %02d%02d)",
6023 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
6024 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
6027 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
6028 strcat(buf, " [MDBG]");
6032 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6034 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6035 * @ioc: Pointer to MPT_ADAPTER structure
6036 * @buffer: Pointer to buffer where IOC summary info should be written
6037 * @size: Pointer to number of bytes we wrote (set by this routine)
6038 * @len: Offset at which to start writing in buffer
6039 * @showlan: Display LAN stuff?
6041 * This routine writes (english readable) ASCII text, which represents
6042 * a summary of IOC information, to a buffer.
6045 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
6050 mpt_get_fw_exp_ver(expVer, ioc);
6053 * Shorter summary of attached ioc's...
6055 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6058 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
6059 ioc->facts.FWVersion.Word,
6061 ioc->facts.NumberOfPorts,
6064 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6065 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6066 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6067 a[5], a[4], a[3], a[2], a[1], a[0]);
6070 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
6073 y += sprintf(buffer+len+y, " (disabled)");
6075 y += sprintf(buffer+len+y, "\n");
6080 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6084 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6086 * mpt_HardResetHandler - Generic reset handler
6087 * @ioc: Pointer to MPT_ADAPTER structure
6088 * @sleepFlag: Indicates if sleep or schedule must be called.
6090 * Issues SCSI Task Management call based on input arg values.
6091 * If TaskMgmt fails, returns associated SCSI request.
6093 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
6094 * or a non-interrupt thread. In the former, must not call schedule().
6096 * Note: A return of -1 is a FATAL error case, as it means a
6097 * FW reload/initialization failed.
6099 * Returns 0 for SUCCESS or -1 if FAILED.
6102 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6105 unsigned long flags;
6107 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name));
6109 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
6110 printk("MF count 0x%x !\n", ioc->mfcnt);
6113 /* Reset the adapter. Prevent more than 1 call to
6114 * mpt_do_ioc_recovery at any instant in time.
6116 spin_lock_irqsave(&ioc->diagLock, flags);
6117 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
6118 spin_unlock_irqrestore(&ioc->diagLock, flags);
6121 ioc->diagPending = 1;
6123 spin_unlock_irqrestore(&ioc->diagLock, flags);
6125 /* FIXME: If do_ioc_recovery fails, repeat....
6128 /* The SCSI driver needs to adjust timeouts on all current
6129 * commands prior to the diagnostic reset being issued.
6130 * Prevents timeouts occurring during a diagnostic reset...very bad.
6131 * For all other protocol drivers, this is a no-op.
6137 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
6138 if (MptResetHandlers[ii]) {
6139 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling IOC reset_setup handler #%d\n",
6141 r += mpt_signal_reset(ii, ioc, MPT_IOC_SETUP_RESET);
6143 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling alt-%s setup reset handler #%d\n",
6144 ioc->name, ioc->alt_ioc->name, ii));
6145 r += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_SETUP_RESET);
6151 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
6152 printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
6157 ioc->alt_ioc->reload_fw = 0;
6159 spin_lock_irqsave(&ioc->diagLock, flags);
6160 ioc->diagPending = 0;
6162 ioc->alt_ioc->diagPending = 0;
6163 spin_unlock_irqrestore(&ioc->diagLock, flags);
6165 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
6170 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6172 EventDescriptionStr(u8 event, u32 evData0, char *evStr)
6177 case MPI_EVENT_NONE:
6180 case MPI_EVENT_LOG_DATA:
6183 case MPI_EVENT_STATE_CHANGE:
6184 ds = "State Change";
6186 case MPI_EVENT_UNIT_ATTENTION:
6187 ds = "Unit Attention";
6189 case MPI_EVENT_IOC_BUS_RESET:
6190 ds = "IOC Bus Reset";
6192 case MPI_EVENT_EXT_BUS_RESET:
6193 ds = "External Bus Reset";
6195 case MPI_EVENT_RESCAN:
6196 ds = "Bus Rescan Event";
6198 case MPI_EVENT_LINK_STATUS_CHANGE:
6199 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
6200 ds = "Link Status(FAILURE) Change";
6202 ds = "Link Status(ACTIVE) Change";
6204 case MPI_EVENT_LOOP_STATE_CHANGE:
6205 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
6206 ds = "Loop State(LIP) Change";
6207 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
6208 ds = "Loop State(LPE) Change"; /* ??? */
6210 ds = "Loop State(LPB) Change"; /* ??? */
6212 case MPI_EVENT_LOGOUT:
6215 case MPI_EVENT_EVENT_CHANGE:
6221 case MPI_EVENT_INTEGRATED_RAID:
6223 u8 ReasonCode = (u8)(evData0 >> 16);
6224 switch (ReasonCode) {
6225 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
6226 ds = "Integrated Raid: Volume Created";
6228 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
6229 ds = "Integrated Raid: Volume Deleted";
6231 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
6232 ds = "Integrated Raid: Volume Settings Changed";
6234 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
6235 ds = "Integrated Raid: Volume Status Changed";
6237 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
6238 ds = "Integrated Raid: Volume Physdisk Changed";
6240 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
6241 ds = "Integrated Raid: Physdisk Created";
6243 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
6244 ds = "Integrated Raid: Physdisk Deleted";
6246 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
6247 ds = "Integrated Raid: Physdisk Settings Changed";
6249 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
6250 ds = "Integrated Raid: Physdisk Status Changed";
6252 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
6253 ds = "Integrated Raid: Domain Validation Needed";
6255 case MPI_EVENT_RAID_RC_SMART_DATA :
6256 ds = "Integrated Raid; Smart Data";
6258 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
6259 ds = "Integrated Raid: Replace Action Started";
6262 ds = "Integrated Raid";
6267 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
6268 ds = "SCSI Device Status Change";
6270 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
6272 u8 id = (u8)(evData0);
6273 u8 channel = (u8)(evData0 >> 8);
6274 u8 ReasonCode = (u8)(evData0 >> 16);
6275 switch (ReasonCode) {
6276 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
6277 snprintf(evStr, EVENT_DESCR_STR_SZ,
6278 "SAS Device Status Change: Added: "
6279 "id=%d channel=%d", id, channel);
6281 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
6282 snprintf(evStr, EVENT_DESCR_STR_SZ,
6283 "SAS Device Status Change: Deleted: "
6284 "id=%d channel=%d", id, channel);
6286 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
6287 snprintf(evStr, EVENT_DESCR_STR_SZ,
6288 "SAS Device Status Change: SMART Data: "
6289 "id=%d channel=%d", id, channel);
6291 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
6292 snprintf(evStr, EVENT_DESCR_STR_SZ,
6293 "SAS Device Status Change: No Persistancy: "
6294 "id=%d channel=%d", id, channel);
6296 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
6297 snprintf(evStr, EVENT_DESCR_STR_SZ,
6298 "SAS Device Status Change: Unsupported Device "
6299 "Discovered : id=%d channel=%d", id, channel);
6301 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
6302 snprintf(evStr, EVENT_DESCR_STR_SZ,
6303 "SAS Device Status Change: Internal Device "
6304 "Reset : id=%d channel=%d", id, channel);
6306 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
6307 snprintf(evStr, EVENT_DESCR_STR_SZ,
6308 "SAS Device Status Change: Internal Task "
6309 "Abort : id=%d channel=%d", id, channel);
6311 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
6312 snprintf(evStr, EVENT_DESCR_STR_SZ,
6313 "SAS Device Status Change: Internal Abort "
6314 "Task Set : id=%d channel=%d", id, channel);
6316 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
6317 snprintf(evStr, EVENT_DESCR_STR_SZ,
6318 "SAS Device Status Change: Internal Clear "
6319 "Task Set : id=%d channel=%d", id, channel);
6321 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
6322 snprintf(evStr, EVENT_DESCR_STR_SZ,
6323 "SAS Device Status Change: Internal Query "
6324 "Task : id=%d channel=%d", id, channel);
6327 snprintf(evStr, EVENT_DESCR_STR_SZ,
6328 "SAS Device Status Change: Unknown: "
6329 "id=%d channel=%d", id, channel);
6334 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
6335 ds = "Bus Timer Expired";
6337 case MPI_EVENT_QUEUE_FULL:
6339 u16 curr_depth = (u16)(evData0 >> 16);
6340 u8 channel = (u8)(evData0 >> 8);
6341 u8 id = (u8)(evData0);
6343 snprintf(evStr, EVENT_DESCR_STR_SZ,
6344 "Queue Full: channel=%d id=%d depth=%d",
6345 channel, id, curr_depth);
6348 case MPI_EVENT_SAS_SES:
6349 ds = "SAS SES Event";
6351 case MPI_EVENT_PERSISTENT_TABLE_FULL:
6352 ds = "Persistent Table Full";
6354 case MPI_EVENT_SAS_PHY_LINK_STATUS:
6356 u8 LinkRates = (u8)(evData0 >> 8);
6357 u8 PhyNumber = (u8)(evData0);
6358 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
6359 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
6360 switch (LinkRates) {
6361 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
6362 snprintf(evStr, EVENT_DESCR_STR_SZ,
6363 "SAS PHY Link Status: Phy=%d:"
6364 " Rate Unknown",PhyNumber);
6366 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
6367 snprintf(evStr, EVENT_DESCR_STR_SZ,
6368 "SAS PHY Link Status: Phy=%d:"
6369 " Phy Disabled",PhyNumber);
6371 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
6372 snprintf(evStr, EVENT_DESCR_STR_SZ,
6373 "SAS PHY Link Status: Phy=%d:"
6374 " Failed Speed Nego",PhyNumber);
6376 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
6377 snprintf(evStr, EVENT_DESCR_STR_SZ,
6378 "SAS PHY Link Status: Phy=%d:"
6379 " Sata OOB Completed",PhyNumber);
6381 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
6382 snprintf(evStr, EVENT_DESCR_STR_SZ,
6383 "SAS PHY Link Status: Phy=%d:"
6384 " Rate 1.5 Gbps",PhyNumber);
6386 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
6387 snprintf(evStr, EVENT_DESCR_STR_SZ,
6388 "SAS PHY Link Status: Phy=%d:"
6389 " Rate 3.0 Gpbs",PhyNumber);
6392 snprintf(evStr, EVENT_DESCR_STR_SZ,
6393 "SAS PHY Link Status: Phy=%d", PhyNumber);
6398 case MPI_EVENT_SAS_DISCOVERY_ERROR:
6399 ds = "SAS Discovery Error";
6401 case MPI_EVENT_IR_RESYNC_UPDATE:
6403 u8 resync_complete = (u8)(evData0 >> 16);
6404 snprintf(evStr, EVENT_DESCR_STR_SZ,
6405 "IR Resync Update: Complete = %d:",resync_complete);
6410 u8 ReasonCode = (u8)(evData0 >> 16);
6411 switch (ReasonCode) {
6412 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
6413 ds = "IR2: LD State Changed";
6415 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
6416 ds = "IR2: PD State Changed";
6418 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
6419 ds = "IR2: Bad Block Table Full";
6421 case MPI_EVENT_IR2_RC_PD_INSERTED:
6422 ds = "IR2: PD Inserted";
6424 case MPI_EVENT_IR2_RC_PD_REMOVED:
6425 ds = "IR2: PD Removed";
6427 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
6428 ds = "IR2: Foreign CFG Detected";
6430 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
6431 ds = "IR2: Rebuild Medium Error";
6439 case MPI_EVENT_SAS_DISCOVERY:
6442 ds = "SAS Discovery: Start";
6444 ds = "SAS Discovery: Stop";
6447 case MPI_EVENT_LOG_ENTRY_ADDED:
6448 ds = "SAS Log Entry Added";
6451 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
6453 u8 phy_num = (u8)(evData0);
6454 u8 port_num = (u8)(evData0 >> 8);
6455 u8 port_width = (u8)(evData0 >> 16);
6456 u8 primative = (u8)(evData0 >> 24);
6457 snprintf(evStr, EVENT_DESCR_STR_SZ,
6458 "SAS Broadcase Primative: phy=%d port=%d "
6459 "width=%d primative=0x%02x",
6460 phy_num, port_num, port_width, primative);
6464 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
6466 u8 reason = (u8)(evData0);
6467 u8 port_num = (u8)(evData0 >> 8);
6468 u16 handle = le16_to_cpu(evData0 >> 16);
6470 snprintf(evStr, EVENT_DESCR_STR_SZ,
6471 "SAS Initiator Device Status Change: reason=0x%02x "
6472 "port=%d handle=0x%04x",
6473 reason, port_num, handle);
6477 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
6479 u8 max_init = (u8)(evData0);
6480 u8 current_init = (u8)(evData0 >> 8);
6482 snprintf(evStr, EVENT_DESCR_STR_SZ,
6483 "SAS Initiator Device Table Overflow: max initiators=%02d "
6484 "current initators=%02d",
6485 max_init, current_init);
6488 case MPI_EVENT_SAS_SMP_ERROR:
6490 u8 status = (u8)(evData0);
6491 u8 port_num = (u8)(evData0 >> 8);
6492 u8 result = (u8)(evData0 >> 16);
6494 if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
6495 snprintf(evStr, EVENT_DESCR_STR_SZ,
6496 "SAS SMP Error: port=%d result=0x%02x",
6498 else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
6499 snprintf(evStr, EVENT_DESCR_STR_SZ,
6500 "SAS SMP Error: port=%d : CRC Error",
6502 else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
6503 snprintf(evStr, EVENT_DESCR_STR_SZ,
6504 "SAS SMP Error: port=%d : Timeout",
6506 else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
6507 snprintf(evStr, EVENT_DESCR_STR_SZ,
6508 "SAS SMP Error: port=%d : No Destination",
6510 else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
6511 snprintf(evStr, EVENT_DESCR_STR_SZ,
6512 "SAS SMP Error: port=%d : Bad Destination",
6515 snprintf(evStr, EVENT_DESCR_STR_SZ,
6516 "SAS SMP Error: port=%d : status=0x%02x",
6522 * MPT base "custom" events may be added here...
6529 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
6532 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6534 * ProcessEventNotification - Route EventNotificationReply to all event handlers
6535 * @ioc: Pointer to MPT_ADAPTER structure
6536 * @pEventReply: Pointer to EventNotification reply frame
6537 * @evHandlers: Pointer to integer, number of event handlers
6539 * Routes a received EventNotificationReply to all currently registered
6541 * Returns sum of event handlers return values.
6544 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
6552 char evStr[EVENT_DESCR_STR_SZ];
6556 * Do platform normalization of values
6558 event = le32_to_cpu(pEventReply->Event) & 0xFF;
6559 // evCtx = le32_to_cpu(pEventReply->EventContext);
6560 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
6562 evData0 = le32_to_cpu(pEventReply->Data[0]);
6565 EventDescriptionStr(event, evData0, evStr);
6566 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event:(%02Xh) : %s\n",
6571 #ifdef CONFIG_FUSION_LOGGING
6572 devtverboseprintk(ioc, printk(KERN_DEBUG MYNAM
6573 ": Event data:\n"));
6574 for (ii = 0; ii < evDataLen; ii++)
6575 devtverboseprintk(ioc, printk(" %08x",
6576 le32_to_cpu(pEventReply->Data[ii])));
6577 devtverboseprintk(ioc, printk(KERN_DEBUG "\n"));
6581 * Do general / base driver event processing
6584 case MPI_EVENT_EVENT_CHANGE: /* 0A */
6586 u8 evState = evData0 & 0xFF;
6588 /* CHECKME! What if evState unexpectedly says OFF (0)? */
6590 /* Update EventState field in cached IocFacts */
6591 if (ioc->facts.Function) {
6592 ioc->facts.EventState = evState;
6596 case MPI_EVENT_INTEGRATED_RAID:
6597 mptbase_raid_process_event_data(ioc,
6598 (MpiEventDataRaid_t *)pEventReply->Data);
6605 * Should this event be logged? Events are written sequentially.
6606 * When buffer is full, start again at the top.
6608 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
6611 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
6613 ioc->events[idx].event = event;
6614 ioc->events[idx].eventContext = ioc->eventContext;
6616 for (ii = 0; ii < 2; ii++) {
6618 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
6620 ioc->events[idx].data[ii] = 0;
6623 ioc->eventContext++;
6628 * Call each currently registered protocol event handler.
6630 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
6631 if (MptEvHandlers[ii]) {
6632 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Routing Event to event handler #%d\n",
6634 r += (*(MptEvHandlers[ii]))(ioc, pEventReply);
6638 /* FIXME? Examine results here? */
6641 * If needed, send (a single) EventAck.
6643 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
6644 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6645 "EventAck required\n",ioc->name));
6646 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
6647 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SendEventAck returned %d\n",
6652 *evHandlers = handlers;
6656 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6658 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
6659 * @ioc: Pointer to MPT_ADAPTER structure
6660 * @log_info: U32 LogInfo reply word from the IOC
6662 * Refer to lsi/mpi_log_fc.h.
6665 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
6667 char *desc = "unknown";
6669 switch (log_info & 0xFF000000) {
6670 case MPI_IOCLOGINFO_FC_INIT_BASE:
6671 desc = "FCP Initiator";
6673 case MPI_IOCLOGINFO_FC_TARGET_BASE:
6674 desc = "FCP Target";
6676 case MPI_IOCLOGINFO_FC_LAN_BASE:
6679 case MPI_IOCLOGINFO_FC_MSG_BASE:
6680 desc = "MPI Message Layer";
6682 case MPI_IOCLOGINFO_FC_LINK_BASE:
6685 case MPI_IOCLOGINFO_FC_CTX_BASE:
6686 desc = "Context Manager";
6688 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
6689 desc = "Invalid Field Offset";
6691 case MPI_IOCLOGINFO_FC_STATE_CHANGE:
6692 desc = "State Change Info";
6696 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
6697 ioc->name, log_info, desc, (log_info & 0xFFFFFF));
6700 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6702 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
6703 * @ioc: Pointer to MPT_ADAPTER structure
6704 * @mr: Pointer to MPT reply frame
6705 * @log_info: U32 LogInfo word from the IOC
6707 * Refer to lsi/sp_log.h.
6710 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
6712 u32 info = log_info & 0x00FF0000;
6713 char *desc = "unknown";
6717 desc = "bug! MID not found";
6718 if (ioc->reload_fw == 0)
6723 desc = "Parity Error";
6727 desc = "ASYNC Outbound Overrun";
6731 desc = "SYNC Offset Error";
6739 desc = "Msg In Overflow";
6747 desc = "Outbound DMA Overrun";
6751 desc = "Task Management";
6755 desc = "Device Problem";
6759 desc = "Invalid Phase Change";
6763 desc = "Untagged Table Size";
6768 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
6771 /* strings for sas loginfo */
6772 static char *originator_str[] = {
6777 static char *iop_code_str[] = {
6779 "Invalid SAS Address", /* 01h */
6781 "Invalid Page", /* 03h */
6782 "Diag Message Error", /* 04h */
6783 "Task Terminated", /* 05h */
6784 "Enclosure Management", /* 06h */
6785 "Target Mode" /* 07h */
6787 static char *pl_code_str[] = {
6789 "Open Failure", /* 01h */
6790 "Invalid Scatter Gather List", /* 02h */
6791 "Wrong Relative Offset or Frame Length", /* 03h */
6792 "Frame Transfer Error", /* 04h */
6793 "Transmit Frame Connected Low", /* 05h */
6794 "SATA Non-NCQ RW Error Bit Set", /* 06h */
6795 "SATA Read Log Receive Data Error", /* 07h */
6796 "SATA NCQ Fail All Commands After Error", /* 08h */
6797 "SATA Error in Receive Set Device Bit FIS", /* 09h */
6798 "Receive Frame Invalid Message", /* 0Ah */
6799 "Receive Context Message Valid Error", /* 0Bh */
6800 "Receive Frame Current Frame Error", /* 0Ch */
6801 "SATA Link Down", /* 0Dh */
6802 "Discovery SATA Init W IOS", /* 0Eh */
6803 "Config Invalid Page", /* 0Fh */
6804 "Discovery SATA Init Timeout", /* 10h */
6807 "IO Not Yet Executed", /* 13h */
6808 "IO Executed", /* 14h */
6809 "Persistent Reservation Out Not Affiliation "
6811 "Open Transmit DMA Abort", /* 16h */
6812 "IO Device Missing Delay Retry", /* 17h */
6813 "IO Cancelled Due to Recieve Error", /* 18h */
6821 "Enclosure Management" /* 20h */
6823 static char *ir_code_str[] = {
6824 "Raid Action Error", /* 00h */
6834 static char *raid_sub_code_str[] = {
6836 "Volume Creation Failed: Data Passed too "
6838 "Volume Creation Failed: Duplicate Volumes "
6839 "Attempted", /* 02h */
6840 "Volume Creation Failed: Max Number "
6841 "Supported Volumes Exceeded", /* 03h */
6842 "Volume Creation Failed: DMA Error", /* 04h */
6843 "Volume Creation Failed: Invalid Volume Type", /* 05h */
6844 "Volume Creation Failed: Error Reading "
6845 "MFG Page 4", /* 06h */
6846 "Volume Creation Failed: Creating Internal "
6847 "Structures", /* 07h */
6856 "Activation failed: Already Active Volume", /* 10h */
6857 "Activation failed: Unsupported Volume Type", /* 11h */
6858 "Activation failed: Too Many Active Volumes", /* 12h */
6859 "Activation failed: Volume ID in Use", /* 13h */
6860 "Activation failed: Reported Failure", /* 14h */
6861 "Activation failed: Importing a Volume", /* 15h */
6872 "Phys Disk failed: Too Many Phys Disks", /* 20h */
6873 "Phys Disk failed: Data Passed too Large", /* 21h */
6874 "Phys Disk failed: DMA Error", /* 22h */
6875 "Phys Disk failed: Invalid <channel:id>", /* 23h */
6876 "Phys Disk failed: Creating Phys Disk Config "
6889 "Compatibility Error: IR Disabled", /* 30h */
6890 "Compatibility Error: Inquiry Comand Failed", /* 31h */
6891 "Compatibility Error: Device not Direct Access "
6892 "Device ", /* 32h */
6893 "Compatibility Error: Removable Device Found", /* 33h */
6894 "Compatibility Error: Device SCSI Version not "
6895 "2 or Higher", /* 34h */
6896 "Compatibility Error: SATA Device, 48 BIT LBA "
6897 "not Supported", /* 35h */
6898 "Compatibility Error: Device doesn't have "
6899 "512 Byte Block Sizes", /* 36h */
6900 "Compatibility Error: Volume Type Check Failed", /* 37h */
6901 "Compatibility Error: Volume Type is "
6902 "Unsupported by FW", /* 38h */
6903 "Compatibility Error: Disk Drive too Small for "
6904 "use in Volume", /* 39h */
6905 "Compatibility Error: Phys Disk for Create "
6906 "Volume not Found", /* 3Ah */
6907 "Compatibility Error: Too Many or too Few "
6908 "Disks for Volume Type", /* 3Bh */
6909 "Compatibility Error: Disk stripe Sizes "
6910 "Must be 64KB", /* 3Ch */
6911 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
6914 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6916 * mpt_sas_log_info - Log information returned from SAS IOC.
6917 * @ioc: Pointer to MPT_ADAPTER structure
6918 * @log_info: U32 LogInfo reply word from the IOC
6920 * Refer to lsi/mpi_log_sas.h.
6923 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
6925 union loginfo_type {
6934 union loginfo_type sas_loginfo;
6935 char *originator_desc = NULL;
6936 char *code_desc = NULL;
6937 char *sub_code_desc = NULL;
6939 sas_loginfo.loginfo = log_info;
6940 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
6941 (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
6944 originator_desc = originator_str[sas_loginfo.dw.originator];
6946 switch (sas_loginfo.dw.originator) {
6949 if (sas_loginfo.dw.code <
6950 sizeof(iop_code_str)/sizeof(char*))
6951 code_desc = iop_code_str[sas_loginfo.dw.code];
6954 if (sas_loginfo.dw.code <
6955 sizeof(pl_code_str)/sizeof(char*))
6956 code_desc = pl_code_str[sas_loginfo.dw.code];
6959 if (sas_loginfo.dw.code >=
6960 sizeof(ir_code_str)/sizeof(char*))
6962 code_desc = ir_code_str[sas_loginfo.dw.code];
6963 if (sas_loginfo.dw.subcode >=
6964 sizeof(raid_sub_code_str)/sizeof(char*))
6966 if (sas_loginfo.dw.code == 0)
6968 raid_sub_code_str[sas_loginfo.dw.subcode];
6974 if (sub_code_desc != NULL)
6975 printk(MYIOC_s_INFO_FMT
6976 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
6978 ioc->name, log_info, originator_desc, code_desc,
6980 else if (code_desc != NULL)
6981 printk(MYIOC_s_INFO_FMT
6982 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
6983 " SubCode(0x%04x)\n",
6984 ioc->name, log_info, originator_desc, code_desc,
6985 sas_loginfo.dw.subcode);
6987 printk(MYIOC_s_INFO_FMT
6988 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
6989 " SubCode(0x%04x)\n",
6990 ioc->name, log_info, originator_desc,
6991 sas_loginfo.dw.code, sas_loginfo.dw.subcode);
6994 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6996 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
6997 * @ioc: Pointer to MPT_ADAPTER structure
6998 * @ioc_status: U32 IOCStatus word from IOC
6999 * @mf: Pointer to MPT request frame
7001 * Refer to lsi/mpi.h.
7004 mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7006 Config_t *pReq = (Config_t *)mf;
7007 char extend_desc[EVENT_DESCR_STR_SZ];
7012 if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
7013 page_type = pReq->ExtPageType;
7015 page_type = pReq->Header.PageType;
7018 * ignore invalid page messages for GET_NEXT_HANDLE
7020 form = le32_to_cpu(pReq->PageAddress);
7021 if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
7022 if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
7023 page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
7024 page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
7025 if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
7026 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
7029 if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
7030 if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
7031 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
7035 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
7036 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
7037 page_type, pReq->Header.PageNumber, pReq->Action, form);
7039 switch (ioc_status) {
7041 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7042 desc = "Config Page Invalid Action";
7045 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7046 desc = "Config Page Invalid Type";
7049 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7050 desc = "Config Page Invalid Page";
7053 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7054 desc = "Config Page Invalid Data";
7057 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7058 desc = "Config Page No Defaults";
7061 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7062 desc = "Config Page Can't Commit";
7069 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s: %s\n",
7070 ioc->name, ioc_status, desc, extend_desc);
7074 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
7075 * @ioc: Pointer to MPT_ADAPTER structure
7076 * @ioc_status: U32 IOCStatus word from IOC
7077 * @mf: Pointer to MPT request frame
7079 * Refer to lsi/mpi.h.
7082 mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7084 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
7089 /****************************************************************************/
7090 /* Common IOCStatus values for all replies */
7091 /****************************************************************************/
7093 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
7094 desc = "Invalid Function";
7097 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
7101 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
7102 desc = "Invalid SGL";
7105 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
7106 desc = "Internal Error";
7109 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
7113 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
7114 desc = "Insufficient Resources";
7117 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
7118 desc = "Invalid Field";
7121 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
7122 desc = "Invalid State";
7125 /****************************************************************************/
7126 /* Config IOCStatus values */
7127 /****************************************************************************/
7129 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7130 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7131 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7132 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7133 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7134 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7135 mpt_iocstatus_info_config(ioc, status, mf);
7138 /****************************************************************************/
7139 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
7141 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
7143 /****************************************************************************/
7145 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
7146 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
7147 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
7148 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
7149 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
7150 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
7151 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
7152 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
7153 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
7154 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
7155 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
7156 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
7157 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
7160 /****************************************************************************/
7161 /* SCSI Target values */
7162 /****************************************************************************/
7164 case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
7165 desc = "Target: Priority IO";
7168 case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
7169 desc = "Target: Invalid Port";
7172 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
7173 desc = "Target Invalid IO Index:";
7176 case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
7177 desc = "Target: Aborted";
7180 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
7181 desc = "Target: No Conn Retryable";
7184 case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
7185 desc = "Target: No Connection";
7188 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
7189 desc = "Target: Transfer Count Mismatch";
7192 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
7193 desc = "Target: STS Data not Sent";
7196 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
7197 desc = "Target: Data Offset Error";
7200 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
7201 desc = "Target: Too Much Write Data";
7204 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
7205 desc = "Target: IU Too Short";
7208 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
7209 desc = "Target: ACK NAK Timeout";
7212 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
7213 desc = "Target: Nak Received";
7216 /****************************************************************************/
7217 /* Fibre Channel Direct Access values */
7218 /****************************************************************************/
7220 case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
7221 desc = "FC: Aborted";
7224 case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
7225 desc = "FC: RX ID Invalid";
7228 case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
7229 desc = "FC: DID Invalid";
7232 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
7233 desc = "FC: Node Logged Out";
7236 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
7237 desc = "FC: Exchange Canceled";
7240 /****************************************************************************/
7242 /****************************************************************************/
7244 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
7245 desc = "LAN: Device not Found";
7248 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
7249 desc = "LAN: Device Failure";
7252 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
7253 desc = "LAN: Transmit Error";
7256 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
7257 desc = "LAN: Transmit Aborted";
7260 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
7261 desc = "LAN: Receive Error";
7264 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
7265 desc = "LAN: Receive Aborted";
7268 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
7269 desc = "LAN: Partial Packet";
7272 case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
7273 desc = "LAN: Canceled";
7276 /****************************************************************************/
7277 /* Serial Attached SCSI values */
7278 /****************************************************************************/
7280 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
7281 desc = "SAS: SMP Request Failed";
7284 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
7285 desc = "SAS: SMP Data Overrun";
7296 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s\n", ioc->name, status, desc);
7299 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7300 EXPORT_SYMBOL(mpt_attach);
7301 EXPORT_SYMBOL(mpt_detach);
7303 EXPORT_SYMBOL(mpt_resume);
7304 EXPORT_SYMBOL(mpt_suspend);
7306 EXPORT_SYMBOL(ioc_list);
7307 EXPORT_SYMBOL(mpt_proc_root_dir);
7308 EXPORT_SYMBOL(mpt_register);
7309 EXPORT_SYMBOL(mpt_deregister);
7310 EXPORT_SYMBOL(mpt_event_register);
7311 EXPORT_SYMBOL(mpt_event_deregister);
7312 EXPORT_SYMBOL(mpt_reset_register);
7313 EXPORT_SYMBOL(mpt_reset_deregister);
7314 EXPORT_SYMBOL(mpt_device_driver_register);
7315 EXPORT_SYMBOL(mpt_device_driver_deregister);
7316 EXPORT_SYMBOL(mpt_get_msg_frame);
7317 EXPORT_SYMBOL(mpt_put_msg_frame);
7318 EXPORT_SYMBOL(mpt_free_msg_frame);
7319 EXPORT_SYMBOL(mpt_add_sge);
7320 EXPORT_SYMBOL(mpt_send_handshake_request);
7321 EXPORT_SYMBOL(mpt_verify_adapter);
7322 EXPORT_SYMBOL(mpt_GetIocState);
7323 EXPORT_SYMBOL(mpt_print_ioc_summary);
7324 EXPORT_SYMBOL(mpt_lan_index);
7325 EXPORT_SYMBOL(mpt_stm_index);
7326 EXPORT_SYMBOL(mpt_HardResetHandler);
7327 EXPORT_SYMBOL(mpt_config);
7328 EXPORT_SYMBOL(mpt_findImVolumes);
7329 EXPORT_SYMBOL(mpt_alloc_fw_memory);
7330 EXPORT_SYMBOL(mpt_free_fw_memory);
7331 EXPORT_SYMBOL(mptbase_sas_persist_operation);
7332 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
7334 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7336 * fusion_init - Fusion MPT base driver initialization routine.
7338 * Returns 0 for success, non-zero for failure.
7345 show_mptmod_ver(my_NAME, my_VERSION);
7346 printk(KERN_INFO COPYRIGHT "\n");
7348 for (i = 0; i < MPT_MAX_PROTOCOL_DRIVERS; i++) {
7349 MptCallbacks[i] = NULL;
7350 MptDriverClass[i] = MPTUNKNOWN_DRIVER;
7351 MptEvHandlers[i] = NULL;
7352 MptResetHandlers[i] = NULL;
7355 /* Register ourselves (mptbase) in order to facilitate
7356 * EventNotification handling.
7358 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
7360 /* Register for hard reset handling callbacks.
7362 mpt_reset_register(mpt_base_index, mpt_ioc_reset);
7364 #ifdef CONFIG_PROC_FS
7365 (void) procmpt_create();
7370 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7372 * fusion_exit - Perform driver unload cleanup.
7374 * This routine frees all resources associated with each MPT adapter
7375 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
7381 mpt_reset_deregister(mpt_base_index);
7383 #ifdef CONFIG_PROC_FS
7388 module_init(fusion_init);
7389 module_exit(fusion_exit);