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-2005 LSI Logic Corporation
9 * (mailto:mpt_linux_developer@lsil.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/config.h>
50 #include <linux/kernel.h>
51 #include <linux/module.h>
52 #include <linux/errno.h>
53 #include <linux/init.h>
54 #include <linux/slab.h>
55 #include <linux/types.h>
56 #include <linux/pci.h>
57 #include <linux/kdev_t.h>
58 #include <linux/blkdev.h>
59 #include <linux/delay.h>
60 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
61 #include <linux/dma-mapping.h>
67 #include <asm/irq.h> /* needed for __irq_itoa() proto */
72 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
73 #define my_NAME "Fusion MPT base driver"
74 #define my_VERSION MPT_LINUX_VERSION_COMMON
75 #define MYNAM "mptbase"
77 MODULE_AUTHOR(MODULEAUTHOR);
78 MODULE_DESCRIPTION(my_NAME);
79 MODULE_LICENSE("GPL");
84 static int mpt_msi_enable;
85 module_param(mpt_msi_enable, int, 0);
86 MODULE_PARM_DESC(mpt_msi_enable, " MSI Support Enable (default=0)");
89 static int mfcounter = 0;
90 #define PRINT_MF_COUNT 20000
93 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
97 int mpt_lan_index = -1;
98 int mpt_stm_index = -1;
100 struct proc_dir_entry *mpt_proc_root_dir;
102 #define WHOINIT_UNKNOWN 0xAA
104 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
108 /* Adapter link list */
110 /* Callback lookup table */
111 static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
112 /* Protocol driver class lookup table */
113 static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
114 /* Event handler lookup table */
115 static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
116 /* Reset handler lookup table */
117 static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
118 static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
120 static int mpt_base_index = -1;
121 static int last_drv_idx = -1;
123 static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq);
125 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
129 static irqreturn_t mpt_interrupt(int irq, void *bus_id, struct pt_regs *r);
130 static int mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
131 static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
132 u32 *req, int replyBytes, u16 *u16reply, int maxwait,
134 static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
135 static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
136 static void mpt_adapter_disable(MPT_ADAPTER *ioc);
137 static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
139 static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
140 static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
141 static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
142 static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
143 static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
144 static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
145 static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
146 static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
147 static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
148 static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
149 static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
150 static int PrimeIocFifos(MPT_ADAPTER *ioc);
151 static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
152 static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
153 static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
154 static int GetLanConfigPages(MPT_ADAPTER *ioc);
155 static int GetIoUnitPage2(MPT_ADAPTER *ioc);
156 int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
157 static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
158 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
159 static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
160 static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
161 static void mpt_timer_expired(unsigned long data);
162 static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
163 static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
164 static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
165 static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
167 #ifdef CONFIG_PROC_FS
168 static int procmpt_summary_read(char *buf, char **start, off_t offset,
169 int request, int *eof, void *data);
170 static int procmpt_version_read(char *buf, char **start, off_t offset,
171 int request, int *eof, void *data);
172 static int procmpt_iocinfo_read(char *buf, char **start, off_t offset,
173 int request, int *eof, void *data);
175 static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
177 //int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
178 static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers);
179 static void mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
180 static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
181 static void mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info);
182 static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
184 /* module entry point */
185 static int __init fusion_init (void);
186 static void __exit fusion_exit (void);
188 #define CHIPREG_READ32(addr) readl_relaxed(addr)
189 #define CHIPREG_READ32_dmasync(addr) readl(addr)
190 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
191 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
192 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
195 pci_disable_io_access(struct pci_dev *pdev)
199 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
201 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
205 pci_enable_io_access(struct pci_dev *pdev)
209 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
211 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
215 * Process turbo (context) reply...
218 mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
220 MPT_FRAME_HDR *mf = NULL;
221 MPT_FRAME_HDR *mr = NULL;
225 dmfprintk((MYIOC_s_INFO_FMT "Got TURBO reply req_idx=%08x\n",
228 switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
229 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
230 req_idx = pa & 0x0000FFFF;
231 cb_idx = (pa & 0x00FF0000) >> 16;
232 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
234 case MPI_CONTEXT_REPLY_TYPE_LAN:
235 cb_idx = mpt_lan_index;
237 * Blind set of mf to NULL here was fatal
238 * after lan_reply says "freeme"
239 * Fix sort of combined with an optimization here;
240 * added explicit check for case where lan_reply
241 * was just returning 1 and doing nothing else.
242 * For this case skip the callback, but set up
243 * proper mf value first here:-)
245 if ((pa & 0x58000000) == 0x58000000) {
246 req_idx = pa & 0x0000FFFF;
247 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
248 mpt_free_msg_frame(ioc, mf);
253 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
255 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
256 cb_idx = mpt_stm_index;
257 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
264 /* Check for (valid) IO callback! */
265 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
266 MptCallbacks[cb_idx] == NULL) {
267 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
268 __FUNCTION__, ioc->name, cb_idx);
272 if (MptCallbacks[cb_idx](ioc, mf, mr))
273 mpt_free_msg_frame(ioc, mf);
279 mpt_reply(MPT_ADAPTER *ioc, u32 pa)
290 /* non-TURBO reply! Hmmm, something may be up...
291 * Newest turbo reply mechanism; get address
292 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
295 /* Map DMA address of reply header to cpu address.
296 * pa is 32 bits - but the dma address may be 32 or 64 bits
297 * get offset based only only the low addresses
300 reply_dma_low = (pa <<= 1);
301 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
302 (reply_dma_low - ioc->reply_frames_low_dma));
304 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
305 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
306 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
308 dmfprintk((MYIOC_s_INFO_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
309 ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
310 DBG_DUMP_REPLY_FRAME(mr)
312 /* Check/log IOC log info
314 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
315 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
316 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
317 if (ioc->bus_type == FC)
318 mpt_fc_log_info(ioc, log_info);
319 else if (ioc->bus_type == SPI)
320 mpt_sp_log_info(ioc, log_info);
321 else if (ioc->bus_type == SAS)
322 mpt_sas_log_info(ioc, log_info);
324 if (ioc_stat & MPI_IOCSTATUS_MASK) {
325 if (ioc->bus_type == SPI &&
326 cb_idx != mpt_stm_index &&
327 cb_idx != mpt_lan_index)
328 mpt_sp_ioc_info(ioc, (u32)ioc_stat, mf);
332 /* Check for (valid) IO callback! */
333 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
334 MptCallbacks[cb_idx] == NULL) {
335 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
336 __FUNCTION__, ioc->name, cb_idx);
341 freeme = MptCallbacks[cb_idx](ioc, mf, mr);
344 /* Flush (non-TURBO) reply with a WRITE! */
345 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
348 mpt_free_msg_frame(ioc, mf);
352 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
354 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
355 * @irq: irq number (not used)
356 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
357 * @r: pt_regs pointer (not used)
359 * This routine is registered via the request_irq() kernel API call,
360 * and handles all interrupts generated from a specific MPT adapter
361 * (also referred to as a IO Controller or IOC).
362 * This routine must clear the interrupt from the adapter and does
363 * so by reading the reply FIFO. Multiple replies may be processed
364 * per single call to this routine.
366 * This routine handles register-level access of the adapter but
367 * dispatches (calls) a protocol-specific callback routine to handle
368 * the protocol-specific details of the MPT request completion.
371 mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
373 MPT_ADAPTER *ioc = bus_id;
377 * Drain the reply FIFO!
380 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
381 if (pa == 0xFFFFFFFF)
383 else if (pa & MPI_ADDRESS_REPLY_A_BIT)
386 mpt_turbo_reply(ioc, pa);
392 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
394 * mpt_base_reply - MPT base driver's callback routine; all base driver
395 * "internal" request/reply processing is routed here.
396 * Currently used for EventNotification and EventAck handling.
397 * @ioc: Pointer to MPT_ADAPTER structure
398 * @mf: Pointer to original MPT request frame
399 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
401 * Returns 1 indicating original alloc'd request frame ptr
402 * should be freed, or 0 if it shouldn't.
405 mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
410 dmfprintk((MYIOC_s_INFO_FMT "mpt_base_reply() called\n", ioc->name));
412 #if defined(MPT_DEBUG_MSG_FRAME)
413 if (!(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) {
414 dmfprintk((KERN_INFO MYNAM ": Original request frame (@%p) header\n", mf));
415 DBG_DUMP_REQUEST_FRAME_HDR(mf)
419 func = reply->u.hdr.Function;
420 dmfprintk((MYIOC_s_INFO_FMT "mpt_base_reply, Function=%02Xh\n",
423 if (func == MPI_FUNCTION_EVENT_NOTIFICATION) {
424 EventNotificationReply_t *pEvReply = (EventNotificationReply_t *) reply;
428 results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
429 if (results != evHandlers) {
430 /* CHECKME! Any special handling needed here? */
431 devtprintk((MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
432 ioc->name, evHandlers, results));
436 * Hmmm... It seems that EventNotificationReply is an exception
437 * to the rule of one reply per request.
439 if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) {
441 devtprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p does not return Request frame\n",
442 ioc->name, pEvReply));
444 devtprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
445 ioc->name, pEvReply));
448 #ifdef CONFIG_PROC_FS
449 // LogEvent(ioc, pEvReply);
452 } else if (func == MPI_FUNCTION_EVENT_ACK) {
453 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n",
455 } else if (func == MPI_FUNCTION_CONFIG ||
456 func == MPI_FUNCTION_TOOLBOX) {
460 dcprintk((MYIOC_s_INFO_FMT "config_complete (mf=%p,mr=%p)\n",
461 ioc->name, mf, reply));
463 pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *)));
466 /* disable timer and remove from linked list */
467 del_timer(&pCfg->timer);
469 spin_lock_irqsave(&ioc->FreeQlock, flags);
470 list_del(&pCfg->linkage);
471 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
474 * If IOC Status is SUCCESS, save the header
475 * and set the status code to GOOD.
477 pCfg->status = MPT_CONFIG_ERROR;
479 ConfigReply_t *pReply = (ConfigReply_t *)reply;
482 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
483 dcprintk((KERN_NOTICE " IOCStatus=%04xh, IOCLogInfo=%08xh\n",
484 status, le32_to_cpu(pReply->IOCLogInfo)));
486 pCfg->status = status;
487 if (status == MPI_IOCSTATUS_SUCCESS) {
488 if ((pReply->Header.PageType &
489 MPI_CONFIG_PAGETYPE_MASK) ==
490 MPI_CONFIG_PAGETYPE_EXTENDED) {
491 pCfg->cfghdr.ehdr->ExtPageLength =
492 le16_to_cpu(pReply->ExtPageLength);
493 pCfg->cfghdr.ehdr->ExtPageType =
496 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
498 /* If this is a regular header, save PageLength. */
499 /* LMP Do this better so not using a reserved field! */
500 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
501 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
502 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
507 * Wake up the original calling thread
512 } else if (func == MPI_FUNCTION_SAS_IO_UNIT_CONTROL) {
513 /* we should be always getting a reply frame */
514 memcpy(ioc->persist_reply_frame, reply,
515 min(MPT_DEFAULT_FRAME_SIZE,
516 4*reply->u.reply.MsgLength));
517 del_timer(&ioc->persist_timer);
518 ioc->persist_wait_done = 1;
521 printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
526 * Conditionally tell caller to free the original
527 * EventNotification/EventAck/unexpected request frame!
532 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
534 * mpt_register - Register protocol-specific main callback handler.
535 * @cbfunc: callback function pointer
536 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
538 * This routine is called by a protocol-specific driver (SCSI host,
539 * LAN, SCSI target) to register it's reply callback routine. Each
540 * protocol-specific driver must do this before it will be able to
541 * use any IOC resources, such as obtaining request frames.
543 * NOTES: The SCSI protocol driver currently calls this routine thrice
544 * in order to register separate callbacks; one for "normal" SCSI IO;
545 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
547 * Returns a positive integer valued "handle" in the
548 * range (and S.O.D. order) {N,...,7,6,5,...,1} if successful.
549 * Any non-positive return value (including zero!) should be considered
550 * an error by the caller.
553 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
560 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
561 * (slot/handle 0 is reserved!)
563 for (i = MPT_MAX_PROTOCOL_DRIVERS-1; i; i--) {
564 if (MptCallbacks[i] == NULL) {
565 MptCallbacks[i] = cbfunc;
566 MptDriverClass[i] = dclass;
567 MptEvHandlers[i] = NULL;
576 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
578 * mpt_deregister - Deregister a protocol drivers resources.
579 * @cb_idx: previously registered callback handle
581 * Each protocol-specific driver should call this routine when it's
582 * module is unloaded.
585 mpt_deregister(int cb_idx)
587 if ((cb_idx >= 0) && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
588 MptCallbacks[cb_idx] = NULL;
589 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
590 MptEvHandlers[cb_idx] = NULL;
596 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
598 * mpt_event_register - Register protocol-specific event callback
600 * @cb_idx: previously registered (via mpt_register) callback handle
601 * @ev_cbfunc: callback function
603 * This routine can be called by one or more protocol-specific drivers
604 * if/when they choose to be notified of MPT events.
606 * Returns 0 for success.
609 mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc)
611 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
614 MptEvHandlers[cb_idx] = ev_cbfunc;
618 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
620 * mpt_event_deregister - Deregister protocol-specific event callback
622 * @cb_idx: previously registered callback handle
624 * Each protocol-specific driver should call this routine
625 * when it does not (or can no longer) handle events,
626 * or when it's module is unloaded.
629 mpt_event_deregister(int cb_idx)
631 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
634 MptEvHandlers[cb_idx] = NULL;
637 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
639 * mpt_reset_register - Register protocol-specific IOC reset handler.
640 * @cb_idx: previously registered (via mpt_register) callback handle
641 * @reset_func: reset function
643 * This routine can be called by one or more protocol-specific drivers
644 * if/when they choose to be notified of IOC resets.
646 * Returns 0 for success.
649 mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func)
651 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
654 MptResetHandlers[cb_idx] = reset_func;
658 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
660 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
661 * @cb_idx: previously registered callback handle
663 * Each protocol-specific driver should call this routine
664 * when it does not (or can no longer) handle IOC reset handling,
665 * or when it's module is unloaded.
668 mpt_reset_deregister(int cb_idx)
670 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
673 MptResetHandlers[cb_idx] = NULL;
676 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
678 * mpt_device_driver_register - Register device driver hooks
681 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx)
685 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) {
689 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
691 /* call per pci device probe entry point */
692 list_for_each_entry(ioc, &ioc_list, list) {
693 if(dd_cbfunc->probe) {
694 dd_cbfunc->probe(ioc->pcidev,
695 ioc->pcidev->driver->id_table);
702 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
704 * mpt_device_driver_deregister - DeRegister device driver hooks
707 mpt_device_driver_deregister(int cb_idx)
709 struct mpt_pci_driver *dd_cbfunc;
712 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
715 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
717 list_for_each_entry(ioc, &ioc_list, list) {
718 if (dd_cbfunc->remove)
719 dd_cbfunc->remove(ioc->pcidev);
722 MptDeviceDriverHandlers[cb_idx] = NULL;
726 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
728 * mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024)
729 * allocated per MPT adapter.
730 * @handle: Handle of registered MPT protocol driver
731 * @ioc: Pointer to MPT adapter structure
733 * Returns pointer to a MPT request frame or %NULL if none are available
734 * or IOC is not active.
737 mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc)
741 u16 req_idx; /* Request index */
743 /* validate handle and ioc identifier */
747 printk(KERN_WARNING "IOC Not Active! mpt_get_msg_frame returning NULL!\n");
750 /* If interrupts are not attached, do not return a request frame */
754 spin_lock_irqsave(&ioc->FreeQlock, flags);
755 if (!list_empty(&ioc->FreeQ)) {
758 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
759 u.frame.linkage.list);
760 list_del(&mf->u.frame.linkage.list);
761 mf->u.frame.linkage.arg1 = 0;
762 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
763 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
765 req_idx = req_offset / ioc->req_sz;
766 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
767 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
768 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame; /* Default, will be changed if necessary in SG generation */
775 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
779 printk(KERN_WARNING "IOC Active. No free Msg Frames! Count 0x%x Max 0x%x\n", ioc->mfcnt, ioc->req_depth);
781 if (mfcounter == PRINT_MF_COUNT)
782 printk(KERN_INFO "MF Count 0x%x Max 0x%x \n", ioc->mfcnt, ioc->req_depth);
785 dmfprintk((KERN_INFO MYNAM ": %s: mpt_get_msg_frame(%d,%d), got mf=%p\n",
786 ioc->name, handle, ioc->id, mf));
790 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
792 * mpt_put_msg_frame - Send a protocol specific MPT request frame
794 * @handle: Handle of registered MPT protocol driver
795 * @ioc: Pointer to MPT adapter structure
796 * @mf: Pointer to MPT request frame
798 * This routine posts a MPT request frame to the request post FIFO of a
799 * specific MPT adapter.
802 mpt_put_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
806 u16 req_idx; /* Request index */
808 /* ensure values are reset properly! */
809 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
810 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
812 req_idx = req_offset / ioc->req_sz;
813 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
814 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
816 #ifdef MPT_DEBUG_MSG_FRAME
818 u32 *m = mf->u.frame.hwhdr.__hdr;
821 printk(KERN_INFO MYNAM ": %s: About to Put msg frame @ %p:\n" KERN_INFO " ",
823 n = ioc->req_sz/4 - 1;
826 for (ii=0; ii<=n; ii++) {
827 if (ii && ((ii%8)==0))
828 printk("\n" KERN_INFO " ");
829 printk(" %08x", le32_to_cpu(m[ii]));
835 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
836 dsgprintk((MYIOC_s_INFO_FMT "mf_dma_addr=%x req_idx=%d RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx, ioc->RequestNB[req_idx]));
837 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
840 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
842 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
843 * @handle: Handle of registered MPT protocol driver
844 * @ioc: Pointer to MPT adapter structure
845 * @mf: Pointer to MPT request frame
847 * This routine places a MPT request frame back on the MPT adapter's
851 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
855 /* Put Request back on FreeQ! */
856 spin_lock_irqsave(&ioc->FreeQlock, flags);
857 mf->u.frame.linkage.arg1 = 0xdeadbeaf; /* signature to know if this mf is freed */
858 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
862 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
865 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
867 * mpt_add_sge - Place a simple SGE at address pAddr.
868 * @pAddr: virtual address for SGE
869 * @flagslength: SGE flags and data transfer length
870 * @dma_addr: Physical address
872 * This routine places a MPT request frame back on the MPT adapter's
876 mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
878 if (sizeof(dma_addr_t) == sizeof(u64)) {
879 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
880 u32 tmp = dma_addr & 0xFFFFFFFF;
882 pSge->FlagsLength = cpu_to_le32(flagslength);
883 pSge->Address.Low = cpu_to_le32(tmp);
884 tmp = (u32) ((u64)dma_addr >> 32);
885 pSge->Address.High = cpu_to_le32(tmp);
888 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
889 pSge->FlagsLength = cpu_to_le32(flagslength);
890 pSge->Address = cpu_to_le32(dma_addr);
894 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
896 * mpt_send_handshake_request - Send MPT request via doorbell
898 * @handle: Handle of registered MPT protocol driver
899 * @ioc: Pointer to MPT adapter structure
900 * @reqBytes: Size of the request in bytes
901 * @req: Pointer to MPT request frame
902 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
904 * This routine is used exclusively to send MptScsiTaskMgmt
905 * requests since they are required to be sent via doorbell handshake.
907 * NOTE: It is the callers responsibility to byte-swap fields in the
908 * request which are greater than 1 byte in size.
910 * Returns 0 for success, non-zero for failure.
913 mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
919 /* State is known to be good upon entering
920 * this function so issue the bus reset
925 * Emulate what mpt_put_msg_frame() does /wrt to sanity
926 * setting cb_idx/req_idx. But ONLY if this request
927 * is in proper (pre-alloc'd) request buffer range...
929 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
930 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
931 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
932 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
933 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;
936 /* Make sure there are no doorbells */
937 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
939 CHIPREG_WRITE32(&ioc->chip->Doorbell,
940 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
941 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
943 /* Wait for IOC doorbell int */
944 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
948 /* Read doorbell and check for active bit */
949 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
952 dhsprintk((KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
955 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
957 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
961 /* Send request via doorbell handshake */
962 req_as_bytes = (u8 *) req;
963 for (ii = 0; ii < reqBytes/4; ii++) {
966 word = ((req_as_bytes[(ii*4) + 0] << 0) |
967 (req_as_bytes[(ii*4) + 1] << 8) |
968 (req_as_bytes[(ii*4) + 2] << 16) |
969 (req_as_bytes[(ii*4) + 3] << 24));
970 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
971 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
977 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
982 /* Make sure there are no doorbells */
983 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
988 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
990 * mpt_host_page_access_control - provides mechanism for the host
991 * driver to control the IOC's Host Page Buffer access.
992 * @ioc: Pointer to MPT adapter structure
993 * @access_control_value: define bits below
995 * Access Control Value - bits[15:12]
997 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
998 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
999 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1001 * Returns 0 for success, non-zero for failure.
1005 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1009 /* return if in use */
1010 if (CHIPREG_READ32(&ioc->chip->Doorbell)
1011 & MPI_DOORBELL_ACTIVE)
1014 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1016 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1017 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1018 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1019 (access_control_value<<12)));
1021 /* Wait for IOC to clear Doorbell Status bit */
1022 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1028 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1030 * mpt_host_page_alloc - allocate system memory for the fw
1031 * If we already allocated memory in past, then resend the same pointer.
1032 * ioc@: Pointer to pointer to IOC adapter
1033 * ioc_init@: Pointer to ioc init config page
1035 * Returns 0 for success, non-zero for failure.
1038 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1042 u32 host_page_buffer_sz=0;
1044 if(!ioc->HostPageBuffer) {
1046 host_page_buffer_sz =
1047 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1049 if(!host_page_buffer_sz)
1050 return 0; /* fw doesn't need any host buffers */
1052 /* spin till we get enough memory */
1053 while(host_page_buffer_sz > 0) {
1055 if((ioc->HostPageBuffer = pci_alloc_consistent(
1057 host_page_buffer_sz,
1058 &ioc->HostPageBuffer_dma)) != NULL) {
1060 dinitprintk((MYIOC_s_INFO_FMT
1061 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1063 ioc->HostPageBuffer,
1064 ioc->HostPageBuffer_dma,
1065 host_page_buffer_sz));
1066 ioc->alloc_total += host_page_buffer_sz;
1067 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1071 host_page_buffer_sz -= (4*1024);
1075 if(!ioc->HostPageBuffer) {
1076 printk(MYIOC_s_ERR_FMT
1077 "Failed to alloc memory for host_page_buffer!\n",
1082 psge = (char *)&ioc_init->HostPageBufferSGE;
1083 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1084 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1085 MPI_SGE_FLAGS_32_BIT_ADDRESSING |
1086 MPI_SGE_FLAGS_HOST_TO_IOC |
1087 MPI_SGE_FLAGS_END_OF_BUFFER;
1088 if (sizeof(dma_addr_t) == sizeof(u64)) {
1089 flags_length |= MPI_SGE_FLAGS_64_BIT_ADDRESSING;
1091 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1092 flags_length |= ioc->HostPageBuffer_sz;
1093 mpt_add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1094 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1099 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1101 * mpt_verify_adapter - Given a unique IOC identifier, set pointer to
1102 * the associated MPT adapter structure.
1103 * @iocid: IOC unique identifier (integer)
1104 * @iocpp: Pointer to pointer to IOC adapter
1106 * Returns iocid and sets iocpp.
1109 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1113 list_for_each_entry(ioc,&ioc_list,list) {
1114 if (ioc->id == iocid) {
1125 mpt_alt_ioc_wait(MPT_ADAPTER *ioc)
1127 int loop_count = 30 * 4; /* Wait 30 seconds */
1128 int status = -1; /* -1 means failed to get board READY */
1131 spin_lock(&ioc->initializing_hba_lock);
1132 if (ioc->initializing_hba_lock_flag == 0) {
1133 ioc->initializing_hba_lock_flag=1;
1134 spin_unlock(&ioc->initializing_hba_lock);
1138 spin_unlock(&ioc->initializing_hba_lock);
1139 set_current_state(TASK_INTERRUPTIBLE);
1140 schedule_timeout(HZ/4);
1141 } while (--loop_count);
1146 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1148 * mpt_bringup_adapter - This is a wrapper function for mpt_do_ioc_recovery
1149 * @ioc: Pointer to MPT adapter structure
1150 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1152 * This routine performs all the steps necessary to bring the IOC
1153 * to a OPERATIONAL state.
1155 * Special Note: This function was added with spin lock's so as to allow
1156 * the dv(domain validation) work thread to succeed on the other channel
1157 * that maybe occuring at the same time when this function is called.
1158 * Without this lock, the dv would fail when message frames were
1159 * requested during hba bringup on the alternate ioc.
1162 mpt_bringup_adapter(MPT_ADAPTER *ioc, int sleepFlag)
1167 if((r=mpt_alt_ioc_wait(ioc->alt_ioc)!=0))
1171 r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1175 spin_lock(&ioc->alt_ioc->initializing_hba_lock);
1176 ioc->alt_ioc->initializing_hba_lock_flag=0;
1177 spin_unlock(&ioc->alt_ioc->initializing_hba_lock);
1183 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1185 * mpt_attach - Install a PCI intelligent MPT adapter.
1186 * @pdev: Pointer to pci_dev structure
1188 * This routine performs all the steps necessary to bring the IOC of
1189 * a MPT adapter to a OPERATIONAL state. This includes registering
1190 * memory regions, registering the interrupt, and allocating request
1191 * and reply memory pools.
1193 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1196 * Returns 0 for success, non-zero for failure.
1198 * TODO: Add support for polled controllers
1201 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1205 unsigned long mem_phys;
1213 static int mpt_ids = 0;
1214 #ifdef CONFIG_PROC_FS
1215 struct proc_dir_entry *dent, *ent;
1218 if (pci_enable_device(pdev))
1221 dinitprintk((KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1223 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
1224 dprintk((KERN_INFO MYNAM
1225 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n"));
1226 } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
1227 printk(KERN_WARNING MYNAM ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");
1231 if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
1232 dprintk((KERN_INFO MYNAM
1233 ": Using 64 bit consistent mask\n"));
1235 dprintk((KERN_INFO MYNAM
1236 ": Not using 64 bit consistent mask\n"));
1238 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1240 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1243 ioc->alloc_total = sizeof(MPT_ADAPTER);
1244 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1245 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1248 ioc->diagPending = 0;
1249 spin_lock_init(&ioc->diagLock);
1250 spin_lock_init(&ioc->fc_rescan_work_lock);
1251 spin_lock_init(&ioc->fc_rport_lock);
1252 spin_lock_init(&ioc->initializing_hba_lock);
1254 /* Initialize the event logging.
1256 ioc->eventTypes = 0; /* None */
1257 ioc->eventContext = 0;
1258 ioc->eventLogSize = 0;
1265 ioc->cached_fw = NULL;
1267 /* Initilize SCSI Config Data structure
1269 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1271 /* Initialize the running configQ head.
1273 INIT_LIST_HEAD(&ioc->configQ);
1275 /* Initialize the fc rport list head.
1277 INIT_LIST_HEAD(&ioc->fc_rports);
1279 /* Find lookup slot. */
1280 INIT_LIST_HEAD(&ioc->list);
1281 ioc->id = mpt_ids++;
1283 mem_phys = msize = 0;
1285 for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1286 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1287 /* Get I/O space! */
1288 port = pci_resource_start(pdev, ii);
1289 psize = pci_resource_len(pdev,ii);
1292 mem_phys = pci_resource_start(pdev, ii);
1293 msize = pci_resource_len(pdev,ii);
1297 ioc->mem_size = msize;
1299 if (ii == DEVICE_COUNT_RESOURCE) {
1300 printk(KERN_ERR MYNAM ": ERROR - MPT adapter has no memory regions defined!\n");
1305 dinitprintk((KERN_INFO MYNAM ": MPT adapter @ %lx, msize=%dd bytes\n", mem_phys, msize));
1306 dinitprintk((KERN_INFO MYNAM ": (port i/o @ %lx, psize=%dd bytes)\n", port, psize));
1309 /* Get logical ptr for PciMem0 space */
1310 /*mem = ioremap(mem_phys, msize);*/
1311 mem = ioremap(mem_phys, 0x100);
1313 printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n");
1318 dinitprintk((KERN_INFO MYNAM ": mem = %p, mem_phys = %lx\n", mem, mem_phys));
1320 dinitprintk((KERN_INFO MYNAM ": facts @ %p, pfacts[0] @ %p\n",
1321 &ioc->facts, &ioc->pfacts[0]));
1323 ioc->mem_phys = mem_phys;
1324 ioc->chip = (SYSIF_REGS __iomem *)mem;
1326 /* Save Port IO values in case we need to do downloadboot */
1328 u8 *pmem = (u8*)port;
1329 ioc->pio_mem_phys = port;
1330 ioc->pio_chip = (SYSIF_REGS __iomem *)pmem;
1333 if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC909) {
1334 ioc->prod_name = "LSIFC909";
1337 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929) {
1338 ioc->prod_name = "LSIFC929";
1341 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919) {
1342 ioc->prod_name = "LSIFC919";
1345 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929X) {
1346 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1348 if (revision < XL_929) {
1349 ioc->prod_name = "LSIFC929X";
1350 /* 929X Chip Fix. Set Split transactions level
1351 * for PCIX. Set MOST bits to zero.
1353 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1355 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1357 ioc->prod_name = "LSIFC929XL";
1358 /* 929XL Chip Fix. Set MMRBC to 0x08.
1360 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1362 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1365 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919X) {
1366 ioc->prod_name = "LSIFC919X";
1368 /* 919X Chip Fix. Set Split transactions level
1369 * for PCIX. Set MOST bits to zero.
1371 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1373 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1375 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC939X) {
1376 ioc->prod_name = "LSIFC939X";
1378 ioc->errata_flag_1064 = 1;
1380 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC949X) {
1381 ioc->prod_name = "LSIFC949X";
1383 ioc->errata_flag_1064 = 1;
1385 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC949E) {
1386 ioc->prod_name = "LSIFC949E";
1389 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {
1390 ioc->prod_name = "LSI53C1030";
1391 ioc->bus_type = SPI;
1392 /* 1030 Chip Fix. Disable Split transactions
1393 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1395 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1396 if (revision < C0_1030) {
1397 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1399 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1402 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_1030_53C1035) {
1403 ioc->prod_name = "LSI53C1035";
1404 ioc->bus_type = SPI;
1406 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064) {
1407 ioc->prod_name = "LSISAS1064";
1408 ioc->bus_type = SAS;
1409 ioc->errata_flag_1064 = 1;
1411 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1066) {
1412 ioc->prod_name = "LSISAS1066";
1413 ioc->bus_type = SAS;
1414 ioc->errata_flag_1064 = 1;
1416 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068) {
1417 ioc->prod_name = "LSISAS1068";
1418 ioc->bus_type = SAS;
1419 ioc->errata_flag_1064 = 1;
1421 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064E) {
1422 ioc->prod_name = "LSISAS1064E";
1423 ioc->bus_type = SAS;
1425 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1066E) {
1426 ioc->prod_name = "LSISAS1066E";
1427 ioc->bus_type = SAS;
1429 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068E) {
1430 ioc->prod_name = "LSISAS1068E";
1431 ioc->bus_type = SAS;
1434 if (ioc->errata_flag_1064)
1435 pci_disable_io_access(pdev);
1437 sprintf(ioc->name, "ioc%d", ioc->id);
1439 spin_lock_init(&ioc->FreeQlock);
1442 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1444 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1446 /* Set lookup ptr. */
1447 list_add_tail(&ioc->list, &ioc_list);
1451 if (mpt_msi_enable && !pci_enable_msi(pdev))
1452 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n", ioc->name);
1454 r = request_irq(pdev->irq, mpt_interrupt, SA_SHIRQ, ioc->name, ioc);
1458 printk(MYIOC_s_ERR_FMT "Unable to allocate interrupt %d!\n",
1459 ioc->name, pdev->irq);
1461 printk(MYIOC_s_ERR_FMT "Unable to allocate interrupt %s!\n",
1462 ioc->name, __irq_itoa(pdev->irq));
1464 list_del(&ioc->list);
1470 ioc->pci_irq = pdev->irq;
1472 pci_set_master(pdev); /* ?? */
1473 pci_set_drvdata(pdev, ioc);
1476 dprintk((KERN_INFO MYNAM ": %s installed at interrupt %d\n", ioc->name, pdev->irq));
1478 dprintk((KERN_INFO MYNAM ": %s installed at interrupt %s\n", ioc->name, __irq_itoa(pdev->irq)));
1482 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1484 mpt_detect_bound_ports(ioc, pdev);
1486 if ((r = mpt_bringup_adapter(ioc, CAN_SLEEP)) != 0){
1487 printk(KERN_WARNING MYNAM
1488 ": WARNING - %s did not initialize properly! (%d)\n",
1491 list_del(&ioc->list);
1492 free_irq(ioc->pci_irq, ioc);
1494 pci_disable_msi(pdev);
1497 pci_set_drvdata(pdev, NULL);
1501 /* call per device driver probe entry point */
1502 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1503 if(MptDeviceDriverHandlers[ii] &&
1504 MptDeviceDriverHandlers[ii]->probe) {
1505 MptDeviceDriverHandlers[ii]->probe(pdev,id);
1509 #ifdef CONFIG_PROC_FS
1511 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1513 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1515 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1517 ent->read_proc = procmpt_iocinfo_read;
1520 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1522 ent->read_proc = procmpt_summary_read;
1531 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1533 * mpt_detach - Remove a PCI intelligent MPT adapter.
1534 * @pdev: Pointer to pci_dev structure
1539 mpt_detach(struct pci_dev *pdev)
1541 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1545 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
1546 remove_proc_entry(pname, NULL);
1547 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
1548 remove_proc_entry(pname, NULL);
1549 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
1550 remove_proc_entry(pname, NULL);
1552 /* call per device driver remove entry point */
1553 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1554 if(MptDeviceDriverHandlers[ii] &&
1555 MptDeviceDriverHandlers[ii]->remove) {
1556 MptDeviceDriverHandlers[ii]->remove(pdev);
1560 /* Disable interrupts! */
1561 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1564 synchronize_irq(pdev->irq);
1566 /* Clear any lingering interrupt */
1567 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1569 CHIPREG_READ32(&ioc->chip->IntStatus);
1571 mpt_adapter_dispose(ioc);
1573 pci_set_drvdata(pdev, NULL);
1576 /**************************************************************************
1580 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1582 * mpt_suspend - Fusion MPT base driver suspend routine.
1587 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
1590 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1592 device_state=pci_choose_state(pdev, state);
1594 printk(MYIOC_s_INFO_FMT
1595 "pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
1596 ioc->name, pdev, pci_name(pdev), device_state);
1598 pci_save_state(pdev);
1600 /* put ioc into READY_STATE */
1601 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
1602 printk(MYIOC_s_ERR_FMT
1603 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
1606 /* disable interrupts */
1607 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1610 /* Clear any lingering interrupt */
1611 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1613 pci_disable_device(pdev);
1614 pci_set_power_state(pdev, device_state);
1619 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1621 * mpt_resume - Fusion MPT base driver resume routine.
1626 mpt_resume(struct pci_dev *pdev)
1628 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1629 u32 device_state = pdev->current_state;
1633 printk(MYIOC_s_INFO_FMT
1634 "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
1635 ioc->name, pdev, pci_name(pdev), device_state);
1637 pci_set_power_state(pdev, 0);
1638 pci_restore_state(pdev);
1639 pci_enable_device(pdev);
1641 /* enable interrupts */
1642 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
1645 /* F/W not running */
1646 if(!CHIPREG_READ32(&ioc->chip->Doorbell)) {
1647 /* enable domain validation flags */
1648 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
1649 ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_NEED_DV;
1653 printk(MYIOC_s_INFO_FMT
1654 "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1656 (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1657 CHIPREG_READ32(&ioc->chip->Doorbell));
1659 /* bring ioc to operational state */
1660 if ((recovery_state = mpt_do_ioc_recovery(ioc,
1661 MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {
1662 printk(MYIOC_s_INFO_FMT
1663 "pci-resume: Cannot recover, error:[%x]\n",
1664 ioc->name, recovery_state);
1666 printk(MYIOC_s_INFO_FMT
1667 "pci-resume: success\n", ioc->name);
1674 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1676 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1677 * @ioc: Pointer to MPT adapter structure
1678 * @reason: Event word / reason
1679 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1681 * This routine performs all the steps necessary to bring the IOC
1682 * to a OPERATIONAL state.
1684 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1689 * -1 if failed to get board READY
1690 * -2 if READY but IOCFacts Failed
1691 * -3 if READY but PrimeIOCFifos Failed
1692 * -4 if READY but IOCInit Failed
1695 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1697 int hard_reset_done = 0;
1698 int alt_ioc_ready = 0;
1704 int reset_alt_ioc_active = 0;
1706 printk(KERN_INFO MYNAM ": Initiating %s %s\n",
1707 ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
1709 /* Disable reply interrupts (also blocks FreeQ) */
1710 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1714 if (ioc->alt_ioc->active)
1715 reset_alt_ioc_active = 1;
1717 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1718 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
1719 ioc->alt_ioc->active = 0;
1723 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
1726 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
1727 if (hard_reset_done == -4) {
1728 printk(KERN_WARNING MYNAM ": %s Owned by PEER..skipping!\n",
1731 if (reset_alt_ioc_active && ioc->alt_ioc) {
1732 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1733 dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1734 ioc->alt_ioc->name));
1735 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
1736 ioc->alt_ioc->active = 1;
1740 printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",
1746 /* hard_reset_done = 0 if a soft reset was performed
1747 * and 1 if a hard reset was performed.
1749 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
1750 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
1753 printk(KERN_WARNING MYNAM
1754 ": alt-%s: Not ready WARNING!\n",
1755 ioc->alt_ioc->name);
1758 for (ii=0; ii<5; ii++) {
1759 /* Get IOC facts! Allow 5 retries */
1760 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
1766 dinitprintk((MYIOC_s_INFO_FMT "Retry IocFacts failed rc=%x\n", ioc->name, rc));
1768 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1769 MptDisplayIocCapabilities(ioc);
1772 if (alt_ioc_ready) {
1773 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
1774 dinitprintk((MYIOC_s_INFO_FMT "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
1775 /* Retry - alt IOC was initialized once
1777 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
1780 dinitprintk((MYIOC_s_INFO_FMT "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
1782 reset_alt_ioc_active = 0;
1783 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1784 MptDisplayIocCapabilities(ioc->alt_ioc);
1788 /* Prime reply & request queues!
1789 * (mucho alloc's) Must be done prior to
1790 * init as upper addresses are needed for init.
1791 * If fails, continue with alt-ioc processing
1793 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
1796 /* May need to check/upload firmware & data here!
1797 * If fails, continue with alt-ioc processing
1799 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
1802 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
1803 printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
1804 ioc->alt_ioc->name, rc);
1806 reset_alt_ioc_active = 0;
1809 if (alt_ioc_ready) {
1810 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
1812 reset_alt_ioc_active = 0;
1813 printk(KERN_WARNING MYNAM
1814 ": alt-%s: (%d) init failure WARNING!\n",
1815 ioc->alt_ioc->name, rc);
1819 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
1820 if (ioc->upload_fw) {
1821 ddlprintk((MYIOC_s_INFO_FMT
1822 "firmware upload required!\n", ioc->name));
1824 /* Controller is not operational, cannot do upload
1827 rc = mpt_do_upload(ioc, sleepFlag);
1829 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
1831 * Maintain only one pointer to FW memory
1832 * so there will not be two attempt to
1833 * downloadboot onboard dual function
1834 * chips (mpt_adapter_disable,
1837 ioc->cached_fw = NULL;
1838 ddlprintk((MYIOC_s_INFO_FMT ": mpt_upload: alt_%s has cached_fw=%p \n",
1839 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
1842 printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
1850 /* Enable! (reply interrupt) */
1851 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
1855 if (reset_alt_ioc_active && ioc->alt_ioc) {
1856 /* (re)Enable alt-IOC! (reply interrupt) */
1857 dinitprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1858 ioc->alt_ioc->name));
1859 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
1860 ioc->alt_ioc->active = 1;
1863 /* Enable MPT base driver management of EventNotification
1864 * and EventAck handling.
1866 if ((ret == 0) && (!ioc->facts.EventState))
1867 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
1869 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
1870 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
1872 /* Add additional "reason" check before call to GetLanConfigPages
1873 * (combined with GetIoUnitPage2 call). This prevents a somewhat
1874 * recursive scenario; GetLanConfigPages times out, timer expired
1875 * routine calls HardResetHandler, which calls into here again,
1876 * and we try GetLanConfigPages again...
1878 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1879 if (ioc->bus_type == SAS) {
1881 /* clear persistency table */
1882 if(ioc->facts.IOCExceptions &
1883 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
1884 ret = mptbase_sas_persist_operation(ioc,
1885 MPI_SAS_OP_CLEAR_NOT_PRESENT);
1892 mpt_findImVolumes(ioc);
1894 } else if (ioc->bus_type == FC) {
1896 * Pre-fetch FC port WWN and stuff...
1897 * (FCPortPage0_t stuff)
1899 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1900 (void) mptbase_GetFcPortPage0(ioc, ii);
1903 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
1904 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
1906 * Pre-fetch the ports LAN MAC address!
1907 * (LANPage1_t stuff)
1909 (void) GetLanConfigPages(ioc);
1912 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
1913 dprintk((MYIOC_s_INFO_FMT "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
1914 ioc->name, a[5], a[4], a[3], a[2], a[1], a[0] ));
1919 /* Get NVRAM and adapter maximums from SPP 0 and 2
1921 mpt_GetScsiPortSettings(ioc, 0);
1923 /* Get version and length of SDP 1
1925 mpt_readScsiDevicePageHeaders(ioc, 0);
1929 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
1930 mpt_findImVolumes(ioc);
1932 /* Check, and possibly reset, the coalescing value
1934 mpt_read_ioc_pg_1(ioc);
1936 mpt_read_ioc_pg_4(ioc);
1939 GetIoUnitPage2(ioc);
1943 * Call each currently registered protocol IOC reset handler
1944 * with post-reset indication.
1945 * NOTE: If we're doing _IOC_BRINGUP, there can be no
1946 * MptResetHandlers[] registered yet.
1948 if (hard_reset_done) {
1950 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
1951 if ((ret == 0) && MptResetHandlers[ii]) {
1952 dprintk((MYIOC_s_INFO_FMT "Calling IOC post_reset handler #%d\n",
1954 rc += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_POST_RESET);
1958 if (alt_ioc_ready && MptResetHandlers[ii]) {
1959 drsprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",
1960 ioc->name, ioc->alt_ioc->name, ii));
1961 rc += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_POST_RESET);
1965 /* FIXME? Examine results here? */
1971 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1973 * mpt_detect_bound_ports - Search for PCI bus/dev_function
1974 * which matches PCI bus/dev_function (+/-1) for newly discovered 929,
1975 * 929X, 1030 or 1035.
1976 * @ioc: Pointer to MPT adapter structure
1977 * @pdev: Pointer to (struct pci_dev) structure
1979 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
1980 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
1983 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
1985 struct pci_dev *peer=NULL;
1986 unsigned int slot = PCI_SLOT(pdev->devfn);
1987 unsigned int func = PCI_FUNC(pdev->devfn);
1988 MPT_ADAPTER *ioc_srch;
1990 dprintk((MYIOC_s_INFO_FMT "PCI device %s devfn=%x/%x,"
1991 " searching for devfn match on %x or %x\n",
1992 ioc->name, pci_name(pdev), pdev->bus->number,
1993 pdev->devfn, func-1, func+1));
1995 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
1997 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
2002 list_for_each_entry(ioc_srch, &ioc_list, list) {
2003 struct pci_dev *_pcidev = ioc_srch->pcidev;
2004 if (_pcidev == peer) {
2005 /* Paranoia checks */
2006 if (ioc->alt_ioc != NULL) {
2007 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
2008 ioc->name, ioc->alt_ioc->name);
2010 } else if (ioc_srch->alt_ioc != NULL) {
2011 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
2012 ioc_srch->name, ioc_srch->alt_ioc->name);
2015 dprintk((KERN_INFO MYNAM ": FOUND! binding %s <==> %s\n",
2016 ioc->name, ioc_srch->name));
2017 ioc_srch->alt_ioc = ioc;
2018 ioc->alt_ioc = ioc_srch;
2024 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2026 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2027 * @this: Pointer to MPT adapter structure
2030 mpt_adapter_disable(MPT_ADAPTER *ioc)
2035 if (ioc->cached_fw != NULL) {
2036 ddlprintk((KERN_INFO MYNAM ": mpt_adapter_disable: Pushing FW onto adapter\n"));
2037 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)ioc->cached_fw, NO_SLEEP)) < 0) {
2038 printk(KERN_WARNING MYNAM
2039 ": firmware downloadboot failure (%d)!\n", ret);
2043 /* Disable adapter interrupts! */
2044 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2046 /* Clear any lingering interrupt */
2047 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2049 if (ioc->alloc != NULL) {
2051 dexitprintk((KERN_INFO MYNAM ": %s.free @ %p, sz=%d bytes\n",
2052 ioc->name, ioc->alloc, ioc->alloc_sz));
2053 pci_free_consistent(ioc->pcidev, sz,
2054 ioc->alloc, ioc->alloc_dma);
2055 ioc->reply_frames = NULL;
2056 ioc->req_frames = NULL;
2058 ioc->alloc_total -= sz;
2061 if (ioc->sense_buf_pool != NULL) {
2062 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2063 pci_free_consistent(ioc->pcidev, sz,
2064 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2065 ioc->sense_buf_pool = NULL;
2066 ioc->alloc_total -= sz;
2069 if (ioc->events != NULL){
2070 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2073 ioc->alloc_total -= sz;
2076 if (ioc->cached_fw != NULL) {
2077 sz = ioc->facts.FWImageSize;
2078 pci_free_consistent(ioc->pcidev, sz,
2079 ioc->cached_fw, ioc->cached_fw_dma);
2080 ioc->cached_fw = NULL;
2081 ioc->alloc_total -= sz;
2084 kfree(ioc->spi_data.nvram);
2085 kfree(ioc->raid_data.pIocPg3);
2086 ioc->spi_data.nvram = NULL;
2087 ioc->raid_data.pIocPg3 = NULL;
2089 if (ioc->spi_data.pIocPg4 != NULL) {
2090 sz = ioc->spi_data.IocPg4Sz;
2091 pci_free_consistent(ioc->pcidev, sz,
2092 ioc->spi_data.pIocPg4,
2093 ioc->spi_data.IocPg4_dma);
2094 ioc->spi_data.pIocPg4 = NULL;
2095 ioc->alloc_total -= sz;
2098 if (ioc->ReqToChain != NULL) {
2099 kfree(ioc->ReqToChain);
2100 kfree(ioc->RequestNB);
2101 ioc->ReqToChain = NULL;
2104 kfree(ioc->ChainToChain);
2105 ioc->ChainToChain = NULL;
2107 if (ioc->HostPageBuffer != NULL) {
2108 if((ret = mpt_host_page_access_control(ioc,
2109 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2110 printk(KERN_ERR MYNAM
2111 ": %s: host page buffers free failed (%d)!\n",
2114 dexitprintk((KERN_INFO MYNAM ": %s HostPageBuffer free @ %p, sz=%d bytes\n",
2115 ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
2116 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2117 ioc->HostPageBuffer,
2118 ioc->HostPageBuffer_dma);
2119 ioc->HostPageBuffer = NULL;
2120 ioc->HostPageBuffer_sz = 0;
2121 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2125 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2127 * mpt_adapter_dispose - Free all resources associated with a MPT
2129 * @ioc: Pointer to MPT adapter structure
2131 * This routine unregisters h/w resources and frees all alloc'd memory
2132 * associated with a MPT adapter structure.
2135 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2137 int sz_first, sz_last;
2142 sz_first = ioc->alloc_total;
2144 mpt_adapter_disable(ioc);
2146 if (ioc->pci_irq != -1) {
2147 free_irq(ioc->pci_irq, ioc);
2149 pci_disable_msi(ioc->pcidev);
2153 if (ioc->memmap != NULL) {
2154 iounmap(ioc->memmap);
2158 #if defined(CONFIG_MTRR) && 0
2159 if (ioc->mtrr_reg > 0) {
2160 mtrr_del(ioc->mtrr_reg, 0, 0);
2161 dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name));
2165 /* Zap the adapter lookup ptr! */
2166 list_del(&ioc->list);
2168 sz_last = ioc->alloc_total;
2169 dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
2170 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2174 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2176 * MptDisplayIocCapabilities - Disply IOC's capacilities.
2177 * @ioc: Pointer to MPT adapter structure
2180 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2184 printk(KERN_INFO "%s: ", ioc->name);
2185 if (ioc->prod_name && strlen(ioc->prod_name) > 3)
2186 printk("%s: ", ioc->prod_name+3);
2187 printk("Capabilities={");
2189 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2190 printk("Initiator");
2194 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2195 printk("%sTarget", i ? "," : "");
2199 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2200 printk("%sLAN", i ? "," : "");
2206 * This would probably evoke more questions than it's worth
2208 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2209 printk("%sLogBusAddr", i ? "," : "");
2217 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2219 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2220 * @ioc: Pointer to MPT_ADAPTER structure
2221 * @force: Force hard KickStart of IOC
2222 * @sleepFlag: Specifies whether the process can sleep
2225 * 1 - DIAG reset and READY
2226 * 0 - READY initially OR soft reset and READY
2227 * -1 - Any failure on KickStart
2228 * -2 - Msg Unit Reset Failed
2229 * -3 - IO Unit Reset Failed
2230 * -4 - IOC owned by a PEER
2233 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2238 int hard_reset_done = 0;
2243 /* Get current [raw] IOC state */
2244 ioc_state = mpt_GetIocState(ioc, 0);
2245 dhsprintk((KERN_INFO MYNAM "::MakeIocReady, %s [raw] state=%08x\n", ioc->name, ioc_state));
2248 * Check to see if IOC got left/stuck in doorbell handshake
2249 * grip of death. If so, hard reset the IOC.
2251 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2253 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2257 /* Is it already READY? */
2258 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
2262 * Check to see if IOC is in FAULT state.
2264 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2266 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2268 printk(KERN_WARNING " FAULT code = %04xh\n",
2269 ioc_state & MPI_DOORBELL_DATA_MASK);
2273 * Hmmm... Did it get left operational?
2275 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2276 dinitprintk((MYIOC_s_INFO_FMT "IOC operational unexpected\n",
2280 * If PCI Peer, exit.
2281 * Else, if no fault conditions are present, issue a MessageUnitReset
2282 * Else, fall through to KickStart case
2284 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2285 dinitprintk((KERN_INFO MYNAM
2286 ": whoinit 0x%x statefault %d force %d\n",
2287 whoinit, statefault, force));
2288 if (whoinit == MPI_WHOINIT_PCI_PEER)
2291 if ((statefault == 0 ) && (force == 0)) {
2292 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2299 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2300 if (hard_reset_done < 0)
2304 * Loop here waiting for IOC to come READY.
2307 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2309 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2310 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2312 * BIOS or previous driver load left IOC in OP state.
2313 * Reset messaging FIFOs.
2315 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2316 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2319 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2321 * Something is wrong. Try to get IOC back
2324 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2325 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2332 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2333 ioc->name, (int)((ii+5)/HZ));
2337 if (sleepFlag == CAN_SLEEP) {
2338 msleep_interruptible(1);
2340 mdelay (1); /* 1 msec delay */
2345 if (statefault < 3) {
2346 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2348 statefault==1 ? "stuck handshake" : "IOC FAULT");
2351 return hard_reset_done;
2354 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2356 * mpt_GetIocState - Get the current state of a MPT adapter.
2357 * @ioc: Pointer to MPT_ADAPTER structure
2358 * @cooked: Request raw or cooked IOC state
2360 * Returns all IOC Doorbell register bits if cooked==0, else just the
2361 * Doorbell bits in MPI_IOC_STATE_MASK.
2364 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2369 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2370 // dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
2371 sc = s & MPI_IOC_STATE_MASK;
2374 ioc->last_state = sc;
2376 return cooked ? sc : s;
2379 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2381 * GetIocFacts - Send IOCFacts request to MPT adapter.
2382 * @ioc: Pointer to MPT_ADAPTER structure
2383 * @sleepFlag: Specifies whether the process can sleep
2384 * @reason: If recovery, only update facts.
2386 * Returns 0 for success, non-zero for failure.
2389 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2391 IOCFacts_t get_facts;
2392 IOCFactsReply_t *facts;
2400 /* IOC *must* NOT be in RESET state! */
2401 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2402 printk(KERN_ERR MYNAM ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
2408 facts = &ioc->facts;
2410 /* Destination (reply area)... */
2411 reply_sz = sizeof(*facts);
2412 memset(facts, 0, reply_sz);
2414 /* Request area (get_facts on the stack right now!) */
2415 req_sz = sizeof(get_facts);
2416 memset(&get_facts, 0, req_sz);
2418 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2419 /* Assert: All other get_facts fields are zero! */
2421 dinitprintk((MYIOC_s_INFO_FMT
2422 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2423 ioc->name, req_sz, reply_sz));
2425 /* No non-zero fields in the get_facts request are greater than
2426 * 1 byte in size, so we can just fire it off as is.
2428 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2429 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2434 * Now byte swap (GRRR) the necessary fields before any further
2435 * inspection of reply contents.
2437 * But need to do some sanity checks on MsgLength (byte) field
2438 * to make sure we don't zero IOC's req_sz!
2440 /* Did we get a valid reply? */
2441 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2442 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2444 * If not been here, done that, save off first WhoInit value
2446 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2447 ioc->FirstWhoInit = facts->WhoInit;
2450 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2451 facts->MsgContext = le32_to_cpu(facts->MsgContext);
2452 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2453 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2454 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2455 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
2456 /* CHECKME! IOCStatus, IOCLogInfo */
2458 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2459 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2462 * FC f/w version changed between 1.1 and 1.2
2463 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2464 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2466 if (facts->MsgVersion < 0x0102) {
2468 * Handle old FC f/w style, convert to new...
2470 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2471 facts->FWVersion.Word =
2472 ((oldv<<12) & 0xFF000000) |
2473 ((oldv<<8) & 0x000FFF00);
2475 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2477 facts->ProductID = le16_to_cpu(facts->ProductID);
2478 facts->CurrentHostMfaHighAddr =
2479 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2480 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2481 facts->CurrentSenseBufferHighAddr =
2482 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2483 facts->CurReplyFrameSize =
2484 le16_to_cpu(facts->CurReplyFrameSize);
2485 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
2488 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2489 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2490 * to 14 in MPI-1.01.0x.
2492 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2493 facts->MsgVersion > 0x0100) {
2494 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2497 sz = facts->FWImageSize;
2502 facts->FWImageSize = sz;
2504 if (!facts->RequestFrameSize) {
2505 /* Something is wrong! */
2506 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2511 r = sz = facts->BlockSize;
2512 vv = ((63 / (sz * 4)) + 1) & 0x03;
2513 ioc->NB_for_64_byte_frame = vv;
2519 ioc->NBShiftFactor = shiftFactor;
2520 dinitprintk((MYIOC_s_INFO_FMT "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2521 ioc->name, vv, shiftFactor, r));
2523 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2525 * Set values for this IOC's request & reply frame sizes,
2526 * and request & reply queue depths...
2528 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2529 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2530 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2531 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2533 dinitprintk((MYIOC_s_INFO_FMT "reply_sz=%3d, reply_depth=%4d\n",
2534 ioc->name, ioc->reply_sz, ioc->reply_depth));
2535 dinitprintk((MYIOC_s_INFO_FMT "req_sz =%3d, req_depth =%4d\n",
2536 ioc->name, ioc->req_sz, ioc->req_depth));
2538 /* Get port facts! */
2539 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2543 printk(MYIOC_s_ERR_FMT
2544 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2545 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2546 RequestFrameSize)/sizeof(u32)));
2553 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2555 * GetPortFacts - Send PortFacts request to MPT adapter.
2556 * @ioc: Pointer to MPT_ADAPTER structure
2557 * @portnum: Port number
2558 * @sleepFlag: Specifies whether the process can sleep
2560 * Returns 0 for success, non-zero for failure.
2563 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2565 PortFacts_t get_pfacts;
2566 PortFactsReply_t *pfacts;
2571 /* IOC *must* NOT be in RESET state! */
2572 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2573 printk(KERN_ERR MYNAM ": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n",
2579 pfacts = &ioc->pfacts[portnum];
2581 /* Destination (reply area)... */
2582 reply_sz = sizeof(*pfacts);
2583 memset(pfacts, 0, reply_sz);
2585 /* Request area (get_pfacts on the stack right now!) */
2586 req_sz = sizeof(get_pfacts);
2587 memset(&get_pfacts, 0, req_sz);
2589 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2590 get_pfacts.PortNumber = portnum;
2591 /* Assert: All other get_pfacts fields are zero! */
2593 dinitprintk((MYIOC_s_INFO_FMT "Sending get PortFacts(%d) request\n",
2594 ioc->name, portnum));
2596 /* No non-zero fields in the get_pfacts request are greater than
2597 * 1 byte in size, so we can just fire it off as is.
2599 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2600 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2604 /* Did we get a valid reply? */
2606 /* Now byte swap the necessary fields in the response. */
2607 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2608 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2609 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2610 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2611 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2612 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2613 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2614 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2615 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2620 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2622 * SendIocInit - Send IOCInit request to MPT adapter.
2623 * @ioc: Pointer to MPT_ADAPTER structure
2624 * @sleepFlag: Specifies whether the process can sleep
2626 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2628 * Returns 0 for success, non-zero for failure.
2631 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2634 MPIDefaultReply_t init_reply;
2640 memset(&ioc_init, 0, sizeof(ioc_init));
2641 memset(&init_reply, 0, sizeof(init_reply));
2643 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2644 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2646 /* If we are in a recovery mode and we uploaded the FW image,
2647 * then this pointer is not NULL. Skip the upload a second time.
2648 * Set this flag if cached_fw set for either IOC.
2650 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
2654 ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n",
2655 ioc->name, ioc->upload_fw, ioc->facts.Flags));
2657 if(ioc->bus_type == SAS)
2658 ioc_init.MaxDevices = ioc->facts.MaxDevices;
2659 else if(ioc->bus_type == FC)
2660 ioc_init.MaxDevices = MPT_MAX_FC_DEVICES;
2662 ioc_init.MaxDevices = MPT_MAX_SCSI_DEVICES;
2663 ioc_init.MaxBuses = MPT_MAX_BUS;
2664 dinitprintk((MYIOC_s_INFO_FMT "facts.MsgVersion=%x\n",
2665 ioc->name, ioc->facts.MsgVersion));
2666 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
2667 // set MsgVersion and HeaderVersion host driver was built with
2668 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
2669 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
2671 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
2672 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
2673 } else if(mpt_host_page_alloc(ioc, &ioc_init))
2676 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
2678 if (sizeof(dma_addr_t) == sizeof(u64)) {
2679 /* Save the upper 32-bits of the request
2680 * (reply) and sense buffers.
2682 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
2683 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2685 /* Force 32-bit addressing */
2686 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
2687 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
2690 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
2691 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
2692 ioc->facts.MaxDevices = ioc_init.MaxDevices;
2693 ioc->facts.MaxBuses = ioc_init.MaxBuses;
2695 dhsprintk((MYIOC_s_INFO_FMT "Sending IOCInit (req @ %p)\n",
2696 ioc->name, &ioc_init));
2698 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
2699 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
2701 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
2705 /* No need to byte swap the multibyte fields in the reply
2706 * since we don't even look at it's contents.
2709 dhsprintk((MYIOC_s_INFO_FMT "Sending PortEnable (req @ %p)\n",
2710 ioc->name, &ioc_init));
2712 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
2713 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
2717 /* YIKES! SUPER IMPORTANT!!!
2718 * Poll IocState until _OPERATIONAL while IOC is doing
2719 * LoopInit and TargetDiscovery!
2722 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
2723 state = mpt_GetIocState(ioc, 1);
2724 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
2725 if (sleepFlag == CAN_SLEEP) {
2726 msleep_interruptible(1);
2732 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
2733 ioc->name, (int)((count+5)/HZ));
2737 state = mpt_GetIocState(ioc, 1);
2740 dinitprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
2746 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2748 * SendPortEnable - Send PortEnable request to MPT adapter port.
2749 * @ioc: Pointer to MPT_ADAPTER structure
2750 * @portnum: Port number to enable
2751 * @sleepFlag: Specifies whether the process can sleep
2753 * Send PortEnable to bring IOC to OPERATIONAL state.
2755 * Returns 0 for success, non-zero for failure.
2758 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2760 PortEnable_t port_enable;
2761 MPIDefaultReply_t reply_buf;
2766 /* Destination... */
2767 reply_sz = sizeof(MPIDefaultReply_t);
2768 memset(&reply_buf, 0, reply_sz);
2770 req_sz = sizeof(PortEnable_t);
2771 memset(&port_enable, 0, req_sz);
2773 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
2774 port_enable.PortNumber = portnum;
2775 /* port_enable.ChainOffset = 0; */
2776 /* port_enable.MsgFlags = 0; */
2777 /* port_enable.MsgContext = 0; */
2779 dinitprintk((MYIOC_s_INFO_FMT "Sending Port(%d)Enable (req @ %p)\n",
2780 ioc->name, portnum, &port_enable));
2782 /* RAID FW may take a long time to enable
2784 if (((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
2785 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI) ||
2786 (ioc->bus_type == SAS)) {
2787 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
2788 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
2789 300 /*seconds*/, sleepFlag);
2791 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
2792 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
2793 30 /*seconds*/, sleepFlag);
2799 * ioc: Pointer to MPT_ADAPTER structure
2800 * size - total FW bytes
2803 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
2806 return; /* use already allocated memory */
2807 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2808 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
2809 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
2811 if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
2812 ioc->alloc_total += size;
2816 * If alt_img is NULL, delete from ioc structure.
2817 * Else, delete a secondary image in same format.
2820 mpt_free_fw_memory(MPT_ADAPTER *ioc)
2824 sz = ioc->facts.FWImageSize;
2825 dinitprintk((KERN_INFO MYNAM "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
2826 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2827 pci_free_consistent(ioc->pcidev, sz,
2828 ioc->cached_fw, ioc->cached_fw_dma);
2829 ioc->cached_fw = NULL;
2835 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2837 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
2838 * @ioc: Pointer to MPT_ADAPTER structure
2839 * @sleepFlag: Specifies whether the process can sleep
2841 * Returns 0 for success, >0 for handshake failure
2842 * <0 for fw upload failure.
2844 * Remark: If bound IOC and a successful FWUpload was performed
2845 * on the bound IOC, the second image is discarded
2846 * and memory is free'd. Both channels must upload to prevent
2847 * IOC from running in degraded mode.
2850 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
2852 u8 request[ioc->req_sz];
2853 u8 reply[sizeof(FWUploadReply_t)];
2854 FWUpload_t *prequest;
2855 FWUploadReply_t *preply;
2856 FWUploadTCSGE_t *ptcsge;
2859 int ii, sz, reply_sz;
2862 /* If the image size is 0, we are done.
2864 if ((sz = ioc->facts.FWImageSize) == 0)
2867 mpt_alloc_fw_memory(ioc, sz);
2869 dinitprintk((KERN_INFO MYNAM ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
2870 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2872 if (ioc->cached_fw == NULL) {
2878 prequest = (FWUpload_t *)&request;
2879 preply = (FWUploadReply_t *)&reply;
2881 /* Destination... */
2882 memset(prequest, 0, ioc->req_sz);
2884 reply_sz = sizeof(reply);
2885 memset(preply, 0, reply_sz);
2887 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
2888 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
2890 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
2891 ptcsge->DetailsLength = 12;
2892 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
2893 ptcsge->ImageSize = cpu_to_le32(sz);
2895 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
2897 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
2898 mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma);
2900 sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
2901 dinitprintk((KERN_INFO MYNAM ": Sending FW Upload (req @ %p) sgeoffset=%d \n",
2902 prequest, sgeoffset));
2903 DBG_DUMP_FW_REQUEST_FRAME(prequest)
2905 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
2906 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
2908 dinitprintk((KERN_INFO MYNAM ": FW Upload completed rc=%x \n", ii));
2910 cmdStatus = -EFAULT;
2912 /* Handshake transfer was complete and successful.
2913 * Check the Reply Frame.
2915 int status, transfer_sz;
2916 status = le16_to_cpu(preply->IOCStatus);
2917 if (status == MPI_IOCSTATUS_SUCCESS) {
2918 transfer_sz = le32_to_cpu(preply->ActualImageSize);
2919 if (transfer_sz == sz)
2923 dinitprintk((MYIOC_s_INFO_FMT ": do_upload cmdStatus=%d \n",
2924 ioc->name, cmdStatus));
2929 ddlprintk((MYIOC_s_INFO_FMT ": fw upload failed, freeing image \n",
2931 mpt_free_fw_memory(ioc);
2937 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2939 * mpt_downloadboot - DownloadBoot code
2940 * @ioc: Pointer to MPT_ADAPTER structure
2941 * @flag: Specify which part of IOC memory is to be uploaded.
2942 * @sleepFlag: Specifies whether the process can sleep
2944 * FwDownloadBoot requires Programmed IO access.
2946 * Returns 0 for success
2947 * -1 FW Image size is 0
2948 * -2 No valid cached_fw Pointer
2949 * <0 for fw upload failure.
2952 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
2954 MpiExtImageHeader_t *pExtImage;
2964 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
2965 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
2967 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2968 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2969 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2970 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2971 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2972 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2974 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
2977 if (sleepFlag == CAN_SLEEP) {
2978 msleep_interruptible(1);
2983 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2984 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
2986 for (count = 0; count < 30; count ++) {
2987 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2988 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
2989 ddlprintk((MYIOC_s_INFO_FMT "RESET_ADAPTER cleared, count=%d\n",
2994 if (sleepFlag == CAN_SLEEP) {
2995 msleep_interruptible (100);
3001 if ( count == 30 ) {
3002 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! "
3003 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3004 ioc->name, diag0val));
3008 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3009 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3010 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3011 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3012 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3013 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3015 /* Set the DiagRwEn and Disable ARM bits */
3016 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3018 fwSize = (pFwHeader->ImageSize + 3)/4;
3019 ptrFw = (u32 *) pFwHeader;
3021 /* Write the LoadStartAddress to the DiagRw Address Register
3022 * using Programmed IO
3024 if (ioc->errata_flag_1064)
3025 pci_enable_io_access(ioc->pcidev);
3027 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3028 ddlprintk((MYIOC_s_INFO_FMT "LoadStart addr written 0x%x \n",
3029 ioc->name, pFwHeader->LoadStartAddress));
3031 ddlprintk((MYIOC_s_INFO_FMT "Write FW Image: 0x%x bytes @ %p\n",
3032 ioc->name, fwSize*4, ptrFw));
3034 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3037 nextImage = pFwHeader->NextImageHeaderOffset;
3039 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3041 load_addr = pExtImage->LoadStartAddress;
3043 fwSize = (pExtImage->ImageSize + 3) >> 2;
3044 ptrFw = (u32 *)pExtImage;
3046 ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3047 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3048 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3051 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3053 nextImage = pExtImage->NextImageHeaderOffset;
3056 /* Write the IopResetVectorRegAddr */
3057 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
3058 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3060 /* Write the IopResetVectorValue */
3061 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3062 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3064 /* Clear the internal flash bad bit - autoincrementing register,
3065 * so must do two writes.
3067 if (ioc->bus_type == SPI) {
3069 * 1030 and 1035 H/W errata, workaround to access
3070 * the ClearFlashBadSignatureBit
3072 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3073 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3074 diagRwData |= 0x40000000;
3075 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3076 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3078 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3079 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3080 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3081 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3084 if (sleepFlag == CAN_SLEEP) {
3085 msleep_interruptible (1);
3091 if (ioc->errata_flag_1064)
3092 pci_disable_io_access(ioc->pcidev);
3094 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3095 ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, "
3096 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3097 ioc->name, diag0val));
3098 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3099 ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
3100 ioc->name, diag0val));
3101 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3103 /* Write 0xFF to reset the sequencer */
3104 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3106 if (ioc->bus_type == SAS) {
3107 ioc_state = mpt_GetIocState(ioc, 0);
3108 if ( (GetIocFacts(ioc, sleepFlag,
3109 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3110 ddlprintk((MYIOC_s_INFO_FMT "GetIocFacts failed: IocState=%x\n",
3111 ioc->name, ioc_state));
3116 for (count=0; count<HZ*20; count++) {
3117 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3118 ddlprintk((MYIOC_s_INFO_FMT "downloadboot successful! (count=%d) IocState=%x\n",
3119 ioc->name, count, ioc_state));
3120 if (ioc->bus_type == SAS) {
3123 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3124 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit failed\n",
3128 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit successful\n",
3132 if (sleepFlag == CAN_SLEEP) {
3133 msleep_interruptible (10);
3138 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! IocState=%x\n",
3139 ioc->name, ioc_state));
3143 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3145 * KickStart - Perform hard reset of MPT adapter.
3146 * @ioc: Pointer to MPT_ADAPTER structure
3147 * @force: Force hard reset
3148 * @sleepFlag: Specifies whether the process can sleep
3150 * This routine places MPT adapter in diagnostic mode via the
3151 * WriteSequence register, and then performs a hard reset of adapter
3152 * via the Diagnostic register.
3154 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3155 * or NO_SLEEP (interrupt thread, use mdelay)
3156 * force - 1 if doorbell active, board fault state
3157 * board operational, IOC_RECOVERY or
3158 * IOC_BRINGUP and there is an alt_ioc.
3162 * 1 - hard reset, READY
3163 * 0 - no reset due to History bit, READY
3164 * -1 - no reset due to History bit but not READY
3165 * OR reset but failed to come READY
3166 * -2 - no reset, could not enter DIAG mode
3167 * -3 - reset but bad FW bit
3170 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3172 int hard_reset_done = 0;
3176 dinitprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
3177 if (ioc->bus_type == SPI) {
3178 /* Always issue a Msg Unit Reset first. This will clear some
3179 * SCSI bus hang conditions.
3181 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3183 if (sleepFlag == CAN_SLEEP) {
3184 msleep_interruptible (1000);
3190 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3191 if (hard_reset_done < 0)
3192 return hard_reset_done;
3194 dinitprintk((MYIOC_s_INFO_FMT "Diagnostic reset successful!\n",
3197 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3198 for (cnt=0; cnt<cntdn; cnt++) {
3199 ioc_state = mpt_GetIocState(ioc, 1);
3200 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3201 dinitprintk((MYIOC_s_INFO_FMT "KickStart successful! (cnt=%d)\n",
3203 return hard_reset_done;
3205 if (sleepFlag == CAN_SLEEP) {
3206 msleep_interruptible (10);
3212 printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3213 ioc->name, ioc_state);
3217 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3219 * mpt_diag_reset - Perform hard reset of the adapter.
3220 * @ioc: Pointer to MPT_ADAPTER structure
3221 * @ignore: Set if to honor and clear to ignore
3222 * the reset history bit
3223 * @sleepflag: CAN_SLEEP if called in a non-interrupt thread,
3224 * else set to NO_SLEEP (use mdelay instead)
3226 * This routine places the adapter in diagnostic mode via the
3227 * WriteSequence register and then performs a hard reset of adapter
3228 * via the Diagnostic register. Adapter should be in ready state
3229 * upon successful completion.
3231 * Returns: 1 hard reset successful
3232 * 0 no reset performed because reset history bit set
3233 * -2 enabling diagnostic mode failed
3234 * -3 diagnostic reset failed
3237 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3241 int hard_reset_done = 0;
3247 /* Clear any existing interrupts */
3248 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3250 /* Use "Diagnostic reset" method! (only thing available!) */
3251 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3255 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3256 dprintk((MYIOC_s_INFO_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3257 ioc->name, diag0val, diag1val));
3260 /* Do the reset if we are told to ignore the reset history
3261 * or if the reset history is 0
3263 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3264 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3265 /* Write magic sequence to WriteSequence register
3266 * Loop until in diagnostic mode
3268 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3269 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3270 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3271 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3272 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3273 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3276 if (sleepFlag == CAN_SLEEP) {
3277 msleep_interruptible (100);
3284 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3285 ioc->name, diag0val);
3290 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3292 dprintk((MYIOC_s_INFO_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3293 ioc->name, diag0val));
3298 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3299 dprintk((MYIOC_s_INFO_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3300 ioc->name, diag0val, diag1val));
3303 * Disable the ARM (Bug fix)
3306 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3310 * Now hit the reset bit in the Diagnostic register
3311 * (THE BIG HAMMER!) (Clears DRWE bit).
3313 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3314 hard_reset_done = 1;
3315 dprintk((MYIOC_s_INFO_FMT "Diagnostic reset performed\n",
3319 * Call each currently registered protocol IOC reset handler
3320 * with pre-reset indication.
3321 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3322 * MptResetHandlers[] registered yet.
3328 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
3329 if (MptResetHandlers[ii]) {
3330 dprintk((MYIOC_s_INFO_FMT "Calling IOC pre_reset handler #%d\n",
3332 r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_PRE_RESET);
3334 dprintk((MYIOC_s_INFO_FMT "Calling alt-%s pre_reset handler #%d\n",
3335 ioc->name, ioc->alt_ioc->name, ii));
3336 r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_PRE_RESET);
3340 /* FIXME? Examine results here? */
3343 if (ioc->cached_fw) {
3344 /* If the DownloadBoot operation fails, the
3345 * IOC will be left unusable. This is a fatal error
3346 * case. _diag_reset will return < 0
3348 for (count = 0; count < 30; count ++) {
3349 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3350 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3355 if (sleepFlag == CAN_SLEEP) {
3356 msleep_interruptible (1000);
3361 if ((count = mpt_downloadboot(ioc,
3362 (MpiFwHeader_t *)ioc->cached_fw, sleepFlag)) < 0) {
3363 printk(KERN_WARNING MYNAM
3364 ": firmware downloadboot failure (%d)!\n", count);
3368 /* Wait for FW to reload and for board
3369 * to go to the READY state.
3370 * Maximum wait is 60 seconds.
3371 * If fail, no error will check again
3372 * with calling program.
3374 for (count = 0; count < 60; count ++) {
3375 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3376 doorbell &= MPI_IOC_STATE_MASK;
3378 if (doorbell == MPI_IOC_STATE_READY) {
3383 if (sleepFlag == CAN_SLEEP) {
3384 msleep_interruptible (1000);
3392 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3395 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3396 dprintk((MYIOC_s_INFO_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3397 ioc->name, diag0val, diag1val));
3400 /* Clear RESET_HISTORY bit! Place board in the
3401 * diagnostic mode to update the diag register.
3403 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3405 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3406 /* Write magic sequence to WriteSequence register
3407 * Loop until in diagnostic mode
3409 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3410 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3411 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3412 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3413 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3414 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3417 if (sleepFlag == CAN_SLEEP) {
3418 msleep_interruptible (100);
3425 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3426 ioc->name, diag0val);
3429 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3431 diag0val &= ~MPI_DIAG_RESET_HISTORY;
3432 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3433 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3434 if (diag0val & MPI_DIAG_RESET_HISTORY) {
3435 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3439 /* Disable Diagnostic Mode
3441 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3443 /* Check FW reload status flags.
3445 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3446 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3447 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3448 ioc->name, diag0val);
3454 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3455 dprintk((MYIOC_s_INFO_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3456 ioc->name, diag0val, diag1val));
3460 * Reset flag that says we've enabled event notification
3462 ioc->facts.EventState = 0;
3465 ioc->alt_ioc->facts.EventState = 0;
3467 return hard_reset_done;
3470 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3472 * SendIocReset - Send IOCReset request to MPT adapter.
3473 * @ioc: Pointer to MPT_ADAPTER structure
3474 * @reset_type: reset type, expected values are
3475 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3477 * Send IOCReset request to the MPT adapter.
3479 * Returns 0 for success, non-zero for failure.
3482 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3488 drsprintk((KERN_INFO MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
3489 ioc->name, reset_type));
3490 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3491 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3494 /* FW ACK'd request, wait for READY state
3497 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
3499 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3503 if (sleepFlag != CAN_SLEEP)
3506 printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
3507 ioc->name, (int)((count+5)/HZ));
3511 if (sleepFlag == CAN_SLEEP) {
3512 msleep_interruptible(1);
3514 mdelay (1); /* 1 msec delay */
3519 * Cleanup all event stuff for this IOC; re-issue EventNotification
3520 * request if needed.
3522 if (ioc->facts.Function)
3523 ioc->facts.EventState = 0;
3528 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3530 * initChainBuffers - Allocate memory for and initialize
3531 * chain buffers, chain buffer control arrays and spinlock.
3532 * @hd: Pointer to MPT_SCSI_HOST structure
3533 * @init: If set, initialize the spin lock.
3536 initChainBuffers(MPT_ADAPTER *ioc)
3539 int sz, ii, num_chain;
3540 int scale, num_sge, numSGE;
3542 /* ReqToChain size must equal the req_depth
3545 if (ioc->ReqToChain == NULL) {
3546 sz = ioc->req_depth * sizeof(int);
3547 mem = kmalloc(sz, GFP_ATOMIC);
3551 ioc->ReqToChain = (int *) mem;
3552 dinitprintk((KERN_INFO MYNAM ": %s ReqToChain alloc @ %p, sz=%d bytes\n",
3553 ioc->name, mem, sz));
3554 mem = kmalloc(sz, GFP_ATOMIC);
3558 ioc->RequestNB = (int *) mem;
3559 dinitprintk((KERN_INFO MYNAM ": %s RequestNB alloc @ %p, sz=%d bytes\n",
3560 ioc->name, mem, sz));
3562 for (ii = 0; ii < ioc->req_depth; ii++) {
3563 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
3566 /* ChainToChain size must equal the total number
3567 * of chain buffers to be allocated.
3570 * Calculate the number of chain buffers needed(plus 1) per I/O
3571 * then multiply the the maximum number of simultaneous cmds
3573 * num_sge = num sge in request frame + last chain buffer
3574 * scale = num sge per chain buffer if no chain element
3576 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3577 if (sizeof(dma_addr_t) == sizeof(u64))
3578 num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3580 num_sge = 1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3582 if (sizeof(dma_addr_t) == sizeof(u64)) {
3583 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3584 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3586 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3587 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3589 dinitprintk((KERN_INFO MYNAM ": %s num_sge=%d numSGE=%d\n",
3590 ioc->name, num_sge, numSGE));
3592 if ( numSGE > MPT_SCSI_SG_DEPTH )
3593 numSGE = MPT_SCSI_SG_DEPTH;
3596 while (numSGE - num_sge > 0) {
3598 num_sge += (scale - 1);
3602 dinitprintk((KERN_INFO MYNAM ": %s Now numSGE=%d num_sge=%d num_chain=%d\n",
3603 ioc->name, numSGE, num_sge, num_chain));
3605 if (ioc->bus_type == SPI)
3606 num_chain *= MPT_SCSI_CAN_QUEUE;
3608 num_chain *= MPT_FC_CAN_QUEUE;
3610 ioc->num_chain = num_chain;
3612 sz = num_chain * sizeof(int);
3613 if (ioc->ChainToChain == NULL) {
3614 mem = kmalloc(sz, GFP_ATOMIC);
3618 ioc->ChainToChain = (int *) mem;
3619 dinitprintk((KERN_INFO MYNAM ": %s ChainToChain alloc @ %p, sz=%d bytes\n",
3620 ioc->name, mem, sz));
3622 mem = (u8 *) ioc->ChainToChain;
3624 memset(mem, 0xFF, sz);
3628 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3630 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
3631 * @ioc: Pointer to MPT_ADAPTER structure
3633 * This routine allocates memory for the MPT reply and request frame
3634 * pools (if necessary), and primes the IOC reply FIFO with
3637 * Returns 0 for success, non-zero for failure.
3640 PrimeIocFifos(MPT_ADAPTER *ioc)
3643 unsigned long flags;
3644 dma_addr_t alloc_dma;
3646 int i, reply_sz, sz, total_size, num_chain;
3648 /* Prime reply FIFO... */
3650 if (ioc->reply_frames == NULL) {
3651 if ( (num_chain = initChainBuffers(ioc)) < 0)
3654 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
3655 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
3656 ioc->name, ioc->reply_sz, ioc->reply_depth));
3657 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d[%x] bytes\n",
3658 ioc->name, reply_sz, reply_sz));
3660 sz = (ioc->req_sz * ioc->req_depth);
3661 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d bytes, RequestDepth=%d\n",
3662 ioc->name, ioc->req_sz, ioc->req_depth));
3663 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d[%x] bytes\n",
3664 ioc->name, sz, sz));
3667 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
3668 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d bytes, ChainDepth=%d\n",
3669 ioc->name, ioc->req_sz, num_chain));
3670 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
3671 ioc->name, sz, sz, num_chain));
3674 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
3676 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
3681 dinitprintk((KERN_INFO MYNAM ": %s.Total alloc @ %p[%p], sz=%d[%x] bytes\n",
3682 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
3684 memset(mem, 0, total_size);
3685 ioc->alloc_total += total_size;
3687 ioc->alloc_dma = alloc_dma;
3688 ioc->alloc_sz = total_size;
3689 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
3690 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3692 dinitprintk((KERN_INFO MYNAM ": %s ReplyBuffers @ %p[%p]\n",
3693 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3695 alloc_dma += reply_sz;
3698 /* Request FIFO - WE manage this! */
3700 ioc->req_frames = (MPT_FRAME_HDR *) mem;
3701 ioc->req_frames_dma = alloc_dma;
3703 dinitprintk((KERN_INFO MYNAM ": %s RequestBuffers @ %p[%p]\n",
3704 ioc->name, mem, (void *)(ulong)alloc_dma));
3706 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3708 #if defined(CONFIG_MTRR) && 0
3710 * Enable Write Combining MTRR for IOC's memory region.
3711 * (at least as much as we can; "size and base must be
3712 * multiples of 4 kiB"
3714 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
3716 MTRR_TYPE_WRCOMB, 1);
3717 dprintk((MYIOC_s_INFO_FMT "MTRR region registered (base:size=%08x:%x)\n",
3718 ioc->name, ioc->req_frames_dma, sz));
3721 for (i = 0; i < ioc->req_depth; i++) {
3722 alloc_dma += ioc->req_sz;
3726 ioc->ChainBuffer = mem;
3727 ioc->ChainBufferDMA = alloc_dma;
3729 dinitprintk((KERN_INFO MYNAM " :%s ChainBuffers @ %p(%p)\n",
3730 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
3732 /* Initialize the free chain Q.
3735 INIT_LIST_HEAD(&ioc->FreeChainQ);
3737 /* Post the chain buffers to the FreeChainQ.
3739 mem = (u8 *)ioc->ChainBuffer;
3740 for (i=0; i < num_chain; i++) {
3741 mf = (MPT_FRAME_HDR *) mem;
3742 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
3746 /* Initialize Request frames linked list
3748 alloc_dma = ioc->req_frames_dma;
3749 mem = (u8 *) ioc->req_frames;
3751 spin_lock_irqsave(&ioc->FreeQlock, flags);
3752 INIT_LIST_HEAD(&ioc->FreeQ);
3753 for (i = 0; i < ioc->req_depth; i++) {
3754 mf = (MPT_FRAME_HDR *) mem;
3756 /* Queue REQUESTs *internally*! */
3757 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
3761 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3763 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3764 ioc->sense_buf_pool =
3765 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
3766 if (ioc->sense_buf_pool == NULL) {
3767 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
3772 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
3773 ioc->alloc_total += sz;
3774 dinitprintk((KERN_INFO MYNAM ": %s.SenseBuffers @ %p[%p]\n",
3775 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
3779 /* Post Reply frames to FIFO
3781 alloc_dma = ioc->alloc_dma;
3782 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffers @ %p[%p]\n",
3783 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3785 for (i = 0; i < ioc->reply_depth; i++) {
3786 /* Write each address to the IOC! */
3787 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
3788 alloc_dma += ioc->reply_sz;
3794 if (ioc->alloc != NULL) {
3796 pci_free_consistent(ioc->pcidev,
3798 ioc->alloc, ioc->alloc_dma);
3799 ioc->reply_frames = NULL;
3800 ioc->req_frames = NULL;
3801 ioc->alloc_total -= sz;
3803 if (ioc->sense_buf_pool != NULL) {
3804 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3805 pci_free_consistent(ioc->pcidev,
3807 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
3808 ioc->sense_buf_pool = NULL;
3813 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3815 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
3816 * from IOC via doorbell handshake method.
3817 * @ioc: Pointer to MPT_ADAPTER structure
3818 * @reqBytes: Size of the request in bytes
3819 * @req: Pointer to MPT request frame
3820 * @replyBytes: Expected size of the reply in bytes
3821 * @u16reply: Pointer to area where reply should be written
3822 * @maxwait: Max wait time for a reply (in seconds)
3823 * @sleepFlag: Specifies whether the process can sleep
3825 * NOTES: It is the callers responsibility to byte-swap fields in the
3826 * request which are greater than 1 byte in size. It is also the
3827 * callers responsibility to byte-swap response fields which are
3828 * greater than 1 byte in size.
3830 * Returns 0 for success, non-zero for failure.
3833 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
3834 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
3836 MPIDefaultReply_t *mptReply;
3841 * Get ready to cache a handshake reply
3843 ioc->hs_reply_idx = 0;
3844 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
3845 mptReply->MsgLength = 0;
3848 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
3849 * then tell IOC that we want to handshake a request of N words.
3850 * (WRITE u32val to Doorbell reg).
3852 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3853 CHIPREG_WRITE32(&ioc->chip->Doorbell,
3854 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
3855 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
3858 * Wait for IOC's doorbell handshake int
3860 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3863 dhsprintk((MYIOC_s_INFO_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
3864 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
3866 /* Read doorbell and check for active bit */
3867 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
3871 * Clear doorbell int (WRITE 0 to IntStatus reg),
3872 * then wait for IOC to ACKnowledge that it's ready for
3873 * our handshake request.
3875 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3876 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3881 u8 *req_as_bytes = (u8 *) req;
3884 * Stuff request words via doorbell handshake,
3885 * with ACK from IOC for each.
3887 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
3888 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
3889 (req_as_bytes[(ii*4) + 1] << 8) |
3890 (req_as_bytes[(ii*4) + 2] << 16) |
3891 (req_as_bytes[(ii*4) + 3] << 24));
3893 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
3894 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3898 dhsprintk((KERN_INFO MYNAM ": Handshake request frame (@%p) header\n", req));
3899 DBG_DUMP_REQUEST_FRAME_HDR(req)
3901 dhsprintk((MYIOC_s_INFO_FMT "HandShake request post done, WaitCnt=%d%s\n",
3902 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
3905 * Wait for completion of doorbell handshake reply from the IOC
3907 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
3910 dhsprintk((MYIOC_s_INFO_FMT "HandShake reply count=%d%s\n",
3911 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
3914 * Copy out the cached reply...
3916 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
3917 u16reply[ii] = ioc->hs_reply[ii];
3925 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3927 * WaitForDoorbellAck - Wait for IOC to clear the IOP_DOORBELL_STATUS bit
3928 * in it's IntStatus register.
3929 * @ioc: Pointer to MPT_ADAPTER structure
3930 * @howlong: How long to wait (in seconds)
3931 * @sleepFlag: Specifies whether the process can sleep
3933 * This routine waits (up to ~2 seconds max) for IOC doorbell
3934 * handshake ACKnowledge.
3936 * Returns a negative value on failure, else wait loop count.
3939 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3945 cntdn = 1000 * howlong;
3947 if (sleepFlag == CAN_SLEEP) {
3949 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3950 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3952 msleep_interruptible (1);
3957 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3958 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3966 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell ACK (count=%d)\n",
3971 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
3972 ioc->name, count, intstat);
3976 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3978 * WaitForDoorbellInt - Wait for IOC to set the HIS_DOORBELL_INTERRUPT bit
3979 * in it's IntStatus register.
3980 * @ioc: Pointer to MPT_ADAPTER structure
3981 * @howlong: How long to wait (in seconds)
3982 * @sleepFlag: Specifies whether the process can sleep
3984 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt.
3986 * Returns a negative value on failure, else wait loop count.
3989 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3995 cntdn = 1000 * howlong;
3996 if (sleepFlag == CAN_SLEEP) {
3998 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3999 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4001 msleep_interruptible(1);
4006 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4007 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4015 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4016 ioc->name, count, howlong));
4020 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4021 ioc->name, count, intstat);
4025 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4027 * WaitForDoorbellReply - Wait for and capture a IOC handshake reply.
4028 * @ioc: Pointer to MPT_ADAPTER structure
4029 * @howlong: How long to wait (in seconds)
4030 * @sleepFlag: Specifies whether the process can sleep
4032 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4033 * Reply is cached to IOC private area large enough to hold a maximum
4034 * of 128 bytes of reply data.
4036 * Returns a negative value on failure, else size of reply in WORDS.
4039 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4044 u16 *hs_reply = ioc->hs_reply;
4045 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4048 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4051 * Get first two u16's so we can look at IOC's intended reply MsgLength
4054 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4057 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4058 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4059 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4062 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4063 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4067 dhsprintk((MYIOC_s_INFO_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4068 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4069 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4072 * If no error (and IOC said MsgLength is > 0), piece together
4073 * reply 16 bits at a time.
4075 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4076 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4078 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4079 /* don't overflow our IOC hs_reply[] buffer! */
4080 if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
4081 hs_reply[u16cnt] = hword;
4082 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4085 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4087 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4090 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4095 else if (u16cnt != (2 * mptReply->MsgLength)) {
4098 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4103 dhsprintk((MYIOC_s_INFO_FMT "Got Handshake reply:\n", ioc->name));
4104 DBG_DUMP_REPLY_FRAME(mptReply)
4106 dhsprintk((MYIOC_s_INFO_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4107 ioc->name, t, u16cnt/2));
4111 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4113 * GetLanConfigPages - Fetch LANConfig pages.
4114 * @ioc: Pointer to MPT_ADAPTER structure
4116 * Return: 0 for success
4117 * -ENOMEM if no memory available
4118 * -EPERM if not allowed due to ISR context
4119 * -EAGAIN if no msg frames currently available
4120 * -EFAULT for non-successful reply or no reply (timeout)
4123 GetLanConfigPages(MPT_ADAPTER *ioc)
4125 ConfigPageHeader_t hdr;
4127 LANPage0_t *ppage0_alloc;
4128 dma_addr_t page0_dma;
4129 LANPage1_t *ppage1_alloc;
4130 dma_addr_t page1_dma;
4135 /* Get LAN Page 0 header */
4136 hdr.PageVersion = 0;
4139 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4140 cfg.cfghdr.hdr = &hdr;
4142 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4147 if ((rc = mpt_config(ioc, &cfg)) != 0)
4150 if (hdr.PageLength > 0) {
4151 data_sz = hdr.PageLength * 4;
4152 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4155 memset((u8 *)ppage0_alloc, 0, data_sz);
4156 cfg.physAddr = page0_dma;
4157 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4159 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4161 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4162 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4166 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4169 * Normalize endianness of structure data,
4170 * by byte-swapping all > 1 byte fields!
4179 /* Get LAN Page 1 header */
4180 hdr.PageVersion = 0;
4183 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4184 cfg.cfghdr.hdr = &hdr;
4186 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4190 if ((rc = mpt_config(ioc, &cfg)) != 0)
4193 if (hdr.PageLength == 0)
4196 data_sz = hdr.PageLength * 4;
4198 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4200 memset((u8 *)ppage1_alloc, 0, data_sz);
4201 cfg.physAddr = page1_dma;
4202 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4204 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4206 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4207 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4210 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4213 * Normalize endianness of structure data,
4214 * by byte-swapping all > 1 byte fields!
4222 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4224 * mptbase_GetFcPortPage0 - Fetch FCPort config Page0.
4225 * @ioc: Pointer to MPT_ADAPTER structure
4226 * @portnum: IOC Port number
4228 * Return: 0 for success
4229 * -ENOMEM if no memory available
4230 * -EPERM if not allowed due to ISR context
4231 * -EAGAIN if no msg frames currently available
4232 * -EFAULT for non-successful reply or no reply (timeout)
4235 mptbase_GetFcPortPage0(MPT_ADAPTER *ioc, int portnum)
4237 ConfigPageHeader_t hdr;
4239 FCPortPage0_t *ppage0_alloc;
4240 FCPortPage0_t *pp0dest;
4241 dma_addr_t page0_dma;
4248 /* Get FCPort Page 0 header */
4249 hdr.PageVersion = 0;
4252 hdr.PageType = MPI_CONFIG_PAGETYPE_FC_PORT;
4253 cfg.cfghdr.hdr = &hdr;
4255 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4257 cfg.pageAddr = portnum;
4260 if ((rc = mpt_config(ioc, &cfg)) != 0)
4263 if (hdr.PageLength == 0)
4266 data_sz = hdr.PageLength * 4;
4268 ppage0_alloc = (FCPortPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4272 memset((u8 *)ppage0_alloc, 0, data_sz);
4273 cfg.physAddr = page0_dma;
4274 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4276 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4278 pp0dest = &ioc->fc_port_page0[portnum];
4279 copy_sz = min_t(int, sizeof(FCPortPage0_t), data_sz);
4280 memcpy(pp0dest, ppage0_alloc, copy_sz);
4283 * Normalize endianness of structure data,
4284 * by byte-swapping all > 1 byte fields!
4286 pp0dest->Flags = le32_to_cpu(pp0dest->Flags);
4287 pp0dest->PortIdentifier = le32_to_cpu(pp0dest->PortIdentifier);
4288 pp0dest->WWNN.Low = le32_to_cpu(pp0dest->WWNN.Low);
4289 pp0dest->WWNN.High = le32_to_cpu(pp0dest->WWNN.High);
4290 pp0dest->WWPN.Low = le32_to_cpu(pp0dest->WWPN.Low);
4291 pp0dest->WWPN.High = le32_to_cpu(pp0dest->WWPN.High);
4292 pp0dest->SupportedServiceClass = le32_to_cpu(pp0dest->SupportedServiceClass);
4293 pp0dest->SupportedSpeeds = le32_to_cpu(pp0dest->SupportedSpeeds);
4294 pp0dest->CurrentSpeed = le32_to_cpu(pp0dest->CurrentSpeed);
4295 pp0dest->MaxFrameSize = le32_to_cpu(pp0dest->MaxFrameSize);
4296 pp0dest->FabricWWNN.Low = le32_to_cpu(pp0dest->FabricWWNN.Low);
4297 pp0dest->FabricWWNN.High = le32_to_cpu(pp0dest->FabricWWNN.High);
4298 pp0dest->FabricWWPN.Low = le32_to_cpu(pp0dest->FabricWWPN.Low);
4299 pp0dest->FabricWWPN.High = le32_to_cpu(pp0dest->FabricWWPN.High);
4300 pp0dest->DiscoveredPortsCount = le32_to_cpu(pp0dest->DiscoveredPortsCount);
4301 pp0dest->MaxInitiators = le32_to_cpu(pp0dest->MaxInitiators);
4304 * if still doing discovery,
4305 * hang loose a while until finished
4307 if (pp0dest->PortState == MPI_FCPORTPAGE0_PORTSTATE_UNKNOWN) {
4309 msleep_interruptible(100);
4312 printk(MYIOC_s_INFO_FMT "Firmware discovery not"
4318 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4324 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4326 * mptbase_sas_persist_operation - Perform operation on SAS Persitent Table
4327 * @ioc: Pointer to MPT_ADAPTER structure
4328 * @sas_address: 64bit SAS Address for operation.
4329 * @target_id: specified target for operation
4330 * @bus: specified bus for operation
4331 * @persist_opcode: see below
4333 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4334 * devices not currently present.
4335 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4337 * NOTE: Don't use not this function during interrupt time.
4339 * Returns: 0 for success, non-zero error
4342 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4344 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4346 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
4347 SasIoUnitControlReply_t *sasIoUnitCntrReply;
4348 MPT_FRAME_HDR *mf = NULL;
4349 MPIHeader_t *mpi_hdr;
4352 /* insure garbage is not sent to fw */
4353 switch(persist_opcode) {
4355 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
4356 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
4364 printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode);
4366 /* Get a MF for this command.
4368 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4369 printk("%s: no msg frames!\n",__FUNCTION__);
4373 mpi_hdr = (MPIHeader_t *) mf;
4374 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
4375 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
4376 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
4377 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
4378 sasIoUnitCntrReq->Operation = persist_opcode;
4380 init_timer(&ioc->persist_timer);
4381 ioc->persist_timer.data = (unsigned long) ioc;
4382 ioc->persist_timer.function = mpt_timer_expired;
4383 ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
4384 ioc->persist_wait_done=0;
4385 add_timer(&ioc->persist_timer);
4386 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4387 wait_event(mpt_waitq, ioc->persist_wait_done);
4389 sasIoUnitCntrReply =
4390 (SasIoUnitControlReply_t *)ioc->persist_reply_frame;
4391 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
4392 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4394 sasIoUnitCntrReply->IOCStatus,
4395 sasIoUnitCntrReply->IOCLogInfo);
4399 printk("%s: success\n",__FUNCTION__);
4403 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4406 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
4407 MpiEventDataRaid_t * pRaidEventData)
4416 volume = pRaidEventData->VolumeID;
4417 reason = pRaidEventData->ReasonCode;
4418 disk = pRaidEventData->PhysDiskNum;
4419 status = le32_to_cpu(pRaidEventData->SettingsStatus);
4420 flags = (status >> 0) & 0xff;
4421 state = (status >> 8) & 0xff;
4423 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
4427 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
4428 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
4429 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
4430 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d\n",
4433 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
4438 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4439 printk(MYIOC_s_INFO_FMT " volume has been created\n",
4443 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4445 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
4449 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
4450 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
4454 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4455 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
4457 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
4459 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
4461 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
4464 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
4466 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
4467 ? ", quiesced" : "",
4468 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
4469 ? ", resync in progress" : "" );
4472 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
4473 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
4477 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4478 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
4482 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4483 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
4487 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
4488 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
4492 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4493 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
4495 state == MPI_PHYSDISK0_STATUS_ONLINE
4497 : state == MPI_PHYSDISK0_STATUS_MISSING
4499 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
4501 : state == MPI_PHYSDISK0_STATUS_FAILED
4503 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
4505 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
4506 ? "offline requested"
4507 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
4508 ? "failed requested"
4509 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
4512 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
4513 ? ", out of sync" : "",
4514 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
4515 ? ", quiesced" : "" );
4518 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
4519 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
4523 case MPI_EVENT_RAID_RC_SMART_DATA:
4524 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
4525 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
4528 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
4529 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
4535 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4537 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4538 * @ioc: Pointer to MPT_ADAPTER structure
4540 * Returns: 0 for success
4541 * -ENOMEM if no memory available
4542 * -EPERM if not allowed due to ISR context
4543 * -EAGAIN if no msg frames currently available
4544 * -EFAULT for non-successful reply or no reply (timeout)
4547 GetIoUnitPage2(MPT_ADAPTER *ioc)
4549 ConfigPageHeader_t hdr;
4551 IOUnitPage2_t *ppage_alloc;
4552 dma_addr_t page_dma;
4556 /* Get the page header */
4557 hdr.PageVersion = 0;
4560 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4561 cfg.cfghdr.hdr = &hdr;
4563 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4568 if ((rc = mpt_config(ioc, &cfg)) != 0)
4571 if (hdr.PageLength == 0)
4574 /* Read the config page */
4575 data_sz = hdr.PageLength * 4;
4577 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4579 memset((u8 *)ppage_alloc, 0, data_sz);
4580 cfg.physAddr = page_dma;
4581 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4583 /* If Good, save data */
4584 if ((rc = mpt_config(ioc, &cfg)) == 0)
4585 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4587 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4593 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4594 /* mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4595 * @ioc: Pointer to a Adapter Strucutre
4596 * @portnum: IOC port number
4598 * Return: -EFAULT if read of config page header fails
4600 * If read of SCSI Port Page 0 fails,
4601 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4602 * Adapter settings: async, narrow
4604 * If read of SCSI Port Page 2 fails,
4605 * Adapter settings valid
4606 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4611 * CHECK - what type of locking mechanisms should be used????
4614 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4619 ConfigPageHeader_t header;
4625 if (!ioc->spi_data.nvram) {
4628 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4629 mem = kmalloc(sz, GFP_ATOMIC);
4633 ioc->spi_data.nvram = (int *) mem;
4635 dprintk((MYIOC_s_INFO_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4636 ioc->name, ioc->spi_data.nvram, sz));
4639 /* Invalidate NVRAM information
4641 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4642 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4645 /* Read SPP0 header, allocate memory, then read page.
4647 header.PageVersion = 0;
4648 header.PageLength = 0;
4649 header.PageNumber = 0;
4650 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4651 cfg.cfghdr.hdr = &header;
4653 cfg.pageAddr = portnum;
4654 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4656 cfg.timeout = 0; /* use default */
4657 if (mpt_config(ioc, &cfg) != 0)
4660 if (header.PageLength > 0) {
4661 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4663 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4664 cfg.physAddr = buf_dma;
4665 if (mpt_config(ioc, &cfg) != 0) {
4666 ioc->spi_data.maxBusWidth = MPT_NARROW;
4667 ioc->spi_data.maxSyncOffset = 0;
4668 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4669 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4671 ddvprintk((MYIOC_s_INFO_FMT "Unable to read PortPage0 minSyncFactor=%x\n",
4672 ioc->name, ioc->spi_data.minSyncFactor));
4674 /* Save the Port Page 0 data
4676 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
4677 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4678 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4680 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
4681 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4682 ddvprintk((KERN_INFO MYNAM " :%s noQas due to Capabilities=%x\n",
4683 ioc->name, pPP0->Capabilities));
4685 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4686 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4688 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4689 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4690 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4691 ddvprintk((MYIOC_s_INFO_FMT "PortPage0 minSyncFactor=%x\n",
4692 ioc->name, ioc->spi_data.minSyncFactor));
4694 ioc->spi_data.maxSyncOffset = 0;
4695 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4698 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4700 /* Update the minSyncFactor based on bus type.
4702 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4703 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
4705 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
4706 ioc->spi_data.minSyncFactor = MPT_ULTRA;
4707 ddvprintk((MYIOC_s_INFO_FMT "HVD or SE detected, minSyncFactor=%x\n",
4708 ioc->name, ioc->spi_data.minSyncFactor));
4713 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4718 /* SCSI Port Page 2 - Read the header then the page.
4720 header.PageVersion = 0;
4721 header.PageLength = 0;
4722 header.PageNumber = 2;
4723 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4724 cfg.cfghdr.hdr = &header;
4726 cfg.pageAddr = portnum;
4727 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4729 if (mpt_config(ioc, &cfg) != 0)
4732 if (header.PageLength > 0) {
4733 /* Allocate memory and read SCSI Port Page 2
4735 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4737 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
4738 cfg.physAddr = buf_dma;
4739 if (mpt_config(ioc, &cfg) != 0) {
4740 /* Nvram data is left with INVALID mark
4744 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
4745 MpiDeviceInfo_t *pdevice = NULL;
4748 * Save "Set to Avoid SCSI Bus Resets" flag
4750 ioc->spi_data.bus_reset =
4751 (le32_to_cpu(pPP2->PortFlags) &
4752 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
4755 /* Save the Port Page 2 data
4756 * (reformat into a 32bit quantity)
4758 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
4759 ioc->spi_data.PortFlags = data;
4760 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4761 pdevice = &pPP2->DeviceSettings[ii];
4762 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
4763 (pdevice->SyncFactor << 8) | pdevice->Timeout;
4764 ioc->spi_data.nvram[ii] = data;
4768 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4772 /* Update Adapter limits with those from NVRAM
4773 * Comment: Don't need to do this. Target performance
4774 * parameters will never exceed the adapters limits.
4780 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4781 /* mpt_readScsiDevicePageHeaders - save version and length of SDP1
4782 * @ioc: Pointer to a Adapter Strucutre
4783 * @portnum: IOC port number
4785 * Return: -EFAULT if read of config page header fails
4789 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
4792 ConfigPageHeader_t header;
4794 /* Read the SCSI Device Page 1 header
4796 header.PageVersion = 0;
4797 header.PageLength = 0;
4798 header.PageNumber = 1;
4799 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4800 cfg.cfghdr.hdr = &header;
4802 cfg.pageAddr = portnum;
4803 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4806 if (mpt_config(ioc, &cfg) != 0)
4809 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
4810 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
4812 header.PageVersion = 0;
4813 header.PageLength = 0;
4814 header.PageNumber = 0;
4815 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4816 if (mpt_config(ioc, &cfg) != 0)
4819 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
4820 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
4822 dcprintk((MYIOC_s_INFO_FMT "Headers: 0: version %d length %d\n",
4823 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
4825 dcprintk((MYIOC_s_INFO_FMT "Headers: 1: version %d length %d\n",
4826 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
4830 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4832 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
4833 * @ioc: Pointer to a Adapter Strucutre
4834 * @portnum: IOC port number
4838 * -EFAULT if read of config page header fails or data pointer not NULL
4839 * -ENOMEM if pci_alloc failed
4842 mpt_findImVolumes(MPT_ADAPTER *ioc)
4846 ConfigPageIoc2RaidVol_t *pIocRv;
4847 dma_addr_t ioc2_dma;
4849 ConfigPageHeader_t header;
4856 /* Read IOCP2 header then the page.
4858 header.PageVersion = 0;
4859 header.PageLength = 0;
4860 header.PageNumber = 2;
4861 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4862 cfg.cfghdr.hdr = &header;
4865 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4868 if (mpt_config(ioc, &cfg) != 0)
4871 if (header.PageLength == 0)
4874 iocpage2sz = header.PageLength * 4;
4875 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
4879 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4880 cfg.physAddr = ioc2_dma;
4881 if (mpt_config(ioc, &cfg) != 0)
4884 if ( (mem = (u8 *)ioc->raid_data.pIocPg2) == NULL ) {
4885 mem = kmalloc(iocpage2sz, GFP_ATOMIC);
4887 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
4892 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
4894 /* Identify RAID Volume Id's */
4895 nVols = pIoc2->NumActiveVolumes;
4901 /* At least 1 RAID Volume
4903 pIocRv = pIoc2->RaidVolume;
4904 ioc->raid_data.isRaid = 0;
4905 for (jj = 0; jj < nVols; jj++, pIocRv++) {
4906 vid = pIocRv->VolumeID;
4907 vbus = pIocRv->VolumeBus;
4908 vioc = pIocRv->VolumeIOC;
4913 ioc->raid_data.isRaid |= (1 << vid);
4915 /* Error! Always bus 0
4921 /* Identify Hidden Physical Disk Id's */
4922 nPhys = pIoc2->NumActivePhysDisks;
4924 /* No physical disks.
4927 mpt_read_ioc_pg_3(ioc);
4931 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
4937 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
4942 ConfigPageHeader_t header;
4943 dma_addr_t ioc3_dma;
4946 /* Free the old page
4948 kfree(ioc->raid_data.pIocPg3);
4949 ioc->raid_data.pIocPg3 = NULL;
4951 /* There is at least one physical disk.
4952 * Read and save IOC Page 3
4954 header.PageVersion = 0;
4955 header.PageLength = 0;
4956 header.PageNumber = 3;
4957 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4958 cfg.cfghdr.hdr = &header;
4961 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4964 if (mpt_config(ioc, &cfg) != 0)
4967 if (header.PageLength == 0)
4970 /* Read Header good, alloc memory
4972 iocpage3sz = header.PageLength * 4;
4973 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
4977 /* Read the Page and save the data
4978 * into malloc'd memory.
4980 cfg.physAddr = ioc3_dma;
4981 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4982 if (mpt_config(ioc, &cfg) == 0) {
4983 mem = kmalloc(iocpage3sz, GFP_ATOMIC);
4985 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
4986 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
4990 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
4996 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
5000 ConfigPageHeader_t header;
5001 dma_addr_t ioc4_dma;
5004 /* Read and save IOC Page 4
5006 header.PageVersion = 0;
5007 header.PageLength = 0;
5008 header.PageNumber = 4;
5009 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5010 cfg.cfghdr.hdr = &header;
5013 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5016 if (mpt_config(ioc, &cfg) != 0)
5019 if (header.PageLength == 0)
5022 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
5023 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
5024 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
5028 ioc4_dma = ioc->spi_data.IocPg4_dma;
5029 iocpage4sz = ioc->spi_data.IocPg4Sz;
5032 /* Read the Page into dma memory.
5034 cfg.physAddr = ioc4_dma;
5035 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5036 if (mpt_config(ioc, &cfg) == 0) {
5037 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
5038 ioc->spi_data.IocPg4_dma = ioc4_dma;
5039 ioc->spi_data.IocPg4Sz = iocpage4sz;
5041 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
5042 ioc->spi_data.pIocPg4 = NULL;
5047 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
5051 ConfigPageHeader_t header;
5052 dma_addr_t ioc1_dma;
5056 /* Check the Coalescing Timeout in IOC Page 1
5058 header.PageVersion = 0;
5059 header.PageLength = 0;
5060 header.PageNumber = 1;
5061 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5062 cfg.cfghdr.hdr = &header;
5065 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5068 if (mpt_config(ioc, &cfg) != 0)
5071 if (header.PageLength == 0)
5074 /* Read Header good, alloc memory
5076 iocpage1sz = header.PageLength * 4;
5077 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
5081 /* Read the Page and check coalescing timeout
5083 cfg.physAddr = ioc1_dma;
5084 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5085 if (mpt_config(ioc, &cfg) == 0) {
5087 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
5088 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
5089 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
5091 dprintk((MYIOC_s_INFO_FMT "Coalescing Enabled Timeout = %d\n",
5094 if (tmp > MPT_COALESCING_TIMEOUT) {
5095 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
5097 /* Write NVRAM and current
5100 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5101 if (mpt_config(ioc, &cfg) == 0) {
5102 dprintk((MYIOC_s_INFO_FMT "Reset Current Coalescing Timeout to = %d\n",
5103 ioc->name, MPT_COALESCING_TIMEOUT));
5105 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
5106 if (mpt_config(ioc, &cfg) == 0) {
5107 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout to = %d\n",
5108 ioc->name, MPT_COALESCING_TIMEOUT));
5110 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout Failed\n",
5115 dprintk((MYIOC_s_WARN_FMT "Reset of Current Coalescing Timeout Failed!\n",
5121 dprintk((MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
5125 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
5130 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5132 * SendEventNotification - Send EventNotification (on or off) request
5134 * @ioc: Pointer to MPT_ADAPTER structure
5135 * @EvSwitch: Event switch flags
5138 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
5140 EventNotification_t *evnp;
5142 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
5144 devtprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
5148 memset(evnp, 0, sizeof(*evnp));
5150 devtprintk((MYIOC_s_INFO_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
5152 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
5153 evnp->ChainOffset = 0;
5155 evnp->Switch = EvSwitch;
5157 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
5162 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5164 * SendEventAck - Send EventAck request to MPT adapter.
5165 * @ioc: Pointer to MPT_ADAPTER structure
5166 * @evnp: Pointer to original EventNotification request
5169 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
5173 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5174 printk(MYIOC_s_WARN_FMT "Unable to allocate event ACK "
5175 "request frame for Event=%x EventContext=%x EventData=%x!\n",
5176 ioc->name, evnp->Event, le32_to_cpu(evnp->EventContext),
5177 le32_to_cpu(evnp->Data[0]));
5180 memset(pAck, 0, sizeof(*pAck));
5182 dprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name));
5184 pAck->Function = MPI_FUNCTION_EVENT_ACK;
5185 pAck->ChainOffset = 0;
5187 pAck->Event = evnp->Event;
5188 pAck->EventContext = evnp->EventContext;
5190 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
5195 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5197 * mpt_config - Generic function to issue config message
5198 * @ioc - Pointer to an adapter structure
5199 * @cfg - Pointer to a configuration structure. Struct contains
5200 * action, page address, direction, physical address
5201 * and pointer to a configuration page header
5202 * Page header is updated.
5204 * Returns 0 for success
5205 * -EPERM if not allowed due to ISR context
5206 * -EAGAIN if no msg frames currently available
5207 * -EFAULT for non-successful reply or no reply (timeout)
5210 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5213 ConfigExtendedPageHeader_t *pExtHdr = NULL;
5215 unsigned long flags;
5220 /* Prevent calling wait_event() (below), if caller happens
5221 * to be in ISR context, because that is fatal!
5223 in_isr = in_interrupt();
5225 dcprintk((MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
5230 /* Get and Populate a free Frame
5232 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5233 dcprintk((MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
5237 pReq = (Config_t *)mf;
5238 pReq->Action = pCfg->action;
5240 pReq->ChainOffset = 0;
5241 pReq->Function = MPI_FUNCTION_CONFIG;
5243 /* Assume page type is not extended and clear "reserved" fields. */
5244 pReq->ExtPageLength = 0;
5245 pReq->ExtPageType = 0;
5248 for (ii=0; ii < 8; ii++)
5249 pReq->Reserved2[ii] = 0;
5251 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
5252 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
5253 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
5254 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
5256 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5257 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
5258 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
5259 pReq->ExtPageType = pExtHdr->ExtPageType;
5260 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
5262 /* Page Length must be treated as a reserved field for the extended header. */
5263 pReq->Header.PageLength = 0;
5266 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
5268 /* Add a SGE to the config request.
5271 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
5273 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
5275 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5276 flagsLength |= pExtHdr->ExtPageLength * 4;
5278 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
5279 ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action));
5282 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
5284 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
5285 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
5288 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
5290 /* Append pCfg pointer to end of mf
5292 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5294 /* Initalize the timer
5296 init_timer(&pCfg->timer);
5297 pCfg->timer.data = (unsigned long) ioc;
5298 pCfg->timer.function = mpt_timer_expired;
5299 pCfg->wait_done = 0;
5301 /* Set the timer; ensure 10 second minimum */
5302 if (pCfg->timeout < 10)
5303 pCfg->timer.expires = jiffies + HZ*10;
5305 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5307 /* Add to end of Q, set timer and then issue this command */
5308 spin_lock_irqsave(&ioc->FreeQlock, flags);
5309 list_add_tail(&pCfg->linkage, &ioc->configQ);
5310 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5312 add_timer(&pCfg->timer);
5313 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5314 wait_event(mpt_waitq, pCfg->wait_done);
5316 /* mf has been freed - do not access */
5323 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5325 * mpt_toolbox - Generic function to issue toolbox message
5326 * @ioc - Pointer to an adapter structure
5327 * @cfg - Pointer to a toolbox structure. Struct contains
5328 * action, page address, direction, physical address
5329 * and pointer to a configuration page header
5330 * Page header is updated.
5332 * Returns 0 for success
5333 * -EPERM if not allowed due to ISR context
5334 * -EAGAIN if no msg frames currently available
5335 * -EFAULT for non-successful reply or no reply (timeout)
5338 mpt_toolbox(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5340 ToolboxIstwiReadWriteRequest_t *pReq;
5342 struct pci_dev *pdev;
5343 unsigned long flags;
5348 /* Prevent calling wait_event() (below), if caller happens
5349 * to be in ISR context, because that is fatal!
5351 in_isr = in_interrupt();
5353 dcprintk((MYIOC_s_WARN_FMT "toobox request not allowed in ISR context!\n",
5358 /* Get and Populate a free Frame
5360 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5361 dcprintk((MYIOC_s_WARN_FMT "mpt_toolbox: no msg frames!\n",
5365 pReq = (ToolboxIstwiReadWriteRequest_t *)mf;
5366 pReq->Tool = pCfg->action;
5368 pReq->ChainOffset = 0;
5369 pReq->Function = MPI_FUNCTION_TOOLBOX;
5370 pReq->Reserved1 = 0;
5371 pReq->Reserved2 = 0;
5373 pReq->Flags = pCfg->dir;
5375 pReq->Reserved3 = 0;
5376 pReq->NumAddressBytes = 0x01;
5377 pReq->Reserved4 = 0;
5378 pReq->DataLength = cpu_to_le16(0x04);
5380 if (pdev->devfn & 1)
5381 pReq->DeviceAddr = 0xB2;
5383 pReq->DeviceAddr = 0xB0;
5387 pReq->Reserved5 = 0;
5389 /* Add a SGE to the config request.
5392 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | 4;
5394 mpt_add_sge((char *)&pReq->SGL, flagsLength, pCfg->physAddr);
5396 dcprintk((MYIOC_s_INFO_FMT "Sending Toolbox request, Tool=%x\n",
5397 ioc->name, pReq->Tool));
5399 /* Append pCfg pointer to end of mf
5401 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5403 /* Initalize the timer
5405 init_timer(&pCfg->timer);
5406 pCfg->timer.data = (unsigned long) ioc;
5407 pCfg->timer.function = mpt_timer_expired;
5408 pCfg->wait_done = 0;
5410 /* Set the timer; ensure 10 second minimum */
5411 if (pCfg->timeout < 10)
5412 pCfg->timer.expires = jiffies + HZ*10;
5414 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5416 /* Add to end of Q, set timer and then issue this command */
5417 spin_lock_irqsave(&ioc->FreeQlock, flags);
5418 list_add_tail(&pCfg->linkage, &ioc->configQ);
5419 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5421 add_timer(&pCfg->timer);
5422 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5423 wait_event(mpt_waitq, pCfg->wait_done);
5425 /* mf has been freed - do not access */
5432 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5434 * mpt_timer_expired - Call back for timer process.
5435 * Used only internal config functionality.
5436 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5439 mpt_timer_expired(unsigned long data)
5441 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
5443 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired! \n", ioc->name));
5445 /* Perform a FW reload */
5446 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
5447 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
5449 /* No more processing.
5450 * Hard reset clean-up will wake up
5451 * process and free all resources.
5453 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired complete!\n", ioc->name));
5458 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5460 * mpt_ioc_reset - Base cleanup for hard reset
5461 * @ioc: Pointer to the adapter structure
5462 * @reset_phase: Indicates pre- or post-reset functionality
5464 * Remark: Free's resources with internally generated commands.
5467 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
5470 unsigned long flags;
5472 dprintk((KERN_WARNING MYNAM
5473 ": IOC %s_reset routed to MPT base driver!\n",
5474 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
5475 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
5477 if (reset_phase == MPT_IOC_SETUP_RESET) {
5479 } else if (reset_phase == MPT_IOC_PRE_RESET) {
5480 /* If the internal config Q is not empty -
5481 * delete timer. MF resources will be freed when
5482 * the FIFO's are primed.
5484 spin_lock_irqsave(&ioc->FreeQlock, flags);
5485 list_for_each_entry(pCfg, &ioc->configQ, linkage)
5486 del_timer(&pCfg->timer);
5487 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5492 /* Search the configQ for internal commands.
5493 * Flush the Q, and wake up all suspended threads.
5495 spin_lock_irqsave(&ioc->FreeQlock, flags);
5496 list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
5497 list_del(&pCfg->linkage);
5499 pCfg->status = MPT_CONFIG_ERROR;
5500 pCfg->wait_done = 1;
5501 wake_up(&mpt_waitq);
5503 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5506 return 1; /* currently means nothing really */
5510 #ifdef CONFIG_PROC_FS /* { */
5511 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5513 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5515 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5517 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5519 * Returns 0 for success, non-zero for failure.
5522 procmpt_create(void)
5524 struct proc_dir_entry *ent;
5526 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
5527 if (mpt_proc_root_dir == NULL)
5530 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5532 ent->read_proc = procmpt_summary_read;
5534 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5536 ent->read_proc = procmpt_version_read;
5541 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5543 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5545 * Returns 0 for success, non-zero for failure.
5548 procmpt_destroy(void)
5550 remove_proc_entry("version", mpt_proc_root_dir);
5551 remove_proc_entry("summary", mpt_proc_root_dir);
5552 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
5555 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5557 * procmpt_summary_read - Handle read request from /proc/mpt/summary
5558 * or from /proc/mpt/iocN/summary.
5559 * @buf: Pointer to area to write information
5560 * @start: Pointer to start pointer
5561 * @offset: Offset to start writing
5563 * @eof: Pointer to EOF integer
5566 * Returns number of characters written to process performing the read.
5569 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5579 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5583 list_for_each_entry(ioc, &ioc_list, list) {
5586 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5589 if ((out-buf) >= request)
5596 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5599 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5601 * procmpt_version_read - Handle read request from /proc/mpt/version.
5602 * @buf: Pointer to area to write information
5603 * @start: Pointer to start pointer
5604 * @offset: Offset to start writing
5606 * @eof: Pointer to EOF integer
5609 * Returns number of characters written to process performing the read.
5612 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5615 int scsi, fc, sas, lan, ctl, targ, dmp;
5619 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
5620 len += sprintf(buf+len, " Fusion MPT base driver\n");
5622 scsi = fc = sas = lan = ctl = targ = dmp = 0;
5623 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5625 if (MptCallbacks[ii]) {
5626 switch (MptDriverClass[ii]) {
5628 if (!scsi++) drvname = "SPI host";
5631 if (!fc++) drvname = "FC host";
5634 if (!sas++) drvname = "SAS host";
5637 if (!lan++) drvname = "LAN";
5640 if (!targ++) drvname = "SCSI target";
5643 if (!ctl++) drvname = "ioctl";
5648 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
5652 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5655 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5657 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
5658 * @buf: Pointer to area to write information
5659 * @start: Pointer to start pointer
5660 * @offset: Offset to start writing
5662 * @eof: Pointer to EOF integer
5665 * Returns number of characters written to process performing the read.
5668 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5670 MPT_ADAPTER *ioc = data;
5676 mpt_get_fw_exp_ver(expVer, ioc);
5678 len = sprintf(buf, "%s:", ioc->name);
5679 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
5680 len += sprintf(buf+len, " (f/w download boot flag set)");
5681 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
5682 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
5684 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
5685 ioc->facts.ProductID,
5687 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
5688 if (ioc->facts.FWImageSize)
5689 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
5690 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
5691 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
5692 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
5694 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
5695 ioc->facts.CurrentHostMfaHighAddr);
5696 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
5697 ioc->facts.CurrentSenseBufferHighAddr);
5699 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
5700 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
5702 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
5703 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
5705 * Rounding UP to nearest 4-kB boundary here...
5707 sz = (ioc->req_sz * ioc->req_depth) + 128;
5708 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
5709 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
5710 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
5711 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
5712 4*ioc->facts.RequestFrameSize,
5713 ioc->facts.GlobalCredits);
5715 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
5716 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
5717 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
5718 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
5719 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
5720 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
5721 ioc->facts.CurReplyFrameSize,
5722 ioc->facts.ReplyQueueDepth);
5724 len += sprintf(buf+len, " MaxDevices = %d\n",
5725 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
5726 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
5729 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
5730 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
5732 ioc->facts.NumberOfPorts);
5733 if (ioc->bus_type == FC) {
5734 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
5735 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5736 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
5737 a[5], a[4], a[3], a[2], a[1], a[0]);
5739 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
5740 ioc->fc_port_page0[p].WWNN.High,
5741 ioc->fc_port_page0[p].WWNN.Low,
5742 ioc->fc_port_page0[p].WWPN.High,
5743 ioc->fc_port_page0[p].WWPN.Low);
5747 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5750 #endif /* CONFIG_PROC_FS } */
5752 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5754 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
5757 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
5758 sprintf(buf, " (Exp %02d%02d)",
5759 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
5760 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
5763 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
5764 strcat(buf, " [MDBG]");
5768 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5770 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
5771 * @ioc: Pointer to MPT_ADAPTER structure
5772 * @buffer: Pointer to buffer where IOC summary info should be written
5773 * @size: Pointer to number of bytes we wrote (set by this routine)
5774 * @len: Offset at which to start writing in buffer
5775 * @showlan: Display LAN stuff?
5777 * This routine writes (english readable) ASCII text, which represents
5778 * a summary of IOC information, to a buffer.
5781 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
5786 mpt_get_fw_exp_ver(expVer, ioc);
5789 * Shorter summary of attached ioc's...
5791 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
5794 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
5795 ioc->facts.FWVersion.Word,
5797 ioc->facts.NumberOfPorts,
5800 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
5801 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5802 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
5803 a[5], a[4], a[3], a[2], a[1], a[0]);
5807 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
5809 y += sprintf(buffer+len+y, ", IRQ=%s", __irq_itoa(ioc->pci_irq));
5813 y += sprintf(buffer+len+y, " (disabled)");
5815 y += sprintf(buffer+len+y, "\n");
5820 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5824 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5826 * mpt_HardResetHandler - Generic reset handler, issue SCSI Task
5827 * Management call based on input arg values. If TaskMgmt fails,
5828 * return associated SCSI request.
5829 * @ioc: Pointer to MPT_ADAPTER structure
5830 * @sleepFlag: Indicates if sleep or schedule must be called.
5832 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
5833 * or a non-interrupt thread. In the former, must not call schedule().
5835 * Remark: A return of -1 is a FATAL error case, as it means a
5836 * FW reload/initialization failed.
5838 * Returns 0 for SUCCESS or -1 if FAILED.
5841 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
5844 unsigned long flags;
5846 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name));
5848 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
5849 printk("MF count 0x%x !\n", ioc->mfcnt);
5852 /* Reset the adapter. Prevent more than 1 call to
5853 * mpt_do_ioc_recovery at any instant in time.
5855 spin_lock_irqsave(&ioc->diagLock, flags);
5856 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
5857 spin_unlock_irqrestore(&ioc->diagLock, flags);
5860 ioc->diagPending = 1;
5862 spin_unlock_irqrestore(&ioc->diagLock, flags);
5864 /* FIXME: If do_ioc_recovery fails, repeat....
5867 /* The SCSI driver needs to adjust timeouts on all current
5868 * commands prior to the diagnostic reset being issued.
5869 * Prevents timeouts occuring during a diagnostic reset...very bad.
5870 * For all other protocol drivers, this is a no-op.
5876 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5877 if (MptResetHandlers[ii]) {
5878 dtmprintk((MYIOC_s_INFO_FMT "Calling IOC reset_setup handler #%d\n",
5880 r += (*(MptResetHandlers[ii]))(ioc, MPT_IOC_SETUP_RESET);
5882 dtmprintk((MYIOC_s_INFO_FMT "Calling alt-%s setup reset handler #%d\n",
5883 ioc->name, ioc->alt_ioc->name, ii));
5884 r += (*(MptResetHandlers[ii]))(ioc->alt_ioc, MPT_IOC_SETUP_RESET);
5890 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
5891 printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
5896 ioc->alt_ioc->reload_fw = 0;
5898 spin_lock_irqsave(&ioc->diagLock, flags);
5899 ioc->diagPending = 0;
5901 ioc->alt_ioc->diagPending = 0;
5902 spin_unlock_irqrestore(&ioc->diagLock, flags);
5904 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
5909 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5911 EventDescriptionStr(u8 event, u32 evData0, char *evStr)
5916 case MPI_EVENT_NONE:
5919 case MPI_EVENT_LOG_DATA:
5922 case MPI_EVENT_STATE_CHANGE:
5923 ds = "State Change";
5925 case MPI_EVENT_UNIT_ATTENTION:
5926 ds = "Unit Attention";
5928 case MPI_EVENT_IOC_BUS_RESET:
5929 ds = "IOC Bus Reset";
5931 case MPI_EVENT_EXT_BUS_RESET:
5932 ds = "External Bus Reset";
5934 case MPI_EVENT_RESCAN:
5935 ds = "Bus Rescan Event";
5936 /* Ok, do we need to do anything here? As far as
5937 I can tell, this is when a new device gets added
5940 case MPI_EVENT_LINK_STATUS_CHANGE:
5941 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
5942 ds = "Link Status(FAILURE) Change";
5944 ds = "Link Status(ACTIVE) Change";
5946 case MPI_EVENT_LOOP_STATE_CHANGE:
5947 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
5948 ds = "Loop State(LIP) Change";
5949 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
5950 ds = "Loop State(LPE) Change"; /* ??? */
5952 ds = "Loop State(LPB) Change"; /* ??? */
5954 case MPI_EVENT_LOGOUT:
5957 case MPI_EVENT_EVENT_CHANGE:
5959 ds = "Events(ON) Change";
5961 ds = "Events(OFF) Change";
5963 case MPI_EVENT_INTEGRATED_RAID:
5965 u8 ReasonCode = (u8)(evData0 >> 16);
5966 switch (ReasonCode) {
5967 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
5968 ds = "Integrated Raid: Volume Created";
5970 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
5971 ds = "Integrated Raid: Volume Deleted";
5973 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
5974 ds = "Integrated Raid: Volume Settings Changed";
5976 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
5977 ds = "Integrated Raid: Volume Status Changed";
5979 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
5980 ds = "Integrated Raid: Volume Physdisk Changed";
5982 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
5983 ds = "Integrated Raid: Physdisk Created";
5985 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
5986 ds = "Integrated Raid: Physdisk Deleted";
5988 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
5989 ds = "Integrated Raid: Physdisk Settings Changed";
5991 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
5992 ds = "Integrated Raid: Physdisk Status Changed";
5994 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
5995 ds = "Integrated Raid: Domain Validation Needed";
5997 case MPI_EVENT_RAID_RC_SMART_DATA :
5998 ds = "Integrated Raid; Smart Data";
6000 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
6001 ds = "Integrated Raid: Replace Action Started";
6004 ds = "Integrated Raid";
6009 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
6010 ds = "SCSI Device Status Change";
6012 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
6014 u8 ReasonCode = (u8)(evData0 >> 16);
6015 switch (ReasonCode) {
6016 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
6017 ds = "SAS Device Status Change: Added";
6019 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
6020 ds = "SAS Device Status Change: Deleted";
6022 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
6023 ds = "SAS Device Status Change: SMART Data";
6025 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
6026 ds = "SAS Device Status Change: No Persistancy Added";
6029 ds = "SAS Device Status Change: Unknown";
6034 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
6035 ds = "Bus Timer Expired";
6037 case MPI_EVENT_QUEUE_FULL:
6040 case MPI_EVENT_SAS_SES:
6041 ds = "SAS SES Event";
6043 case MPI_EVENT_PERSISTENT_TABLE_FULL:
6044 ds = "Persistent Table Full";
6046 case MPI_EVENT_SAS_PHY_LINK_STATUS:
6047 ds = "SAS PHY Link Status";
6049 case MPI_EVENT_SAS_DISCOVERY_ERROR:
6050 ds = "SAS Discovery Error";
6054 * MPT base "custom" events may be added here...
6063 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6065 * ProcessEventNotification - Route a received EventNotificationReply to
6066 * all currently regeistered event handlers.
6067 * @ioc: Pointer to MPT_ADAPTER structure
6068 * @pEventReply: Pointer to EventNotification reply frame
6069 * @evHandlers: Pointer to integer, number of event handlers
6071 * Returns sum of event handlers return values.
6074 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
6086 * Do platform normalization of values
6088 event = le32_to_cpu(pEventReply->Event) & 0xFF;
6089 // evCtx = le32_to_cpu(pEventReply->EventContext);
6090 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
6092 evData0 = le32_to_cpu(pEventReply->Data[0]);
6095 EventDescriptionStr(event, evData0, evStr);
6096 devtprintk((MYIOC_s_INFO_FMT "MPT event (%s=%02Xh) detected!\n",
6101 #if defined(MPT_DEBUG) || defined(MPT_DEBUG_EVENTS)
6102 printk(KERN_INFO MYNAM ": Event data:\n" KERN_INFO);
6103 for (ii = 0; ii < evDataLen; ii++)
6104 printk(" %08x", le32_to_cpu(pEventReply->Data[ii]));
6109 * Do general / base driver event processing
6112 case MPI_EVENT_EVENT_CHANGE: /* 0A */
6114 u8 evState = evData0 & 0xFF;
6116 /* CHECKME! What if evState unexpectedly says OFF (0)? */
6118 /* Update EventState field in cached IocFacts */
6119 if (ioc->facts.Function) {
6120 ioc->facts.EventState = evState;
6124 case MPI_EVENT_INTEGRATED_RAID:
6125 mptbase_raid_process_event_data(ioc,
6126 (MpiEventDataRaid_t *)pEventReply->Data);
6133 * Should this event be logged? Events are written sequentially.
6134 * When buffer is full, start again at the top.
6136 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
6139 idx = ioc->eventContext % ioc->eventLogSize;
6141 ioc->events[idx].event = event;
6142 ioc->events[idx].eventContext = ioc->eventContext;
6144 for (ii = 0; ii < 2; ii++) {
6146 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
6148 ioc->events[idx].data[ii] = 0;
6151 ioc->eventContext++;
6156 * Call each currently registered protocol event handler.
6158 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
6159 if (MptEvHandlers[ii]) {
6160 devtprintk((MYIOC_s_INFO_FMT "Routing Event to event handler #%d\n",
6162 r += (*(MptEvHandlers[ii]))(ioc, pEventReply);
6166 /* FIXME? Examine results here? */
6169 * If needed, send (a single) EventAck.
6171 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
6172 devtprintk((MYIOC_s_WARN_FMT
6173 "EventAck required\n",ioc->name));
6174 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
6175 devtprintk((MYIOC_s_WARN_FMT "SendEventAck returned %d\n",
6180 *evHandlers = handlers;
6184 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6186 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
6187 * @ioc: Pointer to MPT_ADAPTER structure
6188 * @log_info: U32 LogInfo reply word from the IOC
6190 * Refer to lsi/fc_log.h.
6193 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
6195 static char *subcl_str[8] = {
6196 "FCP Initiator", "FCP Target", "LAN", "MPI Message Layer",
6197 "FC Link", "Context Manager", "Invalid Field Offset", "State Change Info"
6199 u8 subcl = (log_info >> 24) & 0x7;
6201 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubCl={%s}\n",
6202 ioc->name, log_info, subcl_str[subcl]);
6205 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6207 * mpt_sp_log_info - Log information returned from SCSI Parallel IOC.
6208 * @ioc: Pointer to MPT_ADAPTER structure
6209 * @mr: Pointer to MPT reply frame
6210 * @log_info: U32 LogInfo word from the IOC
6212 * Refer to lsi/sp_log.h.
6215 mpt_sp_log_info(MPT_ADAPTER *ioc, u32 log_info)
6217 u32 info = log_info & 0x00FF0000;
6218 char *desc = "unknown";
6222 desc = "bug! MID not found";
6223 if (ioc->reload_fw == 0)
6228 desc = "Parity Error";
6232 desc = "ASYNC Outbound Overrun";
6236 desc = "SYNC Offset Error";
6244 desc = "Msg In Overflow";
6252 desc = "Outbound DMA Overrun";
6256 desc = "Task Management";
6260 desc = "Device Problem";
6264 desc = "Invalid Phase Change";
6268 desc = "Untagged Table Size";
6273 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
6276 /* strings for sas loginfo */
6277 static char *originator_str[] = {
6282 static char *iop_code_str[] = {
6284 "Invalid SAS Address", /* 01h */
6286 "Invalid Page", /* 03h */
6288 "Task Terminated" /* 05h */
6290 static char *pl_code_str[] = {
6292 "Open Failure", /* 01h */
6293 "Invalid Scatter Gather List", /* 02h */
6294 "Wrong Relative Offset or Frame Length", /* 03h */
6295 "Frame Transfer Error", /* 04h */
6296 "Transmit Frame Connected Low", /* 05h */
6297 "SATA Non-NCQ RW Error Bit Set", /* 06h */
6298 "SATA Read Log Receive Data Error", /* 07h */
6299 "SATA NCQ Fail All Commands After Error", /* 08h */
6300 "SATA Error in Receive Set Device Bit FIS", /* 09h */
6301 "Receive Frame Invalid Message", /* 0Ah */
6302 "Receive Context Message Valid Error", /* 0Bh */
6303 "Receive Frame Current Frame Error", /* 0Ch */
6304 "SATA Link Down", /* 0Dh */
6305 "Discovery SATA Init W IOS", /* 0Eh */
6306 "Config Invalid Page", /* 0Fh */
6307 "Discovery SATA Init Timeout", /* 10h */
6310 "IO Not Yet Executed", /* 13h */
6311 "IO Executed", /* 14h */
6323 "Enclosure Management" /* 20h */
6326 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6328 * mpt_sas_log_info - Log information returned from SAS IOC.
6329 * @ioc: Pointer to MPT_ADAPTER structure
6330 * @log_info: U32 LogInfo reply word from the IOC
6332 * Refer to lsi/mpi_log_sas.h.
6335 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
6337 union loginfo_type {
6346 union loginfo_type sas_loginfo;
6347 char *code_desc = NULL;
6349 sas_loginfo.loginfo = log_info;
6350 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
6351 (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
6353 if ((sas_loginfo.dw.originator == 0 /*IOP*/) &&
6354 (sas_loginfo.dw.code < sizeof(iop_code_str)/sizeof(char*))) {
6355 code_desc = iop_code_str[sas_loginfo.dw.code];
6356 }else if ((sas_loginfo.dw.originator == 1 /*PL*/) &&
6357 (sas_loginfo.dw.code < sizeof(pl_code_str)/sizeof(char*) )) {
6358 code_desc = pl_code_str[sas_loginfo.dw.code];
6361 if (code_desc != NULL)
6362 printk(MYIOC_s_INFO_FMT
6363 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
6364 " SubCode(0x%04x)\n",
6367 originator_str[sas_loginfo.dw.originator],
6369 sas_loginfo.dw.subcode);
6371 printk(MYIOC_s_INFO_FMT
6372 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
6373 " SubCode(0x%04x)\n",
6376 originator_str[sas_loginfo.dw.originator],
6377 sas_loginfo.dw.code,
6378 sas_loginfo.dw.subcode);
6381 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6383 * mpt_sp_ioc_info - IOC information returned from SCSI Parallel IOC.
6384 * @ioc: Pointer to MPT_ADAPTER structure
6385 * @ioc_status: U32 IOCStatus word from IOC
6386 * @mf: Pointer to MPT request frame
6388 * Refer to lsi/mpi.h.
6391 mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
6393 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
6397 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
6398 desc = "Invalid Function";
6401 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
6405 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
6406 desc = "Invalid SGL";
6409 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
6410 desc = "Internal Error";
6413 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
6417 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
6418 desc = "Insufficient Resources";
6421 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
6422 desc = "Invalid Field";
6425 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
6426 desc = "Invalid State";
6429 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
6430 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
6431 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
6432 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
6433 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
6434 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
6435 /* No message for Config IOCStatus values */
6438 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
6439 /* No message for recovered error
6440 desc = "SCSI Recovered Error";
6444 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
6445 desc = "SCSI Invalid Bus";
6448 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
6449 desc = "SCSI Invalid TargetID";
6452 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
6454 SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
6455 U8 cdb = pScsiReq->CDB[0];
6456 if (cdb != 0x12) { /* Inquiry is issued for device scanning */
6457 desc = "SCSI Device Not There";
6462 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
6463 desc = "SCSI Data Overrun";
6466 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
6467 /* This error is checked in scsi_io_done(). Skip.
6468 desc = "SCSI Data Underrun";
6472 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
6473 desc = "SCSI I/O Data Error";
6476 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
6477 desc = "SCSI Protocol Error";
6480 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
6481 desc = "SCSI Task Terminated";
6484 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
6485 desc = "SCSI Residual Mismatch";
6488 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
6489 desc = "SCSI Task Management Failed";
6492 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
6493 desc = "SCSI IOC Terminated";
6496 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
6497 desc = "SCSI Ext Terminated";
6505 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04x): %s\n", ioc->name, status, desc);
6508 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6509 EXPORT_SYMBOL(mpt_attach);
6510 EXPORT_SYMBOL(mpt_detach);
6512 EXPORT_SYMBOL(mpt_resume);
6513 EXPORT_SYMBOL(mpt_suspend);
6515 EXPORT_SYMBOL(ioc_list);
6516 EXPORT_SYMBOL(mpt_proc_root_dir);
6517 EXPORT_SYMBOL(mpt_register);
6518 EXPORT_SYMBOL(mpt_deregister);
6519 EXPORT_SYMBOL(mpt_event_register);
6520 EXPORT_SYMBOL(mpt_event_deregister);
6521 EXPORT_SYMBOL(mpt_reset_register);
6522 EXPORT_SYMBOL(mpt_reset_deregister);
6523 EXPORT_SYMBOL(mpt_device_driver_register);
6524 EXPORT_SYMBOL(mpt_device_driver_deregister);
6525 EXPORT_SYMBOL(mpt_get_msg_frame);
6526 EXPORT_SYMBOL(mpt_put_msg_frame);
6527 EXPORT_SYMBOL(mpt_free_msg_frame);
6528 EXPORT_SYMBOL(mpt_add_sge);
6529 EXPORT_SYMBOL(mpt_send_handshake_request);
6530 EXPORT_SYMBOL(mpt_verify_adapter);
6531 EXPORT_SYMBOL(mpt_GetIocState);
6532 EXPORT_SYMBOL(mpt_print_ioc_summary);
6533 EXPORT_SYMBOL(mpt_lan_index);
6534 EXPORT_SYMBOL(mpt_stm_index);
6535 EXPORT_SYMBOL(mpt_HardResetHandler);
6536 EXPORT_SYMBOL(mpt_config);
6537 EXPORT_SYMBOL(mpt_toolbox);
6538 EXPORT_SYMBOL(mpt_findImVolumes);
6539 EXPORT_SYMBOL(mpt_read_ioc_pg_3);
6540 EXPORT_SYMBOL(mpt_alloc_fw_memory);
6541 EXPORT_SYMBOL(mpt_free_fw_memory);
6542 EXPORT_SYMBOL(mptbase_sas_persist_operation);
6543 EXPORT_SYMBOL(mpt_alt_ioc_wait);
6544 EXPORT_SYMBOL(mptbase_GetFcPortPage0);
6547 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6549 * fusion_init - Fusion MPT base driver initialization routine.
6551 * Returns 0 for success, non-zero for failure.
6558 show_mptmod_ver(my_NAME, my_VERSION);
6559 printk(KERN_INFO COPYRIGHT "\n");
6561 for (i = 0; i < MPT_MAX_PROTOCOL_DRIVERS; i++) {
6562 MptCallbacks[i] = NULL;
6563 MptDriverClass[i] = MPTUNKNOWN_DRIVER;
6564 MptEvHandlers[i] = NULL;
6565 MptResetHandlers[i] = NULL;
6568 /* Register ourselves (mptbase) in order to facilitate
6569 * EventNotification handling.
6571 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
6573 /* Register for hard reset handling callbacks.
6575 if (mpt_reset_register(mpt_base_index, mpt_ioc_reset) == 0) {
6576 dprintk((KERN_INFO MYNAM ": Register for IOC reset notification\n"));
6581 #ifdef CONFIG_PROC_FS
6582 (void) procmpt_create();
6587 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6589 * fusion_exit - Perform driver unload cleanup.
6591 * This routine frees all resources associated with each MPT adapter
6592 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
6598 dexitprintk((KERN_INFO MYNAM ": fusion_exit() called!\n"));
6600 mpt_reset_deregister(mpt_base_index);
6602 #ifdef CONFIG_PROC_FS
6607 module_init(fusion_init);
6608 module_exit(fusion_exit);