2 * linux/drivers/message/fusion/mptbase.c
3 * This is the Fusion MPT base driver which supports multiple
4 * (SCSI + LAN) specialized protocol drivers.
5 * For use with LSI Logic PCI chip/adapter(s)
6 * running LSI Logic Fusion MPT (Message Passing Technology) firmware.
8 * Copyright (c) 1999-2007 LSI Logic Corporation
9 * (mailto: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/kernel.h>
50 #include <linux/module.h>
51 #include <linux/errno.h>
52 #include <linux/init.h>
53 #include <linux/slab.h>
54 #include <linux/types.h>
55 #include <linux/pci.h>
56 #include <linux/kdev_t.h>
57 #include <linux/blkdev.h>
58 #include <linux/delay.h>
59 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
60 #include <linux/dma-mapping.h>
68 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
69 #define my_NAME "Fusion MPT base driver"
70 #define my_VERSION MPT_LINUX_VERSION_COMMON
71 #define MYNAM "mptbase"
73 MODULE_AUTHOR(MODULEAUTHOR);
74 MODULE_DESCRIPTION(my_NAME);
75 MODULE_LICENSE("GPL");
76 MODULE_VERSION(my_VERSION);
81 static int mpt_msi_enable;
82 module_param(mpt_msi_enable, int, 0);
83 MODULE_PARM_DESC(mpt_msi_enable, " MSI Support Enable (default=0)");
86 static int mfcounter = 0;
87 #define PRINT_MF_COUNT 20000
90 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
94 int mpt_lan_index = -1;
95 int mpt_stm_index = -1;
97 struct proc_dir_entry *mpt_proc_root_dir;
99 #define WHOINIT_UNKNOWN 0xAA
101 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
105 /* Adapter link list */
107 /* Callback lookup table */
108 static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
109 /* Protocol driver class lookup table */
110 static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
111 /* Event handler lookup table */
112 static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
113 /* Reset handler lookup table */
114 static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
115 static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
117 static int mpt_base_index = -1;
118 static int last_drv_idx = -1;
120 static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq);
122 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
126 static irqreturn_t mpt_interrupt(int irq, void *bus_id);
127 static int mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
128 static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
129 u32 *req, int replyBytes, u16 *u16reply, int maxwait,
131 static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
132 static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
133 static void mpt_adapter_disable(MPT_ADAPTER *ioc);
134 static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
136 static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
137 static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
138 static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
139 static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
140 static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
141 static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
142 static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
143 static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
144 static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
145 static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
146 static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
147 static int PrimeIocFifos(MPT_ADAPTER *ioc);
148 static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
149 static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
150 static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
151 static int GetLanConfigPages(MPT_ADAPTER *ioc);
152 static int GetIoUnitPage2(MPT_ADAPTER *ioc);
153 int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
154 static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
155 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
156 static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
157 static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
158 static void mpt_timer_expired(unsigned long data);
159 static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
160 static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
161 static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
162 static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
164 #ifdef CONFIG_PROC_FS
165 static int procmpt_summary_read(char *buf, char **start, off_t offset,
166 int request, int *eof, void *data);
167 static int procmpt_version_read(char *buf, char **start, off_t offset,
168 int request, int *eof, void *data);
169 static int procmpt_iocinfo_read(char *buf, char **start, off_t offset,
170 int request, int *eof, void *data);
172 static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
174 //int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
175 static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers);
176 static void mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
177 static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
178 static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
179 static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
180 static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
182 /* module entry point */
183 static int __init fusion_init (void);
184 static void __exit fusion_exit (void);
186 #define CHIPREG_READ32(addr) readl_relaxed(addr)
187 #define CHIPREG_READ32_dmasync(addr) readl(addr)
188 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
189 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
190 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
193 pci_disable_io_access(struct pci_dev *pdev)
197 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
199 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
203 pci_enable_io_access(struct pci_dev *pdev)
207 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
209 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
213 * Process turbo (context) reply...
216 mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
218 MPT_FRAME_HDR *mf = NULL;
219 MPT_FRAME_HDR *mr = NULL;
223 dmfprintk((MYIOC_s_INFO_FMT "Got TURBO reply req_idx=%08x\n",
226 switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
227 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
228 req_idx = pa & 0x0000FFFF;
229 cb_idx = (pa & 0x00FF0000) >> 16;
230 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
232 case MPI_CONTEXT_REPLY_TYPE_LAN:
233 cb_idx = mpt_lan_index;
235 * Blind set of mf to NULL here was fatal
236 * after lan_reply says "freeme"
237 * Fix sort of combined with an optimization here;
238 * added explicit check for case where lan_reply
239 * was just returning 1 and doing nothing else.
240 * For this case skip the callback, but set up
241 * proper mf value first here:-)
243 if ((pa & 0x58000000) == 0x58000000) {
244 req_idx = pa & 0x0000FFFF;
245 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
246 mpt_free_msg_frame(ioc, mf);
251 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
253 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
254 cb_idx = mpt_stm_index;
255 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
262 /* Check for (valid) IO callback! */
263 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
264 MptCallbacks[cb_idx] == NULL) {
265 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
266 __FUNCTION__, ioc->name, cb_idx);
270 if (MptCallbacks[cb_idx](ioc, mf, mr))
271 mpt_free_msg_frame(ioc, mf);
277 mpt_reply(MPT_ADAPTER *ioc, u32 pa)
288 /* non-TURBO reply! Hmmm, something may be up...
289 * Newest turbo reply mechanism; get address
290 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
293 /* Map DMA address of reply header to cpu address.
294 * pa is 32 bits - but the dma address may be 32 or 64 bits
295 * get offset based only only the low addresses
298 reply_dma_low = (pa <<= 1);
299 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
300 (reply_dma_low - ioc->reply_frames_low_dma));
302 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
303 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
304 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
306 dmfprintk((MYIOC_s_INFO_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
307 ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
308 DBG_DUMP_REPLY_FRAME(mr)
310 /* Check/log IOC log info
312 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
313 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
314 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
315 if (ioc->bus_type == FC)
316 mpt_fc_log_info(ioc, log_info);
317 else if (ioc->bus_type == SPI)
318 mpt_spi_log_info(ioc, log_info);
319 else if (ioc->bus_type == SAS)
320 mpt_sas_log_info(ioc, log_info);
322 if (ioc_stat & MPI_IOCSTATUS_MASK) {
323 if (ioc->bus_type == SPI &&
324 cb_idx != mpt_stm_index &&
325 cb_idx != mpt_lan_index)
326 mpt_sp_ioc_info(ioc, (u32)ioc_stat, mf);
330 /* Check for (valid) IO callback! */
331 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
332 MptCallbacks[cb_idx] == NULL) {
333 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
334 __FUNCTION__, ioc->name, cb_idx);
339 freeme = MptCallbacks[cb_idx](ioc, mf, mr);
342 /* Flush (non-TURBO) reply with a WRITE! */
343 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
346 mpt_free_msg_frame(ioc, mf);
350 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
352 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
353 * @irq: irq number (not used)
354 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
356 * This routine is registered via the request_irq() kernel API call,
357 * and handles all interrupts generated from a specific MPT adapter
358 * (also referred to as a IO Controller or IOC).
359 * This routine must clear the interrupt from the adapter and does
360 * so by reading the reply FIFO. Multiple replies may be processed
361 * per single call to this routine.
363 * This routine handles register-level access of the adapter but
364 * dispatches (calls) a protocol-specific callback routine to handle
365 * the protocol-specific details of the MPT request completion.
368 mpt_interrupt(int irq, void *bus_id)
370 MPT_ADAPTER *ioc = bus_id;
371 u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
373 if (pa == 0xFFFFFFFF)
377 * Drain the reply FIFO!
380 if (pa & MPI_ADDRESS_REPLY_A_BIT)
383 mpt_turbo_reply(ioc, pa);
384 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
385 } while (pa != 0xFFFFFFFF);
390 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
392 * mpt_base_reply - MPT base driver's callback routine
393 * @ioc: Pointer to MPT_ADAPTER structure
394 * @mf: Pointer to original MPT request frame
395 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
397 * MPT base driver's callback routine; all base driver
398 * "internal" request/reply processing is routed here.
399 * Currently used for EventNotification and EventAck handling.
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 devtverboseprintk((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) {
442 devtverboseprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
443 ioc->name, pEvReply));
446 #ifdef CONFIG_PROC_FS
447 // LogEvent(ioc, pEvReply);
450 } else if (func == MPI_FUNCTION_EVENT_ACK) {
451 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n",
453 } else if (func == MPI_FUNCTION_CONFIG) {
457 dcprintk((MYIOC_s_INFO_FMT "config_complete (mf=%p,mr=%p)\n",
458 ioc->name, mf, reply));
460 pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *)));
463 /* disable timer and remove from linked list */
464 del_timer(&pCfg->timer);
466 spin_lock_irqsave(&ioc->FreeQlock, flags);
467 list_del(&pCfg->linkage);
468 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
471 * If IOC Status is SUCCESS, save the header
472 * and set the status code to GOOD.
474 pCfg->status = MPT_CONFIG_ERROR;
476 ConfigReply_t *pReply = (ConfigReply_t *)reply;
479 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
480 dcprintk((KERN_NOTICE " IOCStatus=%04xh, IOCLogInfo=%08xh\n",
481 status, le32_to_cpu(pReply->IOCLogInfo)));
483 pCfg->status = status;
484 if (status == MPI_IOCSTATUS_SUCCESS) {
485 if ((pReply->Header.PageType &
486 MPI_CONFIG_PAGETYPE_MASK) ==
487 MPI_CONFIG_PAGETYPE_EXTENDED) {
488 pCfg->cfghdr.ehdr->ExtPageLength =
489 le16_to_cpu(pReply->ExtPageLength);
490 pCfg->cfghdr.ehdr->ExtPageType =
493 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
495 /* If this is a regular header, save PageLength. */
496 /* LMP Do this better so not using a reserved field! */
497 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
498 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
499 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
504 * Wake up the original calling thread
509 } else if (func == MPI_FUNCTION_SAS_IO_UNIT_CONTROL) {
510 /* we should be always getting a reply frame */
511 memcpy(ioc->persist_reply_frame, reply,
512 min(MPT_DEFAULT_FRAME_SIZE,
513 4*reply->u.reply.MsgLength));
514 del_timer(&ioc->persist_timer);
515 ioc->persist_wait_done = 1;
518 printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
523 * Conditionally tell caller to free the original
524 * EventNotification/EventAck/unexpected request frame!
529 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
531 * mpt_register - Register protocol-specific main callback handler.
532 * @cbfunc: callback function pointer
533 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
535 * This routine is called by a protocol-specific driver (SCSI host,
536 * LAN, SCSI target) to register its reply callback routine. Each
537 * protocol-specific driver must do this before it will be able to
538 * use any IOC resources, such as obtaining request frames.
540 * NOTES: The SCSI protocol driver currently calls this routine thrice
541 * in order to register separate callbacks; one for "normal" SCSI IO;
542 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
544 * Returns a positive integer valued "handle" in the
545 * range (and S.O.D. order) {N,...,7,6,5,...,1} if successful.
546 * Any non-positive return value (including zero!) should be considered
547 * an error by the caller.
550 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
557 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
558 * (slot/handle 0 is reserved!)
560 for (i = MPT_MAX_PROTOCOL_DRIVERS-1; i; i--) {
561 if (MptCallbacks[i] == NULL) {
562 MptCallbacks[i] = cbfunc;
563 MptDriverClass[i] = dclass;
564 MptEvHandlers[i] = NULL;
573 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
575 * mpt_deregister - Deregister a protocol drivers resources.
576 * @cb_idx: previously registered callback handle
578 * Each protocol-specific driver should call this routine when its
579 * module is unloaded.
582 mpt_deregister(int cb_idx)
584 if ((cb_idx >= 0) && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
585 MptCallbacks[cb_idx] = NULL;
586 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
587 MptEvHandlers[cb_idx] = NULL;
593 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
595 * mpt_event_register - Register protocol-specific event callback
597 * @cb_idx: previously registered (via mpt_register) callback handle
598 * @ev_cbfunc: callback function
600 * This routine can be called by one or more protocol-specific drivers
601 * if/when they choose to be notified of MPT events.
603 * Returns 0 for success.
606 mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc)
608 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
611 MptEvHandlers[cb_idx] = ev_cbfunc;
615 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
617 * mpt_event_deregister - Deregister protocol-specific event callback
619 * @cb_idx: previously registered callback handle
621 * Each protocol-specific driver should call this routine
622 * when it does not (or can no longer) handle events,
623 * or when its module is unloaded.
626 mpt_event_deregister(int cb_idx)
628 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
631 MptEvHandlers[cb_idx] = NULL;
634 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
636 * mpt_reset_register - Register protocol-specific IOC reset handler.
637 * @cb_idx: previously registered (via mpt_register) callback handle
638 * @reset_func: reset function
640 * This routine can be called by one or more protocol-specific drivers
641 * if/when they choose to be notified of IOC resets.
643 * Returns 0 for success.
646 mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func)
648 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
651 MptResetHandlers[cb_idx] = reset_func;
655 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
657 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
658 * @cb_idx: previously registered callback handle
660 * Each protocol-specific driver should call this routine
661 * when it does not (or can no longer) handle IOC reset handling,
662 * or when its module is unloaded.
665 mpt_reset_deregister(int cb_idx)
667 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
670 MptResetHandlers[cb_idx] = NULL;
673 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
675 * mpt_device_driver_register - Register device driver hooks
676 * @dd_cbfunc: driver callbacks struct
677 * @cb_idx: MPT protocol driver index
680 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx)
683 const struct pci_device_id *id;
685 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
688 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
690 /* call per pci device probe entry point */
691 list_for_each_entry(ioc, &ioc_list, list) {
692 id = ioc->pcidev->driver ?
693 ioc->pcidev->driver->id_table : NULL;
694 if (dd_cbfunc->probe)
695 dd_cbfunc->probe(ioc->pcidev, id);
701 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
703 * mpt_device_driver_deregister - DeRegister device driver hooks
704 * @cb_idx: MPT protocol driver index
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 handshake method.
897 * @handle: Handle of registered MPT protocol driver
898 * @ioc: Pointer to MPT adapter structure
899 * @reqBytes: Size of the request in bytes
900 * @req: Pointer to MPT request frame
901 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
903 * This routine is used exclusively to send MptScsiTaskMgmt
904 * requests since they are required to be sent via doorbell handshake.
906 * NOTE: It is the callers responsibility to byte-swap fields in the
907 * request which are greater than 1 byte in size.
909 * Returns 0 for success, non-zero for failure.
912 mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
918 /* State is known to be good upon entering
919 * this function so issue the bus reset
924 * Emulate what mpt_put_msg_frame() does /wrt to sanity
925 * setting cb_idx/req_idx. But ONLY if this request
926 * is in proper (pre-alloc'd) request buffer range...
928 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
929 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
930 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
931 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
932 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;
935 /* Make sure there are no doorbells */
936 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
938 CHIPREG_WRITE32(&ioc->chip->Doorbell,
939 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
940 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
942 /* Wait for IOC doorbell int */
943 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
947 /* Read doorbell and check for active bit */
948 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
951 dhsprintk((KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
954 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
956 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
960 /* Send request via doorbell handshake */
961 req_as_bytes = (u8 *) req;
962 for (ii = 0; ii < reqBytes/4; ii++) {
965 word = ((req_as_bytes[(ii*4) + 0] << 0) |
966 (req_as_bytes[(ii*4) + 1] << 8) |
967 (req_as_bytes[(ii*4) + 2] << 16) |
968 (req_as_bytes[(ii*4) + 3] << 24));
969 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
970 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
976 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
981 /* Make sure there are no doorbells */
982 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
987 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
989 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
990 * @ioc: Pointer to MPT adapter structure
991 * @access_control_value: define bits below
992 * @sleepFlag: Specifies whether the process can sleep
994 * Provides mechanism for the host driver to control the IOC's
995 * Host Page Buffer access.
997 * Access Control Value - bits[15:12]
999 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1000 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1001 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1003 * Returns 0 for success, non-zero for failure.
1007 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1011 /* return if in use */
1012 if (CHIPREG_READ32(&ioc->chip->Doorbell)
1013 & MPI_DOORBELL_ACTIVE)
1016 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1018 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1019 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1020 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1021 (access_control_value<<12)));
1023 /* Wait for IOC to clear Doorbell Status bit */
1024 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1030 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1032 * mpt_host_page_alloc - allocate system memory for the fw
1033 * @ioc: Pointer to pointer to IOC adapter
1034 * @ioc_init: Pointer to ioc init config page
1036 * If we already allocated memory in past, then resend the same pointer.
1037 * Returns 0 for success, non-zero for failure.
1040 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1044 u32 host_page_buffer_sz=0;
1046 if(!ioc->HostPageBuffer) {
1048 host_page_buffer_sz =
1049 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1051 if(!host_page_buffer_sz)
1052 return 0; /* fw doesn't need any host buffers */
1054 /* spin till we get enough memory */
1055 while(host_page_buffer_sz > 0) {
1057 if((ioc->HostPageBuffer = pci_alloc_consistent(
1059 host_page_buffer_sz,
1060 &ioc->HostPageBuffer_dma)) != NULL) {
1062 dinitprintk((MYIOC_s_INFO_FMT
1063 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1064 ioc->name, ioc->HostPageBuffer,
1065 (u32)ioc->HostPageBuffer_dma,
1066 host_page_buffer_sz));
1067 ioc->alloc_total += host_page_buffer_sz;
1068 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1072 host_page_buffer_sz -= (4*1024);
1076 if(!ioc->HostPageBuffer) {
1077 printk(MYIOC_s_ERR_FMT
1078 "Failed to alloc memory for host_page_buffer!\n",
1083 psge = (char *)&ioc_init->HostPageBufferSGE;
1084 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1085 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1086 MPI_SGE_FLAGS_32_BIT_ADDRESSING |
1087 MPI_SGE_FLAGS_HOST_TO_IOC |
1088 MPI_SGE_FLAGS_END_OF_BUFFER;
1089 if (sizeof(dma_addr_t) == sizeof(u64)) {
1090 flags_length |= MPI_SGE_FLAGS_64_BIT_ADDRESSING;
1092 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1093 flags_length |= ioc->HostPageBuffer_sz;
1094 mpt_add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1095 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1100 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1102 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1103 * @iocid: IOC unique identifier (integer)
1104 * @iocpp: Pointer to pointer to IOC adapter
1106 * Given a unique IOC identifier, set pointer to the associated MPT
1107 * adapter structure.
1109 * Returns iocid and sets iocpp if iocid is found.
1110 * Returns -1 if iocid is not found.
1113 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1117 list_for_each_entry(ioc,&ioc_list,list) {
1118 if (ioc->id == iocid) {
1128 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1130 * mpt_attach - Install a PCI intelligent MPT adapter.
1131 * @pdev: Pointer to pci_dev structure
1132 * @id: PCI device ID information
1134 * This routine performs all the steps necessary to bring the IOC of
1135 * a MPT adapter to a OPERATIONAL state. This includes registering
1136 * memory regions, registering the interrupt, and allocating request
1137 * and reply memory pools.
1139 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1142 * Returns 0 for success, non-zero for failure.
1144 * TODO: Add support for polled controllers
1147 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1151 unsigned long mem_phys;
1159 static int mpt_ids = 0;
1160 #ifdef CONFIG_PROC_FS
1161 struct proc_dir_entry *dent, *ent;
1164 if (pci_enable_device(pdev))
1167 dinitprintk((KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1169 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
1170 dprintk((KERN_INFO MYNAM
1171 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n"));
1172 } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
1173 printk(KERN_WARNING MYNAM ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");
1177 if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
1178 dprintk((KERN_INFO MYNAM
1179 ": Using 64 bit consistent mask\n"));
1181 dprintk((KERN_INFO MYNAM
1182 ": Not using 64 bit consistent mask\n"));
1184 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1186 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1189 ioc->alloc_total = sizeof(MPT_ADAPTER);
1190 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1191 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1194 ioc->diagPending = 0;
1195 spin_lock_init(&ioc->diagLock);
1196 spin_lock_init(&ioc->initializing_hba_lock);
1198 /* Initialize the event logging.
1200 ioc->eventTypes = 0; /* None */
1201 ioc->eventContext = 0;
1202 ioc->eventLogSize = 0;
1209 ioc->cached_fw = NULL;
1211 /* Initilize SCSI Config Data structure
1213 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1215 /* Initialize the running configQ head.
1217 INIT_LIST_HEAD(&ioc->configQ);
1219 /* Initialize the fc rport list head.
1221 INIT_LIST_HEAD(&ioc->fc_rports);
1223 /* Find lookup slot. */
1224 INIT_LIST_HEAD(&ioc->list);
1225 ioc->id = mpt_ids++;
1227 mem_phys = msize = 0;
1229 for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1230 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1233 /* Get I/O space! */
1234 port = pci_resource_start(pdev, ii);
1235 psize = pci_resource_len(pdev,ii);
1240 mem_phys = pci_resource_start(pdev, ii);
1241 msize = pci_resource_len(pdev,ii);
1244 ioc->mem_size = msize;
1247 /* Get logical ptr for PciMem0 space */
1248 /*mem = ioremap(mem_phys, msize);*/
1249 mem = ioremap(mem_phys, msize);
1251 printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n");
1256 dinitprintk((KERN_INFO MYNAM ": mem = %p, mem_phys = %lx\n", mem, mem_phys));
1258 dinitprintk((KERN_INFO MYNAM ": facts @ %p, pfacts[0] @ %p\n",
1259 &ioc->facts, &ioc->pfacts[0]));
1261 ioc->mem_phys = mem_phys;
1262 ioc->chip = (SYSIF_REGS __iomem *)mem;
1264 /* Save Port IO values in case we need to do downloadboot */
1266 u8 *pmem = (u8*)port;
1267 ioc->pio_mem_phys = port;
1268 ioc->pio_chip = (SYSIF_REGS __iomem *)pmem;
1271 if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC909) {
1272 ioc->prod_name = "LSIFC909";
1275 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929) {
1276 ioc->prod_name = "LSIFC929";
1279 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919) {
1280 ioc->prod_name = "LSIFC919";
1283 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929X) {
1284 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1286 if (revision < XL_929) {
1287 ioc->prod_name = "LSIFC929X";
1288 /* 929X Chip Fix. Set Split transactions level
1289 * for PCIX. Set MOST bits to zero.
1291 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1293 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1295 ioc->prod_name = "LSIFC929XL";
1296 /* 929XL Chip Fix. Set MMRBC to 0x08.
1298 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1300 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1303 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919X) {
1304 ioc->prod_name = "LSIFC919X";
1306 /* 919X Chip Fix. Set Split transactions level
1307 * for PCIX. Set MOST bits to zero.
1309 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1311 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1313 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC939X) {
1314 ioc->prod_name = "LSIFC939X";
1316 ioc->errata_flag_1064 = 1;
1318 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC949X) {
1319 ioc->prod_name = "LSIFC949X";
1321 ioc->errata_flag_1064 = 1;
1323 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC949E) {
1324 ioc->prod_name = "LSIFC949E";
1327 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {
1328 ioc->prod_name = "LSI53C1030";
1329 ioc->bus_type = SPI;
1330 /* 1030 Chip Fix. Disable Split transactions
1331 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1333 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1334 if (revision < C0_1030) {
1335 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1337 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1340 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_1030_53C1035) {
1341 ioc->prod_name = "LSI53C1035";
1342 ioc->bus_type = SPI;
1344 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064) {
1345 ioc->prod_name = "LSISAS1064";
1346 ioc->bus_type = SAS;
1347 ioc->errata_flag_1064 = 1;
1349 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068) {
1350 ioc->prod_name = "LSISAS1068";
1351 ioc->bus_type = SAS;
1352 ioc->errata_flag_1064 = 1;
1354 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064E) {
1355 ioc->prod_name = "LSISAS1064E";
1356 ioc->bus_type = SAS;
1358 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068E) {
1359 ioc->prod_name = "LSISAS1068E";
1360 ioc->bus_type = SAS;
1362 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
1363 ioc->prod_name = "LSISAS1078";
1364 ioc->bus_type = SAS;
1367 if (ioc->errata_flag_1064)
1368 pci_disable_io_access(pdev);
1370 sprintf(ioc->name, "ioc%d", ioc->id);
1372 spin_lock_init(&ioc->FreeQlock);
1375 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1377 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1379 /* Set lookup ptr. */
1380 list_add_tail(&ioc->list, &ioc_list);
1382 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1384 mpt_detect_bound_ports(ioc, pdev);
1386 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1388 printk(KERN_WARNING MYNAM
1389 ": WARNING - %s did not initialize properly! (%d)\n",
1392 list_del(&ioc->list);
1394 ioc->alt_ioc->alt_ioc = NULL;
1397 pci_set_drvdata(pdev, NULL);
1401 /* call per device driver probe entry point */
1402 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1403 if(MptDeviceDriverHandlers[ii] &&
1404 MptDeviceDriverHandlers[ii]->probe) {
1405 MptDeviceDriverHandlers[ii]->probe(pdev,id);
1409 #ifdef CONFIG_PROC_FS
1411 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1413 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1415 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1417 ent->read_proc = procmpt_iocinfo_read;
1420 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1422 ent->read_proc = procmpt_summary_read;
1431 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1433 * mpt_detach - Remove a PCI intelligent MPT adapter.
1434 * @pdev: Pointer to pci_dev structure
1438 mpt_detach(struct pci_dev *pdev)
1440 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1444 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
1445 remove_proc_entry(pname, NULL);
1446 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
1447 remove_proc_entry(pname, NULL);
1448 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
1449 remove_proc_entry(pname, NULL);
1451 /* call per device driver remove entry point */
1452 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1453 if(MptDeviceDriverHandlers[ii] &&
1454 MptDeviceDriverHandlers[ii]->remove) {
1455 MptDeviceDriverHandlers[ii]->remove(pdev);
1459 /* Disable interrupts! */
1460 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1463 synchronize_irq(pdev->irq);
1465 /* Clear any lingering interrupt */
1466 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1468 CHIPREG_READ32(&ioc->chip->IntStatus);
1470 mpt_adapter_dispose(ioc);
1472 pci_set_drvdata(pdev, NULL);
1475 /**************************************************************************
1479 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1481 * mpt_suspend - Fusion MPT base driver suspend routine.
1482 * @pdev: Pointer to pci_dev structure
1483 * @state: new state to enter
1486 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
1489 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1491 device_state=pci_choose_state(pdev, state);
1493 printk(MYIOC_s_INFO_FMT
1494 "pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
1495 ioc->name, pdev, pci_name(pdev), device_state);
1497 pci_save_state(pdev);
1499 /* put ioc into READY_STATE */
1500 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
1501 printk(MYIOC_s_ERR_FMT
1502 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
1505 /* disable interrupts */
1506 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1509 /* Clear any lingering interrupt */
1510 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1512 pci_disable_device(pdev);
1513 pci_set_power_state(pdev, device_state);
1518 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1520 * mpt_resume - Fusion MPT base driver resume routine.
1521 * @pdev: Pointer to pci_dev structure
1524 mpt_resume(struct pci_dev *pdev)
1526 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1527 u32 device_state = pdev->current_state;
1530 printk(MYIOC_s_INFO_FMT
1531 "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
1532 ioc->name, pdev, pci_name(pdev), device_state);
1534 pci_set_power_state(pdev, 0);
1535 pci_restore_state(pdev);
1536 pci_enable_device(pdev);
1538 /* enable interrupts */
1539 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
1542 printk(MYIOC_s_INFO_FMT
1543 "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1545 (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1546 CHIPREG_READ32(&ioc->chip->Doorbell));
1548 /* bring ioc to operational state */
1549 if ((recovery_state = mpt_do_ioc_recovery(ioc,
1550 MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {
1551 printk(MYIOC_s_INFO_FMT
1552 "pci-resume: Cannot recover, error:[%x]\n",
1553 ioc->name, recovery_state);
1555 printk(MYIOC_s_INFO_FMT
1556 "pci-resume: success\n", ioc->name);
1564 mpt_signal_reset(int index, MPT_ADAPTER *ioc, int reset_phase)
1566 if ((MptDriverClass[index] == MPTSPI_DRIVER &&
1567 ioc->bus_type != SPI) ||
1568 (MptDriverClass[index] == MPTFC_DRIVER &&
1569 ioc->bus_type != FC) ||
1570 (MptDriverClass[index] == MPTSAS_DRIVER &&
1571 ioc->bus_type != SAS))
1572 /* make sure we only call the relevant reset handler
1575 return (MptResetHandlers[index])(ioc, reset_phase);
1578 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1580 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1581 * @ioc: Pointer to MPT adapter structure
1582 * @reason: Event word / reason
1583 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1585 * This routine performs all the steps necessary to bring the IOC
1586 * to a OPERATIONAL state.
1588 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1593 * -1 if failed to get board READY
1594 * -2 if READY but IOCFacts Failed
1595 * -3 if READY but PrimeIOCFifos Failed
1596 * -4 if READY but IOCInit Failed
1599 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1601 int hard_reset_done = 0;
1602 int alt_ioc_ready = 0;
1608 int reset_alt_ioc_active = 0;
1609 int irq_allocated = 0;
1611 printk(KERN_INFO MYNAM ": Initiating %s %s\n",
1612 ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
1614 /* Disable reply interrupts (also blocks FreeQ) */
1615 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1619 if (ioc->alt_ioc->active)
1620 reset_alt_ioc_active = 1;
1622 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1623 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
1624 ioc->alt_ioc->active = 0;
1628 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
1631 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
1632 if (hard_reset_done == -4) {
1633 printk(KERN_WARNING MYNAM ": %s Owned by PEER..skipping!\n",
1636 if (reset_alt_ioc_active && ioc->alt_ioc) {
1637 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1638 dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1639 ioc->alt_ioc->name));
1640 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
1641 ioc->alt_ioc->active = 1;
1645 printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",
1651 /* hard_reset_done = 0 if a soft reset was performed
1652 * and 1 if a hard reset was performed.
1654 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
1655 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
1658 printk(KERN_WARNING MYNAM
1659 ": alt-%s: Not ready WARNING!\n",
1660 ioc->alt_ioc->name);
1663 for (ii=0; ii<5; ii++) {
1664 /* Get IOC facts! Allow 5 retries */
1665 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
1671 dinitprintk((MYIOC_s_INFO_FMT "Retry IocFacts failed rc=%x\n", ioc->name, rc));
1673 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1674 MptDisplayIocCapabilities(ioc);
1677 if (alt_ioc_ready) {
1678 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
1679 dinitprintk((MYIOC_s_INFO_FMT "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
1680 /* Retry - alt IOC was initialized once
1682 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
1685 dinitprintk((MYIOC_s_INFO_FMT "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
1687 reset_alt_ioc_active = 0;
1688 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1689 MptDisplayIocCapabilities(ioc->alt_ioc);
1694 * Device is reset now. It must have de-asserted the interrupt line
1695 * (if it was asserted) and it should be safe to register for the
1698 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1700 if (ioc->pcidev->irq) {
1701 if (mpt_msi_enable && !pci_enable_msi(ioc->pcidev))
1702 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
1704 rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
1705 IRQF_SHARED, ioc->name, ioc);
1707 printk(MYIOC_s_ERR_FMT "Unable to allocate "
1708 "interrupt %d!\n", ioc->name,
1711 pci_disable_msi(ioc->pcidev);
1715 ioc->pci_irq = ioc->pcidev->irq;
1716 pci_set_master(ioc->pcidev); /* ?? */
1717 pci_set_drvdata(ioc->pcidev, ioc);
1718 dprintk((KERN_INFO MYNAM ": %s installed at interrupt "
1719 "%d\n", ioc->name, ioc->pcidev->irq));
1723 /* Prime reply & request queues!
1724 * (mucho alloc's) Must be done prior to
1725 * init as upper addresses are needed for init.
1726 * If fails, continue with alt-ioc processing
1728 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
1731 /* May need to check/upload firmware & data here!
1732 * If fails, continue with alt-ioc processing
1734 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
1737 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
1738 printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
1739 ioc->alt_ioc->name, rc);
1741 reset_alt_ioc_active = 0;
1744 if (alt_ioc_ready) {
1745 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
1747 reset_alt_ioc_active = 0;
1748 printk(KERN_WARNING MYNAM
1749 ": alt-%s: (%d) init failure WARNING!\n",
1750 ioc->alt_ioc->name, rc);
1754 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
1755 if (ioc->upload_fw) {
1756 ddlprintk((MYIOC_s_INFO_FMT
1757 "firmware upload required!\n", ioc->name));
1759 /* Controller is not operational, cannot do upload
1762 rc = mpt_do_upload(ioc, sleepFlag);
1764 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
1766 * Maintain only one pointer to FW memory
1767 * so there will not be two attempt to
1768 * downloadboot onboard dual function
1769 * chips (mpt_adapter_disable,
1772 ddlprintk((MYIOC_s_INFO_FMT ": mpt_upload: alt_%s has cached_fw=%p \n",
1773 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
1774 ioc->alt_ioc->cached_fw = NULL;
1777 printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
1785 /* Enable! (reply interrupt) */
1786 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
1790 if (reset_alt_ioc_active && ioc->alt_ioc) {
1791 /* (re)Enable alt-IOC! (reply interrupt) */
1792 dinitprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1793 ioc->alt_ioc->name));
1794 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
1795 ioc->alt_ioc->active = 1;
1798 /* Enable MPT base driver management of EventNotification
1799 * and EventAck handling.
1801 if ((ret == 0) && (!ioc->facts.EventState))
1802 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
1804 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
1805 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
1807 /* Add additional "reason" check before call to GetLanConfigPages
1808 * (combined with GetIoUnitPage2 call). This prevents a somewhat
1809 * recursive scenario; GetLanConfigPages times out, timer expired
1810 * routine calls HardResetHandler, which calls into here again,
1811 * and we try GetLanConfigPages again...
1813 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1814 if (ioc->bus_type == SAS) {
1816 /* clear persistency table */
1817 if(ioc->facts.IOCExceptions &
1818 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
1819 ret = mptbase_sas_persist_operation(ioc,
1820 MPI_SAS_OP_CLEAR_NOT_PRESENT);
1827 mpt_findImVolumes(ioc);
1829 } else if (ioc->bus_type == FC) {
1830 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
1831 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
1833 * Pre-fetch the ports LAN MAC address!
1834 * (LANPage1_t stuff)
1836 (void) GetLanConfigPages(ioc);
1839 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
1840 dprintk((MYIOC_s_INFO_FMT "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
1841 ioc->name, a[5], a[4], a[3], a[2], a[1], a[0] ));
1846 /* Get NVRAM and adapter maximums from SPP 0 and 2
1848 mpt_GetScsiPortSettings(ioc, 0);
1850 /* Get version and length of SDP 1
1852 mpt_readScsiDevicePageHeaders(ioc, 0);
1856 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
1857 mpt_findImVolumes(ioc);
1859 /* Check, and possibly reset, the coalescing value
1861 mpt_read_ioc_pg_1(ioc);
1863 mpt_read_ioc_pg_4(ioc);
1866 GetIoUnitPage2(ioc);
1870 * Call each currently registered protocol IOC reset handler
1871 * with post-reset indication.
1872 * NOTE: If we're doing _IOC_BRINGUP, there can be no
1873 * MptResetHandlers[] registered yet.
1875 if (hard_reset_done) {
1877 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
1878 if ((ret == 0) && MptResetHandlers[ii]) {
1879 dprintk((MYIOC_s_INFO_FMT "Calling IOC post_reset handler #%d\n",
1881 rc += mpt_signal_reset(ii, ioc, MPT_IOC_POST_RESET);
1885 if (alt_ioc_ready && MptResetHandlers[ii]) {
1886 drsprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",
1887 ioc->name, ioc->alt_ioc->name, ii));
1888 rc += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_POST_RESET);
1892 /* FIXME? Examine results here? */
1896 if ((ret != 0) && irq_allocated) {
1897 free_irq(ioc->pci_irq, ioc);
1899 pci_disable_msi(ioc->pcidev);
1904 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1906 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
1907 * @ioc: Pointer to MPT adapter structure
1908 * @pdev: Pointer to (struct pci_dev) structure
1910 * Search for PCI bus/dev_function which matches
1911 * PCI bus/dev_function (+/-1) for newly discovered 929,
1912 * 929X, 1030 or 1035.
1914 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
1915 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
1918 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
1920 struct pci_dev *peer=NULL;
1921 unsigned int slot = PCI_SLOT(pdev->devfn);
1922 unsigned int func = PCI_FUNC(pdev->devfn);
1923 MPT_ADAPTER *ioc_srch;
1925 dprintk((MYIOC_s_INFO_FMT "PCI device %s devfn=%x/%x,"
1926 " searching for devfn match on %x or %x\n",
1927 ioc->name, pci_name(pdev), pdev->bus->number,
1928 pdev->devfn, func-1, func+1));
1930 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
1932 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
1937 list_for_each_entry(ioc_srch, &ioc_list, list) {
1938 struct pci_dev *_pcidev = ioc_srch->pcidev;
1939 if (_pcidev == peer) {
1940 /* Paranoia checks */
1941 if (ioc->alt_ioc != NULL) {
1942 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1943 ioc->name, ioc->alt_ioc->name);
1945 } else if (ioc_srch->alt_ioc != NULL) {
1946 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1947 ioc_srch->name, ioc_srch->alt_ioc->name);
1950 dprintk((KERN_INFO MYNAM ": FOUND! binding %s <==> %s\n",
1951 ioc->name, ioc_srch->name));
1952 ioc_srch->alt_ioc = ioc;
1953 ioc->alt_ioc = ioc_srch;
1959 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1961 * mpt_adapter_disable - Disable misbehaving MPT adapter.
1962 * @ioc: Pointer to MPT adapter structure
1965 mpt_adapter_disable(MPT_ADAPTER *ioc)
1970 if (ioc->cached_fw != NULL) {
1971 ddlprintk((KERN_INFO MYNAM ": mpt_adapter_disable: Pushing FW onto adapter\n"));
1972 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)ioc->cached_fw, NO_SLEEP)) < 0) {
1973 printk(KERN_WARNING MYNAM
1974 ": firmware downloadboot failure (%d)!\n", ret);
1978 /* Disable adapter interrupts! */
1979 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1981 /* Clear any lingering interrupt */
1982 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1984 if (ioc->alloc != NULL) {
1986 dexitprintk((KERN_INFO MYNAM ": %s.free @ %p, sz=%d bytes\n",
1987 ioc->name, ioc->alloc, ioc->alloc_sz));
1988 pci_free_consistent(ioc->pcidev, sz,
1989 ioc->alloc, ioc->alloc_dma);
1990 ioc->reply_frames = NULL;
1991 ioc->req_frames = NULL;
1993 ioc->alloc_total -= sz;
1996 if (ioc->sense_buf_pool != NULL) {
1997 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
1998 pci_free_consistent(ioc->pcidev, sz,
1999 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2000 ioc->sense_buf_pool = NULL;
2001 ioc->alloc_total -= sz;
2004 if (ioc->events != NULL){
2005 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2008 ioc->alloc_total -= sz;
2011 if (ioc->cached_fw != NULL) {
2012 sz = ioc->facts.FWImageSize;
2013 pci_free_consistent(ioc->pcidev, sz,
2014 ioc->cached_fw, ioc->cached_fw_dma);
2015 ioc->cached_fw = NULL;
2016 ioc->alloc_total -= sz;
2019 kfree(ioc->spi_data.nvram);
2020 kfree(ioc->raid_data.pIocPg3);
2021 ioc->spi_data.nvram = NULL;
2022 ioc->raid_data.pIocPg3 = NULL;
2024 if (ioc->spi_data.pIocPg4 != NULL) {
2025 sz = ioc->spi_data.IocPg4Sz;
2026 pci_free_consistent(ioc->pcidev, sz,
2027 ioc->spi_data.pIocPg4,
2028 ioc->spi_data.IocPg4_dma);
2029 ioc->spi_data.pIocPg4 = NULL;
2030 ioc->alloc_total -= sz;
2033 if (ioc->ReqToChain != NULL) {
2034 kfree(ioc->ReqToChain);
2035 kfree(ioc->RequestNB);
2036 ioc->ReqToChain = NULL;
2039 kfree(ioc->ChainToChain);
2040 ioc->ChainToChain = NULL;
2042 if (ioc->HostPageBuffer != NULL) {
2043 if((ret = mpt_host_page_access_control(ioc,
2044 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2045 printk(KERN_ERR MYNAM
2046 ": %s: host page buffers free failed (%d)!\n",
2049 dexitprintk((KERN_INFO MYNAM ": %s HostPageBuffer free @ %p, sz=%d bytes\n",
2050 ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
2051 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2052 ioc->HostPageBuffer,
2053 ioc->HostPageBuffer_dma);
2054 ioc->HostPageBuffer = NULL;
2055 ioc->HostPageBuffer_sz = 0;
2056 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2060 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2062 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2063 * @ioc: Pointer to MPT adapter structure
2065 * This routine unregisters h/w resources and frees all alloc'd memory
2066 * associated with a MPT adapter structure.
2069 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2071 int sz_first, sz_last;
2076 sz_first = ioc->alloc_total;
2078 mpt_adapter_disable(ioc);
2080 if (ioc->pci_irq != -1) {
2081 free_irq(ioc->pci_irq, ioc);
2083 pci_disable_msi(ioc->pcidev);
2087 if (ioc->memmap != NULL) {
2088 iounmap(ioc->memmap);
2092 #if defined(CONFIG_MTRR) && 0
2093 if (ioc->mtrr_reg > 0) {
2094 mtrr_del(ioc->mtrr_reg, 0, 0);
2095 dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name));
2099 /* Zap the adapter lookup ptr! */
2100 list_del(&ioc->list);
2102 sz_last = ioc->alloc_total;
2103 dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
2104 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2107 ioc->alt_ioc->alt_ioc = NULL;
2112 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2114 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2115 * @ioc: Pointer to MPT adapter structure
2118 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2122 printk(KERN_INFO "%s: ", ioc->name);
2123 if (ioc->prod_name && strlen(ioc->prod_name) > 3)
2124 printk("%s: ", ioc->prod_name+3);
2125 printk("Capabilities={");
2127 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2128 printk("Initiator");
2132 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2133 printk("%sTarget", i ? "," : "");
2137 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2138 printk("%sLAN", i ? "," : "");
2144 * This would probably evoke more questions than it's worth
2146 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2147 printk("%sLogBusAddr", i ? "," : "");
2155 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2157 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2158 * @ioc: Pointer to MPT_ADAPTER structure
2159 * @force: Force hard KickStart of IOC
2160 * @sleepFlag: Specifies whether the process can sleep
2163 * 1 - DIAG reset and READY
2164 * 0 - READY initially OR soft reset and READY
2165 * -1 - Any failure on KickStart
2166 * -2 - Msg Unit Reset Failed
2167 * -3 - IO Unit Reset Failed
2168 * -4 - IOC owned by a PEER
2171 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2176 int hard_reset_done = 0;
2181 /* Get current [raw] IOC state */
2182 ioc_state = mpt_GetIocState(ioc, 0);
2183 dhsprintk((KERN_INFO MYNAM "::MakeIocReady, %s [raw] state=%08x\n", ioc->name, ioc_state));
2186 * Check to see if IOC got left/stuck in doorbell handshake
2187 * grip of death. If so, hard reset the IOC.
2189 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2191 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2195 /* Is it already READY? */
2196 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
2200 * Check to see if IOC is in FAULT state.
2202 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2204 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2206 printk(KERN_WARNING " FAULT code = %04xh\n",
2207 ioc_state & MPI_DOORBELL_DATA_MASK);
2211 * Hmmm... Did it get left operational?
2213 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2214 dinitprintk((MYIOC_s_INFO_FMT "IOC operational unexpected\n",
2218 * If PCI Peer, exit.
2219 * Else, if no fault conditions are present, issue a MessageUnitReset
2220 * Else, fall through to KickStart case
2222 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2223 dinitprintk((KERN_INFO MYNAM
2224 ": whoinit 0x%x statefault %d force %d\n",
2225 whoinit, statefault, force));
2226 if (whoinit == MPI_WHOINIT_PCI_PEER)
2229 if ((statefault == 0 ) && (force == 0)) {
2230 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2237 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2238 if (hard_reset_done < 0)
2242 * Loop here waiting for IOC to come READY.
2245 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2247 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2248 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2250 * BIOS or previous driver load left IOC in OP state.
2251 * Reset messaging FIFOs.
2253 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2254 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2257 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2259 * Something is wrong. Try to get IOC back
2262 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2263 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2270 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2271 ioc->name, (int)((ii+5)/HZ));
2275 if (sleepFlag == CAN_SLEEP) {
2278 mdelay (1); /* 1 msec delay */
2283 if (statefault < 3) {
2284 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2286 statefault==1 ? "stuck handshake" : "IOC FAULT");
2289 return hard_reset_done;
2292 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2294 * mpt_GetIocState - Get the current state of a MPT adapter.
2295 * @ioc: Pointer to MPT_ADAPTER structure
2296 * @cooked: Request raw or cooked IOC state
2298 * Returns all IOC Doorbell register bits if cooked==0, else just the
2299 * Doorbell bits in MPI_IOC_STATE_MASK.
2302 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2307 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2308 // dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
2309 sc = s & MPI_IOC_STATE_MASK;
2312 ioc->last_state = sc;
2314 return cooked ? sc : s;
2317 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2319 * GetIocFacts - Send IOCFacts request to MPT adapter.
2320 * @ioc: Pointer to MPT_ADAPTER structure
2321 * @sleepFlag: Specifies whether the process can sleep
2322 * @reason: If recovery, only update facts.
2324 * Returns 0 for success, non-zero for failure.
2327 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2329 IOCFacts_t get_facts;
2330 IOCFactsReply_t *facts;
2338 /* IOC *must* NOT be in RESET state! */
2339 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2340 printk(KERN_ERR MYNAM ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
2346 facts = &ioc->facts;
2348 /* Destination (reply area)... */
2349 reply_sz = sizeof(*facts);
2350 memset(facts, 0, reply_sz);
2352 /* Request area (get_facts on the stack right now!) */
2353 req_sz = sizeof(get_facts);
2354 memset(&get_facts, 0, req_sz);
2356 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2357 /* Assert: All other get_facts fields are zero! */
2359 dinitprintk((MYIOC_s_INFO_FMT
2360 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2361 ioc->name, req_sz, reply_sz));
2363 /* No non-zero fields in the get_facts request are greater than
2364 * 1 byte in size, so we can just fire it off as is.
2366 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2367 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2372 * Now byte swap (GRRR) the necessary fields before any further
2373 * inspection of reply contents.
2375 * But need to do some sanity checks on MsgLength (byte) field
2376 * to make sure we don't zero IOC's req_sz!
2378 /* Did we get a valid reply? */
2379 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2380 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2382 * If not been here, done that, save off first WhoInit value
2384 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2385 ioc->FirstWhoInit = facts->WhoInit;
2388 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2389 facts->MsgContext = le32_to_cpu(facts->MsgContext);
2390 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2391 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2392 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2393 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
2394 /* CHECKME! IOCStatus, IOCLogInfo */
2396 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2397 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2400 * FC f/w version changed between 1.1 and 1.2
2401 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2402 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2404 if (facts->MsgVersion < 0x0102) {
2406 * Handle old FC f/w style, convert to new...
2408 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2409 facts->FWVersion.Word =
2410 ((oldv<<12) & 0xFF000000) |
2411 ((oldv<<8) & 0x000FFF00);
2413 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2415 facts->ProductID = le16_to_cpu(facts->ProductID);
2416 facts->CurrentHostMfaHighAddr =
2417 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2418 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2419 facts->CurrentSenseBufferHighAddr =
2420 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2421 facts->CurReplyFrameSize =
2422 le16_to_cpu(facts->CurReplyFrameSize);
2423 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
2426 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2427 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2428 * to 14 in MPI-1.01.0x.
2430 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2431 facts->MsgVersion > 0x0100) {
2432 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2435 sz = facts->FWImageSize;
2440 facts->FWImageSize = sz;
2442 if (!facts->RequestFrameSize) {
2443 /* Something is wrong! */
2444 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2449 r = sz = facts->BlockSize;
2450 vv = ((63 / (sz * 4)) + 1) & 0x03;
2451 ioc->NB_for_64_byte_frame = vv;
2457 ioc->NBShiftFactor = shiftFactor;
2458 dinitprintk((MYIOC_s_INFO_FMT "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2459 ioc->name, vv, shiftFactor, r));
2461 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2463 * Set values for this IOC's request & reply frame sizes,
2464 * and request & reply queue depths...
2466 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2467 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2468 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2469 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2471 dinitprintk((MYIOC_s_INFO_FMT "reply_sz=%3d, reply_depth=%4d\n",
2472 ioc->name, ioc->reply_sz, ioc->reply_depth));
2473 dinitprintk((MYIOC_s_INFO_FMT "req_sz =%3d, req_depth =%4d\n",
2474 ioc->name, ioc->req_sz, ioc->req_depth));
2476 /* Get port facts! */
2477 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2481 printk(MYIOC_s_ERR_FMT
2482 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2483 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2484 RequestFrameSize)/sizeof(u32)));
2491 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2493 * GetPortFacts - Send PortFacts request to MPT adapter.
2494 * @ioc: Pointer to MPT_ADAPTER structure
2495 * @portnum: Port number
2496 * @sleepFlag: Specifies whether the process can sleep
2498 * Returns 0 for success, non-zero for failure.
2501 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2503 PortFacts_t get_pfacts;
2504 PortFactsReply_t *pfacts;
2509 /* IOC *must* NOT be in RESET state! */
2510 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2511 printk(KERN_ERR MYNAM ": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n",
2517 pfacts = &ioc->pfacts[portnum];
2519 /* Destination (reply area)... */
2520 reply_sz = sizeof(*pfacts);
2521 memset(pfacts, 0, reply_sz);
2523 /* Request area (get_pfacts on the stack right now!) */
2524 req_sz = sizeof(get_pfacts);
2525 memset(&get_pfacts, 0, req_sz);
2527 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2528 get_pfacts.PortNumber = portnum;
2529 /* Assert: All other get_pfacts fields are zero! */
2531 dinitprintk((MYIOC_s_INFO_FMT "Sending get PortFacts(%d) request\n",
2532 ioc->name, portnum));
2534 /* No non-zero fields in the get_pfacts request are greater than
2535 * 1 byte in size, so we can just fire it off as is.
2537 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2538 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2542 /* Did we get a valid reply? */
2544 /* Now byte swap the necessary fields in the response. */
2545 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2546 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2547 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2548 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2549 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2550 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2551 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2552 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2553 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2558 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2560 * SendIocInit - Send IOCInit request to MPT adapter.
2561 * @ioc: Pointer to MPT_ADAPTER structure
2562 * @sleepFlag: Specifies whether the process can sleep
2564 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2566 * Returns 0 for success, non-zero for failure.
2569 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2572 MPIDefaultReply_t init_reply;
2578 memset(&ioc_init, 0, sizeof(ioc_init));
2579 memset(&init_reply, 0, sizeof(init_reply));
2581 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2582 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2584 /* If we are in a recovery mode and we uploaded the FW image,
2585 * then this pointer is not NULL. Skip the upload a second time.
2586 * Set this flag if cached_fw set for either IOC.
2588 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
2592 ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n",
2593 ioc->name, ioc->upload_fw, ioc->facts.Flags));
2595 if(ioc->bus_type == SAS)
2596 ioc_init.MaxDevices = ioc->facts.MaxDevices;
2597 else if(ioc->bus_type == FC)
2598 ioc_init.MaxDevices = MPT_MAX_FC_DEVICES;
2600 ioc_init.MaxDevices = MPT_MAX_SCSI_DEVICES;
2601 ioc_init.MaxBuses = MPT_MAX_BUS;
2602 dinitprintk((MYIOC_s_INFO_FMT "facts.MsgVersion=%x\n",
2603 ioc->name, ioc->facts.MsgVersion));
2604 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
2605 // set MsgVersion and HeaderVersion host driver was built with
2606 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
2607 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
2609 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
2610 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
2611 } else if(mpt_host_page_alloc(ioc, &ioc_init))
2614 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
2616 if (sizeof(dma_addr_t) == sizeof(u64)) {
2617 /* Save the upper 32-bits of the request
2618 * (reply) and sense buffers.
2620 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
2621 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2623 /* Force 32-bit addressing */
2624 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
2625 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
2628 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
2629 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
2630 ioc->facts.MaxDevices = ioc_init.MaxDevices;
2631 ioc->facts.MaxBuses = ioc_init.MaxBuses;
2633 dhsprintk((MYIOC_s_INFO_FMT "Sending IOCInit (req @ %p)\n",
2634 ioc->name, &ioc_init));
2636 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
2637 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
2639 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
2643 /* No need to byte swap the multibyte fields in the reply
2644 * since we don't even look at its contents.
2647 dhsprintk((MYIOC_s_INFO_FMT "Sending PortEnable (req @ %p)\n",
2648 ioc->name, &ioc_init));
2650 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
2651 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
2655 /* YIKES! SUPER IMPORTANT!!!
2656 * Poll IocState until _OPERATIONAL while IOC is doing
2657 * LoopInit and TargetDiscovery!
2660 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
2661 state = mpt_GetIocState(ioc, 1);
2662 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
2663 if (sleepFlag == CAN_SLEEP) {
2670 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
2671 ioc->name, (int)((count+5)/HZ));
2675 state = mpt_GetIocState(ioc, 1);
2678 dinitprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
2681 ioc->aen_event_read_flag=0;
2685 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2687 * SendPortEnable - Send PortEnable request to MPT adapter port.
2688 * @ioc: Pointer to MPT_ADAPTER structure
2689 * @portnum: Port number to enable
2690 * @sleepFlag: Specifies whether the process can sleep
2692 * Send PortEnable to bring IOC to OPERATIONAL state.
2694 * Returns 0 for success, non-zero for failure.
2697 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2699 PortEnable_t port_enable;
2700 MPIDefaultReply_t reply_buf;
2705 /* Destination... */
2706 reply_sz = sizeof(MPIDefaultReply_t);
2707 memset(&reply_buf, 0, reply_sz);
2709 req_sz = sizeof(PortEnable_t);
2710 memset(&port_enable, 0, req_sz);
2712 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
2713 port_enable.PortNumber = portnum;
2714 /* port_enable.ChainOffset = 0; */
2715 /* port_enable.MsgFlags = 0; */
2716 /* port_enable.MsgContext = 0; */
2718 dinitprintk((MYIOC_s_INFO_FMT "Sending Port(%d)Enable (req @ %p)\n",
2719 ioc->name, portnum, &port_enable));
2721 /* RAID FW may take a long time to enable
2723 if (((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
2724 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI) ||
2725 (ioc->bus_type == SAS)) {
2726 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
2727 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
2728 300 /*seconds*/, sleepFlag);
2730 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
2731 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
2732 30 /*seconds*/, sleepFlag);
2738 * mpt_alloc_fw_memory - allocate firmware memory
2739 * @ioc: Pointer to MPT_ADAPTER structure
2740 * @size: total FW bytes
2742 * If memory has already been allocated, the same (cached) value
2746 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
2749 return; /* use already allocated memory */
2750 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2751 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
2752 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
2753 ioc->alloc_total += size;
2754 ioc->alt_ioc->alloc_total -= size;
2756 if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
2757 ioc->alloc_total += size;
2761 * mpt_free_fw_memory - free firmware memory
2762 * @ioc: Pointer to MPT_ADAPTER structure
2764 * If alt_img is NULL, delete from ioc structure.
2765 * Else, delete a secondary image in same format.
2768 mpt_free_fw_memory(MPT_ADAPTER *ioc)
2772 sz = ioc->facts.FWImageSize;
2773 dinitprintk((KERN_INFO MYNAM "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
2774 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2775 pci_free_consistent(ioc->pcidev, sz,
2776 ioc->cached_fw, ioc->cached_fw_dma);
2777 ioc->cached_fw = NULL;
2783 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2785 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
2786 * @ioc: Pointer to MPT_ADAPTER structure
2787 * @sleepFlag: Specifies whether the process can sleep
2789 * Returns 0 for success, >0 for handshake failure
2790 * <0 for fw upload failure.
2792 * Remark: If bound IOC and a successful FWUpload was performed
2793 * on the bound IOC, the second image is discarded
2794 * and memory is free'd. Both channels must upload to prevent
2795 * IOC from running in degraded mode.
2798 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
2800 u8 request[ioc->req_sz];
2801 u8 reply[sizeof(FWUploadReply_t)];
2802 FWUpload_t *prequest;
2803 FWUploadReply_t *preply;
2804 FWUploadTCSGE_t *ptcsge;
2807 int ii, sz, reply_sz;
2810 /* If the image size is 0, we are done.
2812 if ((sz = ioc->facts.FWImageSize) == 0)
2815 mpt_alloc_fw_memory(ioc, sz);
2817 dinitprintk((KERN_INFO MYNAM ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
2818 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2820 if (ioc->cached_fw == NULL) {
2826 prequest = (FWUpload_t *)&request;
2827 preply = (FWUploadReply_t *)&reply;
2829 /* Destination... */
2830 memset(prequest, 0, ioc->req_sz);
2832 reply_sz = sizeof(reply);
2833 memset(preply, 0, reply_sz);
2835 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
2836 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
2838 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
2839 ptcsge->DetailsLength = 12;
2840 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
2841 ptcsge->ImageSize = cpu_to_le32(sz);
2843 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
2845 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
2846 mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma);
2848 sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
2849 dinitprintk((KERN_INFO MYNAM ": Sending FW Upload (req @ %p) sgeoffset=%d \n",
2850 prequest, sgeoffset));
2851 DBG_DUMP_FW_REQUEST_FRAME(prequest)
2853 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
2854 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
2856 dinitprintk((KERN_INFO MYNAM ": FW Upload completed rc=%x \n", ii));
2858 cmdStatus = -EFAULT;
2860 /* Handshake transfer was complete and successful.
2861 * Check the Reply Frame.
2863 int status, transfer_sz;
2864 status = le16_to_cpu(preply->IOCStatus);
2865 if (status == MPI_IOCSTATUS_SUCCESS) {
2866 transfer_sz = le32_to_cpu(preply->ActualImageSize);
2867 if (transfer_sz == sz)
2871 dinitprintk((MYIOC_s_INFO_FMT ": do_upload cmdStatus=%d \n",
2872 ioc->name, cmdStatus));
2877 ddlprintk((MYIOC_s_INFO_FMT ": fw upload failed, freeing image \n",
2879 mpt_free_fw_memory(ioc);
2885 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2887 * mpt_downloadboot - DownloadBoot code
2888 * @ioc: Pointer to MPT_ADAPTER structure
2889 * @pFwHeader: Pointer to firmware header info
2890 * @sleepFlag: Specifies whether the process can sleep
2892 * FwDownloadBoot requires Programmed IO access.
2894 * Returns 0 for success
2895 * -1 FW Image size is 0
2896 * -2 No valid cached_fw Pointer
2897 * <0 for fw upload failure.
2900 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
2902 MpiExtImageHeader_t *pExtImage;
2912 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
2913 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
2915 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2916 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2917 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2918 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2919 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2920 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2922 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
2925 if (sleepFlag == CAN_SLEEP) {
2931 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2932 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
2934 for (count = 0; count < 30; count ++) {
2935 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2936 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
2937 ddlprintk((MYIOC_s_INFO_FMT "RESET_ADAPTER cleared, count=%d\n",
2942 if (sleepFlag == CAN_SLEEP) {
2949 if ( count == 30 ) {
2950 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! "
2951 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
2952 ioc->name, diag0val));
2956 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2957 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2958 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2959 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2960 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2961 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2963 /* Set the DiagRwEn and Disable ARM bits */
2964 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
2966 fwSize = (pFwHeader->ImageSize + 3)/4;
2967 ptrFw = (u32 *) pFwHeader;
2969 /* Write the LoadStartAddress to the DiagRw Address Register
2970 * using Programmed IO
2972 if (ioc->errata_flag_1064)
2973 pci_enable_io_access(ioc->pcidev);
2975 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
2976 ddlprintk((MYIOC_s_INFO_FMT "LoadStart addr written 0x%x \n",
2977 ioc->name, pFwHeader->LoadStartAddress));
2979 ddlprintk((MYIOC_s_INFO_FMT "Write FW Image: 0x%x bytes @ %p\n",
2980 ioc->name, fwSize*4, ptrFw));
2982 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
2985 nextImage = pFwHeader->NextImageHeaderOffset;
2987 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
2989 load_addr = pExtImage->LoadStartAddress;
2991 fwSize = (pExtImage->ImageSize + 3) >> 2;
2992 ptrFw = (u32 *)pExtImage;
2994 ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
2995 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
2996 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
2999 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3001 nextImage = pExtImage->NextImageHeaderOffset;
3004 /* Write the IopResetVectorRegAddr */
3005 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
3006 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3008 /* Write the IopResetVectorValue */
3009 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3010 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3012 /* Clear the internal flash bad bit - autoincrementing register,
3013 * so must do two writes.
3015 if (ioc->bus_type == SPI) {
3017 * 1030 and 1035 H/W errata, workaround to access
3018 * the ClearFlashBadSignatureBit
3020 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3021 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3022 diagRwData |= 0x40000000;
3023 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3024 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3026 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3027 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3028 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3029 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3032 if (sleepFlag == CAN_SLEEP) {
3039 if (ioc->errata_flag_1064)
3040 pci_disable_io_access(ioc->pcidev);
3042 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3043 ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, "
3044 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3045 ioc->name, diag0val));
3046 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3047 ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
3048 ioc->name, diag0val));
3049 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3051 /* Write 0xFF to reset the sequencer */
3052 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3054 if (ioc->bus_type == SAS) {
3055 ioc_state = mpt_GetIocState(ioc, 0);
3056 if ( (GetIocFacts(ioc, sleepFlag,
3057 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3058 ddlprintk((MYIOC_s_INFO_FMT "GetIocFacts failed: IocState=%x\n",
3059 ioc->name, ioc_state));
3064 for (count=0; count<HZ*20; count++) {
3065 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3066 ddlprintk((MYIOC_s_INFO_FMT "downloadboot successful! (count=%d) IocState=%x\n",
3067 ioc->name, count, ioc_state));
3068 if (ioc->bus_type == SAS) {
3071 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3072 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit failed\n",
3076 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit successful\n",
3080 if (sleepFlag == CAN_SLEEP) {
3086 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! IocState=%x\n",
3087 ioc->name, ioc_state));
3091 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3093 * KickStart - Perform hard reset of MPT adapter.
3094 * @ioc: Pointer to MPT_ADAPTER structure
3095 * @force: Force hard reset
3096 * @sleepFlag: Specifies whether the process can sleep
3098 * This routine places MPT adapter in diagnostic mode via the
3099 * WriteSequence register, and then performs a hard reset of adapter
3100 * via the Diagnostic register.
3102 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3103 * or NO_SLEEP (interrupt thread, use mdelay)
3104 * force - 1 if doorbell active, board fault state
3105 * board operational, IOC_RECOVERY or
3106 * IOC_BRINGUP and there is an alt_ioc.
3110 * 1 - hard reset, READY
3111 * 0 - no reset due to History bit, READY
3112 * -1 - no reset due to History bit but not READY
3113 * OR reset but failed to come READY
3114 * -2 - no reset, could not enter DIAG mode
3115 * -3 - reset but bad FW bit
3118 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3120 int hard_reset_done = 0;
3124 dinitprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
3125 if (ioc->bus_type == SPI) {
3126 /* Always issue a Msg Unit Reset first. This will clear some
3127 * SCSI bus hang conditions.
3129 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3131 if (sleepFlag == CAN_SLEEP) {
3138 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3139 if (hard_reset_done < 0)
3140 return hard_reset_done;
3142 dinitprintk((MYIOC_s_INFO_FMT "Diagnostic reset successful!\n",
3145 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3146 for (cnt=0; cnt<cntdn; cnt++) {
3147 ioc_state = mpt_GetIocState(ioc, 1);
3148 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3149 dinitprintk((MYIOC_s_INFO_FMT "KickStart successful! (cnt=%d)\n",
3151 return hard_reset_done;
3153 if (sleepFlag == CAN_SLEEP) {
3160 printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3161 ioc->name, ioc_state);
3165 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3167 * mpt_diag_reset - Perform hard reset of the adapter.
3168 * @ioc: Pointer to MPT_ADAPTER structure
3169 * @ignore: Set if to honor and clear to ignore
3170 * the reset history bit
3171 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3172 * else set to NO_SLEEP (use mdelay instead)
3174 * This routine places the adapter in diagnostic mode via the
3175 * WriteSequence register and then performs a hard reset of adapter
3176 * via the Diagnostic register. Adapter should be in ready state
3177 * upon successful completion.
3179 * Returns: 1 hard reset successful
3180 * 0 no reset performed because reset history bit set
3181 * -2 enabling diagnostic mode failed
3182 * -3 diagnostic reset failed
3185 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3187 MPT_ADAPTER *iocp=NULL;
3190 int hard_reset_done = 0;
3196 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3197 drsprintk((MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3198 "address=%p\n", ioc->name, __FUNCTION__,
3199 &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3200 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3201 if (sleepFlag == CAN_SLEEP)
3206 for (count = 0; count < 60; count ++) {
3207 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3208 doorbell &= MPI_IOC_STATE_MASK;
3210 drsprintk((MYIOC_s_INFO_FMT
3211 "looking for READY STATE: doorbell=%x"
3213 ioc->name, doorbell, count));
3214 if (doorbell == MPI_IOC_STATE_READY) {
3219 if (sleepFlag == CAN_SLEEP)
3227 /* Clear any existing interrupts */
3228 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3230 /* Use "Diagnostic reset" method! (only thing available!) */
3231 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3235 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3236 dprintk((MYIOC_s_INFO_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3237 ioc->name, diag0val, diag1val));
3240 /* Do the reset if we are told to ignore the reset history
3241 * or if the reset history is 0
3243 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3244 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3245 /* Write magic sequence to WriteSequence register
3246 * Loop until in diagnostic mode
3248 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3249 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3250 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3251 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3252 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3253 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3256 if (sleepFlag == CAN_SLEEP) {
3264 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3265 ioc->name, diag0val);
3270 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3272 dprintk((MYIOC_s_INFO_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3273 ioc->name, diag0val));
3278 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3279 dprintk((MYIOC_s_INFO_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3280 ioc->name, diag0val, diag1val));
3283 * Disable the ARM (Bug fix)
3286 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3290 * Now hit the reset bit in the Diagnostic register
3291 * (THE BIG HAMMER!) (Clears DRWE bit).
3293 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3294 hard_reset_done = 1;
3295 dprintk((MYIOC_s_INFO_FMT "Diagnostic reset performed\n",
3299 * Call each currently registered protocol IOC reset handler
3300 * with pre-reset indication.
3301 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3302 * MptResetHandlers[] registered yet.
3308 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
3309 if (MptResetHandlers[ii]) {
3310 dprintk((MYIOC_s_INFO_FMT "Calling IOC pre_reset handler #%d\n",
3312 r += mpt_signal_reset(ii, ioc, MPT_IOC_PRE_RESET);
3314 dprintk((MYIOC_s_INFO_FMT "Calling alt-%s pre_reset handler #%d\n",
3315 ioc->name, ioc->alt_ioc->name, ii));
3316 r += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_PRE_RESET);
3320 /* FIXME? Examine results here? */
3325 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
3326 iocp = ioc->alt_ioc;
3328 /* If the DownloadBoot operation fails, the
3329 * IOC will be left unusable. This is a fatal error
3330 * case. _diag_reset will return < 0
3332 for (count = 0; count < 30; count ++) {
3333 diag0val = CHIPREG_READ32(&iocp->chip->Diagnostic);
3334 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3338 dprintk((MYIOC_s_INFO_FMT "cached_fw: diag0val=%x count=%d\n",
3339 iocp->name, diag0val, count));
3341 if (sleepFlag == CAN_SLEEP) {
3347 if ((count = mpt_downloadboot(ioc,
3348 (MpiFwHeader_t *)iocp->cached_fw, sleepFlag)) < 0) {
3349 printk(KERN_WARNING MYNAM
3350 ": firmware downloadboot failure (%d)!\n", count);
3354 /* Wait for FW to reload and for board
3355 * to go to the READY state.
3356 * Maximum wait is 60 seconds.
3357 * If fail, no error will check again
3358 * with calling program.
3360 for (count = 0; count < 60; count ++) {
3361 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3362 doorbell &= MPI_IOC_STATE_MASK;
3364 if (doorbell == MPI_IOC_STATE_READY) {
3369 if (sleepFlag == CAN_SLEEP) {
3378 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3381 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3382 dprintk((MYIOC_s_INFO_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3383 ioc->name, diag0val, diag1val));
3386 /* Clear RESET_HISTORY bit! Place board in the
3387 * diagnostic mode to update the diag register.
3389 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3391 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3392 /* Write magic sequence to WriteSequence register
3393 * Loop until in diagnostic mode
3395 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3396 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3397 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3398 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3399 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3400 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3403 if (sleepFlag == CAN_SLEEP) {
3411 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3412 ioc->name, diag0val);
3415 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3417 diag0val &= ~MPI_DIAG_RESET_HISTORY;
3418 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3419 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3420 if (diag0val & MPI_DIAG_RESET_HISTORY) {
3421 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3425 /* Disable Diagnostic Mode
3427 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3429 /* Check FW reload status flags.
3431 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3432 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3433 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3434 ioc->name, diag0val);
3440 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3441 dprintk((MYIOC_s_INFO_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3442 ioc->name, diag0val, diag1val));
3446 * Reset flag that says we've enabled event notification
3448 ioc->facts.EventState = 0;
3451 ioc->alt_ioc->facts.EventState = 0;
3453 return hard_reset_done;
3456 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3458 * SendIocReset - Send IOCReset request to MPT adapter.
3459 * @ioc: Pointer to MPT_ADAPTER structure
3460 * @reset_type: reset type, expected values are
3461 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3462 * @sleepFlag: Specifies whether the process can sleep
3464 * Send IOCReset request to the MPT adapter.
3466 * Returns 0 for success, non-zero for failure.
3469 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3475 drsprintk((KERN_INFO MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
3476 ioc->name, reset_type));
3477 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3478 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3481 /* FW ACK'd request, wait for READY state
3484 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
3486 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3490 if (sleepFlag != CAN_SLEEP)
3493 printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
3494 ioc->name, (int)((count+5)/HZ));
3498 if (sleepFlag == CAN_SLEEP) {
3501 mdelay (1); /* 1 msec delay */
3506 * Cleanup all event stuff for this IOC; re-issue EventNotification
3507 * request if needed.
3509 if (ioc->facts.Function)
3510 ioc->facts.EventState = 0;
3515 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3517 * initChainBuffers - Allocate memory for and initialize chain buffers
3518 * @ioc: Pointer to MPT_ADAPTER structure
3520 * Allocates memory for and initializes chain buffers,
3521 * chain buffer control arrays and spinlock.
3524 initChainBuffers(MPT_ADAPTER *ioc)
3527 int sz, ii, num_chain;
3528 int scale, num_sge, numSGE;
3530 /* ReqToChain size must equal the req_depth
3533 if (ioc->ReqToChain == NULL) {
3534 sz = ioc->req_depth * sizeof(int);
3535 mem = kmalloc(sz, GFP_ATOMIC);
3539 ioc->ReqToChain = (int *) mem;
3540 dinitprintk((KERN_INFO MYNAM ": %s ReqToChain alloc @ %p, sz=%d bytes\n",
3541 ioc->name, mem, sz));
3542 mem = kmalloc(sz, GFP_ATOMIC);
3546 ioc->RequestNB = (int *) mem;
3547 dinitprintk((KERN_INFO MYNAM ": %s RequestNB alloc @ %p, sz=%d bytes\n",
3548 ioc->name, mem, sz));
3550 for (ii = 0; ii < ioc->req_depth; ii++) {
3551 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
3554 /* ChainToChain size must equal the total number
3555 * of chain buffers to be allocated.
3558 * Calculate the number of chain buffers needed(plus 1) per I/O
3559 * then multiply the the maximum number of simultaneous cmds
3561 * num_sge = num sge in request frame + last chain buffer
3562 * scale = num sge per chain buffer if no chain element
3564 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3565 if (sizeof(dma_addr_t) == sizeof(u64))
3566 num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3568 num_sge = 1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3570 if (sizeof(dma_addr_t) == sizeof(u64)) {
3571 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3572 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3574 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3575 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3577 dinitprintk((KERN_INFO MYNAM ": %s num_sge=%d numSGE=%d\n",
3578 ioc->name, num_sge, numSGE));
3580 if ( numSGE > MPT_SCSI_SG_DEPTH )
3581 numSGE = MPT_SCSI_SG_DEPTH;
3584 while (numSGE - num_sge > 0) {
3586 num_sge += (scale - 1);
3590 dinitprintk((KERN_INFO MYNAM ": %s Now numSGE=%d num_sge=%d num_chain=%d\n",
3591 ioc->name, numSGE, num_sge, num_chain));
3593 if (ioc->bus_type == SPI)
3594 num_chain *= MPT_SCSI_CAN_QUEUE;
3596 num_chain *= MPT_FC_CAN_QUEUE;
3598 ioc->num_chain = num_chain;
3600 sz = num_chain * sizeof(int);
3601 if (ioc->ChainToChain == NULL) {
3602 mem = kmalloc(sz, GFP_ATOMIC);
3606 ioc->ChainToChain = (int *) mem;
3607 dinitprintk((KERN_INFO MYNAM ": %s ChainToChain alloc @ %p, sz=%d bytes\n",
3608 ioc->name, mem, sz));
3610 mem = (u8 *) ioc->ChainToChain;
3612 memset(mem, 0xFF, sz);
3616 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3618 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
3619 * @ioc: Pointer to MPT_ADAPTER structure
3621 * This routine allocates memory for the MPT reply and request frame
3622 * pools (if necessary), and primes the IOC reply FIFO with
3625 * Returns 0 for success, non-zero for failure.
3628 PrimeIocFifos(MPT_ADAPTER *ioc)
3631 unsigned long flags;
3632 dma_addr_t alloc_dma;
3634 int i, reply_sz, sz, total_size, num_chain;
3636 /* Prime reply FIFO... */
3638 if (ioc->reply_frames == NULL) {
3639 if ( (num_chain = initChainBuffers(ioc)) < 0)
3642 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
3643 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
3644 ioc->name, ioc->reply_sz, ioc->reply_depth));
3645 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d[%x] bytes\n",
3646 ioc->name, reply_sz, reply_sz));
3648 sz = (ioc->req_sz * ioc->req_depth);
3649 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d bytes, RequestDepth=%d\n",
3650 ioc->name, ioc->req_sz, ioc->req_depth));
3651 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d[%x] bytes\n",
3652 ioc->name, sz, sz));
3655 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
3656 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d bytes, ChainDepth=%d\n",
3657 ioc->name, ioc->req_sz, num_chain));
3658 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
3659 ioc->name, sz, sz, num_chain));
3662 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
3664 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
3669 dinitprintk((KERN_INFO MYNAM ": %s.Total alloc @ %p[%p], sz=%d[%x] bytes\n",
3670 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
3672 memset(mem, 0, total_size);
3673 ioc->alloc_total += total_size;
3675 ioc->alloc_dma = alloc_dma;
3676 ioc->alloc_sz = total_size;
3677 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
3678 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3680 dinitprintk((KERN_INFO MYNAM ": %s ReplyBuffers @ %p[%p]\n",
3681 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3683 alloc_dma += reply_sz;
3686 /* Request FIFO - WE manage this! */
3688 ioc->req_frames = (MPT_FRAME_HDR *) mem;
3689 ioc->req_frames_dma = alloc_dma;
3691 dinitprintk((KERN_INFO MYNAM ": %s RequestBuffers @ %p[%p]\n",
3692 ioc->name, mem, (void *)(ulong)alloc_dma));
3694 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3696 #if defined(CONFIG_MTRR) && 0
3698 * Enable Write Combining MTRR for IOC's memory region.
3699 * (at least as much as we can; "size and base must be
3700 * multiples of 4 kiB"
3702 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
3704 MTRR_TYPE_WRCOMB, 1);
3705 dprintk((MYIOC_s_INFO_FMT "MTRR region registered (base:size=%08x:%x)\n",
3706 ioc->name, ioc->req_frames_dma, sz));
3709 for (i = 0; i < ioc->req_depth; i++) {
3710 alloc_dma += ioc->req_sz;
3714 ioc->ChainBuffer = mem;
3715 ioc->ChainBufferDMA = alloc_dma;
3717 dinitprintk((KERN_INFO MYNAM " :%s ChainBuffers @ %p(%p)\n",
3718 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
3720 /* Initialize the free chain Q.
3723 INIT_LIST_HEAD(&ioc->FreeChainQ);
3725 /* Post the chain buffers to the FreeChainQ.
3727 mem = (u8 *)ioc->ChainBuffer;
3728 for (i=0; i < num_chain; i++) {
3729 mf = (MPT_FRAME_HDR *) mem;
3730 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
3734 /* Initialize Request frames linked list
3736 alloc_dma = ioc->req_frames_dma;
3737 mem = (u8 *) ioc->req_frames;
3739 spin_lock_irqsave(&ioc->FreeQlock, flags);
3740 INIT_LIST_HEAD(&ioc->FreeQ);
3741 for (i = 0; i < ioc->req_depth; i++) {
3742 mf = (MPT_FRAME_HDR *) mem;
3744 /* Queue REQUESTs *internally*! */
3745 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
3749 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3751 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3752 ioc->sense_buf_pool =
3753 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
3754 if (ioc->sense_buf_pool == NULL) {
3755 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
3760 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
3761 ioc->alloc_total += sz;
3762 dinitprintk((KERN_INFO MYNAM ": %s.SenseBuffers @ %p[%p]\n",
3763 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
3767 /* Post Reply frames to FIFO
3769 alloc_dma = ioc->alloc_dma;
3770 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffers @ %p[%p]\n",
3771 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3773 for (i = 0; i < ioc->reply_depth; i++) {
3774 /* Write each address to the IOC! */
3775 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
3776 alloc_dma += ioc->reply_sz;
3782 if (ioc->alloc != NULL) {
3784 pci_free_consistent(ioc->pcidev,
3786 ioc->alloc, ioc->alloc_dma);
3787 ioc->reply_frames = NULL;
3788 ioc->req_frames = NULL;
3789 ioc->alloc_total -= sz;
3791 if (ioc->sense_buf_pool != NULL) {
3792 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3793 pci_free_consistent(ioc->pcidev,
3795 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
3796 ioc->sense_buf_pool = NULL;
3801 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3803 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
3804 * from IOC via doorbell handshake method.
3805 * @ioc: Pointer to MPT_ADAPTER structure
3806 * @reqBytes: Size of the request in bytes
3807 * @req: Pointer to MPT request frame
3808 * @replyBytes: Expected size of the reply in bytes
3809 * @u16reply: Pointer to area where reply should be written
3810 * @maxwait: Max wait time for a reply (in seconds)
3811 * @sleepFlag: Specifies whether the process can sleep
3813 * NOTES: It is the callers responsibility to byte-swap fields in the
3814 * request which are greater than 1 byte in size. It is also the
3815 * callers responsibility to byte-swap response fields which are
3816 * greater than 1 byte in size.
3818 * Returns 0 for success, non-zero for failure.
3821 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
3822 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
3824 MPIDefaultReply_t *mptReply;
3829 * Get ready to cache a handshake reply
3831 ioc->hs_reply_idx = 0;
3832 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
3833 mptReply->MsgLength = 0;
3836 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
3837 * then tell IOC that we want to handshake a request of N words.
3838 * (WRITE u32val to Doorbell reg).
3840 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3841 CHIPREG_WRITE32(&ioc->chip->Doorbell,
3842 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
3843 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
3846 * Wait for IOC's doorbell handshake int
3848 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3851 dhsprintk((MYIOC_s_INFO_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
3852 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
3854 /* Read doorbell and check for active bit */
3855 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
3859 * Clear doorbell int (WRITE 0 to IntStatus reg),
3860 * then wait for IOC to ACKnowledge that it's ready for
3861 * our handshake request.
3863 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3864 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3869 u8 *req_as_bytes = (u8 *) req;
3872 * Stuff request words via doorbell handshake,
3873 * with ACK from IOC for each.
3875 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
3876 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
3877 (req_as_bytes[(ii*4) + 1] << 8) |
3878 (req_as_bytes[(ii*4) + 2] << 16) |
3879 (req_as_bytes[(ii*4) + 3] << 24));
3881 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
3882 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3886 dhsprintk((KERN_INFO MYNAM ": Handshake request frame (@%p) header\n", req));
3887 DBG_DUMP_REQUEST_FRAME_HDR(req)
3889 dhsprintk((MYIOC_s_INFO_FMT "HandShake request post done, WaitCnt=%d%s\n",
3890 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
3893 * Wait for completion of doorbell handshake reply from the IOC
3895 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
3898 dhsprintk((MYIOC_s_INFO_FMT "HandShake reply count=%d%s\n",
3899 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
3902 * Copy out the cached reply...
3904 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
3905 u16reply[ii] = ioc->hs_reply[ii];
3913 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3915 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
3916 * @ioc: Pointer to MPT_ADAPTER structure
3917 * @howlong: How long to wait (in seconds)
3918 * @sleepFlag: Specifies whether the process can sleep
3920 * This routine waits (up to ~2 seconds max) for IOC doorbell
3921 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
3922 * bit in its IntStatus register being clear.
3924 * Returns a negative value on failure, else wait loop count.
3927 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3933 cntdn = 1000 * howlong;
3935 if (sleepFlag == CAN_SLEEP) {
3938 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3939 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3946 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3947 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3954 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell ACK (count=%d)\n",
3959 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
3960 ioc->name, count, intstat);
3964 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3966 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
3967 * @ioc: Pointer to MPT_ADAPTER structure
3968 * @howlong: How long to wait (in seconds)
3969 * @sleepFlag: Specifies whether the process can sleep
3971 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
3972 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
3974 * Returns a negative value on failure, else wait loop count.
3977 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3983 cntdn = 1000 * howlong;
3984 if (sleepFlag == CAN_SLEEP) {
3986 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3987 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
3994 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3995 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4003 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4004 ioc->name, count, howlong));
4008 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4009 ioc->name, count, intstat);
4013 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4015 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4016 * @ioc: Pointer to MPT_ADAPTER structure
4017 * @howlong: How long to wait (in seconds)
4018 * @sleepFlag: Specifies whether the process can sleep
4020 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4021 * Reply is cached to IOC private area large enough to hold a maximum
4022 * of 128 bytes of reply data.
4024 * Returns a negative value on failure, else size of reply in WORDS.
4027 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4032 u16 *hs_reply = ioc->hs_reply;
4033 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4036 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4039 * Get first two u16's so we can look at IOC's intended reply MsgLength
4042 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4045 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4046 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4047 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4050 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4051 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4055 dhsprintk((MYIOC_s_INFO_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4056 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4057 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4060 * If no error (and IOC said MsgLength is > 0), piece together
4061 * reply 16 bits at a time.
4063 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4064 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4066 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4067 /* don't overflow our IOC hs_reply[] buffer! */
4068 if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
4069 hs_reply[u16cnt] = hword;
4070 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4073 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4075 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4078 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4083 else if (u16cnt != (2 * mptReply->MsgLength)) {
4086 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4091 dhsprintk((MYIOC_s_INFO_FMT "Got Handshake reply:\n", ioc->name));
4092 DBG_DUMP_REPLY_FRAME(mptReply)
4094 dhsprintk((MYIOC_s_INFO_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4095 ioc->name, t, u16cnt/2));
4099 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4101 * GetLanConfigPages - Fetch LANConfig pages.
4102 * @ioc: Pointer to MPT_ADAPTER structure
4104 * Return: 0 for success
4105 * -ENOMEM if no memory available
4106 * -EPERM if not allowed due to ISR context
4107 * -EAGAIN if no msg frames currently available
4108 * -EFAULT for non-successful reply or no reply (timeout)
4111 GetLanConfigPages(MPT_ADAPTER *ioc)
4113 ConfigPageHeader_t hdr;
4115 LANPage0_t *ppage0_alloc;
4116 dma_addr_t page0_dma;
4117 LANPage1_t *ppage1_alloc;
4118 dma_addr_t page1_dma;
4123 /* Get LAN Page 0 header */
4124 hdr.PageVersion = 0;
4127 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4128 cfg.cfghdr.hdr = &hdr;
4130 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4135 if ((rc = mpt_config(ioc, &cfg)) != 0)
4138 if (hdr.PageLength > 0) {
4139 data_sz = hdr.PageLength * 4;
4140 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4143 memset((u8 *)ppage0_alloc, 0, data_sz);
4144 cfg.physAddr = page0_dma;
4145 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4147 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4149 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4150 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4154 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4157 * Normalize endianness of structure data,
4158 * by byte-swapping all > 1 byte fields!
4167 /* Get LAN Page 1 header */
4168 hdr.PageVersion = 0;
4171 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4172 cfg.cfghdr.hdr = &hdr;
4174 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4178 if ((rc = mpt_config(ioc, &cfg)) != 0)
4181 if (hdr.PageLength == 0)
4184 data_sz = hdr.PageLength * 4;
4186 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4188 memset((u8 *)ppage1_alloc, 0, data_sz);
4189 cfg.physAddr = page1_dma;
4190 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4192 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4194 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4195 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4198 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4201 * Normalize endianness of structure data,
4202 * by byte-swapping all > 1 byte fields!
4210 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4212 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
4213 * @ioc: Pointer to MPT_ADAPTER structure
4214 * @persist_opcode: see below
4216 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4217 * devices not currently present.
4218 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4220 * NOTE: Don't use not this function during interrupt time.
4222 * Returns 0 for success, non-zero error
4225 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4227 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4229 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
4230 SasIoUnitControlReply_t *sasIoUnitCntrReply;
4231 MPT_FRAME_HDR *mf = NULL;
4232 MPIHeader_t *mpi_hdr;
4235 /* insure garbage is not sent to fw */
4236 switch(persist_opcode) {
4238 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
4239 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
4247 printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode);
4249 /* Get a MF for this command.
4251 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4252 printk("%s: no msg frames!\n",__FUNCTION__);
4256 mpi_hdr = (MPIHeader_t *) mf;
4257 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
4258 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
4259 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
4260 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
4261 sasIoUnitCntrReq->Operation = persist_opcode;
4263 init_timer(&ioc->persist_timer);
4264 ioc->persist_timer.data = (unsigned long) ioc;
4265 ioc->persist_timer.function = mpt_timer_expired;
4266 ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
4267 ioc->persist_wait_done=0;
4268 add_timer(&ioc->persist_timer);
4269 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4270 wait_event(mpt_waitq, ioc->persist_wait_done);
4272 sasIoUnitCntrReply =
4273 (SasIoUnitControlReply_t *)ioc->persist_reply_frame;
4274 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
4275 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4277 sasIoUnitCntrReply->IOCStatus,
4278 sasIoUnitCntrReply->IOCLogInfo);
4282 printk("%s: success\n",__FUNCTION__);
4286 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4289 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
4290 MpiEventDataRaid_t * pRaidEventData)
4299 volume = pRaidEventData->VolumeID;
4300 reason = pRaidEventData->ReasonCode;
4301 disk = pRaidEventData->PhysDiskNum;
4302 status = le32_to_cpu(pRaidEventData->SettingsStatus);
4303 flags = (status >> 0) & 0xff;
4304 state = (status >> 8) & 0xff;
4306 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
4310 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
4311 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
4312 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
4313 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d\n",
4316 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
4321 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4322 printk(MYIOC_s_INFO_FMT " volume has been created\n",
4326 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4328 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
4332 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
4333 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
4337 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4338 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
4340 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
4342 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
4344 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
4347 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
4349 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
4350 ? ", quiesced" : "",
4351 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
4352 ? ", resync in progress" : "" );
4355 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
4356 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
4360 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4361 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
4365 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4366 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
4370 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
4371 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
4375 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4376 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
4378 state == MPI_PHYSDISK0_STATUS_ONLINE
4380 : state == MPI_PHYSDISK0_STATUS_MISSING
4382 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
4384 : state == MPI_PHYSDISK0_STATUS_FAILED
4386 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
4388 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
4389 ? "offline requested"
4390 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
4391 ? "failed requested"
4392 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
4395 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
4396 ? ", out of sync" : "",
4397 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
4398 ? ", quiesced" : "" );
4401 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
4402 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
4406 case MPI_EVENT_RAID_RC_SMART_DATA:
4407 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
4408 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
4411 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
4412 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
4418 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4420 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4421 * @ioc: Pointer to MPT_ADAPTER structure
4423 * Returns: 0 for success
4424 * -ENOMEM if no memory available
4425 * -EPERM if not allowed due to ISR context
4426 * -EAGAIN if no msg frames currently available
4427 * -EFAULT for non-successful reply or no reply (timeout)
4430 GetIoUnitPage2(MPT_ADAPTER *ioc)
4432 ConfigPageHeader_t hdr;
4434 IOUnitPage2_t *ppage_alloc;
4435 dma_addr_t page_dma;
4439 /* Get the page header */
4440 hdr.PageVersion = 0;
4443 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4444 cfg.cfghdr.hdr = &hdr;
4446 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4451 if ((rc = mpt_config(ioc, &cfg)) != 0)
4454 if (hdr.PageLength == 0)
4457 /* Read the config page */
4458 data_sz = hdr.PageLength * 4;
4460 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4462 memset((u8 *)ppage_alloc, 0, data_sz);
4463 cfg.physAddr = page_dma;
4464 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4466 /* If Good, save data */
4467 if ((rc = mpt_config(ioc, &cfg)) == 0)
4468 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4470 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4476 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4478 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4479 * @ioc: Pointer to a Adapter Strucutre
4480 * @portnum: IOC port number
4482 * Return: -EFAULT if read of config page header fails
4484 * If read of SCSI Port Page 0 fails,
4485 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4486 * Adapter settings: async, narrow
4488 * If read of SCSI Port Page 2 fails,
4489 * Adapter settings valid
4490 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4495 * CHECK - what type of locking mechanisms should be used????
4498 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4503 ConfigPageHeader_t header;
4509 if (!ioc->spi_data.nvram) {
4512 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4513 mem = kmalloc(sz, GFP_ATOMIC);
4517 ioc->spi_data.nvram = (int *) mem;
4519 dprintk((MYIOC_s_INFO_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4520 ioc->name, ioc->spi_data.nvram, sz));
4523 /* Invalidate NVRAM information
4525 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4526 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4529 /* Read SPP0 header, allocate memory, then read page.
4531 header.PageVersion = 0;
4532 header.PageLength = 0;
4533 header.PageNumber = 0;
4534 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4535 cfg.cfghdr.hdr = &header;
4537 cfg.pageAddr = portnum;
4538 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4540 cfg.timeout = 0; /* use default */
4541 if (mpt_config(ioc, &cfg) != 0)
4544 if (header.PageLength > 0) {
4545 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4547 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4548 cfg.physAddr = buf_dma;
4549 if (mpt_config(ioc, &cfg) != 0) {
4550 ioc->spi_data.maxBusWidth = MPT_NARROW;
4551 ioc->spi_data.maxSyncOffset = 0;
4552 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4553 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4555 ddvprintk((MYIOC_s_INFO_FMT "Unable to read PortPage0 minSyncFactor=%x\n",
4556 ioc->name, ioc->spi_data.minSyncFactor));
4558 /* Save the Port Page 0 data
4560 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
4561 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4562 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4564 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
4565 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4566 ddvprintk((KERN_INFO MYNAM " :%s noQas due to Capabilities=%x\n",
4567 ioc->name, pPP0->Capabilities));
4569 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4570 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4572 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4573 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4574 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4575 ddvprintk((MYIOC_s_INFO_FMT "PortPage0 minSyncFactor=%x\n",
4576 ioc->name, ioc->spi_data.minSyncFactor));
4578 ioc->spi_data.maxSyncOffset = 0;
4579 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4582 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4584 /* Update the minSyncFactor based on bus type.
4586 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4587 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
4589 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
4590 ioc->spi_data.minSyncFactor = MPT_ULTRA;
4591 ddvprintk((MYIOC_s_INFO_FMT "HVD or SE detected, minSyncFactor=%x\n",
4592 ioc->name, ioc->spi_data.minSyncFactor));
4597 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4602 /* SCSI Port Page 2 - Read the header then the page.
4604 header.PageVersion = 0;
4605 header.PageLength = 0;
4606 header.PageNumber = 2;
4607 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4608 cfg.cfghdr.hdr = &header;
4610 cfg.pageAddr = portnum;
4611 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4613 if (mpt_config(ioc, &cfg) != 0)
4616 if (header.PageLength > 0) {
4617 /* Allocate memory and read SCSI Port Page 2
4619 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4621 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
4622 cfg.physAddr = buf_dma;
4623 if (mpt_config(ioc, &cfg) != 0) {
4624 /* Nvram data is left with INVALID mark
4628 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
4629 MpiDeviceInfo_t *pdevice = NULL;
4632 * Save "Set to Avoid SCSI Bus Resets" flag
4634 ioc->spi_data.bus_reset =
4635 (le32_to_cpu(pPP2->PortFlags) &
4636 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
4639 /* Save the Port Page 2 data
4640 * (reformat into a 32bit quantity)
4642 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
4643 ioc->spi_data.PortFlags = data;
4644 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4645 pdevice = &pPP2->DeviceSettings[ii];
4646 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
4647 (pdevice->SyncFactor << 8) | pdevice->Timeout;
4648 ioc->spi_data.nvram[ii] = data;
4652 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4656 /* Update Adapter limits with those from NVRAM
4657 * Comment: Don't need to do this. Target performance
4658 * parameters will never exceed the adapters limits.
4664 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4666 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
4667 * @ioc: Pointer to a Adapter Strucutre
4668 * @portnum: IOC port number
4670 * Return: -EFAULT if read of config page header fails
4674 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
4677 ConfigPageHeader_t header;
4679 /* Read the SCSI Device Page 1 header
4681 header.PageVersion = 0;
4682 header.PageLength = 0;
4683 header.PageNumber = 1;
4684 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4685 cfg.cfghdr.hdr = &header;
4687 cfg.pageAddr = portnum;
4688 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4691 if (mpt_config(ioc, &cfg) != 0)
4694 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
4695 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
4697 header.PageVersion = 0;
4698 header.PageLength = 0;
4699 header.PageNumber = 0;
4700 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4701 if (mpt_config(ioc, &cfg) != 0)
4704 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
4705 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
4707 dcprintk((MYIOC_s_INFO_FMT "Headers: 0: version %d length %d\n",
4708 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
4710 dcprintk((MYIOC_s_INFO_FMT "Headers: 1: version %d length %d\n",
4711 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
4715 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4717 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
4718 * @ioc: Pointer to a Adapter Strucutre
4719 * @portnum: IOC port number
4723 * -EFAULT if read of config page header fails or data pointer not NULL
4724 * -ENOMEM if pci_alloc failed
4727 mpt_findImVolumes(MPT_ADAPTER *ioc)
4731 ConfigPageIoc2RaidVol_t *pIocRv;
4732 dma_addr_t ioc2_dma;
4734 ConfigPageHeader_t header;
4741 /* Read IOCP2 header then the page.
4743 header.PageVersion = 0;
4744 header.PageLength = 0;
4745 header.PageNumber = 2;
4746 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4747 cfg.cfghdr.hdr = &header;
4750 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4753 if (mpt_config(ioc, &cfg) != 0)
4756 if (header.PageLength == 0)
4759 iocpage2sz = header.PageLength * 4;
4760 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
4764 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4765 cfg.physAddr = ioc2_dma;
4766 if (mpt_config(ioc, &cfg) != 0)
4769 if ( (mem = (u8 *)ioc->raid_data.pIocPg2) == NULL ) {
4770 mem = kmalloc(iocpage2sz, GFP_ATOMIC);
4772 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
4777 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
4779 /* Identify RAID Volume Id's */
4780 nVols = pIoc2->NumActiveVolumes;
4786 /* At least 1 RAID Volume
4788 pIocRv = pIoc2->RaidVolume;
4789 ioc->raid_data.isRaid = 0;
4790 for (jj = 0; jj < nVols; jj++, pIocRv++) {
4791 vid = pIocRv->VolumeID;
4792 vbus = pIocRv->VolumeBus;
4793 vioc = pIocRv->VolumeIOC;
4798 ioc->raid_data.isRaid |= (1 << vid);
4800 /* Error! Always bus 0
4806 /* Identify Hidden Physical Disk Id's */
4807 nPhys = pIoc2->NumActivePhysDisks;
4809 /* No physical disks.
4812 mpt_read_ioc_pg_3(ioc);
4816 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
4822 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
4827 ConfigPageHeader_t header;
4828 dma_addr_t ioc3_dma;
4831 /* Free the old page
4833 kfree(ioc->raid_data.pIocPg3);
4834 ioc->raid_data.pIocPg3 = NULL;
4836 /* There is at least one physical disk.
4837 * Read and save IOC Page 3
4839 header.PageVersion = 0;
4840 header.PageLength = 0;
4841 header.PageNumber = 3;
4842 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4843 cfg.cfghdr.hdr = &header;
4846 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4849 if (mpt_config(ioc, &cfg) != 0)
4852 if (header.PageLength == 0)
4855 /* Read Header good, alloc memory
4857 iocpage3sz = header.PageLength * 4;
4858 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
4862 /* Read the Page and save the data
4863 * into malloc'd memory.
4865 cfg.physAddr = ioc3_dma;
4866 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4867 if (mpt_config(ioc, &cfg) == 0) {
4868 mem = kmalloc(iocpage3sz, GFP_ATOMIC);
4870 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
4871 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
4875 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
4881 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
4885 ConfigPageHeader_t header;
4886 dma_addr_t ioc4_dma;
4889 /* Read and save IOC Page 4
4891 header.PageVersion = 0;
4892 header.PageLength = 0;
4893 header.PageNumber = 4;
4894 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4895 cfg.cfghdr.hdr = &header;
4898 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4901 if (mpt_config(ioc, &cfg) != 0)
4904 if (header.PageLength == 0)
4907 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
4908 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
4909 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
4912 ioc->alloc_total += iocpage4sz;
4914 ioc4_dma = ioc->spi_data.IocPg4_dma;
4915 iocpage4sz = ioc->spi_data.IocPg4Sz;
4918 /* Read the Page into dma memory.
4920 cfg.physAddr = ioc4_dma;
4921 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4922 if (mpt_config(ioc, &cfg) == 0) {
4923 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
4924 ioc->spi_data.IocPg4_dma = ioc4_dma;
4925 ioc->spi_data.IocPg4Sz = iocpage4sz;
4927 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
4928 ioc->spi_data.pIocPg4 = NULL;
4929 ioc->alloc_total -= iocpage4sz;
4934 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
4938 ConfigPageHeader_t header;
4939 dma_addr_t ioc1_dma;
4943 /* Check the Coalescing Timeout in IOC Page 1
4945 header.PageVersion = 0;
4946 header.PageLength = 0;
4947 header.PageNumber = 1;
4948 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4949 cfg.cfghdr.hdr = &header;
4952 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4955 if (mpt_config(ioc, &cfg) != 0)
4958 if (header.PageLength == 0)
4961 /* Read Header good, alloc memory
4963 iocpage1sz = header.PageLength * 4;
4964 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
4968 /* Read the Page and check coalescing timeout
4970 cfg.physAddr = ioc1_dma;
4971 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4972 if (mpt_config(ioc, &cfg) == 0) {
4974 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
4975 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
4976 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
4978 dprintk((MYIOC_s_INFO_FMT "Coalescing Enabled Timeout = %d\n",
4981 if (tmp > MPT_COALESCING_TIMEOUT) {
4982 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
4984 /* Write NVRAM and current
4987 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4988 if (mpt_config(ioc, &cfg) == 0) {
4989 dprintk((MYIOC_s_INFO_FMT "Reset Current Coalescing Timeout to = %d\n",
4990 ioc->name, MPT_COALESCING_TIMEOUT));
4992 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
4993 if (mpt_config(ioc, &cfg) == 0) {
4994 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout to = %d\n",
4995 ioc->name, MPT_COALESCING_TIMEOUT));
4997 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout Failed\n",
5002 dprintk((MYIOC_s_WARN_FMT "Reset of Current Coalescing Timeout Failed!\n",
5008 dprintk((MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
5012 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
5017 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5019 * SendEventNotification - Send EventNotification (on or off) request to adapter
5020 * @ioc: Pointer to MPT_ADAPTER structure
5021 * @EvSwitch: Event switch flags
5024 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
5026 EventNotification_t *evnp;
5028 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
5030 devtverboseprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
5034 memset(evnp, 0, sizeof(*evnp));
5036 devtverboseprintk((MYIOC_s_INFO_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
5038 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
5039 evnp->ChainOffset = 0;
5041 evnp->Switch = EvSwitch;
5043 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
5048 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5050 * SendEventAck - Send EventAck request to MPT adapter.
5051 * @ioc: Pointer to MPT_ADAPTER structure
5052 * @evnp: Pointer to original EventNotification request
5055 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
5059 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5060 dfailprintk((MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
5061 ioc->name,__FUNCTION__));
5065 devtverboseprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name));
5067 pAck->Function = MPI_FUNCTION_EVENT_ACK;
5068 pAck->ChainOffset = 0;
5069 pAck->Reserved[0] = pAck->Reserved[1] = 0;
5071 pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
5072 pAck->Event = evnp->Event;
5073 pAck->EventContext = evnp->EventContext;
5075 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
5080 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5082 * mpt_config - Generic function to issue config message
5083 * @ioc: Pointer to an adapter structure
5084 * @pCfg: Pointer to a configuration structure. Struct contains
5085 * action, page address, direction, physical address
5086 * and pointer to a configuration page header
5087 * Page header is updated.
5089 * Returns 0 for success
5090 * -EPERM if not allowed due to ISR context
5091 * -EAGAIN if no msg frames currently available
5092 * -EFAULT for non-successful reply or no reply (timeout)
5095 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5098 ConfigExtendedPageHeader_t *pExtHdr = NULL;
5100 unsigned long flags;
5105 /* Prevent calling wait_event() (below), if caller happens
5106 * to be in ISR context, because that is fatal!
5108 in_isr = in_interrupt();
5110 dcprintk((MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
5115 /* Get and Populate a free Frame
5117 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5118 dcprintk((MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
5122 pReq = (Config_t *)mf;
5123 pReq->Action = pCfg->action;
5125 pReq->ChainOffset = 0;
5126 pReq->Function = MPI_FUNCTION_CONFIG;
5128 /* Assume page type is not extended and clear "reserved" fields. */
5129 pReq->ExtPageLength = 0;
5130 pReq->ExtPageType = 0;
5133 for (ii=0; ii < 8; ii++)
5134 pReq->Reserved2[ii] = 0;
5136 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
5137 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
5138 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
5139 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
5141 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5142 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
5143 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
5144 pReq->ExtPageType = pExtHdr->ExtPageType;
5145 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
5147 /* Page Length must be treated as a reserved field for the extended header. */
5148 pReq->Header.PageLength = 0;
5151 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
5153 /* Add a SGE to the config request.
5156 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
5158 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
5160 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5161 flagsLength |= pExtHdr->ExtPageLength * 4;
5163 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
5164 ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action));
5167 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
5169 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
5170 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
5173 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
5175 /* Append pCfg pointer to end of mf
5177 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5179 /* Initalize the timer
5181 init_timer(&pCfg->timer);
5182 pCfg->timer.data = (unsigned long) ioc;
5183 pCfg->timer.function = mpt_timer_expired;
5184 pCfg->wait_done = 0;
5186 /* Set the timer; ensure 10 second minimum */
5187 if (pCfg->timeout < 10)
5188 pCfg->timer.expires = jiffies + HZ*10;
5190 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5192 /* Add to end of Q, set timer and then issue this command */
5193 spin_lock_irqsave(&ioc->FreeQlock, flags);
5194 list_add_tail(&pCfg->linkage, &ioc->configQ);
5195 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5197 add_timer(&pCfg->timer);
5198 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5199 wait_event(mpt_waitq, pCfg->wait_done);
5201 /* mf has been freed - do not access */
5208 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5210 * mpt_timer_expired - Callback for timer process.
5211 * Used only internal config functionality.
5212 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5215 mpt_timer_expired(unsigned long data)
5217 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
5219 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired! \n", ioc->name));
5221 /* Perform a FW reload */
5222 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
5223 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
5225 /* No more processing.
5226 * Hard reset clean-up will wake up
5227 * process and free all resources.
5229 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired complete!\n", ioc->name));
5234 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5236 * mpt_ioc_reset - Base cleanup for hard reset
5237 * @ioc: Pointer to the adapter structure
5238 * @reset_phase: Indicates pre- or post-reset functionality
5240 * Remark: Frees resources with internally generated commands.
5243 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
5246 unsigned long flags;
5248 dprintk((KERN_WARNING MYNAM
5249 ": IOC %s_reset routed to MPT base driver!\n",
5250 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
5251 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
5253 if (reset_phase == MPT_IOC_SETUP_RESET) {
5255 } else if (reset_phase == MPT_IOC_PRE_RESET) {
5256 /* If the internal config Q is not empty -
5257 * delete timer. MF resources will be freed when
5258 * the FIFO's are primed.
5260 spin_lock_irqsave(&ioc->FreeQlock, flags);
5261 list_for_each_entry(pCfg, &ioc->configQ, linkage)
5262 del_timer(&pCfg->timer);
5263 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5268 /* Search the configQ for internal commands.
5269 * Flush the Q, and wake up all suspended threads.
5271 spin_lock_irqsave(&ioc->FreeQlock, flags);
5272 list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
5273 list_del(&pCfg->linkage);
5275 pCfg->status = MPT_CONFIG_ERROR;
5276 pCfg->wait_done = 1;
5277 wake_up(&mpt_waitq);
5279 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5282 return 1; /* currently means nothing really */
5286 #ifdef CONFIG_PROC_FS /* { */
5287 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5289 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5291 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5293 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5295 * Returns 0 for success, non-zero for failure.
5298 procmpt_create(void)
5300 struct proc_dir_entry *ent;
5302 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
5303 if (mpt_proc_root_dir == NULL)
5306 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5308 ent->read_proc = procmpt_summary_read;
5310 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5312 ent->read_proc = procmpt_version_read;
5317 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5319 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5321 * Returns 0 for success, non-zero for failure.
5324 procmpt_destroy(void)
5326 remove_proc_entry("version", mpt_proc_root_dir);
5327 remove_proc_entry("summary", mpt_proc_root_dir);
5328 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
5331 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5333 * procmpt_summary_read - Handle read request of a summary file
5334 * @buf: Pointer to area to write information
5335 * @start: Pointer to start pointer
5336 * @offset: Offset to start writing
5337 * @request: Amount of read data requested
5338 * @eof: Pointer to EOF integer
5341 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
5342 * Returns number of characters written to process performing the read.
5345 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5355 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5359 list_for_each_entry(ioc, &ioc_list, list) {
5362 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5365 if ((out-buf) >= request)
5372 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5375 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5377 * procmpt_version_read - Handle read request from /proc/mpt/version.
5378 * @buf: Pointer to area to write information
5379 * @start: Pointer to start pointer
5380 * @offset: Offset to start writing
5381 * @request: Amount of read data requested
5382 * @eof: Pointer to EOF integer
5385 * Returns number of characters written to process performing the read.
5388 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5391 int scsi, fc, sas, lan, ctl, targ, dmp;
5395 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
5396 len += sprintf(buf+len, " Fusion MPT base driver\n");
5398 scsi = fc = sas = lan = ctl = targ = dmp = 0;
5399 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5401 if (MptCallbacks[ii]) {
5402 switch (MptDriverClass[ii]) {
5404 if (!scsi++) drvname = "SPI host";
5407 if (!fc++) drvname = "FC host";
5410 if (!sas++) drvname = "SAS host";
5413 if (!lan++) drvname = "LAN";
5416 if (!targ++) drvname = "SCSI target";
5419 if (!ctl++) drvname = "ioctl";
5424 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
5428 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5431 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5433 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
5434 * @buf: Pointer to area to write information
5435 * @start: Pointer to start pointer
5436 * @offset: Offset to start writing
5437 * @request: Amount of read data requested
5438 * @eof: Pointer to EOF integer
5441 * Returns number of characters written to process performing the read.
5444 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5446 MPT_ADAPTER *ioc = data;
5452 mpt_get_fw_exp_ver(expVer, ioc);
5454 len = sprintf(buf, "%s:", ioc->name);
5455 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
5456 len += sprintf(buf+len, " (f/w download boot flag set)");
5457 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
5458 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
5460 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
5461 ioc->facts.ProductID,
5463 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
5464 if (ioc->facts.FWImageSize)
5465 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
5466 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
5467 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
5468 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
5470 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
5471 ioc->facts.CurrentHostMfaHighAddr);
5472 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
5473 ioc->facts.CurrentSenseBufferHighAddr);
5475 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
5476 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
5478 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
5479 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
5481 * Rounding UP to nearest 4-kB boundary here...
5483 sz = (ioc->req_sz * ioc->req_depth) + 128;
5484 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
5485 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
5486 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
5487 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
5488 4*ioc->facts.RequestFrameSize,
5489 ioc->facts.GlobalCredits);
5491 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
5492 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
5493 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
5494 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
5495 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
5496 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
5497 ioc->facts.CurReplyFrameSize,
5498 ioc->facts.ReplyQueueDepth);
5500 len += sprintf(buf+len, " MaxDevices = %d\n",
5501 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
5502 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
5505 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
5506 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
5508 ioc->facts.NumberOfPorts);
5509 if (ioc->bus_type == FC) {
5510 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
5511 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5512 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
5513 a[5], a[4], a[3], a[2], a[1], a[0]);
5515 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
5516 ioc->fc_port_page0[p].WWNN.High,
5517 ioc->fc_port_page0[p].WWNN.Low,
5518 ioc->fc_port_page0[p].WWPN.High,
5519 ioc->fc_port_page0[p].WWPN.Low);
5523 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5526 #endif /* CONFIG_PROC_FS } */
5528 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5530 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
5533 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
5534 sprintf(buf, " (Exp %02d%02d)",
5535 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
5536 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
5539 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
5540 strcat(buf, " [MDBG]");
5544 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5546 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
5547 * @ioc: Pointer to MPT_ADAPTER structure
5548 * @buffer: Pointer to buffer where IOC summary info should be written
5549 * @size: Pointer to number of bytes we wrote (set by this routine)
5550 * @len: Offset at which to start writing in buffer
5551 * @showlan: Display LAN stuff?
5553 * This routine writes (english readable) ASCII text, which represents
5554 * a summary of IOC information, to a buffer.
5557 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
5562 mpt_get_fw_exp_ver(expVer, ioc);
5565 * Shorter summary of attached ioc's...
5567 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
5570 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
5571 ioc->facts.FWVersion.Word,
5573 ioc->facts.NumberOfPorts,
5576 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
5577 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5578 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
5579 a[5], a[4], a[3], a[2], a[1], a[0]);
5582 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
5585 y += sprintf(buffer+len+y, " (disabled)");
5587 y += sprintf(buffer+len+y, "\n");
5592 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5596 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5598 * mpt_HardResetHandler - Generic reset handler
5599 * @ioc: Pointer to MPT_ADAPTER structure
5600 * @sleepFlag: Indicates if sleep or schedule must be called.
5602 * Issues SCSI Task Management call based on input arg values.
5603 * If TaskMgmt fails, returns associated SCSI request.
5605 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
5606 * or a non-interrupt thread. In the former, must not call schedule().
5608 * Note: A return of -1 is a FATAL error case, as it means a
5609 * FW reload/initialization failed.
5611 * Returns 0 for SUCCESS or -1 if FAILED.
5614 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
5617 unsigned long flags;
5619 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name));
5621 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
5622 printk("MF count 0x%x !\n", ioc->mfcnt);
5625 /* Reset the adapter. Prevent more than 1 call to
5626 * mpt_do_ioc_recovery at any instant in time.
5628 spin_lock_irqsave(&ioc->diagLock, flags);
5629 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
5630 spin_unlock_irqrestore(&ioc->diagLock, flags);
5633 ioc->diagPending = 1;
5635 spin_unlock_irqrestore(&ioc->diagLock, flags);
5637 /* FIXME: If do_ioc_recovery fails, repeat....
5640 /* The SCSI driver needs to adjust timeouts on all current
5641 * commands prior to the diagnostic reset being issued.
5642 * Prevents timeouts occurring during a diagnostic reset...very bad.
5643 * For all other protocol drivers, this is a no-op.
5649 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5650 if (MptResetHandlers[ii]) {
5651 dtmprintk((MYIOC_s_INFO_FMT "Calling IOC reset_setup handler #%d\n",
5653 r += mpt_signal_reset(ii, ioc, MPT_IOC_SETUP_RESET);
5655 dtmprintk((MYIOC_s_INFO_FMT "Calling alt-%s setup reset handler #%d\n",
5656 ioc->name, ioc->alt_ioc->name, ii));
5657 r += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_SETUP_RESET);
5663 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
5664 printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
5669 ioc->alt_ioc->reload_fw = 0;
5671 spin_lock_irqsave(&ioc->diagLock, flags);
5672 ioc->diagPending = 0;
5674 ioc->alt_ioc->diagPending = 0;
5675 spin_unlock_irqrestore(&ioc->diagLock, flags);
5677 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
5682 # define EVENT_DESCR_STR_SZ 100
5684 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5686 EventDescriptionStr(u8 event, u32 evData0, char *evStr)
5691 case MPI_EVENT_NONE:
5694 case MPI_EVENT_LOG_DATA:
5697 case MPI_EVENT_STATE_CHANGE:
5698 ds = "State Change";
5700 case MPI_EVENT_UNIT_ATTENTION:
5701 ds = "Unit Attention";
5703 case MPI_EVENT_IOC_BUS_RESET:
5704 ds = "IOC Bus Reset";
5706 case MPI_EVENT_EXT_BUS_RESET:
5707 ds = "External Bus Reset";
5709 case MPI_EVENT_RESCAN:
5710 ds = "Bus Rescan Event";
5711 /* Ok, do we need to do anything here? As far as
5712 I can tell, this is when a new device gets added
5715 case MPI_EVENT_LINK_STATUS_CHANGE:
5716 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
5717 ds = "Link Status(FAILURE) Change";
5719 ds = "Link Status(ACTIVE) Change";
5721 case MPI_EVENT_LOOP_STATE_CHANGE:
5722 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
5723 ds = "Loop State(LIP) Change";
5724 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
5725 ds = "Loop State(LPE) Change"; /* ??? */
5727 ds = "Loop State(LPB) Change"; /* ??? */
5729 case MPI_EVENT_LOGOUT:
5732 case MPI_EVENT_EVENT_CHANGE:
5738 case MPI_EVENT_INTEGRATED_RAID:
5740 u8 ReasonCode = (u8)(evData0 >> 16);
5741 switch (ReasonCode) {
5742 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
5743 ds = "Integrated Raid: Volume Created";
5745 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
5746 ds = "Integrated Raid: Volume Deleted";
5748 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
5749 ds = "Integrated Raid: Volume Settings Changed";
5751 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
5752 ds = "Integrated Raid: Volume Status Changed";
5754 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
5755 ds = "Integrated Raid: Volume Physdisk Changed";
5757 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
5758 ds = "Integrated Raid: Physdisk Created";
5760 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
5761 ds = "Integrated Raid: Physdisk Deleted";
5763 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
5764 ds = "Integrated Raid: Physdisk Settings Changed";
5766 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
5767 ds = "Integrated Raid: Physdisk Status Changed";
5769 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
5770 ds = "Integrated Raid: Domain Validation Needed";
5772 case MPI_EVENT_RAID_RC_SMART_DATA :
5773 ds = "Integrated Raid; Smart Data";
5775 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
5776 ds = "Integrated Raid: Replace Action Started";
5779 ds = "Integrated Raid";
5784 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
5785 ds = "SCSI Device Status Change";
5787 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
5789 u8 id = (u8)(evData0);
5790 u8 ReasonCode = (u8)(evData0 >> 16);
5791 switch (ReasonCode) {
5792 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
5793 snprintf(evStr, EVENT_DESCR_STR_SZ,
5794 "SAS Device Status Change: Added: id=%d", id);
5796 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
5797 snprintf(evStr, EVENT_DESCR_STR_SZ,
5798 "SAS Device Status Change: Deleted: id=%d", id);
5800 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
5801 snprintf(evStr, EVENT_DESCR_STR_SZ,
5802 "SAS Device Status Change: SMART Data: id=%d",
5805 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
5806 snprintf(evStr, EVENT_DESCR_STR_SZ,
5807 "SAS Device Status Change: No Persistancy: id=%d", id);
5809 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
5810 snprintf(evStr, EVENT_DESCR_STR_SZ,
5811 "SAS Device Status Change: Internal Device Reset : id=%d", id);
5813 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
5814 snprintf(evStr, EVENT_DESCR_STR_SZ,
5815 "SAS Device Status Change: Internal Task Abort : id=%d", id);
5817 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
5818 snprintf(evStr, EVENT_DESCR_STR_SZ,
5819 "SAS Device Status Change: Internal Abort Task Set : id=%d", id);
5821 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
5822 snprintf(evStr, EVENT_DESCR_STR_SZ,
5823 "SAS Device Status Change: Internal Clear Task Set : id=%d", id);
5825 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
5826 snprintf(evStr, EVENT_DESCR_STR_SZ,
5827 "SAS Device Status Change: Internal Query Task : id=%d", id);
5830 snprintf(evStr, EVENT_DESCR_STR_SZ,
5831 "SAS Device Status Change: Unknown: id=%d", id);
5836 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
5837 ds = "Bus Timer Expired";
5839 case MPI_EVENT_QUEUE_FULL:
5842 case MPI_EVENT_SAS_SES:
5843 ds = "SAS SES Event";
5845 case MPI_EVENT_PERSISTENT_TABLE_FULL:
5846 ds = "Persistent Table Full";
5848 case MPI_EVENT_SAS_PHY_LINK_STATUS:
5850 u8 LinkRates = (u8)(evData0 >> 8);
5851 u8 PhyNumber = (u8)(evData0);
5852 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
5853 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
5854 switch (LinkRates) {
5855 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
5856 snprintf(evStr, EVENT_DESCR_STR_SZ,
5857 "SAS PHY Link Status: Phy=%d:"
5858 " Rate Unknown",PhyNumber);
5860 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
5861 snprintf(evStr, EVENT_DESCR_STR_SZ,
5862 "SAS PHY Link Status: Phy=%d:"
5863 " Phy Disabled",PhyNumber);
5865 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
5866 snprintf(evStr, EVENT_DESCR_STR_SZ,
5867 "SAS PHY Link Status: Phy=%d:"
5868 " Failed Speed Nego",PhyNumber);
5870 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
5871 snprintf(evStr, EVENT_DESCR_STR_SZ,
5872 "SAS PHY Link Status: Phy=%d:"
5873 " Sata OOB Completed",PhyNumber);
5875 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
5876 snprintf(evStr, EVENT_DESCR_STR_SZ,
5877 "SAS PHY Link Status: Phy=%d:"
5878 " Rate 1.5 Gbps",PhyNumber);
5880 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
5881 snprintf(evStr, EVENT_DESCR_STR_SZ,
5882 "SAS PHY Link Status: Phy=%d:"
5883 " Rate 3.0 Gpbs",PhyNumber);
5886 snprintf(evStr, EVENT_DESCR_STR_SZ,
5887 "SAS PHY Link Status: Phy=%d", PhyNumber);
5892 case MPI_EVENT_SAS_DISCOVERY_ERROR:
5893 ds = "SAS Discovery Error";
5895 case MPI_EVENT_IR_RESYNC_UPDATE:
5897 u8 resync_complete = (u8)(evData0 >> 16);
5898 snprintf(evStr, EVENT_DESCR_STR_SZ,
5899 "IR Resync Update: Complete = %d:",resync_complete);
5904 u8 ReasonCode = (u8)(evData0 >> 16);
5905 switch (ReasonCode) {
5906 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
5907 ds = "IR2: LD State Changed";
5909 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
5910 ds = "IR2: PD State Changed";
5912 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
5913 ds = "IR2: Bad Block Table Full";
5915 case MPI_EVENT_IR2_RC_PD_INSERTED:
5916 ds = "IR2: PD Inserted";
5918 case MPI_EVENT_IR2_RC_PD_REMOVED:
5919 ds = "IR2: PD Removed";
5921 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
5922 ds = "IR2: Foreign CFG Detected";
5924 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
5925 ds = "IR2: Rebuild Medium Error";
5933 case MPI_EVENT_SAS_DISCOVERY:
5936 ds = "SAS Discovery: Start";
5938 ds = "SAS Discovery: Stop";
5941 case MPI_EVENT_LOG_ENTRY_ADDED:
5942 ds = "SAS Log Entry Added";
5946 * MPT base "custom" events may be added here...
5953 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
5956 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5958 * ProcessEventNotification - Route EventNotificationReply to all event handlers
5959 * @ioc: Pointer to MPT_ADAPTER structure
5960 * @pEventReply: Pointer to EventNotification reply frame
5961 * @evHandlers: Pointer to integer, number of event handlers
5963 * Routes a received EventNotificationReply to all currently registered
5965 * Returns sum of event handlers return values.
5968 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
5976 char evStr[EVENT_DESCR_STR_SZ];
5980 * Do platform normalization of values
5982 event = le32_to_cpu(pEventReply->Event) & 0xFF;
5983 // evCtx = le32_to_cpu(pEventReply->EventContext);
5984 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
5986 evData0 = le32_to_cpu(pEventReply->Data[0]);
5989 EventDescriptionStr(event, evData0, evStr);
5990 devtprintk((MYIOC_s_INFO_FMT "MPT event:(%02Xh) : %s\n",
5995 #if defined(MPT_DEBUG) || defined(MPT_DEBUG_VERBOSE_EVENTS)
5996 printk(KERN_INFO MYNAM ": Event data:\n" KERN_INFO);
5997 for (ii = 0; ii < evDataLen; ii++)
5998 printk(" %08x", le32_to_cpu(pEventReply->Data[ii]));
6003 * Do general / base driver event processing
6006 case MPI_EVENT_EVENT_CHANGE: /* 0A */
6008 u8 evState = evData0 & 0xFF;
6010 /* CHECKME! What if evState unexpectedly says OFF (0)? */
6012 /* Update EventState field in cached IocFacts */
6013 if (ioc->facts.Function) {
6014 ioc->facts.EventState = evState;
6018 case MPI_EVENT_INTEGRATED_RAID:
6019 mptbase_raid_process_event_data(ioc,
6020 (MpiEventDataRaid_t *)pEventReply->Data);
6027 * Should this event be logged? Events are written sequentially.
6028 * When buffer is full, start again at the top.
6030 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
6033 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
6035 ioc->events[idx].event = event;
6036 ioc->events[idx].eventContext = ioc->eventContext;
6038 for (ii = 0; ii < 2; ii++) {
6040 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
6042 ioc->events[idx].data[ii] = 0;
6045 ioc->eventContext++;
6050 * Call each currently registered protocol event handler.
6052 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
6053 if (MptEvHandlers[ii]) {
6054 devtverboseprintk((MYIOC_s_INFO_FMT "Routing Event to event handler #%d\n",
6056 r += (*(MptEvHandlers[ii]))(ioc, pEventReply);
6060 /* FIXME? Examine results here? */
6063 * If needed, send (a single) EventAck.
6065 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
6066 devtverboseprintk((MYIOC_s_WARN_FMT
6067 "EventAck required\n",ioc->name));
6068 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
6069 devtverboseprintk((MYIOC_s_WARN_FMT "SendEventAck returned %d\n",
6074 *evHandlers = handlers;
6078 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6080 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
6081 * @ioc: Pointer to MPT_ADAPTER structure
6082 * @log_info: U32 LogInfo reply word from the IOC
6084 * Refer to lsi/mpi_log_fc.h.
6087 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
6089 static char *subcl_str[8] = {
6090 "FCP Initiator", "FCP Target", "LAN", "MPI Message Layer",
6091 "FC Link", "Context Manager", "Invalid Field Offset", "State Change Info"
6093 u8 subcl = (log_info >> 24) & 0x7;
6095 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubCl={%s}\n",
6096 ioc->name, log_info, subcl_str[subcl]);
6099 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6101 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
6102 * @ioc: Pointer to MPT_ADAPTER structure
6103 * @mr: Pointer to MPT reply frame
6104 * @log_info: U32 LogInfo word from the IOC
6106 * Refer to lsi/sp_log.h.
6109 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
6111 u32 info = log_info & 0x00FF0000;
6112 char *desc = "unknown";
6116 desc = "bug! MID not found";
6117 if (ioc->reload_fw == 0)
6122 desc = "Parity Error";
6126 desc = "ASYNC Outbound Overrun";
6130 desc = "SYNC Offset Error";
6138 desc = "Msg In Overflow";
6146 desc = "Outbound DMA Overrun";
6150 desc = "Task Management";
6154 desc = "Device Problem";
6158 desc = "Invalid Phase Change";
6162 desc = "Untagged Table Size";
6167 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
6170 /* strings for sas loginfo */
6171 static char *originator_str[] = {
6176 static char *iop_code_str[] = {
6178 "Invalid SAS Address", /* 01h */
6180 "Invalid Page", /* 03h */
6181 "Diag Message Error", /* 04h */
6182 "Task Terminated", /* 05h */
6183 "Enclosure Management", /* 06h */
6184 "Target Mode" /* 07h */
6186 static char *pl_code_str[] = {
6188 "Open Failure", /* 01h */
6189 "Invalid Scatter Gather List", /* 02h */
6190 "Wrong Relative Offset or Frame Length", /* 03h */
6191 "Frame Transfer Error", /* 04h */
6192 "Transmit Frame Connected Low", /* 05h */
6193 "SATA Non-NCQ RW Error Bit Set", /* 06h */
6194 "SATA Read Log Receive Data Error", /* 07h */
6195 "SATA NCQ Fail All Commands After Error", /* 08h */
6196 "SATA Error in Receive Set Device Bit FIS", /* 09h */
6197 "Receive Frame Invalid Message", /* 0Ah */
6198 "Receive Context Message Valid Error", /* 0Bh */
6199 "Receive Frame Current Frame Error", /* 0Ch */
6200 "SATA Link Down", /* 0Dh */
6201 "Discovery SATA Init W IOS", /* 0Eh */
6202 "Config Invalid Page", /* 0Fh */
6203 "Discovery SATA Init Timeout", /* 10h */
6206 "IO Not Yet Executed", /* 13h */
6207 "IO Executed", /* 14h */
6208 "Persistent Reservation Out Not Affiliation Owner", /* 15h */
6209 "Open Transmit DMA Abort", /* 16h */
6210 "IO Device Missing Delay Retry", /* 17h */
6219 "Enclosure Management" /* 20h */
6222 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6224 * mpt_sas_log_info - Log information returned from SAS IOC.
6225 * @ioc: Pointer to MPT_ADAPTER structure
6226 * @log_info: U32 LogInfo reply word from the IOC
6228 * Refer to lsi/mpi_log_sas.h.
6231 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
6233 union loginfo_type {
6242 union loginfo_type sas_loginfo;
6243 char *code_desc = NULL;
6245 sas_loginfo.loginfo = log_info;
6246 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
6247 (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
6249 if ((sas_loginfo.dw.originator == 0 /*IOP*/) &&
6250 (sas_loginfo.dw.code < sizeof(iop_code_str)/sizeof(char*))) {
6251 code_desc = iop_code_str[sas_loginfo.dw.code];
6252 }else if ((sas_loginfo.dw.originator == 1 /*PL*/) &&
6253 (sas_loginfo.dw.code < sizeof(pl_code_str)/sizeof(char*) )) {
6254 code_desc = pl_code_str[sas_loginfo.dw.code];
6257 if (code_desc != NULL)
6258 printk(MYIOC_s_INFO_FMT
6259 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
6260 " SubCode(0x%04x)\n",
6263 originator_str[sas_loginfo.dw.originator],
6265 sas_loginfo.dw.subcode);
6267 printk(MYIOC_s_INFO_FMT
6268 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
6269 " SubCode(0x%04x)\n",
6272 originator_str[sas_loginfo.dw.originator],
6273 sas_loginfo.dw.code,
6274 sas_loginfo.dw.subcode);
6277 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6279 * mpt_sp_ioc_info - IOC information returned from SCSI Parallel IOC.
6280 * @ioc: Pointer to MPT_ADAPTER structure
6281 * @ioc_status: U32 IOCStatus word from IOC
6282 * @mf: Pointer to MPT request frame
6284 * Refer to lsi/mpi.h.
6287 mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
6289 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
6293 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
6294 desc = "Invalid Function";
6297 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
6301 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
6302 desc = "Invalid SGL";
6305 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
6306 desc = "Internal Error";
6309 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
6313 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
6314 desc = "Insufficient Resources";
6317 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
6318 desc = "Invalid Field";
6321 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
6322 desc = "Invalid State";
6325 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
6326 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
6327 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
6328 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
6329 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
6330 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
6331 /* No message for Config IOCStatus values */
6334 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
6335 /* No message for recovered error
6336 desc = "SCSI Recovered Error";
6340 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
6341 desc = "SCSI Invalid Bus";
6344 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
6345 desc = "SCSI Invalid TargetID";
6348 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
6350 SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
6351 U8 cdb = pScsiReq->CDB[0];
6352 if (cdb != 0x12) { /* Inquiry is issued for device scanning */
6353 desc = "SCSI Device Not There";
6358 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
6359 desc = "SCSI Data Overrun";
6362 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
6363 /* This error is checked in scsi_io_done(). Skip.
6364 desc = "SCSI Data Underrun";
6368 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
6369 desc = "SCSI I/O Data Error";
6372 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
6373 desc = "SCSI Protocol Error";
6376 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
6377 desc = "SCSI Task Terminated";
6380 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
6381 desc = "SCSI Residual Mismatch";
6384 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
6385 desc = "SCSI Task Management Failed";
6388 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
6389 desc = "SCSI IOC Terminated";
6392 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
6393 desc = "SCSI Ext Terminated";
6401 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04x): %s\n", ioc->name, status, desc);
6404 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6405 EXPORT_SYMBOL(mpt_attach);
6406 EXPORT_SYMBOL(mpt_detach);
6408 EXPORT_SYMBOL(mpt_resume);
6409 EXPORT_SYMBOL(mpt_suspend);
6411 EXPORT_SYMBOL(ioc_list);
6412 EXPORT_SYMBOL(mpt_proc_root_dir);
6413 EXPORT_SYMBOL(mpt_register);
6414 EXPORT_SYMBOL(mpt_deregister);
6415 EXPORT_SYMBOL(mpt_event_register);
6416 EXPORT_SYMBOL(mpt_event_deregister);
6417 EXPORT_SYMBOL(mpt_reset_register);
6418 EXPORT_SYMBOL(mpt_reset_deregister);
6419 EXPORT_SYMBOL(mpt_device_driver_register);
6420 EXPORT_SYMBOL(mpt_device_driver_deregister);
6421 EXPORT_SYMBOL(mpt_get_msg_frame);
6422 EXPORT_SYMBOL(mpt_put_msg_frame);
6423 EXPORT_SYMBOL(mpt_free_msg_frame);
6424 EXPORT_SYMBOL(mpt_add_sge);
6425 EXPORT_SYMBOL(mpt_send_handshake_request);
6426 EXPORT_SYMBOL(mpt_verify_adapter);
6427 EXPORT_SYMBOL(mpt_GetIocState);
6428 EXPORT_SYMBOL(mpt_print_ioc_summary);
6429 EXPORT_SYMBOL(mpt_lan_index);
6430 EXPORT_SYMBOL(mpt_stm_index);
6431 EXPORT_SYMBOL(mpt_HardResetHandler);
6432 EXPORT_SYMBOL(mpt_config);
6433 EXPORT_SYMBOL(mpt_findImVolumes);
6434 EXPORT_SYMBOL(mpt_alloc_fw_memory);
6435 EXPORT_SYMBOL(mpt_free_fw_memory);
6436 EXPORT_SYMBOL(mptbase_sas_persist_operation);
6438 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6440 * fusion_init - Fusion MPT base driver initialization routine.
6442 * Returns 0 for success, non-zero for failure.
6449 show_mptmod_ver(my_NAME, my_VERSION);
6450 printk(KERN_INFO COPYRIGHT "\n");
6452 for (i = 0; i < MPT_MAX_PROTOCOL_DRIVERS; i++) {
6453 MptCallbacks[i] = NULL;
6454 MptDriverClass[i] = MPTUNKNOWN_DRIVER;
6455 MptEvHandlers[i] = NULL;
6456 MptResetHandlers[i] = NULL;
6459 /* Register ourselves (mptbase) in order to facilitate
6460 * EventNotification handling.
6462 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
6464 /* Register for hard reset handling callbacks.
6466 if (mpt_reset_register(mpt_base_index, mpt_ioc_reset) == 0) {
6467 dprintk((KERN_INFO MYNAM ": Register for IOC reset notification\n"));
6472 #ifdef CONFIG_PROC_FS
6473 (void) procmpt_create();
6478 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6480 * fusion_exit - Perform driver unload cleanup.
6482 * This routine frees all resources associated with each MPT adapter
6483 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
6489 dexitprintk((KERN_INFO MYNAM ": fusion_exit() called!\n"));
6491 mpt_reset_deregister(mpt_base_index);
6493 #ifdef CONFIG_PROC_FS
6498 module_init(fusion_init);
6499 module_exit(fusion_exit);