2 * linux/drivers/message/fusion/mptbase.c
3 * This is the Fusion MPT base driver which supports multiple
4 * (SCSI + LAN) specialized protocol drivers.
5 * For use with LSI Logic PCI chip/adapter(s)
6 * running LSI Logic Fusion MPT (Message Passing Technology) firmware.
8 * Copyright (c) 1999-2007 LSI Logic Corporation
9 * (mailto:mpt_linux_developer@lsil.com)
12 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
14 This program is free software; you can redistribute it and/or modify
15 it under the terms of the GNU General Public License as published by
16 the Free Software Foundation; version 2 of the License.
18 This program is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 GNU General Public License for more details.
24 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
25 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
26 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
27 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
28 solely responsible for determining the appropriateness of using and
29 distributing the Program and assumes all risks associated with its
30 exercise of rights under this Agreement, including but not limited to
31 the risks and costs of program errors, damage to or loss of data,
32 programs or equipment, and unavailability or interruption of operations.
34 DISCLAIMER OF LIABILITY
35 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
36 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
37 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
38 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
39 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
40 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
41 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
43 You should have received a copy of the GNU General Public License
44 along with this program; if not, write to the Free Software
45 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
47 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
49 #include <linux/kernel.h>
50 #include <linux/module.h>
51 #include <linux/errno.h>
52 #include <linux/init.h>
53 #include <linux/slab.h>
54 #include <linux/types.h>
55 #include <linux/pci.h>
56 #include <linux/kdev_t.h>
57 #include <linux/blkdev.h>
58 #include <linux/delay.h>
59 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
60 #include <linux/dma-mapping.h>
68 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
69 #define my_NAME "Fusion MPT base driver"
70 #define my_VERSION MPT_LINUX_VERSION_COMMON
71 #define MYNAM "mptbase"
73 MODULE_AUTHOR(MODULEAUTHOR);
74 MODULE_DESCRIPTION(my_NAME);
75 MODULE_LICENSE("GPL");
76 MODULE_VERSION(my_VERSION);
81 static int mpt_msi_enable;
82 module_param(mpt_msi_enable, int, 0);
83 MODULE_PARM_DESC(mpt_msi_enable, " MSI Support Enable (default=0)");
85 static int mpt_channel_mapping;
86 module_param(mpt_channel_mapping, int, 0);
87 MODULE_PARM_DESC(mpt_channel_mapping, " Mapping id's to channels (default=0)");
90 static int mfcounter = 0;
91 #define PRINT_MF_COUNT 20000
94 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
98 int mpt_lan_index = -1;
99 int mpt_stm_index = -1;
101 struct proc_dir_entry *mpt_proc_root_dir;
103 #define WHOINIT_UNKNOWN 0xAA
105 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
109 /* Adapter link list */
111 /* Callback lookup table */
112 static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
113 /* Protocol driver class lookup table */
114 static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
115 /* Event handler lookup table */
116 static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
117 /* Reset handler lookup table */
118 static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
119 static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
121 static int mpt_base_index = -1;
122 static int last_drv_idx = -1;
124 static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq);
126 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
130 static irqreturn_t mpt_interrupt(int irq, void *bus_id);
131 static int mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
132 static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
133 u32 *req, int replyBytes, u16 *u16reply, int maxwait,
135 static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
136 static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
137 static void mpt_adapter_disable(MPT_ADAPTER *ioc);
138 static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
140 static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
141 static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
142 static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
143 static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
144 static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
145 static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
146 static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
147 static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
148 static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
149 static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
150 static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
151 static int PrimeIocFifos(MPT_ADAPTER *ioc);
152 static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
153 static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
154 static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
155 static int GetLanConfigPages(MPT_ADAPTER *ioc);
156 static int GetIoUnitPage2(MPT_ADAPTER *ioc);
157 int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
158 static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
159 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
160 static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
161 static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
162 static void mpt_timer_expired(unsigned long data);
163 static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
164 static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
165 static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
166 static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
168 #ifdef CONFIG_PROC_FS
169 static int procmpt_summary_read(char *buf, char **start, off_t offset,
170 int request, int *eof, void *data);
171 static int procmpt_version_read(char *buf, char **start, off_t offset,
172 int request, int *eof, void *data);
173 static int procmpt_iocinfo_read(char *buf, char **start, off_t offset,
174 int request, int *eof, void *data);
176 static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
178 //int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
179 static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers);
180 #ifdef MPT_DEBUG_REPLY
181 static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
183 static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
184 static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
185 static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
186 static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
188 /* module entry point */
189 static int __init fusion_init (void);
190 static void __exit fusion_exit (void);
192 #define CHIPREG_READ32(addr) readl_relaxed(addr)
193 #define CHIPREG_READ32_dmasync(addr) readl(addr)
194 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
195 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
196 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
199 pci_disable_io_access(struct pci_dev *pdev)
203 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
205 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
209 pci_enable_io_access(struct pci_dev *pdev)
213 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
215 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
219 * Process turbo (context) reply...
222 mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
224 MPT_FRAME_HDR *mf = NULL;
225 MPT_FRAME_HDR *mr = NULL;
229 dmfprintk((MYIOC_s_INFO_FMT "Got TURBO reply req_idx=%08x\n",
232 switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
233 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
234 req_idx = pa & 0x0000FFFF;
235 cb_idx = (pa & 0x00FF0000) >> 16;
236 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
238 case MPI_CONTEXT_REPLY_TYPE_LAN:
239 cb_idx = mpt_lan_index;
241 * Blind set of mf to NULL here was fatal
242 * after lan_reply says "freeme"
243 * Fix sort of combined with an optimization here;
244 * added explicit check for case where lan_reply
245 * was just returning 1 and doing nothing else.
246 * For this case skip the callback, but set up
247 * proper mf value first here:-)
249 if ((pa & 0x58000000) == 0x58000000) {
250 req_idx = pa & 0x0000FFFF;
251 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
252 mpt_free_msg_frame(ioc, mf);
257 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
259 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
260 cb_idx = mpt_stm_index;
261 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
268 /* Check for (valid) IO callback! */
269 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
270 MptCallbacks[cb_idx] == NULL) {
271 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
272 __FUNCTION__, ioc->name, cb_idx);
276 if (MptCallbacks[cb_idx](ioc, mf, mr))
277 mpt_free_msg_frame(ioc, mf);
283 mpt_reply(MPT_ADAPTER *ioc, u32 pa)
294 /* non-TURBO reply! Hmmm, something may be up...
295 * Newest turbo reply mechanism; get address
296 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
299 /* Map DMA address of reply header to cpu address.
300 * pa is 32 bits - but the dma address may be 32 or 64 bits
301 * get offset based only only the low addresses
304 reply_dma_low = (pa <<= 1);
305 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
306 (reply_dma_low - ioc->reply_frames_low_dma));
308 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
309 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
310 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
312 dmfprintk((MYIOC_s_INFO_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
313 ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
314 DBG_DUMP_REPLY_FRAME(mr)
316 /* Check/log IOC log info
318 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
319 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
320 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
321 if (ioc->bus_type == FC)
322 mpt_fc_log_info(ioc, log_info);
323 else if (ioc->bus_type == SPI)
324 mpt_spi_log_info(ioc, log_info);
325 else if (ioc->bus_type == SAS)
326 mpt_sas_log_info(ioc, log_info);
329 #ifdef MPT_DEBUG_REPLY
330 if (ioc_stat & MPI_IOCSTATUS_MASK)
331 mpt_iocstatus_info(ioc, (u32)ioc_stat, mf);
334 /* Check for (valid) IO callback! */
335 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
336 MptCallbacks[cb_idx] == NULL) {
337 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
338 __FUNCTION__, ioc->name, cb_idx);
343 freeme = MptCallbacks[cb_idx](ioc, mf, mr);
346 /* Flush (non-TURBO) reply with a WRITE! */
347 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
350 mpt_free_msg_frame(ioc, mf);
354 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
356 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
357 * @irq: irq number (not used)
358 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
360 * This routine is registered via the request_irq() kernel API call,
361 * and handles all interrupts generated from a specific MPT adapter
362 * (also referred to as a IO Controller or IOC).
363 * This routine must clear the interrupt from the adapter and does
364 * so by reading the reply FIFO. Multiple replies may be processed
365 * per single call to this routine.
367 * This routine handles register-level access of the adapter but
368 * dispatches (calls) a protocol-specific callback routine to handle
369 * the protocol-specific details of the MPT request completion.
372 mpt_interrupt(int irq, void *bus_id)
374 MPT_ADAPTER *ioc = bus_id;
375 u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
377 if (pa == 0xFFFFFFFF)
381 * Drain the reply FIFO!
384 if (pa & MPI_ADDRESS_REPLY_A_BIT)
387 mpt_turbo_reply(ioc, pa);
388 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
389 } while (pa != 0xFFFFFFFF);
394 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
396 * mpt_base_reply - MPT base driver's callback routine
397 * @ioc: Pointer to MPT_ADAPTER structure
398 * @mf: Pointer to original MPT request frame
399 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
401 * MPT base driver's callback routine; all base driver
402 * "internal" request/reply processing is routed here.
403 * Currently used for EventNotification and EventAck handling.
405 * Returns 1 indicating original alloc'd request frame ptr
406 * should be freed, or 0 if it shouldn't.
409 mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
414 dmfprintk((MYIOC_s_INFO_FMT "mpt_base_reply() called\n", ioc->name));
416 #if defined(MPT_DEBUG_MSG_FRAME)
417 if (!(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) {
418 dmfprintk((KERN_INFO MYNAM ": Original request frame (@%p) header\n", mf));
419 DBG_DUMP_REQUEST_FRAME_HDR(mf)
423 func = reply->u.hdr.Function;
424 dmfprintk((MYIOC_s_INFO_FMT "mpt_base_reply, Function=%02Xh\n",
427 if (func == MPI_FUNCTION_EVENT_NOTIFICATION) {
428 EventNotificationReply_t *pEvReply = (EventNotificationReply_t *) reply;
432 results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
433 if (results != evHandlers) {
434 /* CHECKME! Any special handling needed here? */
435 devtverboseprintk((MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
436 ioc->name, evHandlers, results));
440 * Hmmm... It seems that EventNotificationReply is an exception
441 * to the rule of one reply per request.
443 if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) {
446 devtverboseprintk((MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
447 ioc->name, pEvReply));
450 #ifdef CONFIG_PROC_FS
451 // LogEvent(ioc, pEvReply);
454 } else if (func == MPI_FUNCTION_EVENT_ACK) {
455 dprintk((MYIOC_s_INFO_FMT "mpt_base_reply, EventAck reply received\n",
457 } else if (func == MPI_FUNCTION_CONFIG) {
461 dcprintk((MYIOC_s_INFO_FMT "config_complete (mf=%p,mr=%p)\n",
462 ioc->name, mf, reply));
464 pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *)));
467 /* disable timer and remove from linked list */
468 del_timer(&pCfg->timer);
470 spin_lock_irqsave(&ioc->FreeQlock, flags);
471 list_del(&pCfg->linkage);
472 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
475 * If IOC Status is SUCCESS, save the header
476 * and set the status code to GOOD.
478 pCfg->status = MPT_CONFIG_ERROR;
480 ConfigReply_t *pReply = (ConfigReply_t *)reply;
483 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
484 dcprintk((KERN_NOTICE " IOCStatus=%04xh, IOCLogInfo=%08xh\n",
485 status, le32_to_cpu(pReply->IOCLogInfo)));
487 pCfg->status = status;
488 if (status == MPI_IOCSTATUS_SUCCESS) {
489 if ((pReply->Header.PageType &
490 MPI_CONFIG_PAGETYPE_MASK) ==
491 MPI_CONFIG_PAGETYPE_EXTENDED) {
492 pCfg->cfghdr.ehdr->ExtPageLength =
493 le16_to_cpu(pReply->ExtPageLength);
494 pCfg->cfghdr.ehdr->ExtPageType =
497 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
499 /* If this is a regular header, save PageLength. */
500 /* LMP Do this better so not using a reserved field! */
501 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
502 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
503 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
508 * Wake up the original calling thread
513 } else if (func == MPI_FUNCTION_SAS_IO_UNIT_CONTROL) {
514 /* we should be always getting a reply frame */
515 memcpy(ioc->persist_reply_frame, reply,
516 min(MPT_DEFAULT_FRAME_SIZE,
517 4*reply->u.reply.MsgLength));
518 del_timer(&ioc->persist_timer);
519 ioc->persist_wait_done = 1;
522 printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
527 * Conditionally tell caller to free the original
528 * EventNotification/EventAck/unexpected request frame!
533 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
535 * mpt_register - Register protocol-specific main callback handler.
536 * @cbfunc: callback function pointer
537 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
539 * This routine is called by a protocol-specific driver (SCSI host,
540 * LAN, SCSI target) to register its reply callback routine. Each
541 * protocol-specific driver must do this before it will be able to
542 * use any IOC resources, such as obtaining request frames.
544 * NOTES: The SCSI protocol driver currently calls this routine thrice
545 * in order to register separate callbacks; one for "normal" SCSI IO;
546 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
548 * Returns a positive integer valued "handle" in the
549 * range (and S.O.D. order) {N,...,7,6,5,...,1} if successful.
550 * Any non-positive return value (including zero!) should be considered
551 * an error by the caller.
554 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
561 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
562 * (slot/handle 0 is reserved!)
564 for (i = MPT_MAX_PROTOCOL_DRIVERS-1; i; i--) {
565 if (MptCallbacks[i] == NULL) {
566 MptCallbacks[i] = cbfunc;
567 MptDriverClass[i] = dclass;
568 MptEvHandlers[i] = NULL;
577 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
579 * mpt_deregister - Deregister a protocol drivers resources.
580 * @cb_idx: previously registered callback handle
582 * Each protocol-specific driver should call this routine when its
583 * module is unloaded.
586 mpt_deregister(int cb_idx)
588 if ((cb_idx >= 0) && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
589 MptCallbacks[cb_idx] = NULL;
590 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
591 MptEvHandlers[cb_idx] = NULL;
597 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
599 * mpt_event_register - Register protocol-specific event callback
601 * @cb_idx: previously registered (via mpt_register) callback handle
602 * @ev_cbfunc: callback function
604 * This routine can be called by one or more protocol-specific drivers
605 * if/when they choose to be notified of MPT events.
607 * Returns 0 for success.
610 mpt_event_register(int cb_idx, MPT_EVHANDLER ev_cbfunc)
612 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
615 MptEvHandlers[cb_idx] = ev_cbfunc;
619 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
621 * mpt_event_deregister - Deregister protocol-specific event callback
623 * @cb_idx: previously registered callback handle
625 * Each protocol-specific driver should call this routine
626 * when it does not (or can no longer) handle events,
627 * or when its module is unloaded.
630 mpt_event_deregister(int cb_idx)
632 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
635 MptEvHandlers[cb_idx] = NULL;
638 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
640 * mpt_reset_register - Register protocol-specific IOC reset handler.
641 * @cb_idx: previously registered (via mpt_register) callback handle
642 * @reset_func: reset function
644 * This routine can be called by one or more protocol-specific drivers
645 * if/when they choose to be notified of IOC resets.
647 * Returns 0 for success.
650 mpt_reset_register(int cb_idx, MPT_RESETHANDLER reset_func)
652 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
655 MptResetHandlers[cb_idx] = reset_func;
659 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
661 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
662 * @cb_idx: previously registered callback handle
664 * Each protocol-specific driver should call this routine
665 * when it does not (or can no longer) handle IOC reset handling,
666 * or when its module is unloaded.
669 mpt_reset_deregister(int cb_idx)
671 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
674 MptResetHandlers[cb_idx] = NULL;
677 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
679 * mpt_device_driver_register - Register device driver hooks
680 * @dd_cbfunc: driver callbacks struct
681 * @cb_idx: MPT protocol driver index
684 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, int cb_idx)
687 const struct pci_device_id *id;
689 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
692 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
694 /* call per pci device probe entry point */
695 list_for_each_entry(ioc, &ioc_list, list) {
696 id = ioc->pcidev->driver ?
697 ioc->pcidev->driver->id_table : NULL;
698 if (dd_cbfunc->probe)
699 dd_cbfunc->probe(ioc->pcidev, id);
705 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
707 * mpt_device_driver_deregister - DeRegister device driver hooks
708 * @cb_idx: MPT protocol driver index
711 mpt_device_driver_deregister(int cb_idx)
713 struct mpt_pci_driver *dd_cbfunc;
716 if (cb_idx < 1 || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
719 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
721 list_for_each_entry(ioc, &ioc_list, list) {
722 if (dd_cbfunc->remove)
723 dd_cbfunc->remove(ioc->pcidev);
726 MptDeviceDriverHandlers[cb_idx] = NULL;
730 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
732 * mpt_get_msg_frame - Obtain a MPT request frame from the pool (of 1024)
733 * allocated per MPT adapter.
734 * @handle: Handle of registered MPT protocol driver
735 * @ioc: Pointer to MPT adapter structure
737 * Returns pointer to a MPT request frame or %NULL if none are available
738 * or IOC is not active.
741 mpt_get_msg_frame(int handle, MPT_ADAPTER *ioc)
745 u16 req_idx; /* Request index */
747 /* validate handle and ioc identifier */
751 printk(KERN_WARNING "IOC Not Active! mpt_get_msg_frame returning NULL!\n");
754 /* If interrupts are not attached, do not return a request frame */
758 spin_lock_irqsave(&ioc->FreeQlock, flags);
759 if (!list_empty(&ioc->FreeQ)) {
762 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
763 u.frame.linkage.list);
764 list_del(&mf->u.frame.linkage.list);
765 mf->u.frame.linkage.arg1 = 0;
766 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
767 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
769 req_idx = req_offset / ioc->req_sz;
770 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
771 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
772 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame; /* Default, will be changed if necessary in SG generation */
779 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
783 printk(KERN_WARNING "IOC Active. No free Msg Frames! Count 0x%x Max 0x%x\n", ioc->mfcnt, ioc->req_depth);
785 if (mfcounter == PRINT_MF_COUNT)
786 printk(KERN_INFO "MF Count 0x%x Max 0x%x \n", ioc->mfcnt, ioc->req_depth);
789 dmfprintk((KERN_INFO MYNAM ": %s: mpt_get_msg_frame(%d,%d), got mf=%p\n",
790 ioc->name, handle, ioc->id, mf));
794 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
796 * mpt_put_msg_frame - Send a protocol specific MPT request frame
798 * @handle: Handle of registered MPT protocol driver
799 * @ioc: Pointer to MPT adapter structure
800 * @mf: Pointer to MPT request frame
802 * This routine posts a MPT request frame to the request post FIFO of a
803 * specific MPT adapter.
806 mpt_put_msg_frame(int handle, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
810 u16 req_idx; /* Request index */
812 /* ensure values are reset properly! */
813 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle; /* byte */
814 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
816 req_idx = req_offset / ioc->req_sz;
817 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
818 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
820 #ifdef MPT_DEBUG_MSG_FRAME
822 u32 *m = mf->u.frame.hwhdr.__hdr;
825 printk(KERN_INFO MYNAM ": %s: About to Put msg frame @ %p:\n" KERN_INFO " ",
827 n = ioc->req_sz/4 - 1;
830 for (ii=0; ii<=n; ii++) {
831 if (ii && ((ii%8)==0))
832 printk("\n" KERN_INFO " ");
833 printk(" %08x", le32_to_cpu(m[ii]));
839 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
840 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]));
841 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
844 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
846 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
847 * @handle: Handle of registered MPT protocol driver
848 * @ioc: Pointer to MPT adapter structure
849 * @mf: Pointer to MPT request frame
851 * This routine places a MPT request frame back on the MPT adapter's
855 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
859 /* Put Request back on FreeQ! */
860 spin_lock_irqsave(&ioc->FreeQlock, flags);
861 mf->u.frame.linkage.arg1 = 0xdeadbeaf; /* signature to know if this mf is freed */
862 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
866 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
869 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
871 * mpt_add_sge - Place a simple SGE at address pAddr.
872 * @pAddr: virtual address for SGE
873 * @flagslength: SGE flags and data transfer length
874 * @dma_addr: Physical address
876 * This routine places a MPT request frame back on the MPT adapter's
880 mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
882 if (sizeof(dma_addr_t) == sizeof(u64)) {
883 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
884 u32 tmp = dma_addr & 0xFFFFFFFF;
886 pSge->FlagsLength = cpu_to_le32(flagslength);
887 pSge->Address.Low = cpu_to_le32(tmp);
888 tmp = (u32) ((u64)dma_addr >> 32);
889 pSge->Address.High = cpu_to_le32(tmp);
892 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
893 pSge->FlagsLength = cpu_to_le32(flagslength);
894 pSge->Address = cpu_to_le32(dma_addr);
898 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
900 * mpt_send_handshake_request - Send MPT request via doorbell handshake method.
901 * @handle: Handle of registered MPT protocol driver
902 * @ioc: Pointer to MPT adapter structure
903 * @reqBytes: Size of the request in bytes
904 * @req: Pointer to MPT request frame
905 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
907 * This routine is used exclusively to send MptScsiTaskMgmt
908 * requests since they are required to be sent via doorbell handshake.
910 * NOTE: It is the callers responsibility to byte-swap fields in the
911 * request which are greater than 1 byte in size.
913 * Returns 0 for success, non-zero for failure.
916 mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
922 /* State is known to be good upon entering
923 * this function so issue the bus reset
928 * Emulate what mpt_put_msg_frame() does /wrt to sanity
929 * setting cb_idx/req_idx. But ONLY if this request
930 * is in proper (pre-alloc'd) request buffer range...
932 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
933 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
934 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
935 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
936 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = handle;
939 /* Make sure there are no doorbells */
940 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
942 CHIPREG_WRITE32(&ioc->chip->Doorbell,
943 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
944 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
946 /* Wait for IOC doorbell int */
947 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
951 /* Read doorbell and check for active bit */
952 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
955 dhsprintk((KERN_INFO MYNAM ": %s: mpt_send_handshake_request start, WaitCnt=%d\n",
958 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
960 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
964 /* Send request via doorbell handshake */
965 req_as_bytes = (u8 *) req;
966 for (ii = 0; ii < reqBytes/4; ii++) {
969 word = ((req_as_bytes[(ii*4) + 0] << 0) |
970 (req_as_bytes[(ii*4) + 1] << 8) |
971 (req_as_bytes[(ii*4) + 2] << 16) |
972 (req_as_bytes[(ii*4) + 3] << 24));
973 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
974 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
980 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
985 /* Make sure there are no doorbells */
986 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
991 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
993 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
994 * @ioc: Pointer to MPT adapter structure
995 * @access_control_value: define bits below
996 * @sleepFlag: Specifies whether the process can sleep
998 * Provides mechanism for the host driver to control the IOC's
999 * Host Page Buffer access.
1001 * Access Control Value - bits[15:12]
1003 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1004 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1005 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1007 * Returns 0 for success, non-zero for failure.
1011 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1015 /* return if in use */
1016 if (CHIPREG_READ32(&ioc->chip->Doorbell)
1017 & MPI_DOORBELL_ACTIVE)
1020 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1022 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1023 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1024 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1025 (access_control_value<<12)));
1027 /* Wait for IOC to clear Doorbell Status bit */
1028 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1034 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1036 * mpt_host_page_alloc - allocate system memory for the fw
1037 * @ioc: Pointer to pointer to IOC adapter
1038 * @ioc_init: Pointer to ioc init config page
1040 * If we already allocated memory in past, then resend the same pointer.
1041 * Returns 0 for success, non-zero for failure.
1044 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1048 u32 host_page_buffer_sz=0;
1050 if(!ioc->HostPageBuffer) {
1052 host_page_buffer_sz =
1053 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1055 if(!host_page_buffer_sz)
1056 return 0; /* fw doesn't need any host buffers */
1058 /* spin till we get enough memory */
1059 while(host_page_buffer_sz > 0) {
1061 if((ioc->HostPageBuffer = pci_alloc_consistent(
1063 host_page_buffer_sz,
1064 &ioc->HostPageBuffer_dma)) != NULL) {
1066 dinitprintk((MYIOC_s_INFO_FMT
1067 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1068 ioc->name, ioc->HostPageBuffer,
1069 (u32)ioc->HostPageBuffer_dma,
1070 host_page_buffer_sz));
1071 ioc->alloc_total += host_page_buffer_sz;
1072 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1076 host_page_buffer_sz -= (4*1024);
1080 if(!ioc->HostPageBuffer) {
1081 printk(MYIOC_s_ERR_FMT
1082 "Failed to alloc memory for host_page_buffer!\n",
1087 psge = (char *)&ioc_init->HostPageBufferSGE;
1088 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1089 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1090 MPI_SGE_FLAGS_32_BIT_ADDRESSING |
1091 MPI_SGE_FLAGS_HOST_TO_IOC |
1092 MPI_SGE_FLAGS_END_OF_BUFFER;
1093 if (sizeof(dma_addr_t) == sizeof(u64)) {
1094 flags_length |= MPI_SGE_FLAGS_64_BIT_ADDRESSING;
1096 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1097 flags_length |= ioc->HostPageBuffer_sz;
1098 mpt_add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1099 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1104 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1106 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1107 * @iocid: IOC unique identifier (integer)
1108 * @iocpp: Pointer to pointer to IOC adapter
1110 * Given a unique IOC identifier, set pointer to the associated MPT
1111 * adapter structure.
1113 * Returns iocid and sets iocpp if iocid is found.
1114 * Returns -1 if iocid is not found.
1117 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1121 list_for_each_entry(ioc,&ioc_list,list) {
1122 if (ioc->id == iocid) {
1132 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1134 * mpt_attach - Install a PCI intelligent MPT adapter.
1135 * @pdev: Pointer to pci_dev structure
1136 * @id: PCI device ID information
1138 * This routine performs all the steps necessary to bring the IOC of
1139 * a MPT adapter to a OPERATIONAL state. This includes registering
1140 * memory regions, registering the interrupt, and allocating request
1141 * and reply memory pools.
1143 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1146 * Returns 0 for success, non-zero for failure.
1148 * TODO: Add support for polled controllers
1151 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1155 unsigned long mem_phys;
1163 static int mpt_ids = 0;
1164 #ifdef CONFIG_PROC_FS
1165 struct proc_dir_entry *dent, *ent;
1168 if (pci_enable_device(pdev))
1171 dinitprintk((KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1173 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
1174 dprintk((KERN_INFO MYNAM
1175 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n"));
1176 } else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
1177 printk(KERN_WARNING MYNAM ": 32 BIT PCI BUS DMA ADDRESSING NOT SUPPORTED\n");
1181 if (!pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
1182 dprintk((KERN_INFO MYNAM
1183 ": Using 64 bit consistent mask\n"));
1185 dprintk((KERN_INFO MYNAM
1186 ": Not using 64 bit consistent mask\n"));
1188 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1190 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1193 ioc->alloc_total = sizeof(MPT_ADAPTER);
1194 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1195 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1198 ioc->diagPending = 0;
1199 spin_lock_init(&ioc->diagLock);
1200 spin_lock_init(&ioc->initializing_hba_lock);
1202 /* Initialize the event logging.
1204 ioc->eventTypes = 0; /* None */
1205 ioc->eventContext = 0;
1206 ioc->eventLogSize = 0;
1213 ioc->cached_fw = NULL;
1215 /* Initilize SCSI Config Data structure
1217 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1219 /* Initialize the running configQ head.
1221 INIT_LIST_HEAD(&ioc->configQ);
1223 /* Initialize the fc rport list head.
1225 INIT_LIST_HEAD(&ioc->fc_rports);
1227 /* Find lookup slot. */
1228 INIT_LIST_HEAD(&ioc->list);
1229 ioc->id = mpt_ids++;
1231 mem_phys = msize = 0;
1233 for (ii=0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1234 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1237 /* Get I/O space! */
1238 port = pci_resource_start(pdev, ii);
1239 psize = pci_resource_len(pdev,ii);
1244 mem_phys = pci_resource_start(pdev, ii);
1245 msize = pci_resource_len(pdev,ii);
1248 ioc->mem_size = msize;
1251 /* Get logical ptr for PciMem0 space */
1252 /*mem = ioremap(mem_phys, msize);*/
1253 mem = ioremap(mem_phys, msize);
1255 printk(KERN_ERR MYNAM ": ERROR - Unable to map adapter memory!\n");
1260 dinitprintk((KERN_INFO MYNAM ": mem = %p, mem_phys = %lx\n", mem, mem_phys));
1262 dinitprintk((KERN_INFO MYNAM ": facts @ %p, pfacts[0] @ %p\n",
1263 &ioc->facts, &ioc->pfacts[0]));
1265 ioc->mem_phys = mem_phys;
1266 ioc->chip = (SYSIF_REGS __iomem *)mem;
1268 /* Save Port IO values in case we need to do downloadboot */
1270 u8 *pmem = (u8*)port;
1271 ioc->pio_mem_phys = port;
1272 ioc->pio_chip = (SYSIF_REGS __iomem *)pmem;
1275 if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC909) {
1276 ioc->prod_name = "LSIFC909";
1279 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929) {
1280 ioc->prod_name = "LSIFC929";
1283 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919) {
1284 ioc->prod_name = "LSIFC919";
1287 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC929X) {
1288 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1290 if (revision < XL_929) {
1291 ioc->prod_name = "LSIFC929X";
1292 /* 929X Chip Fix. Set Split transactions level
1293 * for PCIX. Set MOST bits to zero.
1295 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1297 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1299 ioc->prod_name = "LSIFC929XL";
1300 /* 929XL Chip Fix. Set MMRBC to 0x08.
1302 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1304 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1307 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC919X) {
1308 ioc->prod_name = "LSIFC919X";
1310 /* 919X Chip Fix. Set Split transactions level
1311 * for PCIX. Set MOST bits to zero.
1313 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1315 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1317 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC939X) {
1318 ioc->prod_name = "LSIFC939X";
1320 ioc->errata_flag_1064 = 1;
1322 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC949X) {
1323 ioc->prod_name = "LSIFC949X";
1325 ioc->errata_flag_1064 = 1;
1327 else if (pdev->device == MPI_MANUFACTPAGE_DEVICEID_FC949E) {
1328 ioc->prod_name = "LSIFC949E";
1331 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_53C1030) {
1332 ioc->prod_name = "LSI53C1030";
1333 ioc->bus_type = SPI;
1334 /* 1030 Chip Fix. Disable Split transactions
1335 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1337 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1338 if (revision < C0_1030) {
1339 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1341 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1344 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_1030_53C1035) {
1345 ioc->prod_name = "LSI53C1035";
1346 ioc->bus_type = SPI;
1348 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064) {
1349 ioc->prod_name = "LSISAS1064";
1350 ioc->bus_type = SAS;
1351 ioc->errata_flag_1064 = 1;
1353 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068) {
1354 ioc->prod_name = "LSISAS1068";
1355 ioc->bus_type = SAS;
1356 ioc->errata_flag_1064 = 1;
1358 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1064E) {
1359 ioc->prod_name = "LSISAS1064E";
1360 ioc->bus_type = SAS;
1362 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1068E) {
1363 ioc->prod_name = "LSISAS1068E";
1364 ioc->bus_type = SAS;
1366 else if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
1367 ioc->prod_name = "LSISAS1078";
1368 ioc->bus_type = SAS;
1371 if (ioc->errata_flag_1064)
1372 pci_disable_io_access(pdev);
1374 sprintf(ioc->name, "ioc%d", ioc->id);
1376 spin_lock_init(&ioc->FreeQlock);
1379 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1381 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1383 /* Set lookup ptr. */
1384 list_add_tail(&ioc->list, &ioc_list);
1386 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1388 mpt_detect_bound_ports(ioc, pdev);
1390 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1392 printk(KERN_WARNING MYNAM
1393 ": WARNING - %s did not initialize properly! (%d)\n",
1396 list_del(&ioc->list);
1398 ioc->alt_ioc->alt_ioc = NULL;
1401 pci_set_drvdata(pdev, NULL);
1405 /* call per device driver probe entry point */
1406 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1407 if(MptDeviceDriverHandlers[ii] &&
1408 MptDeviceDriverHandlers[ii]->probe) {
1409 MptDeviceDriverHandlers[ii]->probe(pdev,id);
1413 #ifdef CONFIG_PROC_FS
1415 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1417 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1419 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1421 ent->read_proc = procmpt_iocinfo_read;
1424 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1426 ent->read_proc = procmpt_summary_read;
1435 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1437 * mpt_detach - Remove a PCI intelligent MPT adapter.
1438 * @pdev: Pointer to pci_dev structure
1442 mpt_detach(struct pci_dev *pdev)
1444 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1448 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
1449 remove_proc_entry(pname, NULL);
1450 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
1451 remove_proc_entry(pname, NULL);
1452 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
1453 remove_proc_entry(pname, NULL);
1455 /* call per device driver remove entry point */
1456 for(ii=0; ii<MPT_MAX_PROTOCOL_DRIVERS; ii++) {
1457 if(MptDeviceDriverHandlers[ii] &&
1458 MptDeviceDriverHandlers[ii]->remove) {
1459 MptDeviceDriverHandlers[ii]->remove(pdev);
1463 /* Disable interrupts! */
1464 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1467 synchronize_irq(pdev->irq);
1469 /* Clear any lingering interrupt */
1470 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1472 CHIPREG_READ32(&ioc->chip->IntStatus);
1474 mpt_adapter_dispose(ioc);
1476 pci_set_drvdata(pdev, NULL);
1479 /**************************************************************************
1483 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1485 * mpt_suspend - Fusion MPT base driver suspend routine.
1486 * @pdev: Pointer to pci_dev structure
1487 * @state: new state to enter
1490 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
1493 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1495 device_state=pci_choose_state(pdev, state);
1497 printk(MYIOC_s_INFO_FMT
1498 "pci-suspend: pdev=0x%p, slot=%s, Entering operating state [D%d]\n",
1499 ioc->name, pdev, pci_name(pdev), device_state);
1501 pci_save_state(pdev);
1503 /* put ioc into READY_STATE */
1504 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
1505 printk(MYIOC_s_ERR_FMT
1506 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
1509 /* disable interrupts */
1510 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1513 /* Clear any lingering interrupt */
1514 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1516 pci_disable_device(pdev);
1517 pci_set_power_state(pdev, device_state);
1522 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1524 * mpt_resume - Fusion MPT base driver resume routine.
1525 * @pdev: Pointer to pci_dev structure
1528 mpt_resume(struct pci_dev *pdev)
1530 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1531 u32 device_state = pdev->current_state;
1534 printk(MYIOC_s_INFO_FMT
1535 "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n",
1536 ioc->name, pdev, pci_name(pdev), device_state);
1538 pci_set_power_state(pdev, 0);
1539 pci_restore_state(pdev);
1540 pci_enable_device(pdev);
1542 /* enable interrupts */
1543 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
1546 printk(MYIOC_s_INFO_FMT
1547 "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1549 (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1550 CHIPREG_READ32(&ioc->chip->Doorbell));
1552 /* bring ioc to operational state */
1553 if ((recovery_state = mpt_do_ioc_recovery(ioc,
1554 MPT_HOSTEVENT_IOC_RECOVER, CAN_SLEEP)) != 0) {
1555 printk(MYIOC_s_INFO_FMT
1556 "pci-resume: Cannot recover, error:[%x]\n",
1557 ioc->name, recovery_state);
1559 printk(MYIOC_s_INFO_FMT
1560 "pci-resume: success\n", ioc->name);
1568 mpt_signal_reset(int index, MPT_ADAPTER *ioc, int reset_phase)
1570 if ((MptDriverClass[index] == MPTSPI_DRIVER &&
1571 ioc->bus_type != SPI) ||
1572 (MptDriverClass[index] == MPTFC_DRIVER &&
1573 ioc->bus_type != FC) ||
1574 (MptDriverClass[index] == MPTSAS_DRIVER &&
1575 ioc->bus_type != SAS))
1576 /* make sure we only call the relevant reset handler
1579 return (MptResetHandlers[index])(ioc, reset_phase);
1582 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1584 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
1585 * @ioc: Pointer to MPT adapter structure
1586 * @reason: Event word / reason
1587 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1589 * This routine performs all the steps necessary to bring the IOC
1590 * to a OPERATIONAL state.
1592 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1597 * -1 if failed to get board READY
1598 * -2 if READY but IOCFacts Failed
1599 * -3 if READY but PrimeIOCFifos Failed
1600 * -4 if READY but IOCInit Failed
1603 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
1605 int hard_reset_done = 0;
1606 int alt_ioc_ready = 0;
1612 int reset_alt_ioc_active = 0;
1613 int irq_allocated = 0;
1615 printk(KERN_INFO MYNAM ": Initiating %s %s\n",
1616 ioc->name, reason==MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
1618 /* Disable reply interrupts (also blocks FreeQ) */
1619 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1623 if (ioc->alt_ioc->active)
1624 reset_alt_ioc_active = 1;
1626 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
1627 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
1628 ioc->alt_ioc->active = 0;
1632 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
1635 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
1636 if (hard_reset_done == -4) {
1637 printk(KERN_WARNING MYNAM ": %s Owned by PEER..skipping!\n",
1640 if (reset_alt_ioc_active && ioc->alt_ioc) {
1641 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
1642 dprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1643 ioc->alt_ioc->name));
1644 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
1645 ioc->alt_ioc->active = 1;
1649 printk(KERN_WARNING MYNAM ": %s NOT READY WARNING!\n",
1655 /* hard_reset_done = 0 if a soft reset was performed
1656 * and 1 if a hard reset was performed.
1658 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
1659 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
1662 printk(KERN_WARNING MYNAM
1663 ": alt-%s: Not ready WARNING!\n",
1664 ioc->alt_ioc->name);
1667 for (ii=0; ii<5; ii++) {
1668 /* Get IOC facts! Allow 5 retries */
1669 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
1675 dinitprintk((MYIOC_s_INFO_FMT "Retry IocFacts failed rc=%x\n", ioc->name, rc));
1677 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1678 MptDisplayIocCapabilities(ioc);
1681 if (alt_ioc_ready) {
1682 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
1683 dinitprintk((MYIOC_s_INFO_FMT "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
1684 /* Retry - alt IOC was initialized once
1686 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
1689 dinitprintk((MYIOC_s_INFO_FMT "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
1691 reset_alt_ioc_active = 0;
1692 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
1693 MptDisplayIocCapabilities(ioc->alt_ioc);
1698 * Device is reset now. It must have de-asserted the interrupt line
1699 * (if it was asserted) and it should be safe to register for the
1702 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1704 if (ioc->pcidev->irq) {
1705 if (mpt_msi_enable && !pci_enable_msi(ioc->pcidev))
1706 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
1708 rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
1709 IRQF_SHARED, ioc->name, ioc);
1711 printk(MYIOC_s_ERR_FMT "Unable to allocate "
1712 "interrupt %d!\n", ioc->name,
1715 pci_disable_msi(ioc->pcidev);
1719 ioc->pci_irq = ioc->pcidev->irq;
1720 pci_set_master(ioc->pcidev); /* ?? */
1721 pci_set_drvdata(ioc->pcidev, ioc);
1722 dprintk((KERN_INFO MYNAM ": %s installed at interrupt "
1723 "%d\n", ioc->name, ioc->pcidev->irq));
1727 /* Prime reply & request queues!
1728 * (mucho alloc's) Must be done prior to
1729 * init as upper addresses are needed for init.
1730 * If fails, continue with alt-ioc processing
1732 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
1735 /* May need to check/upload firmware & data here!
1736 * If fails, continue with alt-ioc processing
1738 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
1741 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
1742 printk(KERN_WARNING MYNAM ": alt-%s: (%d) FIFO mgmt alloc WARNING!\n",
1743 ioc->alt_ioc->name, rc);
1745 reset_alt_ioc_active = 0;
1748 if (alt_ioc_ready) {
1749 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
1751 reset_alt_ioc_active = 0;
1752 printk(KERN_WARNING MYNAM
1753 ": alt-%s: (%d) init failure WARNING!\n",
1754 ioc->alt_ioc->name, rc);
1758 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
1759 if (ioc->upload_fw) {
1760 ddlprintk((MYIOC_s_INFO_FMT
1761 "firmware upload required!\n", ioc->name));
1763 /* Controller is not operational, cannot do upload
1766 rc = mpt_do_upload(ioc, sleepFlag);
1768 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
1770 * Maintain only one pointer to FW memory
1771 * so there will not be two attempt to
1772 * downloadboot onboard dual function
1773 * chips (mpt_adapter_disable,
1776 ddlprintk((MYIOC_s_INFO_FMT ": mpt_upload: alt_%s has cached_fw=%p \n",
1777 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
1778 ioc->alt_ioc->cached_fw = NULL;
1781 printk(KERN_WARNING MYNAM ": firmware upload failure!\n");
1789 /* Enable! (reply interrupt) */
1790 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
1794 if (reset_alt_ioc_active && ioc->alt_ioc) {
1795 /* (re)Enable alt-IOC! (reply interrupt) */
1796 dinitprintk((KERN_INFO MYNAM ": alt-%s reply irq re-enabled\n",
1797 ioc->alt_ioc->name));
1798 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
1799 ioc->alt_ioc->active = 1;
1802 /* Enable MPT base driver management of EventNotification
1803 * and EventAck handling.
1805 if ((ret == 0) && (!ioc->facts.EventState))
1806 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
1808 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
1809 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
1811 /* Add additional "reason" check before call to GetLanConfigPages
1812 * (combined with GetIoUnitPage2 call). This prevents a somewhat
1813 * recursive scenario; GetLanConfigPages times out, timer expired
1814 * routine calls HardResetHandler, which calls into here again,
1815 * and we try GetLanConfigPages again...
1817 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
1818 if (ioc->bus_type == SAS) {
1820 /* clear persistency table */
1821 if(ioc->facts.IOCExceptions &
1822 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
1823 ret = mptbase_sas_persist_operation(ioc,
1824 MPI_SAS_OP_CLEAR_NOT_PRESENT);
1831 mpt_findImVolumes(ioc);
1833 } else if (ioc->bus_type == FC) {
1834 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
1835 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
1837 * Pre-fetch the ports LAN MAC address!
1838 * (LANPage1_t stuff)
1840 (void) GetLanConfigPages(ioc);
1843 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
1844 dprintk((MYIOC_s_INFO_FMT "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
1845 ioc->name, a[5], a[4], a[3], a[2], a[1], a[0] ));
1850 /* Get NVRAM and adapter maximums from SPP 0 and 2
1852 mpt_GetScsiPortSettings(ioc, 0);
1854 /* Get version and length of SDP 1
1856 mpt_readScsiDevicePageHeaders(ioc, 0);
1860 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
1861 mpt_findImVolumes(ioc);
1863 /* Check, and possibly reset, the coalescing value
1865 mpt_read_ioc_pg_1(ioc);
1867 mpt_read_ioc_pg_4(ioc);
1870 GetIoUnitPage2(ioc);
1874 * Call each currently registered protocol IOC reset handler
1875 * with post-reset indication.
1876 * NOTE: If we're doing _IOC_BRINGUP, there can be no
1877 * MptResetHandlers[] registered yet.
1879 if (hard_reset_done) {
1881 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
1882 if ((ret == 0) && MptResetHandlers[ii]) {
1883 dprintk((MYIOC_s_INFO_FMT "Calling IOC post_reset handler #%d\n",
1885 rc += mpt_signal_reset(ii, ioc, MPT_IOC_POST_RESET);
1889 if (alt_ioc_ready && MptResetHandlers[ii]) {
1890 drsprintk((MYIOC_s_INFO_FMT "Calling alt-%s post_reset handler #%d\n",
1891 ioc->name, ioc->alt_ioc->name, ii));
1892 rc += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_POST_RESET);
1896 /* FIXME? Examine results here? */
1900 if ((ret != 0) && irq_allocated) {
1901 free_irq(ioc->pci_irq, ioc);
1903 pci_disable_msi(ioc->pcidev);
1908 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1910 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
1911 * @ioc: Pointer to MPT adapter structure
1912 * @pdev: Pointer to (struct pci_dev) structure
1914 * Search for PCI bus/dev_function which matches
1915 * PCI bus/dev_function (+/-1) for newly discovered 929,
1916 * 929X, 1030 or 1035.
1918 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
1919 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
1922 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
1924 struct pci_dev *peer=NULL;
1925 unsigned int slot = PCI_SLOT(pdev->devfn);
1926 unsigned int func = PCI_FUNC(pdev->devfn);
1927 MPT_ADAPTER *ioc_srch;
1929 dprintk((MYIOC_s_INFO_FMT "PCI device %s devfn=%x/%x,"
1930 " searching for devfn match on %x or %x\n",
1931 ioc->name, pci_name(pdev), pdev->bus->number,
1932 pdev->devfn, func-1, func+1));
1934 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
1936 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
1941 list_for_each_entry(ioc_srch, &ioc_list, list) {
1942 struct pci_dev *_pcidev = ioc_srch->pcidev;
1943 if (_pcidev == peer) {
1944 /* Paranoia checks */
1945 if (ioc->alt_ioc != NULL) {
1946 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1947 ioc->name, ioc->alt_ioc->name);
1949 } else if (ioc_srch->alt_ioc != NULL) {
1950 printk(KERN_WARNING MYNAM ": Oops, already bound (%s <==> %s)!\n",
1951 ioc_srch->name, ioc_srch->alt_ioc->name);
1954 dprintk((KERN_INFO MYNAM ": FOUND! binding %s <==> %s\n",
1955 ioc->name, ioc_srch->name));
1956 ioc_srch->alt_ioc = ioc;
1957 ioc->alt_ioc = ioc_srch;
1963 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1965 * mpt_adapter_disable - Disable misbehaving MPT adapter.
1966 * @ioc: Pointer to MPT adapter structure
1969 mpt_adapter_disable(MPT_ADAPTER *ioc)
1974 if (ioc->cached_fw != NULL) {
1975 ddlprintk((KERN_INFO MYNAM ": mpt_adapter_disable: Pushing FW onto adapter\n"));
1976 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)ioc->cached_fw, NO_SLEEP)) < 0) {
1977 printk(KERN_WARNING MYNAM
1978 ": firmware downloadboot failure (%d)!\n", ret);
1982 /* Disable adapter interrupts! */
1983 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1985 /* Clear any lingering interrupt */
1986 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1988 if (ioc->alloc != NULL) {
1990 dexitprintk((KERN_INFO MYNAM ": %s.free @ %p, sz=%d bytes\n",
1991 ioc->name, ioc->alloc, ioc->alloc_sz));
1992 pci_free_consistent(ioc->pcidev, sz,
1993 ioc->alloc, ioc->alloc_dma);
1994 ioc->reply_frames = NULL;
1995 ioc->req_frames = NULL;
1997 ioc->alloc_total -= sz;
2000 if (ioc->sense_buf_pool != NULL) {
2001 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2002 pci_free_consistent(ioc->pcidev, sz,
2003 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2004 ioc->sense_buf_pool = NULL;
2005 ioc->alloc_total -= sz;
2008 if (ioc->events != NULL){
2009 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2012 ioc->alloc_total -= sz;
2015 if (ioc->cached_fw != NULL) {
2016 sz = ioc->facts.FWImageSize;
2017 pci_free_consistent(ioc->pcidev, sz,
2018 ioc->cached_fw, ioc->cached_fw_dma);
2019 ioc->cached_fw = NULL;
2020 ioc->alloc_total -= sz;
2023 kfree(ioc->spi_data.nvram);
2024 kfree(ioc->raid_data.pIocPg3);
2025 ioc->spi_data.nvram = NULL;
2026 ioc->raid_data.pIocPg3 = NULL;
2028 if (ioc->spi_data.pIocPg4 != NULL) {
2029 sz = ioc->spi_data.IocPg4Sz;
2030 pci_free_consistent(ioc->pcidev, sz,
2031 ioc->spi_data.pIocPg4,
2032 ioc->spi_data.IocPg4_dma);
2033 ioc->spi_data.pIocPg4 = NULL;
2034 ioc->alloc_total -= sz;
2037 if (ioc->ReqToChain != NULL) {
2038 kfree(ioc->ReqToChain);
2039 kfree(ioc->RequestNB);
2040 ioc->ReqToChain = NULL;
2043 kfree(ioc->ChainToChain);
2044 ioc->ChainToChain = NULL;
2046 if (ioc->HostPageBuffer != NULL) {
2047 if((ret = mpt_host_page_access_control(ioc,
2048 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2049 printk(KERN_ERR MYNAM
2050 ": %s: host page buffers free failed (%d)!\n",
2053 dexitprintk((KERN_INFO MYNAM ": %s HostPageBuffer free @ %p, sz=%d bytes\n",
2054 ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
2055 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2056 ioc->HostPageBuffer,
2057 ioc->HostPageBuffer_dma);
2058 ioc->HostPageBuffer = NULL;
2059 ioc->HostPageBuffer_sz = 0;
2060 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2064 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2066 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2067 * @ioc: Pointer to MPT adapter structure
2069 * This routine unregisters h/w resources and frees all alloc'd memory
2070 * associated with a MPT adapter structure.
2073 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2075 int sz_first, sz_last;
2080 sz_first = ioc->alloc_total;
2082 mpt_adapter_disable(ioc);
2084 if (ioc->pci_irq != -1) {
2085 free_irq(ioc->pci_irq, ioc);
2087 pci_disable_msi(ioc->pcidev);
2091 if (ioc->memmap != NULL) {
2092 iounmap(ioc->memmap);
2096 #if defined(CONFIG_MTRR) && 0
2097 if (ioc->mtrr_reg > 0) {
2098 mtrr_del(ioc->mtrr_reg, 0, 0);
2099 dprintk((KERN_INFO MYNAM ": %s: MTRR region de-registered\n", ioc->name));
2103 /* Zap the adapter lookup ptr! */
2104 list_del(&ioc->list);
2106 sz_last = ioc->alloc_total;
2107 dprintk((KERN_INFO MYNAM ": %s: free'd %d of %d bytes\n",
2108 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2111 ioc->alt_ioc->alt_ioc = NULL;
2116 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2118 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2119 * @ioc: Pointer to MPT adapter structure
2122 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2126 printk(KERN_INFO "%s: ", ioc->name);
2127 if (ioc->prod_name && strlen(ioc->prod_name) > 3)
2128 printk("%s: ", ioc->prod_name+3);
2129 printk("Capabilities={");
2131 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2132 printk("Initiator");
2136 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2137 printk("%sTarget", i ? "," : "");
2141 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2142 printk("%sLAN", i ? "," : "");
2148 * This would probably evoke more questions than it's worth
2150 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2151 printk("%sLogBusAddr", i ? "," : "");
2159 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2161 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2162 * @ioc: Pointer to MPT_ADAPTER structure
2163 * @force: Force hard KickStart of IOC
2164 * @sleepFlag: Specifies whether the process can sleep
2167 * 1 - DIAG reset and READY
2168 * 0 - READY initially OR soft reset and READY
2169 * -1 - Any failure on KickStart
2170 * -2 - Msg Unit Reset Failed
2171 * -3 - IO Unit Reset Failed
2172 * -4 - IOC owned by a PEER
2175 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2180 int hard_reset_done = 0;
2185 /* Get current [raw] IOC state */
2186 ioc_state = mpt_GetIocState(ioc, 0);
2187 dhsprintk((KERN_INFO MYNAM "::MakeIocReady, %s [raw] state=%08x\n", ioc->name, ioc_state));
2190 * Check to see if IOC got left/stuck in doorbell handshake
2191 * grip of death. If so, hard reset the IOC.
2193 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2195 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2199 /* Is it already READY? */
2200 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
2204 * Check to see if IOC is in FAULT state.
2206 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2208 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2210 printk(KERN_WARNING " FAULT code = %04xh\n",
2211 ioc_state & MPI_DOORBELL_DATA_MASK);
2215 * Hmmm... Did it get left operational?
2217 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2218 dinitprintk((MYIOC_s_INFO_FMT "IOC operational unexpected\n",
2222 * If PCI Peer, exit.
2223 * Else, if no fault conditions are present, issue a MessageUnitReset
2224 * Else, fall through to KickStart case
2226 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2227 dinitprintk((KERN_INFO MYNAM
2228 ": whoinit 0x%x statefault %d force %d\n",
2229 whoinit, statefault, force));
2230 if (whoinit == MPI_WHOINIT_PCI_PEER)
2233 if ((statefault == 0 ) && (force == 0)) {
2234 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2241 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2242 if (hard_reset_done < 0)
2246 * Loop here waiting for IOC to come READY.
2249 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2251 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2252 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2254 * BIOS or previous driver load left IOC in OP state.
2255 * Reset messaging FIFOs.
2257 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2258 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2261 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2263 * Something is wrong. Try to get IOC back
2266 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2267 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2274 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2275 ioc->name, (int)((ii+5)/HZ));
2279 if (sleepFlag == CAN_SLEEP) {
2282 mdelay (1); /* 1 msec delay */
2287 if (statefault < 3) {
2288 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2290 statefault==1 ? "stuck handshake" : "IOC FAULT");
2293 return hard_reset_done;
2296 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2298 * mpt_GetIocState - Get the current state of a MPT adapter.
2299 * @ioc: Pointer to MPT_ADAPTER structure
2300 * @cooked: Request raw or cooked IOC state
2302 * Returns all IOC Doorbell register bits if cooked==0, else just the
2303 * Doorbell bits in MPI_IOC_STATE_MASK.
2306 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2311 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2312 // dprintk((MYIOC_s_INFO_FMT "raw state = %08x\n", ioc->name, s));
2313 sc = s & MPI_IOC_STATE_MASK;
2316 ioc->last_state = sc;
2318 return cooked ? sc : s;
2321 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2323 * GetIocFacts - Send IOCFacts request to MPT adapter.
2324 * @ioc: Pointer to MPT_ADAPTER structure
2325 * @sleepFlag: Specifies whether the process can sleep
2326 * @reason: If recovery, only update facts.
2328 * Returns 0 for success, non-zero for failure.
2331 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2333 IOCFacts_t get_facts;
2334 IOCFactsReply_t *facts;
2342 /* IOC *must* NOT be in RESET state! */
2343 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2344 printk(KERN_ERR MYNAM ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
2350 facts = &ioc->facts;
2352 /* Destination (reply area)... */
2353 reply_sz = sizeof(*facts);
2354 memset(facts, 0, reply_sz);
2356 /* Request area (get_facts on the stack right now!) */
2357 req_sz = sizeof(get_facts);
2358 memset(&get_facts, 0, req_sz);
2360 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2361 /* Assert: All other get_facts fields are zero! */
2363 dinitprintk((MYIOC_s_INFO_FMT
2364 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2365 ioc->name, req_sz, reply_sz));
2367 /* No non-zero fields in the get_facts request are greater than
2368 * 1 byte in size, so we can just fire it off as is.
2370 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2371 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2376 * Now byte swap (GRRR) the necessary fields before any further
2377 * inspection of reply contents.
2379 * But need to do some sanity checks on MsgLength (byte) field
2380 * to make sure we don't zero IOC's req_sz!
2382 /* Did we get a valid reply? */
2383 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2384 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2386 * If not been here, done that, save off first WhoInit value
2388 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2389 ioc->FirstWhoInit = facts->WhoInit;
2392 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2393 facts->MsgContext = le32_to_cpu(facts->MsgContext);
2394 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2395 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2396 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2397 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
2398 /* CHECKME! IOCStatus, IOCLogInfo */
2400 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2401 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2404 * FC f/w version changed between 1.1 and 1.2
2405 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2406 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2408 if (facts->MsgVersion < 0x0102) {
2410 * Handle old FC f/w style, convert to new...
2412 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2413 facts->FWVersion.Word =
2414 ((oldv<<12) & 0xFF000000) |
2415 ((oldv<<8) & 0x000FFF00);
2417 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2419 facts->ProductID = le16_to_cpu(facts->ProductID);
2420 facts->CurrentHostMfaHighAddr =
2421 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2422 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2423 facts->CurrentSenseBufferHighAddr =
2424 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2425 facts->CurReplyFrameSize =
2426 le16_to_cpu(facts->CurReplyFrameSize);
2427 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
2430 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2431 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2432 * to 14 in MPI-1.01.0x.
2434 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2435 facts->MsgVersion > 0x0100) {
2436 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2439 sz = facts->FWImageSize;
2444 facts->FWImageSize = sz;
2446 if (!facts->RequestFrameSize) {
2447 /* Something is wrong! */
2448 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2453 r = sz = facts->BlockSize;
2454 vv = ((63 / (sz * 4)) + 1) & 0x03;
2455 ioc->NB_for_64_byte_frame = vv;
2461 ioc->NBShiftFactor = shiftFactor;
2462 dinitprintk((MYIOC_s_INFO_FMT "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2463 ioc->name, vv, shiftFactor, r));
2465 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2467 * Set values for this IOC's request & reply frame sizes,
2468 * and request & reply queue depths...
2470 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2471 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2472 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2473 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2475 dinitprintk((MYIOC_s_INFO_FMT "reply_sz=%3d, reply_depth=%4d\n",
2476 ioc->name, ioc->reply_sz, ioc->reply_depth));
2477 dinitprintk((MYIOC_s_INFO_FMT "req_sz =%3d, req_depth =%4d\n",
2478 ioc->name, ioc->req_sz, ioc->req_depth));
2480 /* Get port facts! */
2481 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2485 printk(MYIOC_s_ERR_FMT
2486 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2487 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2488 RequestFrameSize)/sizeof(u32)));
2495 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2497 * GetPortFacts - Send PortFacts request to MPT adapter.
2498 * @ioc: Pointer to MPT_ADAPTER structure
2499 * @portnum: Port number
2500 * @sleepFlag: Specifies whether the process can sleep
2502 * Returns 0 for success, non-zero for failure.
2505 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2507 PortFacts_t get_pfacts;
2508 PortFactsReply_t *pfacts;
2514 /* IOC *must* NOT be in RESET state! */
2515 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2516 printk(KERN_ERR MYNAM ": ERROR - Can't get PortFacts, %s NOT READY! (%08x)\n",
2522 pfacts = &ioc->pfacts[portnum];
2524 /* Destination (reply area)... */
2525 reply_sz = sizeof(*pfacts);
2526 memset(pfacts, 0, reply_sz);
2528 /* Request area (get_pfacts on the stack right now!) */
2529 req_sz = sizeof(get_pfacts);
2530 memset(&get_pfacts, 0, req_sz);
2532 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2533 get_pfacts.PortNumber = portnum;
2534 /* Assert: All other get_pfacts fields are zero! */
2536 dinitprintk((MYIOC_s_INFO_FMT "Sending get PortFacts(%d) request\n",
2537 ioc->name, portnum));
2539 /* No non-zero fields in the get_pfacts request are greater than
2540 * 1 byte in size, so we can just fire it off as is.
2542 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
2543 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
2547 /* Did we get a valid reply? */
2549 /* Now byte swap the necessary fields in the response. */
2550 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
2551 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
2552 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
2553 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
2554 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
2555 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
2556 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
2557 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
2558 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
2560 max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
2562 ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
2563 ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
2566 * Place all the devices on channels
2570 if (mpt_channel_mapping) {
2571 ioc->devices_per_bus = 1;
2572 ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
2578 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2580 * SendIocInit - Send IOCInit request to MPT adapter.
2581 * @ioc: Pointer to MPT_ADAPTER structure
2582 * @sleepFlag: Specifies whether the process can sleep
2584 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
2586 * Returns 0 for success, non-zero for failure.
2589 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
2592 MPIDefaultReply_t init_reply;
2598 memset(&ioc_init, 0, sizeof(ioc_init));
2599 memset(&init_reply, 0, sizeof(init_reply));
2601 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
2602 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
2604 /* If we are in a recovery mode and we uploaded the FW image,
2605 * then this pointer is not NULL. Skip the upload a second time.
2606 * Set this flag if cached_fw set for either IOC.
2608 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
2612 ddlprintk((MYIOC_s_INFO_FMT "upload_fw %d facts.Flags=%x\n",
2613 ioc->name, ioc->upload_fw, ioc->facts.Flags));
2615 ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
2616 ioc_init.MaxBuses = (U8)ioc->number_of_buses;
2617 dinitprintk((MYIOC_s_INFO_FMT "facts.MsgVersion=%x\n",
2618 ioc->name, ioc->facts.MsgVersion));
2619 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
2620 // set MsgVersion and HeaderVersion host driver was built with
2621 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
2622 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
2624 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
2625 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
2626 } else if(mpt_host_page_alloc(ioc, &ioc_init))
2629 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
2631 if (sizeof(dma_addr_t) == sizeof(u64)) {
2632 /* Save the upper 32-bits of the request
2633 * (reply) and sense buffers.
2635 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
2636 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
2638 /* Force 32-bit addressing */
2639 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
2640 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
2643 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
2644 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
2645 ioc->facts.MaxDevices = ioc_init.MaxDevices;
2646 ioc->facts.MaxBuses = ioc_init.MaxBuses;
2648 dhsprintk((MYIOC_s_INFO_FMT "Sending IOCInit (req @ %p)\n",
2649 ioc->name, &ioc_init));
2651 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
2652 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
2654 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
2658 /* No need to byte swap the multibyte fields in the reply
2659 * since we don't even look at its contents.
2662 dhsprintk((MYIOC_s_INFO_FMT "Sending PortEnable (req @ %p)\n",
2663 ioc->name, &ioc_init));
2665 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
2666 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
2670 /* YIKES! SUPER IMPORTANT!!!
2671 * Poll IocState until _OPERATIONAL while IOC is doing
2672 * LoopInit and TargetDiscovery!
2675 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
2676 state = mpt_GetIocState(ioc, 1);
2677 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
2678 if (sleepFlag == CAN_SLEEP) {
2685 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
2686 ioc->name, (int)((count+5)/HZ));
2690 state = mpt_GetIocState(ioc, 1);
2693 dinitprintk((MYIOC_s_INFO_FMT "INFO - Wait IOC_OPERATIONAL state (cnt=%d)\n",
2696 ioc->aen_event_read_flag=0;
2700 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2702 * SendPortEnable - Send PortEnable request to MPT adapter port.
2703 * @ioc: Pointer to MPT_ADAPTER structure
2704 * @portnum: Port number to enable
2705 * @sleepFlag: Specifies whether the process can sleep
2707 * Send PortEnable to bring IOC to OPERATIONAL state.
2709 * Returns 0 for success, non-zero for failure.
2712 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2714 PortEnable_t port_enable;
2715 MPIDefaultReply_t reply_buf;
2720 /* Destination... */
2721 reply_sz = sizeof(MPIDefaultReply_t);
2722 memset(&reply_buf, 0, reply_sz);
2724 req_sz = sizeof(PortEnable_t);
2725 memset(&port_enable, 0, req_sz);
2727 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
2728 port_enable.PortNumber = portnum;
2729 /* port_enable.ChainOffset = 0; */
2730 /* port_enable.MsgFlags = 0; */
2731 /* port_enable.MsgContext = 0; */
2733 dinitprintk((MYIOC_s_INFO_FMT "Sending Port(%d)Enable (req @ %p)\n",
2734 ioc->name, portnum, &port_enable));
2736 /* RAID FW may take a long time to enable
2738 if (((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
2739 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI) ||
2740 (ioc->bus_type == SAS)) {
2741 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
2742 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
2743 300 /*seconds*/, sleepFlag);
2745 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
2746 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
2747 30 /*seconds*/, sleepFlag);
2753 * mpt_alloc_fw_memory - allocate firmware memory
2754 * @ioc: Pointer to MPT_ADAPTER structure
2755 * @size: total FW bytes
2757 * If memory has already been allocated, the same (cached) value
2761 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
2764 return; /* use already allocated memory */
2765 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2766 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
2767 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
2768 ioc->alloc_total += size;
2769 ioc->alt_ioc->alloc_total -= size;
2771 if ( (ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma) ) )
2772 ioc->alloc_total += size;
2776 * mpt_free_fw_memory - free firmware memory
2777 * @ioc: Pointer to MPT_ADAPTER structure
2779 * If alt_img is NULL, delete from ioc structure.
2780 * Else, delete a secondary image in same format.
2783 mpt_free_fw_memory(MPT_ADAPTER *ioc)
2787 sz = ioc->facts.FWImageSize;
2788 dinitprintk((KERN_INFO MYNAM "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
2789 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2790 pci_free_consistent(ioc->pcidev, sz,
2791 ioc->cached_fw, ioc->cached_fw_dma);
2792 ioc->cached_fw = NULL;
2798 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2800 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
2801 * @ioc: Pointer to MPT_ADAPTER structure
2802 * @sleepFlag: Specifies whether the process can sleep
2804 * Returns 0 for success, >0 for handshake failure
2805 * <0 for fw upload failure.
2807 * Remark: If bound IOC and a successful FWUpload was performed
2808 * on the bound IOC, the second image is discarded
2809 * and memory is free'd. Both channels must upload to prevent
2810 * IOC from running in degraded mode.
2813 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
2815 u8 request[ioc->req_sz];
2816 u8 reply[sizeof(FWUploadReply_t)];
2817 FWUpload_t *prequest;
2818 FWUploadReply_t *preply;
2819 FWUploadTCSGE_t *ptcsge;
2822 int ii, sz, reply_sz;
2825 /* If the image size is 0, we are done.
2827 if ((sz = ioc->facts.FWImageSize) == 0)
2830 mpt_alloc_fw_memory(ioc, sz);
2832 dinitprintk((KERN_INFO MYNAM ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
2833 ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
2835 if (ioc->cached_fw == NULL) {
2841 prequest = (FWUpload_t *)&request;
2842 preply = (FWUploadReply_t *)&reply;
2844 /* Destination... */
2845 memset(prequest, 0, ioc->req_sz);
2847 reply_sz = sizeof(reply);
2848 memset(preply, 0, reply_sz);
2850 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
2851 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
2853 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
2854 ptcsge->DetailsLength = 12;
2855 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
2856 ptcsge->ImageSize = cpu_to_le32(sz);
2858 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
2860 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
2861 mpt_add_sge(&request[sgeoffset], flagsLength, ioc->cached_fw_dma);
2863 sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
2864 dinitprintk((KERN_INFO MYNAM ": Sending FW Upload (req @ %p) sgeoffset=%d \n",
2865 prequest, sgeoffset));
2866 DBG_DUMP_FW_REQUEST_FRAME(prequest)
2868 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
2869 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
2871 dinitprintk((KERN_INFO MYNAM ": FW Upload completed rc=%x \n", ii));
2873 cmdStatus = -EFAULT;
2875 /* Handshake transfer was complete and successful.
2876 * Check the Reply Frame.
2878 int status, transfer_sz;
2879 status = le16_to_cpu(preply->IOCStatus);
2880 if (status == MPI_IOCSTATUS_SUCCESS) {
2881 transfer_sz = le32_to_cpu(preply->ActualImageSize);
2882 if (transfer_sz == sz)
2886 dinitprintk((MYIOC_s_INFO_FMT ": do_upload cmdStatus=%d \n",
2887 ioc->name, cmdStatus));
2892 ddlprintk((MYIOC_s_INFO_FMT ": fw upload failed, freeing image \n",
2894 mpt_free_fw_memory(ioc);
2900 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2902 * mpt_downloadboot - DownloadBoot code
2903 * @ioc: Pointer to MPT_ADAPTER structure
2904 * @pFwHeader: Pointer to firmware header info
2905 * @sleepFlag: Specifies whether the process can sleep
2907 * FwDownloadBoot requires Programmed IO access.
2909 * Returns 0 for success
2910 * -1 FW Image size is 0
2911 * -2 No valid cached_fw Pointer
2912 * <0 for fw upload failure.
2915 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
2917 MpiExtImageHeader_t *pExtImage;
2927 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
2928 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
2930 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2931 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2932 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2933 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2934 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2935 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2937 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
2940 if (sleepFlag == CAN_SLEEP) {
2946 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2947 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
2949 for (count = 0; count < 30; count ++) {
2950 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
2951 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
2952 ddlprintk((MYIOC_s_INFO_FMT "RESET_ADAPTER cleared, count=%d\n",
2957 if (sleepFlag == CAN_SLEEP) {
2964 if ( count == 30 ) {
2965 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! "
2966 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
2967 ioc->name, diag0val));
2971 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
2972 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
2973 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
2974 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
2975 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
2976 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
2978 /* Set the DiagRwEn and Disable ARM bits */
2979 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
2981 fwSize = (pFwHeader->ImageSize + 3)/4;
2982 ptrFw = (u32 *) pFwHeader;
2984 /* Write the LoadStartAddress to the DiagRw Address Register
2985 * using Programmed IO
2987 if (ioc->errata_flag_1064)
2988 pci_enable_io_access(ioc->pcidev);
2990 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
2991 ddlprintk((MYIOC_s_INFO_FMT "LoadStart addr written 0x%x \n",
2992 ioc->name, pFwHeader->LoadStartAddress));
2994 ddlprintk((MYIOC_s_INFO_FMT "Write FW Image: 0x%x bytes @ %p\n",
2995 ioc->name, fwSize*4, ptrFw));
2997 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3000 nextImage = pFwHeader->NextImageHeaderOffset;
3002 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3004 load_addr = pExtImage->LoadStartAddress;
3006 fwSize = (pExtImage->ImageSize + 3) >> 2;
3007 ptrFw = (u32 *)pExtImage;
3009 ddlprintk((MYIOC_s_INFO_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3010 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3011 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3014 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3016 nextImage = pExtImage->NextImageHeaderOffset;
3019 /* Write the IopResetVectorRegAddr */
3020 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
3021 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3023 /* Write the IopResetVectorValue */
3024 ddlprintk((MYIOC_s_INFO_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3025 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3027 /* Clear the internal flash bad bit - autoincrementing register,
3028 * so must do two writes.
3030 if (ioc->bus_type == SPI) {
3032 * 1030 and 1035 H/W errata, workaround to access
3033 * the ClearFlashBadSignatureBit
3035 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3036 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3037 diagRwData |= 0x40000000;
3038 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3039 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3041 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3042 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3043 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3044 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3047 if (sleepFlag == CAN_SLEEP) {
3054 if (ioc->errata_flag_1064)
3055 pci_disable_io_access(ioc->pcidev);
3057 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3058 ddlprintk((MYIOC_s_INFO_FMT "downloadboot diag0val=%x, "
3059 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3060 ioc->name, diag0val));
3061 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3062 ddlprintk((MYIOC_s_INFO_FMT "downloadboot now diag0val=%x\n",
3063 ioc->name, diag0val));
3064 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3066 /* Write 0xFF to reset the sequencer */
3067 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3069 if (ioc->bus_type == SAS) {
3070 ioc_state = mpt_GetIocState(ioc, 0);
3071 if ( (GetIocFacts(ioc, sleepFlag,
3072 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3073 ddlprintk((MYIOC_s_INFO_FMT "GetIocFacts failed: IocState=%x\n",
3074 ioc->name, ioc_state));
3079 for (count=0; count<HZ*20; count++) {
3080 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3081 ddlprintk((MYIOC_s_INFO_FMT "downloadboot successful! (count=%d) IocState=%x\n",
3082 ioc->name, count, ioc_state));
3083 if (ioc->bus_type == SAS) {
3086 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3087 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit failed\n",
3091 ddlprintk((MYIOC_s_INFO_FMT "downloadboot: SendIocInit successful\n",
3095 if (sleepFlag == CAN_SLEEP) {
3101 ddlprintk((MYIOC_s_INFO_FMT "downloadboot failed! IocState=%x\n",
3102 ioc->name, ioc_state));
3106 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3108 * KickStart - Perform hard reset of MPT adapter.
3109 * @ioc: Pointer to MPT_ADAPTER structure
3110 * @force: Force hard reset
3111 * @sleepFlag: Specifies whether the process can sleep
3113 * This routine places MPT adapter in diagnostic mode via the
3114 * WriteSequence register, and then performs a hard reset of adapter
3115 * via the Diagnostic register.
3117 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3118 * or NO_SLEEP (interrupt thread, use mdelay)
3119 * force - 1 if doorbell active, board fault state
3120 * board operational, IOC_RECOVERY or
3121 * IOC_BRINGUP and there is an alt_ioc.
3125 * 1 - hard reset, READY
3126 * 0 - no reset due to History bit, READY
3127 * -1 - no reset due to History bit but not READY
3128 * OR reset but failed to come READY
3129 * -2 - no reset, could not enter DIAG mode
3130 * -3 - reset but bad FW bit
3133 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3135 int hard_reset_done = 0;
3139 dinitprintk((KERN_WARNING MYNAM ": KickStarting %s!\n", ioc->name));
3140 if (ioc->bus_type == SPI) {
3141 /* Always issue a Msg Unit Reset first. This will clear some
3142 * SCSI bus hang conditions.
3144 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3146 if (sleepFlag == CAN_SLEEP) {
3153 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3154 if (hard_reset_done < 0)
3155 return hard_reset_done;
3157 dinitprintk((MYIOC_s_INFO_FMT "Diagnostic reset successful!\n",
3160 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3161 for (cnt=0; cnt<cntdn; cnt++) {
3162 ioc_state = mpt_GetIocState(ioc, 1);
3163 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3164 dinitprintk((MYIOC_s_INFO_FMT "KickStart successful! (cnt=%d)\n",
3166 return hard_reset_done;
3168 if (sleepFlag == CAN_SLEEP) {
3175 printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3176 ioc->name, ioc_state);
3180 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3182 * mpt_diag_reset - Perform hard reset of the adapter.
3183 * @ioc: Pointer to MPT_ADAPTER structure
3184 * @ignore: Set if to honor and clear to ignore
3185 * the reset history bit
3186 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3187 * else set to NO_SLEEP (use mdelay instead)
3189 * This routine places the adapter in diagnostic mode via the
3190 * WriteSequence register and then performs a hard reset of adapter
3191 * via the Diagnostic register. Adapter should be in ready state
3192 * upon successful completion.
3194 * Returns: 1 hard reset successful
3195 * 0 no reset performed because reset history bit set
3196 * -2 enabling diagnostic mode failed
3197 * -3 diagnostic reset failed
3200 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3202 MPT_ADAPTER *iocp=NULL;
3205 int hard_reset_done = 0;
3211 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3212 drsprintk((MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3213 "address=%p\n", ioc->name, __FUNCTION__,
3214 &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3215 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3216 if (sleepFlag == CAN_SLEEP)
3221 for (count = 0; count < 60; count ++) {
3222 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3223 doorbell &= MPI_IOC_STATE_MASK;
3225 drsprintk((MYIOC_s_INFO_FMT
3226 "looking for READY STATE: doorbell=%x"
3228 ioc->name, doorbell, count));
3229 if (doorbell == MPI_IOC_STATE_READY) {
3234 if (sleepFlag == CAN_SLEEP)
3242 /* Clear any existing interrupts */
3243 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3245 /* Use "Diagnostic reset" method! (only thing available!) */
3246 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3250 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3251 dprintk((MYIOC_s_INFO_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3252 ioc->name, diag0val, diag1val));
3255 /* Do the reset if we are told to ignore the reset history
3256 * or if the reset history is 0
3258 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3259 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3260 /* Write magic sequence to WriteSequence register
3261 * Loop until in diagnostic mode
3263 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3264 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3265 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3266 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3267 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3268 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3271 if (sleepFlag == CAN_SLEEP) {
3279 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3280 ioc->name, diag0val);
3285 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3287 dprintk((MYIOC_s_INFO_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3288 ioc->name, diag0val));
3293 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3294 dprintk((MYIOC_s_INFO_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3295 ioc->name, diag0val, diag1val));
3298 * Disable the ARM (Bug fix)
3301 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3305 * Now hit the reset bit in the Diagnostic register
3306 * (THE BIG HAMMER!) (Clears DRWE bit).
3308 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3309 hard_reset_done = 1;
3310 dprintk((MYIOC_s_INFO_FMT "Diagnostic reset performed\n",
3314 * Call each currently registered protocol IOC reset handler
3315 * with pre-reset indication.
3316 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3317 * MptResetHandlers[] registered yet.
3323 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
3324 if (MptResetHandlers[ii]) {
3325 dprintk((MYIOC_s_INFO_FMT "Calling IOC pre_reset handler #%d\n",
3327 r += mpt_signal_reset(ii, ioc, MPT_IOC_PRE_RESET);
3329 dprintk((MYIOC_s_INFO_FMT "Calling alt-%s pre_reset handler #%d\n",
3330 ioc->name, ioc->alt_ioc->name, ii));
3331 r += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_PRE_RESET);
3335 /* FIXME? Examine results here? */
3340 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
3341 iocp = ioc->alt_ioc;
3343 /* If the DownloadBoot operation fails, the
3344 * IOC will be left unusable. This is a fatal error
3345 * case. _diag_reset will return < 0
3347 for (count = 0; count < 30; count ++) {
3348 diag0val = CHIPREG_READ32(&iocp->chip->Diagnostic);
3349 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3353 dprintk((MYIOC_s_INFO_FMT "cached_fw: diag0val=%x count=%d\n",
3354 iocp->name, diag0val, count));
3356 if (sleepFlag == CAN_SLEEP) {
3362 if ((count = mpt_downloadboot(ioc,
3363 (MpiFwHeader_t *)iocp->cached_fw, sleepFlag)) < 0) {
3364 printk(KERN_WARNING MYNAM
3365 ": firmware downloadboot failure (%d)!\n", count);
3369 /* Wait for FW to reload and for board
3370 * to go to the READY state.
3371 * Maximum wait is 60 seconds.
3372 * If fail, no error will check again
3373 * with calling program.
3375 for (count = 0; count < 60; count ++) {
3376 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3377 doorbell &= MPI_IOC_STATE_MASK;
3379 if (doorbell == MPI_IOC_STATE_READY) {
3384 if (sleepFlag == CAN_SLEEP) {
3393 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3396 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3397 dprintk((MYIOC_s_INFO_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3398 ioc->name, diag0val, diag1val));
3401 /* Clear RESET_HISTORY bit! Place board in the
3402 * diagnostic mode to update the diag register.
3404 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3406 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3407 /* Write magic sequence to WriteSequence register
3408 * Loop until in diagnostic mode
3410 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3411 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3412 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3413 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3414 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3415 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3418 if (sleepFlag == CAN_SLEEP) {
3426 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3427 ioc->name, diag0val);
3430 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3432 diag0val &= ~MPI_DIAG_RESET_HISTORY;
3433 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3434 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3435 if (diag0val & MPI_DIAG_RESET_HISTORY) {
3436 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3440 /* Disable Diagnostic Mode
3442 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3444 /* Check FW reload status flags.
3446 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3447 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3448 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3449 ioc->name, diag0val);
3455 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3456 dprintk((MYIOC_s_INFO_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3457 ioc->name, diag0val, diag1val));
3461 * Reset flag that says we've enabled event notification
3463 ioc->facts.EventState = 0;
3466 ioc->alt_ioc->facts.EventState = 0;
3468 return hard_reset_done;
3471 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3473 * SendIocReset - Send IOCReset request to MPT adapter.
3474 * @ioc: Pointer to MPT_ADAPTER structure
3475 * @reset_type: reset type, expected values are
3476 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3477 * @sleepFlag: Specifies whether the process can sleep
3479 * Send IOCReset request to the MPT adapter.
3481 * Returns 0 for success, non-zero for failure.
3484 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3490 drsprintk((KERN_INFO MYNAM ": %s: Sending IOC reset(0x%02x)!\n",
3491 ioc->name, reset_type));
3492 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3493 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3496 /* FW ACK'd request, wait for READY state
3499 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
3501 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3505 if (sleepFlag != CAN_SLEEP)
3508 printk(KERN_ERR MYNAM ": %s: ERROR - Wait IOC_READY state timeout(%d)!\n",
3509 ioc->name, (int)((count+5)/HZ));
3513 if (sleepFlag == CAN_SLEEP) {
3516 mdelay (1); /* 1 msec delay */
3521 * Cleanup all event stuff for this IOC; re-issue EventNotification
3522 * request if needed.
3524 if (ioc->facts.Function)
3525 ioc->facts.EventState = 0;
3530 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3532 * initChainBuffers - Allocate memory for and initialize chain buffers
3533 * @ioc: Pointer to MPT_ADAPTER structure
3535 * Allocates memory for and initializes chain buffers,
3536 * chain buffer control arrays and spinlock.
3539 initChainBuffers(MPT_ADAPTER *ioc)
3542 int sz, ii, num_chain;
3543 int scale, num_sge, numSGE;
3545 /* ReqToChain size must equal the req_depth
3548 if (ioc->ReqToChain == NULL) {
3549 sz = ioc->req_depth * sizeof(int);
3550 mem = kmalloc(sz, GFP_ATOMIC);
3554 ioc->ReqToChain = (int *) mem;
3555 dinitprintk((KERN_INFO MYNAM ": %s ReqToChain alloc @ %p, sz=%d bytes\n",
3556 ioc->name, mem, sz));
3557 mem = kmalloc(sz, GFP_ATOMIC);
3561 ioc->RequestNB = (int *) mem;
3562 dinitprintk((KERN_INFO MYNAM ": %s RequestNB alloc @ %p, sz=%d bytes\n",
3563 ioc->name, mem, sz));
3565 for (ii = 0; ii < ioc->req_depth; ii++) {
3566 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
3569 /* ChainToChain size must equal the total number
3570 * of chain buffers to be allocated.
3573 * Calculate the number of chain buffers needed(plus 1) per I/O
3574 * then multiply the the maximum number of simultaneous cmds
3576 * num_sge = num sge in request frame + last chain buffer
3577 * scale = num sge per chain buffer if no chain element
3579 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
3580 if (sizeof(dma_addr_t) == sizeof(u64))
3581 num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3583 num_sge = 1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3585 if (sizeof(dma_addr_t) == sizeof(u64)) {
3586 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3587 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
3589 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
3590 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
3592 dinitprintk((KERN_INFO MYNAM ": %s num_sge=%d numSGE=%d\n",
3593 ioc->name, num_sge, numSGE));
3595 if ( numSGE > MPT_SCSI_SG_DEPTH )
3596 numSGE = MPT_SCSI_SG_DEPTH;
3599 while (numSGE - num_sge > 0) {
3601 num_sge += (scale - 1);
3605 dinitprintk((KERN_INFO MYNAM ": %s Now numSGE=%d num_sge=%d num_chain=%d\n",
3606 ioc->name, numSGE, num_sge, num_chain));
3608 if (ioc->bus_type == SPI)
3609 num_chain *= MPT_SCSI_CAN_QUEUE;
3611 num_chain *= MPT_FC_CAN_QUEUE;
3613 ioc->num_chain = num_chain;
3615 sz = num_chain * sizeof(int);
3616 if (ioc->ChainToChain == NULL) {
3617 mem = kmalloc(sz, GFP_ATOMIC);
3621 ioc->ChainToChain = (int *) mem;
3622 dinitprintk((KERN_INFO MYNAM ": %s ChainToChain alloc @ %p, sz=%d bytes\n",
3623 ioc->name, mem, sz));
3625 mem = (u8 *) ioc->ChainToChain;
3627 memset(mem, 0xFF, sz);
3631 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3633 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
3634 * @ioc: Pointer to MPT_ADAPTER structure
3636 * This routine allocates memory for the MPT reply and request frame
3637 * pools (if necessary), and primes the IOC reply FIFO with
3640 * Returns 0 for success, non-zero for failure.
3643 PrimeIocFifos(MPT_ADAPTER *ioc)
3646 unsigned long flags;
3647 dma_addr_t alloc_dma;
3649 int i, reply_sz, sz, total_size, num_chain;
3651 /* Prime reply FIFO... */
3653 if (ioc->reply_frames == NULL) {
3654 if ( (num_chain = initChainBuffers(ioc)) < 0)
3657 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
3658 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
3659 ioc->name, ioc->reply_sz, ioc->reply_depth));
3660 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffer sz=%d[%x] bytes\n",
3661 ioc->name, reply_sz, reply_sz));
3663 sz = (ioc->req_sz * ioc->req_depth);
3664 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d bytes, RequestDepth=%d\n",
3665 ioc->name, ioc->req_sz, ioc->req_depth));
3666 dinitprintk((KERN_INFO MYNAM ": %s.RequestBuffer sz=%d[%x] bytes\n",
3667 ioc->name, sz, sz));
3670 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
3671 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d bytes, ChainDepth=%d\n",
3672 ioc->name, ioc->req_sz, num_chain));
3673 dinitprintk((KERN_INFO MYNAM ": %s.ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
3674 ioc->name, sz, sz, num_chain));
3677 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
3679 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
3684 dinitprintk((KERN_INFO MYNAM ": %s.Total alloc @ %p[%p], sz=%d[%x] bytes\n",
3685 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
3687 memset(mem, 0, total_size);
3688 ioc->alloc_total += total_size;
3690 ioc->alloc_dma = alloc_dma;
3691 ioc->alloc_sz = total_size;
3692 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
3693 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3695 dinitprintk((KERN_INFO MYNAM ": %s ReplyBuffers @ %p[%p]\n",
3696 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3698 alloc_dma += reply_sz;
3701 /* Request FIFO - WE manage this! */
3703 ioc->req_frames = (MPT_FRAME_HDR *) mem;
3704 ioc->req_frames_dma = alloc_dma;
3706 dinitprintk((KERN_INFO MYNAM ": %s RequestBuffers @ %p[%p]\n",
3707 ioc->name, mem, (void *)(ulong)alloc_dma));
3709 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
3711 #if defined(CONFIG_MTRR) && 0
3713 * Enable Write Combining MTRR for IOC's memory region.
3714 * (at least as much as we can; "size and base must be
3715 * multiples of 4 kiB"
3717 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
3719 MTRR_TYPE_WRCOMB, 1);
3720 dprintk((MYIOC_s_INFO_FMT "MTRR region registered (base:size=%08x:%x)\n",
3721 ioc->name, ioc->req_frames_dma, sz));
3724 for (i = 0; i < ioc->req_depth; i++) {
3725 alloc_dma += ioc->req_sz;
3729 ioc->ChainBuffer = mem;
3730 ioc->ChainBufferDMA = alloc_dma;
3732 dinitprintk((KERN_INFO MYNAM " :%s ChainBuffers @ %p(%p)\n",
3733 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
3735 /* Initialize the free chain Q.
3738 INIT_LIST_HEAD(&ioc->FreeChainQ);
3740 /* Post the chain buffers to the FreeChainQ.
3742 mem = (u8 *)ioc->ChainBuffer;
3743 for (i=0; i < num_chain; i++) {
3744 mf = (MPT_FRAME_HDR *) mem;
3745 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
3749 /* Initialize Request frames linked list
3751 alloc_dma = ioc->req_frames_dma;
3752 mem = (u8 *) ioc->req_frames;
3754 spin_lock_irqsave(&ioc->FreeQlock, flags);
3755 INIT_LIST_HEAD(&ioc->FreeQ);
3756 for (i = 0; i < ioc->req_depth; i++) {
3757 mf = (MPT_FRAME_HDR *) mem;
3759 /* Queue REQUESTs *internally*! */
3760 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
3764 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
3766 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3767 ioc->sense_buf_pool =
3768 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
3769 if (ioc->sense_buf_pool == NULL) {
3770 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
3775 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
3776 ioc->alloc_total += sz;
3777 dinitprintk((KERN_INFO MYNAM ": %s.SenseBuffers @ %p[%p]\n",
3778 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
3782 /* Post Reply frames to FIFO
3784 alloc_dma = ioc->alloc_dma;
3785 dinitprintk((KERN_INFO MYNAM ": %s.ReplyBuffers @ %p[%p]\n",
3786 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
3788 for (i = 0; i < ioc->reply_depth; i++) {
3789 /* Write each address to the IOC! */
3790 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
3791 alloc_dma += ioc->reply_sz;
3797 if (ioc->alloc != NULL) {
3799 pci_free_consistent(ioc->pcidev,
3801 ioc->alloc, ioc->alloc_dma);
3802 ioc->reply_frames = NULL;
3803 ioc->req_frames = NULL;
3804 ioc->alloc_total -= sz;
3806 if (ioc->sense_buf_pool != NULL) {
3807 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
3808 pci_free_consistent(ioc->pcidev,
3810 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
3811 ioc->sense_buf_pool = NULL;
3816 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3818 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
3819 * from IOC via doorbell handshake method.
3820 * @ioc: Pointer to MPT_ADAPTER structure
3821 * @reqBytes: Size of the request in bytes
3822 * @req: Pointer to MPT request frame
3823 * @replyBytes: Expected size of the reply in bytes
3824 * @u16reply: Pointer to area where reply should be written
3825 * @maxwait: Max wait time for a reply (in seconds)
3826 * @sleepFlag: Specifies whether the process can sleep
3828 * NOTES: It is the callers responsibility to byte-swap fields in the
3829 * request which are greater than 1 byte in size. It is also the
3830 * callers responsibility to byte-swap response fields which are
3831 * greater than 1 byte in size.
3833 * Returns 0 for success, non-zero for failure.
3836 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
3837 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
3839 MPIDefaultReply_t *mptReply;
3844 * Get ready to cache a handshake reply
3846 ioc->hs_reply_idx = 0;
3847 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
3848 mptReply->MsgLength = 0;
3851 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
3852 * then tell IOC that we want to handshake a request of N words.
3853 * (WRITE u32val to Doorbell reg).
3855 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3856 CHIPREG_WRITE32(&ioc->chip->Doorbell,
3857 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
3858 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
3861 * Wait for IOC's doorbell handshake int
3863 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
3866 dhsprintk((MYIOC_s_INFO_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
3867 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
3869 /* Read doorbell and check for active bit */
3870 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
3874 * Clear doorbell int (WRITE 0 to IntStatus reg),
3875 * then wait for IOC to ACKnowledge that it's ready for
3876 * our handshake request.
3878 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3879 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3884 u8 *req_as_bytes = (u8 *) req;
3887 * Stuff request words via doorbell handshake,
3888 * with ACK from IOC for each.
3890 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
3891 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
3892 (req_as_bytes[(ii*4) + 1] << 8) |
3893 (req_as_bytes[(ii*4) + 2] << 16) |
3894 (req_as_bytes[(ii*4) + 3] << 24));
3896 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
3897 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3901 dhsprintk((KERN_INFO MYNAM ": Handshake request frame (@%p) header\n", req));
3902 DBG_DUMP_REQUEST_FRAME_HDR(req)
3904 dhsprintk((MYIOC_s_INFO_FMT "HandShake request post done, WaitCnt=%d%s\n",
3905 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
3908 * Wait for completion of doorbell handshake reply from the IOC
3910 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
3913 dhsprintk((MYIOC_s_INFO_FMT "HandShake reply count=%d%s\n",
3914 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
3917 * Copy out the cached reply...
3919 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
3920 u16reply[ii] = ioc->hs_reply[ii];
3928 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3930 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
3931 * @ioc: Pointer to MPT_ADAPTER structure
3932 * @howlong: How long to wait (in seconds)
3933 * @sleepFlag: Specifies whether the process can sleep
3935 * This routine waits (up to ~2 seconds max) for IOC doorbell
3936 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
3937 * bit in its IntStatus register being clear.
3939 * Returns a negative value on failure, else wait loop count.
3942 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3948 cntdn = 1000 * howlong;
3950 if (sleepFlag == CAN_SLEEP) {
3953 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3954 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3961 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
3962 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
3969 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell ACK (count=%d)\n",
3974 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
3975 ioc->name, count, intstat);
3979 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3981 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
3982 * @ioc: Pointer to MPT_ADAPTER structure
3983 * @howlong: How long to wait (in seconds)
3984 * @sleepFlag: Specifies whether the process can sleep
3986 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
3987 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
3989 * Returns a negative value on failure, else wait loop count.
3992 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
3998 cntdn = 1000 * howlong;
3999 if (sleepFlag == CAN_SLEEP) {
4001 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4002 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4009 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4010 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4018 dprintk((MYIOC_s_INFO_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4019 ioc->name, count, howlong));
4023 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4024 ioc->name, count, intstat);
4028 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4030 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4031 * @ioc: Pointer to MPT_ADAPTER structure
4032 * @howlong: How long to wait (in seconds)
4033 * @sleepFlag: Specifies whether the process can sleep
4035 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4036 * Reply is cached to IOC private area large enough to hold a maximum
4037 * of 128 bytes of reply data.
4039 * Returns a negative value on failure, else size of reply in WORDS.
4042 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4047 u16 *hs_reply = ioc->hs_reply;
4048 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4051 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4054 * Get first two u16's so we can look at IOC's intended reply MsgLength
4057 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4060 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4061 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4062 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4065 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4066 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4070 dhsprintk((MYIOC_s_INFO_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4071 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4072 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4075 * If no error (and IOC said MsgLength is > 0), piece together
4076 * reply 16 bits at a time.
4078 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4079 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4081 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4082 /* don't overflow our IOC hs_reply[] buffer! */
4083 if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
4084 hs_reply[u16cnt] = hword;
4085 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4088 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4090 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4093 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4098 else if (u16cnt != (2 * mptReply->MsgLength)) {
4101 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4106 dhsprintk((MYIOC_s_INFO_FMT "Got Handshake reply:\n", ioc->name));
4107 DBG_DUMP_REPLY_FRAME(mptReply)
4109 dhsprintk((MYIOC_s_INFO_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4110 ioc->name, t, u16cnt/2));
4114 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4116 * GetLanConfigPages - Fetch LANConfig pages.
4117 * @ioc: Pointer to MPT_ADAPTER structure
4119 * Return: 0 for success
4120 * -ENOMEM if no memory available
4121 * -EPERM if not allowed due to ISR context
4122 * -EAGAIN if no msg frames currently available
4123 * -EFAULT for non-successful reply or no reply (timeout)
4126 GetLanConfigPages(MPT_ADAPTER *ioc)
4128 ConfigPageHeader_t hdr;
4130 LANPage0_t *ppage0_alloc;
4131 dma_addr_t page0_dma;
4132 LANPage1_t *ppage1_alloc;
4133 dma_addr_t page1_dma;
4138 /* Get LAN Page 0 header */
4139 hdr.PageVersion = 0;
4142 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4143 cfg.cfghdr.hdr = &hdr;
4145 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4150 if ((rc = mpt_config(ioc, &cfg)) != 0)
4153 if (hdr.PageLength > 0) {
4154 data_sz = hdr.PageLength * 4;
4155 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4158 memset((u8 *)ppage0_alloc, 0, data_sz);
4159 cfg.physAddr = page0_dma;
4160 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4162 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4164 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4165 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4169 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4172 * Normalize endianness of structure data,
4173 * by byte-swapping all > 1 byte fields!
4182 /* Get LAN Page 1 header */
4183 hdr.PageVersion = 0;
4186 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4187 cfg.cfghdr.hdr = &hdr;
4189 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4193 if ((rc = mpt_config(ioc, &cfg)) != 0)
4196 if (hdr.PageLength == 0)
4199 data_sz = hdr.PageLength * 4;
4201 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4203 memset((u8 *)ppage1_alloc, 0, data_sz);
4204 cfg.physAddr = page1_dma;
4205 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4207 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4209 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4210 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4213 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4216 * Normalize endianness of structure data,
4217 * by byte-swapping all > 1 byte fields!
4225 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4227 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
4228 * @ioc: Pointer to MPT_ADAPTER structure
4229 * @persist_opcode: see below
4231 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4232 * devices not currently present.
4233 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4235 * NOTE: Don't use not this function during interrupt time.
4237 * Returns 0 for success, non-zero error
4240 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4242 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4244 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
4245 SasIoUnitControlReply_t *sasIoUnitCntrReply;
4246 MPT_FRAME_HDR *mf = NULL;
4247 MPIHeader_t *mpi_hdr;
4250 /* insure garbage is not sent to fw */
4251 switch(persist_opcode) {
4253 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
4254 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
4262 printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode);
4264 /* Get a MF for this command.
4266 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4267 printk("%s: no msg frames!\n",__FUNCTION__);
4271 mpi_hdr = (MPIHeader_t *) mf;
4272 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
4273 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
4274 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
4275 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
4276 sasIoUnitCntrReq->Operation = persist_opcode;
4278 init_timer(&ioc->persist_timer);
4279 ioc->persist_timer.data = (unsigned long) ioc;
4280 ioc->persist_timer.function = mpt_timer_expired;
4281 ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
4282 ioc->persist_wait_done=0;
4283 add_timer(&ioc->persist_timer);
4284 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4285 wait_event(mpt_waitq, ioc->persist_wait_done);
4287 sasIoUnitCntrReply =
4288 (SasIoUnitControlReply_t *)ioc->persist_reply_frame;
4289 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
4290 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4292 sasIoUnitCntrReply->IOCStatus,
4293 sasIoUnitCntrReply->IOCLogInfo);
4297 printk("%s: success\n",__FUNCTION__);
4301 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4304 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
4305 MpiEventDataRaid_t * pRaidEventData)
4314 volume = pRaidEventData->VolumeID;
4315 reason = pRaidEventData->ReasonCode;
4316 disk = pRaidEventData->PhysDiskNum;
4317 status = le32_to_cpu(pRaidEventData->SettingsStatus);
4318 flags = (status >> 0) & 0xff;
4319 state = (status >> 8) & 0xff;
4321 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
4325 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
4326 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
4327 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
4328 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d\n",
4331 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
4336 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4337 printk(MYIOC_s_INFO_FMT " volume has been created\n",
4341 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4343 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
4347 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
4348 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
4352 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4353 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
4355 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
4357 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
4359 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
4362 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
4364 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
4365 ? ", quiesced" : "",
4366 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
4367 ? ", resync in progress" : "" );
4370 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
4371 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
4375 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4376 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
4380 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4381 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
4385 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
4386 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
4390 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4391 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
4393 state == MPI_PHYSDISK0_STATUS_ONLINE
4395 : state == MPI_PHYSDISK0_STATUS_MISSING
4397 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
4399 : state == MPI_PHYSDISK0_STATUS_FAILED
4401 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
4403 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
4404 ? "offline requested"
4405 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
4406 ? "failed requested"
4407 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
4410 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
4411 ? ", out of sync" : "",
4412 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
4413 ? ", quiesced" : "" );
4416 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
4417 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
4421 case MPI_EVENT_RAID_RC_SMART_DATA:
4422 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
4423 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
4426 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
4427 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
4433 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4435 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4436 * @ioc: Pointer to MPT_ADAPTER structure
4438 * Returns: 0 for success
4439 * -ENOMEM if no memory available
4440 * -EPERM if not allowed due to ISR context
4441 * -EAGAIN if no msg frames currently available
4442 * -EFAULT for non-successful reply or no reply (timeout)
4445 GetIoUnitPage2(MPT_ADAPTER *ioc)
4447 ConfigPageHeader_t hdr;
4449 IOUnitPage2_t *ppage_alloc;
4450 dma_addr_t page_dma;
4454 /* Get the page header */
4455 hdr.PageVersion = 0;
4458 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4459 cfg.cfghdr.hdr = &hdr;
4461 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4466 if ((rc = mpt_config(ioc, &cfg)) != 0)
4469 if (hdr.PageLength == 0)
4472 /* Read the config page */
4473 data_sz = hdr.PageLength * 4;
4475 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4477 memset((u8 *)ppage_alloc, 0, data_sz);
4478 cfg.physAddr = page_dma;
4479 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4481 /* If Good, save data */
4482 if ((rc = mpt_config(ioc, &cfg)) == 0)
4483 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4485 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4491 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4493 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4494 * @ioc: Pointer to a Adapter Strucutre
4495 * @portnum: IOC port number
4497 * Return: -EFAULT if read of config page header fails
4499 * If read of SCSI Port Page 0 fails,
4500 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4501 * Adapter settings: async, narrow
4503 * If read of SCSI Port Page 2 fails,
4504 * Adapter settings valid
4505 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4510 * CHECK - what type of locking mechanisms should be used????
4513 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4518 ConfigPageHeader_t header;
4524 if (!ioc->spi_data.nvram) {
4527 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
4528 mem = kmalloc(sz, GFP_ATOMIC);
4532 ioc->spi_data.nvram = (int *) mem;
4534 dprintk((MYIOC_s_INFO_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
4535 ioc->name, ioc->spi_data.nvram, sz));
4538 /* Invalidate NVRAM information
4540 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4541 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
4544 /* Read SPP0 header, allocate memory, then read page.
4546 header.PageVersion = 0;
4547 header.PageLength = 0;
4548 header.PageNumber = 0;
4549 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4550 cfg.cfghdr.hdr = &header;
4552 cfg.pageAddr = portnum;
4553 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4555 cfg.timeout = 0; /* use default */
4556 if (mpt_config(ioc, &cfg) != 0)
4559 if (header.PageLength > 0) {
4560 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4562 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4563 cfg.physAddr = buf_dma;
4564 if (mpt_config(ioc, &cfg) != 0) {
4565 ioc->spi_data.maxBusWidth = MPT_NARROW;
4566 ioc->spi_data.maxSyncOffset = 0;
4567 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4568 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
4570 ddvprintk((MYIOC_s_INFO_FMT "Unable to read PortPage0 minSyncFactor=%x\n",
4571 ioc->name, ioc->spi_data.minSyncFactor));
4573 /* Save the Port Page 0 data
4575 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
4576 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
4577 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
4579 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
4580 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
4581 ddvprintk((KERN_INFO MYNAM " :%s noQas due to Capabilities=%x\n",
4582 ioc->name, pPP0->Capabilities));
4584 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
4585 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
4587 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
4588 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
4589 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
4590 ddvprintk((MYIOC_s_INFO_FMT "PortPage0 minSyncFactor=%x\n",
4591 ioc->name, ioc->spi_data.minSyncFactor));
4593 ioc->spi_data.maxSyncOffset = 0;
4594 ioc->spi_data.minSyncFactor = MPT_ASYNC;
4597 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
4599 /* Update the minSyncFactor based on bus type.
4601 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
4602 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
4604 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
4605 ioc->spi_data.minSyncFactor = MPT_ULTRA;
4606 ddvprintk((MYIOC_s_INFO_FMT "HVD or SE detected, minSyncFactor=%x\n",
4607 ioc->name, ioc->spi_data.minSyncFactor));
4612 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4617 /* SCSI Port Page 2 - Read the header then the page.
4619 header.PageVersion = 0;
4620 header.PageLength = 0;
4621 header.PageNumber = 2;
4622 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
4623 cfg.cfghdr.hdr = &header;
4625 cfg.pageAddr = portnum;
4626 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4628 if (mpt_config(ioc, &cfg) != 0)
4631 if (header.PageLength > 0) {
4632 /* Allocate memory and read SCSI Port Page 2
4634 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
4636 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
4637 cfg.physAddr = buf_dma;
4638 if (mpt_config(ioc, &cfg) != 0) {
4639 /* Nvram data is left with INVALID mark
4643 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
4644 MpiDeviceInfo_t *pdevice = NULL;
4647 * Save "Set to Avoid SCSI Bus Resets" flag
4649 ioc->spi_data.bus_reset =
4650 (le32_to_cpu(pPP2->PortFlags) &
4651 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
4654 /* Save the Port Page 2 data
4655 * (reformat into a 32bit quantity)
4657 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
4658 ioc->spi_data.PortFlags = data;
4659 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4660 pdevice = &pPP2->DeviceSettings[ii];
4661 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
4662 (pdevice->SyncFactor << 8) | pdevice->Timeout;
4663 ioc->spi_data.nvram[ii] = data;
4667 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
4671 /* Update Adapter limits with those from NVRAM
4672 * Comment: Don't need to do this. Target performance
4673 * parameters will never exceed the adapters limits.
4679 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4681 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
4682 * @ioc: Pointer to a Adapter Strucutre
4683 * @portnum: IOC port number
4685 * Return: -EFAULT if read of config page header fails
4689 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
4692 ConfigPageHeader_t header;
4694 /* Read the SCSI Device Page 1 header
4696 header.PageVersion = 0;
4697 header.PageLength = 0;
4698 header.PageNumber = 1;
4699 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4700 cfg.cfghdr.hdr = &header;
4702 cfg.pageAddr = portnum;
4703 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4706 if (mpt_config(ioc, &cfg) != 0)
4709 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
4710 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
4712 header.PageVersion = 0;
4713 header.PageLength = 0;
4714 header.PageNumber = 0;
4715 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4716 if (mpt_config(ioc, &cfg) != 0)
4719 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
4720 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
4722 dcprintk((MYIOC_s_INFO_FMT "Headers: 0: version %d length %d\n",
4723 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
4725 dcprintk((MYIOC_s_INFO_FMT "Headers: 1: version %d length %d\n",
4726 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
4730 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4732 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
4733 * @ioc: Pointer to a Adapter Strucutre
4734 * @portnum: IOC port number
4738 * -EFAULT if read of config page header fails or data pointer not NULL
4739 * -ENOMEM if pci_alloc failed
4742 mpt_findImVolumes(MPT_ADAPTER *ioc)
4746 ConfigPageIoc2RaidVol_t *pIocRv;
4747 dma_addr_t ioc2_dma;
4749 ConfigPageHeader_t header;
4756 /* Read IOCP2 header then the page.
4758 header.PageVersion = 0;
4759 header.PageLength = 0;
4760 header.PageNumber = 2;
4761 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4762 cfg.cfghdr.hdr = &header;
4765 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4768 if (mpt_config(ioc, &cfg) != 0)
4771 if (header.PageLength == 0)
4774 iocpage2sz = header.PageLength * 4;
4775 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
4779 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4780 cfg.physAddr = ioc2_dma;
4781 if (mpt_config(ioc, &cfg) != 0)
4784 if ( (mem = (u8 *)ioc->raid_data.pIocPg2) == NULL ) {
4785 mem = kmalloc(iocpage2sz, GFP_ATOMIC);
4787 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
4792 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
4794 /* Identify RAID Volume Id's */
4795 nVols = pIoc2->NumActiveVolumes;
4801 /* At least 1 RAID Volume
4803 pIocRv = pIoc2->RaidVolume;
4804 ioc->raid_data.isRaid = 0;
4805 for (jj = 0; jj < nVols; jj++, pIocRv++) {
4806 vid = pIocRv->VolumeID;
4807 vbus = pIocRv->VolumeBus;
4808 vioc = pIocRv->VolumeIOC;
4813 ioc->raid_data.isRaid |= (1 << vid);
4815 /* Error! Always bus 0
4821 /* Identify Hidden Physical Disk Id's */
4822 nPhys = pIoc2->NumActivePhysDisks;
4824 /* No physical disks.
4827 mpt_read_ioc_pg_3(ioc);
4831 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
4837 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
4842 ConfigPageHeader_t header;
4843 dma_addr_t ioc3_dma;
4846 /* Free the old page
4848 kfree(ioc->raid_data.pIocPg3);
4849 ioc->raid_data.pIocPg3 = NULL;
4851 /* There is at least one physical disk.
4852 * Read and save IOC Page 3
4854 header.PageVersion = 0;
4855 header.PageLength = 0;
4856 header.PageNumber = 3;
4857 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4858 cfg.cfghdr.hdr = &header;
4861 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4864 if (mpt_config(ioc, &cfg) != 0)
4867 if (header.PageLength == 0)
4870 /* Read Header good, alloc memory
4872 iocpage3sz = header.PageLength * 4;
4873 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
4877 /* Read the Page and save the data
4878 * into malloc'd memory.
4880 cfg.physAddr = ioc3_dma;
4881 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4882 if (mpt_config(ioc, &cfg) == 0) {
4883 mem = kmalloc(iocpage3sz, GFP_ATOMIC);
4885 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
4886 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
4890 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
4896 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
4900 ConfigPageHeader_t header;
4901 dma_addr_t ioc4_dma;
4904 /* Read and save IOC Page 4
4906 header.PageVersion = 0;
4907 header.PageLength = 0;
4908 header.PageNumber = 4;
4909 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4910 cfg.cfghdr.hdr = &header;
4913 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4916 if (mpt_config(ioc, &cfg) != 0)
4919 if (header.PageLength == 0)
4922 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
4923 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
4924 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
4927 ioc->alloc_total += iocpage4sz;
4929 ioc4_dma = ioc->spi_data.IocPg4_dma;
4930 iocpage4sz = ioc->spi_data.IocPg4Sz;
4933 /* Read the Page into dma memory.
4935 cfg.physAddr = ioc4_dma;
4936 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4937 if (mpt_config(ioc, &cfg) == 0) {
4938 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
4939 ioc->spi_data.IocPg4_dma = ioc4_dma;
4940 ioc->spi_data.IocPg4Sz = iocpage4sz;
4942 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
4943 ioc->spi_data.pIocPg4 = NULL;
4944 ioc->alloc_total -= iocpage4sz;
4949 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
4953 ConfigPageHeader_t header;
4954 dma_addr_t ioc1_dma;
4958 /* Check the Coalescing Timeout in IOC Page 1
4960 header.PageVersion = 0;
4961 header.PageLength = 0;
4962 header.PageNumber = 1;
4963 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
4964 cfg.cfghdr.hdr = &header;
4967 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4970 if (mpt_config(ioc, &cfg) != 0)
4973 if (header.PageLength == 0)
4976 /* Read Header good, alloc memory
4978 iocpage1sz = header.PageLength * 4;
4979 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
4983 /* Read the Page and check coalescing timeout
4985 cfg.physAddr = ioc1_dma;
4986 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4987 if (mpt_config(ioc, &cfg) == 0) {
4989 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
4990 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
4991 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
4993 dprintk((MYIOC_s_INFO_FMT "Coalescing Enabled Timeout = %d\n",
4996 if (tmp > MPT_COALESCING_TIMEOUT) {
4997 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
4999 /* Write NVRAM and current
5002 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5003 if (mpt_config(ioc, &cfg) == 0) {
5004 dprintk((MYIOC_s_INFO_FMT "Reset Current Coalescing Timeout to = %d\n",
5005 ioc->name, MPT_COALESCING_TIMEOUT));
5007 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
5008 if (mpt_config(ioc, &cfg) == 0) {
5009 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout to = %d\n",
5010 ioc->name, MPT_COALESCING_TIMEOUT));
5012 dprintk((MYIOC_s_INFO_FMT "Reset NVRAM Coalescing Timeout Failed\n",
5017 dprintk((MYIOC_s_WARN_FMT "Reset of Current Coalescing Timeout Failed!\n",
5023 dprintk((MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
5027 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
5032 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5034 * SendEventNotification - Send EventNotification (on or off) request to adapter
5035 * @ioc: Pointer to MPT_ADAPTER structure
5036 * @EvSwitch: Event switch flags
5039 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
5041 EventNotification_t *evnp;
5043 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
5045 devtverboseprintk((MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
5049 memset(evnp, 0, sizeof(*evnp));
5051 devtverboseprintk((MYIOC_s_INFO_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
5053 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
5054 evnp->ChainOffset = 0;
5056 evnp->Switch = EvSwitch;
5058 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
5063 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5065 * SendEventAck - Send EventAck request to MPT adapter.
5066 * @ioc: Pointer to MPT_ADAPTER structure
5067 * @evnp: Pointer to original EventNotification request
5070 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
5074 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5075 dfailprintk((MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
5076 ioc->name,__FUNCTION__));
5080 devtverboseprintk((MYIOC_s_INFO_FMT "Sending EventAck\n", ioc->name));
5082 pAck->Function = MPI_FUNCTION_EVENT_ACK;
5083 pAck->ChainOffset = 0;
5084 pAck->Reserved[0] = pAck->Reserved[1] = 0;
5086 pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
5087 pAck->Event = evnp->Event;
5088 pAck->EventContext = evnp->EventContext;
5090 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
5095 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5097 * mpt_config - Generic function to issue config message
5098 * @ioc: Pointer to an adapter structure
5099 * @pCfg: Pointer to a configuration structure. Struct contains
5100 * action, page address, direction, physical address
5101 * and pointer to a configuration page header
5102 * Page header is updated.
5104 * Returns 0 for success
5105 * -EPERM if not allowed due to ISR context
5106 * -EAGAIN if no msg frames currently available
5107 * -EFAULT for non-successful reply or no reply (timeout)
5110 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5113 ConfigExtendedPageHeader_t *pExtHdr = NULL;
5115 unsigned long flags;
5120 /* Prevent calling wait_event() (below), if caller happens
5121 * to be in ISR context, because that is fatal!
5123 in_isr = in_interrupt();
5125 dcprintk((MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
5130 /* Get and Populate a free Frame
5132 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5133 dcprintk((MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
5137 pReq = (Config_t *)mf;
5138 pReq->Action = pCfg->action;
5140 pReq->ChainOffset = 0;
5141 pReq->Function = MPI_FUNCTION_CONFIG;
5143 /* Assume page type is not extended and clear "reserved" fields. */
5144 pReq->ExtPageLength = 0;
5145 pReq->ExtPageType = 0;
5148 for (ii=0; ii < 8; ii++)
5149 pReq->Reserved2[ii] = 0;
5151 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
5152 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
5153 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
5154 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
5156 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5157 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
5158 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
5159 pReq->ExtPageType = pExtHdr->ExtPageType;
5160 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
5162 /* Page Length must be treated as a reserved field for the extended header. */
5163 pReq->Header.PageLength = 0;
5166 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
5168 /* Add a SGE to the config request.
5171 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
5173 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
5175 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5176 flagsLength |= pExtHdr->ExtPageLength * 4;
5178 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
5179 ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action));
5182 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
5184 dcprintk((MYIOC_s_INFO_FMT "Sending Config request type %d, page %d and action %d\n",
5185 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
5188 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
5190 /* Append pCfg pointer to end of mf
5192 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5194 /* Initalize the timer
5196 init_timer(&pCfg->timer);
5197 pCfg->timer.data = (unsigned long) ioc;
5198 pCfg->timer.function = mpt_timer_expired;
5199 pCfg->wait_done = 0;
5201 /* Set the timer; ensure 10 second minimum */
5202 if (pCfg->timeout < 10)
5203 pCfg->timer.expires = jiffies + HZ*10;
5205 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5207 /* Add to end of Q, set timer and then issue this command */
5208 spin_lock_irqsave(&ioc->FreeQlock, flags);
5209 list_add_tail(&pCfg->linkage, &ioc->configQ);
5210 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5212 add_timer(&pCfg->timer);
5213 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5214 wait_event(mpt_waitq, pCfg->wait_done);
5216 /* mf has been freed - do not access */
5223 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5225 * mpt_timer_expired - Callback for timer process.
5226 * Used only internal config functionality.
5227 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5230 mpt_timer_expired(unsigned long data)
5232 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
5234 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired! \n", ioc->name));
5236 /* Perform a FW reload */
5237 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
5238 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
5240 /* No more processing.
5241 * Hard reset clean-up will wake up
5242 * process and free all resources.
5244 dcprintk((MYIOC_s_WARN_FMT "mpt_timer_expired complete!\n", ioc->name));
5249 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5251 * mpt_ioc_reset - Base cleanup for hard reset
5252 * @ioc: Pointer to the adapter structure
5253 * @reset_phase: Indicates pre- or post-reset functionality
5255 * Remark: Frees resources with internally generated commands.
5258 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
5261 unsigned long flags;
5263 dprintk((KERN_WARNING MYNAM
5264 ": IOC %s_reset routed to MPT base driver!\n",
5265 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
5266 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
5268 if (reset_phase == MPT_IOC_SETUP_RESET) {
5270 } else if (reset_phase == MPT_IOC_PRE_RESET) {
5271 /* If the internal config Q is not empty -
5272 * delete timer. MF resources will be freed when
5273 * the FIFO's are primed.
5275 spin_lock_irqsave(&ioc->FreeQlock, flags);
5276 list_for_each_entry(pCfg, &ioc->configQ, linkage)
5277 del_timer(&pCfg->timer);
5278 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5283 /* Search the configQ for internal commands.
5284 * Flush the Q, and wake up all suspended threads.
5286 spin_lock_irqsave(&ioc->FreeQlock, flags);
5287 list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
5288 list_del(&pCfg->linkage);
5290 pCfg->status = MPT_CONFIG_ERROR;
5291 pCfg->wait_done = 1;
5292 wake_up(&mpt_waitq);
5294 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5297 return 1; /* currently means nothing really */
5301 #ifdef CONFIG_PROC_FS /* { */
5302 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5304 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
5306 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5308 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
5310 * Returns 0 for success, non-zero for failure.
5313 procmpt_create(void)
5315 struct proc_dir_entry *ent;
5317 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
5318 if (mpt_proc_root_dir == NULL)
5321 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5323 ent->read_proc = procmpt_summary_read;
5325 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
5327 ent->read_proc = procmpt_version_read;
5332 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5334 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
5336 * Returns 0 for success, non-zero for failure.
5339 procmpt_destroy(void)
5341 remove_proc_entry("version", mpt_proc_root_dir);
5342 remove_proc_entry("summary", mpt_proc_root_dir);
5343 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
5346 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5348 * procmpt_summary_read - Handle read request of a summary file
5349 * @buf: Pointer to area to write information
5350 * @start: Pointer to start pointer
5351 * @offset: Offset to start writing
5352 * @request: Amount of read data requested
5353 * @eof: Pointer to EOF integer
5356 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
5357 * Returns number of characters written to process performing the read.
5360 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5370 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5374 list_for_each_entry(ioc, &ioc_list, list) {
5377 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
5380 if ((out-buf) >= request)
5387 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5390 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5392 * procmpt_version_read - Handle read request from /proc/mpt/version.
5393 * @buf: Pointer to area to write information
5394 * @start: Pointer to start pointer
5395 * @offset: Offset to start writing
5396 * @request: Amount of read data requested
5397 * @eof: Pointer to EOF integer
5400 * Returns number of characters written to process performing the read.
5403 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5406 int scsi, fc, sas, lan, ctl, targ, dmp;
5410 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
5411 len += sprintf(buf+len, " Fusion MPT base driver\n");
5413 scsi = fc = sas = lan = ctl = targ = dmp = 0;
5414 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5416 if (MptCallbacks[ii]) {
5417 switch (MptDriverClass[ii]) {
5419 if (!scsi++) drvname = "SPI host";
5422 if (!fc++) drvname = "FC host";
5425 if (!sas++) drvname = "SAS host";
5428 if (!lan++) drvname = "LAN";
5431 if (!targ++) drvname = "SCSI target";
5434 if (!ctl++) drvname = "ioctl";
5439 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
5443 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5446 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5448 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
5449 * @buf: Pointer to area to write information
5450 * @start: Pointer to start pointer
5451 * @offset: Offset to start writing
5452 * @request: Amount of read data requested
5453 * @eof: Pointer to EOF integer
5456 * Returns number of characters written to process performing the read.
5459 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
5461 MPT_ADAPTER *ioc = data;
5467 mpt_get_fw_exp_ver(expVer, ioc);
5469 len = sprintf(buf, "%s:", ioc->name);
5470 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
5471 len += sprintf(buf+len, " (f/w download boot flag set)");
5472 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
5473 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
5475 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
5476 ioc->facts.ProductID,
5478 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
5479 if (ioc->facts.FWImageSize)
5480 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
5481 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
5482 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
5483 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
5485 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
5486 ioc->facts.CurrentHostMfaHighAddr);
5487 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
5488 ioc->facts.CurrentSenseBufferHighAddr);
5490 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
5491 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
5493 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
5494 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
5496 * Rounding UP to nearest 4-kB boundary here...
5498 sz = (ioc->req_sz * ioc->req_depth) + 128;
5499 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
5500 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
5501 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
5502 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
5503 4*ioc->facts.RequestFrameSize,
5504 ioc->facts.GlobalCredits);
5506 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
5507 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
5508 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
5509 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
5510 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
5511 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
5512 ioc->facts.CurReplyFrameSize,
5513 ioc->facts.ReplyQueueDepth);
5515 len += sprintf(buf+len, " MaxDevices = %d\n",
5516 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
5517 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
5520 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
5521 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
5523 ioc->facts.NumberOfPorts);
5524 if (ioc->bus_type == FC) {
5525 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
5526 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5527 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
5528 a[5], a[4], a[3], a[2], a[1], a[0]);
5530 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
5531 ioc->fc_port_page0[p].WWNN.High,
5532 ioc->fc_port_page0[p].WWNN.Low,
5533 ioc->fc_port_page0[p].WWPN.High,
5534 ioc->fc_port_page0[p].WWPN.Low);
5538 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
5541 #endif /* CONFIG_PROC_FS } */
5543 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5545 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
5548 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
5549 sprintf(buf, " (Exp %02d%02d)",
5550 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
5551 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
5554 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
5555 strcat(buf, " [MDBG]");
5559 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5561 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
5562 * @ioc: Pointer to MPT_ADAPTER structure
5563 * @buffer: Pointer to buffer where IOC summary info should be written
5564 * @size: Pointer to number of bytes we wrote (set by this routine)
5565 * @len: Offset at which to start writing in buffer
5566 * @showlan: Display LAN stuff?
5568 * This routine writes (english readable) ASCII text, which represents
5569 * a summary of IOC information, to a buffer.
5572 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
5577 mpt_get_fw_exp_ver(expVer, ioc);
5580 * Shorter summary of attached ioc's...
5582 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
5585 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
5586 ioc->facts.FWVersion.Word,
5588 ioc->facts.NumberOfPorts,
5591 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
5592 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
5593 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
5594 a[5], a[4], a[3], a[2], a[1], a[0]);
5597 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
5600 y += sprintf(buffer+len+y, " (disabled)");
5602 y += sprintf(buffer+len+y, "\n");
5607 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5611 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5613 * mpt_HardResetHandler - Generic reset handler
5614 * @ioc: Pointer to MPT_ADAPTER structure
5615 * @sleepFlag: Indicates if sleep or schedule must be called.
5617 * Issues SCSI Task Management call based on input arg values.
5618 * If TaskMgmt fails, returns associated SCSI request.
5620 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
5621 * or a non-interrupt thread. In the former, must not call schedule().
5623 * Note: A return of -1 is a FATAL error case, as it means a
5624 * FW reload/initialization failed.
5626 * Returns 0 for SUCCESS or -1 if FAILED.
5629 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
5632 unsigned long flags;
5634 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name));
5636 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
5637 printk("MF count 0x%x !\n", ioc->mfcnt);
5640 /* Reset the adapter. Prevent more than 1 call to
5641 * mpt_do_ioc_recovery at any instant in time.
5643 spin_lock_irqsave(&ioc->diagLock, flags);
5644 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
5645 spin_unlock_irqrestore(&ioc->diagLock, flags);
5648 ioc->diagPending = 1;
5650 spin_unlock_irqrestore(&ioc->diagLock, flags);
5652 /* FIXME: If do_ioc_recovery fails, repeat....
5655 /* The SCSI driver needs to adjust timeouts on all current
5656 * commands prior to the diagnostic reset being issued.
5657 * Prevents timeouts occurring during a diagnostic reset...very bad.
5658 * For all other protocol drivers, this is a no-op.
5664 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
5665 if (MptResetHandlers[ii]) {
5666 dtmprintk((MYIOC_s_INFO_FMT "Calling IOC reset_setup handler #%d\n",
5668 r += mpt_signal_reset(ii, ioc, MPT_IOC_SETUP_RESET);
5670 dtmprintk((MYIOC_s_INFO_FMT "Calling alt-%s setup reset handler #%d\n",
5671 ioc->name, ioc->alt_ioc->name, ii));
5672 r += mpt_signal_reset(ii, ioc->alt_ioc, MPT_IOC_SETUP_RESET);
5678 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
5679 printk(KERN_WARNING MYNAM ": WARNING - (%d) Cannot recover %s\n",
5684 ioc->alt_ioc->reload_fw = 0;
5686 spin_lock_irqsave(&ioc->diagLock, flags);
5687 ioc->diagPending = 0;
5689 ioc->alt_ioc->diagPending = 0;
5690 spin_unlock_irqrestore(&ioc->diagLock, flags);
5692 dtmprintk((MYIOC_s_INFO_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
5697 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5699 EventDescriptionStr(u8 event, u32 evData0, char *evStr)
5704 case MPI_EVENT_NONE:
5707 case MPI_EVENT_LOG_DATA:
5710 case MPI_EVENT_STATE_CHANGE:
5711 ds = "State Change";
5713 case MPI_EVENT_UNIT_ATTENTION:
5714 ds = "Unit Attention";
5716 case MPI_EVENT_IOC_BUS_RESET:
5717 ds = "IOC Bus Reset";
5719 case MPI_EVENT_EXT_BUS_RESET:
5720 ds = "External Bus Reset";
5722 case MPI_EVENT_RESCAN:
5723 ds = "Bus Rescan Event";
5725 case MPI_EVENT_LINK_STATUS_CHANGE:
5726 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
5727 ds = "Link Status(FAILURE) Change";
5729 ds = "Link Status(ACTIVE) Change";
5731 case MPI_EVENT_LOOP_STATE_CHANGE:
5732 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
5733 ds = "Loop State(LIP) Change";
5734 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
5735 ds = "Loop State(LPE) Change"; /* ??? */
5737 ds = "Loop State(LPB) Change"; /* ??? */
5739 case MPI_EVENT_LOGOUT:
5742 case MPI_EVENT_EVENT_CHANGE:
5748 case MPI_EVENT_INTEGRATED_RAID:
5750 u8 ReasonCode = (u8)(evData0 >> 16);
5751 switch (ReasonCode) {
5752 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
5753 ds = "Integrated Raid: Volume Created";
5755 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
5756 ds = "Integrated Raid: Volume Deleted";
5758 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
5759 ds = "Integrated Raid: Volume Settings Changed";
5761 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
5762 ds = "Integrated Raid: Volume Status Changed";
5764 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
5765 ds = "Integrated Raid: Volume Physdisk Changed";
5767 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
5768 ds = "Integrated Raid: Physdisk Created";
5770 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
5771 ds = "Integrated Raid: Physdisk Deleted";
5773 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
5774 ds = "Integrated Raid: Physdisk Settings Changed";
5776 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
5777 ds = "Integrated Raid: Physdisk Status Changed";
5779 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
5780 ds = "Integrated Raid: Domain Validation Needed";
5782 case MPI_EVENT_RAID_RC_SMART_DATA :
5783 ds = "Integrated Raid; Smart Data";
5785 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
5786 ds = "Integrated Raid: Replace Action Started";
5789 ds = "Integrated Raid";
5794 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
5795 ds = "SCSI Device Status Change";
5797 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
5799 u8 id = (u8)(evData0);
5800 u8 channel = (u8)(evData0 >> 8);
5801 u8 ReasonCode = (u8)(evData0 >> 16);
5802 switch (ReasonCode) {
5803 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
5804 snprintf(evStr, EVENT_DESCR_STR_SZ,
5805 "SAS Device Status Change: Added: "
5806 "id=%d channel=%d", id, channel);
5808 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
5809 snprintf(evStr, EVENT_DESCR_STR_SZ,
5810 "SAS Device Status Change: Deleted: "
5811 "id=%d channel=%d", id, channel);
5813 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
5814 snprintf(evStr, EVENT_DESCR_STR_SZ,
5815 "SAS Device Status Change: SMART Data: "
5816 "id=%d channel=%d", id, channel);
5818 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
5819 snprintf(evStr, EVENT_DESCR_STR_SZ,
5820 "SAS Device Status Change: No Persistancy: "
5821 "id=%d channel=%d", id, channel);
5823 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
5824 snprintf(evStr, EVENT_DESCR_STR_SZ,
5825 "SAS Device Status Change: Unsupported Device "
5826 "Discovered : id=%d channel=%d", id, channel);
5828 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
5829 snprintf(evStr, EVENT_DESCR_STR_SZ,
5830 "SAS Device Status Change: Internal Device "
5831 "Reset : id=%d channel=%d", id, channel);
5833 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
5834 snprintf(evStr, EVENT_DESCR_STR_SZ,
5835 "SAS Device Status Change: Internal Task "
5836 "Abort : id=%d channel=%d", id, channel);
5838 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
5839 snprintf(evStr, EVENT_DESCR_STR_SZ,
5840 "SAS Device Status Change: Internal Abort "
5841 "Task Set : id=%d channel=%d", id, channel);
5843 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
5844 snprintf(evStr, EVENT_DESCR_STR_SZ,
5845 "SAS Device Status Change: Internal Clear "
5846 "Task Set : id=%d channel=%d", id, channel);
5848 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
5849 snprintf(evStr, EVENT_DESCR_STR_SZ,
5850 "SAS Device Status Change: Internal Query "
5851 "Task : id=%d channel=%d", id, channel);
5854 snprintf(evStr, EVENT_DESCR_STR_SZ,
5855 "SAS Device Status Change: Unknown: "
5856 "id=%d channel=%d", id, channel);
5861 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
5862 ds = "Bus Timer Expired";
5864 case MPI_EVENT_QUEUE_FULL:
5866 u16 curr_depth = (u16)(evData0 >> 16);
5867 u8 channel = (u8)(evData0 >> 8);
5868 u8 id = (u8)(evData0);
5870 snprintf(evStr, EVENT_DESCR_STR_SZ,
5871 "Queue Full: channel=%d id=%d depth=%d",
5872 channel, id, curr_depth);
5875 case MPI_EVENT_SAS_SES:
5876 ds = "SAS SES Event";
5878 case MPI_EVENT_PERSISTENT_TABLE_FULL:
5879 ds = "Persistent Table Full";
5881 case MPI_EVENT_SAS_PHY_LINK_STATUS:
5883 u8 LinkRates = (u8)(evData0 >> 8);
5884 u8 PhyNumber = (u8)(evData0);
5885 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
5886 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
5887 switch (LinkRates) {
5888 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
5889 snprintf(evStr, EVENT_DESCR_STR_SZ,
5890 "SAS PHY Link Status: Phy=%d:"
5891 " Rate Unknown",PhyNumber);
5893 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
5894 snprintf(evStr, EVENT_DESCR_STR_SZ,
5895 "SAS PHY Link Status: Phy=%d:"
5896 " Phy Disabled",PhyNumber);
5898 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
5899 snprintf(evStr, EVENT_DESCR_STR_SZ,
5900 "SAS PHY Link Status: Phy=%d:"
5901 " Failed Speed Nego",PhyNumber);
5903 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
5904 snprintf(evStr, EVENT_DESCR_STR_SZ,
5905 "SAS PHY Link Status: Phy=%d:"
5906 " Sata OOB Completed",PhyNumber);
5908 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
5909 snprintf(evStr, EVENT_DESCR_STR_SZ,
5910 "SAS PHY Link Status: Phy=%d:"
5911 " Rate 1.5 Gbps",PhyNumber);
5913 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
5914 snprintf(evStr, EVENT_DESCR_STR_SZ,
5915 "SAS PHY Link Status: Phy=%d:"
5916 " Rate 3.0 Gpbs",PhyNumber);
5919 snprintf(evStr, EVENT_DESCR_STR_SZ,
5920 "SAS PHY Link Status: Phy=%d", PhyNumber);
5925 case MPI_EVENT_SAS_DISCOVERY_ERROR:
5926 ds = "SAS Discovery Error";
5928 case MPI_EVENT_IR_RESYNC_UPDATE:
5930 u8 resync_complete = (u8)(evData0 >> 16);
5931 snprintf(evStr, EVENT_DESCR_STR_SZ,
5932 "IR Resync Update: Complete = %d:",resync_complete);
5937 u8 ReasonCode = (u8)(evData0 >> 16);
5938 switch (ReasonCode) {
5939 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
5940 ds = "IR2: LD State Changed";
5942 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
5943 ds = "IR2: PD State Changed";
5945 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
5946 ds = "IR2: Bad Block Table Full";
5948 case MPI_EVENT_IR2_RC_PD_INSERTED:
5949 ds = "IR2: PD Inserted";
5951 case MPI_EVENT_IR2_RC_PD_REMOVED:
5952 ds = "IR2: PD Removed";
5954 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
5955 ds = "IR2: Foreign CFG Detected";
5957 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
5958 ds = "IR2: Rebuild Medium Error";
5966 case MPI_EVENT_SAS_DISCOVERY:
5969 ds = "SAS Discovery: Start";
5971 ds = "SAS Discovery: Stop";
5974 case MPI_EVENT_LOG_ENTRY_ADDED:
5975 ds = "SAS Log Entry Added";
5978 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
5980 u8 phy_num = (u8)(evData0);
5981 u8 port_num = (u8)(evData0 >> 8);
5982 u8 port_width = (u8)(evData0 >> 16);
5983 u8 primative = (u8)(evData0 >> 24);
5984 snprintf(evStr, EVENT_DESCR_STR_SZ,
5985 "SAS Broadcase Primative: phy=%d port=%d "
5986 "width=%d primative=0x%02x",
5987 phy_num, port_num, port_width, primative);
5991 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
5993 u8 reason = (u8)(evData0);
5994 u8 port_num = (u8)(evData0 >> 8);
5995 u16 handle = le16_to_cpu(evData0 >> 16);
5997 snprintf(evStr, EVENT_DESCR_STR_SZ,
5998 "SAS Initiator Device Status Change: reason=0x%02x "
5999 "port=%d handle=0x%04x",
6000 reason, port_num, handle);
6004 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
6006 u8 max_init = (u8)(evData0);
6007 u8 current_init = (u8)(evData0 >> 8);
6009 snprintf(evStr, EVENT_DESCR_STR_SZ,
6010 "SAS Initiator Device Table Overflow: max initiators=%02d "
6011 "current initators=%02d",
6012 max_init, current_init);
6015 case MPI_EVENT_SAS_SMP_ERROR:
6017 u8 status = (u8)(evData0);
6018 u8 port_num = (u8)(evData0 >> 8);
6019 u8 result = (u8)(evData0 >> 16);
6021 if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
6022 snprintf(evStr, EVENT_DESCR_STR_SZ,
6023 "SAS SMP Error: port=%d result=0x%02x",
6025 else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
6026 snprintf(evStr, EVENT_DESCR_STR_SZ,
6027 "SAS SMP Error: port=%d : CRC Error",
6029 else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
6030 snprintf(evStr, EVENT_DESCR_STR_SZ,
6031 "SAS SMP Error: port=%d : Timeout",
6033 else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
6034 snprintf(evStr, EVENT_DESCR_STR_SZ,
6035 "SAS SMP Error: port=%d : No Destination",
6037 else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
6038 snprintf(evStr, EVENT_DESCR_STR_SZ,
6039 "SAS SMP Error: port=%d : Bad Destination",
6042 snprintf(evStr, EVENT_DESCR_STR_SZ,
6043 "SAS SMP Error: port=%d : status=0x%02x",
6049 * MPT base "custom" events may be added here...
6056 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
6059 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6061 * ProcessEventNotification - Route EventNotificationReply to all event handlers
6062 * @ioc: Pointer to MPT_ADAPTER structure
6063 * @pEventReply: Pointer to EventNotification reply frame
6064 * @evHandlers: Pointer to integer, number of event handlers
6066 * Routes a received EventNotificationReply to all currently registered
6068 * Returns sum of event handlers return values.
6071 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
6079 char evStr[EVENT_DESCR_STR_SZ];
6083 * Do platform normalization of values
6085 event = le32_to_cpu(pEventReply->Event) & 0xFF;
6086 // evCtx = le32_to_cpu(pEventReply->EventContext);
6087 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
6089 evData0 = le32_to_cpu(pEventReply->Data[0]);
6092 EventDescriptionStr(event, evData0, evStr);
6093 devtprintk((MYIOC_s_INFO_FMT "MPT event:(%02Xh) : %s\n",
6098 #if defined(MPT_DEBUG) || defined(MPT_DEBUG_VERBOSE_EVENTS)
6099 printk(KERN_INFO MYNAM ": Event data:\n" KERN_INFO);
6100 for (ii = 0; ii < evDataLen; ii++)
6101 printk(" %08x", le32_to_cpu(pEventReply->Data[ii]));
6106 * Do general / base driver event processing
6109 case MPI_EVENT_EVENT_CHANGE: /* 0A */
6111 u8 evState = evData0 & 0xFF;
6113 /* CHECKME! What if evState unexpectedly says OFF (0)? */
6115 /* Update EventState field in cached IocFacts */
6116 if (ioc->facts.Function) {
6117 ioc->facts.EventState = evState;
6121 case MPI_EVENT_INTEGRATED_RAID:
6122 mptbase_raid_process_event_data(ioc,
6123 (MpiEventDataRaid_t *)pEventReply->Data);
6130 * Should this event be logged? Events are written sequentially.
6131 * When buffer is full, start again at the top.
6133 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
6136 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
6138 ioc->events[idx].event = event;
6139 ioc->events[idx].eventContext = ioc->eventContext;
6141 for (ii = 0; ii < 2; ii++) {
6143 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
6145 ioc->events[idx].data[ii] = 0;
6148 ioc->eventContext++;
6153 * Call each currently registered protocol event handler.
6155 for (ii=MPT_MAX_PROTOCOL_DRIVERS-1; ii; ii--) {
6156 if (MptEvHandlers[ii]) {
6157 devtverboseprintk((MYIOC_s_INFO_FMT "Routing Event to event handler #%d\n",
6159 r += (*(MptEvHandlers[ii]))(ioc, pEventReply);
6163 /* FIXME? Examine results here? */
6166 * If needed, send (a single) EventAck.
6168 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
6169 devtverboseprintk((MYIOC_s_WARN_FMT
6170 "EventAck required\n",ioc->name));
6171 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
6172 devtverboseprintk((MYIOC_s_WARN_FMT "SendEventAck returned %d\n",
6177 *evHandlers = handlers;
6181 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6183 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
6184 * @ioc: Pointer to MPT_ADAPTER structure
6185 * @log_info: U32 LogInfo reply word from the IOC
6187 * Refer to lsi/mpi_log_fc.h.
6190 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
6192 static char *subcl_str[8] = {
6193 "FCP Initiator", "FCP Target", "LAN", "MPI Message Layer",
6194 "FC Link", "Context Manager", "Invalid Field Offset", "State Change Info"
6196 u8 subcl = (log_info >> 24) & 0x7;
6198 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubCl={%s}\n",
6199 ioc->name, log_info, subcl_str[subcl]);
6202 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6204 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
6205 * @ioc: Pointer to MPT_ADAPTER structure
6206 * @mr: Pointer to MPT reply frame
6207 * @log_info: U32 LogInfo word from the IOC
6209 * Refer to lsi/sp_log.h.
6212 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
6214 u32 info = log_info & 0x00FF0000;
6215 char *desc = "unknown";
6219 desc = "bug! MID not found";
6220 if (ioc->reload_fw == 0)
6225 desc = "Parity Error";
6229 desc = "ASYNC Outbound Overrun";
6233 desc = "SYNC Offset Error";
6241 desc = "Msg In Overflow";
6249 desc = "Outbound DMA Overrun";
6253 desc = "Task Management";
6257 desc = "Device Problem";
6261 desc = "Invalid Phase Change";
6265 desc = "Untagged Table Size";
6270 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
6273 /* strings for sas loginfo */
6274 static char *originator_str[] = {
6279 static char *iop_code_str[] = {
6281 "Invalid SAS Address", /* 01h */
6283 "Invalid Page", /* 03h */
6284 "Diag Message Error", /* 04h */
6285 "Task Terminated", /* 05h */
6286 "Enclosure Management", /* 06h */
6287 "Target Mode" /* 07h */
6289 static char *pl_code_str[] = {
6291 "Open Failure", /* 01h */
6292 "Invalid Scatter Gather List", /* 02h */
6293 "Wrong Relative Offset or Frame Length", /* 03h */
6294 "Frame Transfer Error", /* 04h */
6295 "Transmit Frame Connected Low", /* 05h */
6296 "SATA Non-NCQ RW Error Bit Set", /* 06h */
6297 "SATA Read Log Receive Data Error", /* 07h */
6298 "SATA NCQ Fail All Commands After Error", /* 08h */
6299 "SATA Error in Receive Set Device Bit FIS", /* 09h */
6300 "Receive Frame Invalid Message", /* 0Ah */
6301 "Receive Context Message Valid Error", /* 0Bh */
6302 "Receive Frame Current Frame Error", /* 0Ch */
6303 "SATA Link Down", /* 0Dh */
6304 "Discovery SATA Init W IOS", /* 0Eh */
6305 "Config Invalid Page", /* 0Fh */
6306 "Discovery SATA Init Timeout", /* 10h */
6309 "IO Not Yet Executed", /* 13h */
6310 "IO Executed", /* 14h */
6311 "Persistent Reservation Out Not Affiliation "
6313 "Open Transmit DMA Abort", /* 16h */
6314 "IO Device Missing Delay Retry", /* 17h */
6315 "IO Cancelled Due to Recieve Error", /* 18h */
6323 "Enclosure Management" /* 20h */
6325 static char *ir_code_str[] = {
6326 "Raid Action Error", /* 00h */
6336 static char *raid_sub_code_str[] = {
6338 "Volume Creation Failed: Data Passed too "
6340 "Volume Creation Failed: Duplicate Volumes "
6341 "Attempted", /* 02h */
6342 "Volume Creation Failed: Max Number "
6343 "Supported Volumes Exceeded", /* 03h */
6344 "Volume Creation Failed: DMA Error", /* 04h */
6345 "Volume Creation Failed: Invalid Volume Type", /* 05h */
6346 "Volume Creation Failed: Error Reading "
6347 "MFG Page 4", /* 06h */
6348 "Volume Creation Failed: Creating Internal "
6349 "Structures", /* 07h */
6358 "Activation failed: Already Active Volume", /* 10h */
6359 "Activation failed: Unsupported Volume Type", /* 11h */
6360 "Activation failed: Too Many Active Volumes", /* 12h */
6361 "Activation failed: Volume ID in Use", /* 13h */
6362 "Activation failed: Reported Failure", /* 14h */
6363 "Activation failed: Importing a Volume", /* 15h */
6374 "Phys Disk failed: Too Many Phys Disks", /* 20h */
6375 "Phys Disk failed: Data Passed too Large", /* 21h */
6376 "Phys Disk failed: DMA Error", /* 22h */
6377 "Phys Disk failed: Invalid <channel:id>", /* 23h */
6378 "Phys Disk failed: Creating Phys Disk Config "
6391 "Compatibility Error: IR Disabled", /* 30h */
6392 "Compatibility Error: Inquiry Comand Failed", /* 31h */
6393 "Compatibility Error: Device not Direct Access "
6394 "Device ", /* 32h */
6395 "Compatibility Error: Removable Device Found", /* 33h */
6396 "Compatibility Error: Device SCSI Version not "
6397 "2 or Higher", /* 34h */
6398 "Compatibility Error: SATA Device, 48 BIT LBA "
6399 "not Supported", /* 35h */
6400 "Compatibility Error: Device doesn't have "
6401 "512 Byte Block Sizes", /* 36h */
6402 "Compatibility Error: Volume Type Check Failed", /* 37h */
6403 "Compatibility Error: Volume Type is "
6404 "Unsupported by FW", /* 38h */
6405 "Compatibility Error: Disk Drive too Small for "
6406 "use in Volume", /* 39h */
6407 "Compatibility Error: Phys Disk for Create "
6408 "Volume not Found", /* 3Ah */
6409 "Compatibility Error: Too Many or too Few "
6410 "Disks for Volume Type", /* 3Bh */
6411 "Compatibility Error: Disk stripe Sizes "
6412 "Must be 64KB", /* 3Ch */
6413 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
6416 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6418 * mpt_sas_log_info - Log information returned from SAS IOC.
6419 * @ioc: Pointer to MPT_ADAPTER structure
6420 * @log_info: U32 LogInfo reply word from the IOC
6422 * Refer to lsi/mpi_log_sas.h.
6425 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
6427 union loginfo_type {
6436 union loginfo_type sas_loginfo;
6437 char *originator_desc = NULL;
6438 char *code_desc = NULL;
6439 char *sub_code_desc = NULL;
6441 sas_loginfo.loginfo = log_info;
6442 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
6443 (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
6446 originator_desc = originator_str[sas_loginfo.dw.originator];
6448 switch (sas_loginfo.dw.originator) {
6451 if (sas_loginfo.dw.code <
6452 sizeof(iop_code_str)/sizeof(char*))
6453 code_desc = iop_code_str[sas_loginfo.dw.code];
6456 if (sas_loginfo.dw.code <
6457 sizeof(pl_code_str)/sizeof(char*))
6458 code_desc = pl_code_str[sas_loginfo.dw.code];
6461 if (sas_loginfo.dw.code >=
6462 sizeof(ir_code_str)/sizeof(char*))
6464 code_desc = ir_code_str[sas_loginfo.dw.code];
6465 if (sas_loginfo.dw.subcode >=
6466 sizeof(raid_sub_code_str)/sizeof(char*))
6468 if (sas_loginfo.dw.code == 0)
6470 raid_sub_code_str[sas_loginfo.dw.subcode];
6476 if (sub_code_desc != NULL)
6477 printk(MYIOC_s_INFO_FMT
6478 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
6480 ioc->name, log_info, originator_desc, code_desc,
6482 else if (code_desc != NULL)
6483 printk(MYIOC_s_INFO_FMT
6484 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
6485 " SubCode(0x%04x)\n",
6486 ioc->name, log_info, originator_desc, code_desc,
6487 sas_loginfo.dw.subcode);
6489 printk(MYIOC_s_INFO_FMT
6490 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
6491 " SubCode(0x%04x)\n",
6492 ioc->name, log_info, originator_desc,
6493 sas_loginfo.dw.code, sas_loginfo.dw.subcode);
6496 #ifdef MPT_DEBUG_REPLY
6497 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6499 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
6500 * @ioc: Pointer to MPT_ADAPTER structure
6501 * ioc_status: U32 IOCStatus word from IOC
6502 * @mf: Pointer to MPT request frame
6504 * Refer to lsi/mpi.h.
6507 mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
6509 Config_t *pReq = (Config_t *)mf;
6510 char extend_desc[EVENT_DESCR_STR_SZ];
6515 if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
6516 page_type = pReq->ExtPageType;
6518 page_type = pReq->Header.PageType;
6521 * ignore invalid page messages for GET_NEXT_HANDLE
6523 form = le32_to_cpu(pReq->PageAddress);
6524 if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
6525 if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
6526 page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
6527 page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
6528 if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
6529 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
6532 if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
6533 if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
6534 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
6538 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
6539 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
6540 page_type, pReq->Header.PageNumber, pReq->Action, form);
6542 switch (ioc_status) {
6544 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
6545 desc = "Config Page Invalid Action";
6548 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
6549 desc = "Config Page Invalid Type";
6552 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
6553 desc = "Config Page Invalid Page";
6556 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
6557 desc = "Config Page Invalid Data";
6560 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
6561 desc = "Config Page No Defaults";
6564 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
6565 desc = "Config Page Can't Commit";
6572 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s: %s\n",
6573 ioc->name, ioc_status, desc, extend_desc);
6577 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
6578 * @ioc: Pointer to MPT_ADAPTER structure
6579 * @ioc_status: U32 IOCStatus word from IOC
6580 * @mf: Pointer to MPT request frame
6582 * Refer to lsi/mpi.h.
6585 mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
6587 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
6592 /****************************************************************************/
6593 /* Common IOCStatus values for all replies */
6594 /****************************************************************************/
6596 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
6597 desc = "Invalid Function";
6600 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
6604 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
6605 desc = "Invalid SGL";
6608 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
6609 desc = "Internal Error";
6612 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
6616 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
6617 desc = "Insufficient Resources";
6620 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
6621 desc = "Invalid Field";
6624 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
6625 desc = "Invalid State";
6628 /****************************************************************************/
6629 /* Config IOCStatus values */
6630 /****************************************************************************/
6632 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
6633 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
6634 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
6635 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
6636 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
6637 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
6638 mpt_iocstatus_info_config(ioc, status, mf);
6641 /****************************************************************************/
6642 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
6644 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
6646 /****************************************************************************/
6648 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
6649 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
6650 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
6651 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
6652 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
6653 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
6654 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
6655 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
6656 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
6657 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
6658 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
6659 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
6660 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
6663 /****************************************************************************/
6664 /* SCSI Target values */
6665 /****************************************************************************/
6667 case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
6668 desc = "Target: Priority IO";
6671 case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
6672 desc = "Target: Invalid Port";
6675 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
6676 desc = "Target Invalid IO Index:";
6679 case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
6680 desc = "Target: Aborted";
6683 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
6684 desc = "Target: No Conn Retryable";
6687 case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
6688 desc = "Target: No Connection";
6691 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
6692 desc = "Target: Transfer Count Mismatch";
6695 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
6696 desc = "Target: STS Data not Sent";
6699 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
6700 desc = "Target: Data Offset Error";
6703 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
6704 desc = "Target: Too Much Write Data";
6707 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
6708 desc = "Target: IU Too Short";
6711 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
6712 desc = "Target: ACK NAK Timeout";
6715 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
6716 desc = "Target: Nak Received";
6719 /****************************************************************************/
6720 /* Fibre Channel Direct Access values */
6721 /****************************************************************************/
6723 case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
6724 desc = "FC: Aborted";
6727 case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
6728 desc = "FC: RX ID Invalid";
6731 case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
6732 desc = "FC: DID Invalid";
6735 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
6736 desc = "FC: Node Logged Out";
6739 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
6740 desc = "FC: Exchange Canceled";
6743 /****************************************************************************/
6745 /****************************************************************************/
6747 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
6748 desc = "LAN: Device not Found";
6751 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
6752 desc = "LAN: Device Failure";
6755 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
6756 desc = "LAN: Transmit Error";
6759 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
6760 desc = "LAN: Transmit Aborted";
6763 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
6764 desc = "LAN: Receive Error";
6767 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
6768 desc = "LAN: Receive Aborted";
6771 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
6772 desc = "LAN: Partial Packet";
6775 case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
6776 desc = "LAN: Canceled";
6779 /****************************************************************************/
6780 /* Serial Attached SCSI values */
6781 /****************************************************************************/
6783 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
6784 desc = "SAS: SMP Request Failed";
6787 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
6788 desc = "SAS: SMP Data Overrun";
6799 printk(MYIOC_s_INFO_FMT "IOCStatus(0x%04X): %s\n", ioc->name, status, desc);
6803 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6804 EXPORT_SYMBOL(mpt_attach);
6805 EXPORT_SYMBOL(mpt_detach);
6807 EXPORT_SYMBOL(mpt_resume);
6808 EXPORT_SYMBOL(mpt_suspend);
6810 EXPORT_SYMBOL(ioc_list);
6811 EXPORT_SYMBOL(mpt_proc_root_dir);
6812 EXPORT_SYMBOL(mpt_register);
6813 EXPORT_SYMBOL(mpt_deregister);
6814 EXPORT_SYMBOL(mpt_event_register);
6815 EXPORT_SYMBOL(mpt_event_deregister);
6816 EXPORT_SYMBOL(mpt_reset_register);
6817 EXPORT_SYMBOL(mpt_reset_deregister);
6818 EXPORT_SYMBOL(mpt_device_driver_register);
6819 EXPORT_SYMBOL(mpt_device_driver_deregister);
6820 EXPORT_SYMBOL(mpt_get_msg_frame);
6821 EXPORT_SYMBOL(mpt_put_msg_frame);
6822 EXPORT_SYMBOL(mpt_free_msg_frame);
6823 EXPORT_SYMBOL(mpt_add_sge);
6824 EXPORT_SYMBOL(mpt_send_handshake_request);
6825 EXPORT_SYMBOL(mpt_verify_adapter);
6826 EXPORT_SYMBOL(mpt_GetIocState);
6827 EXPORT_SYMBOL(mpt_print_ioc_summary);
6828 EXPORT_SYMBOL(mpt_lan_index);
6829 EXPORT_SYMBOL(mpt_stm_index);
6830 EXPORT_SYMBOL(mpt_HardResetHandler);
6831 EXPORT_SYMBOL(mpt_config);
6832 EXPORT_SYMBOL(mpt_findImVolumes);
6833 EXPORT_SYMBOL(mpt_alloc_fw_memory);
6834 EXPORT_SYMBOL(mpt_free_fw_memory);
6835 EXPORT_SYMBOL(mptbase_sas_persist_operation);
6837 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6839 * fusion_init - Fusion MPT base driver initialization routine.
6841 * Returns 0 for success, non-zero for failure.
6848 show_mptmod_ver(my_NAME, my_VERSION);
6849 printk(KERN_INFO COPYRIGHT "\n");
6851 for (i = 0; i < MPT_MAX_PROTOCOL_DRIVERS; i++) {
6852 MptCallbacks[i] = NULL;
6853 MptDriverClass[i] = MPTUNKNOWN_DRIVER;
6854 MptEvHandlers[i] = NULL;
6855 MptResetHandlers[i] = NULL;
6858 /* Register ourselves (mptbase) in order to facilitate
6859 * EventNotification handling.
6861 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
6863 /* Register for hard reset handling callbacks.
6865 if (mpt_reset_register(mpt_base_index, mpt_ioc_reset) == 0) {
6866 dprintk((KERN_INFO MYNAM ": Register for IOC reset notification\n"));
6871 #ifdef CONFIG_PROC_FS
6872 (void) procmpt_create();
6877 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6879 * fusion_exit - Perform driver unload cleanup.
6881 * This routine frees all resources associated with each MPT adapter
6882 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
6888 dexitprintk((KERN_INFO MYNAM ": fusion_exit() called!\n"));
6890 mpt_reset_deregister(mpt_base_index);
6892 #ifdef CONFIG_PROC_FS
6897 module_init(fusion_init);
6898 module_exit(fusion_exit);