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);
846 * mpt_put_msg_frame_hi_pri - Send a protocol specific MPT request frame
847 * to a IOC using hi priority request queue.
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 posts a MPT request frame to the request post FIFO of a
853 * specific MPT adapter.
856 mpt_put_msg_frame_hi_pri(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
860 u16 req_idx; /* Request index */
862 /* ensure values are reset properly! */
863 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;
864 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
865 req_idx = req_offset / ioc->req_sz;
866 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
867 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
869 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
871 mf_dma_addr = (ioc->req_frames_low_dma + req_offset);
872 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d\n",
873 ioc->name, mf_dma_addr, req_idx));
874 CHIPREG_WRITE32(&ioc->chip->RequestHiPriFifo, mf_dma_addr);
877 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
879 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
880 * @handle: Handle of registered MPT protocol driver
881 * @ioc: Pointer to MPT adapter structure
882 * @mf: Pointer to MPT request frame
884 * This routine places a MPT request frame back on the MPT adapter's
888 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
892 /* Put Request back on FreeQ! */
893 spin_lock_irqsave(&ioc->FreeQlock, flags);
894 mf->u.frame.linkage.arg1 = 0xdeadbeaf; /* signature to know if this mf is freed */
895 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
899 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
902 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
904 * mpt_add_sge - Place a simple SGE at address pAddr.
905 * @pAddr: virtual address for SGE
906 * @flagslength: SGE flags and data transfer length
907 * @dma_addr: Physical address
909 * This routine places a MPT request frame back on the MPT adapter's
913 mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
915 if (sizeof(dma_addr_t) == sizeof(u64)) {
916 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
917 u32 tmp = dma_addr & 0xFFFFFFFF;
919 pSge->FlagsLength = cpu_to_le32(flagslength);
920 pSge->Address.Low = cpu_to_le32(tmp);
921 tmp = (u32) ((u64)dma_addr >> 32);
922 pSge->Address.High = cpu_to_le32(tmp);
925 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
926 pSge->FlagsLength = cpu_to_le32(flagslength);
927 pSge->Address = cpu_to_le32(dma_addr);
931 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
933 * mpt_send_handshake_request - Send MPT request via doorbell handshake method.
934 * @handle: Handle of registered MPT protocol driver
935 * @ioc: Pointer to MPT adapter structure
936 * @reqBytes: Size of the request in bytes
937 * @req: Pointer to MPT request frame
938 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
940 * This routine is used exclusively to send MptScsiTaskMgmt
941 * requests since they are required to be sent via doorbell handshake.
943 * NOTE: It is the callers responsibility to byte-swap fields in the
944 * request which are greater than 1 byte in size.
946 * Returns 0 for success, non-zero for failure.
949 mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
955 /* State is known to be good upon entering
956 * this function so issue the bus reset
961 * Emulate what mpt_put_msg_frame() does /wrt to sanity
962 * setting cb_idx/req_idx. But ONLY if this request
963 * is in proper (pre-alloc'd) request buffer range...
965 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
966 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
967 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
968 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
969 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;
972 /* Make sure there are no doorbells */
973 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
975 CHIPREG_WRITE32(&ioc->chip->Doorbell,
976 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
977 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
979 /* Wait for IOC doorbell int */
980 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
984 /* Read doorbell and check for active bit */
985 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
988 dhsprintk(ioc, printk(KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
991 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
993 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
997 /* Send request via doorbell handshake */
998 req_as_bytes = (u8 *) req;
999 for (ii = 0; ii < reqBytes/4; ii++) {
1002 word = ((req_as_bytes[(ii*4) + 0] << 0) |
1003 (req_as_bytes[(ii*4) + 1] << 8) |
1004 (req_as_bytes[(ii*4) + 2] << 16) |
1005 (req_as_bytes[(ii*4) + 3] << 24));
1006 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
1007 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1013 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
1018 /* Make sure there are no doorbells */
1019 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1024 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1026 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
1027 * @ioc: Pointer to MPT adapter structure
1028 * @access_control_value: define bits below
1029 * @sleepFlag: Specifies whether the process can sleep
1031 * Provides mechanism for the host driver to control the IOC's
1032 * Host Page Buffer access.
1034 * Access Control Value - bits[15:12]
1036 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1037 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1038 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1040 * Returns 0 for success, non-zero for failure.
1044 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1048 /* return if in use */
1049 if (CHIPREG_READ32(&ioc->chip->Doorbell)
1050 & MPI_DOORBELL_ACTIVE)
1053 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1055 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1056 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1057 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1058 (access_control_value<<12)));
1060 /* Wait for IOC to clear Doorbell Status bit */
1061 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1067 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1069 * mpt_host_page_alloc - allocate system memory for the fw
1070 * @ioc: Pointer to pointer to IOC adapter
1071 * @ioc_init: Pointer to ioc init config page
1073 * If we already allocated memory in past, then resend the same pointer.
1074 * Returns 0 for success, non-zero for failure.
1077 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1081 u32 host_page_buffer_sz=0;
1083 if(!ioc->HostPageBuffer) {
1085 host_page_buffer_sz =
1086 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1088 if(!host_page_buffer_sz)
1089 return 0; /* fw doesn't need any host buffers */
1091 /* spin till we get enough memory */
1092 while(host_page_buffer_sz > 0) {
1094 if((ioc->HostPageBuffer = pci_alloc_consistent(
1096 host_page_buffer_sz,
1097 &ioc->HostPageBuffer_dma)) != NULL) {
1099 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1100 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1101 ioc->name, ioc->HostPageBuffer,
1102 (u32)ioc->HostPageBuffer_dma,
1103 host_page_buffer_sz));
1104 ioc->alloc_total += host_page_buffer_sz;
1105 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1109 host_page_buffer_sz -= (4*1024);
1113 if(!ioc->HostPageBuffer) {
1114 printk(MYIOC_s_ERR_FMT
1115 "Failed to alloc memory for host_page_buffer!\n",
1120 psge = (char *)&ioc_init->HostPageBufferSGE;
1121 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1122 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1123 MPI_SGE_FLAGS_32_BIT_ADDRESSING |
1124 MPI_SGE_FLAGS_HOST_TO_IOC |
1125 MPI_SGE_FLAGS_END_OF_BUFFER;
1126 if (sizeof(dma_addr_t) == sizeof(u64)) {
1127 flags_length |= MPI_SGE_FLAGS_64_BIT_ADDRESSING;
1129 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1130 flags_length |= ioc->HostPageBuffer_sz;
1131 mpt_add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1132 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1137 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1139 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1140 * @iocid: IOC unique identifier (integer)
1141 * @iocpp: Pointer to pointer to IOC adapter
1143 * Given a unique IOC identifier, set pointer to the associated MPT
1144 * adapter structure.
1146 * Returns iocid and sets iocpp if iocid is found.
1147 * Returns -1 if iocid is not found.
1150 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1154 list_for_each_entry(ioc,&ioc_list,list) {
1155 if (ioc->id == iocid) {
1166 * mpt_get_product_name - returns product string
1167 * @vendor: pci vendor id
1168 * @device: pci device id
1169 * @revision: pci revision id
1170 * @prod_name: string returned
1172 * Returns product string displayed when driver loads,
1173 * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1177 mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name)
1179 char *product_str = NULL;
1181 if (vendor == PCI_VENDOR_ID_BROCADE) {
1184 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1188 product_str = "BRE040 A0";
1191 product_str = "BRE040 A1";
1194 product_str = "BRE040";
1204 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1205 product_str = "LSIFC909 B1";
1207 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1208 product_str = "LSIFC919 B0";
1210 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1211 product_str = "LSIFC929 B0";
1213 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1214 if (revision < 0x80)
1215 product_str = "LSIFC919X A0";
1217 product_str = "LSIFC919XL A1";
1219 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1220 if (revision < 0x80)
1221 product_str = "LSIFC929X A0";
1223 product_str = "LSIFC929XL A1";
1225 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1226 product_str = "LSIFC939X A1";
1228 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1229 product_str = "LSIFC949X A1";
1231 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1235 product_str = "LSIFC949E A0";
1238 product_str = "LSIFC949E A1";
1241 product_str = "LSIFC949E";
1245 case MPI_MANUFACTPAGE_DEVID_53C1030:
1249 product_str = "LSI53C1030 A0";
1252 product_str = "LSI53C1030 B0";
1255 product_str = "LSI53C1030 B1";
1258 product_str = "LSI53C1030 B2";
1261 product_str = "LSI53C1030 C0";
1264 product_str = "LSI53C1030T A0";
1267 product_str = "LSI53C1030T A2";
1270 product_str = "LSI53C1030T A3";
1273 product_str = "LSI53C1020A A1";
1276 product_str = "LSI53C1030";
1280 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1284 product_str = "LSI53C1035 A2";
1287 product_str = "LSI53C1035 B0";
1290 product_str = "LSI53C1035";
1294 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1298 product_str = "LSISAS1064 A1";
1301 product_str = "LSISAS1064 A2";
1304 product_str = "LSISAS1064 A3";
1307 product_str = "LSISAS1064 A4";
1310 product_str = "LSISAS1064";
1314 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1318 product_str = "LSISAS1064E A0";
1321 product_str = "LSISAS1064E B0";
1324 product_str = "LSISAS1064E B1";
1327 product_str = "LSISAS1064E B2";
1330 product_str = "LSISAS1064E B3";
1333 product_str = "LSISAS1064E";
1337 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1341 product_str = "LSISAS1068 A0";
1344 product_str = "LSISAS1068 B0";
1347 product_str = "LSISAS1068 B1";
1350 product_str = "LSISAS1068";
1354 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1358 product_str = "LSISAS1068E A0";
1361 product_str = "LSISAS1068E B0";
1364 product_str = "LSISAS1068E B1";
1367 product_str = "LSISAS1068E B2";
1370 product_str = "LSISAS1068E B3";
1373 product_str = "LSISAS1068E";
1377 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1381 product_str = "LSISAS1078 A0";
1384 product_str = "LSISAS1078 B0";
1387 product_str = "LSISAS1078 C0";
1390 product_str = "LSISAS1078 C1";
1393 product_str = "LSISAS1078 C2";
1396 product_str = "LSISAS1078";
1404 sprintf(prod_name, "%s", product_str);
1407 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1409 * mpt_attach - Install a PCI intelligent MPT adapter.
1410 * @pdev: Pointer to pci_dev structure
1411 * @id: PCI device ID information
1413 * This routine performs all the steps necessary to bring the IOC of
1414 * a MPT adapter to a OPERATIONAL state. This includes registering
1415 * memory regions, registering the interrupt, and allocating request
1416 * and reply memory pools.
1418 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1421 * Returns 0 for success, non-zero for failure.
1423 * TODO: Add support for polled controllers
1426 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1430 unsigned long mem_phys;
1438 static int mpt_ids = 0;
1439 #ifdef CONFIG_PROC_FS
1440 struct proc_dir_entry *dent, *ent;
1443 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1445 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1449 ioc->debug_level = mpt_debug_level;
1450 if (mpt_debug_level)
1451 printk(KERN_INFO MYNAM ": mpt_debug_level=%xh\n", mpt_debug_level);
1453 if (pci_enable_device(pdev))
1456 dinitprintk(ioc, printk(KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1458 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
1459 dprintk(ioc, printk(KERN_INFO MYNAM
1460 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n"));
1461 } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
1462 printk(KERN_WARNING MYNAM ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");
1466 if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
1467 dprintk(ioc, printk(KERN_INFO MYNAM
1468 ": Using 64 bit consistent mask\n"));
1470 dprintk(ioc, printk(KERN_INFO MYNAM
1471 ": Not using 64 bit consistent mask\n"));
1474 ioc->alloc_total = sizeof(MPT_ADAPTER);
1475 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1476 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1479 ioc->diagPending = 0;
1480 spin_lock_init(&ioc->diagLock);
1481 spin_lock_init(&ioc->initializing_hba_lock);
1483 /* Initialize the event logging.
1485 ioc->eventTypes = 0; /* None */
1486 ioc->eventContext = 0;
1487 ioc->eventLogSize = 0;
1494 ioc->cached_fw = NULL;
1496 /* Initilize SCSI Config Data structure
1498 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1500 /* Initialize the running configQ head.
1502 INIT_LIST_HEAD(&ioc->configQ);
1504 /* Initialize the fc rport list head.
1506 INIT_LIST_HEAD(&ioc->fc_rports);
1508 /* Find lookup slot. */
1509 INIT_LIST_HEAD(&ioc->list);
1510 ioc->id = mpt_ids++;
1512 mem_phys = msize = 0;
1514 for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1515 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1518 /* Get I/O space! */
1519 port = pci_resource_start(pdev, ii);
1520 psize = pci_resource_len(pdev,ii);
1525 mem_phys = pci_resource_start(pdev, ii);
1526 msize = pci_resource_len(pdev,ii);
1529 ioc->mem_size = msize;
1532 /* Get logical ptr for PciMem0 space */
1533 /*mem = ioremap(mem_phys, msize);*/
1534 mem = ioremap(mem_phys, msize);
1536 printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n");
1541 dinitprintk(ioc, printk(KERN_INFO MYNAM ": mem = %p, mem_phys = %lx\n", mem, mem_phys));
1543 dinitprintk(ioc, printk(KERN_INFO MYNAM ": facts @ %p, pfacts[0] @ %p\n",
1544 &ioc->facts, &ioc->pfacts[0]));
1546 ioc->mem_phys = mem_phys;
1547 ioc->chip = (SYSIF_REGS __iomem *)mem;
1549 /* Save Port IO values in case we need to do downloadboot */
1551 u8 *pmem = (u8*)port;
1552 ioc->pio_mem_phys = port;
1553 ioc->pio_chip = (SYSIF_REGS __iomem *)pmem;
1556 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1557 mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name);
1559 switch (pdev->device)
1561 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1562 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1563 ioc->errata_flag_1064 = 1;
1564 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1565 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1566 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1567 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1571 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1572 if (revision < XL_929) {
1573 /* 929X Chip Fix. Set Split transactions level
1574 * for PCIX. Set MOST bits to zero.
1576 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1578 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1580 /* 929XL Chip Fix. Set MMRBC to 0x08.
1582 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1584 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1589 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1590 /* 919X Chip Fix. Set Split transactions level
1591 * for PCIX. Set MOST bits to zero.
1593 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1595 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1599 case MPI_MANUFACTPAGE_DEVID_53C1030:
1600 /* 1030 Chip Fix. Disable Split transactions
1601 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1603 if (revision < C0_1030) {
1604 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1606 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1609 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1610 ioc->bus_type = SPI;
1613 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1614 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1615 ioc->errata_flag_1064 = 1;
1617 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1618 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1619 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1620 ioc->bus_type = SAS;
1623 if (ioc->errata_flag_1064)
1624 pci_disable_io_access(pdev);
1626 sprintf(ioc->name, "ioc%d", ioc->id);
1628 spin_lock_init(&ioc->FreeQlock);
1631 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1633 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1635 /* Set lookup ptr. */
1636 list_add_tail(&ioc->list, &ioc_list);
1638 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1640 mpt_detect_bound_ports(ioc, pdev);
1642 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1644 printk(KERN_WARNING MYNAM
1645 ": WARNING - %s did not initialize properly! (%d)\n",
1648 list_del(&ioc->list);
1650 ioc->alt_ioc->alt_ioc = NULL;
1653 pci_set_drvdata(pdev, NULL);
1657 /* call per device driver probe entry point */
1658 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1659 if(MptDeviceDriverHandlers[ii] &&
1660 MptDeviceDriverHandlers[ii]->probe) {
1661 MptDeviceDriverHandlers[ii]->probe(pdev,id);
1665 #ifdef CONFIG_PROC_FS
1667 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1669 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1671 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1673 ent->read_proc = procmpt_iocinfo_read;
1676 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1678 ent->read_proc = procmpt_summary_read;
1687 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1689 * mpt_detach - Remove a PCI intelligent MPT adapter.
1690 * @pdev: Pointer to pci_dev structure
1694 mpt_detach(struct pci_dev *pdev)
1696 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1700 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
1701 remove_proc_entry(pname, NULL);
1702 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
1703 remove_proc_entry(pname, NULL);
1704 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
1705 remove_proc_entry(pname, NULL);
1707 /* call per device driver remove entry point */
1708 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1709 if(MptDeviceDriverHandlers[ii] &&
1710 MptDeviceDriverHandlers[ii]->remove) {
1711 MptDeviceDriverHandlers[ii]->remove(pdev);
1715 /* Disable interrupts! */
1716 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1719 synchronize_irq(pdev->irq);
1721 /* Clear any lingering interrupt */
1722 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1724 CHIPREG_READ32(&ioc->chip->IntStatus);
1726 mpt_adapter_dispose(ioc);
1728 pci_set_drvdata(pdev, NULL);
1731 /**************************************************************************
1735 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1737 * mpt_suspend - Fusion MPT base driver suspend routine.
1738 * @pdev: Pointer to pci_dev structure
1739 * @state: new state to enter
1742 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
1745 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1747 device_state=pci_choose_state(pdev, state);
1749 printk(MYIOC_s_INFO_FMT
1750 "pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
1751 ioc->name, pdev, pci_name(pdev), device_state);
1753 pci_save_state(pdev);
1755 /* put ioc into READY_STATE */
1756 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
1757 printk(MYIOC_s_ERR_FMT
1758 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
1761 /* disable interrupts */
1762 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1765 /* Clear any lingering interrupt */
1766 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1768 pci_disable_device(pdev);
1769 pci_set_power_state(pdev, device_state);
1774 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1776 * mpt_resume - Fusion MPT base driver resume routine.
1777 * @pdev: Pointer to pci_dev structure
1780 mpt_resume(struct pci_dev *pdev)
1782 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1783 u32 device_state = pdev->current_state;
1787 printk(MYIOC_s_INFO_FMT
1788 "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
1789 ioc->name, pdev, pci_name(pdev), device_state);
1791 pci_set_power_state(pdev, 0);
1792 pci_restore_state(pdev);
1793 err = pci_enable_device(pdev);
1797 /* enable interrupts */
1798 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
1801 printk(MYIOC_s_INFO_FMT
1802 "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1804 (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1805 CHIPREG_READ32(&ioc->chip->Doorbell));
1807 /* bring ioc to operational state */
1808 if ((recovery_state = mpt_do_ioc_recovery(ioc,
1809 MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {
1810 printk(MYIOC_s_INFO_FMT
1811 "pci-resume: Cannot recover, error:[%x]\n",
1812 ioc->name, recovery_state);
1814 printk(MYIOC_s_INFO_FMT
1815 "pci-resume: success\n", ioc->name);
1823 mpt_signal_reset(int index, MPT_ADAPTER *ioc, int reset_phase)
1825 if ((MptDriverClass[index] == MPTSPI_DRIVER &&
1826 ioc->bus_type != SPI) ||
1827 (MptDriverClass[index] == MPTFC_DRIVER &&
1828 ioc->bus_type != FC) ||
1829 (MptDriverClass[index] == MPTSAS_DRIVER &&
1830 ioc->bus_type != SAS))
1831 /* make sure we only call the relevant reset handler
1834 return (MptResetHandlers[index])(ioc, reset_phase);
1837 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1839 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1840 * @ioc: Pointer to MPT adapter structure
1841 * @reason: Event word / reason
1842 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1844 * This routine performs all the steps necessary to bring the IOC
1845 * to a OPERATIONAL state.
1847 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1852 * -1 if failed to get board READY
1853 * -2 if READY but IOCFacts Failed
1854 * -3 if READY but PrimeIOCFifos Failed
1855 * -4 if READY but IOCInit Failed
1858 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1860 int hard_reset_done = 0;
1861 int alt_ioc_ready = 0;
1867 int reset_alt_ioc_active = 0;
1868 int irq_allocated = 0;
1871 printk(KERN_INFO MYNAM ": Initiating %s %s\n",
1872 ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
1874 /* Disable reply interrupts (also blocks FreeQ) */
1875 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1879 if (ioc->alt_ioc->active)
1880 reset_alt_ioc_active = 1;
1882 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1883 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
1884 ioc->alt_ioc->active = 0;
1888 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
1891 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
1892 if (hard_reset_done == -4) {
1893 printk(KERN_WARNING MYNAM ": %s Owned by PEER..skipping!\n",
1896 if (reset_alt_ioc_active && ioc->alt_ioc) {
1897 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1898 dprintk(ioc, printk(KERN_INFO MYNAM
1899 ": alt-%s reply irq re-enabled\n",
1900 ioc->alt_ioc->name));
1901 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
1902 ioc->alt_ioc->active = 1;
1906 printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",
1912 /* hard_reset_done = 0 if a soft reset was performed
1913 * and 1 if a hard reset was performed.
1915 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
1916 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
1919 printk(KERN_WARNING MYNAM
1920 ": alt-%s: Not ready WARNING!\n",
1921 ioc->alt_ioc->name);
1924 for (ii=0; ii<5; ii++) {
1925 /* Get IOC facts! Allow 5 retries */
1926 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
1932 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Retry IocFacts failed rc=%x\n", ioc->name, rc));
1934 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1935 MptDisplayIocCapabilities(ioc);
1938 if (alt_ioc_ready) {
1939 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
1940 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1941 "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
1942 /* Retry - alt IOC was initialized once
1944 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
1947 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1948 "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
1950 reset_alt_ioc_active = 0;
1951 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1952 MptDisplayIocCapabilities(ioc->alt_ioc);
1957 * Device is reset now. It must have de-asserted the interrupt line
1958 * (if it was asserted) and it should be safe to register for the
1961 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1963 if (ioc->pcidev->irq) {
1964 if (mpt_msi_enable && !pci_enable_msi(ioc->pcidev))
1965 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
1967 rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
1968 IRQF_SHARED, ioc->name, ioc);
1970 printk(MYIOC_s_ERR_FMT "Unable to allocate "
1971 "interrupt %d!\n", ioc->name,
1974 pci_disable_msi(ioc->pcidev);
1978 ioc->pci_irq = ioc->pcidev->irq;
1979 pci_set_master(ioc->pcidev); /* ?? */
1980 pci_set_drvdata(ioc->pcidev, ioc);
1981 dprintk(ioc, printk(KERN_INFO MYNAM ": %s installed at interrupt "
1982 "%d\n", ioc->name, ioc->pcidev->irq));
1986 /* Prime reply & request queues!
1987 * (mucho alloc's) Must be done prior to
1988 * init as upper addresses are needed for init.
1989 * If fails, continue with alt-ioc processing
1991 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
1994 /* May need to check/upload firmware & data here!
1995 * If fails, continue with alt-ioc processing
1997 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
2000 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
2001 printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
2002 ioc->alt_ioc->name, rc);
2004 reset_alt_ioc_active = 0;
2007 if (alt_ioc_ready) {
2008 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
2010 reset_alt_ioc_active = 0;
2011 printk(KERN_WARNING MYNAM
2012 ": alt-%s: (%d) init failure WARNING!\n",
2013 ioc->alt_ioc->name, rc);
2017 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
2018 if (ioc->upload_fw) {
2019 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2020 "firmware upload required!\n", ioc->name));
2022 /* Controller is not operational, cannot do upload
2025 rc = mpt_do_upload(ioc, sleepFlag);
2027 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2029 * Maintain only one pointer to FW memory
2030 * so there will not be two attempt to
2031 * downloadboot onboard dual function
2032 * chips (mpt_adapter_disable,
2035 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2036 ": mpt_upload: alt_%s has cached_fw=%p \n",
2037 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
2038 ioc->alt_ioc->cached_fw = NULL;
2041 printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
2049 /* Enable! (reply interrupt) */
2050 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
2054 if (reset_alt_ioc_active && ioc->alt_ioc) {
2055 /* (re)Enable alt-IOC! (reply interrupt) */
2056 dinitprintk(ioc, printk(KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
2057 ioc->alt_ioc->name));
2058 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2059 ioc->alt_ioc->active = 1;
2062 /* Enable MPT base driver management of EventNotification
2063 * and EventAck handling.
2065 if ((ret == 0) && (!ioc->facts.EventState))
2066 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
2068 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2069 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
2071 /* Add additional "reason" check before call to GetLanConfigPages
2072 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2073 * recursive scenario; GetLanConfigPages times out, timer expired
2074 * routine calls HardResetHandler, which calls into here again,
2075 * and we try GetLanConfigPages again...
2077 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2080 * Initalize link list for inactive raid volumes.
2082 init_MUTEX(&ioc->raid_data.inactive_list_mutex);
2083 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2085 if (ioc->bus_type == SAS) {
2087 /* clear persistency table */
2088 if(ioc->facts.IOCExceptions &
2089 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
2090 ret = mptbase_sas_persist_operation(ioc,
2091 MPI_SAS_OP_CLEAR_NOT_PRESENT);
2098 mpt_findImVolumes(ioc);
2100 } else if (ioc->bus_type == FC) {
2101 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
2102 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2104 * Pre-fetch the ports LAN MAC address!
2105 * (LANPage1_t stuff)
2107 (void) GetLanConfigPages(ioc);
2108 a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2109 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2110 "LanAddr = %02X:%02X:%02X:"
2112 ioc->name, a[5], a[4],
2113 a[3], a[2], a[1], a[0] ));
2117 /* Get NVRAM and adapter maximums from SPP 0 and 2
2119 mpt_GetScsiPortSettings(ioc, 0);
2121 /* Get version and length of SDP 1
2123 mpt_readScsiDevicePageHeaders(ioc, 0);
2127 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
2128 mpt_findImVolumes(ioc);
2130 /* Check, and possibly reset, the coalescing value
2132 mpt_read_ioc_pg_1(ioc);
2134 mpt_read_ioc_pg_4(ioc);
2137 GetIoUnitPage2(ioc);
2138 mpt_get_manufacturing_pg_0(ioc);
2142 * Call each currently registered protocol IOC reset handler
2143 * with post-reset indication.
2144 * NOTE: If we're doing _IOC_BRINGUP, there can be no
2145 * MptResetHandlers[] registered yet.
2147 if (hard_reset_done) {
2149 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
2150 if ((ret == 0) && MptResetHandlers[ii]) {
2151 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2152 "Calling IOC post_reset handler #%d\n",
2154 rc += mpt_signal_reset(ii, ioc, MPT_IOC_POST_RESET);
2158 if (alt_ioc_ready && MptResetHandlers[ii]) {
2159 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2160 "Calling alt-%s post_reset handler #%d\n",
2161 ioc->name, ioc->alt_ioc->name, ii));
2162 rc += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_POST_RESET);
2166 /* FIXME? Examine results here? */
2170 if ((ret != 0) && irq_allocated) {
2171 free_irq(ioc->pci_irq, ioc);
2173 pci_disable_msi(ioc->pcidev);
2178 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2180 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2181 * @ioc: Pointer to MPT adapter structure
2182 * @pdev: Pointer to (struct pci_dev) structure
2184 * Search for PCI bus/dev_function which matches
2185 * PCI bus/dev_function (+/-1) for newly discovered 929,
2186 * 929X, 1030 or 1035.
2188 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2189 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2192 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
2194 struct pci_dev *peer=NULL;
2195 unsigned int slot = PCI_SLOT(pdev->devfn);
2196 unsigned int func = PCI_FUNC(pdev->devfn);
2197 MPT_ADAPTER *ioc_srch;
2199 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PCI device %s devfn=%x/%x,"
2200 " searching for devfn match on %x or %x\n",
2201 ioc->name, pci_name(pdev), pdev->bus->number,
2202 pdev->devfn, func-1, func+1));
2204 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
2206 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
2211 list_for_each_entry(ioc_srch, &ioc_list, list) {
2212 struct pci_dev *_pcidev = ioc_srch->pcidev;
2213 if (_pcidev == peer) {
2214 /* Paranoia checks */
2215 if (ioc->alt_ioc != NULL) {
2216 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
2217 ioc->name, ioc->alt_ioc->name);
2219 } else if (ioc_srch->alt_ioc != NULL) {
2220 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
2221 ioc_srch->name, ioc_srch->alt_ioc->name);
2224 dprintk(ioc, printk(KERN_INFO MYNAM ": FOUND! binding %s <==> %s\n",
2225 ioc->name, ioc_srch->name));
2226 ioc_srch->alt_ioc = ioc;
2227 ioc->alt_ioc = ioc_srch;
2233 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2235 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2236 * @ioc: Pointer to MPT adapter structure
2239 mpt_adapter_disable(MPT_ADAPTER *ioc)
2244 if (ioc->cached_fw != NULL) {
2245 ddlprintk(ioc, printk(KERN_INFO MYNAM ": mpt_adapter_disable: Pushing FW onto adapter\n"));
2246 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)ioc->cached_fw, NO_SLEEP)) < 0) {
2247 printk(KERN_WARNING MYNAM
2248 ": firmware downloadboot failure (%d)!\n", ret);
2252 /* Disable adapter interrupts! */
2253 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2255 /* Clear any lingering interrupt */
2256 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2258 if (ioc->alloc != NULL) {
2260 dexitprintk(ioc, printk(KERN_INFO MYNAM ": %s.free @ %p, sz=%d bytes\n",
2261 ioc->name, ioc->alloc, ioc->alloc_sz));
2262 pci_free_consistent(ioc->pcidev, sz,
2263 ioc->alloc, ioc->alloc_dma);
2264 ioc->reply_frames = NULL;
2265 ioc->req_frames = NULL;
2267 ioc->alloc_total -= sz;
2270 if (ioc->sense_buf_pool != NULL) {
2271 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2272 pci_free_consistent(ioc->pcidev, sz,
2273 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2274 ioc->sense_buf_pool = NULL;
2275 ioc->alloc_total -= sz;
2278 if (ioc->events != NULL){
2279 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2282 ioc->alloc_total -= sz;
2285 if (ioc->cached_fw != NULL) {
2286 sz = ioc->facts.FWImageSize;
2287 pci_free_consistent(ioc->pcidev, sz,
2288 ioc->cached_fw, ioc->cached_fw_dma);
2289 ioc->cached_fw = NULL;
2290 ioc->alloc_total -= sz;
2293 kfree(ioc->spi_data.nvram);
2294 mpt_inactive_raid_list_free(ioc);
2295 kfree(ioc->raid_data.pIocPg2);
2296 kfree(ioc->raid_data.pIocPg3);
2297 ioc->spi_data.nvram = NULL;
2298 ioc->raid_data.pIocPg3 = NULL;
2300 if (ioc->spi_data.pIocPg4 != NULL) {
2301 sz = ioc->spi_data.IocPg4Sz;
2302 pci_free_consistent(ioc->pcidev, sz,
2303 ioc->spi_data.pIocPg4,
2304 ioc->spi_data.IocPg4_dma);
2305 ioc->spi_data.pIocPg4 = NULL;
2306 ioc->alloc_total -= sz;
2309 if (ioc->ReqToChain != NULL) {
2310 kfree(ioc->ReqToChain);
2311 kfree(ioc->RequestNB);
2312 ioc->ReqToChain = NULL;
2315 kfree(ioc->ChainToChain);
2316 ioc->ChainToChain = NULL;
2318 if (ioc->HostPageBuffer != NULL) {
2319 if((ret = mpt_host_page_access_control(ioc,
2320 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2321 printk(KERN_ERR MYNAM
2322 ": %s: host page buffers free failed (%d)!\n",
2325 dexitprintk(ioc, printk(KERN_INFO MYNAM ": %s HostPageBuffer free @ %p, sz=%d bytes\n",
2326 ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
2327 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2328 ioc->HostPageBuffer,
2329 ioc->HostPageBuffer_dma);
2330 ioc->HostPageBuffer = NULL;
2331 ioc->HostPageBuffer_sz = 0;
2332 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2336 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2338 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2339 * @ioc: Pointer to MPT adapter structure
2341 * This routine unregisters h/w resources and frees all alloc'd memory
2342 * associated with a MPT adapter structure.
2345 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2347 int sz_first, sz_last;
2352 sz_first = ioc->alloc_total;
2354 mpt_adapter_disable(ioc);
2356 if (ioc->pci_irq != -1) {
2357 free_irq(ioc->pci_irq, ioc);
2359 pci_disable_msi(ioc->pcidev);
2363 if (ioc->memmap != NULL) {
2364 iounmap(ioc->memmap);
2368 #if defined(CONFIG_MTRR) && 0
2369 if (ioc->mtrr_reg > 0) {
2370 mtrr_del(ioc->mtrr_reg, 0, 0);
2371 dprintk(ioc, printk(KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name));
2375 /* Zap the adapter lookup ptr! */
2376 list_del(&ioc->list);
2378 sz_last = ioc->alloc_total;
2379 dprintk(ioc, printk(KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
2380 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2383 ioc->alt_ioc->alt_ioc = NULL;
2388 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2390 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2391 * @ioc: Pointer to MPT adapter structure
2394 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2398 printk(KERN_INFO "%s: ", ioc->name);
2400 printk("%s: ", ioc->prod_name);
2401 printk("Capabilities={");
2403 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2404 printk("Initiator");
2408 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2409 printk("%sTarget", i ? "," : "");
2413 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2414 printk("%sLAN", i ? "," : "");
2420 * This would probably evoke more questions than it's worth
2422 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2423 printk("%sLogBusAddr", i ? "," : "");
2431 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2433 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2434 * @ioc: Pointer to MPT_ADAPTER structure
2435 * @force: Force hard KickStart of IOC
2436 * @sleepFlag: Specifies whether the process can sleep
2439 * 1 - DIAG reset and READY
2440 * 0 - READY initially OR soft reset and READY
2441 * -1 - Any failure on KickStart
2442 * -2 - Msg Unit Reset Failed
2443 * -3 - IO Unit Reset Failed
2444 * -4 - IOC owned by a PEER
2447 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2452 int hard_reset_done = 0;
2457 /* Get current [raw] IOC state */
2458 ioc_state = mpt_GetIocState(ioc, 0);
2459 dhsprintk(ioc, printk(KERN_INFO MYNAM "::MakeIocReady, %s [raw] state=%08x\n", ioc->name, ioc_state));
2462 * Check to see if IOC got left/stuck in doorbell handshake
2463 * grip of death. If so, hard reset the IOC.
2465 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2467 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2471 /* Is it already READY? */
2472 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
2476 * Check to see if IOC is in FAULT state.
2478 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2480 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2482 printk(KERN_WARNING " FAULT code = %04xh\n",
2483 ioc_state & MPI_DOORBELL_DATA_MASK);
2487 * Hmmm... Did it get left operational?
2489 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2490 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC operational unexpected\n",
2494 * If PCI Peer, exit.
2495 * Else, if no fault conditions are present, issue a MessageUnitReset
2496 * Else, fall through to KickStart case
2498 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2499 dinitprintk(ioc, printk(KERN_INFO MYNAM
2500 ": whoinit 0x%x statefault %d force %d\n",
2501 whoinit, statefault, force));
2502 if (whoinit == MPI_WHOINIT_PCI_PEER)
2505 if ((statefault == 0 ) && (force == 0)) {
2506 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2513 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2514 if (hard_reset_done < 0)
2518 * Loop here waiting for IOC to come READY.
2521 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2523 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2524 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2526 * BIOS or previous driver load left IOC in OP state.
2527 * Reset messaging FIFOs.
2529 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2530 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2533 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2535 * Something is wrong. Try to get IOC back
2538 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2539 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2546 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2547 ioc->name, (int)((ii+5)/HZ));
2551 if (sleepFlag == CAN_SLEEP) {
2554 mdelay (1); /* 1 msec delay */
2559 if (statefault < 3) {
2560 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2562 statefault==1 ? "stuck handshake" : "IOC FAULT");
2565 return hard_reset_done;
2568 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2570 * mpt_GetIocState - Get the current state of a MPT adapter.
2571 * @ioc: Pointer to MPT_ADAPTER structure
2572 * @cooked: Request raw or cooked IOC state
2574 * Returns all IOC Doorbell register bits if cooked==0, else just the
2575 * Doorbell bits in MPI_IOC_STATE_MASK.
2578 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2583 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2584 // dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
2585 sc = s & MPI_IOC_STATE_MASK;
2588 ioc->last_state = sc;
2590 return cooked ? sc : s;
2593 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2595 * GetIocFacts - Send IOCFacts request to MPT adapter.
2596 * @ioc: Pointer to MPT_ADAPTER structure
2597 * @sleepFlag: Specifies whether the process can sleep
2598 * @reason: If recovery, only update facts.
2600 * Returns 0 for success, non-zero for failure.
2603 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2605 IOCFacts_t get_facts;
2606 IOCFactsReply_t *facts;
2614 /* IOC *must* NOT be in RESET state! */
2615 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2616 printk(KERN_ERR MYNAM ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
2622 facts = &ioc->facts;
2624 /* Destination (reply area)... */
2625 reply_sz = sizeof(*facts);
2626 memset(facts, 0, reply_sz);
2628 /* Request area (get_facts on the stack right now!) */
2629 req_sz = sizeof(get_facts);
2630 memset(&get_facts, 0, req_sz);
2632 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2633 /* Assert: All other get_facts fields are zero! */
2635 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2636 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2637 ioc->name, req_sz, reply_sz));
2639 /* No non-zero fields in the get_facts request are greater than
2640 * 1 byte in size, so we can just fire it off as is.
2642 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2643 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2648 * Now byte swap (GRRR) the necessary fields before any further
2649 * inspection of reply contents.
2651 * But need to do some sanity checks on MsgLength (byte) field
2652 * to make sure we don't zero IOC's req_sz!
2654 /* Did we get a valid reply? */
2655 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2656 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2658 * If not been here, done that, save off first WhoInit value
2660 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2661 ioc->FirstWhoInit = facts->WhoInit;
2664 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2665 facts->MsgContext = le32_to_cpu(facts->MsgContext);
2666 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2667 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2668 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2669 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
2670 /* CHECKME! IOCStatus, IOCLogInfo */
2672 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2673 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2676 * FC f/w version changed between 1.1 and 1.2
2677 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2678 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2680 if (facts->MsgVersion < 0x0102) {
2682 * Handle old FC f/w style, convert to new...
2684 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2685 facts->FWVersion.Word =
2686 ((oldv<<12) & 0xFF000000) |
2687 ((oldv<<8) & 0x000FFF00);
2689 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2691 facts->ProductID = le16_to_cpu(facts->ProductID);
2692 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
2693 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
2694 ioc->ir_firmware = 1;
2695 facts->CurrentHostMfaHighAddr =
2696 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2697 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2698 facts->CurrentSenseBufferHighAddr =
2699 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2700 facts->CurReplyFrameSize =
2701 le16_to_cpu(facts->CurReplyFrameSize);
2702 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
2705 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2706 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2707 * to 14 in MPI-1.01.0x.
2709 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2710 facts->MsgVersion > 0x0100) {
2711 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2714 sz = facts->FWImageSize;
2719 facts->FWImageSize = sz;
2721 if (!facts->RequestFrameSize) {
2722 /* Something is wrong! */
2723 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2728 r = sz = facts->BlockSize;
2729 vv = ((63 / (sz * 4)) + 1) & 0x03;
2730 ioc->NB_for_64_byte_frame = vv;
2736 ioc->NBShiftFactor = shiftFactor;
2737 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2738 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2739 ioc->name, vv, shiftFactor, r));
2741 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2743 * Set values for this IOC's request & reply frame sizes,
2744 * and request & reply queue depths...
2746 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2747 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2748 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2749 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2751 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "reply_sz=%3d, reply_depth=%4d\n",
2752 ioc->name, ioc->reply_sz, ioc->reply_depth));
2753 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "req_sz =%3d, req_depth =%4d\n",
2754 ioc->name, ioc->req_sz, ioc->req_depth));
2756 /* Get port facts! */
2757 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2761 printk(MYIOC_s_ERR_FMT
2762 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2763 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2764 RequestFrameSize)/sizeof(u32)));
2771 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2773 * GetPortFacts - Send PortFacts request to MPT adapter.
2774 * @ioc: Pointer to MPT_ADAPTER structure
2775 * @portnum: Port number
2776 * @sleepFlag: Specifies whether the process can sleep
2778 * Returns 0 for success, non-zero for failure.
2781 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2783 PortFacts_t get_pfacts;
2784 PortFactsReply_t *pfacts;
2790 /* IOC *must* NOT be in RESET state! */
2791 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2792 printk(KERN_ERR MYNAM ": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n",
2798 pfacts = &ioc->pfacts[portnum];
2800 /* Destination (reply area)... */
2801 reply_sz = sizeof(*pfacts);
2802 memset(pfacts, 0, reply_sz);
2804 /* Request area (get_pfacts on the stack right now!) */
2805 req_sz = sizeof(get_pfacts);
2806 memset(&get_pfacts, 0, req_sz);
2808 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2809 get_pfacts.PortNumber = portnum;
2810 /* Assert: All other get_pfacts fields are zero! */
2812 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending get PortFacts(%d) request\n",
2813 ioc->name, portnum));
2815 /* No non-zero fields in the get_pfacts request are greater than
2816 * 1 byte in size, so we can just fire it off as is.
2818 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2819 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2823 /* Did we get a valid reply? */
2825 /* Now byte swap the necessary fields in the response. */
2826 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2827 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2828 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2829 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2830 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2831 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2832 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2833 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2834 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2836 max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
2838 ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
2839 ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
2842 * Place all the devices on channels
2846 if (mpt_channel_mapping) {
2847 ioc->devices_per_bus = 1;
2848 ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
2854 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2856 * SendIocInit - Send IOCInit request to MPT adapter.
2857 * @ioc: Pointer to MPT_ADAPTER structure
2858 * @sleepFlag: Specifies whether the process can sleep
2860 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2862 * Returns 0 for success, non-zero for failure.
2865 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2868 MPIDefaultReply_t init_reply;
2874 memset(&ioc_init, 0, sizeof(ioc_init));
2875 memset(&init_reply, 0, sizeof(init_reply));
2877 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2878 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2880 /* If we are in a recovery mode and we uploaded the FW image,
2881 * then this pointer is not NULL. Skip the upload a second time.
2882 * Set this flag if cached_fw set for either IOC.
2884 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
2888 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "upload_fw %d facts.Flags=%x\n",
2889 ioc->name, ioc->upload_fw, ioc->facts.Flags));
2891 ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
2892 ioc_init.MaxBuses = (U8)ioc->number_of_buses;
2893 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n",
2894 ioc->name, ioc->facts.MsgVersion));
2895 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
2896 // set MsgVersion and HeaderVersion host driver was built with
2897 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
2898 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
2900 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
2901 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
2902 } else if(mpt_host_page_alloc(ioc, &ioc_init))
2905 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
2907 if (sizeof(dma_addr_t) == sizeof(u64)) {
2908 /* Save the upper 32-bits of the request
2909 * (reply) and sense buffers.
2911 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
2912 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2914 /* Force 32-bit addressing */
2915 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
2916 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
2919 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
2920 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
2921 ioc->facts.MaxDevices = ioc_init.MaxDevices;
2922 ioc->facts.MaxBuses = ioc_init.MaxBuses;
2924 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOCInit (req @ %p)\n",
2925 ioc->name, &ioc_init));
2927 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
2928 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
2930 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
2934 /* No need to byte swap the multibyte fields in the reply
2935 * since we don't even look at its contents.
2938 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending PortEnable (req @ %p)\n",
2939 ioc->name, &ioc_init));
2941 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
2942 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
2946 /* YIKES! SUPER IMPORTANT!!!
2947 * Poll IocState until _OPERATIONAL while IOC is doing
2948 * LoopInit and TargetDiscovery!
2951 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
2952 state = mpt_GetIocState(ioc, 1);
2953 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
2954 if (sleepFlag == CAN_SLEEP) {
2961 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
2962 ioc->name, (int)((count+5)/HZ));
2966 state = mpt_GetIocState(ioc, 1);
2969 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
2972 ioc->aen_event_read_flag=0;
2976 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2978 * SendPortEnable - Send PortEnable request to MPT adapter port.
2979 * @ioc: Pointer to MPT_ADAPTER structure
2980 * @portnum: Port number to enable
2981 * @sleepFlag: Specifies whether the process can sleep
2983 * Send PortEnable to bring IOC to OPERATIONAL state.
2985 * Returns 0 for success, non-zero for failure.
2988 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2990 PortEnable_t port_enable;
2991 MPIDefaultReply_t reply_buf;
2996 /* Destination... */
2997 reply_sz = sizeof(MPIDefaultReply_t);
2998 memset(&reply_buf, 0, reply_sz);
3000 req_sz = sizeof(PortEnable_t);
3001 memset(&port_enable, 0, req_sz);
3003 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
3004 port_enable.PortNumber = portnum;
3005 /* port_enable.ChainOffset = 0; */
3006 /* port_enable.MsgFlags = 0; */
3007 /* port_enable.MsgContext = 0; */
3009 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Port(%d)Enable (req @ %p)\n",
3010 ioc->name, portnum, &port_enable));
3012 /* RAID FW may take a long time to enable
3014 if (ioc->ir_firmware || ioc->bus_type == SAS) {
3015 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3016 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3017 300 /*seconds*/, sleepFlag);
3019 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3020 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3021 30 /*seconds*/, sleepFlag);
3027 * mpt_alloc_fw_memory - allocate firmware memory
3028 * @ioc: Pointer to MPT_ADAPTER structure
3029 * @size: total FW bytes
3031 * If memory has already been allocated, the same (cached) value
3035 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
3038 return; /* use already allocated memory */
3039 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
3040 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
3041 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
3042 ioc->alloc_total += size;
3043 ioc->alt_ioc->alloc_total -= size;
3045 if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
3046 ioc->alloc_total += size;
3050 * mpt_free_fw_memory - free firmware memory
3051 * @ioc: Pointer to MPT_ADAPTER structure
3053 * If alt_img is NULL, delete from ioc structure.
3054 * Else, delete a secondary image in same format.
3057 mpt_free_fw_memory(MPT_ADAPTER *ioc)
3061 sz = ioc->facts.FWImageSize;
3062 dinitprintk(ioc, printk(KERN_INFO MYNAM "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3063 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3064 pci_free_consistent(ioc->pcidev, sz,
3065 ioc->cached_fw, ioc->cached_fw_dma);
3066 ioc->cached_fw = NULL;
3072 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3074 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3075 * @ioc: Pointer to MPT_ADAPTER structure
3076 * @sleepFlag: Specifies whether the process can sleep
3078 * Returns 0 for success, >0 for handshake failure
3079 * <0 for fw upload failure.
3081 * Remark: If bound IOC and a successful FWUpload was performed
3082 * on the bound IOC, the second image is discarded
3083 * and memory is free'd. Both channels must upload to prevent
3084 * IOC from running in degraded mode.
3087 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3089 u8 request[ioc->req_sz];
3090 u8 reply[sizeof(FWUploadReply_t)];
3091 FWUpload_t *prequest;
3092 FWUploadReply_t *preply;
3093 FWUploadTCSGE_t *ptcsge;
3096 int ii, sz, reply_sz;
3099 /* If the image size is 0, we are done.
3101 if ((sz = ioc->facts.FWImageSize) == 0)
3104 mpt_alloc_fw_memory(ioc, sz);
3106 dinitprintk(ioc, printk(KERN_INFO MYNAM ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3107 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3109 if (ioc->cached_fw == NULL) {
3115 prequest = (FWUpload_t *)&request;
3116 preply = (FWUploadReply_t *)&reply;
3118 /* Destination... */
3119 memset(prequest, 0, ioc->req_sz);
3121 reply_sz = sizeof(reply);
3122 memset(preply, 0, reply_sz);
3124 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
3125 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
3127 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
3128 ptcsge->DetailsLength = 12;
3129 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
3130 ptcsge->ImageSize = cpu_to_le32(sz);
3132 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
3134 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3135 mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma);
3137 sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
3138 dinitprintk(ioc, printk(KERN_INFO MYNAM ": Sending FW Upload (req @ %p) sgeoffset=%d \n",
3139 prequest, sgeoffset));
3140 DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest)
3142 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
3143 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
3145 dinitprintk(ioc, printk(KERN_INFO MYNAM ": FW Upload completed rc=%x \n", ii));
3147 cmdStatus = -EFAULT;
3149 /* Handshake transfer was complete and successful.
3150 * Check the Reply Frame.
3152 int status, transfer_sz;
3153 status = le16_to_cpu(preply->IOCStatus);
3154 if (status == MPI_IOCSTATUS_SUCCESS) {
3155 transfer_sz = le32_to_cpu(preply->ActualImageSize);
3156 if (transfer_sz == sz)
3160 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n",
3161 ioc->name, cmdStatus));
3166 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": fw upload failed, freeing image \n",
3168 mpt_free_fw_memory(ioc);
3174 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3176 * mpt_downloadboot - DownloadBoot code
3177 * @ioc: Pointer to MPT_ADAPTER structure
3178 * @pFwHeader: Pointer to firmware header info
3179 * @sleepFlag: Specifies whether the process can sleep
3181 * FwDownloadBoot requires Programmed IO access.
3183 * Returns 0 for success
3184 * -1 FW Image size is 0
3185 * -2 No valid cached_fw Pointer
3186 * <0 for fw upload failure.
3189 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3191 MpiExtImageHeader_t *pExtImage;
3201 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3202 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
3204 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3205 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3206 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3207 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3208 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3209 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3211 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
3214 if (sleepFlag == CAN_SLEEP) {
3220 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3221 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3223 for (count = 0; count < 30; count ++) {
3224 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3225 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3226 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESET_ADAPTER cleared, count=%d\n",
3231 if (sleepFlag == CAN_SLEEP) {
3238 if ( count == 30 ) {
3239 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot failed! "
3240 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3241 ioc->name, diag0val));
3245 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3246 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3247 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3248 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3249 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3250 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3252 /* Set the DiagRwEn and Disable ARM bits */
3253 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3255 fwSize = (pFwHeader->ImageSize + 3)/4;
3256 ptrFw = (u32 *) pFwHeader;
3258 /* Write the LoadStartAddress to the DiagRw Address Register
3259 * using Programmed IO
3261 if (ioc->errata_flag_1064)
3262 pci_enable_io_access(ioc->pcidev);
3264 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3265 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "LoadStart addr written 0x%x \n",
3266 ioc->name, pFwHeader->LoadStartAddress));
3268 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write FW Image: 0x%x bytes @ %p\n",
3269 ioc->name, fwSize*4, ptrFw));
3271 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3274 nextImage = pFwHeader->NextImageHeaderOffset;
3276 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3278 load_addr = pExtImage->LoadStartAddress;
3280 fwSize = (pExtImage->ImageSize + 3) >> 2;
3281 ptrFw = (u32 *)pExtImage;
3283 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3284 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3285 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3288 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3290 nextImage = pExtImage->NextImageHeaderOffset;
3293 /* Write the IopResetVectorRegAddr */
3294 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
3295 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3297 /* Write the IopResetVectorValue */
3298 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3299 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3301 /* Clear the internal flash bad bit - autoincrementing register,
3302 * so must do two writes.
3304 if (ioc->bus_type == SPI) {
3306 * 1030 and 1035 H/W errata, workaround to access
3307 * the ClearFlashBadSignatureBit
3309 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3310 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3311 diagRwData |= 0x40000000;
3312 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3313 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3315 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3316 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3317 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3318 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3321 if (sleepFlag == CAN_SLEEP) {
3328 if (ioc->errata_flag_1064)
3329 pci_disable_io_access(ioc->pcidev);
3331 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3332 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot diag0val=%x, "
3333 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3334 ioc->name, diag0val));
3335 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3336 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot now diag0val=%x\n",
3337 ioc->name, diag0val));
3338 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3340 /* Write 0xFF to reset the sequencer */
3341 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3343 if (ioc->bus_type == SAS) {
3344 ioc_state = mpt_GetIocState(ioc, 0);
3345 if ( (GetIocFacts(ioc, sleepFlag,
3346 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3347 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "GetIocFacts failed: IocState=%x\n",
3348 ioc->name, ioc_state));
3353 for (count=0; count<HZ*20; count++) {
3354 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3355 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3356 "downloadboot successful! (count=%d) IocState=%x\n",
3357 ioc->name, count, ioc_state));
3358 if (ioc->bus_type == SAS) {
3361 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3362 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3363 "downloadboot: SendIocInit failed\n",
3367 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3368 "downloadboot: SendIocInit successful\n",
3372 if (sleepFlag == CAN_SLEEP) {
3378 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3379 "downloadboot failed! IocState=%x\n",ioc->name, ioc_state));
3383 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3385 * KickStart - Perform hard reset of MPT adapter.
3386 * @ioc: Pointer to MPT_ADAPTER structure
3387 * @force: Force hard reset
3388 * @sleepFlag: Specifies whether the process can sleep
3390 * This routine places MPT adapter in diagnostic mode via the
3391 * WriteSequence register, and then performs a hard reset of adapter
3392 * via the Diagnostic register.
3394 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3395 * or NO_SLEEP (interrupt thread, use mdelay)
3396 * force - 1 if doorbell active, board fault state
3397 * board operational, IOC_RECOVERY or
3398 * IOC_BRINGUP and there is an alt_ioc.
3402 * 1 - hard reset, READY
3403 * 0 - no reset due to History bit, READY
3404 * -1 - no reset due to History bit but not READY
3405 * OR reset but failed to come READY
3406 * -2 - no reset, could not enter DIAG mode
3407 * -3 - reset but bad FW bit
3410 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3412 int hard_reset_done = 0;
3416 dinitprintk(ioc, printk(KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
3417 if (ioc->bus_type == SPI) {
3418 /* Always issue a Msg Unit Reset first. This will clear some
3419 * SCSI bus hang conditions.
3421 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3423 if (sleepFlag == CAN_SLEEP) {
3430 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3431 if (hard_reset_done < 0)
3432 return hard_reset_done;
3434 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n",
3437 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3438 for (cnt=0; cnt<cntdn; cnt++) {
3439 ioc_state = mpt_GetIocState(ioc, 1);
3440 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3441 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStart successful! (cnt=%d)\n",
3443 return hard_reset_done;
3445 if (sleepFlag == CAN_SLEEP) {
3452 printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3453 ioc->name, ioc_state);
3457 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3459 * mpt_diag_reset - Perform hard reset of the adapter.
3460 * @ioc: Pointer to MPT_ADAPTER structure
3461 * @ignore: Set if to honor and clear to ignore
3462 * the reset history bit
3463 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3464 * else set to NO_SLEEP (use mdelay instead)
3466 * This routine places the adapter in diagnostic mode via the
3467 * WriteSequence register and then performs a hard reset of adapter
3468 * via the Diagnostic register. Adapter should be in ready state
3469 * upon successful completion.
3471 * Returns: 1 hard reset successful
3472 * 0 no reset performed because reset history bit set
3473 * -2 enabling diagnostic mode failed
3474 * -3 diagnostic reset failed
3477 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3479 MPT_ADAPTER *iocp=NULL;
3482 int hard_reset_done = 0;
3486 /* Clear any existing interrupts */
3487 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3489 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3490 drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3491 "address=%p\n", ioc->name, __FUNCTION__,
3492 &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3493 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3494 if (sleepFlag == CAN_SLEEP)
3499 for (count = 0; count < 60; count ++) {
3500 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3501 doorbell &= MPI_IOC_STATE_MASK;
3503 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3504 "looking for READY STATE: doorbell=%x"
3506 ioc->name, doorbell, count));
3507 if (doorbell == MPI_IOC_STATE_READY) {
3512 if (sleepFlag == CAN_SLEEP)
3520 /* Use "Diagnostic reset" method! (only thing available!) */
3521 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3523 if (ioc->debug_level & MPT_DEBUG) {
3525 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3526 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3527 ioc->name, diag0val, diag1val));
3530 /* Do the reset if we are told to ignore the reset history
3531 * or if the reset history is 0
3533 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3534 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3535 /* Write magic sequence to WriteSequence register
3536 * Loop until in diagnostic mode
3538 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3539 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3540 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3541 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3542 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3543 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3546 if (sleepFlag == CAN_SLEEP) {
3554 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3555 ioc->name, diag0val);
3560 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3562 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3563 ioc->name, diag0val));
3566 if (ioc->debug_level & MPT_DEBUG) {
3568 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3569 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3570 ioc->name, diag0val, diag1val));
3573 * Disable the ARM (Bug fix)
3576 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3580 * Now hit the reset bit in the Diagnostic register
3581 * (THE BIG HAMMER!) (Clears DRWE bit).
3583 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3584 hard_reset_done = 1;
3585 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset performed\n",
3589 * Call each currently registered protocol IOC reset handler
3590 * with pre-reset indication.
3591 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3592 * MptResetHandlers[] registered yet.
3598 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
3599 if (MptResetHandlers[ii]) {
3600 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3601 "Calling IOC pre_reset handler #%d\n",
3603 r += mpt_signal_reset(ii, ioc, MPT_IOC_PRE_RESET);
3605 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3606 "Calling alt-%s pre_reset handler #%d\n",
3607 ioc->name, ioc->alt_ioc->name, ii));
3608 r += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_PRE_RESET);
3612 /* FIXME? Examine results here? */
3617 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
3618 iocp = ioc->alt_ioc;
3620 /* If the DownloadBoot operation fails, the
3621 * IOC will be left unusable. This is a fatal error
3622 * case. _diag_reset will return < 0
3624 for (count = 0; count < 30; count ++) {
3625 diag0val = CHIPREG_READ32(&iocp->chip->Diagnostic);
3626 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3630 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n",
3631 iocp->name, diag0val, count));
3633 if (sleepFlag == CAN_SLEEP) {
3639 if ((count = mpt_downloadboot(ioc,
3640 (MpiFwHeader_t *)iocp->cached_fw, sleepFlag)) < 0) {
3641 printk(KERN_WARNING MYNAM
3642 ": firmware downloadboot failure (%d)!\n", count);
3646 /* Wait for FW to reload and for board
3647 * to go to the READY state.
3648 * Maximum wait is 60 seconds.
3649 * If fail, no error will check again
3650 * with calling program.
3652 for (count = 0; count < 60; count ++) {
3653 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3654 doorbell &= MPI_IOC_STATE_MASK;
3656 if (doorbell == MPI_IOC_STATE_READY) {
3661 if (sleepFlag == CAN_SLEEP) {
3670 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3671 if (ioc->debug_level & MPT_DEBUG) {
3673 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3674 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3675 ioc->name, diag0val, diag1val));
3678 /* Clear RESET_HISTORY bit! Place board in the
3679 * diagnostic mode to update the diag register.
3681 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3683 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3684 /* Write magic sequence to WriteSequence register
3685 * Loop until in diagnostic mode
3687 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3688 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3689 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3690 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3691 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3692 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3695 if (sleepFlag == CAN_SLEEP) {
3703 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3704 ioc->name, diag0val);
3707 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3709 diag0val &= ~MPI_DIAG_RESET_HISTORY;
3710 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3711 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3712 if (diag0val & MPI_DIAG_RESET_HISTORY) {
3713 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3717 /* Disable Diagnostic Mode
3719 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3721 /* Check FW reload status flags.
3723 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3724 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3725 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3726 ioc->name, diag0val);
3730 if (ioc->debug_level & MPT_DEBUG) {
3732 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3733 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3734 ioc->name, diag0val, diag1val));
3738 * Reset flag that says we've enabled event notification
3740 ioc->facts.EventState = 0;
3743 ioc->alt_ioc->facts.EventState = 0;
3745 return hard_reset_done;
3748 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3750 * SendIocReset - Send IOCReset request to MPT adapter.
3751 * @ioc: Pointer to MPT_ADAPTER structure
3752 * @reset_type: reset type, expected values are
3753 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3754 * @sleepFlag: Specifies whether the process can sleep
3756 * Send IOCReset request to the MPT adapter.
3758 * Returns 0 for success, non-zero for failure.
3761 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3767 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOC reset(0x%02x)!\n",
3768 ioc->name, reset_type));
3769 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3770 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3773 /* FW ACK'd request, wait for READY state
3776 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
3778 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3782 if (sleepFlag != CAN_SLEEP)
3785 printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
3786 ioc->name, (int)((count+5)/HZ));
3790 if (sleepFlag == CAN_SLEEP) {
3793 mdelay (1); /* 1 msec delay */
3798 * Cleanup all event stuff for this IOC; re-issue EventNotification
3799 * request if needed.
3801 if (ioc->facts.Function)
3802 ioc->facts.EventState = 0;
3807 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3809 * initChainBuffers - Allocate memory for and initialize chain buffers
3810 * @ioc: Pointer to MPT_ADAPTER structure
3812 * Allocates memory for and initializes chain buffers,
3813 * chain buffer control arrays and spinlock.
3816 initChainBuffers(MPT_ADAPTER *ioc)
3819 int sz, ii, num_chain;
3820 int scale, num_sge, numSGE;
3822 /* ReqToChain size must equal the req_depth
3825 if (ioc->ReqToChain == NULL) {
3826 sz = ioc->req_depth * sizeof(int);
3827 mem = kmalloc(sz, GFP_ATOMIC);
3831 ioc->ReqToChain = (int *) mem;
3832 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReqToChain alloc @ %p, sz=%d bytes\n",
3833 ioc->name, mem, sz));
3834 mem = kmalloc(sz, GFP_ATOMIC);
3838 ioc->RequestNB = (int *) mem;
3839 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestNB alloc @ %p, sz=%d bytes\n",
3840 ioc->name, mem, sz));
3842 for (ii = 0; ii < ioc->req_depth; ii++) {
3843 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
3846 /* ChainToChain size must equal the total number
3847 * of chain buffers to be allocated.
3850 * Calculate the number of chain buffers needed(plus 1) per I/O
3851 * then multiply the maximum number of simultaneous cmds
3853 * num_sge = num sge in request frame + last chain buffer
3854 * scale = num sge per chain buffer if no chain element
3856 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3857 if (sizeof(dma_addr_t) == sizeof(u64))
3858 num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3860 num_sge = 1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3862 if (sizeof(dma_addr_t) == sizeof(u64)) {
3863 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3864 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3866 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3867 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3869 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n",
3870 ioc->name, num_sge, numSGE));
3872 if ( numSGE > MPT_SCSI_SG_DEPTH )
3873 numSGE = MPT_SCSI_SG_DEPTH;
3876 while (numSGE - num_sge > 0) {
3878 num_sge += (scale - 1);
3882 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Now numSGE=%d num_sge=%d num_chain=%d\n",
3883 ioc->name, numSGE, num_sge, num_chain));
3885 if (ioc->bus_type == SPI)
3886 num_chain *= MPT_SCSI_CAN_QUEUE;
3888 num_chain *= MPT_FC_CAN_QUEUE;
3890 ioc->num_chain = num_chain;
3892 sz = num_chain * sizeof(int);
3893 if (ioc->ChainToChain == NULL) {
3894 mem = kmalloc(sz, GFP_ATOMIC);
3898 ioc->ChainToChain = (int *) mem;
3899 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainToChain alloc @ %p, sz=%d bytes\n",
3900 ioc->name, mem, sz));
3902 mem = (u8 *) ioc->ChainToChain;
3904 memset(mem, 0xFF, sz);
3908 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3910 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
3911 * @ioc: Pointer to MPT_ADAPTER structure
3913 * This routine allocates memory for the MPT reply and request frame
3914 * pools (if necessary), and primes the IOC reply FIFO with
3917 * Returns 0 for success, non-zero for failure.
3920 PrimeIocFifos(MPT_ADAPTER *ioc)
3923 unsigned long flags;
3924 dma_addr_t alloc_dma;
3926 int i, reply_sz, sz, total_size, num_chain;
3928 /* Prime reply FIFO... */
3930 if (ioc->reply_frames == NULL) {
3931 if ( (num_chain = initChainBuffers(ioc)) < 0)
3934 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
3935 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
3936 ioc->name, ioc->reply_sz, ioc->reply_depth));
3937 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d[%x] bytes\n",
3938 ioc->name, reply_sz, reply_sz));
3940 sz = (ioc->req_sz * ioc->req_depth);
3941 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d bytes, RequestDepth=%d\n",
3942 ioc->name, ioc->req_sz, ioc->req_depth));
3943 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d[%x] bytes\n",
3944 ioc->name, sz, sz));
3947 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
3948 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d bytes, ChainDepth=%d\n",
3949 ioc->name, ioc->req_sz, num_chain));
3950 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
3951 ioc->name, sz, sz, num_chain));
3954 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
3956 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
3961 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Total alloc @ %p[%p], sz=%d[%x] bytes\n",
3962 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
3964 memset(mem, 0, total_size);
3965 ioc->alloc_total += total_size;
3967 ioc->alloc_dma = alloc_dma;
3968 ioc->alloc_sz = total_size;
3969 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
3970 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3972 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
3973 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3975 alloc_dma += reply_sz;
3978 /* Request FIFO - WE manage this! */
3980 ioc->req_frames = (MPT_FRAME_HDR *) mem;
3981 ioc->req_frames_dma = alloc_dma;
3983 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffers @ %p[%p]\n",
3984 ioc->name, mem, (void *)(ulong)alloc_dma));
3986 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3988 #if defined(CONFIG_MTRR) && 0
3990 * Enable Write Combining MTRR for IOC's memory region.
3991 * (at least as much as we can; "size and base must be
3992 * multiples of 4 kiB"
3994 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
3996 MTRR_TYPE_WRCOMB, 1);
3997 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MTRR region registered (base:size=%08x:%x)\n",
3998 ioc->name, ioc->req_frames_dma, sz));
4001 for (i = 0; i < ioc->req_depth; i++) {
4002 alloc_dma += ioc->req_sz;
4006 ioc->ChainBuffer = mem;
4007 ioc->ChainBufferDMA = alloc_dma;
4009 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffers @ %p(%p)\n",
4010 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
4012 /* Initialize the free chain Q.
4015 INIT_LIST_HEAD(&ioc->FreeChainQ);
4017 /* Post the chain buffers to the FreeChainQ.
4019 mem = (u8 *)ioc->ChainBuffer;
4020 for (i=0; i < num_chain; i++) {
4021 mf = (MPT_FRAME_HDR *) mem;
4022 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
4026 /* Initialize Request frames linked list
4028 alloc_dma = ioc->req_frames_dma;
4029 mem = (u8 *) ioc->req_frames;
4031 spin_lock_irqsave(&ioc->FreeQlock, flags);
4032 INIT_LIST_HEAD(&ioc->FreeQ);
4033 for (i = 0; i < ioc->req_depth; i++) {
4034 mf = (MPT_FRAME_HDR *) mem;
4036 /* Queue REQUESTs *internally*! */
4037 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
4041 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4043 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4044 ioc->sense_buf_pool =
4045 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
4046 if (ioc->sense_buf_pool == NULL) {
4047 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
4052 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
4053 ioc->alloc_total += sz;
4054 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SenseBuffers @ %p[%p]\n",
4055 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
4059 /* Post Reply frames to FIFO
4061 alloc_dma = ioc->alloc_dma;
4062 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4063 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4065 for (i = 0; i < ioc->reply_depth; i++) {
4066 /* Write each address to the IOC! */
4067 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
4068 alloc_dma += ioc->reply_sz;
4074 if (ioc->alloc != NULL) {
4076 pci_free_consistent(ioc->pcidev,
4078 ioc->alloc, ioc->alloc_dma);
4079 ioc->reply_frames = NULL;
4080 ioc->req_frames = NULL;
4081 ioc->alloc_total -= sz;
4083 if (ioc->sense_buf_pool != NULL) {
4084 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4085 pci_free_consistent(ioc->pcidev,
4087 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
4088 ioc->sense_buf_pool = NULL;
4093 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4095 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4096 * from IOC via doorbell handshake method.
4097 * @ioc: Pointer to MPT_ADAPTER structure
4098 * @reqBytes: Size of the request in bytes
4099 * @req: Pointer to MPT request frame
4100 * @replyBytes: Expected size of the reply in bytes
4101 * @u16reply: Pointer to area where reply should be written
4102 * @maxwait: Max wait time for a reply (in seconds)
4103 * @sleepFlag: Specifies whether the process can sleep
4105 * NOTES: It is the callers responsibility to byte-swap fields in the
4106 * request which are greater than 1 byte in size. It is also the
4107 * callers responsibility to byte-swap response fields which are
4108 * greater than 1 byte in size.
4110 * Returns 0 for success, non-zero for failure.
4113 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
4114 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
4116 MPIDefaultReply_t *mptReply;
4121 * Get ready to cache a handshake reply
4123 ioc->hs_reply_idx = 0;
4124 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4125 mptReply->MsgLength = 0;
4128 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4129 * then tell IOC that we want to handshake a request of N words.
4130 * (WRITE u32val to Doorbell reg).
4132 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4133 CHIPREG_WRITE32(&ioc->chip->Doorbell,
4134 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
4135 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
4138 * Wait for IOC's doorbell handshake int
4140 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4143 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4144 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4146 /* Read doorbell and check for active bit */
4147 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
4151 * Clear doorbell int (WRITE 0 to IntStatus reg),
4152 * then wait for IOC to ACKnowledge that it's ready for
4153 * our handshake request.
4155 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4156 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4161 u8 *req_as_bytes = (u8 *) req;
4164 * Stuff request words via doorbell handshake,
4165 * with ACK from IOC for each.
4167 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
4168 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
4169 (req_as_bytes[(ii*4) + 1] << 8) |
4170 (req_as_bytes[(ii*4) + 2] << 16) |
4171 (req_as_bytes[(ii*4) + 3] << 24));
4173 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
4174 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4178 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req));
4179 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req)
4181 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n",
4182 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
4185 * Wait for completion of doorbell handshake reply from the IOC
4187 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
4190 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake reply count=%d%s\n",
4191 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
4194 * Copy out the cached reply...
4196 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
4197 u16reply[ii] = ioc->hs_reply[ii];
4205 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4207 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4208 * @ioc: Pointer to MPT_ADAPTER structure
4209 * @howlong: How long to wait (in seconds)
4210 * @sleepFlag: Specifies whether the process can sleep
4212 * This routine waits (up to ~2 seconds max) for IOC doorbell
4213 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4214 * bit in its IntStatus register being clear.
4216 * Returns a negative value on failure, else wait loop count.
4219 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4225 cntdn = 1000 * howlong;
4227 if (sleepFlag == CAN_SLEEP) {
4230 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4231 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4238 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4239 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4246 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell ACK (count=%d)\n",
4251 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4252 ioc->name, count, intstat);
4256 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4258 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4259 * @ioc: Pointer to MPT_ADAPTER structure
4260 * @howlong: How long to wait (in seconds)
4261 * @sleepFlag: Specifies whether the process can sleep
4263 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4264 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4266 * Returns a negative value on failure, else wait loop count.
4269 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4275 cntdn = 1000 * howlong;
4276 if (sleepFlag == CAN_SLEEP) {
4278 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4279 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4286 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4287 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4295 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4296 ioc->name, count, howlong));
4300 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4301 ioc->name, count, intstat);
4305 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4307 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4308 * @ioc: Pointer to MPT_ADAPTER structure
4309 * @howlong: How long to wait (in seconds)
4310 * @sleepFlag: Specifies whether the process can sleep
4312 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4313 * Reply is cached to IOC private area large enough to hold a maximum
4314 * of 128 bytes of reply data.
4316 * Returns a negative value on failure, else size of reply in WORDS.
4319 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4324 u16 *hs_reply = ioc->hs_reply;
4325 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4328 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4331 * Get first two u16's so we can look at IOC's intended reply MsgLength
4334 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4337 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4338 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4339 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4342 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4343 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4347 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4348 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4349 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4352 * If no error (and IOC said MsgLength is > 0), piece together
4353 * reply 16 bits at a time.
4355 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4356 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4358 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4359 /* don't overflow our IOC hs_reply[] buffer! */
4360 if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
4361 hs_reply[u16cnt] = hword;
4362 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4365 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4367 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4370 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4375 else if (u16cnt != (2 * mptReply->MsgLength)) {
4378 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4383 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name));
4384 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply)
4386 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4387 ioc->name, t, u16cnt/2));
4391 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4393 * GetLanConfigPages - Fetch LANConfig pages.
4394 * @ioc: Pointer to MPT_ADAPTER structure
4396 * Return: 0 for success
4397 * -ENOMEM if no memory available
4398 * -EPERM if not allowed due to ISR context
4399 * -EAGAIN if no msg frames currently available
4400 * -EFAULT for non-successful reply or no reply (timeout)
4403 GetLanConfigPages(MPT_ADAPTER *ioc)
4405 ConfigPageHeader_t hdr;
4407 LANPage0_t *ppage0_alloc;
4408 dma_addr_t page0_dma;
4409 LANPage1_t *ppage1_alloc;
4410 dma_addr_t page1_dma;
4415 /* Get LAN Page 0 header */
4416 hdr.PageVersion = 0;
4419 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4420 cfg.cfghdr.hdr = &hdr;
4422 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4427 if ((rc = mpt_config(ioc, &cfg)) != 0)
4430 if (hdr.PageLength > 0) {
4431 data_sz = hdr.PageLength * 4;
4432 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4435 memset((u8 *)ppage0_alloc, 0, data_sz);
4436 cfg.physAddr = page0_dma;
4437 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4439 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4441 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4442 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4446 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4449 * Normalize endianness of structure data,
4450 * by byte-swapping all > 1 byte fields!
4459 /* Get LAN Page 1 header */
4460 hdr.PageVersion = 0;
4463 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4464 cfg.cfghdr.hdr = &hdr;
4466 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4470 if ((rc = mpt_config(ioc, &cfg)) != 0)
4473 if (hdr.PageLength == 0)
4476 data_sz = hdr.PageLength * 4;
4478 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4480 memset((u8 *)ppage1_alloc, 0, data_sz);
4481 cfg.physAddr = page1_dma;
4482 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4484 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4486 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4487 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4490 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4493 * Normalize endianness of structure data,
4494 * by byte-swapping all > 1 byte fields!
4502 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4504 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
4505 * @ioc: Pointer to MPT_ADAPTER structure
4506 * @persist_opcode: see below
4508 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4509 * devices not currently present.
4510 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4512 * NOTE: Don't use not this function during interrupt time.
4514 * Returns 0 for success, non-zero error
4517 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4519 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4521 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
4522 SasIoUnitControlReply_t *sasIoUnitCntrReply;
4523 MPT_FRAME_HDR *mf = NULL;
4524 MPIHeader_t *mpi_hdr;
4527 /* insure garbage is not sent to fw */
4528 switch(persist_opcode) {
4530 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
4531 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
4539 printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode);
4541 /* Get a MF for this command.
4543 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4544 printk("%s: no msg frames!\n",__FUNCTION__);
4548 mpi_hdr = (MPIHeader_t *) mf;
4549 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
4550 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
4551 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
4552 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
4553 sasIoUnitCntrReq->Operation = persist_opcode;
4555 init_timer(&ioc->persist_timer);
4556 ioc->persist_timer.data = (unsigned long) ioc;
4557 ioc->persist_timer.function = mpt_timer_expired;
4558 ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
4559 ioc->persist_wait_done=0;
4560 add_timer(&ioc->persist_timer);
4561 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4562 wait_event(mpt_waitq, ioc->persist_wait_done);
4564 sasIoUnitCntrReply =
4565 (SasIoUnitControlReply_t *)ioc->persist_reply_frame;
4566 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
4567 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4569 sasIoUnitCntrReply->IOCStatus,
4570 sasIoUnitCntrReply->IOCLogInfo);
4574 printk("%s: success\n",__FUNCTION__);
4578 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4581 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
4582 MpiEventDataRaid_t * pRaidEventData)
4591 volume = pRaidEventData->VolumeID;
4592 reason = pRaidEventData->ReasonCode;
4593 disk = pRaidEventData->PhysDiskNum;
4594 status = le32_to_cpu(pRaidEventData->SettingsStatus);
4595 flags = (status >> 0) & 0xff;
4596 state = (status >> 8) & 0xff;
4598 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
4602 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
4603 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
4604 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
4605 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
4606 ioc->name, disk, volume);
4608 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
4613 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4614 printk(MYIOC_s_INFO_FMT " volume has been created\n",
4618 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4620 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
4624 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
4625 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
4629 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4630 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
4632 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
4634 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
4636 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
4639 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
4641 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
4642 ? ", quiesced" : "",
4643 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
4644 ? ", resync in progress" : "" );
4647 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
4648 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
4652 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4653 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
4657 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4658 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
4662 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
4663 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
4667 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4668 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
4670 state == MPI_PHYSDISK0_STATUS_ONLINE
4672 : state == MPI_PHYSDISK0_STATUS_MISSING
4674 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
4676 : state == MPI_PHYSDISK0_STATUS_FAILED
4678 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
4680 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
4681 ? "offline requested"
4682 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
4683 ? "failed requested"
4684 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
4687 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
4688 ? ", out of sync" : "",
4689 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
4690 ? ", quiesced" : "" );
4693 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
4694 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
4698 case MPI_EVENT_RAID_RC_SMART_DATA:
4699 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
4700 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
4703 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
4704 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
4710 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4712 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4713 * @ioc: Pointer to MPT_ADAPTER structure
4715 * Returns: 0 for success
4716 * -ENOMEM if no memory available
4717 * -EPERM if not allowed due to ISR context
4718 * -EAGAIN if no msg frames currently available
4719 * -EFAULT for non-successful reply or no reply (timeout)
4722 GetIoUnitPage2(MPT_ADAPTER *ioc)
4724 ConfigPageHeader_t hdr;
4726 IOUnitPage2_t *ppage_alloc;
4727 dma_addr_t page_dma;
4731 /* Get the page header */
4732 hdr.PageVersion = 0;
4735 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4736 cfg.cfghdr.hdr = &hdr;
4738 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4743 if ((rc = mpt_config(ioc, &cfg)) != 0)
4746 if (hdr.PageLength == 0)
4749 /* Read the config page */
4750 data_sz = hdr.PageLength * 4;
4752 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4754 memset((u8 *)ppage_alloc, 0, data_sz);
4755 cfg.physAddr = page_dma;
4756 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4758 /* If Good, save data */
4759 if ((rc = mpt_config(ioc, &cfg)) == 0)
4760 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4762 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4768 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4770 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4771 * @ioc: Pointer to a Adapter Strucutre
4772 * @portnum: IOC port number
4774 * Return: -EFAULT if read of config page header fails
4776 * If read of SCSI Port Page 0 fails,
4777 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4778 * Adapter settings: async, narrow
4780 * If read of SCSI Port Page 2 fails,
4781 * Adapter settings valid
4782 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4787 * CHECK - what type of locking mechanisms should be used????
4790 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4795 ConfigPageHeader_t header;
4801 if (!ioc->spi_data.nvram) {
4804 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4805 mem = kmalloc(sz, GFP_ATOMIC);
4809 ioc->spi_data.nvram = (int *) mem;
4811 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4812 ioc->name, ioc->spi_data.nvram, sz));
4815 /* Invalidate NVRAM information
4817 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4818 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4821 /* Read SPP0 header, allocate memory, then read page.
4823 header.PageVersion = 0;
4824 header.PageLength = 0;
4825 header.PageNumber = 0;
4826 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4827 cfg.cfghdr.hdr = &header;
4829 cfg.pageAddr = portnum;
4830 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4832 cfg.timeout = 0; /* use default */
4833 if (mpt_config(ioc, &cfg) != 0)
4836 if (header.PageLength > 0) {
4837 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4839 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4840 cfg.physAddr = buf_dma;
4841 if (mpt_config(ioc, &cfg) != 0) {
4842 ioc->spi_data.maxBusWidth = MPT_NARROW;
4843 ioc->spi_data.maxSyncOffset = 0;
4844 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4845 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4847 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4848 "Unable to read PortPage0 minSyncFactor=%x\n",
4849 ioc->name, ioc->spi_data.minSyncFactor));
4851 /* Save the Port Page 0 data
4853 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
4854 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4855 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4857 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
4858 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4859 ddvprintk(ioc, printk(KERN_INFO MYNAM
4860 " :%s noQas due to Capabilities=%x\n",
4861 ioc->name, pPP0->Capabilities));
4863 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4864 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4866 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4867 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4868 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4869 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4870 "PortPage0 minSyncFactor=%x\n",
4871 ioc->name, ioc->spi_data.minSyncFactor));
4873 ioc->spi_data.maxSyncOffset = 0;
4874 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4877 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4879 /* Update the minSyncFactor based on bus type.
4881 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4882 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
4884 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
4885 ioc->spi_data.minSyncFactor = MPT_ULTRA;
4886 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4887 "HVD or SE detected, minSyncFactor=%x\n",
4888 ioc->name, ioc->spi_data.minSyncFactor));
4893 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4898 /* SCSI Port Page 2 - Read the header then the page.
4900 header.PageVersion = 0;
4901 header.PageLength = 0;
4902 header.PageNumber = 2;
4903 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4904 cfg.cfghdr.hdr = &header;
4906 cfg.pageAddr = portnum;
4907 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4909 if (mpt_config(ioc, &cfg) != 0)
4912 if (header.PageLength > 0) {
4913 /* Allocate memory and read SCSI Port Page 2
4915 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4917 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
4918 cfg.physAddr = buf_dma;
4919 if (mpt_config(ioc, &cfg) != 0) {
4920 /* Nvram data is left with INVALID mark
4923 } else if (ioc->pcidev->vendor == PCI_VENDOR_ID_ATTO) {
4925 /* This is an ATTO adapter, read Page2 accordingly
4927 ATTO_SCSIPortPage2_t *pPP2 = (ATTO_SCSIPortPage2_t *) pbuf;
4928 ATTODeviceInfo_t *pdevice = NULL;
4931 /* Save the Port Page 2 data
4932 * (reformat into a 32bit quantity)
4934 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4935 pdevice = &pPP2->DeviceSettings[ii];
4936 ATTOFlags = le16_to_cpu(pdevice->ATTOFlags);
4939 /* Translate ATTO device flags to LSI format
4941 if (ATTOFlags & ATTOFLAG_DISC)
4942 data |= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE);
4943 if (ATTOFlags & ATTOFLAG_ID_ENB)
4944 data |= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE);
4945 if (ATTOFlags & ATTOFLAG_LUN_ENB)
4946 data |= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE);
4947 if (ATTOFlags & ATTOFLAG_TAGGED)
4948 data |= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE);
4949 if (!(ATTOFlags & ATTOFLAG_WIDE_ENB))
4950 data |= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE);
4952 data = (data << 16) | (pdevice->Period << 8) | 10;
4953 ioc->spi_data.nvram[ii] = data;
4956 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
4957 MpiDeviceInfo_t *pdevice = NULL;
4960 * Save "Set to Avoid SCSI Bus Resets" flag
4962 ioc->spi_data.bus_reset =
4963 (le32_to_cpu(pPP2->PortFlags) &
4964 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
4967 /* Save the Port Page 2 data
4968 * (reformat into a 32bit quantity)
4970 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
4971 ioc->spi_data.PortFlags = data;
4972 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4973 pdevice = &pPP2->DeviceSettings[ii];
4974 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
4975 (pdevice->SyncFactor << 8) | pdevice->Timeout;
4976 ioc->spi_data.nvram[ii] = data;
4980 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4984 /* Update Adapter limits with those from NVRAM
4985 * Comment: Don't need to do this. Target performance
4986 * parameters will never exceed the adapters limits.
4992 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4994 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
4995 * @ioc: Pointer to a Adapter Strucutre
4996 * @portnum: IOC port number
4998 * Return: -EFAULT if read of config page header fails
5002 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
5005 ConfigPageHeader_t header;
5007 /* Read the SCSI Device Page 1 header
5009 header.PageVersion = 0;
5010 header.PageLength = 0;
5011 header.PageNumber = 1;
5012 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5013 cfg.cfghdr.hdr = &header;
5015 cfg.pageAddr = portnum;
5016 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5019 if (mpt_config(ioc, &cfg) != 0)
5022 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
5023 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
5025 header.PageVersion = 0;
5026 header.PageLength = 0;
5027 header.PageNumber = 0;
5028 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5029 if (mpt_config(ioc, &cfg) != 0)
5032 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
5033 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
5035 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 0: version %d length %d\n",
5036 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
5038 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 1: version %d length %d\n",
5039 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
5044 * mpt_inactive_raid_list_free - This clears this link list.
5045 * @ioc : pointer to per adapter structure
5048 mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
5050 struct inactive_raid_component_info *component_info, *pNext;
5052 if (list_empty(&ioc->raid_data.inactive_list))
5055 down(&ioc->raid_data.inactive_list_mutex);
5056 list_for_each_entry_safe(component_info, pNext,
5057 &ioc->raid_data.inactive_list, list) {
5058 list_del(&component_info->list);
5059 kfree(component_info);
5061 up(&ioc->raid_data.inactive_list_mutex);
5065 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5067 * @ioc : pointer to per adapter structure
5068 * @channel : volume channel
5069 * @id : volume target id
5072 mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
5075 ConfigPageHeader_t hdr;
5076 dma_addr_t dma_handle;
5077 pRaidVolumePage0_t buffer = NULL;
5079 RaidPhysDiskPage0_t phys_disk;
5080 struct inactive_raid_component_info *component_info;
5081 int handle_inactive_volumes;
5083 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5084 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5085 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
5086 cfg.pageAddr = (channel << 8) + id;
5087 cfg.cfghdr.hdr = &hdr;
5088 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5090 if (mpt_config(ioc, &cfg) != 0)
5093 if (!hdr.PageLength)
5096 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5102 cfg.physAddr = dma_handle;
5103 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5105 if (mpt_config(ioc, &cfg) != 0)
5108 if (!buffer->NumPhysDisks)
5111 handle_inactive_volumes =
5112 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
5113 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
5114 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
5115 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
5117 if (!handle_inactive_volumes)
5120 down(&ioc->raid_data.inactive_list_mutex);
5121 for (i = 0; i < buffer->NumPhysDisks; i++) {
5122 if(mpt_raid_phys_disk_pg0(ioc,
5123 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
5126 if ((component_info = kmalloc(sizeof (*component_info),
5127 GFP_KERNEL)) == NULL)
5130 component_info->volumeID = id;
5131 component_info->volumeBus = channel;
5132 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
5133 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
5134 component_info->d.PhysDiskID = phys_disk.PhysDiskID;
5135 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
5137 list_add_tail(&component_info->list,
5138 &ioc->raid_data.inactive_list);
5140 up(&ioc->raid_data.inactive_list_mutex);
5144 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5149 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5150 * @ioc: Pointer to a Adapter Structure
5151 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5152 * @phys_disk: requested payload data returned
5156 * -EFAULT if read of config page header fails or data pointer not NULL
5157 * -ENOMEM if pci_alloc failed
5160 mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk)
5163 ConfigPageHeader_t hdr;
5164 dma_addr_t dma_handle;
5165 pRaidPhysDiskPage0_t buffer = NULL;
5168 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5169 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5171 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5172 cfg.cfghdr.hdr = &hdr;
5174 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5176 if (mpt_config(ioc, &cfg) != 0) {
5181 if (!hdr.PageLength) {
5186 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5194 cfg.physAddr = dma_handle;
5195 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5196 cfg.pageAddr = phys_disk_num;
5198 if (mpt_config(ioc, &cfg) != 0) {
5204 memcpy(phys_disk, buffer, sizeof(*buffer));
5205 phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
5210 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5217 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5218 * @ioc: Pointer to a Adapter Strucutre
5219 * @portnum: IOC port number
5223 * -EFAULT if read of config page header fails or data pointer not NULL
5224 * -ENOMEM if pci_alloc failed
5227 mpt_findImVolumes(MPT_ADAPTER *ioc)
5231 dma_addr_t ioc2_dma;
5233 ConfigPageHeader_t header;
5238 if (!ioc->ir_firmware)
5241 /* Free the old page
5243 kfree(ioc->raid_data.pIocPg2);
5244 ioc->raid_data.pIocPg2 = NULL;
5245 mpt_inactive_raid_list_free(ioc);
5247 /* Read IOCP2 header then the page.
5249 header.PageVersion = 0;
5250 header.PageLength = 0;
5251 header.PageNumber = 2;
5252 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5253 cfg.cfghdr.hdr = &header;
5256 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5259 if (mpt_config(ioc, &cfg) != 0)
5262 if (header.PageLength == 0)
5265 iocpage2sz = header.PageLength * 4;
5266 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
5270 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5271 cfg.physAddr = ioc2_dma;
5272 if (mpt_config(ioc, &cfg) != 0)
5275 mem = kmalloc(iocpage2sz, GFP_KERNEL);
5279 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
5280 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
5282 mpt_read_ioc_pg_3(ioc);
5284 for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
5285 mpt_inactive_raid_volumes(ioc,
5286 pIoc2->RaidVolume[i].VolumeBus,
5287 pIoc2->RaidVolume[i].VolumeID);
5290 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
5296 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
5301 ConfigPageHeader_t header;
5302 dma_addr_t ioc3_dma;
5305 /* Free the old page
5307 kfree(ioc->raid_data.pIocPg3);
5308 ioc->raid_data.pIocPg3 = NULL;
5310 /* There is at least one physical disk.
5311 * Read and save IOC Page 3
5313 header.PageVersion = 0;
5314 header.PageLength = 0;
5315 header.PageNumber = 3;
5316 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5317 cfg.cfghdr.hdr = &header;
5320 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5323 if (mpt_config(ioc, &cfg) != 0)
5326 if (header.PageLength == 0)
5329 /* Read Header good, alloc memory
5331 iocpage3sz = header.PageLength * 4;
5332 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
5336 /* Read the Page and save the data
5337 * into malloc'd memory.
5339 cfg.physAddr = ioc3_dma;
5340 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5341 if (mpt_config(ioc, &cfg) == 0) {
5342 mem = kmalloc(iocpage3sz, GFP_KERNEL);
5344 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
5345 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
5349 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
5355 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
5359 ConfigPageHeader_t header;
5360 dma_addr_t ioc4_dma;
5363 /* Read and save IOC Page 4
5365 header.PageVersion = 0;
5366 header.PageLength = 0;
5367 header.PageNumber = 4;
5368 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5369 cfg.cfghdr.hdr = &header;
5372 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5375 if (mpt_config(ioc, &cfg) != 0)
5378 if (header.PageLength == 0)
5381 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
5382 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
5383 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
5386 ioc->alloc_total += iocpage4sz;
5388 ioc4_dma = ioc->spi_data.IocPg4_dma;
5389 iocpage4sz = ioc->spi_data.IocPg4Sz;
5392 /* Read the Page into dma memory.
5394 cfg.physAddr = ioc4_dma;
5395 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5396 if (mpt_config(ioc, &cfg) == 0) {
5397 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
5398 ioc->spi_data.IocPg4_dma = ioc4_dma;
5399 ioc->spi_data.IocPg4Sz = iocpage4sz;
5401 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
5402 ioc->spi_data.pIocPg4 = NULL;
5403 ioc->alloc_total -= iocpage4sz;
5408 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
5412 ConfigPageHeader_t header;
5413 dma_addr_t ioc1_dma;
5417 /* Check the Coalescing Timeout in IOC Page 1
5419 header.PageVersion = 0;
5420 header.PageLength = 0;
5421 header.PageNumber = 1;
5422 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5423 cfg.cfghdr.hdr = &header;
5426 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5429 if (mpt_config(ioc, &cfg) != 0)
5432 if (header.PageLength == 0)
5435 /* Read Header good, alloc memory
5437 iocpage1sz = header.PageLength * 4;
5438 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
5442 /* Read the Page and check coalescing timeout
5444 cfg.physAddr = ioc1_dma;
5445 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5446 if (mpt_config(ioc, &cfg) == 0) {
5448 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
5449 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
5450 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
5452 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Coalescing Enabled Timeout = %d\n",
5455 if (tmp > MPT_COALESCING_TIMEOUT) {
5456 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
5458 /* Write NVRAM and current
5461 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5462 if (mpt_config(ioc, &cfg) == 0) {
5463 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Reset Current Coalescing Timeout to = %d\n",
5464 ioc->name, MPT_COALESCING_TIMEOUT));
5466 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
5467 if (mpt_config(ioc, &cfg) == 0) {
5468 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5469 "Reset NVRAM Coalescing Timeout to = %d\n",
5470 ioc->name, MPT_COALESCING_TIMEOUT));
5472 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5473 "Reset NVRAM Coalescing Timeout Failed\n",
5478 dprintk(ioc, printk(MYIOC_s_WARN_FMT
5479 "Reset of Current Coalescing Timeout Failed!\n",
5485 dprintk(ioc, printk(MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
5489 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
5495 mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
5498 ConfigPageHeader_t hdr;
5500 ManufacturingPage0_t *pbuf = NULL;
5502 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5503 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5505 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
5506 cfg.cfghdr.hdr = &hdr;
5508 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5511 if (mpt_config(ioc, &cfg) != 0)
5514 if (!cfg.cfghdr.hdr->PageLength)
5517 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5518 pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
5522 cfg.physAddr = buf_dma;
5524 if (mpt_config(ioc, &cfg) != 0)
5527 memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name));
5528 memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
5529 memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
5534 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
5537 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5539 * SendEventNotification - Send EventNotification (on or off) request to adapter
5540 * @ioc: Pointer to MPT_ADAPTER structure
5541 * @EvSwitch: Event switch flags
5544 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
5546 EventNotification_t *evnp;
5548 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
5550 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
5554 memset(evnp, 0, sizeof(*evnp));
5556 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
5558 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
5559 evnp->ChainOffset = 0;
5561 evnp->Switch = EvSwitch;
5563 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
5568 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5570 * SendEventAck - Send EventAck request to MPT adapter.
5571 * @ioc: Pointer to MPT_ADAPTER structure
5572 * @evnp: Pointer to original EventNotification request
5575 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
5579 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5580 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
5581 ioc->name,__FUNCTION__));
5585 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventAck\n", ioc->name));
5587 pAck->Function = MPI_FUNCTION_EVENT_ACK;
5588 pAck->ChainOffset = 0;
5589 pAck->Reserved[0] = pAck->Reserved[1] = 0;
5591 pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
5592 pAck->Event = evnp->Event;
5593 pAck->EventContext = evnp->EventContext;
5595 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
5600 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5602 * mpt_config - Generic function to issue config message
5603 * @ioc: Pointer to an adapter structure
5604 * @pCfg: Pointer to a configuration structure. Struct contains
5605 * action, page address, direction, physical address
5606 * and pointer to a configuration page header
5607 * Page header is updated.
5609 * Returns 0 for success
5610 * -EPERM if not allowed due to ISR context
5611 * -EAGAIN if no msg frames currently available
5612 * -EFAULT for non-successful reply or no reply (timeout)
5615 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5618 ConfigExtendedPageHeader_t *pExtHdr = NULL;
5620 unsigned long flags;
5625 /* Prevent calling wait_event() (below), if caller happens
5626 * to be in ISR context, because that is fatal!
5628 in_isr = in_interrupt();
5630 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
5635 /* Get and Populate a free Frame
5637 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5638 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
5642 pReq = (Config_t *)mf;
5643 pReq->Action = pCfg->action;
5645 pReq->ChainOffset = 0;
5646 pReq->Function = MPI_FUNCTION_CONFIG;
5648 /* Assume page type is not extended and clear "reserved" fields. */
5649 pReq->ExtPageLength = 0;
5650 pReq->ExtPageType = 0;
5653 for (ii=0; ii < 8; ii++)
5654 pReq->Reserved2[ii] = 0;
5656 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
5657 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
5658 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
5659 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
5661 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5662 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
5663 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
5664 pReq->ExtPageType = pExtHdr->ExtPageType;
5665 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
5667 /* Page Length must be treated as a reserved field for the extended header. */
5668 pReq->Header.PageLength = 0;
5671 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
5673 /* Add a SGE to the config request.
5676 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
5678 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
5680 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5681 flagsLength |= pExtHdr->ExtPageLength * 4;
5683 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n",
5684 ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action));
5687 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
5689 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n",
5690 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
5693 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
5695 /* Append pCfg pointer to end of mf
5697 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5699 /* Initalize the timer
5701 init_timer(&pCfg->timer);
5702 pCfg->timer.data = (unsigned long) ioc;
5703 pCfg->timer.function = mpt_timer_expired;
5704 pCfg->wait_done = 0;
5706 /* Set the timer; ensure 10 second minimum */
5707 if (pCfg->timeout < 10)
5708 pCfg->timer.expires = jiffies + HZ*10;
5710 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5712 /* Add to end of Q, set timer and then issue this command */
5713 spin_lock_irqsave(&ioc->FreeQlock, flags);
5714 list_add_tail(&pCfg->linkage, &ioc->configQ);
5715 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5717 add_timer(&pCfg->timer);
5718 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5719 wait_event(mpt_waitq, pCfg->wait_done);
5721 /* mf has been freed - do not access */
5728 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5730 * mpt_timer_expired - Callback for timer process.
5731 * Used only internal config functionality.
5732 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5735 mpt_timer_expired(unsigned long data)
5737 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
5739 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired! \n", ioc->name));
5741 /* Perform a FW reload */
5742 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
5743 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
5745 /* No more processing.
5746 * Hard reset clean-up will wake up
5747 * process and free all resources.
5749 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired complete!\n", ioc->name));
5754 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5756 * mpt_ioc_reset - Base cleanup for hard reset
5757 * @ioc: Pointer to the adapter structure
5758 * @reset_phase: Indicates pre- or post-reset functionality
5760 * Remark: Frees resources with internally generated commands.
5763 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
5766 unsigned long flags;
5768 dprintk(ioc, printk(KERN_DEBUG MYNAM
5769 ": IOC %s_reset routed to MPT base driver!\n",
5770 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
5771 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
5773 if (reset_phase == MPT_IOC_SETUP_RESET) {
5775 } else if (reset_phase == MPT_IOC_PRE_RESET) {
5776 /* If the internal config Q is not empty -
5777 * delete timer. MF resources will be freed when
5778 * the FIFO's are primed.
5780 spin_lock_irqsave(&ioc->FreeQlock, flags);
5781 list_for_each_entry(pCfg, &ioc->configQ, linkage)
5782 del_timer(&pCfg->timer);
5783 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5788 /* Search the configQ for internal commands.
5789 * Flush the Q, and wake up all suspended threads.
5791 spin_lock_irqsave(&ioc->FreeQlock, flags);
5792 list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
5793 list_del(&pCfg->linkage);
5795 pCfg->status = MPT_CONFIG_ERROR;
5796 pCfg->wait_done = 1;
5797 wake_up(&mpt_waitq);
5799 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5802 return 1; /* currently means nothing really */
5806 #ifdef CONFIG_PROC_FS /* { */
5807 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5809 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5811 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5813 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5815 * Returns 0 for success, non-zero for failure.
5818 procmpt_create(void)
5820 struct proc_dir_entry *ent;
5822 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
5823 if (mpt_proc_root_dir == NULL)
5826 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5828 ent->read_proc = procmpt_summary_read;
5830 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5832 ent->read_proc = procmpt_version_read;
5837 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5839 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5841 * Returns 0 for success, non-zero for failure.
5844 procmpt_destroy(void)
5846 remove_proc_entry("version", mpt_proc_root_dir);
5847 remove_proc_entry("summary", mpt_proc_root_dir);
5848 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
5851 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5853 * procmpt_summary_read - Handle read request of a summary file
5854 * @buf: Pointer to area to write information
5855 * @start: Pointer to start pointer
5856 * @offset: Offset to start writing
5857 * @request: Amount of read data requested
5858 * @eof: Pointer to EOF integer
5861 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
5862 * Returns number of characters written to process performing the read.
5865 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5875 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5879 list_for_each_entry(ioc, &ioc_list, list) {
5882 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5885 if ((out-buf) >= request)
5892 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5895 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5897 * procmpt_version_read - Handle read request from /proc/mpt/version.
5898 * @buf: Pointer to area to write information
5899 * @start: Pointer to start pointer
5900 * @offset: Offset to start writing
5901 * @request: Amount of read data requested
5902 * @eof: Pointer to EOF integer
5905 * Returns number of characters written to process performing the read.
5908 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5911 int scsi, fc, sas, lan, ctl, targ, dmp;
5915 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
5916 len += sprintf(buf+len, " Fusion MPT base driver\n");
5918 scsi = fc = sas = lan = ctl = targ = dmp = 0;
5919 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5921 if (MptCallbacks[ii]) {
5922 switch (MptDriverClass[ii]) {
5924 if (!scsi++) drvname = "SPI host";
5927 if (!fc++) drvname = "FC host";
5930 if (!sas++) drvname = "SAS host";
5933 if (!lan++) drvname = "LAN";
5936 if (!targ++) drvname = "SCSI target";
5939 if (!ctl++) drvname = "ioctl";
5944 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
5948 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5951 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5953 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
5954 * @buf: Pointer to area to write information
5955 * @start: Pointer to start pointer
5956 * @offset: Offset to start writing
5957 * @request: Amount of read data requested
5958 * @eof: Pointer to EOF integer
5961 * Returns number of characters written to process performing the read.
5964 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5966 MPT_ADAPTER *ioc = data;
5972 mpt_get_fw_exp_ver(expVer, ioc);
5974 len = sprintf(buf, "%s:", ioc->name);
5975 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
5976 len += sprintf(buf+len, " (f/w download boot flag set)");
5977 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
5978 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
5980 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
5981 ioc->facts.ProductID,
5983 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
5984 if (ioc->facts.FWImageSize)
5985 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
5986 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
5987 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
5988 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
5990 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
5991 ioc->facts.CurrentHostMfaHighAddr);
5992 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
5993 ioc->facts.CurrentSenseBufferHighAddr);
5995 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
5996 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
5998 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
5999 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
6001 * Rounding UP to nearest 4-kB boundary here...
6003 sz = (ioc->req_sz * ioc->req_depth) + 128;
6004 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
6005 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6006 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
6007 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
6008 4*ioc->facts.RequestFrameSize,
6009 ioc->facts.GlobalCredits);
6011 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
6012 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
6013 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
6014 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6015 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
6016 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
6017 ioc->facts.CurReplyFrameSize,
6018 ioc->facts.ReplyQueueDepth);
6020 len += sprintf(buf+len, " MaxDevices = %d\n",
6021 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
6022 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
6025 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
6026 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
6028 ioc->facts.NumberOfPorts);
6029 if (ioc->bus_type == FC) {
6030 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
6031 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6032 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6033 a[5], a[4], a[3], a[2], a[1], a[0]);
6035 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
6036 ioc->fc_port_page0[p].WWNN.High,
6037 ioc->fc_port_page0[p].WWNN.Low,
6038 ioc->fc_port_page0[p].WWPN.High,
6039 ioc->fc_port_page0[p].WWPN.Low);
6043 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6046 #endif /* CONFIG_PROC_FS } */
6048 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6050 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
6053 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
6054 sprintf(buf, " (Exp %02d%02d)",
6055 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
6056 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
6059 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
6060 strcat(buf, " [MDBG]");
6064 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6066 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6067 * @ioc: Pointer to MPT_ADAPTER structure
6068 * @buffer: Pointer to buffer where IOC summary info should be written
6069 * @size: Pointer to number of bytes we wrote (set by this routine)
6070 * @len: Offset at which to start writing in buffer
6071 * @showlan: Display LAN stuff?
6073 * This routine writes (english readable) ASCII text, which represents
6074 * a summary of IOC information, to a buffer.
6077 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
6082 mpt_get_fw_exp_ver(expVer, ioc);
6085 * Shorter summary of attached ioc's...
6087 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6090 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
6091 ioc->facts.FWVersion.Word,
6093 ioc->facts.NumberOfPorts,
6096 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6097 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6098 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6099 a[5], a[4], a[3], a[2], a[1], a[0]);
6102 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
6105 y += sprintf(buffer+len+y, " (disabled)");
6107 y += sprintf(buffer+len+y, "\n");
6112 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6116 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6118 * mpt_HardResetHandler - Generic reset handler
6119 * @ioc: Pointer to MPT_ADAPTER structure
6120 * @sleepFlag: Indicates if sleep or schedule must be called.
6122 * Issues SCSI Task Management call based on input arg values.
6123 * If TaskMgmt fails, returns associated SCSI request.
6125 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
6126 * or a non-interrupt thread. In the former, must not call schedule().
6128 * Note: A return of -1 is a FATAL error case, as it means a
6129 * FW reload/initialization failed.
6131 * Returns 0 for SUCCESS or -1 if FAILED.
6134 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6137 unsigned long flags;
6139 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name));
6141 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
6142 printk("MF count 0x%x !\n", ioc->mfcnt);
6145 /* Reset the adapter. Prevent more than 1 call to
6146 * mpt_do_ioc_recovery at any instant in time.
6148 spin_lock_irqsave(&ioc->diagLock, flags);
6149 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
6150 spin_unlock_irqrestore(&ioc->diagLock, flags);
6153 ioc->diagPending = 1;
6155 spin_unlock_irqrestore(&ioc->diagLock, flags);
6157 /* FIXME: If do_ioc_recovery fails, repeat....
6160 /* The SCSI driver needs to adjust timeouts on all current
6161 * commands prior to the diagnostic reset being issued.
6162 * Prevents timeouts occurring during a diagnostic reset...very bad.
6163 * For all other protocol drivers, this is a no-op.
6169 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
6170 if (MptResetHandlers[ii]) {
6171 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling IOC reset_setup handler #%d\n",
6173 r += mpt_signal_reset(ii, ioc, MPT_IOC_SETUP_RESET);
6175 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling alt-%s setup reset handler #%d\n",
6176 ioc->name, ioc->alt_ioc->name, ii));
6177 r += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_SETUP_RESET);
6183 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
6184 printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
6189 ioc->alt_ioc->reload_fw = 0;
6191 spin_lock_irqsave(&ioc->diagLock, flags);
6192 ioc->diagPending = 0;
6194 ioc->alt_ioc->diagPending = 0;
6195 spin_unlock_irqrestore(&ioc->diagLock, flags);
6197 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
6202 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6204 EventDescriptionStr(u8 event, u32 evData0, char *evStr)
6209 case MPI_EVENT_NONE:
6212 case MPI_EVENT_LOG_DATA:
6215 case MPI_EVENT_STATE_CHANGE:
6216 ds = "State Change";
6218 case MPI_EVENT_UNIT_ATTENTION:
6219 ds = "Unit Attention";
6221 case MPI_EVENT_IOC_BUS_RESET:
6222 ds = "IOC Bus Reset";
6224 case MPI_EVENT_EXT_BUS_RESET:
6225 ds = "External Bus Reset";
6227 case MPI_EVENT_RESCAN:
6228 ds = "Bus Rescan Event";
6230 case MPI_EVENT_LINK_STATUS_CHANGE:
6231 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
6232 ds = "Link Status(FAILURE) Change";
6234 ds = "Link Status(ACTIVE) Change";
6236 case MPI_EVENT_LOOP_STATE_CHANGE:
6237 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
6238 ds = "Loop State(LIP) Change";
6239 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
6240 ds = "Loop State(LPE) Change"; /* ??? */
6242 ds = "Loop State(LPB) Change"; /* ??? */
6244 case MPI_EVENT_LOGOUT:
6247 case MPI_EVENT_EVENT_CHANGE:
6253 case MPI_EVENT_INTEGRATED_RAID:
6255 u8 ReasonCode = (u8)(evData0 >> 16);
6256 switch (ReasonCode) {
6257 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
6258 ds = "Integrated Raid: Volume Created";
6260 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
6261 ds = "Integrated Raid: Volume Deleted";
6263 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
6264 ds = "Integrated Raid: Volume Settings Changed";
6266 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
6267 ds = "Integrated Raid: Volume Status Changed";
6269 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
6270 ds = "Integrated Raid: Volume Physdisk Changed";
6272 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
6273 ds = "Integrated Raid: Physdisk Created";
6275 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
6276 ds = "Integrated Raid: Physdisk Deleted";
6278 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
6279 ds = "Integrated Raid: Physdisk Settings Changed";
6281 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
6282 ds = "Integrated Raid: Physdisk Status Changed";
6284 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
6285 ds = "Integrated Raid: Domain Validation Needed";
6287 case MPI_EVENT_RAID_RC_SMART_DATA :
6288 ds = "Integrated Raid; Smart Data";
6290 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
6291 ds = "Integrated Raid: Replace Action Started";
6294 ds = "Integrated Raid";
6299 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
6300 ds = "SCSI Device Status Change";
6302 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
6304 u8 id = (u8)(evData0);
6305 u8 channel = (u8)(evData0 >> 8);
6306 u8 ReasonCode = (u8)(evData0 >> 16);
6307 switch (ReasonCode) {
6308 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
6309 snprintf(evStr, EVENT_DESCR_STR_SZ,
6310 "SAS Device Status Change: Added: "
6311 "id=%d channel=%d", id, channel);
6313 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
6314 snprintf(evStr, EVENT_DESCR_STR_SZ,
6315 "SAS Device Status Change: Deleted: "
6316 "id=%d channel=%d", id, channel);
6318 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
6319 snprintf(evStr, EVENT_DESCR_STR_SZ,
6320 "SAS Device Status Change: SMART Data: "
6321 "id=%d channel=%d", id, channel);
6323 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
6324 snprintf(evStr, EVENT_DESCR_STR_SZ,
6325 "SAS Device Status Change: No Persistancy: "
6326 "id=%d channel=%d", id, channel);
6328 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
6329 snprintf(evStr, EVENT_DESCR_STR_SZ,
6330 "SAS Device Status Change: Unsupported Device "
6331 "Discovered : id=%d channel=%d", id, channel);
6333 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
6334 snprintf(evStr, EVENT_DESCR_STR_SZ,
6335 "SAS Device Status Change: Internal Device "
6336 "Reset : id=%d channel=%d", id, channel);
6338 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
6339 snprintf(evStr, EVENT_DESCR_STR_SZ,
6340 "SAS Device Status Change: Internal Task "
6341 "Abort : id=%d channel=%d", id, channel);
6343 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
6344 snprintf(evStr, EVENT_DESCR_STR_SZ,
6345 "SAS Device Status Change: Internal Abort "
6346 "Task Set : id=%d channel=%d", id, channel);
6348 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
6349 snprintf(evStr, EVENT_DESCR_STR_SZ,
6350 "SAS Device Status Change: Internal Clear "
6351 "Task Set : id=%d channel=%d", id, channel);
6353 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
6354 snprintf(evStr, EVENT_DESCR_STR_SZ,
6355 "SAS Device Status Change: Internal Query "
6356 "Task : id=%d channel=%d", id, channel);
6359 snprintf(evStr, EVENT_DESCR_STR_SZ,
6360 "SAS Device Status Change: Unknown: "
6361 "id=%d channel=%d", id, channel);
6366 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
6367 ds = "Bus Timer Expired";
6369 case MPI_EVENT_QUEUE_FULL:
6371 u16 curr_depth = (u16)(evData0 >> 16);
6372 u8 channel = (u8)(evData0 >> 8);
6373 u8 id = (u8)(evData0);
6375 snprintf(evStr, EVENT_DESCR_STR_SZ,
6376 "Queue Full: channel=%d id=%d depth=%d",
6377 channel, id, curr_depth);
6380 case MPI_EVENT_SAS_SES:
6381 ds = "SAS SES Event";
6383 case MPI_EVENT_PERSISTENT_TABLE_FULL:
6384 ds = "Persistent Table Full";
6386 case MPI_EVENT_SAS_PHY_LINK_STATUS:
6388 u8 LinkRates = (u8)(evData0 >> 8);
6389 u8 PhyNumber = (u8)(evData0);
6390 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
6391 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
6392 switch (LinkRates) {
6393 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
6394 snprintf(evStr, EVENT_DESCR_STR_SZ,
6395 "SAS PHY Link Status: Phy=%d:"
6396 " Rate Unknown",PhyNumber);
6398 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
6399 snprintf(evStr, EVENT_DESCR_STR_SZ,
6400 "SAS PHY Link Status: Phy=%d:"
6401 " Phy Disabled",PhyNumber);
6403 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
6404 snprintf(evStr, EVENT_DESCR_STR_SZ,
6405 "SAS PHY Link Status: Phy=%d:"
6406 " Failed Speed Nego",PhyNumber);
6408 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
6409 snprintf(evStr, EVENT_DESCR_STR_SZ,
6410 "SAS PHY Link Status: Phy=%d:"
6411 " Sata OOB Completed",PhyNumber);
6413 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
6414 snprintf(evStr, EVENT_DESCR_STR_SZ,
6415 "SAS PHY Link Status: Phy=%d:"
6416 " Rate 1.5 Gbps",PhyNumber);
6418 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
6419 snprintf(evStr, EVENT_DESCR_STR_SZ,
6420 "SAS PHY Link Status: Phy=%d:"
6421 " Rate 3.0 Gpbs",PhyNumber);
6424 snprintf(evStr, EVENT_DESCR_STR_SZ,
6425 "SAS PHY Link Status: Phy=%d", PhyNumber);
6430 case MPI_EVENT_SAS_DISCOVERY_ERROR:
6431 ds = "SAS Discovery Error";
6433 case MPI_EVENT_IR_RESYNC_UPDATE:
6435 u8 resync_complete = (u8)(evData0 >> 16);
6436 snprintf(evStr, EVENT_DESCR_STR_SZ,
6437 "IR Resync Update: Complete = %d:",resync_complete);
6442 u8 ReasonCode = (u8)(evData0 >> 16);
6443 switch (ReasonCode) {
6444 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
6445 ds = "IR2: LD State Changed";
6447 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
6448 ds = "IR2: PD State Changed";
6450 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
6451 ds = "IR2: Bad Block Table Full";
6453 case MPI_EVENT_IR2_RC_PD_INSERTED:
6454 ds = "IR2: PD Inserted";
6456 case MPI_EVENT_IR2_RC_PD_REMOVED:
6457 ds = "IR2: PD Removed";
6459 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
6460 ds = "IR2: Foreign CFG Detected";
6462 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
6463 ds = "IR2: Rebuild Medium Error";
6471 case MPI_EVENT_SAS_DISCOVERY:
6474 ds = "SAS Discovery: Start";
6476 ds = "SAS Discovery: Stop";
6479 case MPI_EVENT_LOG_ENTRY_ADDED:
6480 ds = "SAS Log Entry Added";
6483 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
6485 u8 phy_num = (u8)(evData0);
6486 u8 port_num = (u8)(evData0 >> 8);
6487 u8 port_width = (u8)(evData0 >> 16);
6488 u8 primative = (u8)(evData0 >> 24);
6489 snprintf(evStr, EVENT_DESCR_STR_SZ,
6490 "SAS Broadcase Primative: phy=%d port=%d "
6491 "width=%d primative=0x%02x",
6492 phy_num, port_num, port_width, primative);
6496 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
6498 u8 reason = (u8)(evData0);
6499 u8 port_num = (u8)(evData0 >> 8);
6500 u16 handle = le16_to_cpu(evData0 >> 16);
6502 snprintf(evStr, EVENT_DESCR_STR_SZ,
6503 "SAS Initiator Device Status Change: reason=0x%02x "
6504 "port=%d handle=0x%04x",
6505 reason, port_num, handle);
6509 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
6511 u8 max_init = (u8)(evData0);
6512 u8 current_init = (u8)(evData0 >> 8);
6514 snprintf(evStr, EVENT_DESCR_STR_SZ,
6515 "SAS Initiator Device Table Overflow: max initiators=%02d "
6516 "current initators=%02d",
6517 max_init, current_init);
6520 case MPI_EVENT_SAS_SMP_ERROR:
6522 u8 status = (u8)(evData0);
6523 u8 port_num = (u8)(evData0 >> 8);
6524 u8 result = (u8)(evData0 >> 16);
6526 if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
6527 snprintf(evStr, EVENT_DESCR_STR_SZ,
6528 "SAS SMP Error: port=%d result=0x%02x",
6530 else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
6531 snprintf(evStr, EVENT_DESCR_STR_SZ,
6532 "SAS SMP Error: port=%d : CRC Error",
6534 else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
6535 snprintf(evStr, EVENT_DESCR_STR_SZ,
6536 "SAS SMP Error: port=%d : Timeout",
6538 else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
6539 snprintf(evStr, EVENT_DESCR_STR_SZ,
6540 "SAS SMP Error: port=%d : No Destination",
6542 else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
6543 snprintf(evStr, EVENT_DESCR_STR_SZ,
6544 "SAS SMP Error: port=%d : Bad Destination",
6547 snprintf(evStr, EVENT_DESCR_STR_SZ,
6548 "SAS SMP Error: port=%d : status=0x%02x",
6554 * MPT base "custom" events may be added here...
6561 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
6564 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6566 * ProcessEventNotification - Route EventNotificationReply to all event handlers
6567 * @ioc: Pointer to MPT_ADAPTER structure
6568 * @pEventReply: Pointer to EventNotification reply frame
6569 * @evHandlers: Pointer to integer, number of event handlers
6571 * Routes a received EventNotificationReply to all currently registered
6573 * Returns sum of event handlers return values.
6576 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
6584 char evStr[EVENT_DESCR_STR_SZ];
6588 * Do platform normalization of values
6590 event = le32_to_cpu(pEventReply->Event) & 0xFF;
6591 // evCtx = le32_to_cpu(pEventReply->EventContext);
6592 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
6594 evData0 = le32_to_cpu(pEventReply->Data[0]);
6597 EventDescriptionStr(event, evData0, evStr);
6598 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event:(%02Xh) : %s\n",
6603 #ifdef CONFIG_FUSION_LOGGING
6604 devtverboseprintk(ioc, printk(KERN_DEBUG MYNAM
6605 ": Event data:\n"));
6606 for (ii = 0; ii < evDataLen; ii++)
6607 devtverboseprintk(ioc, printk(" %08x",
6608 le32_to_cpu(pEventReply->Data[ii])));
6609 devtverboseprintk(ioc, printk(KERN_DEBUG "\n"));
6613 * Do general / base driver event processing
6616 case MPI_EVENT_EVENT_CHANGE: /* 0A */
6618 u8 evState = evData0 & 0xFF;
6620 /* CHECKME! What if evState unexpectedly says OFF (0)? */
6622 /* Update EventState field in cached IocFacts */
6623 if (ioc->facts.Function) {
6624 ioc->facts.EventState = evState;
6628 case MPI_EVENT_INTEGRATED_RAID:
6629 mptbase_raid_process_event_data(ioc,
6630 (MpiEventDataRaid_t *)pEventReply->Data);
6637 * Should this event be logged? Events are written sequentially.
6638 * When buffer is full, start again at the top.
6640 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
6643 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
6645 ioc->events[idx].event = event;
6646 ioc->events[idx].eventContext = ioc->eventContext;
6648 for (ii = 0; ii < 2; ii++) {
6650 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
6652 ioc->events[idx].data[ii] = 0;
6655 ioc->eventContext++;
6660 * Call each currently registered protocol event handler.
6662 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
6663 if (MptEvHandlers[ii]) {
6664 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Routing Event to event handler #%d\n",
6666 r += (*(MptEvHandlers[ii]))(ioc, pEventReply);
6670 /* FIXME? Examine results here? */
6673 * If needed, send (a single) EventAck.
6675 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
6676 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6677 "EventAck required\n",ioc->name));
6678 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
6679 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SendEventAck returned %d\n",
6684 *evHandlers = handlers;
6688 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6690 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
6691 * @ioc: Pointer to MPT_ADAPTER structure
6692 * @log_info: U32 LogInfo reply word from the IOC
6694 * Refer to lsi/mpi_log_fc.h.
6697 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
6699 char *desc = "unknown";
6701 switch (log_info & 0xFF000000) {
6702 case MPI_IOCLOGINFO_FC_INIT_BASE:
6703 desc = "FCP Initiator";
6705 case MPI_IOCLOGINFO_FC_TARGET_BASE:
6706 desc = "FCP Target";
6708 case MPI_IOCLOGINFO_FC_LAN_BASE:
6711 case MPI_IOCLOGINFO_FC_MSG_BASE:
6712 desc = "MPI Message Layer";
6714 case MPI_IOCLOGINFO_FC_LINK_BASE:
6717 case MPI_IOCLOGINFO_FC_CTX_BASE:
6718 desc = "Context Manager";
6720 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
6721 desc = "Invalid Field Offset";
6723 case MPI_IOCLOGINFO_FC_STATE_CHANGE:
6724 desc = "State Change Info";
6728 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
6729 ioc->name, log_info, desc, (log_info & 0xFFFFFF));
6732 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6734 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
6735 * @ioc: Pointer to MPT_ADAPTER structure
6736 * @mr: Pointer to MPT reply frame
6737 * @log_info: U32 LogInfo word from the IOC
6739 * Refer to lsi/sp_log.h.
6742 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
6744 u32 info = log_info & 0x00FF0000;
6745 char *desc = "unknown";
6749 desc = "bug! MID not found";
6750 if (ioc->reload_fw == 0)
6755 desc = "Parity Error";
6759 desc = "ASYNC Outbound Overrun";
6763 desc = "SYNC Offset Error";
6771 desc = "Msg In Overflow";
6779 desc = "Outbound DMA Overrun";
6783 desc = "Task Management";
6787 desc = "Device Problem";
6791 desc = "Invalid Phase Change";
6795 desc = "Untagged Table Size";
6800 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
6803 /* strings for sas loginfo */
6804 static char *originator_str[] = {
6809 static char *iop_code_str[] = {
6811 "Invalid SAS Address", /* 01h */
6813 "Invalid Page", /* 03h */
6814 "Diag Message Error", /* 04h */
6815 "Task Terminated", /* 05h */
6816 "Enclosure Management", /* 06h */
6817 "Target Mode" /* 07h */
6819 static char *pl_code_str[] = {
6821 "Open Failure", /* 01h */
6822 "Invalid Scatter Gather List", /* 02h */
6823 "Wrong Relative Offset or Frame Length", /* 03h */
6824 "Frame Transfer Error", /* 04h */
6825 "Transmit Frame Connected Low", /* 05h */
6826 "SATA Non-NCQ RW Error Bit Set", /* 06h */
6827 "SATA Read Log Receive Data Error", /* 07h */
6828 "SATA NCQ Fail All Commands After Error", /* 08h */
6829 "SATA Error in Receive Set Device Bit FIS", /* 09h */
6830 "Receive Frame Invalid Message", /* 0Ah */
6831 "Receive Context Message Valid Error", /* 0Bh */
6832 "Receive Frame Current Frame Error", /* 0Ch */
6833 "SATA Link Down", /* 0Dh */
6834 "Discovery SATA Init W IOS", /* 0Eh */
6835 "Config Invalid Page", /* 0Fh */
6836 "Discovery SATA Init Timeout", /* 10h */
6839 "IO Not Yet Executed", /* 13h */
6840 "IO Executed", /* 14h */
6841 "Persistent Reservation Out Not Affiliation "
6843 "Open Transmit DMA Abort", /* 16h */
6844 "IO Device Missing Delay Retry", /* 17h */
6845 "IO Cancelled Due to Recieve Error", /* 18h */
6853 "Enclosure Management" /* 20h */
6855 static char *ir_code_str[] = {
6856 "Raid Action Error", /* 00h */
6866 static char *raid_sub_code_str[] = {
6868 "Volume Creation Failed: Data Passed too "
6870 "Volume Creation Failed: Duplicate Volumes "
6871 "Attempted", /* 02h */
6872 "Volume Creation Failed: Max Number "
6873 "Supported Volumes Exceeded", /* 03h */
6874 "Volume Creation Failed: DMA Error", /* 04h */
6875 "Volume Creation Failed: Invalid Volume Type", /* 05h */
6876 "Volume Creation Failed: Error Reading "
6877 "MFG Page 4", /* 06h */
6878 "Volume Creation Failed: Creating Internal "
6879 "Structures", /* 07h */
6888 "Activation failed: Already Active Volume", /* 10h */
6889 "Activation failed: Unsupported Volume Type", /* 11h */
6890 "Activation failed: Too Many Active Volumes", /* 12h */
6891 "Activation failed: Volume ID in Use", /* 13h */
6892 "Activation failed: Reported Failure", /* 14h */
6893 "Activation failed: Importing a Volume", /* 15h */
6904 "Phys Disk failed: Too Many Phys Disks", /* 20h */
6905 "Phys Disk failed: Data Passed too Large", /* 21h */
6906 "Phys Disk failed: DMA Error", /* 22h */
6907 "Phys Disk failed: Invalid <channel:id>", /* 23h */
6908 "Phys Disk failed: Creating Phys Disk Config "
6921 "Compatibility Error: IR Disabled", /* 30h */
6922 "Compatibility Error: Inquiry Comand Failed", /* 31h */
6923 "Compatibility Error: Device not Direct Access "
6924 "Device ", /* 32h */
6925 "Compatibility Error: Removable Device Found", /* 33h */
6926 "Compatibility Error: Device SCSI Version not "
6927 "2 or Higher", /* 34h */
6928 "Compatibility Error: SATA Device, 48 BIT LBA "
6929 "not Supported", /* 35h */
6930 "Compatibility Error: Device doesn't have "
6931 "512 Byte Block Sizes", /* 36h */
6932 "Compatibility Error: Volume Type Check Failed", /* 37h */
6933 "Compatibility Error: Volume Type is "
6934 "Unsupported by FW", /* 38h */
6935 "Compatibility Error: Disk Drive too Small for "
6936 "use in Volume", /* 39h */
6937 "Compatibility Error: Phys Disk for Create "
6938 "Volume not Found", /* 3Ah */
6939 "Compatibility Error: Too Many or too Few "
6940 "Disks for Volume Type", /* 3Bh */
6941 "Compatibility Error: Disk stripe Sizes "
6942 "Must be 64KB", /* 3Ch */
6943 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
6946 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6948 * mpt_sas_log_info - Log information returned from SAS IOC.
6949 * @ioc: Pointer to MPT_ADAPTER structure
6950 * @log_info: U32 LogInfo reply word from the IOC
6952 * Refer to lsi/mpi_log_sas.h.
6955 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
6957 union loginfo_type {
6966 union loginfo_type sas_loginfo;
6967 char *originator_desc = NULL;
6968 char *code_desc = NULL;
6969 char *sub_code_desc = NULL;
6971 sas_loginfo.loginfo = log_info;
6972 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
6973 (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
6976 originator_desc = originator_str[sas_loginfo.dw.originator];
6978 switch (sas_loginfo.dw.originator) {
6981 if (sas_loginfo.dw.code <
6982 sizeof(iop_code_str)/sizeof(char*))
6983 code_desc = iop_code_str[sas_loginfo.dw.code];
6986 if (sas_loginfo.dw.code <
6987 sizeof(pl_code_str)/sizeof(char*))
6988 code_desc = pl_code_str[sas_loginfo.dw.code];
6991 if (sas_loginfo.dw.code >=
6992 sizeof(ir_code_str)/sizeof(char*))
6994 code_desc = ir_code_str[sas_loginfo.dw.code];
6995 if (sas_loginfo.dw.subcode >=
6996 sizeof(raid_sub_code_str)/sizeof(char*))
6998 if (sas_loginfo.dw.code == 0)
7000 raid_sub_code_str[sas_loginfo.dw.subcode];
7006 if (sub_code_desc != NULL)
7007 printk(MYIOC_s_INFO_FMT
7008 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7010 ioc->name, log_info, originator_desc, code_desc,
7012 else if (code_desc != NULL)
7013 printk(MYIOC_s_INFO_FMT
7014 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7015 " SubCode(0x%04x)\n",
7016 ioc->name, log_info, originator_desc, code_desc,
7017 sas_loginfo.dw.subcode);
7019 printk(MYIOC_s_INFO_FMT
7020 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
7021 " SubCode(0x%04x)\n",
7022 ioc->name, log_info, originator_desc,
7023 sas_loginfo.dw.code, sas_loginfo.dw.subcode);
7026 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7028 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
7029 * @ioc: Pointer to MPT_ADAPTER structure
7030 * @ioc_status: U32 IOCStatus word from IOC
7031 * @mf: Pointer to MPT request frame
7033 * Refer to lsi/mpi.h.
7036 mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7038 Config_t *pReq = (Config_t *)mf;
7039 char extend_desc[EVENT_DESCR_STR_SZ];
7044 if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
7045 page_type = pReq->ExtPageType;
7047 page_type = pReq->Header.PageType;
7050 * ignore invalid page messages for GET_NEXT_HANDLE
7052 form = le32_to_cpu(pReq->PageAddress);
7053 if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
7054 if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
7055 page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
7056 page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
7057 if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
7058 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
7061 if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
7062 if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
7063 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
7067 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
7068 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
7069 page_type, pReq->Header.PageNumber, pReq->Action, form);
7071 switch (ioc_status) {
7073 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7074 desc = "Config Page Invalid Action";
7077 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7078 desc = "Config Page Invalid Type";
7081 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7082 desc = "Config Page Invalid Page";
7085 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7086 desc = "Config Page Invalid Data";
7089 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7090 desc = "Config Page No Defaults";
7093 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7094 desc = "Config Page Can't Commit";
7101 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s: %s\n",
7102 ioc->name, ioc_status, desc, extend_desc);
7106 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
7107 * @ioc: Pointer to MPT_ADAPTER structure
7108 * @ioc_status: U32 IOCStatus word from IOC
7109 * @mf: Pointer to MPT request frame
7111 * Refer to lsi/mpi.h.
7114 mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7116 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
7121 /****************************************************************************/
7122 /* Common IOCStatus values for all replies */
7123 /****************************************************************************/
7125 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
7126 desc = "Invalid Function";
7129 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
7133 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
7134 desc = "Invalid SGL";
7137 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
7138 desc = "Internal Error";
7141 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
7145 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
7146 desc = "Insufficient Resources";
7149 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
7150 desc = "Invalid Field";
7153 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
7154 desc = "Invalid State";
7157 /****************************************************************************/
7158 /* Config IOCStatus values */
7159 /****************************************************************************/
7161 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7162 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7163 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7164 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7165 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7166 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7167 mpt_iocstatus_info_config(ioc, status, mf);
7170 /****************************************************************************/
7171 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
7173 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
7175 /****************************************************************************/
7177 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
7178 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
7179 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
7180 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
7181 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
7182 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
7183 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
7184 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
7185 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
7186 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
7187 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
7188 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
7189 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
7192 /****************************************************************************/
7193 /* SCSI Target values */
7194 /****************************************************************************/
7196 case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
7197 desc = "Target: Priority IO";
7200 case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
7201 desc = "Target: Invalid Port";
7204 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
7205 desc = "Target Invalid IO Index:";
7208 case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
7209 desc = "Target: Aborted";
7212 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
7213 desc = "Target: No Conn Retryable";
7216 case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
7217 desc = "Target: No Connection";
7220 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
7221 desc = "Target: Transfer Count Mismatch";
7224 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
7225 desc = "Target: STS Data not Sent";
7228 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
7229 desc = "Target: Data Offset Error";
7232 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
7233 desc = "Target: Too Much Write Data";
7236 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
7237 desc = "Target: IU Too Short";
7240 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
7241 desc = "Target: ACK NAK Timeout";
7244 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
7245 desc = "Target: Nak Received";
7248 /****************************************************************************/
7249 /* Fibre Channel Direct Access values */
7250 /****************************************************************************/
7252 case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
7253 desc = "FC: Aborted";
7256 case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
7257 desc = "FC: RX ID Invalid";
7260 case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
7261 desc = "FC: DID Invalid";
7264 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
7265 desc = "FC: Node Logged Out";
7268 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
7269 desc = "FC: Exchange Canceled";
7272 /****************************************************************************/
7274 /****************************************************************************/
7276 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
7277 desc = "LAN: Device not Found";
7280 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
7281 desc = "LAN: Device Failure";
7284 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
7285 desc = "LAN: Transmit Error";
7288 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
7289 desc = "LAN: Transmit Aborted";
7292 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
7293 desc = "LAN: Receive Error";
7296 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
7297 desc = "LAN: Receive Aborted";
7300 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
7301 desc = "LAN: Partial Packet";
7304 case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
7305 desc = "LAN: Canceled";
7308 /****************************************************************************/
7309 /* Serial Attached SCSI values */
7310 /****************************************************************************/
7312 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
7313 desc = "SAS: SMP Request Failed";
7316 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
7317 desc = "SAS: SMP Data Overrun";
7328 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s\n", ioc->name, status, desc);
7331 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7332 EXPORT_SYMBOL(mpt_attach);
7333 EXPORT_SYMBOL(mpt_detach);
7335 EXPORT_SYMBOL(mpt_resume);
7336 EXPORT_SYMBOL(mpt_suspend);
7338 EXPORT_SYMBOL(ioc_list);
7339 EXPORT_SYMBOL(mpt_proc_root_dir);
7340 EXPORT_SYMBOL(mpt_register);
7341 EXPORT_SYMBOL(mpt_deregister);
7342 EXPORT_SYMBOL(mpt_event_register);
7343 EXPORT_SYMBOL(mpt_event_deregister);
7344 EXPORT_SYMBOL(mpt_reset_register);
7345 EXPORT_SYMBOL(mpt_reset_deregister);
7346 EXPORT_SYMBOL(mpt_device_driver_register);
7347 EXPORT_SYMBOL(mpt_device_driver_deregister);
7348 EXPORT_SYMBOL(mpt_get_msg_frame);
7349 EXPORT_SYMBOL(mpt_put_msg_frame);
7350 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri);
7351 EXPORT_SYMBOL(mpt_free_msg_frame);
7352 EXPORT_SYMBOL(mpt_add_sge);
7353 EXPORT_SYMBOL(mpt_send_handshake_request);
7354 EXPORT_SYMBOL(mpt_verify_adapter);
7355 EXPORT_SYMBOL(mpt_GetIocState);
7356 EXPORT_SYMBOL(mpt_print_ioc_summary);
7357 EXPORT_SYMBOL(mpt_lan_index);
7358 EXPORT_SYMBOL(mpt_stm_index);
7359 EXPORT_SYMBOL(mpt_HardResetHandler);
7360 EXPORT_SYMBOL(mpt_config);
7361 EXPORT_SYMBOL(mpt_findImVolumes);
7362 EXPORT_SYMBOL(mpt_alloc_fw_memory);
7363 EXPORT_SYMBOL(mpt_free_fw_memory);
7364 EXPORT_SYMBOL(mptbase_sas_persist_operation);
7365 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
7367 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7369 * fusion_init - Fusion MPT base driver initialization routine.
7371 * Returns 0 for success, non-zero for failure.
7378 show_mptmod_ver(my_NAME, my_VERSION);
7379 printk(KERN_INFO COPYRIGHT "\n");
7381 for (i = 0; i < MPT_MAX_PROTOCOL_DRIVERS; i++) {
7382 MptCallbacks[i] = NULL;
7383 MptDriverClass[i] = MPTUNKNOWN_DRIVER;
7384 MptEvHandlers[i] = NULL;
7385 MptResetHandlers[i] = NULL;
7388 /* Register ourselves (mptbase) in order to facilitate
7389 * EventNotification handling.
7391 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
7393 /* Register for hard reset handling callbacks.
7395 mpt_reset_register(mpt_base_index, mpt_ioc_reset);
7397 #ifdef CONFIG_PROC_FS
7398 (void) procmpt_create();
7403 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7405 * fusion_exit - Perform driver unload cleanup.
7407 * This routine frees all resources associated with each MPT adapter
7408 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
7414 mpt_reset_deregister(mpt_base_index);
7416 #ifdef CONFIG_PROC_FS
7421 module_init(fusion_init);
7422 module_exit(fusion_exit);