2 * linux/drivers/message/fusion/mptbase.c
3 * This is the Fusion MPT base driver which supports multiple
4 * (SCSI + LAN) specialized protocol drivers.
5 * For use with LSI Logic PCI chip/adapter(s)
6 * running LSI Logic Fusion MPT (Message Passing Technology) firmware.
8 * Copyright (c) 1999-2005 LSI Logic Corporation
9 * (mailto:mpt_linux_developer@lsil.com)
12 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; version 2 of the License.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
24 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
25 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
26 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
27 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
28 solely responsible for determining the appropriateness of using and
29 distributing the Program and assumes all risks associated with its
30 exercise of rights under this Agreement, including but not limited to
31 the risks and costs of program errors, damage to or loss of data,
32 programs or equipment, and unavailability or interruption of operations.
34 DISCLAIMER OF LIABILITY
35 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
36 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
38 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
39 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
40 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
41 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
43 You should have received a copy of the GNU General Public License
44 along with this program; if not, write to the Free Software
45 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
47 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
49 #include <linux/config.h>
50 #include <linux/kernel.h>
51 #include <linux/module.h>
52 #include <linux/errno.h>
53 #include <linux/init.h>
54 #include <linux/slab.h>
55 #include <linux/types.h>
56 #include <linux/pci.h>
57 #include <linux/kdev_t.h>
58 #include <linux/blkdev.h>
59 #include <linux/delay.h>
60 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
61 #include <linux/dma-mapping.h>
69 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
70 #define my_NAME "Fusion MPT base driver"
71 #define my_VERSION MPT_LINUX_VERSION_COMMON
72 #define MYNAM "mptbase"
74 MODULE_AUTHOR(MODULEAUTHOR);
75 MODULE_DESCRIPTION(my_NAME);
76 MODULE_LICENSE("GPL");
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, struct pt_regs *r);
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
355 * @r: pt_regs pointer (not used)
357 * This routine is registered via the request_irq() kernel API call,
358 * and handles all interrupts generated from a specific MPT adapter
359 * (also referred to as a IO Controller or IOC).
360 * This routine must clear the interrupt from the adapter and does
361 * so by reading the reply FIFO. Multiple replies may be processed
362 * per single call to this routine.
364 * This routine handles register-level access of the adapter but
365 * dispatches (calls) a protocol-specific callback routine to handle
366 * the protocol-specific details of the MPT request completion.
369 mpt_interrupt(int irq, void *bus_id, struct pt_regs *r)
371 MPT_ADAPTER *ioc = bus_id;
372 u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
374 if (pa == 0xFFFFFFFF)
378 * Drain the reply FIFO!
381 if (pa & MPI_ADDRESS_REPLY_A_BIT)
384 mpt_turbo_reply(ioc, pa);
385 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
386 } while (pa != 0xFFFFFFFF);
391 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
393 * mpt_base_reply - MPT base driver's callback routine; all base driver
394 * "internal" request/reply processing is routed here.
395 * Currently used for EventNotification and EventAck handling.
396 * @ioc: Pointer to MPT_ADAPTER structure
397 * @mf: Pointer to original MPT request frame
398 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
400 * Returns 1 indicating original alloc'd request frame ptr
401 * should be freed, or 0 if it shouldn't.
404 mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
409 dmfprintk((MYIOC_s_INFO_FMT "mpt_base_reply() called\n", ioc->name));
411 #if defined(MPT_DEBUG_MSG_FRAME)
412 if (!(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) {
413 dmfprintk((KERN_INFO MYNAM ": Original request frame (@%p) header\n", mf));
414 DBG_DUMP_REQUEST_FRAME_HDR(mf)
418 func = reply->u.hdr.Function;
419 dmfprintk((MYIOC_s_INFO_FMT "mpt_base_reply, Function=%02Xh\n",
422 if (func == MPI_FUNCTION_EVENT_NOTIFICATION) {
423 EventNotificationReply_t *pEvReply = (EventNotificationReply_t *) reply;
427 results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
428 if (results != evHandlers) {
429 /* CHECKME! Any special handling needed here? */
430 devtverboseprintk((MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
431 ioc->name, evHandlers, results));
435 * Hmmm... It seems that EventNotificationReply is an exception
436 * to the rule of one reply per request.
438 if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) {
440 devtverboseprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p does not return Request frame\n",
441 ioc->name, pEvReply));
443 devtverboseprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
444 ioc->name, pEvReply));
447 #ifdef CONFIG_PROC_FS
448 // LogEvent(ioc, pEvReply);
451 } else if (func == MPI_FUNCTION_EVENT_ACK) {
452 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n",
454 } else if (func == MPI_FUNCTION_CONFIG) {
458 dcprintk((MYIOC_s_INFO_FMT "config_complete (mf=%p,mr=%p)\n",
459 ioc->name, mf, reply));
461 pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *)));
464 /* disable timer and remove from linked list */
465 del_timer(&pCfg->timer);
467 spin_lock_irqsave(&ioc->FreeQlock, flags);
468 list_del(&pCfg->linkage);
469 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
472 * If IOC Status is SUCCESS, save the header
473 * and set the status code to GOOD.
475 pCfg->status = MPT_CONFIG_ERROR;
477 ConfigReply_t *pReply = (ConfigReply_t *)reply;
480 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
481 dcprintk((KERN_NOTICE " IOCStatus=%04xh, IOCLogInfo=%08xh\n",
482 status, le32_to_cpu(pReply->IOCLogInfo)));
484 pCfg->status = status;
485 if (status == MPI_IOCSTATUS_SUCCESS) {
486 if ((pReply->Header.PageType &
487 MPI_CONFIG_PAGETYPE_MASK) ==
488 MPI_CONFIG_PAGETYPE_EXTENDED) {
489 pCfg->cfghdr.ehdr->ExtPageLength =
490 le16_to_cpu(pReply->ExtPageLength);
491 pCfg->cfghdr.ehdr->ExtPageType =
494 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
496 /* If this is a regular header, save PageLength. */
497 /* LMP Do this better so not using a reserved field! */
498 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
499 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
500 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
505 * Wake up the original calling thread
510 } else if (func == MPI_FUNCTION_SAS_IO_UNIT_CONTROL) {
511 /* we should be always getting a reply frame */
512 memcpy(ioc->persist_reply_frame, reply,
513 min(MPT_DEFAULT_FRAME_SIZE,
514 4*reply->u.reply.MsgLength));
515 del_timer(&ioc->persist_timer);
516 ioc->persist_wait_done = 1;
519 printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
524 * Conditionally tell caller to free the original
525 * EventNotification/EventAck/unexpected request frame!
530 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
532 * mpt_register - Register protocol-specific main callback handler.
533 * @cbfunc: callback function pointer
534 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
536 * This routine is called by a protocol-specific driver (SCSI host,
537 * LAN, SCSI target) to register it's reply callback routine. Each
538 * protocol-specific driver must do this before it will be able to
539 * use any IOC resources, such as obtaining request frames.
541 * NOTES: The SCSI protocol driver currently calls this routine thrice
542 * in order to register separate callbacks; one for "normal" SCSI IO;
543 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
545 * Returns a positive integer valued "handle" in the
546 * range (and S.O.D. order) {N,...,7,6,5,...,1} if successful.
547 * Any non-positive return value (including zero!) should be considered
548 * an error by the caller.
551 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
558 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
559 * (slot/handle 0 is reserved!)
561 for (i = MPT_MAX_PROTOCOL_DRIVERS-1; i; i--) {
562 if (MptCallbacks[i] == NULL) {
563 MptCallbacks[i] = cbfunc;
564 MptDriverClass[i] = dclass;
565 MptEvHandlers[i] = NULL;
574 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
576 * mpt_deregister - Deregister a protocol drivers resources.
577 * @cb_idx: previously registered callback handle
579 * Each protocol-specific driver should call this routine when it's
580 * module is unloaded.
583 mpt_deregister(int cb_idx)
585 if ((cb_idx >= 0) && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
586 MptCallbacks[cb_idx] = NULL;
587 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
588 MptEvHandlers[cb_idx] = NULL;
594 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
596 * mpt_event_register - Register protocol-specific event callback
598 * @cb_idx: previously registered (via mpt_register) callback handle
599 * @ev_cbfunc: callback function
601 * This routine can be called by one or more protocol-specific drivers
602 * if/when they choose to be notified of MPT events.
604 * Returns 0 for success.
607 mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc)
609 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
612 MptEvHandlers[cb_idx] = ev_cbfunc;
616 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
618 * mpt_event_deregister - Deregister protocol-specific event callback
620 * @cb_idx: previously registered callback handle
622 * Each protocol-specific driver should call this routine
623 * when it does not (or can no longer) handle events,
624 * or when it's module is unloaded.
627 mpt_event_deregister(int cb_idx)
629 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
632 MptEvHandlers[cb_idx] = NULL;
635 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
637 * mpt_reset_register - Register protocol-specific IOC reset handler.
638 * @cb_idx: previously registered (via mpt_register) callback handle
639 * @reset_func: reset function
641 * This routine can be called by one or more protocol-specific drivers
642 * if/when they choose to be notified of IOC resets.
644 * Returns 0 for success.
647 mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func)
649 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
652 MptResetHandlers[cb_idx] = reset_func;
656 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
658 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
659 * @cb_idx: previously registered callback handle
661 * Each protocol-specific driver should call this routine
662 * when it does not (or can no longer) handle IOC reset handling,
663 * or when it's module is unloaded.
666 mpt_reset_deregister(int cb_idx)
668 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
671 MptResetHandlers[cb_idx] = NULL;
674 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
676 * mpt_device_driver_register - Register device driver hooks
679 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx)
683 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) {
687 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
689 /* call per pci device probe entry point */
690 list_for_each_entry(ioc, &ioc_list, list) {
691 if(dd_cbfunc->probe) {
692 dd_cbfunc->probe(ioc->pcidev,
693 ioc->pcidev->driver->id_table);
700 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
702 * mpt_device_driver_deregister - DeRegister device driver hooks
705 mpt_device_driver_deregister(int cb_idx)
707 struct mpt_pci_driver *dd_cbfunc;
710 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
713 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
715 list_for_each_entry(ioc, &ioc_list, list) {
716 if (dd_cbfunc->remove)
717 dd_cbfunc->remove(ioc->pcidev);
720 MptDeviceDriverHandlers[cb_idx] = NULL;
724 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
726 * mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024)
727 * allocated per MPT adapter.
728 * @handle: Handle of registered MPT protocol driver
729 * @ioc: Pointer to MPT adapter structure
731 * Returns pointer to a MPT request frame or %NULL if none are available
732 * or IOC is not active.
735 mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc)
739 u16 req_idx; /* Request index */
741 /* validate handle and ioc identifier */
745 printk(KERN_WARNING "IOC Not Active! mpt_get_msg_frame returning NULL!\n");
748 /* If interrupts are not attached, do not return a request frame */
752 spin_lock_irqsave(&ioc->FreeQlock, flags);
753 if (!list_empty(&ioc->FreeQ)) {
756 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
757 u.frame.linkage.list);
758 list_del(&mf->u.frame.linkage.list);
759 mf->u.frame.linkage.arg1 = 0;
760 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
761 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
763 req_idx = req_offset / ioc->req_sz;
764 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
765 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
766 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame; /* Default, will be changed if necessary in SG generation */
773 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
777 printk(KERN_WARNING "IOC Active. No free Msg Frames! Count 0x%x Max 0x%x\n", ioc->mfcnt, ioc->req_depth);
779 if (mfcounter == PRINT_MF_COUNT)
780 printk(KERN_INFO "MF Count 0x%x Max 0x%x \n", ioc->mfcnt, ioc->req_depth);
783 dmfprintk((KERN_INFO MYNAM ": %s: mpt_get_msg_frame(%d,%d), got mf=%p\n",
784 ioc->name, handle, ioc->id, mf));
788 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
790 * mpt_put_msg_frame - Send a protocol specific MPT request frame
792 * @handle: Handle of registered MPT protocol driver
793 * @ioc: Pointer to MPT adapter structure
794 * @mf: Pointer to MPT request frame
796 * This routine posts a MPT request frame to the request post FIFO of a
797 * specific MPT adapter.
800 mpt_put_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
804 u16 req_idx; /* Request index */
806 /* ensure values are reset properly! */
807 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
808 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
810 req_idx = req_offset / ioc->req_sz;
811 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
812 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
814 #ifdef MPT_DEBUG_MSG_FRAME
816 u32 *m = mf->u.frame.hwhdr.__hdr;
819 printk(KERN_INFO MYNAM ": %s: About to Put msg frame @ %p:\n" KERN_INFO " ",
821 n = ioc->req_sz/4 - 1;
824 for (ii=0; ii<=n; ii++) {
825 if (ii && ((ii%8)==0))
826 printk("\n" KERN_INFO " ");
827 printk(" %08x", le32_to_cpu(m[ii]));
833 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
834 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]));
835 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
838 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
840 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
841 * @handle: Handle of registered MPT protocol driver
842 * @ioc: Pointer to MPT adapter structure
843 * @mf: Pointer to MPT request frame
845 * This routine places a MPT request frame back on the MPT adapter's
849 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
853 /* Put Request back on FreeQ! */
854 spin_lock_irqsave(&ioc->FreeQlock, flags);
855 mf->u.frame.linkage.arg1 = 0xdeadbeaf; /* signature to know if this mf is freed */
856 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
860 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
863 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
865 * mpt_add_sge - Place a simple SGE at address pAddr.
866 * @pAddr: virtual address for SGE
867 * @flagslength: SGE flags and data transfer length
868 * @dma_addr: Physical address
870 * This routine places a MPT request frame back on the MPT adapter's
874 mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
876 if (sizeof(dma_addr_t) == sizeof(u64)) {
877 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
878 u32 tmp = dma_addr & 0xFFFFFFFF;
880 pSge->FlagsLength = cpu_to_le32(flagslength);
881 pSge->Address.Low = cpu_to_le32(tmp);
882 tmp = (u32) ((u64)dma_addr >> 32);
883 pSge->Address.High = cpu_to_le32(tmp);
886 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
887 pSge->FlagsLength = cpu_to_le32(flagslength);
888 pSge->Address = cpu_to_le32(dma_addr);
892 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
894 * mpt_send_handshake_request - Send MPT request via doorbell
896 * @handle: Handle of registered MPT protocol driver
897 * @ioc: Pointer to MPT adapter structure
898 * @reqBytes: Size of the request in bytes
899 * @req: Pointer to MPT request frame
900 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
902 * This routine is used exclusively to send MptScsiTaskMgmt
903 * requests since they are required to be sent via doorbell handshake.
905 * NOTE: It is the callers responsibility to byte-swap fields in the
906 * request which are greater than 1 byte in size.
908 * Returns 0 for success, non-zero for failure.
911 mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
917 /* State is known to be good upon entering
918 * this function so issue the bus reset
923 * Emulate what mpt_put_msg_frame() does /wrt to sanity
924 * setting cb_idx/req_idx. But ONLY if this request
925 * is in proper (pre-alloc'd) request buffer range...
927 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
928 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
929 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
930 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
931 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;
934 /* Make sure there are no doorbells */
935 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
937 CHIPREG_WRITE32(&ioc->chip->Doorbell,
938 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
939 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
941 /* Wait for IOC doorbell int */
942 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
946 /* Read doorbell and check for active bit */
947 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
950 dhsprintk((KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
953 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
955 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
959 /* Send request via doorbell handshake */
960 req_as_bytes = (u8 *) req;
961 for (ii = 0; ii < reqBytes/4; ii++) {
964 word = ((req_as_bytes[(ii*4) + 0] << 0) |
965 (req_as_bytes[(ii*4) + 1] << 8) |
966 (req_as_bytes[(ii*4) + 2] << 16) |
967 (req_as_bytes[(ii*4) + 3] << 24));
968 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
969 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
975 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
980 /* Make sure there are no doorbells */
981 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
986 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
988 * mpt_host_page_access_control - provides mechanism for the host
989 * driver to control the IOC's Host Page Buffer access.
990 * @ioc: Pointer to MPT adapter structure
991 * @access_control_value: define bits below
993 * Access Control Value - bits[15:12]
995 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
996 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
997 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
999 * Returns 0 for success, non-zero for failure.
1003 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1007 /* return if in use */
1008 if (CHIPREG_READ32(&ioc->chip->Doorbell)
1009 & MPI_DOORBELL_ACTIVE)
1012 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1014 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1015 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1016 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1017 (access_control_value<<12)));
1019 /* Wait for IOC to clear Doorbell Status bit */
1020 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1026 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1028 * mpt_host_page_alloc - allocate system memory for the fw
1029 * If we already allocated memory in past, then resend the same pointer.
1030 * ioc@: Pointer to pointer to IOC adapter
1031 * ioc_init@: Pointer to ioc init config page
1033 * Returns 0 for success, non-zero for failure.
1036 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1040 u32 host_page_buffer_sz=0;
1042 if(!ioc->HostPageBuffer) {
1044 host_page_buffer_sz =
1045 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1047 if(!host_page_buffer_sz)
1048 return 0; /* fw doesn't need any host buffers */
1050 /* spin till we get enough memory */
1051 while(host_page_buffer_sz > 0) {
1053 if((ioc->HostPageBuffer = pci_alloc_consistent(
1055 host_page_buffer_sz,
1056 &ioc->HostPageBuffer_dma)) != NULL) {
1058 dinitprintk((MYIOC_s_INFO_FMT
1059 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1061 ioc->HostPageBuffer,
1062 ioc->HostPageBuffer_dma,
1063 host_page_buffer_sz));
1064 ioc->alloc_total += host_page_buffer_sz;
1065 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1069 host_page_buffer_sz -= (4*1024);
1073 if(!ioc->HostPageBuffer) {
1074 printk(MYIOC_s_ERR_FMT
1075 "Failed to alloc memory for host_page_buffer!\n",
1080 psge = (char *)&ioc_init->HostPageBufferSGE;
1081 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1082 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1083 MPI_SGE_FLAGS_32_BIT_ADDRESSING |
1084 MPI_SGE_FLAGS_HOST_TO_IOC |
1085 MPI_SGE_FLAGS_END_OF_BUFFER;
1086 if (sizeof(dma_addr_t) == sizeof(u64)) {
1087 flags_length |= MPI_SGE_FLAGS_64_BIT_ADDRESSING;
1089 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1090 flags_length |= ioc->HostPageBuffer_sz;
1091 mpt_add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1092 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1097 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1099 * mpt_verify_adapter - Given a unique IOC identifier, set pointer to
1100 * the associated MPT adapter structure.
1101 * @iocid: IOC unique identifier (integer)
1102 * @iocpp: Pointer to pointer to IOC adapter
1104 * Returns iocid and sets iocpp.
1107 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1111 list_for_each_entry(ioc,&ioc_list,list) {
1112 if (ioc->id == iocid) {
1122 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1124 * mpt_attach - Install a PCI intelligent MPT adapter.
1125 * @pdev: Pointer to pci_dev structure
1127 * This routine performs all the steps necessary to bring the IOC of
1128 * a MPT adapter to a OPERATIONAL state. This includes registering
1129 * memory regions, registering the interrupt, and allocating request
1130 * and reply memory pools.
1132 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1135 * Returns 0 for success, non-zero for failure.
1137 * TODO: Add support for polled controllers
1140 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1144 unsigned long mem_phys;
1152 static int mpt_ids = 0;
1153 #ifdef CONFIG_PROC_FS
1154 struct proc_dir_entry *dent, *ent;
1157 if (pci_enable_device(pdev))
1160 dinitprintk((KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1162 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
1163 dprintk((KERN_INFO MYNAM
1164 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n"));
1165 } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
1166 printk(KERN_WARNING MYNAM ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");
1170 if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
1171 dprintk((KERN_INFO MYNAM
1172 ": Using 64 bit consistent mask\n"));
1174 dprintk((KERN_INFO MYNAM
1175 ": Not using 64 bit consistent mask\n"));
1177 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1179 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1182 ioc->alloc_total = sizeof(MPT_ADAPTER);
1183 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1184 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1187 ioc->diagPending = 0;
1188 spin_lock_init(&ioc->diagLock);
1189 spin_lock_init(&ioc->initializing_hba_lock);
1191 /* Initialize the event logging.
1193 ioc->eventTypes = 0; /* None */
1194 ioc->eventContext = 0;
1195 ioc->eventLogSize = 0;
1202 ioc->cached_fw = NULL;
1204 /* Initilize SCSI Config Data structure
1206 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1208 /* Initialize the running configQ head.
1210 INIT_LIST_HEAD(&ioc->configQ);
1212 /* Initialize the fc rport list head.
1214 INIT_LIST_HEAD(&ioc->fc_rports);
1216 /* Find lookup slot. */
1217 INIT_LIST_HEAD(&ioc->list);
1218 ioc->id = mpt_ids++;
1220 mem_phys = msize = 0;
1222 for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1223 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1226 /* Get I/O space! */
1227 port = pci_resource_start(pdev, ii);
1228 psize = pci_resource_len(pdev,ii);
1233 mem_phys = pci_resource_start(pdev, ii);
1234 msize = pci_resource_len(pdev,ii);
1237 ioc->mem_size = msize;
1240 /* Get logical ptr for PciMem0 space */
1241 /*mem = ioremap(mem_phys, msize);*/
1242 mem = ioremap(mem_phys, msize);
1244 printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n");
1249 dinitprintk((KERN_INFO MYNAM ": mem = %p, mem_phys = %lx\n", mem, mem_phys));
1251 dinitprintk((KERN_INFO MYNAM ": facts @ %p, pfacts[0] @ %p\n",
1252 &ioc->facts, &ioc->pfacts[0]));
1254 ioc->mem_phys = mem_phys;
1255 ioc->chip = (SYSIF_REGS __iomem *)mem;
1257 /* Save Port IO values in case we need to do downloadboot */
1259 u8 *pmem = (u8*)port;
1260 ioc->pio_mem_phys = port;
1261 ioc->pio_chip = (SYSIF_REGS __iomem *)pmem;
1264 if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC909) {
1265 ioc->prod_name = "LSIFC909";
1268 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929) {
1269 ioc->prod_name = "LSIFC929";
1272 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919) {
1273 ioc->prod_name = "LSIFC919";
1276 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929X) {
1277 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1279 if (revision < XL_929) {
1280 ioc->prod_name = "LSIFC929X";
1281 /* 929X Chip Fix. Set Split transactions level
1282 * for PCIX. Set MOST bits to zero.
1284 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1286 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1288 ioc->prod_name = "LSIFC929XL";
1289 /* 929XL Chip Fix. Set MMRBC to 0x08.
1291 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1293 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1296 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919X) {
1297 ioc->prod_name = "LSIFC919X";
1299 /* 919X Chip Fix. Set Split transactions level
1300 * for PCIX. Set MOST bits to zero.
1302 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1304 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1306 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC939X) {
1307 ioc->prod_name = "LSIFC939X";
1309 ioc->errata_flag_1064 = 1;
1311 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC949X) {
1312 ioc->prod_name = "LSIFC949X";
1314 ioc->errata_flag_1064 = 1;
1316 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC949E) {
1317 ioc->prod_name = "LSIFC949E";
1320 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {
1321 ioc->prod_name = "LSI53C1030";
1322 ioc->bus_type = SPI;
1323 /* 1030 Chip Fix. Disable Split transactions
1324 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1326 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1327 if (revision < C0_1030) {
1328 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1330 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1333 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_1030_53C1035) {
1334 ioc->prod_name = "LSI53C1035";
1335 ioc->bus_type = SPI;
1337 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064) {
1338 ioc->prod_name = "LSISAS1064";
1339 ioc->bus_type = SAS;
1340 ioc->errata_flag_1064 = 1;
1342 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068) {
1343 ioc->prod_name = "LSISAS1068";
1344 ioc->bus_type = SAS;
1345 ioc->errata_flag_1064 = 1;
1347 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064E) {
1348 ioc->prod_name = "LSISAS1064E";
1349 ioc->bus_type = SAS;
1351 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068E) {
1352 ioc->prod_name = "LSISAS1068E";
1353 ioc->bus_type = SAS;
1355 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
1356 ioc->prod_name = "LSISAS1078";
1357 ioc->bus_type = SAS;
1360 if (ioc->errata_flag_1064)
1361 pci_disable_io_access(pdev);
1363 sprintf(ioc->name, "ioc%d", ioc->id);
1365 spin_lock_init(&ioc->FreeQlock);
1368 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1370 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1372 /* Set lookup ptr. */
1373 list_add_tail(&ioc->list, &ioc_list);
1375 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1377 mpt_detect_bound_ports(ioc, pdev);
1379 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1381 printk(KERN_WARNING MYNAM
1382 ": WARNING - %s did not initialize properly! (%d)\n",
1384 list_del(&ioc->list);
1386 ioc->alt_ioc->alt_ioc = NULL;
1389 pci_set_drvdata(pdev, NULL);
1393 /* call per device driver probe entry point */
1394 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1395 if(MptDeviceDriverHandlers[ii] &&
1396 MptDeviceDriverHandlers[ii]->probe) {
1397 MptDeviceDriverHandlers[ii]->probe(pdev,id);
1401 #ifdef CONFIG_PROC_FS
1403 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1405 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1407 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1409 ent->read_proc = procmpt_iocinfo_read;
1412 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1414 ent->read_proc = procmpt_summary_read;
1423 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1425 * mpt_detach - Remove a PCI intelligent MPT adapter.
1426 * @pdev: Pointer to pci_dev structure
1431 mpt_detach(struct pci_dev *pdev)
1433 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1437 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
1438 remove_proc_entry(pname, NULL);
1439 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
1440 remove_proc_entry(pname, NULL);
1441 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
1442 remove_proc_entry(pname, NULL);
1444 /* call per device driver remove entry point */
1445 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1446 if(MptDeviceDriverHandlers[ii] &&
1447 MptDeviceDriverHandlers[ii]->remove) {
1448 MptDeviceDriverHandlers[ii]->remove(pdev);
1452 /* Disable interrupts! */
1453 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1456 synchronize_irq(pdev->irq);
1458 /* Clear any lingering interrupt */
1459 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1461 CHIPREG_READ32(&ioc->chip->IntStatus);
1463 mpt_adapter_dispose(ioc);
1465 pci_set_drvdata(pdev, NULL);
1468 /**************************************************************************
1472 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1474 * mpt_suspend - Fusion MPT base driver suspend routine.
1479 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
1482 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1484 device_state=pci_choose_state(pdev, state);
1486 printk(MYIOC_s_INFO_FMT
1487 "pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
1488 ioc->name, pdev, pci_name(pdev), device_state);
1490 pci_save_state(pdev);
1492 /* put ioc into READY_STATE */
1493 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
1494 printk(MYIOC_s_ERR_FMT
1495 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
1498 /* disable interrupts */
1499 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1502 /* Clear any lingering interrupt */
1503 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1505 pci_disable_device(pdev);
1506 pci_set_power_state(pdev, device_state);
1511 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1513 * mpt_resume - Fusion MPT base driver resume routine.
1518 mpt_resume(struct pci_dev *pdev)
1520 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1521 u32 device_state = pdev->current_state;
1524 printk(MYIOC_s_INFO_FMT
1525 "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
1526 ioc->name, pdev, pci_name(pdev), device_state);
1528 pci_set_power_state(pdev, 0);
1529 pci_restore_state(pdev);
1530 pci_enable_device(pdev);
1532 /* enable interrupts */
1533 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
1536 printk(MYIOC_s_INFO_FMT
1537 "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1539 (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1540 CHIPREG_READ32(&ioc->chip->Doorbell));
1542 /* bring ioc to operational state */
1543 if ((recovery_state = mpt_do_ioc_recovery(ioc,
1544 MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {
1545 printk(MYIOC_s_INFO_FMT
1546 "pci-resume: Cannot recover, error:[%x]\n",
1547 ioc->name, recovery_state);
1549 printk(MYIOC_s_INFO_FMT
1550 "pci-resume: success\n", ioc->name);
1558 mpt_signal_reset(int index, MPT_ADAPTER *ioc, int reset_phase)
1560 if ((MptDriverClass[index] == MPTSPI_DRIVER &&
1561 ioc->bus_type != SPI) ||
1562 (MptDriverClass[index] == MPTFC_DRIVER &&
1563 ioc->bus_type != FC) ||
1564 (MptDriverClass[index] == MPTSAS_DRIVER &&
1565 ioc->bus_type != SAS))
1566 /* make sure we only call the relevant reset handler
1569 return (MptResetHandlers[index])(ioc, reset_phase);
1572 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1574 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1575 * @ioc: Pointer to MPT adapter structure
1576 * @reason: Event word / reason
1577 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1579 * This routine performs all the steps necessary to bring the IOC
1580 * to a OPERATIONAL state.
1582 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1587 * -1 if failed to get board READY
1588 * -2 if READY but IOCFacts Failed
1589 * -3 if READY but PrimeIOCFifos Failed
1590 * -4 if READY but IOCInit Failed
1593 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1595 int hard_reset_done = 0;
1596 int alt_ioc_ready = 0;
1602 int reset_alt_ioc_active = 0;
1603 int irq_allocated = 0;
1605 printk(KERN_INFO MYNAM ": Initiating %s %s\n",
1606 ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
1608 /* Disable reply interrupts (also blocks FreeQ) */
1609 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1613 if (ioc->alt_ioc->active)
1614 reset_alt_ioc_active = 1;
1616 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1617 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
1618 ioc->alt_ioc->active = 0;
1622 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
1625 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
1626 if (hard_reset_done == -4) {
1627 printk(KERN_WARNING MYNAM ": %s Owned by PEER..skipping!\n",
1630 if (reset_alt_ioc_active && ioc->alt_ioc) {
1631 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1632 dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1633 ioc->alt_ioc->name));
1634 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
1635 ioc->alt_ioc->active = 1;
1639 printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",
1645 /* hard_reset_done = 0 if a soft reset was performed
1646 * and 1 if a hard reset was performed.
1648 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
1649 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
1652 printk(KERN_WARNING MYNAM
1653 ": alt-%s: Not ready WARNING!\n",
1654 ioc->alt_ioc->name);
1657 for (ii=0; ii<5; ii++) {
1658 /* Get IOC facts! Allow 5 retries */
1659 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
1665 dinitprintk((MYIOC_s_INFO_FMT "Retry IocFacts failed rc=%x\n", ioc->name, rc));
1667 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1668 MptDisplayIocCapabilities(ioc);
1671 if (alt_ioc_ready) {
1672 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
1673 dinitprintk((MYIOC_s_INFO_FMT "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
1674 /* Retry - alt IOC was initialized once
1676 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
1679 dinitprintk((MYIOC_s_INFO_FMT "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
1681 reset_alt_ioc_active = 0;
1682 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1683 MptDisplayIocCapabilities(ioc->alt_ioc);
1688 * Device is reset now. It must have de-asserted the interrupt line
1689 * (if it was asserted) and it should be safe to register for the
1692 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1694 if (ioc->pcidev->irq) {
1695 if (mpt_msi_enable && !pci_enable_msi(ioc->pcidev))
1696 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
1698 rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
1699 SA_SHIRQ, ioc->name, ioc);
1701 printk(MYIOC_s_ERR_FMT "Unable to allocate "
1702 "interrupt %d!\n", ioc->name,
1705 pci_disable_msi(ioc->pcidev);
1709 ioc->pci_irq = ioc->pcidev->irq;
1710 pci_set_master(ioc->pcidev); /* ?? */
1711 pci_set_drvdata(ioc->pcidev, ioc);
1712 dprintk((KERN_INFO MYNAM ": %s installed at interrupt "
1713 "%d\n", ioc->name, ioc->pcidev->irq));
1717 /* Prime reply & request queues!
1718 * (mucho alloc's) Must be done prior to
1719 * init as upper addresses are needed for init.
1720 * If fails, continue with alt-ioc processing
1722 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
1725 /* May need to check/upload firmware & data here!
1726 * If fails, continue with alt-ioc processing
1728 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
1731 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
1732 printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
1733 ioc->alt_ioc->name, rc);
1735 reset_alt_ioc_active = 0;
1738 if (alt_ioc_ready) {
1739 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
1741 reset_alt_ioc_active = 0;
1742 printk(KERN_WARNING MYNAM
1743 ": alt-%s: (%d) init failure WARNING!\n",
1744 ioc->alt_ioc->name, rc);
1748 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
1749 if (ioc->upload_fw) {
1750 ddlprintk((MYIOC_s_INFO_FMT
1751 "firmware upload required!\n", ioc->name));
1753 /* Controller is not operational, cannot do upload
1756 rc = mpt_do_upload(ioc, sleepFlag);
1758 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
1760 * Maintain only one pointer to FW memory
1761 * so there will not be two attempt to
1762 * downloadboot onboard dual function
1763 * chips (mpt_adapter_disable,
1766 ioc->cached_fw = NULL;
1767 ddlprintk((MYIOC_s_INFO_FMT ": mpt_upload: alt_%s has cached_fw=%p \n",
1768 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
1771 printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
1779 /* Enable! (reply interrupt) */
1780 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
1784 if (reset_alt_ioc_active && ioc->alt_ioc) {
1785 /* (re)Enable alt-IOC! (reply interrupt) */
1786 dinitprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1787 ioc->alt_ioc->name));
1788 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
1789 ioc->alt_ioc->active = 1;
1792 /* Enable MPT base driver management of EventNotification
1793 * and EventAck handling.
1795 if ((ret == 0) && (!ioc->facts.EventState))
1796 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
1798 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
1799 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
1801 /* Add additional "reason" check before call to GetLanConfigPages
1802 * (combined with GetIoUnitPage2 call). This prevents a somewhat
1803 * recursive scenario; GetLanConfigPages times out, timer expired
1804 * routine calls HardResetHandler, which calls into here again,
1805 * and we try GetLanConfigPages again...
1807 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1808 if (ioc->bus_type == SAS) {
1810 /* clear persistency table */
1811 if(ioc->facts.IOCExceptions &
1812 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
1813 ret = mptbase_sas_persist_operation(ioc,
1814 MPI_SAS_OP_CLEAR_NOT_PRESENT);
1821 mpt_findImVolumes(ioc);
1823 } else if (ioc->bus_type == FC) {
1824 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
1825 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
1827 * Pre-fetch the ports LAN MAC address!
1828 * (LANPage1_t stuff)
1830 (void) GetLanConfigPages(ioc);
1833 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
1834 dprintk((MYIOC_s_INFO_FMT "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
1835 ioc->name, a[5], a[4], a[3], a[2], a[1], a[0] ));
1840 /* Get NVRAM and adapter maximums from SPP 0 and 2
1842 mpt_GetScsiPortSettings(ioc, 0);
1844 /* Get version and length of SDP 1
1846 mpt_readScsiDevicePageHeaders(ioc, 0);
1850 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
1851 mpt_findImVolumes(ioc);
1853 /* Check, and possibly reset, the coalescing value
1855 mpt_read_ioc_pg_1(ioc);
1857 mpt_read_ioc_pg_4(ioc);
1860 GetIoUnitPage2(ioc);
1864 * Call each currently registered protocol IOC reset handler
1865 * with post-reset indication.
1866 * NOTE: If we're doing _IOC_BRINGUP, there can be no
1867 * MptResetHandlers[] registered yet.
1869 if (hard_reset_done) {
1871 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
1872 if ((ret == 0) && MptResetHandlers[ii]) {
1873 dprintk((MYIOC_s_INFO_FMT "Calling IOC post_reset handler #%d\n",
1875 rc += mpt_signal_reset(ii, ioc, MPT_IOC_POST_RESET);
1879 if (alt_ioc_ready && MptResetHandlers[ii]) {
1880 drsprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",
1881 ioc->name, ioc->alt_ioc->name, ii));
1882 rc += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_POST_RESET);
1886 /* FIXME? Examine results here? */
1890 if ((ret != 0) && irq_allocated) {
1891 free_irq(ioc->pci_irq, ioc);
1893 pci_disable_msi(ioc->pcidev);
1898 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1900 * mpt_detect_bound_ports - Search for PCI bus/dev_function
1901 * which matches PCI bus/dev_function (+/-1) for newly discovered 929,
1902 * 929X, 1030 or 1035.
1903 * @ioc: Pointer to MPT adapter structure
1904 * @pdev: Pointer to (struct pci_dev) structure
1906 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
1907 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
1910 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
1912 struct pci_dev *peer=NULL;
1913 unsigned int slot = PCI_SLOT(pdev->devfn);
1914 unsigned int func = PCI_FUNC(pdev->devfn);
1915 MPT_ADAPTER *ioc_srch;
1917 dprintk((MYIOC_s_INFO_FMT "PCI device %s devfn=%x/%x,"
1918 " searching for devfn match on %x or %x\n",
1919 ioc->name, pci_name(pdev), pdev->bus->number,
1920 pdev->devfn, func-1, func+1));
1922 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
1924 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
1929 list_for_each_entry(ioc_srch, &ioc_list, list) {
1930 struct pci_dev *_pcidev = ioc_srch->pcidev;
1931 if (_pcidev == peer) {
1932 /* Paranoia checks */
1933 if (ioc->alt_ioc != NULL) {
1934 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1935 ioc->name, ioc->alt_ioc->name);
1937 } else if (ioc_srch->alt_ioc != NULL) {
1938 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1939 ioc_srch->name, ioc_srch->alt_ioc->name);
1942 dprintk((KERN_INFO MYNAM ": FOUND! binding %s <==> %s\n",
1943 ioc->name, ioc_srch->name));
1944 ioc_srch->alt_ioc = ioc;
1945 ioc->alt_ioc = ioc_srch;
1951 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1953 * mpt_adapter_disable - Disable misbehaving MPT adapter.
1954 * @this: Pointer to MPT adapter structure
1957 mpt_adapter_disable(MPT_ADAPTER *ioc)
1962 if (ioc->cached_fw != NULL) {
1963 ddlprintk((KERN_INFO MYNAM ": mpt_adapter_disable: Pushing FW onto adapter\n"));
1964 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)ioc->cached_fw, NO_SLEEP)) < 0) {
1965 printk(KERN_WARNING MYNAM
1966 ": firmware downloadboot failure (%d)!\n", ret);
1970 /* Disable adapter interrupts! */
1971 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1973 /* Clear any lingering interrupt */
1974 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1976 if (ioc->alloc != NULL) {
1978 dexitprintk((KERN_INFO MYNAM ": %s.free @ %p, sz=%d bytes\n",
1979 ioc->name, ioc->alloc, ioc->alloc_sz));
1980 pci_free_consistent(ioc->pcidev, sz,
1981 ioc->alloc, ioc->alloc_dma);
1982 ioc->reply_frames = NULL;
1983 ioc->req_frames = NULL;
1985 ioc->alloc_total -= sz;
1988 if (ioc->sense_buf_pool != NULL) {
1989 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
1990 pci_free_consistent(ioc->pcidev, sz,
1991 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
1992 ioc->sense_buf_pool = NULL;
1993 ioc->alloc_total -= sz;
1996 if (ioc->events != NULL){
1997 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2000 ioc->alloc_total -= sz;
2003 if (ioc->cached_fw != NULL) {
2004 sz = ioc->facts.FWImageSize;
2005 pci_free_consistent(ioc->pcidev, sz,
2006 ioc->cached_fw, ioc->cached_fw_dma);
2007 ioc->cached_fw = NULL;
2008 ioc->alloc_total -= sz;
2011 kfree(ioc->spi_data.nvram);
2012 kfree(ioc->raid_data.pIocPg3);
2013 ioc->spi_data.nvram = NULL;
2014 ioc->raid_data.pIocPg3 = NULL;
2016 if (ioc->spi_data.pIocPg4 != NULL) {
2017 sz = ioc->spi_data.IocPg4Sz;
2018 pci_free_consistent(ioc->pcidev, sz,
2019 ioc->spi_data.pIocPg4,
2020 ioc->spi_data.IocPg4_dma);
2021 ioc->spi_data.pIocPg4 = NULL;
2022 ioc->alloc_total -= sz;
2025 if (ioc->ReqToChain != NULL) {
2026 kfree(ioc->ReqToChain);
2027 kfree(ioc->RequestNB);
2028 ioc->ReqToChain = NULL;
2031 kfree(ioc->ChainToChain);
2032 ioc->ChainToChain = NULL;
2034 if (ioc->HostPageBuffer != NULL) {
2035 if((ret = mpt_host_page_access_control(ioc,
2036 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2037 printk(KERN_ERR MYNAM
2038 ": %s: host page buffers free failed (%d)!\n",
2041 dexitprintk((KERN_INFO MYNAM ": %s HostPageBuffer free @ %p, sz=%d bytes\n",
2042 ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
2043 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2044 ioc->HostPageBuffer,
2045 ioc->HostPageBuffer_dma);
2046 ioc->HostPageBuffer = NULL;
2047 ioc->HostPageBuffer_sz = 0;
2048 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2052 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2054 * mpt_adapter_dispose - Free all resources associated with a MPT
2056 * @ioc: Pointer to MPT adapter structure
2058 * This routine unregisters h/w resources and frees all alloc'd memory
2059 * associated with a MPT adapter structure.
2062 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2064 int sz_first, sz_last;
2069 sz_first = ioc->alloc_total;
2071 mpt_adapter_disable(ioc);
2073 if (ioc->pci_irq != -1) {
2074 free_irq(ioc->pci_irq, ioc);
2076 pci_disable_msi(ioc->pcidev);
2080 if (ioc->memmap != NULL) {
2081 iounmap(ioc->memmap);
2085 #if defined(CONFIG_MTRR) && 0
2086 if (ioc->mtrr_reg > 0) {
2087 mtrr_del(ioc->mtrr_reg, 0, 0);
2088 dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name));
2092 /* Zap the adapter lookup ptr! */
2093 list_del(&ioc->list);
2095 sz_last = ioc->alloc_total;
2096 dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
2097 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2100 ioc->alt_ioc->alt_ioc = NULL;
2105 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2107 * MptDisplayIocCapabilities - Disply IOC's capacilities.
2108 * @ioc: Pointer to MPT adapter structure
2111 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2115 printk(KERN_INFO "%s: ", ioc->name);
2116 if (ioc->prod_name && strlen(ioc->prod_name) > 3)
2117 printk("%s: ", ioc->prod_name+3);
2118 printk("Capabilities={");
2120 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2121 printk("Initiator");
2125 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2126 printk("%sTarget", i ? "," : "");
2130 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2131 printk("%sLAN", i ? "," : "");
2137 * This would probably evoke more questions than it's worth
2139 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2140 printk("%sLogBusAddr", i ? "," : "");
2148 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2150 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2151 * @ioc: Pointer to MPT_ADAPTER structure
2152 * @force: Force hard KickStart of IOC
2153 * @sleepFlag: Specifies whether the process can sleep
2156 * 1 - DIAG reset and READY
2157 * 0 - READY initially OR soft reset and READY
2158 * -1 - Any failure on KickStart
2159 * -2 - Msg Unit Reset Failed
2160 * -3 - IO Unit Reset Failed
2161 * -4 - IOC owned by a PEER
2164 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2169 int hard_reset_done = 0;
2174 /* Get current [raw] IOC state */
2175 ioc_state = mpt_GetIocState(ioc, 0);
2176 dhsprintk((KERN_INFO MYNAM "::MakeIocReady, %s [raw] state=%08x\n", ioc->name, ioc_state));
2179 * Check to see if IOC got left/stuck in doorbell handshake
2180 * grip of death. If so, hard reset the IOC.
2182 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2184 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2188 /* Is it already READY? */
2189 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
2193 * Check to see if IOC is in FAULT state.
2195 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2197 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2199 printk(KERN_WARNING " FAULT code = %04xh\n",
2200 ioc_state & MPI_DOORBELL_DATA_MASK);
2204 * Hmmm... Did it get left operational?
2206 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2207 dinitprintk((MYIOC_s_INFO_FMT "IOC operational unexpected\n",
2211 * If PCI Peer, exit.
2212 * Else, if no fault conditions are present, issue a MessageUnitReset
2213 * Else, fall through to KickStart case
2215 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2216 dinitprintk((KERN_INFO MYNAM
2217 ": whoinit 0x%x statefault %d force %d\n",
2218 whoinit, statefault, force));
2219 if (whoinit == MPI_WHOINIT_PCI_PEER)
2222 if ((statefault == 0 ) && (force == 0)) {
2223 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2230 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2231 if (hard_reset_done < 0)
2235 * Loop here waiting for IOC to come READY.
2238 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2240 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2241 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2243 * BIOS or previous driver load left IOC in OP state.
2244 * Reset messaging FIFOs.
2246 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2247 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2250 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2252 * Something is wrong. Try to get IOC back
2255 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2256 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2263 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2264 ioc->name, (int)((ii+5)/HZ));
2268 if (sleepFlag == CAN_SLEEP) {
2271 mdelay (1); /* 1 msec delay */
2276 if (statefault < 3) {
2277 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2279 statefault==1 ? "stuck handshake" : "IOC FAULT");
2282 return hard_reset_done;
2285 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2287 * mpt_GetIocState - Get the current state of a MPT adapter.
2288 * @ioc: Pointer to MPT_ADAPTER structure
2289 * @cooked: Request raw or cooked IOC state
2291 * Returns all IOC Doorbell register bits if cooked==0, else just the
2292 * Doorbell bits in MPI_IOC_STATE_MASK.
2295 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2300 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2301 // dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
2302 sc = s & MPI_IOC_STATE_MASK;
2305 ioc->last_state = sc;
2307 return cooked ? sc : s;
2310 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2312 * GetIocFacts - Send IOCFacts request to MPT adapter.
2313 * @ioc: Pointer to MPT_ADAPTER structure
2314 * @sleepFlag: Specifies whether the process can sleep
2315 * @reason: If recovery, only update facts.
2317 * Returns 0 for success, non-zero for failure.
2320 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2322 IOCFacts_t get_facts;
2323 IOCFactsReply_t *facts;
2331 /* IOC *must* NOT be in RESET state! */
2332 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2333 printk(KERN_ERR MYNAM ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
2339 facts = &ioc->facts;
2341 /* Destination (reply area)... */
2342 reply_sz = sizeof(*facts);
2343 memset(facts, 0, reply_sz);
2345 /* Request area (get_facts on the stack right now!) */
2346 req_sz = sizeof(get_facts);
2347 memset(&get_facts, 0, req_sz);
2349 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2350 /* Assert: All other get_facts fields are zero! */
2352 dinitprintk((MYIOC_s_INFO_FMT
2353 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2354 ioc->name, req_sz, reply_sz));
2356 /* No non-zero fields in the get_facts request are greater than
2357 * 1 byte in size, so we can just fire it off as is.
2359 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2360 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2365 * Now byte swap (GRRR) the necessary fields before any further
2366 * inspection of reply contents.
2368 * But need to do some sanity checks on MsgLength (byte) field
2369 * to make sure we don't zero IOC's req_sz!
2371 /* Did we get a valid reply? */
2372 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2373 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2375 * If not been here, done that, save off first WhoInit value
2377 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2378 ioc->FirstWhoInit = facts->WhoInit;
2381 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2382 facts->MsgContext = le32_to_cpu(facts->MsgContext);
2383 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2384 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2385 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2386 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
2387 /* CHECKME! IOCStatus, IOCLogInfo */
2389 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2390 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2393 * FC f/w version changed between 1.1 and 1.2
2394 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2395 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2397 if (facts->MsgVersion < 0x0102) {
2399 * Handle old FC f/w style, convert to new...
2401 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2402 facts->FWVersion.Word =
2403 ((oldv<<12) & 0xFF000000) |
2404 ((oldv<<8) & 0x000FFF00);
2406 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2408 facts->ProductID = le16_to_cpu(facts->ProductID);
2409 facts->CurrentHostMfaHighAddr =
2410 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2411 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2412 facts->CurrentSenseBufferHighAddr =
2413 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2414 facts->CurReplyFrameSize =
2415 le16_to_cpu(facts->CurReplyFrameSize);
2416 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
2419 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2420 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2421 * to 14 in MPI-1.01.0x.
2423 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2424 facts->MsgVersion > 0x0100) {
2425 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2428 sz = facts->FWImageSize;
2433 facts->FWImageSize = sz;
2435 if (!facts->RequestFrameSize) {
2436 /* Something is wrong! */
2437 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2442 r = sz = facts->BlockSize;
2443 vv = ((63 / (sz * 4)) + 1) & 0x03;
2444 ioc->NB_for_64_byte_frame = vv;
2450 ioc->NBShiftFactor = shiftFactor;
2451 dinitprintk((MYIOC_s_INFO_FMT "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2452 ioc->name, vv, shiftFactor, r));
2454 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2456 * Set values for this IOC's request & reply frame sizes,
2457 * and request & reply queue depths...
2459 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2460 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2461 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2462 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2464 dinitprintk((MYIOC_s_INFO_FMT "reply_sz=%3d, reply_depth=%4d\n",
2465 ioc->name, ioc->reply_sz, ioc->reply_depth));
2466 dinitprintk((MYIOC_s_INFO_FMT "req_sz =%3d, req_depth =%4d\n",
2467 ioc->name, ioc->req_sz, ioc->req_depth));
2469 /* Get port facts! */
2470 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2474 printk(MYIOC_s_ERR_FMT
2475 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2476 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2477 RequestFrameSize)/sizeof(u32)));
2484 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2486 * GetPortFacts - Send PortFacts request to MPT adapter.
2487 * @ioc: Pointer to MPT_ADAPTER structure
2488 * @portnum: Port number
2489 * @sleepFlag: Specifies whether the process can sleep
2491 * Returns 0 for success, non-zero for failure.
2494 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2496 PortFacts_t get_pfacts;
2497 PortFactsReply_t *pfacts;
2502 /* IOC *must* NOT be in RESET state! */
2503 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2504 printk(KERN_ERR MYNAM ": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n",
2510 pfacts = &ioc->pfacts[portnum];
2512 /* Destination (reply area)... */
2513 reply_sz = sizeof(*pfacts);
2514 memset(pfacts, 0, reply_sz);
2516 /* Request area (get_pfacts on the stack right now!) */
2517 req_sz = sizeof(get_pfacts);
2518 memset(&get_pfacts, 0, req_sz);
2520 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2521 get_pfacts.PortNumber = portnum;
2522 /* Assert: All other get_pfacts fields are zero! */
2524 dinitprintk((MYIOC_s_INFO_FMT "Sending get PortFacts(%d) request\n",
2525 ioc->name, portnum));
2527 /* No non-zero fields in the get_pfacts request are greater than
2528 * 1 byte in size, so we can just fire it off as is.
2530 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2531 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2535 /* Did we get a valid reply? */
2537 /* Now byte swap the necessary fields in the response. */
2538 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2539 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2540 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2541 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2542 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2543 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2544 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2545 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2546 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2551 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2553 * SendIocInit - Send IOCInit request to MPT adapter.
2554 * @ioc: Pointer to MPT_ADAPTER structure
2555 * @sleepFlag: Specifies whether the process can sleep
2557 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2559 * Returns 0 for success, non-zero for failure.
2562 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2565 MPIDefaultReply_t init_reply;
2571 memset(&ioc_init, 0, sizeof(ioc_init));
2572 memset(&init_reply, 0, sizeof(init_reply));
2574 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2575 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2577 /* If we are in a recovery mode and we uploaded the FW image,
2578 * then this pointer is not NULL. Skip the upload a second time.
2579 * Set this flag if cached_fw set for either IOC.
2581 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
2585 ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n",
2586 ioc->name, ioc->upload_fw, ioc->facts.Flags));
2588 if(ioc->bus_type == SAS)
2589 ioc_init.MaxDevices = ioc->facts.MaxDevices;
2590 else if(ioc->bus_type == FC)
2591 ioc_init.MaxDevices = MPT_MAX_FC_DEVICES;
2593 ioc_init.MaxDevices = MPT_MAX_SCSI_DEVICES;
2594 ioc_init.MaxBuses = MPT_MAX_BUS;
2595 dinitprintk((MYIOC_s_INFO_FMT "facts.MsgVersion=%x\n",
2596 ioc->name, ioc->facts.MsgVersion));
2597 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
2598 // set MsgVersion and HeaderVersion host driver was built with
2599 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
2600 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
2602 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
2603 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
2604 } else if(mpt_host_page_alloc(ioc, &ioc_init))
2607 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
2609 if (sizeof(dma_addr_t) == sizeof(u64)) {
2610 /* Save the upper 32-bits of the request
2611 * (reply) and sense buffers.
2613 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
2614 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2616 /* Force 32-bit addressing */
2617 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
2618 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
2621 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
2622 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
2623 ioc->facts.MaxDevices = ioc_init.MaxDevices;
2624 ioc->facts.MaxBuses = ioc_init.MaxBuses;
2626 dhsprintk((MYIOC_s_INFO_FMT "Sending IOCInit (req @ %p)\n",
2627 ioc->name, &ioc_init));
2629 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
2630 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
2632 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
2636 /* No need to byte swap the multibyte fields in the reply
2637 * since we don't even look at it's contents.
2640 dhsprintk((MYIOC_s_INFO_FMT "Sending PortEnable (req @ %p)\n",
2641 ioc->name, &ioc_init));
2643 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
2644 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
2648 /* YIKES! SUPER IMPORTANT!!!
2649 * Poll IocState until _OPERATIONAL while IOC is doing
2650 * LoopInit and TargetDiscovery!
2653 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
2654 state = mpt_GetIocState(ioc, 1);
2655 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
2656 if (sleepFlag == CAN_SLEEP) {
2663 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
2664 ioc->name, (int)((count+5)/HZ));
2668 state = mpt_GetIocState(ioc, 1);
2671 dinitprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
2677 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2679 * SendPortEnable - Send PortEnable request to MPT adapter port.
2680 * @ioc: Pointer to MPT_ADAPTER structure
2681 * @portnum: Port number to enable
2682 * @sleepFlag: Specifies whether the process can sleep
2684 * Send PortEnable to bring IOC to OPERATIONAL state.
2686 * Returns 0 for success, non-zero for failure.
2689 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2691 PortEnable_t port_enable;
2692 MPIDefaultReply_t reply_buf;
2697 /* Destination... */
2698 reply_sz = sizeof(MPIDefaultReply_t);
2699 memset(&reply_buf, 0, reply_sz);
2701 req_sz = sizeof(PortEnable_t);
2702 memset(&port_enable, 0, req_sz);
2704 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
2705 port_enable.PortNumber = portnum;
2706 /* port_enable.ChainOffset = 0; */
2707 /* port_enable.MsgFlags = 0; */
2708 /* port_enable.MsgContext = 0; */
2710 dinitprintk((MYIOC_s_INFO_FMT "Sending Port(%d)Enable (req @ %p)\n",
2711 ioc->name, portnum, &port_enable));
2713 /* RAID FW may take a long time to enable
2715 if (((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
2716 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI) ||
2717 (ioc->bus_type == SAS)) {
2718 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
2719 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
2720 300 /*seconds*/, sleepFlag);
2722 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
2723 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
2724 30 /*seconds*/, sleepFlag);
2730 * ioc: Pointer to MPT_ADAPTER structure
2731 * size - total FW bytes
2734 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
2737 return; /* use already allocated memory */
2738 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2739 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
2740 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
2742 if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
2743 ioc->alloc_total += size;
2747 * If alt_img is NULL, delete from ioc structure.
2748 * Else, delete a secondary image in same format.
2751 mpt_free_fw_memory(MPT_ADAPTER *ioc)
2755 sz = ioc->facts.FWImageSize;
2756 dinitprintk((KERN_INFO MYNAM "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
2757 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2758 pci_free_consistent(ioc->pcidev, sz,
2759 ioc->cached_fw, ioc->cached_fw_dma);
2760 ioc->cached_fw = NULL;
2766 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2768 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
2769 * @ioc: Pointer to MPT_ADAPTER structure
2770 * @sleepFlag: Specifies whether the process can sleep
2772 * Returns 0 for success, >0 for handshake failure
2773 * <0 for fw upload failure.
2775 * Remark: If bound IOC and a successful FWUpload was performed
2776 * on the bound IOC, the second image is discarded
2777 * and memory is free'd. Both channels must upload to prevent
2778 * IOC from running in degraded mode.
2781 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
2783 u8 request[ioc->req_sz];
2784 u8 reply[sizeof(FWUploadReply_t)];
2785 FWUpload_t *prequest;
2786 FWUploadReply_t *preply;
2787 FWUploadTCSGE_t *ptcsge;
2790 int ii, sz, reply_sz;
2793 /* If the image size is 0, we are done.
2795 if ((sz = ioc->facts.FWImageSize) == 0)
2798 mpt_alloc_fw_memory(ioc, sz);
2800 dinitprintk((KERN_INFO MYNAM ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
2801 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2803 if (ioc->cached_fw == NULL) {
2809 prequest = (FWUpload_t *)&request;
2810 preply = (FWUploadReply_t *)&reply;
2812 /* Destination... */
2813 memset(prequest, 0, ioc->req_sz);
2815 reply_sz = sizeof(reply);
2816 memset(preply, 0, reply_sz);
2818 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
2819 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
2821 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
2822 ptcsge->DetailsLength = 12;
2823 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
2824 ptcsge->ImageSize = cpu_to_le32(sz);
2826 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
2828 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
2829 mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma);
2831 sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
2832 dinitprintk((KERN_INFO MYNAM ": Sending FW Upload (req @ %p) sgeoffset=%d \n",
2833 prequest, sgeoffset));
2834 DBG_DUMP_FW_REQUEST_FRAME(prequest)
2836 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
2837 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
2839 dinitprintk((KERN_INFO MYNAM ": FW Upload completed rc=%x \n", ii));
2841 cmdStatus = -EFAULT;
2843 /* Handshake transfer was complete and successful.
2844 * Check the Reply Frame.
2846 int status, transfer_sz;
2847 status = le16_to_cpu(preply->IOCStatus);
2848 if (status == MPI_IOCSTATUS_SUCCESS) {
2849 transfer_sz = le32_to_cpu(preply->ActualImageSize);
2850 if (transfer_sz == sz)
2854 dinitprintk((MYIOC_s_INFO_FMT ": do_upload cmdStatus=%d \n",
2855 ioc->name, cmdStatus));
2860 ddlprintk((MYIOC_s_INFO_FMT ": fw upload failed, freeing image \n",
2862 mpt_free_fw_memory(ioc);
2868 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2870 * mpt_downloadboot - DownloadBoot code
2871 * @ioc: Pointer to MPT_ADAPTER structure
2872 * @flag: Specify which part of IOC memory is to be uploaded.
2873 * @sleepFlag: Specifies whether the process can sleep
2875 * FwDownloadBoot requires Programmed IO access.
2877 * Returns 0 for success
2878 * -1 FW Image size is 0
2879 * -2 No valid cached_fw Pointer
2880 * <0 for fw upload failure.
2883 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
2885 MpiExtImageHeader_t *pExtImage;
2895 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
2896 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
2898 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2899 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2900 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2901 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2902 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2903 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2905 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
2908 if (sleepFlag == CAN_SLEEP) {
2914 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2915 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
2917 for (count = 0; count < 30; count ++) {
2918 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2919 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
2920 ddlprintk((MYIOC_s_INFO_FMT "RESET_ADAPTER cleared, count=%d\n",
2925 if (sleepFlag == CAN_SLEEP) {
2932 if ( count == 30 ) {
2933 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! "
2934 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
2935 ioc->name, diag0val));
2939 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2940 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2941 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2942 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2943 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2944 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2946 /* Set the DiagRwEn and Disable ARM bits */
2947 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
2949 fwSize = (pFwHeader->ImageSize + 3)/4;
2950 ptrFw = (u32 *) pFwHeader;
2952 /* Write the LoadStartAddress to the DiagRw Address Register
2953 * using Programmed IO
2955 if (ioc->errata_flag_1064)
2956 pci_enable_io_access(ioc->pcidev);
2958 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
2959 ddlprintk((MYIOC_s_INFO_FMT "LoadStart addr written 0x%x \n",
2960 ioc->name, pFwHeader->LoadStartAddress));
2962 ddlprintk((MYIOC_s_INFO_FMT "Write FW Image: 0x%x bytes @ %p\n",
2963 ioc->name, fwSize*4, ptrFw));
2965 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
2968 nextImage = pFwHeader->NextImageHeaderOffset;
2970 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
2972 load_addr = pExtImage->LoadStartAddress;
2974 fwSize = (pExtImage->ImageSize + 3) >> 2;
2975 ptrFw = (u32 *)pExtImage;
2977 ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
2978 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
2979 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
2982 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
2984 nextImage = pExtImage->NextImageHeaderOffset;
2987 /* Write the IopResetVectorRegAddr */
2988 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
2989 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
2991 /* Write the IopResetVectorValue */
2992 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
2993 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
2995 /* Clear the internal flash bad bit - autoincrementing register,
2996 * so must do two writes.
2998 if (ioc->bus_type == SPI) {
3000 * 1030 and 1035 H/W errata, workaround to access
3001 * the ClearFlashBadSignatureBit
3003 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3004 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3005 diagRwData |= 0x40000000;
3006 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3007 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3009 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3010 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3011 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3012 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3015 if (sleepFlag == CAN_SLEEP) {
3022 if (ioc->errata_flag_1064)
3023 pci_disable_io_access(ioc->pcidev);
3025 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3026 ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, "
3027 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3028 ioc->name, diag0val));
3029 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3030 ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
3031 ioc->name, diag0val));
3032 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3034 /* Write 0xFF to reset the sequencer */
3035 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3037 if (ioc->bus_type == SAS) {
3038 ioc_state = mpt_GetIocState(ioc, 0);
3039 if ( (GetIocFacts(ioc, sleepFlag,
3040 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3041 ddlprintk((MYIOC_s_INFO_FMT "GetIocFacts failed: IocState=%x\n",
3042 ioc->name, ioc_state));
3047 for (count=0; count<HZ*20; count++) {
3048 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3049 ddlprintk((MYIOC_s_INFO_FMT "downloadboot successful! (count=%d) IocState=%x\n",
3050 ioc->name, count, ioc_state));
3051 if (ioc->bus_type == SAS) {
3054 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3055 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit failed\n",
3059 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit successful\n",
3063 if (sleepFlag == CAN_SLEEP) {
3069 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! IocState=%x\n",
3070 ioc->name, ioc_state));
3074 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3076 * KickStart - Perform hard reset of MPT adapter.
3077 * @ioc: Pointer to MPT_ADAPTER structure
3078 * @force: Force hard reset
3079 * @sleepFlag: Specifies whether the process can sleep
3081 * This routine places MPT adapter in diagnostic mode via the
3082 * WriteSequence register, and then performs a hard reset of adapter
3083 * via the Diagnostic register.
3085 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3086 * or NO_SLEEP (interrupt thread, use mdelay)
3087 * force - 1 if doorbell active, board fault state
3088 * board operational, IOC_RECOVERY or
3089 * IOC_BRINGUP and there is an alt_ioc.
3093 * 1 - hard reset, READY
3094 * 0 - no reset due to History bit, READY
3095 * -1 - no reset due to History bit but not READY
3096 * OR reset but failed to come READY
3097 * -2 - no reset, could not enter DIAG mode
3098 * -3 - reset but bad FW bit
3101 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3103 int hard_reset_done = 0;
3107 dinitprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
3108 if (ioc->bus_type == SPI) {
3109 /* Always issue a Msg Unit Reset first. This will clear some
3110 * SCSI bus hang conditions.
3112 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3114 if (sleepFlag == CAN_SLEEP) {
3121 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3122 if (hard_reset_done < 0)
3123 return hard_reset_done;
3125 dinitprintk((MYIOC_s_INFO_FMT "Diagnostic reset successful!\n",
3128 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3129 for (cnt=0; cnt<cntdn; cnt++) {
3130 ioc_state = mpt_GetIocState(ioc, 1);
3131 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3132 dinitprintk((MYIOC_s_INFO_FMT "KickStart successful! (cnt=%d)\n",
3134 return hard_reset_done;
3136 if (sleepFlag == CAN_SLEEP) {
3143 printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3144 ioc->name, ioc_state);
3148 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3150 * mpt_diag_reset - Perform hard reset of the adapter.
3151 * @ioc: Pointer to MPT_ADAPTER structure
3152 * @ignore: Set if to honor and clear to ignore
3153 * the reset history bit
3154 * @sleepflag: CAN_SLEEP if called in a non-interrupt thread,
3155 * else set to NO_SLEEP (use mdelay instead)
3157 * This routine places the adapter in diagnostic mode via the
3158 * WriteSequence register and then performs a hard reset of adapter
3159 * via the Diagnostic register. Adapter should be in ready state
3160 * upon successful completion.
3162 * Returns: 1 hard reset successful
3163 * 0 no reset performed because reset history bit set
3164 * -2 enabling diagnostic mode failed
3165 * -3 diagnostic reset failed
3168 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3172 int hard_reset_done = 0;
3178 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3179 drsprintk((MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3180 "address=%p\n", ioc->name, __FUNCTION__,
3181 &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3182 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3183 if (sleepFlag == CAN_SLEEP)
3188 for (count = 0; count < 60; count ++) {
3189 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3190 doorbell &= MPI_IOC_STATE_MASK;
3192 drsprintk((MYIOC_s_INFO_FMT
3193 "looking for READY STATE: doorbell=%x"
3195 ioc->name, doorbell, count));
3196 if (doorbell == MPI_IOC_STATE_READY) {
3201 if (sleepFlag == CAN_SLEEP)
3209 /* Clear any existing interrupts */
3210 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3212 /* Use "Diagnostic reset" method! (only thing available!) */
3213 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3217 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3218 dprintk((MYIOC_s_INFO_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3219 ioc->name, diag0val, diag1val));
3222 /* Do the reset if we are told to ignore the reset history
3223 * or if the reset history is 0
3225 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3226 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3227 /* Write magic sequence to WriteSequence register
3228 * Loop until in diagnostic mode
3230 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3231 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3232 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3233 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3234 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3235 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3238 if (sleepFlag == CAN_SLEEP) {
3246 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3247 ioc->name, diag0val);
3252 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3254 dprintk((MYIOC_s_INFO_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3255 ioc->name, diag0val));
3260 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3261 dprintk((MYIOC_s_INFO_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3262 ioc->name, diag0val, diag1val));
3265 * Disable the ARM (Bug fix)
3268 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3272 * Now hit the reset bit in the Diagnostic register
3273 * (THE BIG HAMMER!) (Clears DRWE bit).
3275 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3276 hard_reset_done = 1;
3277 dprintk((MYIOC_s_INFO_FMT "Diagnostic reset performed\n",
3281 * Call each currently registered protocol IOC reset handler
3282 * with pre-reset indication.
3283 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3284 * MptResetHandlers[] registered yet.
3290 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
3291 if (MptResetHandlers[ii]) {
3292 dprintk((MYIOC_s_INFO_FMT "Calling IOC pre_reset handler #%d\n",
3294 r += mpt_signal_reset(ii, ioc, MPT_IOC_PRE_RESET);
3296 dprintk((MYIOC_s_INFO_FMT "Calling alt-%s pre_reset handler #%d\n",
3297 ioc->name, ioc->alt_ioc->name, ii));
3298 r += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_PRE_RESET);
3302 /* FIXME? Examine results here? */
3305 if (ioc->cached_fw) {
3306 /* If the DownloadBoot operation fails, the
3307 * IOC will be left unusable. This is a fatal error
3308 * case. _diag_reset will return < 0
3310 for (count = 0; count < 30; count ++) {
3311 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3312 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3317 if (sleepFlag == CAN_SLEEP) {
3323 if ((count = mpt_downloadboot(ioc,
3324 (MpiFwHeader_t *)ioc->cached_fw, sleepFlag)) < 0) {
3325 printk(KERN_WARNING MYNAM
3326 ": firmware downloadboot failure (%d)!\n", count);
3330 /* Wait for FW to reload and for board
3331 * to go to the READY state.
3332 * Maximum wait is 60 seconds.
3333 * If fail, no error will check again
3334 * with calling program.
3336 for (count = 0; count < 60; count ++) {
3337 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3338 doorbell &= MPI_IOC_STATE_MASK;
3340 if (doorbell == MPI_IOC_STATE_READY) {
3345 if (sleepFlag == CAN_SLEEP) {
3354 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3357 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3358 dprintk((MYIOC_s_INFO_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3359 ioc->name, diag0val, diag1val));
3362 /* Clear RESET_HISTORY bit! Place board in the
3363 * diagnostic mode to update the diag register.
3365 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3367 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3368 /* Write magic sequence to WriteSequence register
3369 * Loop until in diagnostic mode
3371 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3372 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3373 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3374 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3375 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3376 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3379 if (sleepFlag == CAN_SLEEP) {
3387 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3388 ioc->name, diag0val);
3391 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3393 diag0val &= ~MPI_DIAG_RESET_HISTORY;
3394 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3395 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3396 if (diag0val & MPI_DIAG_RESET_HISTORY) {
3397 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3401 /* Disable Diagnostic Mode
3403 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3405 /* Check FW reload status flags.
3407 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3408 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3409 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3410 ioc->name, diag0val);
3416 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3417 dprintk((MYIOC_s_INFO_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3418 ioc->name, diag0val, diag1val));
3422 * Reset flag that says we've enabled event notification
3424 ioc->facts.EventState = 0;
3427 ioc->alt_ioc->facts.EventState = 0;
3429 return hard_reset_done;
3432 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3434 * SendIocReset - Send IOCReset request to MPT adapter.
3435 * @ioc: Pointer to MPT_ADAPTER structure
3436 * @reset_type: reset type, expected values are
3437 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3439 * Send IOCReset request to the MPT adapter.
3441 * Returns 0 for success, non-zero for failure.
3444 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3450 drsprintk((KERN_INFO MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
3451 ioc->name, reset_type));
3452 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3453 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3456 /* FW ACK'd request, wait for READY state
3459 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
3461 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3465 if (sleepFlag != CAN_SLEEP)
3468 printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
3469 ioc->name, (int)((count+5)/HZ));
3473 if (sleepFlag == CAN_SLEEP) {
3476 mdelay (1); /* 1 msec delay */
3481 * Cleanup all event stuff for this IOC; re-issue EventNotification
3482 * request if needed.
3484 if (ioc->facts.Function)
3485 ioc->facts.EventState = 0;
3490 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3492 * initChainBuffers - Allocate memory for and initialize
3493 * chain buffers, chain buffer control arrays and spinlock.
3494 * @hd: Pointer to MPT_SCSI_HOST structure
3495 * @init: If set, initialize the spin lock.
3498 initChainBuffers(MPT_ADAPTER *ioc)
3501 int sz, ii, num_chain;
3502 int scale, num_sge, numSGE;
3504 /* ReqToChain size must equal the req_depth
3507 if (ioc->ReqToChain == NULL) {
3508 sz = ioc->req_depth * sizeof(int);
3509 mem = kmalloc(sz, GFP_ATOMIC);
3513 ioc->ReqToChain = (int *) mem;
3514 dinitprintk((KERN_INFO MYNAM ": %s ReqToChain alloc @ %p, sz=%d bytes\n",
3515 ioc->name, mem, sz));
3516 mem = kmalloc(sz, GFP_ATOMIC);
3520 ioc->RequestNB = (int *) mem;
3521 dinitprintk((KERN_INFO MYNAM ": %s RequestNB alloc @ %p, sz=%d bytes\n",
3522 ioc->name, mem, sz));
3524 for (ii = 0; ii < ioc->req_depth; ii++) {
3525 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
3528 /* ChainToChain size must equal the total number
3529 * of chain buffers to be allocated.
3532 * Calculate the number of chain buffers needed(plus 1) per I/O
3533 * then multiply the the maximum number of simultaneous cmds
3535 * num_sge = num sge in request frame + last chain buffer
3536 * scale = num sge per chain buffer if no chain element
3538 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3539 if (sizeof(dma_addr_t) == sizeof(u64))
3540 num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3542 num_sge = 1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3544 if (sizeof(dma_addr_t) == sizeof(u64)) {
3545 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3546 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3548 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3549 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3551 dinitprintk((KERN_INFO MYNAM ": %s num_sge=%d numSGE=%d\n",
3552 ioc->name, num_sge, numSGE));
3554 if ( numSGE > MPT_SCSI_SG_DEPTH )
3555 numSGE = MPT_SCSI_SG_DEPTH;
3558 while (numSGE - num_sge > 0) {
3560 num_sge += (scale - 1);
3564 dinitprintk((KERN_INFO MYNAM ": %s Now numSGE=%d num_sge=%d num_chain=%d\n",
3565 ioc->name, numSGE, num_sge, num_chain));
3567 if (ioc->bus_type == SPI)
3568 num_chain *= MPT_SCSI_CAN_QUEUE;
3570 num_chain *= MPT_FC_CAN_QUEUE;
3572 ioc->num_chain = num_chain;
3574 sz = num_chain * sizeof(int);
3575 if (ioc->ChainToChain == NULL) {
3576 mem = kmalloc(sz, GFP_ATOMIC);
3580 ioc->ChainToChain = (int *) mem;
3581 dinitprintk((KERN_INFO MYNAM ": %s ChainToChain alloc @ %p, sz=%d bytes\n",
3582 ioc->name, mem, sz));
3584 mem = (u8 *) ioc->ChainToChain;
3586 memset(mem, 0xFF, sz);
3590 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3592 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
3593 * @ioc: Pointer to MPT_ADAPTER structure
3595 * This routine allocates memory for the MPT reply and request frame
3596 * pools (if necessary), and primes the IOC reply FIFO with
3599 * Returns 0 for success, non-zero for failure.
3602 PrimeIocFifos(MPT_ADAPTER *ioc)
3605 unsigned long flags;
3606 dma_addr_t alloc_dma;
3608 int i, reply_sz, sz, total_size, num_chain;
3610 /* Prime reply FIFO... */
3612 if (ioc->reply_frames == NULL) {
3613 if ( (num_chain = initChainBuffers(ioc)) < 0)
3616 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
3617 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
3618 ioc->name, ioc->reply_sz, ioc->reply_depth));
3619 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d[%x] bytes\n",
3620 ioc->name, reply_sz, reply_sz));
3622 sz = (ioc->req_sz * ioc->req_depth);
3623 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d bytes, RequestDepth=%d\n",
3624 ioc->name, ioc->req_sz, ioc->req_depth));
3625 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d[%x] bytes\n",
3626 ioc->name, sz, sz));
3629 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
3630 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d bytes, ChainDepth=%d\n",
3631 ioc->name, ioc->req_sz, num_chain));
3632 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
3633 ioc->name, sz, sz, num_chain));
3636 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
3638 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
3643 dinitprintk((KERN_INFO MYNAM ": %s.Total alloc @ %p[%p], sz=%d[%x] bytes\n",
3644 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
3646 memset(mem, 0, total_size);
3647 ioc->alloc_total += total_size;
3649 ioc->alloc_dma = alloc_dma;
3650 ioc->alloc_sz = total_size;
3651 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
3652 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3654 dinitprintk((KERN_INFO MYNAM ": %s ReplyBuffers @ %p[%p]\n",
3655 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3657 alloc_dma += reply_sz;
3660 /* Request FIFO - WE manage this! */
3662 ioc->req_frames = (MPT_FRAME_HDR *) mem;
3663 ioc->req_frames_dma = alloc_dma;
3665 dinitprintk((KERN_INFO MYNAM ": %s RequestBuffers @ %p[%p]\n",
3666 ioc->name, mem, (void *)(ulong)alloc_dma));
3668 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3670 #if defined(CONFIG_MTRR) && 0
3672 * Enable Write Combining MTRR for IOC's memory region.
3673 * (at least as much as we can; "size and base must be
3674 * multiples of 4 kiB"
3676 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
3678 MTRR_TYPE_WRCOMB, 1);
3679 dprintk((MYIOC_s_INFO_FMT "MTRR region registered (base:size=%08x:%x)\n",
3680 ioc->name, ioc->req_frames_dma, sz));
3683 for (i = 0; i < ioc->req_depth; i++) {
3684 alloc_dma += ioc->req_sz;
3688 ioc->ChainBuffer = mem;
3689 ioc->ChainBufferDMA = alloc_dma;
3691 dinitprintk((KERN_INFO MYNAM " :%s ChainBuffers @ %p(%p)\n",
3692 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
3694 /* Initialize the free chain Q.
3697 INIT_LIST_HEAD(&ioc->FreeChainQ);
3699 /* Post the chain buffers to the FreeChainQ.
3701 mem = (u8 *)ioc->ChainBuffer;
3702 for (i=0; i < num_chain; i++) {
3703 mf = (MPT_FRAME_HDR *) mem;
3704 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
3708 /* Initialize Request frames linked list
3710 alloc_dma = ioc->req_frames_dma;
3711 mem = (u8 *) ioc->req_frames;
3713 spin_lock_irqsave(&ioc->FreeQlock, flags);
3714 INIT_LIST_HEAD(&ioc->FreeQ);
3715 for (i = 0; i < ioc->req_depth; i++) {
3716 mf = (MPT_FRAME_HDR *) mem;
3718 /* Queue REQUESTs *internally*! */
3719 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
3723 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3725 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3726 ioc->sense_buf_pool =
3727 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
3728 if (ioc->sense_buf_pool == NULL) {
3729 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
3734 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
3735 ioc->alloc_total += sz;
3736 dinitprintk((KERN_INFO MYNAM ": %s.SenseBuffers @ %p[%p]\n",
3737 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
3741 /* Post Reply frames to FIFO
3743 alloc_dma = ioc->alloc_dma;
3744 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffers @ %p[%p]\n",
3745 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3747 for (i = 0; i < ioc->reply_depth; i++) {
3748 /* Write each address to the IOC! */
3749 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
3750 alloc_dma += ioc->reply_sz;
3756 if (ioc->alloc != NULL) {
3758 pci_free_consistent(ioc->pcidev,
3760 ioc->alloc, ioc->alloc_dma);
3761 ioc->reply_frames = NULL;
3762 ioc->req_frames = NULL;
3763 ioc->alloc_total -= sz;
3765 if (ioc->sense_buf_pool != NULL) {
3766 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3767 pci_free_consistent(ioc->pcidev,
3769 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
3770 ioc->sense_buf_pool = NULL;
3775 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3777 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
3778 * from IOC via doorbell handshake method.
3779 * @ioc: Pointer to MPT_ADAPTER structure
3780 * @reqBytes: Size of the request in bytes
3781 * @req: Pointer to MPT request frame
3782 * @replyBytes: Expected size of the reply in bytes
3783 * @u16reply: Pointer to area where reply should be written
3784 * @maxwait: Max wait time for a reply (in seconds)
3785 * @sleepFlag: Specifies whether the process can sleep
3787 * NOTES: It is the callers responsibility to byte-swap fields in the
3788 * request which are greater than 1 byte in size. It is also the
3789 * callers responsibility to byte-swap response fields which are
3790 * greater than 1 byte in size.
3792 * Returns 0 for success, non-zero for failure.
3795 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
3796 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
3798 MPIDefaultReply_t *mptReply;
3803 * Get ready to cache a handshake reply
3805 ioc->hs_reply_idx = 0;
3806 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
3807 mptReply->MsgLength = 0;
3810 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
3811 * then tell IOC that we want to handshake a request of N words.
3812 * (WRITE u32val to Doorbell reg).
3814 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3815 CHIPREG_WRITE32(&ioc->chip->Doorbell,
3816 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
3817 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
3820 * Wait for IOC's doorbell handshake int
3822 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3825 dhsprintk((MYIOC_s_INFO_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
3826 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
3828 /* Read doorbell and check for active bit */
3829 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
3833 * Clear doorbell int (WRITE 0 to IntStatus reg),
3834 * then wait for IOC to ACKnowledge that it's ready for
3835 * our handshake request.
3837 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3838 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3843 u8 *req_as_bytes = (u8 *) req;
3846 * Stuff request words via doorbell handshake,
3847 * with ACK from IOC for each.
3849 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
3850 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
3851 (req_as_bytes[(ii*4) + 1] << 8) |
3852 (req_as_bytes[(ii*4) + 2] << 16) |
3853 (req_as_bytes[(ii*4) + 3] << 24));
3855 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
3856 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3860 dhsprintk((KERN_INFO MYNAM ": Handshake request frame (@%p) header\n", req));
3861 DBG_DUMP_REQUEST_FRAME_HDR(req)
3863 dhsprintk((MYIOC_s_INFO_FMT "HandShake request post done, WaitCnt=%d%s\n",
3864 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
3867 * Wait for completion of doorbell handshake reply from the IOC
3869 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
3872 dhsprintk((MYIOC_s_INFO_FMT "HandShake reply count=%d%s\n",
3873 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
3876 * Copy out the cached reply...
3878 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
3879 u16reply[ii] = ioc->hs_reply[ii];
3887 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3889 * WaitForDoorbellAck - Wait for IOC to clear the IOP_DOORBELL_STATUS bit
3890 * in it's IntStatus register.
3891 * @ioc: Pointer to MPT_ADAPTER structure
3892 * @howlong: How long to wait (in seconds)
3893 * @sleepFlag: Specifies whether the process can sleep
3895 * This routine waits (up to ~2 seconds max) for IOC doorbell
3896 * handshake ACKnowledge.
3898 * Returns a negative value on failure, else wait loop count.
3901 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3907 cntdn = 1000 * howlong;
3909 if (sleepFlag == CAN_SLEEP) {
3911 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3912 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3919 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3920 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3928 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell ACK (count=%d)\n",
3933 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
3934 ioc->name, count, intstat);
3938 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3940 * WaitForDoorbellInt - Wait for IOC to set the HIS_DOORBELL_INTERRUPT bit
3941 * in it's IntStatus register.
3942 * @ioc: Pointer to MPT_ADAPTER structure
3943 * @howlong: How long to wait (in seconds)
3944 * @sleepFlag: Specifies whether the process can sleep
3946 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt.
3948 * Returns a negative value on failure, else wait loop count.
3951 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3957 cntdn = 1000 * howlong;
3958 if (sleepFlag == CAN_SLEEP) {
3960 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3961 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
3968 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3969 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
3977 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
3978 ioc->name, count, howlong));
3982 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
3983 ioc->name, count, intstat);
3987 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3989 * WaitForDoorbellReply - Wait for and capture a IOC handshake reply.
3990 * @ioc: Pointer to MPT_ADAPTER structure
3991 * @howlong: How long to wait (in seconds)
3992 * @sleepFlag: Specifies whether the process can sleep
3994 * This routine polls the IOC for a handshake reply, 16 bits at a time.
3995 * Reply is cached to IOC private area large enough to hold a maximum
3996 * of 128 bytes of reply data.
3998 * Returns a negative value on failure, else size of reply in WORDS.
4001 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4006 u16 *hs_reply = ioc->hs_reply;
4007 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4010 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4013 * Get first two u16's so we can look at IOC's intended reply MsgLength
4016 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4019 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4020 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4021 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4024 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4025 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4029 dhsprintk((MYIOC_s_INFO_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4030 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4031 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4034 * If no error (and IOC said MsgLength is > 0), piece together
4035 * reply 16 bits at a time.
4037 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4038 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4040 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4041 /* don't overflow our IOC hs_reply[] buffer! */
4042 if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
4043 hs_reply[u16cnt] = hword;
4044 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4047 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4049 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4052 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4057 else if (u16cnt != (2 * mptReply->MsgLength)) {
4060 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4065 dhsprintk((MYIOC_s_INFO_FMT "Got Handshake reply:\n", ioc->name));
4066 DBG_DUMP_REPLY_FRAME(mptReply)
4068 dhsprintk((MYIOC_s_INFO_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4069 ioc->name, t, u16cnt/2));
4073 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4075 * GetLanConfigPages - Fetch LANConfig pages.
4076 * @ioc: Pointer to MPT_ADAPTER structure
4078 * Return: 0 for success
4079 * -ENOMEM if no memory available
4080 * -EPERM if not allowed due to ISR context
4081 * -EAGAIN if no msg frames currently available
4082 * -EFAULT for non-successful reply or no reply (timeout)
4085 GetLanConfigPages(MPT_ADAPTER *ioc)
4087 ConfigPageHeader_t hdr;
4089 LANPage0_t *ppage0_alloc;
4090 dma_addr_t page0_dma;
4091 LANPage1_t *ppage1_alloc;
4092 dma_addr_t page1_dma;
4097 /* Get LAN Page 0 header */
4098 hdr.PageVersion = 0;
4101 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4102 cfg.cfghdr.hdr = &hdr;
4104 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4109 if ((rc = mpt_config(ioc, &cfg)) != 0)
4112 if (hdr.PageLength > 0) {
4113 data_sz = hdr.PageLength * 4;
4114 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4117 memset((u8 *)ppage0_alloc, 0, data_sz);
4118 cfg.physAddr = page0_dma;
4119 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4121 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4123 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4124 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4128 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4131 * Normalize endianness of structure data,
4132 * by byte-swapping all > 1 byte fields!
4141 /* Get LAN Page 1 header */
4142 hdr.PageVersion = 0;
4145 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4146 cfg.cfghdr.hdr = &hdr;
4148 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4152 if ((rc = mpt_config(ioc, &cfg)) != 0)
4155 if (hdr.PageLength == 0)
4158 data_sz = hdr.PageLength * 4;
4160 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4162 memset((u8 *)ppage1_alloc, 0, data_sz);
4163 cfg.physAddr = page1_dma;
4164 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4166 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4168 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4169 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4172 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4175 * Normalize endianness of structure data,
4176 * by byte-swapping all > 1 byte fields!
4184 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4186 * mptbase_sas_persist_operation - Perform operation on SAS Persitent Table
4187 * @ioc: Pointer to MPT_ADAPTER structure
4188 * @sas_address: 64bit SAS Address for operation.
4189 * @target_id: specified target for operation
4190 * @bus: specified bus for operation
4191 * @persist_opcode: see below
4193 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4194 * devices not currently present.
4195 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4197 * NOTE: Don't use not this function during interrupt time.
4199 * Returns: 0 for success, non-zero error
4202 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4204 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4206 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
4207 SasIoUnitControlReply_t *sasIoUnitCntrReply;
4208 MPT_FRAME_HDR *mf = NULL;
4209 MPIHeader_t *mpi_hdr;
4212 /* insure garbage is not sent to fw */
4213 switch(persist_opcode) {
4215 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
4216 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
4224 printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode);
4226 /* Get a MF for this command.
4228 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4229 printk("%s: no msg frames!\n",__FUNCTION__);
4233 mpi_hdr = (MPIHeader_t *) mf;
4234 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
4235 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
4236 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
4237 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
4238 sasIoUnitCntrReq->Operation = persist_opcode;
4240 init_timer(&ioc->persist_timer);
4241 ioc->persist_timer.data = (unsigned long) ioc;
4242 ioc->persist_timer.function = mpt_timer_expired;
4243 ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
4244 ioc->persist_wait_done=0;
4245 add_timer(&ioc->persist_timer);
4246 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4247 wait_event(mpt_waitq, ioc->persist_wait_done);
4249 sasIoUnitCntrReply =
4250 (SasIoUnitControlReply_t *)ioc->persist_reply_frame;
4251 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
4252 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4254 sasIoUnitCntrReply->IOCStatus,
4255 sasIoUnitCntrReply->IOCLogInfo);
4259 printk("%s: success\n",__FUNCTION__);
4263 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4266 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
4267 MpiEventDataRaid_t * pRaidEventData)
4276 volume = pRaidEventData->VolumeID;
4277 reason = pRaidEventData->ReasonCode;
4278 disk = pRaidEventData->PhysDiskNum;
4279 status = le32_to_cpu(pRaidEventData->SettingsStatus);
4280 flags = (status >> 0) & 0xff;
4281 state = (status >> 8) & 0xff;
4283 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
4287 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
4288 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
4289 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
4290 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d\n",
4293 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
4298 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4299 printk(MYIOC_s_INFO_FMT " volume has been created\n",
4303 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4305 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
4309 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
4310 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
4314 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4315 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
4317 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
4319 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
4321 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
4324 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
4326 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
4327 ? ", quiesced" : "",
4328 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
4329 ? ", resync in progress" : "" );
4332 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
4333 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
4337 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4338 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
4342 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4343 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
4347 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
4348 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
4352 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4353 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
4355 state == MPI_PHYSDISK0_STATUS_ONLINE
4357 : state == MPI_PHYSDISK0_STATUS_MISSING
4359 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
4361 : state == MPI_PHYSDISK0_STATUS_FAILED
4363 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
4365 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
4366 ? "offline requested"
4367 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
4368 ? "failed requested"
4369 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
4372 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
4373 ? ", out of sync" : "",
4374 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
4375 ? ", quiesced" : "" );
4378 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
4379 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
4383 case MPI_EVENT_RAID_RC_SMART_DATA:
4384 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
4385 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
4388 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
4389 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
4395 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4397 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4398 * @ioc: Pointer to MPT_ADAPTER structure
4400 * Returns: 0 for success
4401 * -ENOMEM if no memory available
4402 * -EPERM if not allowed due to ISR context
4403 * -EAGAIN if no msg frames currently available
4404 * -EFAULT for non-successful reply or no reply (timeout)
4407 GetIoUnitPage2(MPT_ADAPTER *ioc)
4409 ConfigPageHeader_t hdr;
4411 IOUnitPage2_t *ppage_alloc;
4412 dma_addr_t page_dma;
4416 /* Get the page header */
4417 hdr.PageVersion = 0;
4420 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4421 cfg.cfghdr.hdr = &hdr;
4423 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4428 if ((rc = mpt_config(ioc, &cfg)) != 0)
4431 if (hdr.PageLength == 0)
4434 /* Read the config page */
4435 data_sz = hdr.PageLength * 4;
4437 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4439 memset((u8 *)ppage_alloc, 0, data_sz);
4440 cfg.physAddr = page_dma;
4441 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4443 /* If Good, save data */
4444 if ((rc = mpt_config(ioc, &cfg)) == 0)
4445 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4447 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4453 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4454 /* mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4455 * @ioc: Pointer to a Adapter Strucutre
4456 * @portnum: IOC port number
4458 * Return: -EFAULT if read of config page header fails
4460 * If read of SCSI Port Page 0 fails,
4461 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4462 * Adapter settings: async, narrow
4464 * If read of SCSI Port Page 2 fails,
4465 * Adapter settings valid
4466 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4471 * CHECK - what type of locking mechanisms should be used????
4474 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4479 ConfigPageHeader_t header;
4485 if (!ioc->spi_data.nvram) {
4488 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4489 mem = kmalloc(sz, GFP_ATOMIC);
4493 ioc->spi_data.nvram = (int *) mem;
4495 dprintk((MYIOC_s_INFO_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4496 ioc->name, ioc->spi_data.nvram, sz));
4499 /* Invalidate NVRAM information
4501 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4502 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4505 /* Read SPP0 header, allocate memory, then read page.
4507 header.PageVersion = 0;
4508 header.PageLength = 0;
4509 header.PageNumber = 0;
4510 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4511 cfg.cfghdr.hdr = &header;
4513 cfg.pageAddr = portnum;
4514 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4516 cfg.timeout = 0; /* use default */
4517 if (mpt_config(ioc, &cfg) != 0)
4520 if (header.PageLength > 0) {
4521 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4523 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4524 cfg.physAddr = buf_dma;
4525 if (mpt_config(ioc, &cfg) != 0) {
4526 ioc->spi_data.maxBusWidth = MPT_NARROW;
4527 ioc->spi_data.maxSyncOffset = 0;
4528 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4529 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4531 ddvprintk((MYIOC_s_INFO_FMT "Unable to read PortPage0 minSyncFactor=%x\n",
4532 ioc->name, ioc->spi_data.minSyncFactor));
4534 /* Save the Port Page 0 data
4536 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
4537 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4538 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4540 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
4541 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4542 ddvprintk((KERN_INFO MYNAM " :%s noQas due to Capabilities=%x\n",
4543 ioc->name, pPP0->Capabilities));
4545 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4546 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4548 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4549 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4550 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4551 ddvprintk((MYIOC_s_INFO_FMT "PortPage0 minSyncFactor=%x\n",
4552 ioc->name, ioc->spi_data.minSyncFactor));
4554 ioc->spi_data.maxSyncOffset = 0;
4555 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4558 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4560 /* Update the minSyncFactor based on bus type.
4562 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4563 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
4565 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
4566 ioc->spi_data.minSyncFactor = MPT_ULTRA;
4567 ddvprintk((MYIOC_s_INFO_FMT "HVD or SE detected, minSyncFactor=%x\n",
4568 ioc->name, ioc->spi_data.minSyncFactor));
4573 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4578 /* SCSI Port Page 2 - Read the header then the page.
4580 header.PageVersion = 0;
4581 header.PageLength = 0;
4582 header.PageNumber = 2;
4583 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4584 cfg.cfghdr.hdr = &header;
4586 cfg.pageAddr = portnum;
4587 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4589 if (mpt_config(ioc, &cfg) != 0)
4592 if (header.PageLength > 0) {
4593 /* Allocate memory and read SCSI Port Page 2
4595 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4597 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
4598 cfg.physAddr = buf_dma;
4599 if (mpt_config(ioc, &cfg) != 0) {
4600 /* Nvram data is left with INVALID mark
4604 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
4605 MpiDeviceInfo_t *pdevice = NULL;
4608 * Save "Set to Avoid SCSI Bus Resets" flag
4610 ioc->spi_data.bus_reset =
4611 (le32_to_cpu(pPP2->PortFlags) &
4612 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
4615 /* Save the Port Page 2 data
4616 * (reformat into a 32bit quantity)
4618 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
4619 ioc->spi_data.PortFlags = data;
4620 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4621 pdevice = &pPP2->DeviceSettings[ii];
4622 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
4623 (pdevice->SyncFactor << 8) | pdevice->Timeout;
4624 ioc->spi_data.nvram[ii] = data;
4628 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4632 /* Update Adapter limits with those from NVRAM
4633 * Comment: Don't need to do this. Target performance
4634 * parameters will never exceed the adapters limits.
4640 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4641 /* mpt_readScsiDevicePageHeaders - save version and length of SDP1
4642 * @ioc: Pointer to a Adapter Strucutre
4643 * @portnum: IOC port number
4645 * Return: -EFAULT if read of config page header fails
4649 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
4652 ConfigPageHeader_t header;
4654 /* Read the SCSI Device Page 1 header
4656 header.PageVersion = 0;
4657 header.PageLength = 0;
4658 header.PageNumber = 1;
4659 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4660 cfg.cfghdr.hdr = &header;
4662 cfg.pageAddr = portnum;
4663 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4666 if (mpt_config(ioc, &cfg) != 0)
4669 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
4670 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
4672 header.PageVersion = 0;
4673 header.PageLength = 0;
4674 header.PageNumber = 0;
4675 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4676 if (mpt_config(ioc, &cfg) != 0)
4679 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
4680 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
4682 dcprintk((MYIOC_s_INFO_FMT "Headers: 0: version %d length %d\n",
4683 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
4685 dcprintk((MYIOC_s_INFO_FMT "Headers: 1: version %d length %d\n",
4686 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
4690 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4692 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
4693 * @ioc: Pointer to a Adapter Strucutre
4694 * @portnum: IOC port number
4698 * -EFAULT if read of config page header fails or data pointer not NULL
4699 * -ENOMEM if pci_alloc failed
4702 mpt_findImVolumes(MPT_ADAPTER *ioc)
4706 ConfigPageIoc2RaidVol_t *pIocRv;
4707 dma_addr_t ioc2_dma;
4709 ConfigPageHeader_t header;
4716 /* Read IOCP2 header then the page.
4718 header.PageVersion = 0;
4719 header.PageLength = 0;
4720 header.PageNumber = 2;
4721 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4722 cfg.cfghdr.hdr = &header;
4725 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4728 if (mpt_config(ioc, &cfg) != 0)
4731 if (header.PageLength == 0)
4734 iocpage2sz = header.PageLength * 4;
4735 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
4739 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4740 cfg.physAddr = ioc2_dma;
4741 if (mpt_config(ioc, &cfg) != 0)
4744 if ( (mem = (u8 *)ioc->raid_data.pIocPg2) == NULL ) {
4745 mem = kmalloc(iocpage2sz, GFP_ATOMIC);
4747 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
4752 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
4754 /* Identify RAID Volume Id's */
4755 nVols = pIoc2->NumActiveVolumes;
4761 /* At least 1 RAID Volume
4763 pIocRv = pIoc2->RaidVolume;
4764 ioc->raid_data.isRaid = 0;
4765 for (jj = 0; jj < nVols; jj++, pIocRv++) {
4766 vid = pIocRv->VolumeID;
4767 vbus = pIocRv->VolumeBus;
4768 vioc = pIocRv->VolumeIOC;
4773 ioc->raid_data.isRaid |= (1 << vid);
4775 /* Error! Always bus 0
4781 /* Identify Hidden Physical Disk Id's */
4782 nPhys = pIoc2->NumActivePhysDisks;
4784 /* No physical disks.
4787 mpt_read_ioc_pg_3(ioc);
4791 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
4797 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
4802 ConfigPageHeader_t header;
4803 dma_addr_t ioc3_dma;
4806 /* Free the old page
4808 kfree(ioc->raid_data.pIocPg3);
4809 ioc->raid_data.pIocPg3 = NULL;
4811 /* There is at least one physical disk.
4812 * Read and save IOC Page 3
4814 header.PageVersion = 0;
4815 header.PageLength = 0;
4816 header.PageNumber = 3;
4817 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4818 cfg.cfghdr.hdr = &header;
4821 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4824 if (mpt_config(ioc, &cfg) != 0)
4827 if (header.PageLength == 0)
4830 /* Read Header good, alloc memory
4832 iocpage3sz = header.PageLength * 4;
4833 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
4837 /* Read the Page and save the data
4838 * into malloc'd memory.
4840 cfg.physAddr = ioc3_dma;
4841 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4842 if (mpt_config(ioc, &cfg) == 0) {
4843 mem = kmalloc(iocpage3sz, GFP_ATOMIC);
4845 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
4846 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
4850 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
4856 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
4860 ConfigPageHeader_t header;
4861 dma_addr_t ioc4_dma;
4864 /* Read and save IOC Page 4
4866 header.PageVersion = 0;
4867 header.PageLength = 0;
4868 header.PageNumber = 4;
4869 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4870 cfg.cfghdr.hdr = &header;
4873 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4876 if (mpt_config(ioc, &cfg) != 0)
4879 if (header.PageLength == 0)
4882 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
4883 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
4884 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
4888 ioc4_dma = ioc->spi_data.IocPg4_dma;
4889 iocpage4sz = ioc->spi_data.IocPg4Sz;
4892 /* Read the Page into dma memory.
4894 cfg.physAddr = ioc4_dma;
4895 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4896 if (mpt_config(ioc, &cfg) == 0) {
4897 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
4898 ioc->spi_data.IocPg4_dma = ioc4_dma;
4899 ioc->spi_data.IocPg4Sz = iocpage4sz;
4901 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
4902 ioc->spi_data.pIocPg4 = NULL;
4907 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
4911 ConfigPageHeader_t header;
4912 dma_addr_t ioc1_dma;
4916 /* Check the Coalescing Timeout in IOC Page 1
4918 header.PageVersion = 0;
4919 header.PageLength = 0;
4920 header.PageNumber = 1;
4921 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4922 cfg.cfghdr.hdr = &header;
4925 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4928 if (mpt_config(ioc, &cfg) != 0)
4931 if (header.PageLength == 0)
4934 /* Read Header good, alloc memory
4936 iocpage1sz = header.PageLength * 4;
4937 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
4941 /* Read the Page and check coalescing timeout
4943 cfg.physAddr = ioc1_dma;
4944 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4945 if (mpt_config(ioc, &cfg) == 0) {
4947 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
4948 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
4949 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
4951 dprintk((MYIOC_s_INFO_FMT "Coalescing Enabled Timeout = %d\n",
4954 if (tmp > MPT_COALESCING_TIMEOUT) {
4955 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
4957 /* Write NVRAM and current
4960 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4961 if (mpt_config(ioc, &cfg) == 0) {
4962 dprintk((MYIOC_s_INFO_FMT "Reset Current Coalescing Timeout to = %d\n",
4963 ioc->name, MPT_COALESCING_TIMEOUT));
4965 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
4966 if (mpt_config(ioc, &cfg) == 0) {
4967 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout to = %d\n",
4968 ioc->name, MPT_COALESCING_TIMEOUT));
4970 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout Failed\n",
4975 dprintk((MYIOC_s_WARN_FMT "Reset of Current Coalescing Timeout Failed!\n",
4981 dprintk((MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
4985 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
4990 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4992 * SendEventNotification - Send EventNotification (on or off) request
4994 * @ioc: Pointer to MPT_ADAPTER structure
4995 * @EvSwitch: Event switch flags
4998 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
5000 EventNotification_t *evnp;
5002 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
5004 devtverboseprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
5008 memset(evnp, 0, sizeof(*evnp));
5010 devtverboseprintk((MYIOC_s_INFO_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
5012 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
5013 evnp->ChainOffset = 0;
5015 evnp->Switch = EvSwitch;
5017 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
5022 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5024 * SendEventAck - Send EventAck request to MPT adapter.
5025 * @ioc: Pointer to MPT_ADAPTER structure
5026 * @evnp: Pointer to original EventNotification request
5029 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
5033 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5034 printk(MYIOC_s_WARN_FMT "Unable to allocate event ACK "
5035 "request frame for Event=%x EventContext=%x EventData=%x!\n",
5036 ioc->name, evnp->Event, le32_to_cpu(evnp->EventContext),
5037 le32_to_cpu(evnp->Data[0]));
5040 memset(pAck, 0, sizeof(*pAck));
5042 dprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name));
5044 pAck->Function = MPI_FUNCTION_EVENT_ACK;
5045 pAck->ChainOffset = 0;
5047 pAck->Event = evnp->Event;
5048 pAck->EventContext = evnp->EventContext;
5050 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
5055 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5057 * mpt_config - Generic function to issue config message
5058 * @ioc - Pointer to an adapter structure
5059 * @cfg - Pointer to a configuration structure. Struct contains
5060 * action, page address, direction, physical address
5061 * and pointer to a configuration page header
5062 * Page header is updated.
5064 * Returns 0 for success
5065 * -EPERM if not allowed due to ISR context
5066 * -EAGAIN if no msg frames currently available
5067 * -EFAULT for non-successful reply or no reply (timeout)
5070 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5073 ConfigExtendedPageHeader_t *pExtHdr = NULL;
5075 unsigned long flags;
5080 /* Prevent calling wait_event() (below), if caller happens
5081 * to be in ISR context, because that is fatal!
5083 in_isr = in_interrupt();
5085 dcprintk((MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
5090 /* Get and Populate a free Frame
5092 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5093 dcprintk((MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
5097 pReq = (Config_t *)mf;
5098 pReq->Action = pCfg->action;
5100 pReq->ChainOffset = 0;
5101 pReq->Function = MPI_FUNCTION_CONFIG;
5103 /* Assume page type is not extended and clear "reserved" fields. */
5104 pReq->ExtPageLength = 0;
5105 pReq->ExtPageType = 0;
5108 for (ii=0; ii < 8; ii++)
5109 pReq->Reserved2[ii] = 0;
5111 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
5112 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
5113 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
5114 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
5116 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5117 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
5118 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
5119 pReq->ExtPageType = pExtHdr->ExtPageType;
5120 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
5122 /* Page Length must be treated as a reserved field for the extended header. */
5123 pReq->Header.PageLength = 0;
5126 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
5128 /* Add a SGE to the config request.
5131 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
5133 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
5135 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5136 flagsLength |= pExtHdr->ExtPageLength * 4;
5138 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
5139 ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action));
5142 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
5144 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
5145 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
5148 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
5150 /* Append pCfg pointer to end of mf
5152 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5154 /* Initalize the timer
5156 init_timer(&pCfg->timer);
5157 pCfg->timer.data = (unsigned long) ioc;
5158 pCfg->timer.function = mpt_timer_expired;
5159 pCfg->wait_done = 0;
5161 /* Set the timer; ensure 10 second minimum */
5162 if (pCfg->timeout < 10)
5163 pCfg->timer.expires = jiffies + HZ*10;
5165 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5167 /* Add to end of Q, set timer and then issue this command */
5168 spin_lock_irqsave(&ioc->FreeQlock, flags);
5169 list_add_tail(&pCfg->linkage, &ioc->configQ);
5170 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5172 add_timer(&pCfg->timer);
5173 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5174 wait_event(mpt_waitq, pCfg->wait_done);
5176 /* mf has been freed - do not access */
5183 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5185 * mpt_timer_expired - Call back for timer process.
5186 * Used only internal config functionality.
5187 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5190 mpt_timer_expired(unsigned long data)
5192 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
5194 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired! \n", ioc->name));
5196 /* Perform a FW reload */
5197 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
5198 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
5200 /* No more processing.
5201 * Hard reset clean-up will wake up
5202 * process and free all resources.
5204 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired complete!\n", ioc->name));
5209 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5211 * mpt_ioc_reset - Base cleanup for hard reset
5212 * @ioc: Pointer to the adapter structure
5213 * @reset_phase: Indicates pre- or post-reset functionality
5215 * Remark: Free's resources with internally generated commands.
5218 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
5221 unsigned long flags;
5223 dprintk((KERN_WARNING MYNAM
5224 ": IOC %s_reset routed to MPT base driver!\n",
5225 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
5226 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
5228 if (reset_phase == MPT_IOC_SETUP_RESET) {
5230 } else if (reset_phase == MPT_IOC_PRE_RESET) {
5231 /* If the internal config Q is not empty -
5232 * delete timer. MF resources will be freed when
5233 * the FIFO's are primed.
5235 spin_lock_irqsave(&ioc->FreeQlock, flags);
5236 list_for_each_entry(pCfg, &ioc->configQ, linkage)
5237 del_timer(&pCfg->timer);
5238 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5243 /* Search the configQ for internal commands.
5244 * Flush the Q, and wake up all suspended threads.
5246 spin_lock_irqsave(&ioc->FreeQlock, flags);
5247 list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
5248 list_del(&pCfg->linkage);
5250 pCfg->status = MPT_CONFIG_ERROR;
5251 pCfg->wait_done = 1;
5252 wake_up(&mpt_waitq);
5254 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5257 return 1; /* currently means nothing really */
5261 #ifdef CONFIG_PROC_FS /* { */
5262 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5264 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5266 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5268 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5270 * Returns 0 for success, non-zero for failure.
5273 procmpt_create(void)
5275 struct proc_dir_entry *ent;
5277 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
5278 if (mpt_proc_root_dir == NULL)
5281 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5283 ent->read_proc = procmpt_summary_read;
5285 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5287 ent->read_proc = procmpt_version_read;
5292 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5294 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5296 * Returns 0 for success, non-zero for failure.
5299 procmpt_destroy(void)
5301 remove_proc_entry("version", mpt_proc_root_dir);
5302 remove_proc_entry("summary", mpt_proc_root_dir);
5303 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
5306 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5308 * procmpt_summary_read - Handle read request from /proc/mpt/summary
5309 * or from /proc/mpt/iocN/summary.
5310 * @buf: Pointer to area to write information
5311 * @start: Pointer to start pointer
5312 * @offset: Offset to start writing
5314 * @eof: Pointer to EOF integer
5317 * Returns number of characters written to process performing the read.
5320 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5330 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5334 list_for_each_entry(ioc, &ioc_list, list) {
5337 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5340 if ((out-buf) >= request)
5347 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5350 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5352 * procmpt_version_read - Handle read request from /proc/mpt/version.
5353 * @buf: Pointer to area to write information
5354 * @start: Pointer to start pointer
5355 * @offset: Offset to start writing
5357 * @eof: Pointer to EOF integer
5360 * Returns number of characters written to process performing the read.
5363 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5366 int scsi, fc, sas, lan, ctl, targ, dmp;
5370 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
5371 len += sprintf(buf+len, " Fusion MPT base driver\n");
5373 scsi = fc = sas = lan = ctl = targ = dmp = 0;
5374 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5376 if (MptCallbacks[ii]) {
5377 switch (MptDriverClass[ii]) {
5379 if (!scsi++) drvname = "SPI host";
5382 if (!fc++) drvname = "FC host";
5385 if (!sas++) drvname = "SAS host";
5388 if (!lan++) drvname = "LAN";
5391 if (!targ++) drvname = "SCSI target";
5394 if (!ctl++) drvname = "ioctl";
5399 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
5403 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5406 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5408 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
5409 * @buf: Pointer to area to write information
5410 * @start: Pointer to start pointer
5411 * @offset: Offset to start writing
5413 * @eof: Pointer to EOF integer
5416 * Returns number of characters written to process performing the read.
5419 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5421 MPT_ADAPTER *ioc = data;
5427 mpt_get_fw_exp_ver(expVer, ioc);
5429 len = sprintf(buf, "%s:", ioc->name);
5430 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
5431 len += sprintf(buf+len, " (f/w download boot flag set)");
5432 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
5433 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
5435 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
5436 ioc->facts.ProductID,
5438 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
5439 if (ioc->facts.FWImageSize)
5440 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
5441 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
5442 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
5443 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
5445 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
5446 ioc->facts.CurrentHostMfaHighAddr);
5447 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
5448 ioc->facts.CurrentSenseBufferHighAddr);
5450 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
5451 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
5453 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
5454 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
5456 * Rounding UP to nearest 4-kB boundary here...
5458 sz = (ioc->req_sz * ioc->req_depth) + 128;
5459 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
5460 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
5461 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
5462 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
5463 4*ioc->facts.RequestFrameSize,
5464 ioc->facts.GlobalCredits);
5466 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
5467 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
5468 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
5469 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
5470 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
5471 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
5472 ioc->facts.CurReplyFrameSize,
5473 ioc->facts.ReplyQueueDepth);
5475 len += sprintf(buf+len, " MaxDevices = %d\n",
5476 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
5477 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
5480 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
5481 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
5483 ioc->facts.NumberOfPorts);
5484 if (ioc->bus_type == FC) {
5485 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
5486 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5487 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
5488 a[5], a[4], a[3], a[2], a[1], a[0]);
5490 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
5491 ioc->fc_port_page0[p].WWNN.High,
5492 ioc->fc_port_page0[p].WWNN.Low,
5493 ioc->fc_port_page0[p].WWPN.High,
5494 ioc->fc_port_page0[p].WWPN.Low);
5498 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5501 #endif /* CONFIG_PROC_FS } */
5503 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5505 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
5508 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
5509 sprintf(buf, " (Exp %02d%02d)",
5510 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
5511 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
5514 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
5515 strcat(buf, " [MDBG]");
5519 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5521 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
5522 * @ioc: Pointer to MPT_ADAPTER structure
5523 * @buffer: Pointer to buffer where IOC summary info should be written
5524 * @size: Pointer to number of bytes we wrote (set by this routine)
5525 * @len: Offset at which to start writing in buffer
5526 * @showlan: Display LAN stuff?
5528 * This routine writes (english readable) ASCII text, which represents
5529 * a summary of IOC information, to a buffer.
5532 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
5537 mpt_get_fw_exp_ver(expVer, ioc);
5540 * Shorter summary of attached ioc's...
5542 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
5545 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
5546 ioc->facts.FWVersion.Word,
5548 ioc->facts.NumberOfPorts,
5551 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
5552 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5553 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
5554 a[5], a[4], a[3], a[2], a[1], a[0]);
5557 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
5560 y += sprintf(buffer+len+y, " (disabled)");
5562 y += sprintf(buffer+len+y, "\n");
5567 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5571 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5573 * mpt_HardResetHandler - Generic reset handler, issue SCSI Task
5574 * Management call based on input arg values. If TaskMgmt fails,
5575 * return associated SCSI request.
5576 * @ioc: Pointer to MPT_ADAPTER structure
5577 * @sleepFlag: Indicates if sleep or schedule must be called.
5579 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
5580 * or a non-interrupt thread. In the former, must not call schedule().
5582 * Remark: A return of -1 is a FATAL error case, as it means a
5583 * FW reload/initialization failed.
5585 * Returns 0 for SUCCESS or -1 if FAILED.
5588 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
5591 unsigned long flags;
5593 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name));
5595 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
5596 printk("MF count 0x%x !\n", ioc->mfcnt);
5599 /* Reset the adapter. Prevent more than 1 call to
5600 * mpt_do_ioc_recovery at any instant in time.
5602 spin_lock_irqsave(&ioc->diagLock, flags);
5603 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
5604 spin_unlock_irqrestore(&ioc->diagLock, flags);
5607 ioc->diagPending = 1;
5609 spin_unlock_irqrestore(&ioc->diagLock, flags);
5611 /* FIXME: If do_ioc_recovery fails, repeat....
5614 /* The SCSI driver needs to adjust timeouts on all current
5615 * commands prior to the diagnostic reset being issued.
5616 * Prevents timeouts occuring during a diagnostic reset...very bad.
5617 * For all other protocol drivers, this is a no-op.
5623 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5624 if (MptResetHandlers[ii]) {
5625 dtmprintk((MYIOC_s_INFO_FMT "Calling IOC reset_setup handler #%d\n",
5627 r += mpt_signal_reset(ii, ioc, MPT_IOC_SETUP_RESET);
5629 dtmprintk((MYIOC_s_INFO_FMT "Calling alt-%s setup reset handler #%d\n",
5630 ioc->name, ioc->alt_ioc->name, ii));
5631 r += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_SETUP_RESET);
5637 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
5638 printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
5643 ioc->alt_ioc->reload_fw = 0;
5645 spin_lock_irqsave(&ioc->diagLock, flags);
5646 ioc->diagPending = 0;
5648 ioc->alt_ioc->diagPending = 0;
5649 spin_unlock_irqrestore(&ioc->diagLock, flags);
5651 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
5656 # define EVENT_DESCR_STR_SZ 100
5658 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5660 EventDescriptionStr(u8 event, u32 evData0, char *evStr)
5665 case MPI_EVENT_NONE:
5668 case MPI_EVENT_LOG_DATA:
5671 case MPI_EVENT_STATE_CHANGE:
5672 ds = "State Change";
5674 case MPI_EVENT_UNIT_ATTENTION:
5675 ds = "Unit Attention";
5677 case MPI_EVENT_IOC_BUS_RESET:
5678 ds = "IOC Bus Reset";
5680 case MPI_EVENT_EXT_BUS_RESET:
5681 ds = "External Bus Reset";
5683 case MPI_EVENT_RESCAN:
5684 ds = "Bus Rescan Event";
5685 /* Ok, do we need to do anything here? As far as
5686 I can tell, this is when a new device gets added
5689 case MPI_EVENT_LINK_STATUS_CHANGE:
5690 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
5691 ds = "Link Status(FAILURE) Change";
5693 ds = "Link Status(ACTIVE) Change";
5695 case MPI_EVENT_LOOP_STATE_CHANGE:
5696 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
5697 ds = "Loop State(LIP) Change";
5698 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
5699 ds = "Loop State(LPE) Change"; /* ??? */
5701 ds = "Loop State(LPB) Change"; /* ??? */
5703 case MPI_EVENT_LOGOUT:
5706 case MPI_EVENT_EVENT_CHANGE:
5708 ds = "Events(ON) Change";
5710 ds = "Events(OFF) Change";
5712 case MPI_EVENT_INTEGRATED_RAID:
5714 u8 ReasonCode = (u8)(evData0 >> 16);
5715 switch (ReasonCode) {
5716 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
5717 ds = "Integrated Raid: Volume Created";
5719 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
5720 ds = "Integrated Raid: Volume Deleted";
5722 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
5723 ds = "Integrated Raid: Volume Settings Changed";
5725 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
5726 ds = "Integrated Raid: Volume Status Changed";
5728 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
5729 ds = "Integrated Raid: Volume Physdisk Changed";
5731 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
5732 ds = "Integrated Raid: Physdisk Created";
5734 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
5735 ds = "Integrated Raid: Physdisk Deleted";
5737 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
5738 ds = "Integrated Raid: Physdisk Settings Changed";
5740 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
5741 ds = "Integrated Raid: Physdisk Status Changed";
5743 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
5744 ds = "Integrated Raid: Domain Validation Needed";
5746 case MPI_EVENT_RAID_RC_SMART_DATA :
5747 ds = "Integrated Raid; Smart Data";
5749 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
5750 ds = "Integrated Raid: Replace Action Started";
5753 ds = "Integrated Raid";
5758 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
5759 ds = "SCSI Device Status Change";
5761 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
5763 u8 id = (u8)(evData0);
5764 u8 ReasonCode = (u8)(evData0 >> 16);
5765 switch (ReasonCode) {
5766 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
5767 snprintf(evStr, EVENT_DESCR_STR_SZ,
5768 "SAS Device Status Change: Added: id=%d", id);
5770 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
5771 snprintf(evStr, EVENT_DESCR_STR_SZ,
5772 "SAS Device Status Change: Deleted: id=%d", id);
5774 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
5775 snprintf(evStr, EVENT_DESCR_STR_SZ,
5776 "SAS Device Status Change: SMART Data: id=%d",
5779 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
5780 snprintf(evStr, EVENT_DESCR_STR_SZ,
5781 "SAS Device Status Change: No Persistancy "
5782 "Added: id=%d", id);
5785 snprintf(evStr, EVENT_DESCR_STR_SZ,
5786 "SAS Device Status Change: Unknown: id=%d", id);
5791 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
5792 ds = "Bus Timer Expired";
5794 case MPI_EVENT_QUEUE_FULL:
5797 case MPI_EVENT_SAS_SES:
5798 ds = "SAS SES Event";
5800 case MPI_EVENT_PERSISTENT_TABLE_FULL:
5801 ds = "Persistent Table Full";
5803 case MPI_EVENT_SAS_PHY_LINK_STATUS:
5805 u8 LinkRates = (u8)(evData0 >> 8);
5806 u8 PhyNumber = (u8)(evData0);
5807 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
5808 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
5809 switch (LinkRates) {
5810 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
5811 snprintf(evStr, EVENT_DESCR_STR_SZ,
5812 "SAS PHY Link Status: Phy=%d:"
5813 " Rate Unknown",PhyNumber);
5815 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
5816 snprintf(evStr, EVENT_DESCR_STR_SZ,
5817 "SAS PHY Link Status: Phy=%d:"
5818 " Phy Disabled",PhyNumber);
5820 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
5821 snprintf(evStr, EVENT_DESCR_STR_SZ,
5822 "SAS PHY Link Status: Phy=%d:"
5823 " Failed Speed Nego",PhyNumber);
5825 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
5826 snprintf(evStr, EVENT_DESCR_STR_SZ,
5827 "SAS PHY Link Status: Phy=%d:"
5828 " Sata OOB Completed",PhyNumber);
5830 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
5831 snprintf(evStr, EVENT_DESCR_STR_SZ,
5832 "SAS PHY Link Status: Phy=%d:"
5833 " Rate 1.5 Gbps",PhyNumber);
5835 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
5836 snprintf(evStr, EVENT_DESCR_STR_SZ,
5837 "SAS PHY Link Status: Phy=%d:"
5838 " Rate 3.0 Gpbs",PhyNumber);
5841 snprintf(evStr, EVENT_DESCR_STR_SZ,
5842 "SAS PHY Link Status: Phy=%d", PhyNumber);
5847 case MPI_EVENT_SAS_DISCOVERY_ERROR:
5848 ds = "SAS Discovery Error";
5850 case MPI_EVENT_IR_RESYNC_UPDATE:
5852 u8 resync_complete = (u8)(evData0 >> 16);
5853 snprintf(evStr, EVENT_DESCR_STR_SZ,
5854 "IR Resync Update: Complete = %d:",resync_complete);
5859 u8 ReasonCode = (u8)(evData0 >> 16);
5860 switch (ReasonCode) {
5861 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
5862 ds = "IR2: LD State Changed";
5864 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
5865 ds = "IR2: PD State Changed";
5867 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
5868 ds = "IR2: Bad Block Table Full";
5870 case MPI_EVENT_IR2_RC_PD_INSERTED:
5871 ds = "IR2: PD Inserted";
5873 case MPI_EVENT_IR2_RC_PD_REMOVED:
5874 ds = "IR2: PD Removed";
5876 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
5877 ds = "IR2: Foreign CFG Detected";
5879 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
5880 ds = "IR2: Rebuild Medium Error";
5888 case MPI_EVENT_SAS_DISCOVERY:
5891 ds = "SAS Discovery: Start";
5893 ds = "SAS Discovery: Stop";
5896 case MPI_EVENT_LOG_ENTRY_ADDED:
5897 ds = "SAS Log Entry Added";
5901 * MPT base "custom" events may be added here...
5908 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
5911 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5913 * ProcessEventNotification - Route a received EventNotificationReply to
5914 * all currently regeistered event handlers.
5915 * @ioc: Pointer to MPT_ADAPTER structure
5916 * @pEventReply: Pointer to EventNotification reply frame
5917 * @evHandlers: Pointer to integer, number of event handlers
5919 * Returns sum of event handlers return values.
5922 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
5930 char evStr[EVENT_DESCR_STR_SZ];
5934 * Do platform normalization of values
5936 event = le32_to_cpu(pEventReply->Event) & 0xFF;
5937 // evCtx = le32_to_cpu(pEventReply->EventContext);
5938 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
5940 evData0 = le32_to_cpu(pEventReply->Data[0]);
5943 EventDescriptionStr(event, evData0, evStr);
5944 devtprintk((MYIOC_s_INFO_FMT "MPT event:(%02Xh) : %s\n",
5949 #if defined(MPT_DEBUG) || defined(MPT_DEBUG_VERBOSE_EVENTS)
5950 printk(KERN_INFO MYNAM ": Event data:\n" KERN_INFO);
5951 for (ii = 0; ii < evDataLen; ii++)
5952 printk(" %08x", le32_to_cpu(pEventReply->Data[ii]));
5957 * Do general / base driver event processing
5960 case MPI_EVENT_EVENT_CHANGE: /* 0A */
5962 u8 evState = evData0 & 0xFF;
5964 /* CHECKME! What if evState unexpectedly says OFF (0)? */
5966 /* Update EventState field in cached IocFacts */
5967 if (ioc->facts.Function) {
5968 ioc->facts.EventState = evState;
5972 case MPI_EVENT_INTEGRATED_RAID:
5973 mptbase_raid_process_event_data(ioc,
5974 (MpiEventDataRaid_t *)pEventReply->Data);
5981 * Should this event be logged? Events are written sequentially.
5982 * When buffer is full, start again at the top.
5984 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
5987 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
5989 ioc->events[idx].event = event;
5990 ioc->events[idx].eventContext = ioc->eventContext;
5992 for (ii = 0; ii < 2; ii++) {
5994 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
5996 ioc->events[idx].data[ii] = 0;
5999 ioc->eventContext++;
6004 * Call each currently registered protocol event handler.
6006 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
6007 if (MptEvHandlers[ii]) {
6008 devtverboseprintk((MYIOC_s_INFO_FMT "Routing Event to event handler #%d\n",
6010 r += (*(MptEvHandlers[ii]))(ioc, pEventReply);
6014 /* FIXME? Examine results here? */
6017 * If needed, send (a single) EventAck.
6019 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
6020 devtverboseprintk((MYIOC_s_WARN_FMT
6021 "EventAck required\n",ioc->name));
6022 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
6023 devtverboseprintk((MYIOC_s_WARN_FMT "SendEventAck returned %d\n",
6028 *evHandlers = handlers;
6032 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6034 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
6035 * @ioc: Pointer to MPT_ADAPTER structure
6036 * @log_info: U32 LogInfo reply word from the IOC
6038 * Refer to lsi/fc_log.h.
6041 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
6043 static char *subcl_str[8] = {
6044 "FCP Initiator", "FCP Target", "LAN", "MPI Message Layer",
6045 "FC Link", "Context Manager", "Invalid Field Offset", "State Change Info"
6047 u8 subcl = (log_info >> 24) & 0x7;
6049 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubCl={%s}\n",
6050 ioc->name, log_info, subcl_str[subcl]);
6053 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6055 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
6056 * @ioc: Pointer to MPT_ADAPTER structure
6057 * @mr: Pointer to MPT reply frame
6058 * @log_info: U32 LogInfo word from the IOC
6060 * Refer to lsi/sp_log.h.
6063 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
6065 u32 info = log_info & 0x00FF0000;
6066 char *desc = "unknown";
6070 desc = "bug! MID not found";
6071 if (ioc->reload_fw == 0)
6076 desc = "Parity Error";
6080 desc = "ASYNC Outbound Overrun";
6084 desc = "SYNC Offset Error";
6092 desc = "Msg In Overflow";
6100 desc = "Outbound DMA Overrun";
6104 desc = "Task Management";
6108 desc = "Device Problem";
6112 desc = "Invalid Phase Change";
6116 desc = "Untagged Table Size";
6121 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
6124 /* strings for sas loginfo */
6125 static char *originator_str[] = {
6130 static char *iop_code_str[] = {
6132 "Invalid SAS Address", /* 01h */
6134 "Invalid Page", /* 03h */
6136 "Task Terminated" /* 05h */
6138 static char *pl_code_str[] = {
6140 "Open Failure", /* 01h */
6141 "Invalid Scatter Gather List", /* 02h */
6142 "Wrong Relative Offset or Frame Length", /* 03h */
6143 "Frame Transfer Error", /* 04h */
6144 "Transmit Frame Connected Low", /* 05h */
6145 "SATA Non-NCQ RW Error Bit Set", /* 06h */
6146 "SATA Read Log Receive Data Error", /* 07h */
6147 "SATA NCQ Fail All Commands After Error", /* 08h */
6148 "SATA Error in Receive Set Device Bit FIS", /* 09h */
6149 "Receive Frame Invalid Message", /* 0Ah */
6150 "Receive Context Message Valid Error", /* 0Bh */
6151 "Receive Frame Current Frame Error", /* 0Ch */
6152 "SATA Link Down", /* 0Dh */
6153 "Discovery SATA Init W IOS", /* 0Eh */
6154 "Config Invalid Page", /* 0Fh */
6155 "Discovery SATA Init Timeout", /* 10h */
6158 "IO Not Yet Executed", /* 13h */
6159 "IO Executed", /* 14h */
6160 "Persistant Reservation Out Not Affiliation Owner", /* 15h */
6161 "Open Transmit DMA Abort", /* 16h */
6171 "Enclosure Management" /* 20h */
6174 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6176 * mpt_sas_log_info - Log information returned from SAS IOC.
6177 * @ioc: Pointer to MPT_ADAPTER structure
6178 * @log_info: U32 LogInfo reply word from the IOC
6180 * Refer to lsi/mpi_log_sas.h.
6183 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
6185 union loginfo_type {
6194 union loginfo_type sas_loginfo;
6195 char *code_desc = NULL;
6197 sas_loginfo.loginfo = log_info;
6198 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
6199 (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
6201 if ((sas_loginfo.dw.originator == 0 /*IOP*/) &&
6202 (sas_loginfo.dw.code < sizeof(iop_code_str)/sizeof(char*))) {
6203 code_desc = iop_code_str[sas_loginfo.dw.code];
6204 }else if ((sas_loginfo.dw.originator == 1 /*PL*/) &&
6205 (sas_loginfo.dw.code < sizeof(pl_code_str)/sizeof(char*) )) {
6206 code_desc = pl_code_str[sas_loginfo.dw.code];
6209 if (code_desc != NULL)
6210 printk(MYIOC_s_INFO_FMT
6211 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
6212 " SubCode(0x%04x)\n",
6215 originator_str[sas_loginfo.dw.originator],
6217 sas_loginfo.dw.subcode);
6219 printk(MYIOC_s_INFO_FMT
6220 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
6221 " SubCode(0x%04x)\n",
6224 originator_str[sas_loginfo.dw.originator],
6225 sas_loginfo.dw.code,
6226 sas_loginfo.dw.subcode);
6229 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6231 * mpt_sp_ioc_info - IOC information returned from SCSI Parallel IOC.
6232 * @ioc: Pointer to MPT_ADAPTER structure
6233 * @ioc_status: U32 IOCStatus word from IOC
6234 * @mf: Pointer to MPT request frame
6236 * Refer to lsi/mpi.h.
6239 mpt_sp_ioc_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
6241 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
6245 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
6246 desc = "Invalid Function";
6249 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
6253 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
6254 desc = "Invalid SGL";
6257 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
6258 desc = "Internal Error";
6261 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
6265 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
6266 desc = "Insufficient Resources";
6269 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
6270 desc = "Invalid Field";
6273 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
6274 desc = "Invalid State";
6277 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
6278 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
6279 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
6280 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
6281 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
6282 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
6283 /* No message for Config IOCStatus values */
6286 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
6287 /* No message for recovered error
6288 desc = "SCSI Recovered Error";
6292 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
6293 desc = "SCSI Invalid Bus";
6296 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
6297 desc = "SCSI Invalid TargetID";
6300 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
6302 SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
6303 U8 cdb = pScsiReq->CDB[0];
6304 if (cdb != 0x12) { /* Inquiry is issued for device scanning */
6305 desc = "SCSI Device Not There";
6310 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
6311 desc = "SCSI Data Overrun";
6314 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
6315 /* This error is checked in scsi_io_done(). Skip.
6316 desc = "SCSI Data Underrun";
6320 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
6321 desc = "SCSI I/O Data Error";
6324 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
6325 desc = "SCSI Protocol Error";
6328 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
6329 desc = "SCSI Task Terminated";
6332 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
6333 desc = "SCSI Residual Mismatch";
6336 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
6337 desc = "SCSI Task Management Failed";
6340 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
6341 desc = "SCSI IOC Terminated";
6344 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
6345 desc = "SCSI Ext Terminated";
6353 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04x): %s\n", ioc->name, status, desc);
6356 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6357 EXPORT_SYMBOL(mpt_attach);
6358 EXPORT_SYMBOL(mpt_detach);
6360 EXPORT_SYMBOL(mpt_resume);
6361 EXPORT_SYMBOL(mpt_suspend);
6363 EXPORT_SYMBOL(ioc_list);
6364 EXPORT_SYMBOL(mpt_proc_root_dir);
6365 EXPORT_SYMBOL(mpt_register);
6366 EXPORT_SYMBOL(mpt_deregister);
6367 EXPORT_SYMBOL(mpt_event_register);
6368 EXPORT_SYMBOL(mpt_event_deregister);
6369 EXPORT_SYMBOL(mpt_reset_register);
6370 EXPORT_SYMBOL(mpt_reset_deregister);
6371 EXPORT_SYMBOL(mpt_device_driver_register);
6372 EXPORT_SYMBOL(mpt_device_driver_deregister);
6373 EXPORT_SYMBOL(mpt_get_msg_frame);
6374 EXPORT_SYMBOL(mpt_put_msg_frame);
6375 EXPORT_SYMBOL(mpt_free_msg_frame);
6376 EXPORT_SYMBOL(mpt_add_sge);
6377 EXPORT_SYMBOL(mpt_send_handshake_request);
6378 EXPORT_SYMBOL(mpt_verify_adapter);
6379 EXPORT_SYMBOL(mpt_GetIocState);
6380 EXPORT_SYMBOL(mpt_print_ioc_summary);
6381 EXPORT_SYMBOL(mpt_lan_index);
6382 EXPORT_SYMBOL(mpt_stm_index);
6383 EXPORT_SYMBOL(mpt_HardResetHandler);
6384 EXPORT_SYMBOL(mpt_config);
6385 EXPORT_SYMBOL(mpt_findImVolumes);
6386 EXPORT_SYMBOL(mpt_alloc_fw_memory);
6387 EXPORT_SYMBOL(mpt_free_fw_memory);
6388 EXPORT_SYMBOL(mptbase_sas_persist_operation);
6391 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6393 * fusion_init - Fusion MPT base driver initialization routine.
6395 * Returns 0 for success, non-zero for failure.
6402 show_mptmod_ver(my_NAME, my_VERSION);
6403 printk(KERN_INFO COPYRIGHT "\n");
6405 for (i = 0; i < MPT_MAX_PROTOCOL_DRIVERS; i++) {
6406 MptCallbacks[i] = NULL;
6407 MptDriverClass[i] = MPTUNKNOWN_DRIVER;
6408 MptEvHandlers[i] = NULL;
6409 MptResetHandlers[i] = NULL;
6412 /* Register ourselves (mptbase) in order to facilitate
6413 * EventNotification handling.
6415 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
6417 /* Register for hard reset handling callbacks.
6419 if (mpt_reset_register(mpt_base_index, mpt_ioc_reset) == 0) {
6420 dprintk((KERN_INFO MYNAM ": Register for IOC reset notification\n"));
6425 #ifdef CONFIG_PROC_FS
6426 (void) procmpt_create();
6431 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6433 * fusion_exit - Perform driver unload cleanup.
6435 * This routine frees all resources associated with each MPT adapter
6436 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
6442 dexitprintk((KERN_INFO MYNAM ": fusion_exit() called!\n"));
6444 mpt_reset_deregister(mpt_base_index);
6446 #ifdef CONFIG_PROC_FS
6451 module_init(fusion_init);
6452 module_exit(fusion_exit);