Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1/*
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 PCI chip/adapter(s)
6 * running LSI Fusion MPT (Message Passing Technology) firmware.
7 *
8 * Copyright (c) 1999-2008 LSI Corporation
9 * (mailto:DL-MPTFusionLinux@lsi.com)
10 *
11 */
12/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
13/*
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.
17
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.
22
23 NO WARRANTY
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.
33
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
42
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
46*/
47/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
48
49#include <linux/kernel.h>
50#include <linux/module.h>
51#include <linux/errno.h>
52#include <linux/init.h>
53#include <linux/seq_file.h>
54#include <linux/slab.h>
55#include <linux/types.h>
56#include <linux/pci.h>
57#include <linux/kdev_t.h>
58#include <linux/blkdev.h>
59#include <linux/delay.h>
60#include <linux/interrupt.h>
61#include <linux/dma-mapping.h>
62#include <linux/kthread.h>
63#include <scsi/scsi_host.h>
64
65#include "mptbase.h"
66#include "lsi/mpi_log_fc.h"
67
68/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
69#define my_NAME "Fusion MPT base driver"
70#define my_VERSION MPT_LINUX_VERSION_COMMON
71#define MYNAM "mptbase"
72
73MODULE_AUTHOR(MODULEAUTHOR);
74MODULE_DESCRIPTION(my_NAME);
75MODULE_LICENSE("GPL");
76MODULE_VERSION(my_VERSION);
77
78/*
79 * cmd line parameters
80 */
81
82static int mpt_msi_enable_spi;
83module_param(mpt_msi_enable_spi, int, 0);
84MODULE_PARM_DESC(mpt_msi_enable_spi,
85 " Enable MSI Support for SPI controllers (default=0)");
86
87static int mpt_msi_enable_fc;
88module_param(mpt_msi_enable_fc, int, 0);
89MODULE_PARM_DESC(mpt_msi_enable_fc,
90 " Enable MSI Support for FC controllers (default=0)");
91
92static int mpt_msi_enable_sas;
93module_param(mpt_msi_enable_sas, int, 0);
94MODULE_PARM_DESC(mpt_msi_enable_sas,
95 " Enable MSI Support for SAS controllers (default=0)");
96
97static int mpt_channel_mapping;
98module_param(mpt_channel_mapping, int, 0);
99MODULE_PARM_DESC(mpt_channel_mapping, " Mapping id's to channels (default=0)");
100
101static int mpt_debug_level;
102static int mpt_set_debug_level(const char *val, const struct kernel_param *kp);
103module_param_call(mpt_debug_level, mpt_set_debug_level, param_get_int,
104 &mpt_debug_level, 0600);
105MODULE_PARM_DESC(mpt_debug_level,
106 " debug level - refer to mptdebug.h - (default=0)");
107
108int mpt_fwfault_debug;
109EXPORT_SYMBOL(mpt_fwfault_debug);
110module_param(mpt_fwfault_debug, int, 0600);
111MODULE_PARM_DESC(mpt_fwfault_debug,
112 "Enable detection of Firmware fault and halt Firmware on fault - (default=0)");
113
114static char MptCallbacksName[MPT_MAX_PROTOCOL_DRIVERS]
115 [MPT_MAX_CALLBACKNAME_LEN+1];
116
117#ifdef MFCNT
118static int mfcounter = 0;
119#define PRINT_MF_COUNT 20000
120#endif
121
122/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
123/*
124 * Public data...
125 */
126
127#define WHOINIT_UNKNOWN 0xAA
128
129/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
130/*
131 * Private data...
132 */
133 /* Adapter link list */
134LIST_HEAD(ioc_list);
135 /* Callback lookup table */
136static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
137 /* Protocol driver class lookup table */
138static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
139 /* Event handler lookup table */
140static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
141 /* Reset handler lookup table */
142static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
143static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
144
145#ifdef CONFIG_PROC_FS
146static struct proc_dir_entry *mpt_proc_root_dir;
147#endif
148
149/*
150 * Driver Callback Index's
151 */
152static u8 mpt_base_index = MPT_MAX_PROTOCOL_DRIVERS;
153static u8 last_drv_idx;
154
155/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
156/*
157 * Forward protos...
158 */
159static irqreturn_t mpt_interrupt(int irq, void *bus_id);
160static int mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req,
161 MPT_FRAME_HDR *reply);
162static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
163 u32 *req, int replyBytes, u16 *u16reply, int maxwait,
164 int sleepFlag);
165static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
166static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
167static void mpt_adapter_disable(MPT_ADAPTER *ioc);
168static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
169
170static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
171static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
172static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
173static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
174static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
175static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
176static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
177static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
178static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
179static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
180static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
181static int PrimeIocFifos(MPT_ADAPTER *ioc);
182static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
183static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
184static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
185static int GetLanConfigPages(MPT_ADAPTER *ioc);
186static int GetIoUnitPage2(MPT_ADAPTER *ioc);
187int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
188static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
189static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
190static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
191static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
192static void mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc);
193static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch,
194 int sleepFlag);
195static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
196static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
197static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
198
199#ifdef CONFIG_PROC_FS
200static int mpt_summary_proc_show(struct seq_file *m, void *v);
201static int mpt_version_proc_show(struct seq_file *m, void *v);
202static int mpt_iocinfo_proc_show(struct seq_file *m, void *v);
203#endif
204static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
205
206static int ProcessEventNotification(MPT_ADAPTER *ioc,
207 EventNotificationReply_t *evReply, int *evHandlers);
208static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
209static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
210static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
211static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info , u8 cb_idx);
212static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
213static void mpt_inactive_raid_list_free(MPT_ADAPTER *ioc);
214
215/* module entry point */
216static int __init fusion_init (void);
217static void __exit fusion_exit (void);
218
219#define CHIPREG_READ32(addr) readl_relaxed(addr)
220#define CHIPREG_READ32_dmasync(addr) readl(addr)
221#define CHIPREG_WRITE32(addr,val) writel(val, addr)
222#define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
223#define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
224
225static void
226pci_disable_io_access(struct pci_dev *pdev)
227{
228 u16 command_reg;
229
230 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
231 command_reg &= ~1;
232 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
233}
234
235static void
236pci_enable_io_access(struct pci_dev *pdev)
237{
238 u16 command_reg;
239
240 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
241 command_reg |= 1;
242 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
243}
244
245static int mpt_set_debug_level(const char *val, const struct kernel_param *kp)
246{
247 int ret = param_set_int(val, kp);
248 MPT_ADAPTER *ioc;
249
250 if (ret)
251 return ret;
252
253 list_for_each_entry(ioc, &ioc_list, list)
254 ioc->debug_level = mpt_debug_level;
255 return 0;
256}
257
258/**
259 * mpt_get_cb_idx - obtain cb_idx for registered driver
260 * @dclass: class driver enum
261 *
262 * Returns cb_idx, or zero means it wasn't found
263 **/
264static u8
265mpt_get_cb_idx(MPT_DRIVER_CLASS dclass)
266{
267 u8 cb_idx;
268
269 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--)
270 if (MptDriverClass[cb_idx] == dclass)
271 return cb_idx;
272 return 0;
273}
274
275/**
276 * mpt_is_discovery_complete - determine if discovery has completed
277 * @ioc: per adatper instance
278 *
279 * Returns 1 when discovery completed, else zero.
280 */
281static int
282mpt_is_discovery_complete(MPT_ADAPTER *ioc)
283{
284 ConfigExtendedPageHeader_t hdr;
285 CONFIGPARMS cfg;
286 SasIOUnitPage0_t *buffer;
287 dma_addr_t dma_handle;
288 int rc = 0;
289
290 memset(&hdr, 0, sizeof(ConfigExtendedPageHeader_t));
291 memset(&cfg, 0, sizeof(CONFIGPARMS));
292 hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION;
293 hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
294 hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT;
295 cfg.cfghdr.ehdr = &hdr;
296 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
297
298 if ((mpt_config(ioc, &cfg)))
299 goto out;
300 if (!hdr.ExtPageLength)
301 goto out;
302
303 buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
304 &dma_handle);
305 if (!buffer)
306 goto out;
307
308 cfg.physAddr = dma_handle;
309 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
310
311 if ((mpt_config(ioc, &cfg)))
312 goto out_free_consistent;
313
314 if (!(buffer->PhyData[0].PortFlags &
315 MPI_SAS_IOUNIT0_PORT_FLAGS_DISCOVERY_IN_PROGRESS))
316 rc = 1;
317
318 out_free_consistent:
319 pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4,
320 buffer, dma_handle);
321 out:
322 return rc;
323}
324
325
326/**
327 * mpt_remove_dead_ioc_func - kthread context to remove dead ioc
328 * @arg: input argument, used to derive ioc
329 *
330 * Return 0 if controller is removed from pci subsystem.
331 * Return -1 for other case.
332 */
333static int mpt_remove_dead_ioc_func(void *arg)
334{
335 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
336 struct pci_dev *pdev;
337
338 if (!ioc)
339 return -1;
340
341 pdev = ioc->pcidev;
342 if (!pdev)
343 return -1;
344
345 pci_stop_and_remove_bus_device_locked(pdev);
346 return 0;
347}
348
349
350
351/**
352 * mpt_fault_reset_work - work performed on workq after ioc fault
353 * @work: input argument, used to derive ioc
354 *
355**/
356static void
357mpt_fault_reset_work(struct work_struct *work)
358{
359 MPT_ADAPTER *ioc =
360 container_of(work, MPT_ADAPTER, fault_reset_work.work);
361 u32 ioc_raw_state;
362 int rc;
363 unsigned long flags;
364 MPT_SCSI_HOST *hd;
365 struct task_struct *p;
366
367 if (ioc->ioc_reset_in_progress || !ioc->active)
368 goto out;
369
370
371 ioc_raw_state = mpt_GetIocState(ioc, 0);
372 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_MASK) {
373 printk(MYIOC_s_INFO_FMT "%s: IOC is non-operational !!!!\n",
374 ioc->name, __func__);
375
376 /*
377 * Call mptscsih_flush_pending_cmds callback so that we
378 * flush all pending commands back to OS.
379 * This call is required to aovid deadlock at block layer.
380 * Dead IOC will fail to do diag reset,and this call is safe
381 * since dead ioc will never return any command back from HW.
382 */
383 hd = shost_priv(ioc->sh);
384 ioc->schedule_dead_ioc_flush_running_cmds(hd);
385
386 /*Remove the Dead Host */
387 p = kthread_run(mpt_remove_dead_ioc_func, ioc,
388 "mpt_dead_ioc_%d", ioc->id);
389 if (IS_ERR(p)) {
390 printk(MYIOC_s_ERR_FMT
391 "%s: Running mpt_dead_ioc thread failed !\n",
392 ioc->name, __func__);
393 } else {
394 printk(MYIOC_s_WARN_FMT
395 "%s: Running mpt_dead_ioc thread success !\n",
396 ioc->name, __func__);
397 }
398 return; /* don't rearm timer */
399 }
400
401 if ((ioc_raw_state & MPI_IOC_STATE_MASK)
402 == MPI_IOC_STATE_FAULT) {
403 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state (%04xh)!!!\n",
404 ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
405 printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n",
406 ioc->name, __func__);
407 rc = mpt_HardResetHandler(ioc, CAN_SLEEP);
408 printk(MYIOC_s_WARN_FMT "%s: HardReset: %s\n", ioc->name,
409 __func__, (rc == 0) ? "success" : "failed");
410 ioc_raw_state = mpt_GetIocState(ioc, 0);
411 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT)
412 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state after "
413 "reset (%04xh)\n", ioc->name, ioc_raw_state &
414 MPI_DOORBELL_DATA_MASK);
415 } else if (ioc->bus_type == SAS && ioc->sas_discovery_quiesce_io) {
416 if ((mpt_is_discovery_complete(ioc))) {
417 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "clearing "
418 "discovery_quiesce_io flag\n", ioc->name));
419 ioc->sas_discovery_quiesce_io = 0;
420 }
421 }
422
423 out:
424 /*
425 * Take turns polling alternate controller
426 */
427 if (ioc->alt_ioc)
428 ioc = ioc->alt_ioc;
429
430 /* rearm the timer */
431 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
432 if (ioc->reset_work_q)
433 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
434 msecs_to_jiffies(MPT_POLLING_INTERVAL));
435 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
436}
437
438
439/*
440 * Process turbo (context) reply...
441 */
442static void
443mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
444{
445 MPT_FRAME_HDR *mf = NULL;
446 MPT_FRAME_HDR *mr = NULL;
447 u16 req_idx = 0;
448 u8 cb_idx;
449
450 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got TURBO reply req_idx=%08x\n",
451 ioc->name, pa));
452
453 switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
454 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
455 req_idx = pa & 0x0000FFFF;
456 cb_idx = (pa & 0x00FF0000) >> 16;
457 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
458 break;
459 case MPI_CONTEXT_REPLY_TYPE_LAN:
460 cb_idx = mpt_get_cb_idx(MPTLAN_DRIVER);
461 /*
462 * Blind set of mf to NULL here was fatal
463 * after lan_reply says "freeme"
464 * Fix sort of combined with an optimization here;
465 * added explicit check for case where lan_reply
466 * was just returning 1 and doing nothing else.
467 * For this case skip the callback, but set up
468 * proper mf value first here:-)
469 */
470 if ((pa & 0x58000000) == 0x58000000) {
471 req_idx = pa & 0x0000FFFF;
472 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
473 mpt_free_msg_frame(ioc, mf);
474 mb();
475 return;
476 }
477 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
478 break;
479 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
480 cb_idx = mpt_get_cb_idx(MPTSTM_DRIVER);
481 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
482 break;
483 default:
484 cb_idx = 0;
485 BUG();
486 }
487
488 /* Check for (valid) IO callback! */
489 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
490 MptCallbacks[cb_idx] == NULL) {
491 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
492 __func__, ioc->name, cb_idx);
493 goto out;
494 }
495
496 if (MptCallbacks[cb_idx](ioc, mf, mr))
497 mpt_free_msg_frame(ioc, mf);
498 out:
499 mb();
500}
501
502static void
503mpt_reply(MPT_ADAPTER *ioc, u32 pa)
504{
505 MPT_FRAME_HDR *mf;
506 MPT_FRAME_HDR *mr;
507 u16 req_idx;
508 u8 cb_idx;
509 int freeme;
510
511 u32 reply_dma_low;
512 u16 ioc_stat;
513
514 /* non-TURBO reply! Hmmm, something may be up...
515 * Newest turbo reply mechanism; get address
516 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
517 */
518
519 /* Map DMA address of reply header to cpu address.
520 * pa is 32 bits - but the dma address may be 32 or 64 bits
521 * get offset based only only the low addresses
522 */
523
524 reply_dma_low = (pa <<= 1);
525 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
526 (reply_dma_low - ioc->reply_frames_low_dma));
527
528 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
529 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
530 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
531
532 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
533 ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
534 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mr);
535
536 /* Check/log IOC log info
537 */
538 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
539 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
540 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
541 if (ioc->bus_type == FC)
542 mpt_fc_log_info(ioc, log_info);
543 else if (ioc->bus_type == SPI)
544 mpt_spi_log_info(ioc, log_info);
545 else if (ioc->bus_type == SAS)
546 mpt_sas_log_info(ioc, log_info, cb_idx);
547 }
548
549 if (ioc_stat & MPI_IOCSTATUS_MASK)
550 mpt_iocstatus_info(ioc, (u32)ioc_stat, mf);
551
552 /* Check for (valid) IO callback! */
553 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
554 MptCallbacks[cb_idx] == NULL) {
555 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
556 __func__, ioc->name, cb_idx);
557 freeme = 0;
558 goto out;
559 }
560
561 freeme = MptCallbacks[cb_idx](ioc, mf, mr);
562
563 out:
564 /* Flush (non-TURBO) reply with a WRITE! */
565 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
566
567 if (freeme)
568 mpt_free_msg_frame(ioc, mf);
569 mb();
570}
571
572/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
573/**
574 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
575 * @irq: irq number (not used)
576 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
577 *
578 * This routine is registered via the request_irq() kernel API call,
579 * and handles all interrupts generated from a specific MPT adapter
580 * (also referred to as a IO Controller or IOC).
581 * This routine must clear the interrupt from the adapter and does
582 * so by reading the reply FIFO. Multiple replies may be processed
583 * per single call to this routine.
584 *
585 * This routine handles register-level access of the adapter but
586 * dispatches (calls) a protocol-specific callback routine to handle
587 * the protocol-specific details of the MPT request completion.
588 */
589static irqreturn_t
590mpt_interrupt(int irq, void *bus_id)
591{
592 MPT_ADAPTER *ioc = bus_id;
593 u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
594
595 if (pa == 0xFFFFFFFF)
596 return IRQ_NONE;
597
598 /*
599 * Drain the reply FIFO!
600 */
601 do {
602 if (pa & MPI_ADDRESS_REPLY_A_BIT)
603 mpt_reply(ioc, pa);
604 else
605 mpt_turbo_reply(ioc, pa);
606 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
607 } while (pa != 0xFFFFFFFF);
608
609 return IRQ_HANDLED;
610}
611
612/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
613/**
614 * mptbase_reply - MPT base driver's callback routine
615 * @ioc: Pointer to MPT_ADAPTER structure
616 * @req: Pointer to original MPT request frame
617 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
618 *
619 * MPT base driver's callback routine; all base driver
620 * "internal" request/reply processing is routed here.
621 * Currently used for EventNotification and EventAck handling.
622 *
623 * Returns 1 indicating original alloc'd request frame ptr
624 * should be freed, or 0 if it shouldn't.
625 */
626static int
627mptbase_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
628{
629 EventNotificationReply_t *pEventReply;
630 u8 event;
631 int evHandlers;
632 int freereq = 1;
633
634 switch (reply->u.hdr.Function) {
635 case MPI_FUNCTION_EVENT_NOTIFICATION:
636 pEventReply = (EventNotificationReply_t *)reply;
637 evHandlers = 0;
638 ProcessEventNotification(ioc, pEventReply, &evHandlers);
639 event = le32_to_cpu(pEventReply->Event) & 0xFF;
640 if (pEventReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)
641 freereq = 0;
642 if (event != MPI_EVENT_EVENT_CHANGE)
643 break;
644 fallthrough;
645 case MPI_FUNCTION_CONFIG:
646 case MPI_FUNCTION_SAS_IO_UNIT_CONTROL:
647 ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_COMMAND_GOOD;
648 ioc->mptbase_cmds.status |= MPT_MGMT_STATUS_RF_VALID;
649 memcpy(ioc->mptbase_cmds.reply, reply,
650 min(MPT_DEFAULT_FRAME_SIZE,
651 4 * reply->u.reply.MsgLength));
652 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) {
653 ioc->mptbase_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
654 complete(&ioc->mptbase_cmds.done);
655 } else
656 freereq = 0;
657 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_FREE_MF)
658 freereq = 1;
659 break;
660 case MPI_FUNCTION_EVENT_ACK:
661 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
662 "EventAck reply received\n", ioc->name));
663 break;
664 default:
665 printk(MYIOC_s_ERR_FMT
666 "Unexpected msg function (=%02Xh) reply received!\n",
667 ioc->name, reply->u.hdr.Function);
668 break;
669 }
670
671 /*
672 * Conditionally tell caller to free the original
673 * EventNotification/EventAck/unexpected request frame!
674 */
675 return freereq;
676}
677
678/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
679/**
680 * mpt_register - Register protocol-specific main callback handler.
681 * @cbfunc: callback function pointer
682 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
683 * @func_name: call function's name
684 *
685 * This routine is called by a protocol-specific driver (SCSI host,
686 * LAN, SCSI target) to register its reply callback routine. Each
687 * protocol-specific driver must do this before it will be able to
688 * use any IOC resources, such as obtaining request frames.
689 *
690 * NOTES: The SCSI protocol driver currently calls this routine thrice
691 * in order to register separate callbacks; one for "normal" SCSI IO;
692 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
693 *
694 * Returns u8 valued "handle" in the range (and S.O.D. order)
695 * {N,...,7,6,5,...,1} if successful.
696 * A return value of MPT_MAX_PROTOCOL_DRIVERS (including zero!) should be
697 * considered an error by the caller.
698 */
699u8
700mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass, char *func_name)
701{
702 u8 cb_idx;
703 last_drv_idx = MPT_MAX_PROTOCOL_DRIVERS;
704
705 /*
706 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
707 * (slot/handle 0 is reserved!)
708 */
709 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
710 if (MptCallbacks[cb_idx] == NULL) {
711 MptCallbacks[cb_idx] = cbfunc;
712 MptDriverClass[cb_idx] = dclass;
713 MptEvHandlers[cb_idx] = NULL;
714 last_drv_idx = cb_idx;
715 strlcpy(MptCallbacksName[cb_idx], func_name,
716 MPT_MAX_CALLBACKNAME_LEN+1);
717 break;
718 }
719 }
720
721 return last_drv_idx;
722}
723
724/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
725/**
726 * mpt_deregister - Deregister a protocol drivers resources.
727 * @cb_idx: previously registered callback handle
728 *
729 * Each protocol-specific driver should call this routine when its
730 * module is unloaded.
731 */
732void
733mpt_deregister(u8 cb_idx)
734{
735 if (cb_idx && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
736 MptCallbacks[cb_idx] = NULL;
737 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
738 MptEvHandlers[cb_idx] = NULL;
739
740 last_drv_idx++;
741 }
742}
743
744/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
745/**
746 * mpt_event_register - Register protocol-specific event callback handler.
747 * @cb_idx: previously registered (via mpt_register) callback handle
748 * @ev_cbfunc: callback function
749 *
750 * This routine can be called by one or more protocol-specific drivers
751 * if/when they choose to be notified of MPT events.
752 *
753 * Returns 0 for success.
754 */
755int
756mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc)
757{
758 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
759 return -1;
760
761 MptEvHandlers[cb_idx] = ev_cbfunc;
762 return 0;
763}
764
765/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
766/**
767 * mpt_event_deregister - Deregister protocol-specific event callback handler
768 * @cb_idx: previously registered callback handle
769 *
770 * Each protocol-specific driver should call this routine
771 * when it does not (or can no longer) handle events,
772 * or when its module is unloaded.
773 */
774void
775mpt_event_deregister(u8 cb_idx)
776{
777 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
778 return;
779
780 MptEvHandlers[cb_idx] = NULL;
781}
782
783/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
784/**
785 * mpt_reset_register - Register protocol-specific IOC reset handler.
786 * @cb_idx: previously registered (via mpt_register) callback handle
787 * @reset_func: reset function
788 *
789 * This routine can be called by one or more protocol-specific drivers
790 * if/when they choose to be notified of IOC resets.
791 *
792 * Returns 0 for success.
793 */
794int
795mpt_reset_register(u8 cb_idx, MPT_RESETHANDLER reset_func)
796{
797 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
798 return -1;
799
800 MptResetHandlers[cb_idx] = reset_func;
801 return 0;
802}
803
804/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
805/**
806 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
807 * @cb_idx: previously registered callback handle
808 *
809 * Each protocol-specific driver should call this routine
810 * when it does not (or can no longer) handle IOC reset handling,
811 * or when its module is unloaded.
812 */
813void
814mpt_reset_deregister(u8 cb_idx)
815{
816 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
817 return;
818
819 MptResetHandlers[cb_idx] = NULL;
820}
821
822/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
823/**
824 * mpt_device_driver_register - Register device driver hooks
825 * @dd_cbfunc: driver callbacks struct
826 * @cb_idx: MPT protocol driver index
827 */
828int
829mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, u8 cb_idx)
830{
831 MPT_ADAPTER *ioc;
832
833 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
834 return -EINVAL;
835
836 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
837
838 /* call per pci device probe entry point */
839 list_for_each_entry(ioc, &ioc_list, list) {
840 if (dd_cbfunc->probe)
841 dd_cbfunc->probe(ioc->pcidev);
842 }
843
844 return 0;
845}
846
847/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
848/**
849 * mpt_device_driver_deregister - DeRegister device driver hooks
850 * @cb_idx: MPT protocol driver index
851 */
852void
853mpt_device_driver_deregister(u8 cb_idx)
854{
855 struct mpt_pci_driver *dd_cbfunc;
856 MPT_ADAPTER *ioc;
857
858 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
859 return;
860
861 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
862
863 list_for_each_entry(ioc, &ioc_list, list) {
864 if (dd_cbfunc->remove)
865 dd_cbfunc->remove(ioc->pcidev);
866 }
867
868 MptDeviceDriverHandlers[cb_idx] = NULL;
869}
870
871
872/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
873/**
874 * mpt_get_msg_frame - Obtain an MPT request frame from the pool
875 * @cb_idx: Handle of registered MPT protocol driver
876 * @ioc: Pointer to MPT adapter structure
877 *
878 * Obtain an MPT request frame from the pool (of 1024) that are
879 * allocated per MPT adapter.
880 *
881 * Returns pointer to a MPT request frame or %NULL if none are available
882 * or IOC is not active.
883 */
884MPT_FRAME_HDR*
885mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc)
886{
887 MPT_FRAME_HDR *mf;
888 unsigned long flags;
889 u16 req_idx; /* Request index */
890
891 /* validate handle and ioc identifier */
892
893#ifdef MFCNT
894 if (!ioc->active)
895 printk(MYIOC_s_WARN_FMT "IOC Not Active! mpt_get_msg_frame "
896 "returning NULL!\n", ioc->name);
897#endif
898
899 /* If interrupts are not attached, do not return a request frame */
900 if (!ioc->active)
901 return NULL;
902
903 spin_lock_irqsave(&ioc->FreeQlock, flags);
904 if (!list_empty(&ioc->FreeQ)) {
905 int req_offset;
906
907 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
908 u.frame.linkage.list);
909 list_del(&mf->u.frame.linkage.list);
910 mf->u.frame.linkage.arg1 = 0;
911 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
912 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
913 /* u16! */
914 req_idx = req_offset / ioc->req_sz;
915 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
916 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
917 /* Default, will be changed if necessary in SG generation */
918 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame;
919#ifdef MFCNT
920 ioc->mfcnt++;
921#endif
922 }
923 else
924 mf = NULL;
925 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
926
927#ifdef MFCNT
928 if (mf == NULL)
929 printk(MYIOC_s_WARN_FMT "IOC Active. No free Msg Frames! "
930 "Count 0x%x Max 0x%x\n", ioc->name, ioc->mfcnt,
931 ioc->req_depth);
932 mfcounter++;
933 if (mfcounter == PRINT_MF_COUNT)
934 printk(MYIOC_s_INFO_FMT "MF Count 0x%x Max 0x%x \n", ioc->name,
935 ioc->mfcnt, ioc->req_depth);
936#endif
937
938 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_get_msg_frame(%d,%d), got mf=%p\n",
939 ioc->name, cb_idx, ioc->id, mf));
940 return mf;
941}
942
943/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
944/**
945 * mpt_put_msg_frame - Send a protocol-specific MPT request frame to an IOC
946 * @cb_idx: Handle of registered MPT protocol driver
947 * @ioc: Pointer to MPT adapter structure
948 * @mf: Pointer to MPT request frame
949 *
950 * This routine posts an MPT request frame to the request post FIFO of a
951 * specific MPT adapter.
952 */
953void
954mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
955{
956 u32 mf_dma_addr;
957 int req_offset;
958 u16 req_idx; /* Request index */
959
960 /* ensure values are reset properly! */
961 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
962 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
963 /* u16! */
964 req_idx = req_offset / ioc->req_sz;
965 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
966 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
967
968 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
969
970 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
971 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d "
972 "RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx,
973 ioc->RequestNB[req_idx]));
974 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
975}
976
977/**
978 * mpt_put_msg_frame_hi_pri - Send a hi-pri protocol-specific MPT request frame
979 * @cb_idx: Handle of registered MPT protocol driver
980 * @ioc: Pointer to MPT adapter structure
981 * @mf: Pointer to MPT request frame
982 *
983 * Send a protocol-specific MPT request frame to an IOC using
984 * hi-priority request queue.
985 *
986 * This routine posts an MPT request frame to the request post FIFO of a
987 * specific MPT adapter.
988 **/
989void
990mpt_put_msg_frame_hi_pri(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
991{
992 u32 mf_dma_addr;
993 int req_offset;
994 u16 req_idx; /* Request index */
995
996 /* ensure values are reset properly! */
997 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
998 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
999 req_idx = req_offset / ioc->req_sz;
1000 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
1001 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
1002
1003 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
1004
1005 mf_dma_addr = (ioc->req_frames_low_dma + req_offset);
1006 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d\n",
1007 ioc->name, mf_dma_addr, req_idx));
1008 CHIPREG_WRITE32(&ioc->chip->RequestHiPriFifo, mf_dma_addr);
1009}
1010
1011/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1012/**
1013 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
1014 * @ioc: Pointer to MPT adapter structure
1015 * @mf: Pointer to MPT request frame
1016 *
1017 * This routine places a MPT request frame back on the MPT adapter's
1018 * FreeQ.
1019 */
1020void
1021mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
1022{
1023 unsigned long flags;
1024
1025 /* Put Request back on FreeQ! */
1026 spin_lock_irqsave(&ioc->FreeQlock, flags);
1027 if (cpu_to_le32(mf->u.frame.linkage.arg1) == 0xdeadbeaf)
1028 goto out;
1029 /* signature to know if this mf is freed */
1030 mf->u.frame.linkage.arg1 = cpu_to_le32(0xdeadbeaf);
1031 list_add(&mf->u.frame.linkage.list, &ioc->FreeQ);
1032#ifdef MFCNT
1033 ioc->mfcnt--;
1034#endif
1035 out:
1036 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1037}
1038
1039/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1040/**
1041 * mpt_add_sge - Place a simple 32 bit SGE at address pAddr.
1042 * @pAddr: virtual address for SGE
1043 * @flagslength: SGE flags and data transfer length
1044 * @dma_addr: Physical address
1045 *
1046 * This routine places a MPT request frame back on the MPT adapter's
1047 * FreeQ.
1048 */
1049static void
1050mpt_add_sge(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1051{
1052 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
1053 pSge->FlagsLength = cpu_to_le32(flagslength);
1054 pSge->Address = cpu_to_le32(dma_addr);
1055}
1056
1057/**
1058 * mpt_add_sge_64bit - Place a simple 64 bit SGE at address pAddr.
1059 * @pAddr: virtual address for SGE
1060 * @flagslength: SGE flags and data transfer length
1061 * @dma_addr: Physical address
1062 *
1063 * This routine places a MPT request frame back on the MPT adapter's
1064 * FreeQ.
1065 **/
1066static void
1067mpt_add_sge_64bit(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1068{
1069 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1070 pSge->Address.Low = cpu_to_le32
1071 (lower_32_bits(dma_addr));
1072 pSge->Address.High = cpu_to_le32
1073 (upper_32_bits(dma_addr));
1074 pSge->FlagsLength = cpu_to_le32
1075 ((flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1076}
1077
1078/**
1079 * mpt_add_sge_64bit_1078 - Place a simple 64 bit SGE at address pAddr (1078 workaround).
1080 * @pAddr: virtual address for SGE
1081 * @flagslength: SGE flags and data transfer length
1082 * @dma_addr: Physical address
1083 *
1084 * This routine places a MPT request frame back on the MPT adapter's
1085 * FreeQ.
1086 **/
1087static void
1088mpt_add_sge_64bit_1078(void *pAddr, u32 flagslength, dma_addr_t dma_addr)
1089{
1090 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
1091 u32 tmp;
1092
1093 pSge->Address.Low = cpu_to_le32
1094 (lower_32_bits(dma_addr));
1095 tmp = (u32)(upper_32_bits(dma_addr));
1096
1097 /*
1098 * 1078 errata workaround for the 36GB limitation
1099 */
1100 if ((((u64)dma_addr + MPI_SGE_LENGTH(flagslength)) >> 32) == 9) {
1101 flagslength |=
1102 MPI_SGE_SET_FLAGS(MPI_SGE_FLAGS_LOCAL_ADDRESS);
1103 tmp |= (1<<31);
1104 if (mpt_debug_level & MPT_DEBUG_36GB_MEM)
1105 printk(KERN_DEBUG "1078 P0M2 addressing for "
1106 "addr = 0x%llx len = %d\n",
1107 (unsigned long long)dma_addr,
1108 MPI_SGE_LENGTH(flagslength));
1109 }
1110
1111 pSge->Address.High = cpu_to_le32(tmp);
1112 pSge->FlagsLength = cpu_to_le32(
1113 (flagslength | MPT_SGE_FLAGS_64_BIT_ADDRESSING));
1114}
1115
1116/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1117/**
1118 * mpt_add_chain - Place a 32 bit chain SGE at address pAddr.
1119 * @pAddr: virtual address for SGE
1120 * @next: nextChainOffset value (u32's)
1121 * @length: length of next SGL segment
1122 * @dma_addr: Physical address
1123 *
1124 */
1125static void
1126mpt_add_chain(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1127{
1128 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
1129
1130 pChain->Length = cpu_to_le16(length);
1131 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT;
1132 pChain->NextChainOffset = next;
1133 pChain->Address = cpu_to_le32(dma_addr);
1134}
1135
1136/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1137/**
1138 * mpt_add_chain_64bit - Place a 64 bit chain SGE at address pAddr.
1139 * @pAddr: virtual address for SGE
1140 * @next: nextChainOffset value (u32's)
1141 * @length: length of next SGL segment
1142 * @dma_addr: Physical address
1143 *
1144 */
1145static void
1146mpt_add_chain_64bit(void *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
1147{
1148 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
1149 u32 tmp = dma_addr & 0xFFFFFFFF;
1150
1151 pChain->Length = cpu_to_le16(length);
1152 pChain->Flags = (MPI_SGE_FLAGS_CHAIN_ELEMENT |
1153 MPI_SGE_FLAGS_64_BIT_ADDRESSING);
1154
1155 pChain->NextChainOffset = next;
1156
1157 pChain->Address.Low = cpu_to_le32(tmp);
1158 tmp = (u32)(upper_32_bits(dma_addr));
1159 pChain->Address.High = cpu_to_le32(tmp);
1160}
1161
1162/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1163/**
1164 * mpt_send_handshake_request - Send MPT request via doorbell handshake method.
1165 * @cb_idx: Handle of registered MPT protocol driver
1166 * @ioc: Pointer to MPT adapter structure
1167 * @reqBytes: Size of the request in bytes
1168 * @req: Pointer to MPT request frame
1169 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1170 *
1171 * This routine is used exclusively to send MptScsiTaskMgmt
1172 * requests since they are required to be sent via doorbell handshake.
1173 *
1174 * NOTE: It is the callers responsibility to byte-swap fields in the
1175 * request which are greater than 1 byte in size.
1176 *
1177 * Returns 0 for success, non-zero for failure.
1178 */
1179int
1180mpt_send_handshake_request(u8 cb_idx, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
1181{
1182 int r = 0;
1183 u8 *req_as_bytes;
1184 int ii;
1185
1186 /* State is known to be good upon entering
1187 * this function so issue the bus reset
1188 * request.
1189 */
1190
1191 /*
1192 * Emulate what mpt_put_msg_frame() does /wrt to sanity
1193 * setting cb_idx/req_idx. But ONLY if this request
1194 * is in proper (pre-alloc'd) request buffer range...
1195 */
1196 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
1197 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
1198 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
1199 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
1200 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
1201 }
1202
1203 /* Make sure there are no doorbells */
1204 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1205
1206 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1207 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
1208 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
1209
1210 /* Wait for IOC doorbell int */
1211 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
1212 return ii;
1213 }
1214
1215 /* Read doorbell and check for active bit */
1216 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
1217 return -5;
1218
1219 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_send_handshake_request start, WaitCnt=%d\n",
1220 ioc->name, ii));
1221
1222 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1223
1224 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1225 return -2;
1226 }
1227
1228 /* Send request via doorbell handshake */
1229 req_as_bytes = (u8 *) req;
1230 for (ii = 0; ii < reqBytes/4; ii++) {
1231 u32 word;
1232
1233 word = ((req_as_bytes[(ii*4) + 0] << 0) |
1234 (req_as_bytes[(ii*4) + 1] << 8) |
1235 (req_as_bytes[(ii*4) + 2] << 16) |
1236 (req_as_bytes[(ii*4) + 3] << 24));
1237 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
1238 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1239 r = -3;
1240 break;
1241 }
1242 }
1243
1244 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
1245 r = 0;
1246 else
1247 r = -4;
1248
1249 /* Make sure there are no doorbells */
1250 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1251
1252 return r;
1253}
1254
1255/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1256/**
1257 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
1258 * @ioc: Pointer to MPT adapter structure
1259 * @access_control_value: define bits below
1260 * @sleepFlag: Specifies whether the process can sleep
1261 *
1262 * Provides mechanism for the host driver to control the IOC's
1263 * Host Page Buffer access.
1264 *
1265 * Access Control Value - bits[15:12]
1266 * 0h Reserved
1267 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1268 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1269 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1270 *
1271 * Returns 0 for success, non-zero for failure.
1272 */
1273
1274static int
1275mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1276{
1277 int r = 0;
1278
1279 /* return if in use */
1280 if (CHIPREG_READ32(&ioc->chip->Doorbell)
1281 & MPI_DOORBELL_ACTIVE)
1282 return -1;
1283
1284 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1285
1286 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1287 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1288 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1289 (access_control_value<<12)));
1290
1291 /* Wait for IOC to clear Doorbell Status bit */
1292 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1293 return -2;
1294 }else
1295 return 0;
1296}
1297
1298/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1299/**
1300 * mpt_host_page_alloc - allocate system memory for the fw
1301 * @ioc: Pointer to pointer to IOC adapter
1302 * @ioc_init: Pointer to ioc init config page
1303 *
1304 * If we already allocated memory in past, then resend the same pointer.
1305 * Returns 0 for success, non-zero for failure.
1306 */
1307static int
1308mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1309{
1310 char *psge;
1311 int flags_length;
1312 u32 host_page_buffer_sz=0;
1313
1314 if(!ioc->HostPageBuffer) {
1315
1316 host_page_buffer_sz =
1317 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1318
1319 if(!host_page_buffer_sz)
1320 return 0; /* fw doesn't need any host buffers */
1321
1322 /* spin till we get enough memory */
1323 while (host_page_buffer_sz > 0) {
1324 ioc->HostPageBuffer =
1325 dma_alloc_coherent(&ioc->pcidev->dev,
1326 host_page_buffer_sz,
1327 &ioc->HostPageBuffer_dma,
1328 GFP_KERNEL);
1329 if (ioc->HostPageBuffer) {
1330 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1331 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1332 ioc->name, ioc->HostPageBuffer,
1333 (u32)ioc->HostPageBuffer_dma,
1334 host_page_buffer_sz));
1335 ioc->alloc_total += host_page_buffer_sz;
1336 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1337 break;
1338 }
1339
1340 host_page_buffer_sz -= (4*1024);
1341 }
1342 }
1343
1344 if(!ioc->HostPageBuffer) {
1345 printk(MYIOC_s_ERR_FMT
1346 "Failed to alloc memory for host_page_buffer!\n",
1347 ioc->name);
1348 return -999;
1349 }
1350
1351 psge = (char *)&ioc_init->HostPageBufferSGE;
1352 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1353 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1354 MPI_SGE_FLAGS_HOST_TO_IOC |
1355 MPI_SGE_FLAGS_END_OF_BUFFER;
1356 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1357 flags_length |= ioc->HostPageBuffer_sz;
1358 ioc->add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1359 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1360
1361 return 0;
1362}
1363
1364/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1365/**
1366 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1367 * @iocid: IOC unique identifier (integer)
1368 * @iocpp: Pointer to pointer to IOC adapter
1369 *
1370 * Given a unique IOC identifier, set pointer to the associated MPT
1371 * adapter structure.
1372 *
1373 * Returns iocid and sets iocpp if iocid is found.
1374 * Returns -1 if iocid is not found.
1375 */
1376int
1377mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1378{
1379 MPT_ADAPTER *ioc;
1380
1381 list_for_each_entry(ioc,&ioc_list,list) {
1382 if (ioc->id == iocid) {
1383 *iocpp =ioc;
1384 return iocid;
1385 }
1386 }
1387
1388 *iocpp = NULL;
1389 return -1;
1390}
1391
1392/**
1393 * mpt_get_product_name - returns product string
1394 * @vendor: pci vendor id
1395 * @device: pci device id
1396 * @revision: pci revision id
1397 *
1398 * Returns product string displayed when driver loads,
1399 * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1400 *
1401 **/
1402static const char*
1403mpt_get_product_name(u16 vendor, u16 device, u8 revision)
1404{
1405 char *product_str = NULL;
1406
1407 if (vendor == PCI_VENDOR_ID_BROCADE) {
1408 switch (device)
1409 {
1410 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1411 switch (revision)
1412 {
1413 case 0x00:
1414 product_str = "BRE040 A0";
1415 break;
1416 case 0x01:
1417 product_str = "BRE040 A1";
1418 break;
1419 default:
1420 product_str = "BRE040";
1421 break;
1422 }
1423 break;
1424 }
1425 goto out;
1426 }
1427
1428 switch (device)
1429 {
1430 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1431 product_str = "LSIFC909 B1";
1432 break;
1433 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1434 product_str = "LSIFC919 B0";
1435 break;
1436 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1437 product_str = "LSIFC929 B0";
1438 break;
1439 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1440 if (revision < 0x80)
1441 product_str = "LSIFC919X A0";
1442 else
1443 product_str = "LSIFC919XL A1";
1444 break;
1445 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1446 if (revision < 0x80)
1447 product_str = "LSIFC929X A0";
1448 else
1449 product_str = "LSIFC929XL A1";
1450 break;
1451 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1452 product_str = "LSIFC939X A1";
1453 break;
1454 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1455 product_str = "LSIFC949X A1";
1456 break;
1457 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1458 switch (revision)
1459 {
1460 case 0x00:
1461 product_str = "LSIFC949E A0";
1462 break;
1463 case 0x01:
1464 product_str = "LSIFC949E A1";
1465 break;
1466 default:
1467 product_str = "LSIFC949E";
1468 break;
1469 }
1470 break;
1471 case MPI_MANUFACTPAGE_DEVID_53C1030:
1472 switch (revision)
1473 {
1474 case 0x00:
1475 product_str = "LSI53C1030 A0";
1476 break;
1477 case 0x01:
1478 product_str = "LSI53C1030 B0";
1479 break;
1480 case 0x03:
1481 product_str = "LSI53C1030 B1";
1482 break;
1483 case 0x07:
1484 product_str = "LSI53C1030 B2";
1485 break;
1486 case 0x08:
1487 product_str = "LSI53C1030 C0";
1488 break;
1489 case 0x80:
1490 product_str = "LSI53C1030T A0";
1491 break;
1492 case 0x83:
1493 product_str = "LSI53C1030T A2";
1494 break;
1495 case 0x87:
1496 product_str = "LSI53C1030T A3";
1497 break;
1498 case 0xc1:
1499 product_str = "LSI53C1020A A1";
1500 break;
1501 default:
1502 product_str = "LSI53C1030";
1503 break;
1504 }
1505 break;
1506 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1507 switch (revision)
1508 {
1509 case 0x03:
1510 product_str = "LSI53C1035 A2";
1511 break;
1512 case 0x04:
1513 product_str = "LSI53C1035 B0";
1514 break;
1515 default:
1516 product_str = "LSI53C1035";
1517 break;
1518 }
1519 break;
1520 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1521 switch (revision)
1522 {
1523 case 0x00:
1524 product_str = "LSISAS1064 A1";
1525 break;
1526 case 0x01:
1527 product_str = "LSISAS1064 A2";
1528 break;
1529 case 0x02:
1530 product_str = "LSISAS1064 A3";
1531 break;
1532 case 0x03:
1533 product_str = "LSISAS1064 A4";
1534 break;
1535 default:
1536 product_str = "LSISAS1064";
1537 break;
1538 }
1539 break;
1540 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1541 switch (revision)
1542 {
1543 case 0x00:
1544 product_str = "LSISAS1064E A0";
1545 break;
1546 case 0x01:
1547 product_str = "LSISAS1064E B0";
1548 break;
1549 case 0x02:
1550 product_str = "LSISAS1064E B1";
1551 break;
1552 case 0x04:
1553 product_str = "LSISAS1064E B2";
1554 break;
1555 case 0x08:
1556 product_str = "LSISAS1064E B3";
1557 break;
1558 default:
1559 product_str = "LSISAS1064E";
1560 break;
1561 }
1562 break;
1563 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1564 switch (revision)
1565 {
1566 case 0x00:
1567 product_str = "LSISAS1068 A0";
1568 break;
1569 case 0x01:
1570 product_str = "LSISAS1068 B0";
1571 break;
1572 case 0x02:
1573 product_str = "LSISAS1068 B1";
1574 break;
1575 default:
1576 product_str = "LSISAS1068";
1577 break;
1578 }
1579 break;
1580 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1581 switch (revision)
1582 {
1583 case 0x00:
1584 product_str = "LSISAS1068E A0";
1585 break;
1586 case 0x01:
1587 product_str = "LSISAS1068E B0";
1588 break;
1589 case 0x02:
1590 product_str = "LSISAS1068E B1";
1591 break;
1592 case 0x04:
1593 product_str = "LSISAS1068E B2";
1594 break;
1595 case 0x08:
1596 product_str = "LSISAS1068E B3";
1597 break;
1598 default:
1599 product_str = "LSISAS1068E";
1600 break;
1601 }
1602 break;
1603 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1604 switch (revision)
1605 {
1606 case 0x00:
1607 product_str = "LSISAS1078 A0";
1608 break;
1609 case 0x01:
1610 product_str = "LSISAS1078 B0";
1611 break;
1612 case 0x02:
1613 product_str = "LSISAS1078 C0";
1614 break;
1615 case 0x03:
1616 product_str = "LSISAS1078 C1";
1617 break;
1618 case 0x04:
1619 product_str = "LSISAS1078 C2";
1620 break;
1621 default:
1622 product_str = "LSISAS1078";
1623 break;
1624 }
1625 break;
1626 }
1627
1628 out:
1629 return product_str;
1630}
1631
1632/**
1633 * mpt_mapresources - map in memory mapped io
1634 * @ioc: Pointer to pointer to IOC adapter
1635 *
1636 **/
1637static int
1638mpt_mapresources(MPT_ADAPTER *ioc)
1639{
1640 u8 __iomem *mem;
1641 int ii;
1642 resource_size_t mem_phys;
1643 unsigned long port;
1644 u32 msize;
1645 u32 psize;
1646 int r = -ENODEV;
1647 struct pci_dev *pdev;
1648
1649 pdev = ioc->pcidev;
1650 ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
1651 if (pci_enable_device_mem(pdev)) {
1652 printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() "
1653 "failed\n", ioc->name);
1654 return r;
1655 }
1656 if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) {
1657 printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with "
1658 "MEM failed\n", ioc->name);
1659 goto out_pci_disable_device;
1660 }
1661
1662 if (sizeof(dma_addr_t) > 4) {
1663 const uint64_t required_mask = dma_get_required_mask
1664 (&pdev->dev);
1665 if (required_mask > DMA_BIT_MASK(32)
1666 && !pci_set_dma_mask(pdev, DMA_BIT_MASK(64))
1667 && !pci_set_consistent_dma_mask(pdev,
1668 DMA_BIT_MASK(64))) {
1669 ioc->dma_mask = DMA_BIT_MASK(64);
1670 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1671 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1672 ioc->name));
1673 } else if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1674 && !pci_set_consistent_dma_mask(pdev,
1675 DMA_BIT_MASK(32))) {
1676 ioc->dma_mask = DMA_BIT_MASK(32);
1677 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1678 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1679 ioc->name));
1680 } else {
1681 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1682 ioc->name, pci_name(pdev));
1683 goto out_pci_release_region;
1684 }
1685 } else {
1686 if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(32))
1687 && !pci_set_consistent_dma_mask(pdev,
1688 DMA_BIT_MASK(32))) {
1689 ioc->dma_mask = DMA_BIT_MASK(32);
1690 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1691 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1692 ioc->name));
1693 } else {
1694 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1695 ioc->name, pci_name(pdev));
1696 goto out_pci_release_region;
1697 }
1698 }
1699
1700 mem_phys = msize = 0;
1701 port = psize = 0;
1702 for (ii = 0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1703 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1704 if (psize)
1705 continue;
1706 /* Get I/O space! */
1707 port = pci_resource_start(pdev, ii);
1708 psize = pci_resource_len(pdev, ii);
1709 } else {
1710 if (msize)
1711 continue;
1712 /* Get memmap */
1713 mem_phys = pci_resource_start(pdev, ii);
1714 msize = pci_resource_len(pdev, ii);
1715 }
1716 }
1717 ioc->mem_size = msize;
1718
1719 mem = NULL;
1720 /* Get logical ptr for PciMem0 space */
1721 /*mem = ioremap(mem_phys, msize);*/
1722 mem = ioremap(mem_phys, msize);
1723 if (mem == NULL) {
1724 printk(MYIOC_s_ERR_FMT ": ERROR - Unable to map adapter"
1725 " memory!\n", ioc->name);
1726 r = -EINVAL;
1727 goto out_pci_release_region;
1728 }
1729 ioc->memmap = mem;
1730 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %llx\n",
1731 ioc->name, mem, (unsigned long long)mem_phys));
1732
1733 ioc->mem_phys = mem_phys;
1734 ioc->chip = (SYSIF_REGS __iomem *)mem;
1735
1736 /* Save Port IO values in case we need to do downloadboot */
1737 ioc->pio_mem_phys = port;
1738 ioc->pio_chip = (SYSIF_REGS __iomem *)port;
1739
1740 return 0;
1741
1742out_pci_release_region:
1743 pci_release_selected_regions(pdev, ioc->bars);
1744out_pci_disable_device:
1745 pci_disable_device(pdev);
1746 return r;
1747}
1748
1749/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1750/**
1751 * mpt_attach - Install a PCI intelligent MPT adapter.
1752 * @pdev: Pointer to pci_dev structure
1753 * @id: PCI device ID information
1754 *
1755 * This routine performs all the steps necessary to bring the IOC of
1756 * a MPT adapter to a OPERATIONAL state. This includes registering
1757 * memory regions, registering the interrupt, and allocating request
1758 * and reply memory pools.
1759 *
1760 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1761 * MPT adapter.
1762 *
1763 * Returns 0 for success, non-zero for failure.
1764 *
1765 * TODO: Add support for polled controllers
1766 */
1767int
1768mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1769{
1770 MPT_ADAPTER *ioc;
1771 u8 cb_idx;
1772 int r = -ENODEV;
1773 u8 pcixcmd;
1774 static int mpt_ids = 0;
1775#ifdef CONFIG_PROC_FS
1776 struct proc_dir_entry *dent;
1777#endif
1778
1779 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_KERNEL);
1780 if (ioc == NULL) {
1781 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1782 return -ENOMEM;
1783 }
1784
1785 ioc->id = mpt_ids++;
1786 sprintf(ioc->name, "ioc%d", ioc->id);
1787 dinitprintk(ioc, printk(KERN_WARNING MYNAM ": mpt_adapter_install\n"));
1788
1789 /*
1790 * set initial debug level
1791 * (refer to mptdebug.h)
1792 *
1793 */
1794 ioc->debug_level = mpt_debug_level;
1795 if (mpt_debug_level)
1796 printk(KERN_INFO "mpt_debug_level=%xh\n", mpt_debug_level);
1797
1798 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name));
1799
1800 ioc->pcidev = pdev;
1801 if (mpt_mapresources(ioc)) {
1802 goto out_free_ioc;
1803 }
1804
1805 /*
1806 * Setting up proper handlers for scatter gather handling
1807 */
1808 if (ioc->dma_mask == DMA_BIT_MASK(64)) {
1809 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
1810 ioc->add_sge = &mpt_add_sge_64bit_1078;
1811 else
1812 ioc->add_sge = &mpt_add_sge_64bit;
1813 ioc->add_chain = &mpt_add_chain_64bit;
1814 ioc->sg_addr_size = 8;
1815 } else {
1816 ioc->add_sge = &mpt_add_sge;
1817 ioc->add_chain = &mpt_add_chain;
1818 ioc->sg_addr_size = 4;
1819 }
1820 ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
1821
1822 ioc->alloc_total = sizeof(MPT_ADAPTER);
1823 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1824 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1825
1826
1827 spin_lock_init(&ioc->taskmgmt_lock);
1828 mutex_init(&ioc->internal_cmds.mutex);
1829 init_completion(&ioc->internal_cmds.done);
1830 mutex_init(&ioc->mptbase_cmds.mutex);
1831 init_completion(&ioc->mptbase_cmds.done);
1832 mutex_init(&ioc->taskmgmt_cmds.mutex);
1833 init_completion(&ioc->taskmgmt_cmds.done);
1834
1835 /* Initialize the event logging.
1836 */
1837 ioc->eventTypes = 0; /* None */
1838 ioc->eventContext = 0;
1839 ioc->eventLogSize = 0;
1840 ioc->events = NULL;
1841
1842#ifdef MFCNT
1843 ioc->mfcnt = 0;
1844#endif
1845
1846 ioc->sh = NULL;
1847 ioc->cached_fw = NULL;
1848
1849 /* Initialize SCSI Config Data structure
1850 */
1851 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1852
1853 /* Initialize the fc rport list head.
1854 */
1855 INIT_LIST_HEAD(&ioc->fc_rports);
1856
1857 /* Find lookup slot. */
1858 INIT_LIST_HEAD(&ioc->list);
1859
1860
1861 /* Initialize workqueue */
1862 INIT_DELAYED_WORK(&ioc->fault_reset_work, mpt_fault_reset_work);
1863
1864 snprintf(ioc->reset_work_q_name, MPT_KOBJ_NAME_LEN,
1865 "mpt_poll_%d", ioc->id);
1866 ioc->reset_work_q = alloc_workqueue(ioc->reset_work_q_name,
1867 WQ_MEM_RECLAIM, 0);
1868 if (!ioc->reset_work_q) {
1869 printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n",
1870 ioc->name);
1871 r = -ENOMEM;
1872 goto out_unmap_resources;
1873 }
1874
1875 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",
1876 ioc->name, &ioc->facts, &ioc->pfacts[0]));
1877
1878 ioc->prod_name = mpt_get_product_name(pdev->vendor, pdev->device,
1879 pdev->revision);
1880
1881 switch (pdev->device)
1882 {
1883 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1884 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1885 ioc->errata_flag_1064 = 1;
1886 fallthrough;
1887 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1888 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1889 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1890 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1891 ioc->bus_type = FC;
1892 break;
1893
1894 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1895 if (pdev->revision < XL_929) {
1896 /* 929X Chip Fix. Set Split transactions level
1897 * for PCIX. Set MOST bits to zero.
1898 */
1899 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1900 pcixcmd &= 0x8F;
1901 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1902 } else {
1903 /* 929XL Chip Fix. Set MMRBC to 0x08.
1904 */
1905 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1906 pcixcmd |= 0x08;
1907 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1908 }
1909 ioc->bus_type = FC;
1910 break;
1911
1912 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1913 /* 919X Chip Fix. Set Split transactions level
1914 * for PCIX. Set MOST bits to zero.
1915 */
1916 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1917 pcixcmd &= 0x8F;
1918 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1919 ioc->bus_type = FC;
1920 break;
1921
1922 case MPI_MANUFACTPAGE_DEVID_53C1030:
1923 /* 1030 Chip Fix. Disable Split transactions
1924 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1925 */
1926 if (pdev->revision < C0_1030) {
1927 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1928 pcixcmd &= 0x8F;
1929 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1930 }
1931 fallthrough;
1932
1933 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1934 ioc->bus_type = SPI;
1935 break;
1936
1937 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1938 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1939 ioc->errata_flag_1064 = 1;
1940 ioc->bus_type = SAS;
1941 break;
1942
1943 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1944 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1945 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1946 ioc->bus_type = SAS;
1947 break;
1948 }
1949
1950
1951 switch (ioc->bus_type) {
1952
1953 case SAS:
1954 ioc->msi_enable = mpt_msi_enable_sas;
1955 break;
1956
1957 case SPI:
1958 ioc->msi_enable = mpt_msi_enable_spi;
1959 break;
1960
1961 case FC:
1962 ioc->msi_enable = mpt_msi_enable_fc;
1963 break;
1964
1965 default:
1966 ioc->msi_enable = 0;
1967 break;
1968 }
1969
1970 ioc->fw_events_off = 1;
1971
1972 if (ioc->errata_flag_1064)
1973 pci_disable_io_access(pdev);
1974
1975 spin_lock_init(&ioc->FreeQlock);
1976
1977 /* Disable all! */
1978 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1979 ioc->active = 0;
1980 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1981
1982 /* Set IOC ptr in the pcidev's driver data. */
1983 pci_set_drvdata(ioc->pcidev, ioc);
1984
1985 /* Set lookup ptr. */
1986 list_add_tail(&ioc->list, &ioc_list);
1987
1988 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1989 */
1990 mpt_detect_bound_ports(ioc, pdev);
1991
1992 INIT_LIST_HEAD(&ioc->fw_event_list);
1993 spin_lock_init(&ioc->fw_event_lock);
1994 snprintf(ioc->fw_event_q_name, MPT_KOBJ_NAME_LEN, "mpt/%d", ioc->id);
1995 ioc->fw_event_q = alloc_workqueue(ioc->fw_event_q_name,
1996 WQ_MEM_RECLAIM, 0);
1997 if (!ioc->fw_event_q) {
1998 printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n",
1999 ioc->name);
2000 r = -ENOMEM;
2001 goto out_remove_ioc;
2002 }
2003
2004 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
2005 CAN_SLEEP)) != 0){
2006 printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",
2007 ioc->name, r);
2008
2009 destroy_workqueue(ioc->fw_event_q);
2010 ioc->fw_event_q = NULL;
2011
2012 list_del(&ioc->list);
2013 if (ioc->alt_ioc)
2014 ioc->alt_ioc->alt_ioc = NULL;
2015 iounmap(ioc->memmap);
2016 if (pci_is_enabled(pdev))
2017 pci_disable_device(pdev);
2018 if (r != -5)
2019 pci_release_selected_regions(pdev, ioc->bars);
2020
2021 destroy_workqueue(ioc->reset_work_q);
2022 ioc->reset_work_q = NULL;
2023
2024 kfree(ioc);
2025 return r;
2026 }
2027
2028 /* call per device driver probe entry point */
2029 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
2030 if(MptDeviceDriverHandlers[cb_idx] &&
2031 MptDeviceDriverHandlers[cb_idx]->probe) {
2032 MptDeviceDriverHandlers[cb_idx]->probe(pdev);
2033 }
2034 }
2035
2036#ifdef CONFIG_PROC_FS
2037 /*
2038 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
2039 */
2040 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
2041 if (dent) {
2042 proc_create_single_data("info", S_IRUGO, dent,
2043 mpt_iocinfo_proc_show, ioc);
2044 proc_create_single_data("summary", S_IRUGO, dent,
2045 mpt_summary_proc_show, ioc);
2046 }
2047#endif
2048
2049 if (!ioc->alt_ioc)
2050 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
2051 msecs_to_jiffies(MPT_POLLING_INTERVAL));
2052
2053 return 0;
2054
2055out_remove_ioc:
2056 list_del(&ioc->list);
2057 if (ioc->alt_ioc)
2058 ioc->alt_ioc->alt_ioc = NULL;
2059
2060 destroy_workqueue(ioc->reset_work_q);
2061 ioc->reset_work_q = NULL;
2062
2063out_unmap_resources:
2064 iounmap(ioc->memmap);
2065 pci_disable_device(pdev);
2066 pci_release_selected_regions(pdev, ioc->bars);
2067
2068out_free_ioc:
2069 kfree(ioc);
2070
2071 return r;
2072}
2073
2074/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2075/**
2076 * mpt_detach - Remove a PCI intelligent MPT adapter.
2077 * @pdev: Pointer to pci_dev structure
2078 */
2079
2080void
2081mpt_detach(struct pci_dev *pdev)
2082{
2083 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2084 char pname[64];
2085 u8 cb_idx;
2086 unsigned long flags;
2087 struct workqueue_struct *wq;
2088
2089 /*
2090 * Stop polling ioc for fault condition
2091 */
2092 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
2093 wq = ioc->reset_work_q;
2094 ioc->reset_work_q = NULL;
2095 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
2096 cancel_delayed_work(&ioc->fault_reset_work);
2097 destroy_workqueue(wq);
2098
2099 spin_lock_irqsave(&ioc->fw_event_lock, flags);
2100 wq = ioc->fw_event_q;
2101 ioc->fw_event_q = NULL;
2102 spin_unlock_irqrestore(&ioc->fw_event_lock, flags);
2103 destroy_workqueue(wq);
2104
2105 snprintf(pname, sizeof(pname), MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
2106 remove_proc_entry(pname, NULL);
2107 snprintf(pname, sizeof(pname), MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
2108 remove_proc_entry(pname, NULL);
2109 snprintf(pname, sizeof(pname), MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
2110 remove_proc_entry(pname, NULL);
2111
2112 /* call per device driver remove entry point */
2113 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
2114 if(MptDeviceDriverHandlers[cb_idx] &&
2115 MptDeviceDriverHandlers[cb_idx]->remove) {
2116 MptDeviceDriverHandlers[cb_idx]->remove(pdev);
2117 }
2118 }
2119
2120 /* Disable interrupts! */
2121 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2122
2123 ioc->active = 0;
2124 synchronize_irq(pdev->irq);
2125
2126 /* Clear any lingering interrupt */
2127 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2128
2129 CHIPREG_READ32(&ioc->chip->IntStatus);
2130
2131 mpt_adapter_dispose(ioc);
2132
2133}
2134
2135/**************************************************************************
2136 * Power Management
2137 */
2138#ifdef CONFIG_PM
2139/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2140/**
2141 * mpt_suspend - Fusion MPT base driver suspend routine.
2142 * @pdev: Pointer to pci_dev structure
2143 * @state: new state to enter
2144 */
2145int
2146mpt_suspend(struct pci_dev *pdev, pm_message_t state)
2147{
2148 u32 device_state;
2149 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2150
2151 device_state = pci_choose_state(pdev, state);
2152 printk(MYIOC_s_INFO_FMT "pci-suspend: pdev=0x%p, slot=%s, Entering "
2153 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2154 device_state);
2155
2156 /* put ioc into READY_STATE */
2157 if (SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
2158 printk(MYIOC_s_ERR_FMT
2159 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
2160 }
2161
2162 /* disable interrupts */
2163 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2164 ioc->active = 0;
2165
2166 /* Clear any lingering interrupt */
2167 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2168
2169 free_irq(ioc->pci_irq, ioc);
2170 if (ioc->msi_enable)
2171 pci_disable_msi(ioc->pcidev);
2172 ioc->pci_irq = -1;
2173 pci_save_state(pdev);
2174 pci_disable_device(pdev);
2175 pci_release_selected_regions(pdev, ioc->bars);
2176 pci_set_power_state(pdev, device_state);
2177 return 0;
2178}
2179
2180/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2181/**
2182 * mpt_resume - Fusion MPT base driver resume routine.
2183 * @pdev: Pointer to pci_dev structure
2184 */
2185int
2186mpt_resume(struct pci_dev *pdev)
2187{
2188 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
2189 u32 device_state = pdev->current_state;
2190 int recovery_state;
2191 int err;
2192
2193 printk(MYIOC_s_INFO_FMT "pci-resume: pdev=0x%p, slot=%s, Previous "
2194 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
2195 device_state);
2196
2197 pci_set_power_state(pdev, PCI_D0);
2198 pci_enable_wake(pdev, PCI_D0, 0);
2199 pci_restore_state(pdev);
2200 ioc->pcidev = pdev;
2201 err = mpt_mapresources(ioc);
2202 if (err)
2203 return err;
2204
2205 if (ioc->dma_mask == DMA_BIT_MASK(64)) {
2206 if (pdev->device == MPI_MANUFACTPAGE_DEVID_SAS1078)
2207 ioc->add_sge = &mpt_add_sge_64bit_1078;
2208 else
2209 ioc->add_sge = &mpt_add_sge_64bit;
2210 ioc->add_chain = &mpt_add_chain_64bit;
2211 ioc->sg_addr_size = 8;
2212 } else {
2213
2214 ioc->add_sge = &mpt_add_sge;
2215 ioc->add_chain = &mpt_add_chain;
2216 ioc->sg_addr_size = 4;
2217 }
2218 ioc->SGE_size = sizeof(u32) + ioc->sg_addr_size;
2219
2220 printk(MYIOC_s_INFO_FMT "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
2221 ioc->name, (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
2222 CHIPREG_READ32(&ioc->chip->Doorbell));
2223
2224 /*
2225 * Errata workaround for SAS pci express:
2226 * Upon returning to the D0 state, the contents of the doorbell will be
2227 * stale data, and this will incorrectly signal to the host driver that
2228 * the firmware is ready to process mpt commands. The workaround is
2229 * to issue a diagnostic reset.
2230 */
2231 if (ioc->bus_type == SAS && (pdev->device ==
2232 MPI_MANUFACTPAGE_DEVID_SAS1068E || pdev->device ==
2233 MPI_MANUFACTPAGE_DEVID_SAS1064E)) {
2234 if (KickStart(ioc, 1, CAN_SLEEP) < 0) {
2235 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover\n",
2236 ioc->name);
2237 goto out;
2238 }
2239 }
2240
2241 /* bring ioc to operational state */
2242 printk(MYIOC_s_INFO_FMT "Sending mpt_do_ioc_recovery\n", ioc->name);
2243 recovery_state = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
2244 CAN_SLEEP);
2245 if (recovery_state != 0)
2246 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover, "
2247 "error:[%x]\n", ioc->name, recovery_state);
2248 else
2249 printk(MYIOC_s_INFO_FMT
2250 "pci-resume: success\n", ioc->name);
2251 out:
2252 return 0;
2253
2254}
2255#endif
2256
2257static int
2258mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase)
2259{
2260 if ((MptDriverClass[index] == MPTSPI_DRIVER &&
2261 ioc->bus_type != SPI) ||
2262 (MptDriverClass[index] == MPTFC_DRIVER &&
2263 ioc->bus_type != FC) ||
2264 (MptDriverClass[index] == MPTSAS_DRIVER &&
2265 ioc->bus_type != SAS))
2266 /* make sure we only call the relevant reset handler
2267 * for the bus */
2268 return 0;
2269 return (MptResetHandlers[index])(ioc, reset_phase);
2270}
2271
2272/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2273/**
2274 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
2275 * @ioc: Pointer to MPT adapter structure
2276 * @reason: Event word / reason
2277 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
2278 *
2279 * This routine performs all the steps necessary to bring the IOC
2280 * to a OPERATIONAL state.
2281 *
2282 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
2283 * MPT adapter.
2284 *
2285 * Returns:
2286 * 0 for success
2287 * -1 if failed to get board READY
2288 * -2 if READY but IOCFacts Failed
2289 * -3 if READY but PrimeIOCFifos Failed
2290 * -4 if READY but IOCInit Failed
2291 * -5 if failed to enable_device and/or request_selected_regions
2292 * -6 if failed to upload firmware
2293 */
2294static int
2295mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2296{
2297 int hard_reset_done = 0;
2298 int alt_ioc_ready = 0;
2299 int hard;
2300 int rc=0;
2301 int ii;
2302 int ret = 0;
2303 int reset_alt_ioc_active = 0;
2304 int irq_allocated = 0;
2305 u8 *a;
2306
2307 printk(MYIOC_s_INFO_FMT "Initiating %s\n", ioc->name,
2308 reason == MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
2309
2310 /* Disable reply interrupts (also blocks FreeQ) */
2311 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2312 ioc->active = 0;
2313
2314 if (ioc->alt_ioc) {
2315 if (ioc->alt_ioc->active ||
2316 reason == MPT_HOSTEVENT_IOC_RECOVER) {
2317 reset_alt_ioc_active = 1;
2318 /* Disable alt-IOC's reply interrupts
2319 * (and FreeQ) for a bit
2320 **/
2321 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask,
2322 0xFFFFFFFF);
2323 ioc->alt_ioc->active = 0;
2324 }
2325 }
2326
2327 hard = 1;
2328 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
2329 hard = 0;
2330
2331 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
2332 if (hard_reset_done == -4) {
2333 printk(MYIOC_s_WARN_FMT "Owned by PEER..skipping!\n",
2334 ioc->name);
2335
2336 if (reset_alt_ioc_active && ioc->alt_ioc) {
2337 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
2338 dprintk(ioc, printk(MYIOC_s_INFO_FMT
2339 "alt_ioc reply irq re-enabled\n", ioc->alt_ioc->name));
2340 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2341 ioc->alt_ioc->active = 1;
2342 }
2343
2344 } else {
2345 printk(MYIOC_s_WARN_FMT
2346 "NOT READY WARNING!\n", ioc->name);
2347 }
2348 ret = -1;
2349 goto out;
2350 }
2351
2352 /* hard_reset_done = 0 if a soft reset was performed
2353 * and 1 if a hard reset was performed.
2354 */
2355 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
2356 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
2357 alt_ioc_ready = 1;
2358 else
2359 printk(MYIOC_s_WARN_FMT
2360 ": alt-ioc Not ready WARNING!\n",
2361 ioc->alt_ioc->name);
2362 }
2363
2364 for (ii=0; ii<5; ii++) {
2365 /* Get IOC facts! Allow 5 retries */
2366 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
2367 break;
2368 }
2369
2370
2371 if (ii == 5) {
2372 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2373 "Retry IocFacts failed rc=%x\n", ioc->name, rc));
2374 ret = -2;
2375 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2376 MptDisplayIocCapabilities(ioc);
2377 }
2378
2379 if (alt_ioc_ready) {
2380 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
2381 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2382 "Initial Alt IocFacts failed rc=%x\n",
2383 ioc->name, rc));
2384 /* Retry - alt IOC was initialized once
2385 */
2386 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
2387 }
2388 if (rc) {
2389 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2390 "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
2391 alt_ioc_ready = 0;
2392 reset_alt_ioc_active = 0;
2393 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2394 MptDisplayIocCapabilities(ioc->alt_ioc);
2395 }
2396 }
2397
2398 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP) &&
2399 (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)) {
2400 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2401 ioc->bars = pci_select_bars(ioc->pcidev, IORESOURCE_MEM |
2402 IORESOURCE_IO);
2403 if (pci_enable_device(ioc->pcidev))
2404 return -5;
2405 if (pci_request_selected_regions(ioc->pcidev, ioc->bars,
2406 "mpt"))
2407 return -5;
2408 }
2409
2410 /*
2411 * Device is reset now. It must have de-asserted the interrupt line
2412 * (if it was asserted) and it should be safe to register for the
2413 * interrupt now.
2414 */
2415 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2416 ioc->pci_irq = -1;
2417 if (ioc->pcidev->irq) {
2418 if (ioc->msi_enable && !pci_enable_msi(ioc->pcidev))
2419 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
2420 ioc->name);
2421 else
2422 ioc->msi_enable = 0;
2423 rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
2424 IRQF_SHARED, ioc->name, ioc);
2425 if (rc < 0) {
2426 printk(MYIOC_s_ERR_FMT "Unable to allocate "
2427 "interrupt %d!\n",
2428 ioc->name, ioc->pcidev->irq);
2429 if (ioc->msi_enable)
2430 pci_disable_msi(ioc->pcidev);
2431 ret = -EBUSY;
2432 goto out;
2433 }
2434 irq_allocated = 1;
2435 ioc->pci_irq = ioc->pcidev->irq;
2436 pci_set_master(ioc->pcidev); /* ?? */
2437 pci_set_drvdata(ioc->pcidev, ioc);
2438 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2439 "installed at interrupt %d\n", ioc->name,
2440 ioc->pcidev->irq));
2441 }
2442 }
2443
2444 /* Prime reply & request queues!
2445 * (mucho alloc's) Must be done prior to
2446 * init as upper addresses are needed for init.
2447 * If fails, continue with alt-ioc processing
2448 */
2449 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "PrimeIocFifos\n",
2450 ioc->name));
2451 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
2452 ret = -3;
2453
2454 /* May need to check/upload firmware & data here!
2455 * If fails, continue with alt-ioc processing
2456 */
2457 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "SendIocInit\n",
2458 ioc->name));
2459 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
2460 ret = -4;
2461// NEW!
2462 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
2463 printk(MYIOC_s_WARN_FMT
2464 ": alt-ioc (%d) FIFO mgmt alloc WARNING!\n",
2465 ioc->alt_ioc->name, rc);
2466 alt_ioc_ready = 0;
2467 reset_alt_ioc_active = 0;
2468 }
2469
2470 if (alt_ioc_ready) {
2471 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
2472 alt_ioc_ready = 0;
2473 reset_alt_ioc_active = 0;
2474 printk(MYIOC_s_WARN_FMT
2475 ": alt-ioc: (%d) init failure WARNING!\n",
2476 ioc->alt_ioc->name, rc);
2477 }
2478 }
2479
2480 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
2481 if (ioc->upload_fw) {
2482 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2483 "firmware upload required!\n", ioc->name));
2484
2485 /* Controller is not operational, cannot do upload
2486 */
2487 if (ret == 0) {
2488 rc = mpt_do_upload(ioc, sleepFlag);
2489 if (rc == 0) {
2490 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2491 /*
2492 * Maintain only one pointer to FW memory
2493 * so there will not be two attempt to
2494 * downloadboot onboard dual function
2495 * chips (mpt_adapter_disable,
2496 * mpt_diag_reset)
2497 */
2498 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2499 "mpt_upload: alt_%s has cached_fw=%p \n",
2500 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
2501 ioc->cached_fw = NULL;
2502 }
2503 } else {
2504 printk(MYIOC_s_WARN_FMT
2505 "firmware upload failure!\n", ioc->name);
2506 ret = -6;
2507 }
2508 }
2509 }
2510 }
2511
2512 /* Enable MPT base driver management of EventNotification
2513 * and EventAck handling.
2514 */
2515 if ((ret == 0) && (!ioc->facts.EventState)) {
2516 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2517 "SendEventNotification\n",
2518 ioc->name));
2519 ret = SendEventNotification(ioc, 1, sleepFlag); /* 1=Enable */
2520 }
2521
2522 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2523 rc = SendEventNotification(ioc->alt_ioc, 1, sleepFlag);
2524
2525 if (ret == 0) {
2526 /* Enable! (reply interrupt) */
2527 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
2528 ioc->active = 1;
2529 }
2530 if (rc == 0) { /* alt ioc */
2531 if (reset_alt_ioc_active && ioc->alt_ioc) {
2532 /* (re)Enable alt-IOC! (reply interrupt) */
2533 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "alt-ioc"
2534 "reply irq re-enabled\n",
2535 ioc->alt_ioc->name));
2536 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask,
2537 MPI_HIM_DIM);
2538 ioc->alt_ioc->active = 1;
2539 }
2540 }
2541
2542
2543 /* Add additional "reason" check before call to GetLanConfigPages
2544 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2545 * recursive scenario; GetLanConfigPages times out, timer expired
2546 * routine calls HardResetHandler, which calls into here again,
2547 * and we try GetLanConfigPages again...
2548 */
2549 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2550
2551 /*
2552 * Initialize link list for inactive raid volumes.
2553 */
2554 mutex_init(&ioc->raid_data.inactive_list_mutex);
2555 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2556
2557 switch (ioc->bus_type) {
2558
2559 case SAS:
2560 /* clear persistency table */
2561 if(ioc->facts.IOCExceptions &
2562 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
2563 ret = mptbase_sas_persist_operation(ioc,
2564 MPI_SAS_OP_CLEAR_NOT_PRESENT);
2565 if(ret != 0)
2566 goto out;
2567 }
2568
2569 /* Find IM volumes
2570 */
2571 mpt_findImVolumes(ioc);
2572
2573 /* Check, and possibly reset, the coalescing value
2574 */
2575 mpt_read_ioc_pg_1(ioc);
2576
2577 break;
2578
2579 case FC:
2580 if ((ioc->pfacts[0].ProtocolFlags &
2581 MPI_PORTFACTS_PROTOCOL_LAN) &&
2582 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2583 /*
2584 * Pre-fetch the ports LAN MAC address!
2585 * (LANPage1_t stuff)
2586 */
2587 (void) GetLanConfigPages(ioc);
2588 a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2589 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2590 "LanAddr = %pMR\n", ioc->name, a));
2591 }
2592 break;
2593
2594 case SPI:
2595 /* Get NVRAM and adapter maximums from SPP 0 and 2
2596 */
2597 mpt_GetScsiPortSettings(ioc, 0);
2598
2599 /* Get version and length of SDP 1
2600 */
2601 mpt_readScsiDevicePageHeaders(ioc, 0);
2602
2603 /* Find IM volumes
2604 */
2605 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
2606 mpt_findImVolumes(ioc);
2607
2608 /* Check, and possibly reset, the coalescing value
2609 */
2610 mpt_read_ioc_pg_1(ioc);
2611
2612 mpt_read_ioc_pg_4(ioc);
2613
2614 break;
2615 }
2616
2617 GetIoUnitPage2(ioc);
2618 mpt_get_manufacturing_pg_0(ioc);
2619 }
2620
2621 out:
2622 if ((ret != 0) && irq_allocated) {
2623 free_irq(ioc->pci_irq, ioc);
2624 if (ioc->msi_enable)
2625 pci_disable_msi(ioc->pcidev);
2626 }
2627 return ret;
2628}
2629
2630/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2631/**
2632 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2633 * @ioc: Pointer to MPT adapter structure
2634 * @pdev: Pointer to (struct pci_dev) structure
2635 *
2636 * Search for PCI bus/dev_function which matches
2637 * PCI bus/dev_function (+/-1) for newly discovered 929,
2638 * 929X, 1030 or 1035.
2639 *
2640 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2641 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2642 */
2643static void
2644mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
2645{
2646 struct pci_dev *peer=NULL;
2647 unsigned int slot = PCI_SLOT(pdev->devfn);
2648 unsigned int func = PCI_FUNC(pdev->devfn);
2649 MPT_ADAPTER *ioc_srch;
2650
2651 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PCI device %s devfn=%x/%x,"
2652 " searching for devfn match on %x or %x\n",
2653 ioc->name, pci_name(pdev), pdev->bus->number,
2654 pdev->devfn, func-1, func+1));
2655
2656 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
2657 if (!peer) {
2658 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
2659 if (!peer)
2660 return;
2661 }
2662
2663 list_for_each_entry(ioc_srch, &ioc_list, list) {
2664 struct pci_dev *_pcidev = ioc_srch->pcidev;
2665 if (_pcidev == peer) {
2666 /* Paranoia checks */
2667 if (ioc->alt_ioc != NULL) {
2668 printk(MYIOC_s_WARN_FMT
2669 "Oops, already bound (%s <==> %s)!\n",
2670 ioc->name, ioc->name, ioc->alt_ioc->name);
2671 break;
2672 } else if (ioc_srch->alt_ioc != NULL) {
2673 printk(MYIOC_s_WARN_FMT
2674 "Oops, already bound (%s <==> %s)!\n",
2675 ioc_srch->name, ioc_srch->name,
2676 ioc_srch->alt_ioc->name);
2677 break;
2678 }
2679 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2680 "FOUND! binding %s <==> %s\n",
2681 ioc->name, ioc->name, ioc_srch->name));
2682 ioc_srch->alt_ioc = ioc;
2683 ioc->alt_ioc = ioc_srch;
2684 }
2685 }
2686 pci_dev_put(peer);
2687}
2688
2689/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2690/**
2691 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2692 * @ioc: Pointer to MPT adapter structure
2693 */
2694static void
2695mpt_adapter_disable(MPT_ADAPTER *ioc)
2696{
2697 int sz;
2698 int ret;
2699
2700 if (ioc->cached_fw != NULL) {
2701 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2702 "%s: Pushing FW onto adapter\n", __func__, ioc->name));
2703 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)
2704 ioc->cached_fw, CAN_SLEEP)) < 0) {
2705 printk(MYIOC_s_WARN_FMT
2706 ": firmware downloadboot failure (%d)!\n",
2707 ioc->name, ret);
2708 }
2709 }
2710
2711 /*
2712 * Put the controller into ready state (if its not already)
2713 */
2714 if (mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_READY) {
2715 if (!SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET,
2716 CAN_SLEEP)) {
2717 if (mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_READY)
2718 printk(MYIOC_s_ERR_FMT "%s: IOC msg unit "
2719 "reset failed to put ioc in ready state!\n",
2720 ioc->name, __func__);
2721 } else
2722 printk(MYIOC_s_ERR_FMT "%s: IOC msg unit reset "
2723 "failed!\n", ioc->name, __func__);
2724 }
2725
2726
2727 /* Disable adapter interrupts! */
2728 synchronize_irq(ioc->pcidev->irq);
2729 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2730 ioc->active = 0;
2731
2732 /* Clear any lingering interrupt */
2733 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2734 CHIPREG_READ32(&ioc->chip->IntStatus);
2735
2736 if (ioc->alloc != NULL) {
2737 sz = ioc->alloc_sz;
2738 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "free @ %p, sz=%d bytes\n",
2739 ioc->name, ioc->alloc, ioc->alloc_sz));
2740 dma_free_coherent(&ioc->pcidev->dev, sz, ioc->alloc,
2741 ioc->alloc_dma);
2742 ioc->reply_frames = NULL;
2743 ioc->req_frames = NULL;
2744 ioc->alloc = NULL;
2745 ioc->alloc_total -= sz;
2746 }
2747
2748 if (ioc->sense_buf_pool != NULL) {
2749 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2750 dma_free_coherent(&ioc->pcidev->dev, sz, ioc->sense_buf_pool,
2751 ioc->sense_buf_pool_dma);
2752 ioc->sense_buf_pool = NULL;
2753 ioc->alloc_total -= sz;
2754 }
2755
2756 if (ioc->events != NULL){
2757 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2758 kfree(ioc->events);
2759 ioc->events = NULL;
2760 ioc->alloc_total -= sz;
2761 }
2762
2763 mpt_free_fw_memory(ioc);
2764
2765 kfree(ioc->spi_data.nvram);
2766 mpt_inactive_raid_list_free(ioc);
2767 kfree(ioc->raid_data.pIocPg2);
2768 kfree(ioc->raid_data.pIocPg3);
2769 ioc->spi_data.nvram = NULL;
2770 ioc->raid_data.pIocPg3 = NULL;
2771
2772 if (ioc->spi_data.pIocPg4 != NULL) {
2773 sz = ioc->spi_data.IocPg4Sz;
2774 pci_free_consistent(ioc->pcidev, sz,
2775 ioc->spi_data.pIocPg4,
2776 ioc->spi_data.IocPg4_dma);
2777 ioc->spi_data.pIocPg4 = NULL;
2778 ioc->alloc_total -= sz;
2779 }
2780
2781 if (ioc->ReqToChain != NULL) {
2782 kfree(ioc->ReqToChain);
2783 kfree(ioc->RequestNB);
2784 ioc->ReqToChain = NULL;
2785 }
2786
2787 kfree(ioc->ChainToChain);
2788 ioc->ChainToChain = NULL;
2789
2790 if (ioc->HostPageBuffer != NULL) {
2791 if((ret = mpt_host_page_access_control(ioc,
2792 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2793 printk(MYIOC_s_ERR_FMT
2794 ": %s: host page buffers free failed (%d)!\n",
2795 ioc->name, __func__, ret);
2796 }
2797 dexitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2798 "HostPageBuffer free @ %p, sz=%d bytes\n",
2799 ioc->name, ioc->HostPageBuffer,
2800 ioc->HostPageBuffer_sz));
2801 dma_free_coherent(&ioc->pcidev->dev, ioc->HostPageBuffer_sz,
2802 ioc->HostPageBuffer, ioc->HostPageBuffer_dma);
2803 ioc->HostPageBuffer = NULL;
2804 ioc->HostPageBuffer_sz = 0;
2805 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2806 }
2807
2808 pci_set_drvdata(ioc->pcidev, NULL);
2809}
2810/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2811/**
2812 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2813 * @ioc: Pointer to MPT adapter structure
2814 *
2815 * This routine unregisters h/w resources and frees all alloc'd memory
2816 * associated with a MPT adapter structure.
2817 */
2818static void
2819mpt_adapter_dispose(MPT_ADAPTER *ioc)
2820{
2821 int sz_first, sz_last;
2822
2823 if (ioc == NULL)
2824 return;
2825
2826 sz_first = ioc->alloc_total;
2827
2828 mpt_adapter_disable(ioc);
2829
2830 if (ioc->pci_irq != -1) {
2831 free_irq(ioc->pci_irq, ioc);
2832 if (ioc->msi_enable)
2833 pci_disable_msi(ioc->pcidev);
2834 ioc->pci_irq = -1;
2835 }
2836
2837 if (ioc->memmap != NULL) {
2838 iounmap(ioc->memmap);
2839 ioc->memmap = NULL;
2840 }
2841
2842 pci_disable_device(ioc->pcidev);
2843 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2844
2845 /* Zap the adapter lookup ptr! */
2846 list_del(&ioc->list);
2847
2848 sz_last = ioc->alloc_total;
2849 dprintk(ioc, printk(MYIOC_s_INFO_FMT "free'd %d of %d bytes\n",
2850 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2851
2852 if (ioc->alt_ioc)
2853 ioc->alt_ioc->alt_ioc = NULL;
2854
2855 kfree(ioc);
2856}
2857
2858/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2859/**
2860 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2861 * @ioc: Pointer to MPT adapter structure
2862 */
2863static void
2864MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2865{
2866 int i = 0;
2867
2868 printk(KERN_INFO "%s: ", ioc->name);
2869 if (ioc->prod_name)
2870 pr_cont("%s: ", ioc->prod_name);
2871 pr_cont("Capabilities={");
2872
2873 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2874 pr_cont("Initiator");
2875 i++;
2876 }
2877
2878 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2879 pr_cont("%sTarget", i ? "," : "");
2880 i++;
2881 }
2882
2883 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2884 pr_cont("%sLAN", i ? "," : "");
2885 i++;
2886 }
2887
2888#if 0
2889 /*
2890 * This would probably evoke more questions than it's worth
2891 */
2892 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2893 pr_cont("%sLogBusAddr", i ? "," : "");
2894 i++;
2895 }
2896#endif
2897
2898 pr_cont("}\n");
2899}
2900
2901/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2902/**
2903 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2904 * @ioc: Pointer to MPT_ADAPTER structure
2905 * @force: Force hard KickStart of IOC
2906 * @sleepFlag: Specifies whether the process can sleep
2907 *
2908 * Returns:
2909 * 1 - DIAG reset and READY
2910 * 0 - READY initially OR soft reset and READY
2911 * -1 - Any failure on KickStart
2912 * -2 - Msg Unit Reset Failed
2913 * -3 - IO Unit Reset Failed
2914 * -4 - IOC owned by a PEER
2915 */
2916static int
2917MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2918{
2919 u32 ioc_state;
2920 int statefault = 0;
2921 int cntdn;
2922 int hard_reset_done = 0;
2923 int r;
2924 int ii;
2925 int whoinit;
2926
2927 /* Get current [raw] IOC state */
2928 ioc_state = mpt_GetIocState(ioc, 0);
2929 dhsprintk(ioc, printk(MYIOC_s_INFO_FMT "MakeIocReady [raw] state=%08x\n", ioc->name, ioc_state));
2930
2931 /*
2932 * Check to see if IOC got left/stuck in doorbell handshake
2933 * grip of death. If so, hard reset the IOC.
2934 */
2935 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2936 statefault = 1;
2937 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2938 ioc->name);
2939 }
2940
2941 /* Is it already READY? */
2942 if (!statefault &&
2943 ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)) {
2944 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2945 "IOC is in READY state\n", ioc->name));
2946 return 0;
2947 }
2948
2949 /*
2950 * Check to see if IOC is in FAULT state.
2951 */
2952 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2953 statefault = 2;
2954 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2955 ioc->name);
2956 printk(MYIOC_s_WARN_FMT " FAULT code = %04xh\n",
2957 ioc->name, ioc_state & MPI_DOORBELL_DATA_MASK);
2958 }
2959
2960 /*
2961 * Hmmm... Did it get left operational?
2962 */
2963 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2964 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC operational unexpected\n",
2965 ioc->name));
2966
2967 /* Check WhoInit.
2968 * If PCI Peer, exit.
2969 * Else, if no fault conditions are present, issue a MessageUnitReset
2970 * Else, fall through to KickStart case
2971 */
2972 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2973 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2974 "whoinit 0x%x statefault %d force %d\n",
2975 ioc->name, whoinit, statefault, force));
2976 if (whoinit == MPI_WHOINIT_PCI_PEER)
2977 return -4;
2978 else {
2979 if ((statefault == 0 ) && (force == 0)) {
2980 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2981 return 0;
2982 }
2983 statefault = 3;
2984 }
2985 }
2986
2987 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2988 if (hard_reset_done < 0)
2989 return -1;
2990
2991 /*
2992 * Loop here waiting for IOC to come READY.
2993 */
2994 ii = 0;
2995 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2996
2997 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2998 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2999 /*
3000 * BIOS or previous driver load left IOC in OP state.
3001 * Reset messaging FIFOs.
3002 */
3003 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
3004 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
3005 return -2;
3006 }
3007 } else if (ioc_state == MPI_IOC_STATE_RESET) {
3008 /*
3009 * Something is wrong. Try to get IOC back
3010 * to a known state.
3011 */
3012 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
3013 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
3014 return -3;
3015 }
3016 }
3017
3018 ii++; cntdn--;
3019 if (!cntdn) {
3020 printk(MYIOC_s_ERR_FMT
3021 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
3022 ioc->name, ioc_state, (int)((ii+5)/HZ));
3023 return -ETIME;
3024 }
3025
3026 if (sleepFlag == CAN_SLEEP) {
3027 msleep(1);
3028 } else {
3029 mdelay (1); /* 1 msec delay */
3030 }
3031
3032 }
3033
3034 if (statefault < 3) {
3035 printk(MYIOC_s_INFO_FMT "Recovered from %s\n", ioc->name,
3036 statefault == 1 ? "stuck handshake" : "IOC FAULT");
3037 }
3038
3039 return hard_reset_done;
3040}
3041
3042/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3043/**
3044 * mpt_GetIocState - Get the current state of a MPT adapter.
3045 * @ioc: Pointer to MPT_ADAPTER structure
3046 * @cooked: Request raw or cooked IOC state
3047 *
3048 * Returns all IOC Doorbell register bits if cooked==0, else just the
3049 * Doorbell bits in MPI_IOC_STATE_MASK.
3050 */
3051u32
3052mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
3053{
3054 u32 s, sc;
3055
3056 /* Get! */
3057 s = CHIPREG_READ32(&ioc->chip->Doorbell);
3058 sc = s & MPI_IOC_STATE_MASK;
3059
3060 /* Save! */
3061 ioc->last_state = sc;
3062
3063 return cooked ? sc : s;
3064}
3065
3066/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3067/**
3068 * GetIocFacts - Send IOCFacts request to MPT adapter.
3069 * @ioc: Pointer to MPT_ADAPTER structure
3070 * @sleepFlag: Specifies whether the process can sleep
3071 * @reason: If recovery, only update facts.
3072 *
3073 * Returns 0 for success, non-zero for failure.
3074 */
3075static int
3076GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
3077{
3078 IOCFacts_t get_facts;
3079 IOCFactsReply_t *facts;
3080 int r;
3081 int req_sz;
3082 int reply_sz;
3083 int sz;
3084 u32 vv;
3085 u8 shiftFactor=1;
3086
3087 /* IOC *must* NOT be in RESET state! */
3088 if (ioc->last_state == MPI_IOC_STATE_RESET) {
3089 printk(KERN_ERR MYNAM
3090 ": ERROR - Can't get IOCFacts, %s NOT READY! (%08x)\n",
3091 ioc->name, ioc->last_state);
3092 return -44;
3093 }
3094
3095 facts = &ioc->facts;
3096
3097 /* Destination (reply area)... */
3098 reply_sz = sizeof(*facts);
3099 memset(facts, 0, reply_sz);
3100
3101 /* Request area (get_facts on the stack right now!) */
3102 req_sz = sizeof(get_facts);
3103 memset(&get_facts, 0, req_sz);
3104
3105 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
3106 /* Assert: All other get_facts fields are zero! */
3107
3108 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3109 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
3110 ioc->name, req_sz, reply_sz));
3111
3112 /* No non-zero fields in the get_facts request are greater than
3113 * 1 byte in size, so we can just fire it off as is.
3114 */
3115 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
3116 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
3117 if (r != 0)
3118 return r;
3119
3120 /*
3121 * Now byte swap (GRRR) the necessary fields before any further
3122 * inspection of reply contents.
3123 *
3124 * But need to do some sanity checks on MsgLength (byte) field
3125 * to make sure we don't zero IOC's req_sz!
3126 */
3127 /* Did we get a valid reply? */
3128 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
3129 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
3130 /*
3131 * If not been here, done that, save off first WhoInit value
3132 */
3133 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
3134 ioc->FirstWhoInit = facts->WhoInit;
3135 }
3136
3137 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
3138 facts->MsgContext = le32_to_cpu(facts->MsgContext);
3139 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
3140 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
3141 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
3142 /* CHECKME! IOCStatus, IOCLogInfo */
3143
3144 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
3145 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
3146
3147 /*
3148 * FC f/w version changed between 1.1 and 1.2
3149 * Old: u16{Major(4),Minor(4),SubMinor(8)}
3150 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
3151 */
3152 if (facts->MsgVersion < MPI_VERSION_01_02) {
3153 /*
3154 * Handle old FC f/w style, convert to new...
3155 */
3156 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
3157 facts->FWVersion.Word =
3158 ((oldv<<12) & 0xFF000000) |
3159 ((oldv<<8) & 0x000FFF00);
3160 } else
3161 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
3162
3163 facts->ProductID = le16_to_cpu(facts->ProductID);
3164
3165 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
3166 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
3167 ioc->ir_firmware = 1;
3168
3169 facts->CurrentHostMfaHighAddr =
3170 le32_to_cpu(facts->CurrentHostMfaHighAddr);
3171 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
3172 facts->CurrentSenseBufferHighAddr =
3173 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
3174 facts->CurReplyFrameSize =
3175 le16_to_cpu(facts->CurReplyFrameSize);
3176 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
3177
3178 /*
3179 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
3180 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
3181 * to 14 in MPI-1.01.0x.
3182 */
3183 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
3184 facts->MsgVersion > MPI_VERSION_01_00) {
3185 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
3186 }
3187
3188 facts->FWImageSize = ALIGN(facts->FWImageSize, 4);
3189
3190 if (!facts->RequestFrameSize) {
3191 /* Something is wrong! */
3192 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
3193 ioc->name);
3194 return -55;
3195 }
3196
3197 r = sz = facts->BlockSize;
3198 vv = ((63 / (sz * 4)) + 1) & 0x03;
3199 ioc->NB_for_64_byte_frame = vv;
3200 while ( sz )
3201 {
3202 shiftFactor++;
3203 sz = sz >> 1;
3204 }
3205 ioc->NBShiftFactor = shiftFactor;
3206 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3207 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
3208 ioc->name, vv, shiftFactor, r));
3209
3210 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
3211 /*
3212 * Set values for this IOC's request & reply frame sizes,
3213 * and request & reply queue depths...
3214 */
3215 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
3216 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
3217 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
3218 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
3219
3220 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "reply_sz=%3d, reply_depth=%4d\n",
3221 ioc->name, ioc->reply_sz, ioc->reply_depth));
3222 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "req_sz =%3d, req_depth =%4d\n",
3223 ioc->name, ioc->req_sz, ioc->req_depth));
3224
3225 /* Get port facts! */
3226 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
3227 return r;
3228 }
3229 } else {
3230 printk(MYIOC_s_ERR_FMT
3231 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
3232 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
3233 RequestFrameSize)/sizeof(u32)));
3234 return -66;
3235 }
3236
3237 return 0;
3238}
3239
3240/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3241/**
3242 * GetPortFacts - Send PortFacts request to MPT adapter.
3243 * @ioc: Pointer to MPT_ADAPTER structure
3244 * @portnum: Port number
3245 * @sleepFlag: Specifies whether the process can sleep
3246 *
3247 * Returns 0 for success, non-zero for failure.
3248 */
3249static int
3250GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3251{
3252 PortFacts_t get_pfacts;
3253 PortFactsReply_t *pfacts;
3254 int ii;
3255 int req_sz;
3256 int reply_sz;
3257 int max_id;
3258
3259 /* IOC *must* NOT be in RESET state! */
3260 if (ioc->last_state == MPI_IOC_STATE_RESET) {
3261 printk(MYIOC_s_ERR_FMT "Can't get PortFacts NOT READY! (%08x)\n",
3262 ioc->name, ioc->last_state );
3263 return -4;
3264 }
3265
3266 pfacts = &ioc->pfacts[portnum];
3267
3268 /* Destination (reply area)... */
3269 reply_sz = sizeof(*pfacts);
3270 memset(pfacts, 0, reply_sz);
3271
3272 /* Request area (get_pfacts on the stack right now!) */
3273 req_sz = sizeof(get_pfacts);
3274 memset(&get_pfacts, 0, req_sz);
3275
3276 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
3277 get_pfacts.PortNumber = portnum;
3278 /* Assert: All other get_pfacts fields are zero! */
3279
3280 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending get PortFacts(%d) request\n",
3281 ioc->name, portnum));
3282
3283 /* No non-zero fields in the get_pfacts request are greater than
3284 * 1 byte in size, so we can just fire it off as is.
3285 */
3286 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
3287 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
3288 if (ii != 0)
3289 return ii;
3290
3291 /* Did we get a valid reply? */
3292
3293 /* Now byte swap the necessary fields in the response. */
3294 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
3295 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
3296 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
3297 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
3298 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
3299 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
3300 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
3301 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
3302 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
3303
3304 max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
3305 pfacts->MaxDevices;
3306 ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
3307 ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
3308
3309 /*
3310 * Place all the devices on channels
3311 *
3312 * (for debuging)
3313 */
3314 if (mpt_channel_mapping) {
3315 ioc->devices_per_bus = 1;
3316 ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
3317 }
3318
3319 return 0;
3320}
3321
3322/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3323/**
3324 * SendIocInit - Send IOCInit request to MPT adapter.
3325 * @ioc: Pointer to MPT_ADAPTER structure
3326 * @sleepFlag: Specifies whether the process can sleep
3327 *
3328 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
3329 *
3330 * Returns 0 for success, non-zero for failure.
3331 */
3332static int
3333SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
3334{
3335 IOCInit_t ioc_init;
3336 MPIDefaultReply_t init_reply;
3337 u32 state;
3338 int r;
3339 int count;
3340 int cntdn;
3341
3342 memset(&ioc_init, 0, sizeof(ioc_init));
3343 memset(&init_reply, 0, sizeof(init_reply));
3344
3345 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
3346 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
3347
3348 /* If we are in a recovery mode and we uploaded the FW image,
3349 * then this pointer is not NULL. Skip the upload a second time.
3350 * Set this flag if cached_fw set for either IOC.
3351 */
3352 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
3353 ioc->upload_fw = 1;
3354 else
3355 ioc->upload_fw = 0;
3356 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "upload_fw %d facts.Flags=%x\n",
3357 ioc->name, ioc->upload_fw, ioc->facts.Flags));
3358
3359 ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
3360 ioc_init.MaxBuses = (U8)ioc->number_of_buses;
3361
3362 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n",
3363 ioc->name, ioc->facts.MsgVersion));
3364 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
3365 // set MsgVersion and HeaderVersion host driver was built with
3366 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
3367 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
3368
3369 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
3370 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
3371 } else if(mpt_host_page_alloc(ioc, &ioc_init))
3372 return -99;
3373 }
3374 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
3375
3376 if (ioc->sg_addr_size == sizeof(u64)) {
3377 /* Save the upper 32-bits of the request
3378 * (reply) and sense buffers.
3379 */
3380 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
3381 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
3382 } else {
3383 /* Force 32-bit addressing */
3384 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
3385 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
3386 }
3387
3388 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
3389 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
3390 ioc->facts.MaxDevices = ioc_init.MaxDevices;
3391 ioc->facts.MaxBuses = ioc_init.MaxBuses;
3392
3393 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOCInit (req @ %p)\n",
3394 ioc->name, &ioc_init));
3395
3396 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
3397 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
3398 if (r != 0) {
3399 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
3400 return r;
3401 }
3402
3403 /* No need to byte swap the multibyte fields in the reply
3404 * since we don't even look at its contents.
3405 */
3406
3407 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending PortEnable (req @ %p)\n",
3408 ioc->name, &ioc_init));
3409
3410 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
3411 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
3412 return r;
3413 }
3414
3415 /* YIKES! SUPER IMPORTANT!!!
3416 * Poll IocState until _OPERATIONAL while IOC is doing
3417 * LoopInit and TargetDiscovery!
3418 */
3419 count = 0;
3420 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
3421 state = mpt_GetIocState(ioc, 1);
3422 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
3423 if (sleepFlag == CAN_SLEEP) {
3424 msleep(1);
3425 } else {
3426 mdelay(1);
3427 }
3428
3429 if (!cntdn) {
3430 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
3431 ioc->name, (int)((count+5)/HZ));
3432 return -9;
3433 }
3434
3435 state = mpt_GetIocState(ioc, 1);
3436 count++;
3437 }
3438 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wait IOC_OPERATIONAL state (cnt=%d)\n",
3439 ioc->name, count));
3440
3441 ioc->aen_event_read_flag=0;
3442 return r;
3443}
3444
3445/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3446/**
3447 * SendPortEnable - Send PortEnable request to MPT adapter port.
3448 * @ioc: Pointer to MPT_ADAPTER structure
3449 * @portnum: Port number to enable
3450 * @sleepFlag: Specifies whether the process can sleep
3451 *
3452 * Send PortEnable to bring IOC to OPERATIONAL state.
3453 *
3454 * Returns 0 for success, non-zero for failure.
3455 */
3456static int
3457SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3458{
3459 PortEnable_t port_enable;
3460 MPIDefaultReply_t reply_buf;
3461 int rc;
3462 int req_sz;
3463 int reply_sz;
3464
3465 /* Destination... */
3466 reply_sz = sizeof(MPIDefaultReply_t);
3467 memset(&reply_buf, 0, reply_sz);
3468
3469 req_sz = sizeof(PortEnable_t);
3470 memset(&port_enable, 0, req_sz);
3471
3472 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
3473 port_enable.PortNumber = portnum;
3474/* port_enable.ChainOffset = 0; */
3475/* port_enable.MsgFlags = 0; */
3476/* port_enable.MsgContext = 0; */
3477
3478 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Port(%d)Enable (req @ %p)\n",
3479 ioc->name, portnum, &port_enable));
3480
3481 /* RAID FW may take a long time to enable
3482 */
3483 if (ioc->ir_firmware || ioc->bus_type == SAS) {
3484 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3485 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3486 300 /*seconds*/, sleepFlag);
3487 } else {
3488 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3489 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3490 30 /*seconds*/, sleepFlag);
3491 }
3492 return rc;
3493}
3494
3495/**
3496 * mpt_alloc_fw_memory - allocate firmware memory
3497 * @ioc: Pointer to MPT_ADAPTER structure
3498 * @size: total FW bytes
3499 *
3500 * If memory has already been allocated, the same (cached) value
3501 * is returned.
3502 *
3503 * Return 0 if successful, or non-zero for failure
3504 **/
3505int
3506mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
3507{
3508 int rc;
3509
3510 if (ioc->cached_fw) {
3511 rc = 0; /* use already allocated memory */
3512 goto out;
3513 }
3514 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
3515 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
3516 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
3517 rc = 0;
3518 goto out;
3519 }
3520 ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma);
3521 if (!ioc->cached_fw) {
3522 printk(MYIOC_s_ERR_FMT "Unable to allocate memory for the cached firmware image!\n",
3523 ioc->name);
3524 rc = -1;
3525 } else {
3526 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Image @ %p[%p], sz=%d[%x] bytes\n",
3527 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, size, size));
3528 ioc->alloc_total += size;
3529 rc = 0;
3530 }
3531 out:
3532 return rc;
3533}
3534
3535/**
3536 * mpt_free_fw_memory - free firmware memory
3537 * @ioc: Pointer to MPT_ADAPTER structure
3538 *
3539 * If alt_img is NULL, delete from ioc structure.
3540 * Else, delete a secondary image in same format.
3541 **/
3542void
3543mpt_free_fw_memory(MPT_ADAPTER *ioc)
3544{
3545 int sz;
3546
3547 if (!ioc->cached_fw)
3548 return;
3549
3550 sz = ioc->facts.FWImageSize;
3551 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3552 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3553 pci_free_consistent(ioc->pcidev, sz, ioc->cached_fw, ioc->cached_fw_dma);
3554 ioc->alloc_total -= sz;
3555 ioc->cached_fw = NULL;
3556}
3557
3558/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3559/**
3560 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3561 * @ioc: Pointer to MPT_ADAPTER structure
3562 * @sleepFlag: Specifies whether the process can sleep
3563 *
3564 * Returns 0 for success, >0 for handshake failure
3565 * <0 for fw upload failure.
3566 *
3567 * Remark: If bound IOC and a successful FWUpload was performed
3568 * on the bound IOC, the second image is discarded
3569 * and memory is free'd. Both channels must upload to prevent
3570 * IOC from running in degraded mode.
3571 */
3572static int
3573mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3574{
3575 u8 reply[sizeof(FWUploadReply_t)];
3576 FWUpload_t *prequest;
3577 FWUploadReply_t *preply;
3578 FWUploadTCSGE_t *ptcsge;
3579 u32 flagsLength;
3580 int ii, sz, reply_sz;
3581 int cmdStatus;
3582 int request_size;
3583 /* If the image size is 0, we are done.
3584 */
3585 if ((sz = ioc->facts.FWImageSize) == 0)
3586 return 0;
3587
3588 if (mpt_alloc_fw_memory(ioc, ioc->facts.FWImageSize) != 0)
3589 return -ENOMEM;
3590
3591 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3592 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3593
3594 prequest = (sleepFlag == NO_SLEEP) ? kzalloc(ioc->req_sz, GFP_ATOMIC) :
3595 kzalloc(ioc->req_sz, GFP_KERNEL);
3596 if (!prequest) {
3597 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed "
3598 "while allocating memory \n", ioc->name));
3599 mpt_free_fw_memory(ioc);
3600 return -ENOMEM;
3601 }
3602
3603 preply = (FWUploadReply_t *)&reply;
3604
3605 reply_sz = sizeof(reply);
3606 memset(preply, 0, reply_sz);
3607
3608 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
3609 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
3610
3611 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
3612 ptcsge->DetailsLength = 12;
3613 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
3614 ptcsge->ImageSize = cpu_to_le32(sz);
3615 ptcsge++;
3616
3617 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3618 ioc->add_sge((char *)ptcsge, flagsLength, ioc->cached_fw_dma);
3619 request_size = offsetof(FWUpload_t, SGL) + sizeof(FWUploadTCSGE_t) +
3620 ioc->SGE_size;
3621 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending FW Upload "
3622 " (req @ %p) fw_size=%d mf_request_size=%d\n", ioc->name, prequest,
3623 ioc->facts.FWImageSize, request_size));
3624 DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest);
3625
3626 ii = mpt_handshake_req_reply_wait(ioc, request_size, (u32 *)prequest,
3627 reply_sz, (u16 *)preply, 65 /*seconds*/, sleepFlag);
3628
3629 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Upload completed "
3630 "rc=%x \n", ioc->name, ii));
3631
3632 cmdStatus = -EFAULT;
3633 if (ii == 0) {
3634 /* Handshake transfer was complete and successful.
3635 * Check the Reply Frame.
3636 */
3637 int status;
3638 status = le16_to_cpu(preply->IOCStatus) &
3639 MPI_IOCSTATUS_MASK;
3640 if (status == MPI_IOCSTATUS_SUCCESS &&
3641 ioc->facts.FWImageSize ==
3642 le32_to_cpu(preply->ActualImageSize))
3643 cmdStatus = 0;
3644 }
3645 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n",
3646 ioc->name, cmdStatus));
3647
3648
3649 if (cmdStatus) {
3650 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed, "
3651 "freeing image \n", ioc->name));
3652 mpt_free_fw_memory(ioc);
3653 }
3654 kfree(prequest);
3655
3656 return cmdStatus;
3657}
3658
3659/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3660/**
3661 * mpt_downloadboot - DownloadBoot code
3662 * @ioc: Pointer to MPT_ADAPTER structure
3663 * @pFwHeader: Pointer to firmware header info
3664 * @sleepFlag: Specifies whether the process can sleep
3665 *
3666 * FwDownloadBoot requires Programmed IO access.
3667 *
3668 * Returns 0 for success
3669 * -1 FW Image size is 0
3670 * -2 No valid cached_fw Pointer
3671 * <0 for fw upload failure.
3672 */
3673static int
3674mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3675{
3676 MpiExtImageHeader_t *pExtImage;
3677 u32 fwSize;
3678 u32 diag0val;
3679 int count;
3680 u32 *ptrFw;
3681 u32 diagRwData;
3682 u32 nextImage;
3683 u32 load_addr;
3684 u32 ioc_state=0;
3685
3686 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3687 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
3688
3689 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3690 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3691 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3692 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3693 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3694 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3695
3696 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
3697
3698 /* wait 1 msec */
3699 if (sleepFlag == CAN_SLEEP) {
3700 msleep(1);
3701 } else {
3702 mdelay (1);
3703 }
3704
3705 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3706 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3707
3708 for (count = 0; count < 30; count ++) {
3709 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3710 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3711 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESET_ADAPTER cleared, count=%d\n",
3712 ioc->name, count));
3713 break;
3714 }
3715 /* wait .1 sec */
3716 if (sleepFlag == CAN_SLEEP) {
3717 msleep (100);
3718 } else {
3719 mdelay (100);
3720 }
3721 }
3722
3723 if ( count == 30 ) {
3724 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot failed! "
3725 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3726 ioc->name, diag0val));
3727 return -3;
3728 }
3729
3730 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3731 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3732 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3733 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3734 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3735 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3736
3737 /* Set the DiagRwEn and Disable ARM bits */
3738 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3739
3740 fwSize = (pFwHeader->ImageSize + 3)/4;
3741 ptrFw = (u32 *) pFwHeader;
3742
3743 /* Write the LoadStartAddress to the DiagRw Address Register
3744 * using Programmed IO
3745 */
3746 if (ioc->errata_flag_1064)
3747 pci_enable_io_access(ioc->pcidev);
3748
3749 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3750 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "LoadStart addr written 0x%x \n",
3751 ioc->name, pFwHeader->LoadStartAddress));
3752
3753 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write FW Image: 0x%x bytes @ %p\n",
3754 ioc->name, fwSize*4, ptrFw));
3755 while (fwSize--) {
3756 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3757 }
3758
3759 nextImage = pFwHeader->NextImageHeaderOffset;
3760 while (nextImage) {
3761 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3762
3763 load_addr = pExtImage->LoadStartAddress;
3764
3765 fwSize = (pExtImage->ImageSize + 3) >> 2;
3766 ptrFw = (u32 *)pExtImage;
3767
3768 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3769 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3770 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3771
3772 while (fwSize--) {
3773 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3774 }
3775 nextImage = pExtImage->NextImageHeaderOffset;
3776 }
3777
3778 /* Write the IopResetVectorRegAddr */
3779 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
3780 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3781
3782 /* Write the IopResetVectorValue */
3783 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3784 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3785
3786 /* Clear the internal flash bad bit - autoincrementing register,
3787 * so must do two writes.
3788 */
3789 if (ioc->bus_type == SPI) {
3790 /*
3791 * 1030 and 1035 H/W errata, workaround to access
3792 * the ClearFlashBadSignatureBit
3793 */
3794 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3795 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3796 diagRwData |= 0x40000000;
3797 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3798 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3799
3800 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3801 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3802 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3803 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3804
3805 /* wait 1 msec */
3806 if (sleepFlag == CAN_SLEEP) {
3807 msleep (1);
3808 } else {
3809 mdelay (1);
3810 }
3811 }
3812
3813 if (ioc->errata_flag_1064)
3814 pci_disable_io_access(ioc->pcidev);
3815
3816 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3817 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot diag0val=%x, "
3818 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3819 ioc->name, diag0val));
3820 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3821 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot now diag0val=%x\n",
3822 ioc->name, diag0val));
3823 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3824
3825 /* Write 0xFF to reset the sequencer */
3826 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3827
3828 if (ioc->bus_type == SAS) {
3829 ioc_state = mpt_GetIocState(ioc, 0);
3830 if ( (GetIocFacts(ioc, sleepFlag,
3831 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3832 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "GetIocFacts failed: IocState=%x\n",
3833 ioc->name, ioc_state));
3834 return -EFAULT;
3835 }
3836 }
3837
3838 for (count=0; count<HZ*20; count++) {
3839 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3840 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3841 "downloadboot successful! (count=%d) IocState=%x\n",
3842 ioc->name, count, ioc_state));
3843 if (ioc->bus_type == SAS) {
3844 return 0;
3845 }
3846 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3847 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3848 "downloadboot: SendIocInit failed\n",
3849 ioc->name));
3850 return -EFAULT;
3851 }
3852 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3853 "downloadboot: SendIocInit successful\n",
3854 ioc->name));
3855 return 0;
3856 }
3857 if (sleepFlag == CAN_SLEEP) {
3858 msleep (10);
3859 } else {
3860 mdelay (10);
3861 }
3862 }
3863 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3864 "downloadboot failed! IocState=%x\n",ioc->name, ioc_state));
3865 return -EFAULT;
3866}
3867
3868/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3869/**
3870 * KickStart - Perform hard reset of MPT adapter.
3871 * @ioc: Pointer to MPT_ADAPTER structure
3872 * @force: Force hard reset
3873 * @sleepFlag: Specifies whether the process can sleep
3874 *
3875 * This routine places MPT adapter in diagnostic mode via the
3876 * WriteSequence register, and then performs a hard reset of adapter
3877 * via the Diagnostic register.
3878 *
3879 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3880 * or NO_SLEEP (interrupt thread, use mdelay)
3881 * force - 1 if doorbell active, board fault state
3882 * board operational, IOC_RECOVERY or
3883 * IOC_BRINGUP and there is an alt_ioc.
3884 * 0 else
3885 *
3886 * Returns:
3887 * 1 - hard reset, READY
3888 * 0 - no reset due to History bit, READY
3889 * -1 - no reset due to History bit but not READY
3890 * OR reset but failed to come READY
3891 * -2 - no reset, could not enter DIAG mode
3892 * -3 - reset but bad FW bit
3893 */
3894static int
3895KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3896{
3897 int hard_reset_done = 0;
3898 u32 ioc_state=0;
3899 int cnt,cntdn;
3900
3901 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStarting!\n", ioc->name));
3902 if (ioc->bus_type == SPI) {
3903 /* Always issue a Msg Unit Reset first. This will clear some
3904 * SCSI bus hang conditions.
3905 */
3906 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3907
3908 if (sleepFlag == CAN_SLEEP) {
3909 msleep (1000);
3910 } else {
3911 mdelay (1000);
3912 }
3913 }
3914
3915 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3916 if (hard_reset_done < 0)
3917 return hard_reset_done;
3918
3919 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n",
3920 ioc->name));
3921
3922 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3923 for (cnt=0; cnt<cntdn; cnt++) {
3924 ioc_state = mpt_GetIocState(ioc, 1);
3925 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3926 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStart successful! (cnt=%d)\n",
3927 ioc->name, cnt));
3928 return hard_reset_done;
3929 }
3930 if (sleepFlag == CAN_SLEEP) {
3931 msleep (10);
3932 } else {
3933 mdelay (10);
3934 }
3935 }
3936
3937 dinitprintk(ioc, printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3938 ioc->name, mpt_GetIocState(ioc, 0)));
3939 return -1;
3940}
3941
3942/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3943/**
3944 * mpt_diag_reset - Perform hard reset of the adapter.
3945 * @ioc: Pointer to MPT_ADAPTER structure
3946 * @ignore: Set if to honor and clear to ignore
3947 * the reset history bit
3948 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3949 * else set to NO_SLEEP (use mdelay instead)
3950 *
3951 * This routine places the adapter in diagnostic mode via the
3952 * WriteSequence register and then performs a hard reset of adapter
3953 * via the Diagnostic register. Adapter should be in ready state
3954 * upon successful completion.
3955 *
3956 * Returns: 1 hard reset successful
3957 * 0 no reset performed because reset history bit set
3958 * -2 enabling diagnostic mode failed
3959 * -3 diagnostic reset failed
3960 */
3961static int
3962mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3963{
3964 u32 diag0val;
3965 u32 doorbell;
3966 int hard_reset_done = 0;
3967 int count = 0;
3968 u32 diag1val = 0;
3969 MpiFwHeader_t *cached_fw; /* Pointer to FW */
3970 u8 cb_idx;
3971
3972 /* Clear any existing interrupts */
3973 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3974
3975 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3976
3977 if (!ignore)
3978 return 0;
3979
3980 drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3981 "address=%p\n", ioc->name, __func__,
3982 &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3983 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3984 if (sleepFlag == CAN_SLEEP)
3985 msleep(1);
3986 else
3987 mdelay(1);
3988
3989 /*
3990 * Call each currently registered protocol IOC reset handler
3991 * with pre-reset indication.
3992 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3993 * MptResetHandlers[] registered yet.
3994 */
3995 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
3996 if (MptResetHandlers[cb_idx])
3997 (*(MptResetHandlers[cb_idx]))(ioc,
3998 MPT_IOC_PRE_RESET);
3999 }
4000
4001 for (count = 0; count < 60; count ++) {
4002 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
4003 doorbell &= MPI_IOC_STATE_MASK;
4004
4005 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4006 "looking for READY STATE: doorbell=%x"
4007 " count=%d\n",
4008 ioc->name, doorbell, count));
4009
4010 if (doorbell == MPI_IOC_STATE_READY) {
4011 return 1;
4012 }
4013
4014 /* wait 1 sec */
4015 if (sleepFlag == CAN_SLEEP)
4016 msleep(1000);
4017 else
4018 mdelay(1000);
4019 }
4020 return -1;
4021 }
4022
4023 /* Use "Diagnostic reset" method! (only thing available!) */
4024 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4025
4026 if (ioc->debug_level & MPT_DEBUG) {
4027 if (ioc->alt_ioc)
4028 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4029 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG1: diag0=%08x, diag1=%08x\n",
4030 ioc->name, diag0val, diag1val));
4031 }
4032
4033 /* Do the reset if we are told to ignore the reset history
4034 * or if the reset history is 0
4035 */
4036 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
4037 while ((diag0val & MPI_DIAG_DRWE) == 0) {
4038 /* Write magic sequence to WriteSequence register
4039 * Loop until in diagnostic mode
4040 */
4041 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
4042 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
4043 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
4044 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
4045 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
4046 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
4047
4048 /* wait 100 msec */
4049 if (sleepFlag == CAN_SLEEP) {
4050 msleep (100);
4051 } else {
4052 mdelay (100);
4053 }
4054
4055 count++;
4056 if (count > 20) {
4057 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
4058 ioc->name, diag0val);
4059 return -2;
4060
4061 }
4062
4063 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4064
4065 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
4066 ioc->name, diag0val));
4067 }
4068
4069 if (ioc->debug_level & MPT_DEBUG) {
4070 if (ioc->alt_ioc)
4071 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4072 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG2: diag0=%08x, diag1=%08x\n",
4073 ioc->name, diag0val, diag1val));
4074 }
4075 /*
4076 * Disable the ARM (Bug fix)
4077 *
4078 */
4079 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
4080 mdelay(1);
4081
4082 /*
4083 * Now hit the reset bit in the Diagnostic register
4084 * (THE BIG HAMMER!) (Clears DRWE bit).
4085 */
4086 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
4087 hard_reset_done = 1;
4088 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset performed\n",
4089 ioc->name));
4090
4091 /*
4092 * Call each currently registered protocol IOC reset handler
4093 * with pre-reset indication.
4094 * NOTE: If we're doing _IOC_BRINGUP, there can be no
4095 * MptResetHandlers[] registered yet.
4096 */
4097 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
4098 if (MptResetHandlers[cb_idx]) {
4099 mpt_signal_reset(cb_idx,
4100 ioc, MPT_IOC_PRE_RESET);
4101 if (ioc->alt_ioc) {
4102 mpt_signal_reset(cb_idx,
4103 ioc->alt_ioc, MPT_IOC_PRE_RESET);
4104 }
4105 }
4106 }
4107
4108 if (ioc->cached_fw)
4109 cached_fw = (MpiFwHeader_t *)ioc->cached_fw;
4110 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
4111 cached_fw = (MpiFwHeader_t *)ioc->alt_ioc->cached_fw;
4112 else
4113 cached_fw = NULL;
4114 if (cached_fw) {
4115 /* If the DownloadBoot operation fails, the
4116 * IOC will be left unusable. This is a fatal error
4117 * case. _diag_reset will return < 0
4118 */
4119 for (count = 0; count < 30; count ++) {
4120 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4121 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
4122 break;
4123 }
4124
4125 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n",
4126 ioc->name, diag0val, count));
4127 /* wait 1 sec */
4128 if (sleepFlag == CAN_SLEEP) {
4129 msleep (1000);
4130 } else {
4131 mdelay (1000);
4132 }
4133 }
4134 if ((count = mpt_downloadboot(ioc, cached_fw, sleepFlag)) < 0) {
4135 printk(MYIOC_s_WARN_FMT
4136 "firmware downloadboot failure (%d)!\n", ioc->name, count);
4137 }
4138
4139 } else {
4140 /* Wait for FW to reload and for board
4141 * to go to the READY state.
4142 * Maximum wait is 60 seconds.
4143 * If fail, no error will check again
4144 * with calling program.
4145 */
4146 for (count = 0; count < 60; count ++) {
4147 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
4148 doorbell &= MPI_IOC_STATE_MASK;
4149
4150 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4151 "looking for READY STATE: doorbell=%x"
4152 " count=%d\n", ioc->name, doorbell, count));
4153
4154 if (doorbell == MPI_IOC_STATE_READY) {
4155 break;
4156 }
4157
4158 /* wait 1 sec */
4159 if (sleepFlag == CAN_SLEEP) {
4160 msleep (1000);
4161 } else {
4162 mdelay (1000);
4163 }
4164 }
4165
4166 if (doorbell != MPI_IOC_STATE_READY)
4167 printk(MYIOC_s_ERR_FMT "Failed to come READY "
4168 "after reset! IocState=%x", ioc->name,
4169 doorbell);
4170 }
4171 }
4172
4173 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4174 if (ioc->debug_level & MPT_DEBUG) {
4175 if (ioc->alt_ioc)
4176 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4177 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG3: diag0=%08x, diag1=%08x\n",
4178 ioc->name, diag0val, diag1val));
4179 }
4180
4181 /* Clear RESET_HISTORY bit! Place board in the
4182 * diagnostic mode to update the diag register.
4183 */
4184 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4185 count = 0;
4186 while ((diag0val & MPI_DIAG_DRWE) == 0) {
4187 /* Write magic sequence to WriteSequence register
4188 * Loop until in diagnostic mode
4189 */
4190 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
4191 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
4192 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
4193 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
4194 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
4195 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
4196
4197 /* wait 100 msec */
4198 if (sleepFlag == CAN_SLEEP) {
4199 msleep (100);
4200 } else {
4201 mdelay (100);
4202 }
4203
4204 count++;
4205 if (count > 20) {
4206 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
4207 ioc->name, diag0val);
4208 break;
4209 }
4210 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4211 }
4212 diag0val &= ~MPI_DIAG_RESET_HISTORY;
4213 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
4214 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4215 if (diag0val & MPI_DIAG_RESET_HISTORY) {
4216 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
4217 ioc->name);
4218 }
4219
4220 /* Disable Diagnostic Mode
4221 */
4222 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
4223
4224 /* Check FW reload status flags.
4225 */
4226 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
4227 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
4228 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
4229 ioc->name, diag0val);
4230 return -3;
4231 }
4232
4233 if (ioc->debug_level & MPT_DEBUG) {
4234 if (ioc->alt_ioc)
4235 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
4236 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG4: diag0=%08x, diag1=%08x\n",
4237 ioc->name, diag0val, diag1val));
4238 }
4239
4240 /*
4241 * Reset flag that says we've enabled event notification
4242 */
4243 ioc->facts.EventState = 0;
4244
4245 if (ioc->alt_ioc)
4246 ioc->alt_ioc->facts.EventState = 0;
4247
4248 return hard_reset_done;
4249}
4250
4251/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4252/**
4253 * SendIocReset - Send IOCReset request to MPT adapter.
4254 * @ioc: Pointer to MPT_ADAPTER structure
4255 * @reset_type: reset type, expected values are
4256 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
4257 * @sleepFlag: Specifies whether the process can sleep
4258 *
4259 * Send IOCReset request to the MPT adapter.
4260 *
4261 * Returns 0 for success, non-zero for failure.
4262 */
4263static int
4264SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
4265{
4266 int r;
4267 u32 state;
4268 int cntdn, count;
4269
4270 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOC reset(0x%02x)!\n",
4271 ioc->name, reset_type));
4272 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
4273 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4274 return r;
4275
4276 /* FW ACK'd request, wait for READY state
4277 */
4278 count = 0;
4279 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
4280
4281 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
4282 cntdn--;
4283 count++;
4284 if (!cntdn) {
4285 if (sleepFlag != CAN_SLEEP)
4286 count *= 10;
4287
4288 printk(MYIOC_s_ERR_FMT
4289 "Wait IOC_READY state (0x%x) timeout(%d)!\n",
4290 ioc->name, state, (int)((count+5)/HZ));
4291 return -ETIME;
4292 }
4293
4294 if (sleepFlag == CAN_SLEEP) {
4295 msleep(1);
4296 } else {
4297 mdelay (1); /* 1 msec delay */
4298 }
4299 }
4300
4301 /* TODO!
4302 * Cleanup all event stuff for this IOC; re-issue EventNotification
4303 * request if needed.
4304 */
4305 if (ioc->facts.Function)
4306 ioc->facts.EventState = 0;
4307
4308 return 0;
4309}
4310
4311/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4312/**
4313 * initChainBuffers - Allocate memory for and initialize chain buffers
4314 * @ioc: Pointer to MPT_ADAPTER structure
4315 *
4316 * Allocates memory for and initializes chain buffers,
4317 * chain buffer control arrays and spinlock.
4318 */
4319static int
4320initChainBuffers(MPT_ADAPTER *ioc)
4321{
4322 u8 *mem;
4323 int sz, ii, num_chain;
4324 int scale, num_sge, numSGE;
4325
4326 /* ReqToChain size must equal the req_depth
4327 * index = req_idx
4328 */
4329 if (ioc->ReqToChain == NULL) {
4330 sz = ioc->req_depth * sizeof(int);
4331 mem = kmalloc(sz, GFP_ATOMIC);
4332 if (mem == NULL)
4333 return -1;
4334
4335 ioc->ReqToChain = (int *) mem;
4336 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReqToChain alloc @ %p, sz=%d bytes\n",
4337 ioc->name, mem, sz));
4338 mem = kmalloc(sz, GFP_ATOMIC);
4339 if (mem == NULL)
4340 return -1;
4341
4342 ioc->RequestNB = (int *) mem;
4343 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestNB alloc @ %p, sz=%d bytes\n",
4344 ioc->name, mem, sz));
4345 }
4346 for (ii = 0; ii < ioc->req_depth; ii++) {
4347 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
4348 }
4349
4350 /* ChainToChain size must equal the total number
4351 * of chain buffers to be allocated.
4352 * index = chain_idx
4353 *
4354 * Calculate the number of chain buffers needed(plus 1) per I/O
4355 * then multiply the maximum number of simultaneous cmds
4356 *
4357 * num_sge = num sge in request frame + last chain buffer
4358 * scale = num sge per chain buffer if no chain element
4359 */
4360 scale = ioc->req_sz / ioc->SGE_size;
4361 if (ioc->sg_addr_size == sizeof(u64))
4362 num_sge = scale + (ioc->req_sz - 60) / ioc->SGE_size;
4363 else
4364 num_sge = 1 + scale + (ioc->req_sz - 64) / ioc->SGE_size;
4365
4366 if (ioc->sg_addr_size == sizeof(u64)) {
4367 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
4368 (ioc->req_sz - 60) / ioc->SGE_size;
4369 } else {
4370 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) +
4371 scale + (ioc->req_sz - 64) / ioc->SGE_size;
4372 }
4373 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n",
4374 ioc->name, num_sge, numSGE));
4375
4376 if (ioc->bus_type == FC) {
4377 if (numSGE > MPT_SCSI_FC_SG_DEPTH)
4378 numSGE = MPT_SCSI_FC_SG_DEPTH;
4379 } else {
4380 if (numSGE > MPT_SCSI_SG_DEPTH)
4381 numSGE = MPT_SCSI_SG_DEPTH;
4382 }
4383
4384 num_chain = 1;
4385 while (numSGE - num_sge > 0) {
4386 num_chain++;
4387 num_sge += (scale - 1);
4388 }
4389 num_chain++;
4390
4391 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Now numSGE=%d num_sge=%d num_chain=%d\n",
4392 ioc->name, numSGE, num_sge, num_chain));
4393
4394 if (ioc->bus_type == SPI)
4395 num_chain *= MPT_SCSI_CAN_QUEUE;
4396 else if (ioc->bus_type == SAS)
4397 num_chain *= MPT_SAS_CAN_QUEUE;
4398 else
4399 num_chain *= MPT_FC_CAN_QUEUE;
4400
4401 ioc->num_chain = num_chain;
4402
4403 sz = num_chain * sizeof(int);
4404 if (ioc->ChainToChain == NULL) {
4405 mem = kmalloc(sz, GFP_ATOMIC);
4406 if (mem == NULL)
4407 return -1;
4408
4409 ioc->ChainToChain = (int *) mem;
4410 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainToChain alloc @ %p, sz=%d bytes\n",
4411 ioc->name, mem, sz));
4412 } else {
4413 mem = (u8 *) ioc->ChainToChain;
4414 }
4415 memset(mem, 0xFF, sz);
4416 return num_chain;
4417}
4418
4419/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4420/**
4421 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
4422 * @ioc: Pointer to MPT_ADAPTER structure
4423 *
4424 * This routine allocates memory for the MPT reply and request frame
4425 * pools (if necessary), and primes the IOC reply FIFO with
4426 * reply frames.
4427 *
4428 * Returns 0 for success, non-zero for failure.
4429 */
4430static int
4431PrimeIocFifos(MPT_ADAPTER *ioc)
4432{
4433 MPT_FRAME_HDR *mf;
4434 unsigned long flags;
4435 dma_addr_t alloc_dma;
4436 u8 *mem;
4437 int i, reply_sz, sz, total_size, num_chain;
4438 u64 dma_mask;
4439
4440 dma_mask = 0;
4441
4442 /* Prime reply FIFO... */
4443
4444 if (ioc->reply_frames == NULL) {
4445 if ( (num_chain = initChainBuffers(ioc)) < 0)
4446 return -1;
4447 /*
4448 * 1078 errata workaround for the 36GB limitation
4449 */
4450 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078 &&
4451 ioc->dma_mask > DMA_BIT_MASK(35)) {
4452 if (!pci_set_dma_mask(ioc->pcidev, DMA_BIT_MASK(32))
4453 && !pci_set_consistent_dma_mask(ioc->pcidev,
4454 DMA_BIT_MASK(32))) {
4455 dma_mask = DMA_BIT_MASK(35);
4456 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4457 "setting 35 bit addressing for "
4458 "Request/Reply/Chain and Sense Buffers\n",
4459 ioc->name));
4460 } else {
4461 /*Reseting DMA mask to 64 bit*/
4462 pci_set_dma_mask(ioc->pcidev,
4463 DMA_BIT_MASK(64));
4464 pci_set_consistent_dma_mask(ioc->pcidev,
4465 DMA_BIT_MASK(64));
4466
4467 printk(MYIOC_s_ERR_FMT
4468 "failed setting 35 bit addressing for "
4469 "Request/Reply/Chain and Sense Buffers\n",
4470 ioc->name);
4471 return -1;
4472 }
4473 }
4474
4475 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
4476 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
4477 ioc->name, ioc->reply_sz, ioc->reply_depth));
4478 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d[%x] bytes\n",
4479 ioc->name, reply_sz, reply_sz));
4480
4481 sz = (ioc->req_sz * ioc->req_depth);
4482 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d bytes, RequestDepth=%d\n",
4483 ioc->name, ioc->req_sz, ioc->req_depth));
4484 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d[%x] bytes\n",
4485 ioc->name, sz, sz));
4486 total_size += sz;
4487
4488 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
4489 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d bytes, ChainDepth=%d\n",
4490 ioc->name, ioc->req_sz, num_chain));
4491 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
4492 ioc->name, sz, sz, num_chain));
4493
4494 total_size += sz;
4495 mem = dma_alloc_coherent(&ioc->pcidev->dev, total_size,
4496 &alloc_dma, GFP_KERNEL);
4497 if (mem == NULL) {
4498 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
4499 ioc->name);
4500 goto out_fail;
4501 }
4502
4503 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Total alloc @ %p[%p], sz=%d[%x] bytes\n",
4504 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
4505
4506 memset(mem, 0, total_size);
4507 ioc->alloc_total += total_size;
4508 ioc->alloc = mem;
4509 ioc->alloc_dma = alloc_dma;
4510 ioc->alloc_sz = total_size;
4511 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
4512 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4513
4514 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4515 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4516
4517 alloc_dma += reply_sz;
4518 mem += reply_sz;
4519
4520 /* Request FIFO - WE manage this! */
4521
4522 ioc->req_frames = (MPT_FRAME_HDR *) mem;
4523 ioc->req_frames_dma = alloc_dma;
4524
4525 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffers @ %p[%p]\n",
4526 ioc->name, mem, (void *)(ulong)alloc_dma));
4527
4528 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4529
4530 for (i = 0; i < ioc->req_depth; i++) {
4531 alloc_dma += ioc->req_sz;
4532 mem += ioc->req_sz;
4533 }
4534
4535 ioc->ChainBuffer = mem;
4536 ioc->ChainBufferDMA = alloc_dma;
4537
4538 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffers @ %p(%p)\n",
4539 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
4540
4541 /* Initialize the free chain Q.
4542 */
4543
4544 INIT_LIST_HEAD(&ioc->FreeChainQ);
4545
4546 /* Post the chain buffers to the FreeChainQ.
4547 */
4548 mem = (u8 *)ioc->ChainBuffer;
4549 for (i=0; i < num_chain; i++) {
4550 mf = (MPT_FRAME_HDR *) mem;
4551 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
4552 mem += ioc->req_sz;
4553 }
4554
4555 /* Initialize Request frames linked list
4556 */
4557 alloc_dma = ioc->req_frames_dma;
4558 mem = (u8 *) ioc->req_frames;
4559
4560 spin_lock_irqsave(&ioc->FreeQlock, flags);
4561 INIT_LIST_HEAD(&ioc->FreeQ);
4562 for (i = 0; i < ioc->req_depth; i++) {
4563 mf = (MPT_FRAME_HDR *) mem;
4564
4565 /* Queue REQUESTs *internally*! */
4566 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
4567
4568 mem += ioc->req_sz;
4569 }
4570 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4571
4572 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4573 ioc->sense_buf_pool = dma_alloc_coherent(&ioc->pcidev->dev, sz,
4574 &ioc->sense_buf_pool_dma, GFP_KERNEL);
4575 if (ioc->sense_buf_pool == NULL) {
4576 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
4577 ioc->name);
4578 goto out_fail;
4579 }
4580
4581 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
4582 ioc->alloc_total += sz;
4583 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SenseBuffers @ %p[%p]\n",
4584 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
4585
4586 }
4587
4588 /* Post Reply frames to FIFO
4589 */
4590 alloc_dma = ioc->alloc_dma;
4591 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4592 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4593
4594 for (i = 0; i < ioc->reply_depth; i++) {
4595 /* Write each address to the IOC! */
4596 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
4597 alloc_dma += ioc->reply_sz;
4598 }
4599
4600 if (dma_mask == DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc->pcidev,
4601 ioc->dma_mask) && !pci_set_consistent_dma_mask(ioc->pcidev,
4602 ioc->dma_mask))
4603 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4604 "restoring 64 bit addressing\n", ioc->name));
4605
4606 return 0;
4607
4608out_fail:
4609
4610 if (ioc->alloc != NULL) {
4611 sz = ioc->alloc_sz;
4612 dma_free_coherent(&ioc->pcidev->dev, sz, ioc->alloc,
4613 ioc->alloc_dma);
4614 ioc->reply_frames = NULL;
4615 ioc->req_frames = NULL;
4616 ioc->alloc_total -= sz;
4617 }
4618 if (ioc->sense_buf_pool != NULL) {
4619 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4620 dma_free_coherent(&ioc->pcidev->dev, sz, ioc->sense_buf_pool,
4621 ioc->sense_buf_pool_dma);
4622 ioc->sense_buf_pool = NULL;
4623 }
4624
4625 if (dma_mask == DMA_BIT_MASK(35) && !pci_set_dma_mask(ioc->pcidev,
4626 DMA_BIT_MASK(64)) && !pci_set_consistent_dma_mask(ioc->pcidev,
4627 DMA_BIT_MASK(64)))
4628 d36memprintk(ioc, printk(MYIOC_s_DEBUG_FMT
4629 "restoring 64 bit addressing\n", ioc->name));
4630
4631 return -1;
4632}
4633
4634/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4635/**
4636 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4637 * from IOC via doorbell handshake method.
4638 * @ioc: Pointer to MPT_ADAPTER structure
4639 * @reqBytes: Size of the request in bytes
4640 * @req: Pointer to MPT request frame
4641 * @replyBytes: Expected size of the reply in bytes
4642 * @u16reply: Pointer to area where reply should be written
4643 * @maxwait: Max wait time for a reply (in seconds)
4644 * @sleepFlag: Specifies whether the process can sleep
4645 *
4646 * NOTES: It is the callers responsibility to byte-swap fields in the
4647 * request which are greater than 1 byte in size. It is also the
4648 * callers responsibility to byte-swap response fields which are
4649 * greater than 1 byte in size.
4650 *
4651 * Returns 0 for success, non-zero for failure.
4652 */
4653static int
4654mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
4655 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
4656{
4657 MPIDefaultReply_t *mptReply;
4658 int failcnt = 0;
4659 int t;
4660
4661 /*
4662 * Get ready to cache a handshake reply
4663 */
4664 ioc->hs_reply_idx = 0;
4665 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4666 mptReply->MsgLength = 0;
4667
4668 /*
4669 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4670 * then tell IOC that we want to handshake a request of N words.
4671 * (WRITE u32val to Doorbell reg).
4672 */
4673 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4674 CHIPREG_WRITE32(&ioc->chip->Doorbell,
4675 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
4676 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
4677
4678 /*
4679 * Wait for IOC's doorbell handshake int
4680 */
4681 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4682 failcnt++;
4683
4684 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4685 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4686
4687 /* Read doorbell and check for active bit */
4688 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
4689 return -1;
4690
4691 /*
4692 * Clear doorbell int (WRITE 0 to IntStatus reg),
4693 * then wait for IOC to ACKnowledge that it's ready for
4694 * our handshake request.
4695 */
4696 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4697 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4698 failcnt++;
4699
4700 if (!failcnt) {
4701 int ii;
4702 u8 *req_as_bytes = (u8 *) req;
4703
4704 /*
4705 * Stuff request words via doorbell handshake,
4706 * with ACK from IOC for each.
4707 */
4708 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
4709 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
4710 (req_as_bytes[(ii*4) + 1] << 8) |
4711 (req_as_bytes[(ii*4) + 2] << 16) |
4712 (req_as_bytes[(ii*4) + 3] << 24));
4713
4714 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
4715 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4716 failcnt++;
4717 }
4718
4719 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req));
4720 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req);
4721
4722 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n",
4723 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
4724
4725 /*
4726 * Wait for completion of doorbell handshake reply from the IOC
4727 */
4728 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
4729 failcnt++;
4730
4731 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake reply count=%d%s\n",
4732 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
4733
4734 /*
4735 * Copy out the cached reply...
4736 */
4737 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
4738 u16reply[ii] = ioc->hs_reply[ii];
4739 } else {
4740 return -99;
4741 }
4742
4743 return -failcnt;
4744}
4745
4746/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4747/**
4748 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4749 * @ioc: Pointer to MPT_ADAPTER structure
4750 * @howlong: How long to wait (in seconds)
4751 * @sleepFlag: Specifies whether the process can sleep
4752 *
4753 * This routine waits (up to ~2 seconds max) for IOC doorbell
4754 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4755 * bit in its IntStatus register being clear.
4756 *
4757 * Returns a negative value on failure, else wait loop count.
4758 */
4759static int
4760WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4761{
4762 int cntdn;
4763 int count = 0;
4764 u32 intstat=0;
4765
4766 cntdn = 1000 * howlong;
4767
4768 if (sleepFlag == CAN_SLEEP) {
4769 while (--cntdn) {
4770 msleep (1);
4771 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4772 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4773 break;
4774 count++;
4775 }
4776 } else {
4777 while (--cntdn) {
4778 udelay (1000);
4779 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4780 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4781 break;
4782 count++;
4783 }
4784 }
4785
4786 if (cntdn) {
4787 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell ACK (count=%d)\n",
4788 ioc->name, count));
4789 return count;
4790 }
4791
4792 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4793 ioc->name, count, intstat);
4794 return -1;
4795}
4796
4797/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4798/**
4799 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4800 * @ioc: Pointer to MPT_ADAPTER structure
4801 * @howlong: How long to wait (in seconds)
4802 * @sleepFlag: Specifies whether the process can sleep
4803 *
4804 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4805 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4806 *
4807 * Returns a negative value on failure, else wait loop count.
4808 */
4809static int
4810WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4811{
4812 int cntdn;
4813 int count = 0;
4814 u32 intstat=0;
4815
4816 cntdn = 1000 * howlong;
4817 if (sleepFlag == CAN_SLEEP) {
4818 while (--cntdn) {
4819 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4820 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4821 break;
4822 msleep(1);
4823 count++;
4824 }
4825 } else {
4826 while (--cntdn) {
4827 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4828 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4829 break;
4830 udelay (1000);
4831 count++;
4832 }
4833 }
4834
4835 if (cntdn) {
4836 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4837 ioc->name, count, howlong));
4838 return count;
4839 }
4840
4841 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4842 ioc->name, count, intstat);
4843 return -1;
4844}
4845
4846/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4847/**
4848 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4849 * @ioc: Pointer to MPT_ADAPTER structure
4850 * @howlong: How long to wait (in seconds)
4851 * @sleepFlag: Specifies whether the process can sleep
4852 *
4853 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4854 * Reply is cached to IOC private area large enough to hold a maximum
4855 * of 128 bytes of reply data.
4856 *
4857 * Returns a negative value on failure, else size of reply in WORDS.
4858 */
4859static int
4860WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4861{
4862 int u16cnt = 0;
4863 int failcnt = 0;
4864 int t;
4865 u16 *hs_reply = ioc->hs_reply;
4866 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4867 u16 hword;
4868
4869 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4870
4871 /*
4872 * Get first two u16's so we can look at IOC's intended reply MsgLength
4873 */
4874 u16cnt=0;
4875 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4876 failcnt++;
4877 } else {
4878 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4879 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4880 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4881 failcnt++;
4882 else {
4883 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4884 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4885 }
4886 }
4887
4888 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4889 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4890 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4891
4892 /*
4893 * If no error (and IOC said MsgLength is > 0), piece together
4894 * reply 16 bits at a time.
4895 */
4896 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4897 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4898 failcnt++;
4899 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4900 /* don't overflow our IOC hs_reply[] buffer! */
4901 if (u16cnt < ARRAY_SIZE(ioc->hs_reply))
4902 hs_reply[u16cnt] = hword;
4903 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4904 }
4905
4906 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4907 failcnt++;
4908 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4909
4910 if (failcnt) {
4911 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4912 ioc->name);
4913 return -failcnt;
4914 }
4915#if 0
4916 else if (u16cnt != (2 * mptReply->MsgLength)) {
4917 return -101;
4918 }
4919 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4920 return -102;
4921 }
4922#endif
4923
4924 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name));
4925 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply);
4926
4927 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4928 ioc->name, t, u16cnt/2));
4929 return u16cnt/2;
4930}
4931
4932/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4933/**
4934 * GetLanConfigPages - Fetch LANConfig pages.
4935 * @ioc: Pointer to MPT_ADAPTER structure
4936 *
4937 * Return: 0 for success
4938 * -ENOMEM if no memory available
4939 * -EPERM if not allowed due to ISR context
4940 * -EAGAIN if no msg frames currently available
4941 * -EFAULT for non-successful reply or no reply (timeout)
4942 */
4943static int
4944GetLanConfigPages(MPT_ADAPTER *ioc)
4945{
4946 ConfigPageHeader_t hdr;
4947 CONFIGPARMS cfg;
4948 LANPage0_t *ppage0_alloc;
4949 dma_addr_t page0_dma;
4950 LANPage1_t *ppage1_alloc;
4951 dma_addr_t page1_dma;
4952 int rc = 0;
4953 int data_sz;
4954 int copy_sz;
4955
4956 /* Get LAN Page 0 header */
4957 hdr.PageVersion = 0;
4958 hdr.PageLength = 0;
4959 hdr.PageNumber = 0;
4960 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4961 cfg.cfghdr.hdr = &hdr;
4962 cfg.physAddr = -1;
4963 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4964 cfg.dir = 0;
4965 cfg.pageAddr = 0;
4966 cfg.timeout = 0;
4967
4968 if ((rc = mpt_config(ioc, &cfg)) != 0)
4969 return rc;
4970
4971 if (hdr.PageLength > 0) {
4972 data_sz = hdr.PageLength * 4;
4973 ppage0_alloc = pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4974 rc = -ENOMEM;
4975 if (ppage0_alloc) {
4976 memset((u8 *)ppage0_alloc, 0, data_sz);
4977 cfg.physAddr = page0_dma;
4978 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4979
4980 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4981 /* save the data */
4982 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4983 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4984
4985 }
4986
4987 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4988
4989 /* FIXME!
4990 * Normalize endianness of structure data,
4991 * by byte-swapping all > 1 byte fields!
4992 */
4993
4994 }
4995
4996 if (rc)
4997 return rc;
4998 }
4999
5000 /* Get LAN Page 1 header */
5001 hdr.PageVersion = 0;
5002 hdr.PageLength = 0;
5003 hdr.PageNumber = 1;
5004 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
5005 cfg.cfghdr.hdr = &hdr;
5006 cfg.physAddr = -1;
5007 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5008 cfg.dir = 0;
5009 cfg.pageAddr = 0;
5010
5011 if ((rc = mpt_config(ioc, &cfg)) != 0)
5012 return rc;
5013
5014 if (hdr.PageLength == 0)
5015 return 0;
5016
5017 data_sz = hdr.PageLength * 4;
5018 rc = -ENOMEM;
5019 ppage1_alloc = pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
5020 if (ppage1_alloc) {
5021 memset((u8 *)ppage1_alloc, 0, data_sz);
5022 cfg.physAddr = page1_dma;
5023 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5024
5025 if ((rc = mpt_config(ioc, &cfg)) == 0) {
5026 /* save the data */
5027 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
5028 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
5029 }
5030
5031 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
5032
5033 /* FIXME!
5034 * Normalize endianness of structure data,
5035 * by byte-swapping all > 1 byte fields!
5036 */
5037
5038 }
5039
5040 return rc;
5041}
5042
5043/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5044/**
5045 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
5046 * @ioc: Pointer to MPT_ADAPTER structure
5047 * @persist_opcode: see below
5048 *
5049 * =============================== ======================================
5050 * MPI_SAS_OP_CLEAR_NOT_PRESENT Free all persist TargetID mappings for
5051 * devices not currently present.
5052 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT Clear al persist TargetID mappings
5053 * =============================== ======================================
5054 *
5055 * NOTE: Don't use not this function during interrupt time.
5056 *
5057 * Returns 0 for success, non-zero error
5058 */
5059
5060/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5061int
5062mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
5063{
5064 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
5065 SasIoUnitControlReply_t *sasIoUnitCntrReply;
5066 MPT_FRAME_HDR *mf = NULL;
5067 MPIHeader_t *mpi_hdr;
5068 int ret = 0;
5069 unsigned long timeleft;
5070
5071 mutex_lock(&ioc->mptbase_cmds.mutex);
5072
5073 /* init the internal cmd struct */
5074 memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE);
5075 INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status)
5076
5077 /* insure garbage is not sent to fw */
5078 switch(persist_opcode) {
5079
5080 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
5081 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
5082 break;
5083
5084 default:
5085 ret = -1;
5086 goto out;
5087 }
5088
5089 printk(KERN_DEBUG "%s: persist_opcode=%x\n",
5090 __func__, persist_opcode);
5091
5092 /* Get a MF for this command.
5093 */
5094 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5095 printk(KERN_DEBUG "%s: no msg frames!\n", __func__);
5096 ret = -1;
5097 goto out;
5098 }
5099
5100 mpi_hdr = (MPIHeader_t *) mf;
5101 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
5102 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
5103 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
5104 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
5105 sasIoUnitCntrReq->Operation = persist_opcode;
5106
5107 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5108 timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done, 10*HZ);
5109 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
5110 ret = -ETIME;
5111 printk(KERN_DEBUG "%s: failed\n", __func__);
5112 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
5113 goto out;
5114 if (!timeleft) {
5115 printk(MYIOC_s_WARN_FMT
5116 "Issuing Reset from %s!!, doorbell=0x%08x\n",
5117 ioc->name, __func__, mpt_GetIocState(ioc, 0));
5118 mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
5119 mpt_free_msg_frame(ioc, mf);
5120 }
5121 goto out;
5122 }
5123
5124 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
5125 ret = -1;
5126 goto out;
5127 }
5128
5129 sasIoUnitCntrReply =
5130 (SasIoUnitControlReply_t *)ioc->mptbase_cmds.reply;
5131 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
5132 printk(KERN_DEBUG "%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
5133 __func__, sasIoUnitCntrReply->IOCStatus,
5134 sasIoUnitCntrReply->IOCLogInfo);
5135 printk(KERN_DEBUG "%s: failed\n", __func__);
5136 ret = -1;
5137 } else
5138 printk(KERN_DEBUG "%s: success\n", __func__);
5139 out:
5140
5141 CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status)
5142 mutex_unlock(&ioc->mptbase_cmds.mutex);
5143 return ret;
5144}
5145
5146/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5147
5148static void
5149mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
5150 MpiEventDataRaid_t * pRaidEventData)
5151{
5152 int volume;
5153 int reason;
5154 int disk;
5155 int status;
5156 int flags;
5157 int state;
5158
5159 volume = pRaidEventData->VolumeID;
5160 reason = pRaidEventData->ReasonCode;
5161 disk = pRaidEventData->PhysDiskNum;
5162 status = le32_to_cpu(pRaidEventData->SettingsStatus);
5163 flags = (status >> 0) & 0xff;
5164 state = (status >> 8) & 0xff;
5165
5166 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
5167 return;
5168 }
5169
5170 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
5171 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
5172 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
5173 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
5174 ioc->name, disk, volume);
5175 } else {
5176 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
5177 ioc->name, volume);
5178 }
5179
5180 switch(reason) {
5181 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
5182 printk(MYIOC_s_INFO_FMT " volume has been created\n",
5183 ioc->name);
5184 break;
5185
5186 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
5187
5188 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
5189 ioc->name);
5190 break;
5191
5192 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
5193 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
5194 ioc->name);
5195 break;
5196
5197 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
5198 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
5199 ioc->name,
5200 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
5201 ? "optimal"
5202 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
5203 ? "degraded"
5204 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
5205 ? "failed"
5206 : "state unknown",
5207 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
5208 ? ", enabled" : "",
5209 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
5210 ? ", quiesced" : "",
5211 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
5212 ? ", resync in progress" : "" );
5213 break;
5214
5215 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
5216 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
5217 ioc->name, disk);
5218 break;
5219
5220 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
5221 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
5222 ioc->name);
5223 break;
5224
5225 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
5226 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
5227 ioc->name);
5228 break;
5229
5230 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
5231 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
5232 ioc->name);
5233 break;
5234
5235 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
5236 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
5237 ioc->name,
5238 state == MPI_PHYSDISK0_STATUS_ONLINE
5239 ? "online"
5240 : state == MPI_PHYSDISK0_STATUS_MISSING
5241 ? "missing"
5242 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
5243 ? "not compatible"
5244 : state == MPI_PHYSDISK0_STATUS_FAILED
5245 ? "failed"
5246 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
5247 ? "initializing"
5248 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
5249 ? "offline requested"
5250 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
5251 ? "failed requested"
5252 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
5253 ? "offline"
5254 : "state unknown",
5255 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
5256 ? ", out of sync" : "",
5257 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
5258 ? ", quiesced" : "" );
5259 break;
5260
5261 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
5262 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
5263 ioc->name, disk);
5264 break;
5265
5266 case MPI_EVENT_RAID_RC_SMART_DATA:
5267 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
5268 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
5269 break;
5270
5271 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
5272 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
5273 ioc->name, disk);
5274 break;
5275 }
5276}
5277
5278/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5279/**
5280 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
5281 * @ioc: Pointer to MPT_ADAPTER structure
5282 *
5283 * Returns: 0 for success
5284 * -ENOMEM if no memory available
5285 * -EPERM if not allowed due to ISR context
5286 * -EAGAIN if no msg frames currently available
5287 * -EFAULT for non-successful reply or no reply (timeout)
5288 */
5289static int
5290GetIoUnitPage2(MPT_ADAPTER *ioc)
5291{
5292 ConfigPageHeader_t hdr;
5293 CONFIGPARMS cfg;
5294 IOUnitPage2_t *ppage_alloc;
5295 dma_addr_t page_dma;
5296 int data_sz;
5297 int rc;
5298
5299 /* Get the page header */
5300 hdr.PageVersion = 0;
5301 hdr.PageLength = 0;
5302 hdr.PageNumber = 2;
5303 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
5304 cfg.cfghdr.hdr = &hdr;
5305 cfg.physAddr = -1;
5306 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5307 cfg.dir = 0;
5308 cfg.pageAddr = 0;
5309 cfg.timeout = 0;
5310
5311 if ((rc = mpt_config(ioc, &cfg)) != 0)
5312 return rc;
5313
5314 if (hdr.PageLength == 0)
5315 return 0;
5316
5317 /* Read the config page */
5318 data_sz = hdr.PageLength * 4;
5319 rc = -ENOMEM;
5320 ppage_alloc = pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
5321 if (ppage_alloc) {
5322 memset((u8 *)ppage_alloc, 0, data_sz);
5323 cfg.physAddr = page_dma;
5324 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5325
5326 /* If Good, save data */
5327 if ((rc = mpt_config(ioc, &cfg)) == 0)
5328 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
5329
5330 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
5331 }
5332
5333 return rc;
5334}
5335
5336/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5337/**
5338 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
5339 * @ioc: Pointer to a Adapter Strucutre
5340 * @portnum: IOC port number
5341 *
5342 * Return: -EFAULT if read of config page header fails
5343 * or if no nvram
5344 * If read of SCSI Port Page 0 fails,
5345 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5346 * Adapter settings: async, narrow
5347 * Return 1
5348 * If read of SCSI Port Page 2 fails,
5349 * Adapter settings valid
5350 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
5351 * Return 1
5352 * Else
5353 * Both valid
5354 * Return 0
5355 * CHECK - what type of locking mechanisms should be used????
5356 */
5357static int
5358mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
5359{
5360 u8 *pbuf;
5361 dma_addr_t buf_dma;
5362 CONFIGPARMS cfg;
5363 ConfigPageHeader_t header;
5364 int ii;
5365 int data, rc = 0;
5366
5367 /* Allocate memory
5368 */
5369 if (!ioc->spi_data.nvram) {
5370 int sz;
5371 u8 *mem;
5372 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
5373 mem = kmalloc(sz, GFP_ATOMIC);
5374 if (mem == NULL)
5375 return -EFAULT;
5376
5377 ioc->spi_data.nvram = (int *) mem;
5378
5379 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
5380 ioc->name, ioc->spi_data.nvram, sz));
5381 }
5382
5383 /* Invalidate NVRAM information
5384 */
5385 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5386 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
5387 }
5388
5389 /* Read SPP0 header, allocate memory, then read page.
5390 */
5391 header.PageVersion = 0;
5392 header.PageLength = 0;
5393 header.PageNumber = 0;
5394 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5395 cfg.cfghdr.hdr = &header;
5396 cfg.physAddr = -1;
5397 cfg.pageAddr = portnum;
5398 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5399 cfg.dir = 0;
5400 cfg.timeout = 0; /* use default */
5401 if (mpt_config(ioc, &cfg) != 0)
5402 return -EFAULT;
5403
5404 if (header.PageLength > 0) {
5405 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5406 if (pbuf) {
5407 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5408 cfg.physAddr = buf_dma;
5409 if (mpt_config(ioc, &cfg) != 0) {
5410 ioc->spi_data.maxBusWidth = MPT_NARROW;
5411 ioc->spi_data.maxSyncOffset = 0;
5412 ioc->spi_data.minSyncFactor = MPT_ASYNC;
5413 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
5414 rc = 1;
5415 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5416 "Unable to read PortPage0 minSyncFactor=%x\n",
5417 ioc->name, ioc->spi_data.minSyncFactor));
5418 } else {
5419 /* Save the Port Page 0 data
5420 */
5421 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
5422 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
5423 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
5424
5425 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
5426 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
5427 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5428 "noQas due to Capabilities=%x\n",
5429 ioc->name, pPP0->Capabilities));
5430 }
5431 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
5432 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
5433 if (data) {
5434 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
5435 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
5436 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
5437 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5438 "PortPage0 minSyncFactor=%x\n",
5439 ioc->name, ioc->spi_data.minSyncFactor));
5440 } else {
5441 ioc->spi_data.maxSyncOffset = 0;
5442 ioc->spi_data.minSyncFactor = MPT_ASYNC;
5443 }
5444
5445 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
5446
5447 /* Update the minSyncFactor based on bus type.
5448 */
5449 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
5450 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
5451
5452 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
5453 ioc->spi_data.minSyncFactor = MPT_ULTRA;
5454 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5455 "HVD or SE detected, minSyncFactor=%x\n",
5456 ioc->name, ioc->spi_data.minSyncFactor));
5457 }
5458 }
5459 }
5460 if (pbuf) {
5461 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5462 }
5463 }
5464 }
5465
5466 /* SCSI Port Page 2 - Read the header then the page.
5467 */
5468 header.PageVersion = 0;
5469 header.PageLength = 0;
5470 header.PageNumber = 2;
5471 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5472 cfg.cfghdr.hdr = &header;
5473 cfg.physAddr = -1;
5474 cfg.pageAddr = portnum;
5475 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5476 cfg.dir = 0;
5477 if (mpt_config(ioc, &cfg) != 0)
5478 return -EFAULT;
5479
5480 if (header.PageLength > 0) {
5481 /* Allocate memory and read SCSI Port Page 2
5482 */
5483 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5484 if (pbuf) {
5485 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
5486 cfg.physAddr = buf_dma;
5487 if (mpt_config(ioc, &cfg) != 0) {
5488 /* Nvram data is left with INVALID mark
5489 */
5490 rc = 1;
5491 } else if (ioc->pcidev->vendor == PCI_VENDOR_ID_ATTO) {
5492
5493 /* This is an ATTO adapter, read Page2 accordingly
5494 */
5495 ATTO_SCSIPortPage2_t *pPP2 = (ATTO_SCSIPortPage2_t *) pbuf;
5496 ATTODeviceInfo_t *pdevice = NULL;
5497 u16 ATTOFlags;
5498
5499 /* Save the Port Page 2 data
5500 * (reformat into a 32bit quantity)
5501 */
5502 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5503 pdevice = &pPP2->DeviceSettings[ii];
5504 ATTOFlags = le16_to_cpu(pdevice->ATTOFlags);
5505 data = 0;
5506
5507 /* Translate ATTO device flags to LSI format
5508 */
5509 if (ATTOFlags & ATTOFLAG_DISC)
5510 data |= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE);
5511 if (ATTOFlags & ATTOFLAG_ID_ENB)
5512 data |= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE);
5513 if (ATTOFlags & ATTOFLAG_LUN_ENB)
5514 data |= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE);
5515 if (ATTOFlags & ATTOFLAG_TAGGED)
5516 data |= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE);
5517 if (!(ATTOFlags & ATTOFLAG_WIDE_ENB))
5518 data |= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE);
5519
5520 data = (data << 16) | (pdevice->Period << 8) | 10;
5521 ioc->spi_data.nvram[ii] = data;
5522 }
5523 } else {
5524 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
5525 MpiDeviceInfo_t *pdevice = NULL;
5526
5527 /*
5528 * Save "Set to Avoid SCSI Bus Resets" flag
5529 */
5530 ioc->spi_data.bus_reset =
5531 (le32_to_cpu(pPP2->PortFlags) &
5532 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
5533 0 : 1 ;
5534
5535 /* Save the Port Page 2 data
5536 * (reformat into a 32bit quantity)
5537 */
5538 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
5539 ioc->spi_data.PortFlags = data;
5540 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5541 pdevice = &pPP2->DeviceSettings[ii];
5542 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
5543 (pdevice->SyncFactor << 8) | pdevice->Timeout;
5544 ioc->spi_data.nvram[ii] = data;
5545 }
5546 }
5547
5548 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5549 }
5550 }
5551
5552 /* Update Adapter limits with those from NVRAM
5553 * Comment: Don't need to do this. Target performance
5554 * parameters will never exceed the adapters limits.
5555 */
5556
5557 return rc;
5558}
5559
5560/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5561/**
5562 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
5563 * @ioc: Pointer to a Adapter Strucutre
5564 * @portnum: IOC port number
5565 *
5566 * Return: -EFAULT if read of config page header fails
5567 * or 0 if success.
5568 */
5569static int
5570mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
5571{
5572 CONFIGPARMS cfg;
5573 ConfigPageHeader_t header;
5574
5575 /* Read the SCSI Device Page 1 header
5576 */
5577 header.PageVersion = 0;
5578 header.PageLength = 0;
5579 header.PageNumber = 1;
5580 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5581 cfg.cfghdr.hdr = &header;
5582 cfg.physAddr = -1;
5583 cfg.pageAddr = portnum;
5584 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5585 cfg.dir = 0;
5586 cfg.timeout = 0;
5587 if (mpt_config(ioc, &cfg) != 0)
5588 return -EFAULT;
5589
5590 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
5591 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
5592
5593 header.PageVersion = 0;
5594 header.PageLength = 0;
5595 header.PageNumber = 0;
5596 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5597 if (mpt_config(ioc, &cfg) != 0)
5598 return -EFAULT;
5599
5600 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
5601 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
5602
5603 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 0: version %d length %d\n",
5604 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
5605
5606 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 1: version %d length %d\n",
5607 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
5608 return 0;
5609}
5610
5611/**
5612 * mpt_inactive_raid_list_free - This clears this link list.
5613 * @ioc : pointer to per adapter structure
5614 **/
5615static void
5616mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
5617{
5618 struct inactive_raid_component_info *component_info, *pNext;
5619
5620 if (list_empty(&ioc->raid_data.inactive_list))
5621 return;
5622
5623 mutex_lock(&ioc->raid_data.inactive_list_mutex);
5624 list_for_each_entry_safe(component_info, pNext,
5625 &ioc->raid_data.inactive_list, list) {
5626 list_del(&component_info->list);
5627 kfree(component_info);
5628 }
5629 mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5630}
5631
5632/**
5633 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5634 *
5635 * @ioc : pointer to per adapter structure
5636 * @channel : volume channel
5637 * @id : volume target id
5638 **/
5639static void
5640mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
5641{
5642 CONFIGPARMS cfg;
5643 ConfigPageHeader_t hdr;
5644 dma_addr_t dma_handle;
5645 pRaidVolumePage0_t buffer = NULL;
5646 int i;
5647 RaidPhysDiskPage0_t phys_disk;
5648 struct inactive_raid_component_info *component_info;
5649 int handle_inactive_volumes;
5650
5651 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5652 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5653 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
5654 cfg.pageAddr = (channel << 8) + id;
5655 cfg.cfghdr.hdr = &hdr;
5656 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5657
5658 if (mpt_config(ioc, &cfg) != 0)
5659 goto out;
5660
5661 if (!hdr.PageLength)
5662 goto out;
5663
5664 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5665 &dma_handle);
5666
5667 if (!buffer)
5668 goto out;
5669
5670 cfg.physAddr = dma_handle;
5671 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5672
5673 if (mpt_config(ioc, &cfg) != 0)
5674 goto out;
5675
5676 if (!buffer->NumPhysDisks)
5677 goto out;
5678
5679 handle_inactive_volumes =
5680 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
5681 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
5682 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
5683 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
5684
5685 if (!handle_inactive_volumes)
5686 goto out;
5687
5688 mutex_lock(&ioc->raid_data.inactive_list_mutex);
5689 for (i = 0; i < buffer->NumPhysDisks; i++) {
5690 if(mpt_raid_phys_disk_pg0(ioc,
5691 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
5692 continue;
5693
5694 if ((component_info = kmalloc(sizeof (*component_info),
5695 GFP_KERNEL)) == NULL)
5696 continue;
5697
5698 component_info->volumeID = id;
5699 component_info->volumeBus = channel;
5700 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
5701 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
5702 component_info->d.PhysDiskID = phys_disk.PhysDiskID;
5703 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
5704
5705 list_add_tail(&component_info->list,
5706 &ioc->raid_data.inactive_list);
5707 }
5708 mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5709
5710 out:
5711 if (buffer)
5712 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5713 dma_handle);
5714}
5715
5716/**
5717 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5718 * @ioc: Pointer to a Adapter Structure
5719 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5720 * @phys_disk: requested payload data returned
5721 *
5722 * Return:
5723 * 0 on success
5724 * -EFAULT if read of config page header fails or data pointer not NULL
5725 * -ENOMEM if pci_alloc failed
5726 **/
5727int
5728mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num,
5729 RaidPhysDiskPage0_t *phys_disk)
5730{
5731 CONFIGPARMS cfg;
5732 ConfigPageHeader_t hdr;
5733 dma_addr_t dma_handle;
5734 pRaidPhysDiskPage0_t buffer = NULL;
5735 int rc;
5736
5737 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5738 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5739 memset(phys_disk, 0, sizeof(RaidPhysDiskPage0_t));
5740
5741 hdr.PageVersion = MPI_RAIDPHYSDISKPAGE0_PAGEVERSION;
5742 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5743 cfg.cfghdr.hdr = &hdr;
5744 cfg.physAddr = -1;
5745 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5746
5747 if (mpt_config(ioc, &cfg) != 0) {
5748 rc = -EFAULT;
5749 goto out;
5750 }
5751
5752 if (!hdr.PageLength) {
5753 rc = -EFAULT;
5754 goto out;
5755 }
5756
5757 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5758 &dma_handle);
5759
5760 if (!buffer) {
5761 rc = -ENOMEM;
5762 goto out;
5763 }
5764
5765 cfg.physAddr = dma_handle;
5766 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5767 cfg.pageAddr = phys_disk_num;
5768
5769 if (mpt_config(ioc, &cfg) != 0) {
5770 rc = -EFAULT;
5771 goto out;
5772 }
5773
5774 rc = 0;
5775 memcpy(phys_disk, buffer, sizeof(*buffer));
5776 phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
5777
5778 out:
5779
5780 if (buffer)
5781 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5782 dma_handle);
5783
5784 return rc;
5785}
5786
5787/**
5788 * mpt_raid_phys_disk_get_num_paths - returns number paths associated to this phys_num
5789 * @ioc: Pointer to a Adapter Structure
5790 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5791 *
5792 * Return:
5793 * returns number paths
5794 **/
5795int
5796mpt_raid_phys_disk_get_num_paths(MPT_ADAPTER *ioc, u8 phys_disk_num)
5797{
5798 CONFIGPARMS cfg;
5799 ConfigPageHeader_t hdr;
5800 dma_addr_t dma_handle;
5801 pRaidPhysDiskPage1_t buffer = NULL;
5802 int rc;
5803
5804 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5805 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5806
5807 hdr.PageVersion = MPI_RAIDPHYSDISKPAGE1_PAGEVERSION;
5808 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5809 hdr.PageNumber = 1;
5810 cfg.cfghdr.hdr = &hdr;
5811 cfg.physAddr = -1;
5812 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5813
5814 if (mpt_config(ioc, &cfg) != 0) {
5815 rc = 0;
5816 goto out;
5817 }
5818
5819 if (!hdr.PageLength) {
5820 rc = 0;
5821 goto out;
5822 }
5823
5824 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5825 &dma_handle);
5826
5827 if (!buffer) {
5828 rc = 0;
5829 goto out;
5830 }
5831
5832 cfg.physAddr = dma_handle;
5833 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5834 cfg.pageAddr = phys_disk_num;
5835
5836 if (mpt_config(ioc, &cfg) != 0) {
5837 rc = 0;
5838 goto out;
5839 }
5840
5841 rc = buffer->NumPhysDiskPaths;
5842 out:
5843
5844 if (buffer)
5845 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5846 dma_handle);
5847
5848 return rc;
5849}
5850EXPORT_SYMBOL(mpt_raid_phys_disk_get_num_paths);
5851
5852/**
5853 * mpt_raid_phys_disk_pg1 - returns phys disk page 1
5854 * @ioc: Pointer to a Adapter Structure
5855 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5856 * @phys_disk: requested payload data returned
5857 *
5858 * Return:
5859 * 0 on success
5860 * -EFAULT if read of config page header fails or data pointer not NULL
5861 * -ENOMEM if pci_alloc failed
5862 **/
5863int
5864mpt_raid_phys_disk_pg1(MPT_ADAPTER *ioc, u8 phys_disk_num,
5865 RaidPhysDiskPage1_t *phys_disk)
5866{
5867 CONFIGPARMS cfg;
5868 ConfigPageHeader_t hdr;
5869 dma_addr_t dma_handle;
5870 pRaidPhysDiskPage1_t buffer = NULL;
5871 int rc;
5872 int i;
5873 __le64 sas_address;
5874
5875 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5876 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5877 rc = 0;
5878
5879 hdr.PageVersion = MPI_RAIDPHYSDISKPAGE1_PAGEVERSION;
5880 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5881 hdr.PageNumber = 1;
5882 cfg.cfghdr.hdr = &hdr;
5883 cfg.physAddr = -1;
5884 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5885
5886 if (mpt_config(ioc, &cfg) != 0) {
5887 rc = -EFAULT;
5888 goto out;
5889 }
5890
5891 if (!hdr.PageLength) {
5892 rc = -EFAULT;
5893 goto out;
5894 }
5895
5896 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5897 &dma_handle);
5898
5899 if (!buffer) {
5900 rc = -ENOMEM;
5901 goto out;
5902 }
5903
5904 cfg.physAddr = dma_handle;
5905 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5906 cfg.pageAddr = phys_disk_num;
5907
5908 if (mpt_config(ioc, &cfg) != 0) {
5909 rc = -EFAULT;
5910 goto out;
5911 }
5912
5913 phys_disk->NumPhysDiskPaths = buffer->NumPhysDiskPaths;
5914 phys_disk->PhysDiskNum = phys_disk_num;
5915 for (i = 0; i < phys_disk->NumPhysDiskPaths; i++) {
5916 phys_disk->Path[i].PhysDiskID = buffer->Path[i].PhysDiskID;
5917 phys_disk->Path[i].PhysDiskBus = buffer->Path[i].PhysDiskBus;
5918 phys_disk->Path[i].OwnerIdentifier =
5919 buffer->Path[i].OwnerIdentifier;
5920 phys_disk->Path[i].Flags = le16_to_cpu(buffer->Path[i].Flags);
5921 memcpy(&sas_address, &buffer->Path[i].WWID, sizeof(__le64));
5922 sas_address = le64_to_cpu(sas_address);
5923 memcpy(&phys_disk->Path[i].WWID, &sas_address, sizeof(__le64));
5924 memcpy(&sas_address,
5925 &buffer->Path[i].OwnerWWID, sizeof(__le64));
5926 sas_address = le64_to_cpu(sas_address);
5927 memcpy(&phys_disk->Path[i].OwnerWWID,
5928 &sas_address, sizeof(__le64));
5929 }
5930
5931 out:
5932
5933 if (buffer)
5934 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5935 dma_handle);
5936
5937 return rc;
5938}
5939EXPORT_SYMBOL(mpt_raid_phys_disk_pg1);
5940
5941
5942/**
5943 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5944 * @ioc: Pointer to a Adapter Strucutre
5945 *
5946 * Return:
5947 * 0 on success
5948 * -EFAULT if read of config page header fails or data pointer not NULL
5949 * -ENOMEM if pci_alloc failed
5950 **/
5951int
5952mpt_findImVolumes(MPT_ADAPTER *ioc)
5953{
5954 IOCPage2_t *pIoc2;
5955 u8 *mem;
5956 dma_addr_t ioc2_dma;
5957 CONFIGPARMS cfg;
5958 ConfigPageHeader_t header;
5959 int rc = 0;
5960 int iocpage2sz;
5961 int i;
5962
5963 if (!ioc->ir_firmware)
5964 return 0;
5965
5966 /* Free the old page
5967 */
5968 kfree(ioc->raid_data.pIocPg2);
5969 ioc->raid_data.pIocPg2 = NULL;
5970 mpt_inactive_raid_list_free(ioc);
5971
5972 /* Read IOCP2 header then the page.
5973 */
5974 header.PageVersion = 0;
5975 header.PageLength = 0;
5976 header.PageNumber = 2;
5977 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5978 cfg.cfghdr.hdr = &header;
5979 cfg.physAddr = -1;
5980 cfg.pageAddr = 0;
5981 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5982 cfg.dir = 0;
5983 cfg.timeout = 0;
5984 if (mpt_config(ioc, &cfg) != 0)
5985 return -EFAULT;
5986
5987 if (header.PageLength == 0)
5988 return -EFAULT;
5989
5990 iocpage2sz = header.PageLength * 4;
5991 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
5992 if (!pIoc2)
5993 return -ENOMEM;
5994
5995 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5996 cfg.physAddr = ioc2_dma;
5997 if (mpt_config(ioc, &cfg) != 0)
5998 goto out;
5999
6000 mem = kmemdup(pIoc2, iocpage2sz, GFP_KERNEL);
6001 if (!mem) {
6002 rc = -ENOMEM;
6003 goto out;
6004 }
6005
6006 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
6007
6008 mpt_read_ioc_pg_3(ioc);
6009
6010 for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
6011 mpt_inactive_raid_volumes(ioc,
6012 pIoc2->RaidVolume[i].VolumeBus,
6013 pIoc2->RaidVolume[i].VolumeID);
6014
6015 out:
6016 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
6017
6018 return rc;
6019}
6020
6021static int
6022mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
6023{
6024 IOCPage3_t *pIoc3;
6025 u8 *mem;
6026 CONFIGPARMS cfg;
6027 ConfigPageHeader_t header;
6028 dma_addr_t ioc3_dma;
6029 int iocpage3sz = 0;
6030
6031 /* Free the old page
6032 */
6033 kfree(ioc->raid_data.pIocPg3);
6034 ioc->raid_data.pIocPg3 = NULL;
6035
6036 /* There is at least one physical disk.
6037 * Read and save IOC Page 3
6038 */
6039 header.PageVersion = 0;
6040 header.PageLength = 0;
6041 header.PageNumber = 3;
6042 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
6043 cfg.cfghdr.hdr = &header;
6044 cfg.physAddr = -1;
6045 cfg.pageAddr = 0;
6046 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6047 cfg.dir = 0;
6048 cfg.timeout = 0;
6049 if (mpt_config(ioc, &cfg) != 0)
6050 return 0;
6051
6052 if (header.PageLength == 0)
6053 return 0;
6054
6055 /* Read Header good, alloc memory
6056 */
6057 iocpage3sz = header.PageLength * 4;
6058 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
6059 if (!pIoc3)
6060 return 0;
6061
6062 /* Read the Page and save the data
6063 * into malloc'd memory.
6064 */
6065 cfg.physAddr = ioc3_dma;
6066 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6067 if (mpt_config(ioc, &cfg) == 0) {
6068 mem = kmalloc(iocpage3sz, GFP_KERNEL);
6069 if (mem) {
6070 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
6071 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
6072 }
6073 }
6074
6075 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
6076
6077 return 0;
6078}
6079
6080static void
6081mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
6082{
6083 IOCPage4_t *pIoc4;
6084 CONFIGPARMS cfg;
6085 ConfigPageHeader_t header;
6086 dma_addr_t ioc4_dma;
6087 int iocpage4sz;
6088
6089 /* Read and save IOC Page 4
6090 */
6091 header.PageVersion = 0;
6092 header.PageLength = 0;
6093 header.PageNumber = 4;
6094 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
6095 cfg.cfghdr.hdr = &header;
6096 cfg.physAddr = -1;
6097 cfg.pageAddr = 0;
6098 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6099 cfg.dir = 0;
6100 cfg.timeout = 0;
6101 if (mpt_config(ioc, &cfg) != 0)
6102 return;
6103
6104 if (header.PageLength == 0)
6105 return;
6106
6107 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
6108 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
6109 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
6110 if (!pIoc4)
6111 return;
6112 ioc->alloc_total += iocpage4sz;
6113 } else {
6114 ioc4_dma = ioc->spi_data.IocPg4_dma;
6115 iocpage4sz = ioc->spi_data.IocPg4Sz;
6116 }
6117
6118 /* Read the Page into dma memory.
6119 */
6120 cfg.physAddr = ioc4_dma;
6121 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6122 if (mpt_config(ioc, &cfg) == 0) {
6123 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
6124 ioc->spi_data.IocPg4_dma = ioc4_dma;
6125 ioc->spi_data.IocPg4Sz = iocpage4sz;
6126 } else {
6127 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
6128 ioc->spi_data.pIocPg4 = NULL;
6129 ioc->alloc_total -= iocpage4sz;
6130 }
6131}
6132
6133static void
6134mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
6135{
6136 IOCPage1_t *pIoc1;
6137 CONFIGPARMS cfg;
6138 ConfigPageHeader_t header;
6139 dma_addr_t ioc1_dma;
6140 int iocpage1sz = 0;
6141 u32 tmp;
6142
6143 /* Check the Coalescing Timeout in IOC Page 1
6144 */
6145 header.PageVersion = 0;
6146 header.PageLength = 0;
6147 header.PageNumber = 1;
6148 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
6149 cfg.cfghdr.hdr = &header;
6150 cfg.physAddr = -1;
6151 cfg.pageAddr = 0;
6152 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6153 cfg.dir = 0;
6154 cfg.timeout = 0;
6155 if (mpt_config(ioc, &cfg) != 0)
6156 return;
6157
6158 if (header.PageLength == 0)
6159 return;
6160
6161 /* Read Header good, alloc memory
6162 */
6163 iocpage1sz = header.PageLength * 4;
6164 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
6165 if (!pIoc1)
6166 return;
6167
6168 /* Read the Page and check coalescing timeout
6169 */
6170 cfg.physAddr = ioc1_dma;
6171 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6172 if (mpt_config(ioc, &cfg) == 0) {
6173
6174 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
6175 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
6176 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
6177
6178 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Coalescing Enabled Timeout = %d\n",
6179 ioc->name, tmp));
6180
6181 if (tmp > MPT_COALESCING_TIMEOUT) {
6182 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
6183
6184 /* Write NVRAM and current
6185 */
6186 cfg.dir = 1;
6187 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
6188 if (mpt_config(ioc, &cfg) == 0) {
6189 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Reset Current Coalescing Timeout to = %d\n",
6190 ioc->name, MPT_COALESCING_TIMEOUT));
6191
6192 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
6193 if (mpt_config(ioc, &cfg) == 0) {
6194 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6195 "Reset NVRAM Coalescing Timeout to = %d\n",
6196 ioc->name, MPT_COALESCING_TIMEOUT));
6197 } else {
6198 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6199 "Reset NVRAM Coalescing Timeout Failed\n",
6200 ioc->name));
6201 }
6202
6203 } else {
6204 dprintk(ioc, printk(MYIOC_s_WARN_FMT
6205 "Reset of Current Coalescing Timeout Failed!\n",
6206 ioc->name));
6207 }
6208 }
6209
6210 } else {
6211 dprintk(ioc, printk(MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
6212 }
6213 }
6214
6215 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
6216
6217 return;
6218}
6219
6220static void
6221mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
6222{
6223 CONFIGPARMS cfg;
6224 ConfigPageHeader_t hdr;
6225 dma_addr_t buf_dma;
6226 ManufacturingPage0_t *pbuf = NULL;
6227
6228 memset(&cfg, 0 , sizeof(CONFIGPARMS));
6229 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
6230
6231 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
6232 cfg.cfghdr.hdr = &hdr;
6233 cfg.physAddr = -1;
6234 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
6235 cfg.timeout = 10;
6236
6237 if (mpt_config(ioc, &cfg) != 0)
6238 goto out;
6239
6240 if (!cfg.cfghdr.hdr->PageLength)
6241 goto out;
6242
6243 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
6244 pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
6245 if (!pbuf)
6246 goto out;
6247
6248 cfg.physAddr = buf_dma;
6249
6250 if (mpt_config(ioc, &cfg) != 0)
6251 goto out;
6252
6253 memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name));
6254 memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
6255 memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
6256
6257out:
6258
6259 if (pbuf)
6260 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
6261}
6262
6263/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6264/**
6265 * SendEventNotification - Send EventNotification (on or off) request to adapter
6266 * @ioc: Pointer to MPT_ADAPTER structure
6267 * @EvSwitch: Event switch flags
6268 * @sleepFlag: Specifies whether the process can sleep
6269 */
6270static int
6271SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch, int sleepFlag)
6272{
6273 EventNotification_t evn;
6274 MPIDefaultReply_t reply_buf;
6275
6276 memset(&evn, 0, sizeof(EventNotification_t));
6277 memset(&reply_buf, 0, sizeof(MPIDefaultReply_t));
6278
6279 evn.Function = MPI_FUNCTION_EVENT_NOTIFICATION;
6280 evn.Switch = EvSwitch;
6281 evn.MsgContext = cpu_to_le32(mpt_base_index << 16);
6282
6283 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6284 "Sending EventNotification (%d) request %p\n",
6285 ioc->name, EvSwitch, &evn));
6286
6287 return mpt_handshake_req_reply_wait(ioc, sizeof(EventNotification_t),
6288 (u32 *)&evn, sizeof(MPIDefaultReply_t), (u16 *)&reply_buf, 30,
6289 sleepFlag);
6290}
6291
6292/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6293/**
6294 * SendEventAck - Send EventAck request to MPT adapter.
6295 * @ioc: Pointer to MPT_ADAPTER structure
6296 * @evnp: Pointer to original EventNotification request
6297 */
6298static int
6299SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
6300{
6301 EventAck_t *pAck;
6302
6303 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
6304 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
6305 ioc->name, __func__));
6306 return -1;
6307 }
6308
6309 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventAck\n", ioc->name));
6310
6311 pAck->Function = MPI_FUNCTION_EVENT_ACK;
6312 pAck->ChainOffset = 0;
6313 pAck->Reserved[0] = pAck->Reserved[1] = 0;
6314 pAck->MsgFlags = 0;
6315 pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
6316 pAck->Event = evnp->Event;
6317 pAck->EventContext = evnp->EventContext;
6318
6319 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
6320
6321 return 0;
6322}
6323
6324/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6325/**
6326 * mpt_config - Generic function to issue config message
6327 * @ioc: Pointer to an adapter structure
6328 * @pCfg: Pointer to a configuration structure. Struct contains
6329 * action, page address, direction, physical address
6330 * and pointer to a configuration page header
6331 * Page header is updated.
6332 *
6333 * Returns 0 for success
6334 * -EAGAIN if no msg frames currently available
6335 * -EFAULT for non-successful reply or no reply (timeout)
6336 */
6337int
6338mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
6339{
6340 Config_t *pReq;
6341 ConfigReply_t *pReply;
6342 ConfigExtendedPageHeader_t *pExtHdr = NULL;
6343 MPT_FRAME_HDR *mf;
6344 int ii;
6345 int flagsLength;
6346 long timeout;
6347 int ret;
6348 u8 page_type = 0, extend_page;
6349 unsigned long timeleft;
6350 unsigned long flags;
6351 u8 issue_hard_reset = 0;
6352 u8 retry_count = 0;
6353
6354 might_sleep();
6355
6356 /* don't send a config page during diag reset */
6357 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6358 if (ioc->ioc_reset_in_progress) {
6359 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6360 "%s: busy with host reset\n", ioc->name, __func__));
6361 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6362 return -EBUSY;
6363 }
6364 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6365
6366 /* don't send if no chance of success */
6367 if (!ioc->active ||
6368 mpt_GetIocState(ioc, 1) != MPI_IOC_STATE_OPERATIONAL) {
6369 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6370 "%s: ioc not operational, %d, %xh\n",
6371 ioc->name, __func__, ioc->active,
6372 mpt_GetIocState(ioc, 0)));
6373 return -EFAULT;
6374 }
6375
6376 retry_config:
6377 mutex_lock(&ioc->mptbase_cmds.mutex);
6378 /* init the internal cmd struct */
6379 memset(ioc->mptbase_cmds.reply, 0 , MPT_DEFAULT_FRAME_SIZE);
6380 INITIALIZE_MGMT_STATUS(ioc->mptbase_cmds.status)
6381
6382 /* Get and Populate a free Frame
6383 */
6384 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
6385 dcprintk(ioc, printk(MYIOC_s_WARN_FMT
6386 "mpt_config: no msg frames!\n", ioc->name));
6387 ret = -EAGAIN;
6388 goto out;
6389 }
6390
6391 pReq = (Config_t *)mf;
6392 pReq->Action = pCfg->action;
6393 pReq->Reserved = 0;
6394 pReq->ChainOffset = 0;
6395 pReq->Function = MPI_FUNCTION_CONFIG;
6396
6397 /* Assume page type is not extended and clear "reserved" fields. */
6398 pReq->ExtPageLength = 0;
6399 pReq->ExtPageType = 0;
6400 pReq->MsgFlags = 0;
6401
6402 for (ii=0; ii < 8; ii++)
6403 pReq->Reserved2[ii] = 0;
6404
6405 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
6406 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
6407 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
6408 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
6409
6410 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
6411 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
6412 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
6413 pReq->ExtPageType = pExtHdr->ExtPageType;
6414 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
6415
6416 /* Page Length must be treated as a reserved field for the
6417 * extended header.
6418 */
6419 pReq->Header.PageLength = 0;
6420 }
6421
6422 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
6423
6424 /* Add a SGE to the config request.
6425 */
6426 if (pCfg->dir)
6427 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
6428 else
6429 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
6430
6431 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) ==
6432 MPI_CONFIG_PAGETYPE_EXTENDED) {
6433 flagsLength |= pExtHdr->ExtPageLength * 4;
6434 page_type = pReq->ExtPageType;
6435 extend_page = 1;
6436 } else {
6437 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
6438 page_type = pReq->Header.PageType;
6439 extend_page = 0;
6440 }
6441
6442 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6443 "Sending Config request type 0x%x, page 0x%x and action %d\n",
6444 ioc->name, page_type, pReq->Header.PageNumber, pReq->Action));
6445
6446 ioc->add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
6447 timeout = (pCfg->timeout < 15) ? HZ*15 : HZ*pCfg->timeout;
6448 mpt_put_msg_frame(mpt_base_index, ioc, mf);
6449 timeleft = wait_for_completion_timeout(&ioc->mptbase_cmds.done,
6450 timeout);
6451 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
6452 ret = -ETIME;
6453 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6454 "Failed Sending Config request type 0x%x, page 0x%x,"
6455 " action %d, status %xh, time left %ld\n\n",
6456 ioc->name, page_type, pReq->Header.PageNumber,
6457 pReq->Action, ioc->mptbase_cmds.status, timeleft));
6458 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET)
6459 goto out;
6460 if (!timeleft) {
6461 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6462 if (ioc->ioc_reset_in_progress) {
6463 spin_unlock_irqrestore(&ioc->taskmgmt_lock,
6464 flags);
6465 printk(MYIOC_s_INFO_FMT "%s: host reset in"
6466 " progress mpt_config timed out.!!\n",
6467 __func__, ioc->name);
6468 mutex_unlock(&ioc->mptbase_cmds.mutex);
6469 return -EFAULT;
6470 }
6471 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6472 issue_hard_reset = 1;
6473 }
6474 goto out;
6475 }
6476
6477 if (!(ioc->mptbase_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
6478 ret = -1;
6479 goto out;
6480 }
6481 pReply = (ConfigReply_t *)ioc->mptbase_cmds.reply;
6482 ret = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
6483 if (ret == MPI_IOCSTATUS_SUCCESS) {
6484 if (extend_page) {
6485 pCfg->cfghdr.ehdr->ExtPageLength =
6486 le16_to_cpu(pReply->ExtPageLength);
6487 pCfg->cfghdr.ehdr->ExtPageType =
6488 pReply->ExtPageType;
6489 }
6490 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
6491 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
6492 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
6493 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
6494
6495 }
6496
6497 if (retry_count)
6498 printk(MYIOC_s_INFO_FMT "Retry completed "
6499 "ret=0x%x timeleft=%ld\n",
6500 ioc->name, ret, timeleft);
6501
6502 dcprintk(ioc, printk(KERN_DEBUG "IOCStatus=%04xh, IOCLogInfo=%08xh\n",
6503 ret, le32_to_cpu(pReply->IOCLogInfo)));
6504
6505out:
6506
6507 CLEAR_MGMT_STATUS(ioc->mptbase_cmds.status)
6508 mutex_unlock(&ioc->mptbase_cmds.mutex);
6509 if (issue_hard_reset) {
6510 issue_hard_reset = 0;
6511 printk(MYIOC_s_WARN_FMT
6512 "Issuing Reset from %s!!, doorbell=0x%08x\n",
6513 ioc->name, __func__, mpt_GetIocState(ioc, 0));
6514 if (retry_count == 0) {
6515 if (mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP) != 0)
6516 retry_count++;
6517 } else
6518 mpt_HardResetHandler(ioc, CAN_SLEEP);
6519
6520 mpt_free_msg_frame(ioc, mf);
6521 /* attempt one retry for a timed out command */
6522 if (retry_count < 2) {
6523 printk(MYIOC_s_INFO_FMT
6524 "Attempting Retry Config request"
6525 " type 0x%x, page 0x%x,"
6526 " action %d\n", ioc->name, page_type,
6527 pCfg->cfghdr.hdr->PageNumber, pCfg->action);
6528 retry_count++;
6529 goto retry_config;
6530 }
6531 }
6532 return ret;
6533
6534}
6535
6536/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6537/**
6538 * mpt_ioc_reset - Base cleanup for hard reset
6539 * @ioc: Pointer to the adapter structure
6540 * @reset_phase: Indicates pre- or post-reset functionality
6541 *
6542 * Remark: Frees resources with internally generated commands.
6543 */
6544static int
6545mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
6546{
6547 switch (reset_phase) {
6548 case MPT_IOC_SETUP_RESET:
6549 ioc->taskmgmt_quiesce_io = 1;
6550 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6551 "%s: MPT_IOC_SETUP_RESET\n", ioc->name, __func__));
6552 break;
6553 case MPT_IOC_PRE_RESET:
6554 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6555 "%s: MPT_IOC_PRE_RESET\n", ioc->name, __func__));
6556 break;
6557 case MPT_IOC_POST_RESET:
6558 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6559 "%s: MPT_IOC_POST_RESET\n", ioc->name, __func__));
6560/* wake up mptbase_cmds */
6561 if (ioc->mptbase_cmds.status & MPT_MGMT_STATUS_PENDING) {
6562 ioc->mptbase_cmds.status |=
6563 MPT_MGMT_STATUS_DID_IOCRESET;
6564 complete(&ioc->mptbase_cmds.done);
6565 }
6566/* wake up taskmgmt_cmds */
6567 if (ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_PENDING) {
6568 ioc->taskmgmt_cmds.status |=
6569 MPT_MGMT_STATUS_DID_IOCRESET;
6570 complete(&ioc->taskmgmt_cmds.done);
6571 }
6572 break;
6573 default:
6574 break;
6575 }
6576
6577 return 1; /* currently means nothing really */
6578}
6579
6580
6581#ifdef CONFIG_PROC_FS /* { */
6582/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6583/*
6584 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
6585 */
6586/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6587/**
6588 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
6589 *
6590 * Returns 0 for success, non-zero for failure.
6591 */
6592static int
6593procmpt_create(void)
6594{
6595 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
6596 if (mpt_proc_root_dir == NULL)
6597 return -ENOTDIR;
6598
6599 proc_create_single("summary", S_IRUGO, mpt_proc_root_dir,
6600 mpt_summary_proc_show);
6601 proc_create_single("version", S_IRUGO, mpt_proc_root_dir,
6602 mpt_version_proc_show);
6603 return 0;
6604}
6605
6606/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6607/**
6608 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
6609 *
6610 * Returns 0 for success, non-zero for failure.
6611 */
6612static void
6613procmpt_destroy(void)
6614{
6615 remove_proc_entry("version", mpt_proc_root_dir);
6616 remove_proc_entry("summary", mpt_proc_root_dir);
6617 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
6618}
6619
6620/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6621/*
6622 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
6623 */
6624static void seq_mpt_print_ioc_summary(MPT_ADAPTER *ioc, struct seq_file *m, int showlan);
6625
6626static int mpt_summary_proc_show(struct seq_file *m, void *v)
6627{
6628 MPT_ADAPTER *ioc = m->private;
6629
6630 if (ioc) {
6631 seq_mpt_print_ioc_summary(ioc, m, 1);
6632 } else {
6633 list_for_each_entry(ioc, &ioc_list, list) {
6634 seq_mpt_print_ioc_summary(ioc, m, 1);
6635 }
6636 }
6637
6638 return 0;
6639}
6640
6641static int mpt_version_proc_show(struct seq_file *m, void *v)
6642{
6643 u8 cb_idx;
6644 int scsi, fc, sas, lan, ctl, targ, dmp;
6645 char *drvname;
6646
6647 seq_printf(m, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
6648 seq_printf(m, " Fusion MPT base driver\n");
6649
6650 scsi = fc = sas = lan = ctl = targ = dmp = 0;
6651 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6652 drvname = NULL;
6653 if (MptCallbacks[cb_idx]) {
6654 switch (MptDriverClass[cb_idx]) {
6655 case MPTSPI_DRIVER:
6656 if (!scsi++) drvname = "SPI host";
6657 break;
6658 case MPTFC_DRIVER:
6659 if (!fc++) drvname = "FC host";
6660 break;
6661 case MPTSAS_DRIVER:
6662 if (!sas++) drvname = "SAS host";
6663 break;
6664 case MPTLAN_DRIVER:
6665 if (!lan++) drvname = "LAN";
6666 break;
6667 case MPTSTM_DRIVER:
6668 if (!targ++) drvname = "SCSI target";
6669 break;
6670 case MPTCTL_DRIVER:
6671 if (!ctl++) drvname = "ioctl";
6672 break;
6673 }
6674
6675 if (drvname)
6676 seq_printf(m, " Fusion MPT %s driver\n", drvname);
6677 }
6678 }
6679
6680 return 0;
6681}
6682
6683static int mpt_iocinfo_proc_show(struct seq_file *m, void *v)
6684{
6685 MPT_ADAPTER *ioc = m->private;
6686 char expVer[32];
6687 int sz;
6688 int p;
6689
6690 mpt_get_fw_exp_ver(expVer, ioc);
6691
6692 seq_printf(m, "%s:", ioc->name);
6693 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
6694 seq_printf(m, " (f/w download boot flag set)");
6695// if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6696// seq_printf(m, " CONFIG_CHECKSUM_FAIL!");
6697
6698 seq_printf(m, "\n ProductID = 0x%04x (%s)\n",
6699 ioc->facts.ProductID,
6700 ioc->prod_name);
6701 seq_printf(m, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
6702 if (ioc->facts.FWImageSize)
6703 seq_printf(m, " (fw_size=%d)", ioc->facts.FWImageSize);
6704 seq_printf(m, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
6705 seq_printf(m, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
6706 seq_printf(m, " EventState = 0x%02x\n", ioc->facts.EventState);
6707
6708 seq_printf(m, " CurrentHostMfaHighAddr = 0x%08x\n",
6709 ioc->facts.CurrentHostMfaHighAddr);
6710 seq_printf(m, " CurrentSenseBufferHighAddr = 0x%08x\n",
6711 ioc->facts.CurrentSenseBufferHighAddr);
6712
6713 seq_printf(m, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
6714 seq_printf(m, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
6715
6716 seq_printf(m, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6717 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
6718 /*
6719 * Rounding UP to nearest 4-kB boundary here...
6720 */
6721 sz = (ioc->req_sz * ioc->req_depth) + 128;
6722 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
6723 seq_printf(m, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6724 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
6725 seq_printf(m, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
6726 4*ioc->facts.RequestFrameSize,
6727 ioc->facts.GlobalCredits);
6728
6729 seq_printf(m, " Frames @ 0x%p (Dma @ 0x%p)\n",
6730 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
6731 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
6732 seq_printf(m, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6733 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
6734 seq_printf(m, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
6735 ioc->facts.CurReplyFrameSize,
6736 ioc->facts.ReplyQueueDepth);
6737
6738 seq_printf(m, " MaxDevices = %d\n",
6739 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
6740 seq_printf(m, " MaxBuses = %d\n", ioc->facts.MaxBuses);
6741
6742 /* per-port info */
6743 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
6744 seq_printf(m, " PortNumber = %d (of %d)\n",
6745 p+1,
6746 ioc->facts.NumberOfPorts);
6747 if (ioc->bus_type == FC) {
6748 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
6749 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6750 seq_printf(m, " LanAddr = %pMR\n", a);
6751 }
6752 seq_printf(m, " WWN = %08X%08X:%08X%08X\n",
6753 ioc->fc_port_page0[p].WWNN.High,
6754 ioc->fc_port_page0[p].WWNN.Low,
6755 ioc->fc_port_page0[p].WWPN.High,
6756 ioc->fc_port_page0[p].WWPN.Low);
6757 }
6758 }
6759
6760 return 0;
6761}
6762#endif /* CONFIG_PROC_FS } */
6763
6764/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6765static void
6766mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
6767{
6768 buf[0] ='\0';
6769 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
6770 sprintf(buf, " (Exp %02d%02d)",
6771 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
6772 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
6773
6774 /* insider hack! */
6775 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
6776 strcat(buf, " [MDBG]");
6777 }
6778}
6779
6780/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6781/**
6782 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6783 * @ioc: Pointer to MPT_ADAPTER structure
6784 * @buffer: Pointer to buffer where IOC summary info should be written
6785 * @size: Pointer to number of bytes we wrote (set by this routine)
6786 * @len: Offset at which to start writing in buffer
6787 * @showlan: Display LAN stuff?
6788 *
6789 * This routine writes (english readable) ASCII text, which represents
6790 * a summary of IOC information, to a buffer.
6791 */
6792void
6793mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
6794{
6795 char expVer[32];
6796 int y;
6797
6798 mpt_get_fw_exp_ver(expVer, ioc);
6799
6800 /*
6801 * Shorter summary of attached ioc's...
6802 */
6803 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6804 ioc->name,
6805 ioc->prod_name,
6806 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
6807 ioc->facts.FWVersion.Word,
6808 expVer,
6809 ioc->facts.NumberOfPorts,
6810 ioc->req_depth);
6811
6812 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6813 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6814 y += sprintf(buffer+len+y, ", LanAddr=%pMR", a);
6815 }
6816
6817 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
6818
6819 if (!ioc->active)
6820 y += sprintf(buffer+len+y, " (disabled)");
6821
6822 y += sprintf(buffer+len+y, "\n");
6823
6824 *size = y;
6825}
6826
6827#ifdef CONFIG_PROC_FS
6828static void seq_mpt_print_ioc_summary(MPT_ADAPTER *ioc, struct seq_file *m, int showlan)
6829{
6830 char expVer[32];
6831
6832 mpt_get_fw_exp_ver(expVer, ioc);
6833
6834 /*
6835 * Shorter summary of attached ioc's...
6836 */
6837 seq_printf(m, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6838 ioc->name,
6839 ioc->prod_name,
6840 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
6841 ioc->facts.FWVersion.Word,
6842 expVer,
6843 ioc->facts.NumberOfPorts,
6844 ioc->req_depth);
6845
6846 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6847 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6848 seq_printf(m, ", LanAddr=%pMR", a);
6849 }
6850
6851 seq_printf(m, ", IRQ=%d", ioc->pci_irq);
6852
6853 if (!ioc->active)
6854 seq_printf(m, " (disabled)");
6855
6856 seq_putc(m, '\n');
6857}
6858#endif
6859
6860/**
6861 * mpt_set_taskmgmt_in_progress_flag - set flags associated with task management
6862 * @ioc: Pointer to MPT_ADAPTER structure
6863 *
6864 * Returns 0 for SUCCESS or -1 if FAILED.
6865 *
6866 * If -1 is return, then it was not possible to set the flags
6867 **/
6868int
6869mpt_set_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc)
6870{
6871 unsigned long flags;
6872 int retval;
6873
6874 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6875 if (ioc->ioc_reset_in_progress || ioc->taskmgmt_in_progress ||
6876 (ioc->alt_ioc && ioc->alt_ioc->taskmgmt_in_progress)) {
6877 retval = -1;
6878 goto out;
6879 }
6880 retval = 0;
6881 ioc->taskmgmt_in_progress = 1;
6882 ioc->taskmgmt_quiesce_io = 1;
6883 if (ioc->alt_ioc) {
6884 ioc->alt_ioc->taskmgmt_in_progress = 1;
6885 ioc->alt_ioc->taskmgmt_quiesce_io = 1;
6886 }
6887 out:
6888 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6889 return retval;
6890}
6891EXPORT_SYMBOL(mpt_set_taskmgmt_in_progress_flag);
6892
6893/**
6894 * mpt_clear_taskmgmt_in_progress_flag - clear flags associated with task management
6895 * @ioc: Pointer to MPT_ADAPTER structure
6896 *
6897 **/
6898void
6899mpt_clear_taskmgmt_in_progress_flag(MPT_ADAPTER *ioc)
6900{
6901 unsigned long flags;
6902
6903 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6904 ioc->taskmgmt_in_progress = 0;
6905 ioc->taskmgmt_quiesce_io = 0;
6906 if (ioc->alt_ioc) {
6907 ioc->alt_ioc->taskmgmt_in_progress = 0;
6908 ioc->alt_ioc->taskmgmt_quiesce_io = 0;
6909 }
6910 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6911}
6912EXPORT_SYMBOL(mpt_clear_taskmgmt_in_progress_flag);
6913
6914
6915/**
6916 * mpt_halt_firmware - Halts the firmware if it is operational and panic
6917 * the kernel
6918 * @ioc: Pointer to MPT_ADAPTER structure
6919 *
6920 **/
6921void
6922mpt_halt_firmware(MPT_ADAPTER *ioc)
6923{
6924 u32 ioc_raw_state;
6925
6926 ioc_raw_state = mpt_GetIocState(ioc, 0);
6927
6928 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
6929 printk(MYIOC_s_ERR_FMT "IOC is in FAULT state (%04xh)!!!\n",
6930 ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
6931 panic("%s: IOC Fault (%04xh)!!!\n", ioc->name,
6932 ioc_raw_state & MPI_DOORBELL_DATA_MASK);
6933 } else {
6934 CHIPREG_WRITE32(&ioc->chip->Doorbell, 0xC0FFEE00);
6935 panic("%s: Firmware is halted due to command timeout\n",
6936 ioc->name);
6937 }
6938}
6939EXPORT_SYMBOL(mpt_halt_firmware);
6940
6941/**
6942 * mpt_SoftResetHandler - Issues a less expensive reset
6943 * @ioc: Pointer to MPT_ADAPTER structure
6944 * @sleepFlag: Indicates if sleep or schedule must be called.
6945 *
6946 * Returns 0 for SUCCESS or -1 if FAILED.
6947 *
6948 * Message Unit Reset - instructs the IOC to reset the Reply Post and
6949 * Free FIFO's. All the Message Frames on Reply Free FIFO are discarded.
6950 * All posted buffers are freed, and event notification is turned off.
6951 * IOC doesn't reply to any outstanding request. This will transfer IOC
6952 * to READY state.
6953 **/
6954static int
6955mpt_SoftResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6956{
6957 int rc;
6958 int ii;
6959 u8 cb_idx;
6960 unsigned long flags;
6961 u32 ioc_state;
6962 unsigned long time_count;
6963
6964 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SoftResetHandler Entered!\n",
6965 ioc->name));
6966
6967 ioc_state = mpt_GetIocState(ioc, 0) & MPI_IOC_STATE_MASK;
6968
6969 if (mpt_fwfault_debug)
6970 mpt_halt_firmware(ioc);
6971
6972 if (ioc_state == MPI_IOC_STATE_FAULT ||
6973 ioc_state == MPI_IOC_STATE_RESET) {
6974 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6975 "skipping, either in FAULT or RESET state!\n", ioc->name));
6976 return -1;
6977 }
6978
6979 if (ioc->bus_type == FC) {
6980 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6981 "skipping, because the bus type is FC!\n", ioc->name));
6982 return -1;
6983 }
6984
6985 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6986 if (ioc->ioc_reset_in_progress) {
6987 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6988 return -1;
6989 }
6990 ioc->ioc_reset_in_progress = 1;
6991 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
6992
6993 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6994 if (MptResetHandlers[cb_idx])
6995 mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
6996 }
6997
6998 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
6999 if (ioc->taskmgmt_in_progress) {
7000 ioc->ioc_reset_in_progress = 0;
7001 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7002 return -1;
7003 }
7004 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7005 /* Disable reply interrupts (also blocks FreeQ) */
7006 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
7007 ioc->active = 0;
7008 time_count = jiffies;
7009
7010 rc = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
7011
7012 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7013 if (MptResetHandlers[cb_idx])
7014 mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET);
7015 }
7016
7017 if (rc)
7018 goto out;
7019
7020 ioc_state = mpt_GetIocState(ioc, 0) & MPI_IOC_STATE_MASK;
7021 if (ioc_state != MPI_IOC_STATE_READY)
7022 goto out;
7023
7024 for (ii = 0; ii < 5; ii++) {
7025 /* Get IOC facts! Allow 5 retries */
7026 rc = GetIocFacts(ioc, sleepFlag,
7027 MPT_HOSTEVENT_IOC_RECOVER);
7028 if (rc == 0)
7029 break;
7030 if (sleepFlag == CAN_SLEEP)
7031 msleep(100);
7032 else
7033 mdelay(100);
7034 }
7035 if (ii == 5)
7036 goto out;
7037
7038 rc = PrimeIocFifos(ioc);
7039 if (rc != 0)
7040 goto out;
7041
7042 rc = SendIocInit(ioc, sleepFlag);
7043 if (rc != 0)
7044 goto out;
7045
7046 rc = SendEventNotification(ioc, 1, sleepFlag);
7047 if (rc != 0)
7048 goto out;
7049
7050 if (ioc->hard_resets < -1)
7051 ioc->hard_resets++;
7052
7053 /*
7054 * At this point, we know soft reset succeeded.
7055 */
7056
7057 ioc->active = 1;
7058 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
7059
7060 out:
7061 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7062 ioc->ioc_reset_in_progress = 0;
7063 ioc->taskmgmt_quiesce_io = 0;
7064 ioc->taskmgmt_in_progress = 0;
7065 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7066
7067 if (ioc->active) { /* otherwise, hard reset coming */
7068 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7069 if (MptResetHandlers[cb_idx])
7070 mpt_signal_reset(cb_idx, ioc,
7071 MPT_IOC_POST_RESET);
7072 }
7073 }
7074
7075 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7076 "SoftResetHandler: completed (%d seconds): %s\n",
7077 ioc->name, jiffies_to_msecs(jiffies - time_count)/1000,
7078 ((rc == 0) ? "SUCCESS" : "FAILED")));
7079
7080 return rc;
7081}
7082
7083/**
7084 * mpt_Soft_Hard_ResetHandler - Try less expensive reset
7085 * @ioc: Pointer to MPT_ADAPTER structure
7086 * @sleepFlag: Indicates if sleep or schedule must be called.
7087 *
7088 * Returns 0 for SUCCESS or -1 if FAILED.
7089 * Try for softreset first, only if it fails go for expensive
7090 * HardReset.
7091 **/
7092int
7093mpt_Soft_Hard_ResetHandler(MPT_ADAPTER *ioc, int sleepFlag) {
7094 int ret = -1;
7095
7096 ret = mpt_SoftResetHandler(ioc, sleepFlag);
7097 if (ret == 0)
7098 return ret;
7099 ret = mpt_HardResetHandler(ioc, sleepFlag);
7100 return ret;
7101}
7102EXPORT_SYMBOL(mpt_Soft_Hard_ResetHandler);
7103
7104/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7105/*
7106 * Reset Handling
7107 */
7108/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7109/**
7110 * mpt_HardResetHandler - Generic reset handler
7111 * @ioc: Pointer to MPT_ADAPTER structure
7112 * @sleepFlag: Indicates if sleep or schedule must be called.
7113 *
7114 * Issues SCSI Task Management call based on input arg values.
7115 * If TaskMgmt fails, returns associated SCSI request.
7116 *
7117 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
7118 * or a non-interrupt thread. In the former, must not call schedule().
7119 *
7120 * Note: A return of -1 is a FATAL error case, as it means a
7121 * FW reload/initialization failed.
7122 *
7123 * Returns 0 for SUCCESS or -1 if FAILED.
7124 */
7125int
7126mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
7127{
7128 int rc;
7129 u8 cb_idx;
7130 unsigned long flags;
7131 unsigned long time_count;
7132
7133 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name));
7134#ifdef MFCNT
7135 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
7136 printk("MF count 0x%x !\n", ioc->mfcnt);
7137#endif
7138 if (mpt_fwfault_debug)
7139 mpt_halt_firmware(ioc);
7140
7141 /* Reset the adapter. Prevent more than 1 call to
7142 * mpt_do_ioc_recovery at any instant in time.
7143 */
7144 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7145 if (ioc->ioc_reset_in_progress) {
7146 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7147 ioc->wait_on_reset_completion = 1;
7148 do {
7149 ssleep(1);
7150 } while (ioc->ioc_reset_in_progress == 1);
7151 ioc->wait_on_reset_completion = 0;
7152 return ioc->reset_status;
7153 }
7154 if (ioc->wait_on_reset_completion) {
7155 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7156 rc = 0;
7157 time_count = jiffies;
7158 goto exit;
7159 }
7160 ioc->ioc_reset_in_progress = 1;
7161 if (ioc->alt_ioc)
7162 ioc->alt_ioc->ioc_reset_in_progress = 1;
7163 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7164
7165
7166 /* The SCSI driver needs to adjust timeouts on all current
7167 * commands prior to the diagnostic reset being issued.
7168 * Prevents timeouts occurring during a diagnostic reset...very bad.
7169 * For all other protocol drivers, this is a no-op.
7170 */
7171 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7172 if (MptResetHandlers[cb_idx]) {
7173 mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
7174 if (ioc->alt_ioc)
7175 mpt_signal_reset(cb_idx, ioc->alt_ioc,
7176 MPT_IOC_SETUP_RESET);
7177 }
7178 }
7179
7180 time_count = jiffies;
7181 rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag);
7182 if (rc != 0) {
7183 printk(KERN_WARNING MYNAM
7184 ": WARNING - (%d) Cannot recover %s, doorbell=0x%08x\n",
7185 rc, ioc->name, mpt_GetIocState(ioc, 0));
7186 } else {
7187 if (ioc->hard_resets < -1)
7188 ioc->hard_resets++;
7189 }
7190
7191 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
7192 ioc->ioc_reset_in_progress = 0;
7193 ioc->taskmgmt_quiesce_io = 0;
7194 ioc->taskmgmt_in_progress = 0;
7195 ioc->reset_status = rc;
7196 if (ioc->alt_ioc) {
7197 ioc->alt_ioc->ioc_reset_in_progress = 0;
7198 ioc->alt_ioc->taskmgmt_quiesce_io = 0;
7199 ioc->alt_ioc->taskmgmt_in_progress = 0;
7200 }
7201 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
7202
7203 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7204 if (MptResetHandlers[cb_idx]) {
7205 mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET);
7206 if (ioc->alt_ioc)
7207 mpt_signal_reset(cb_idx,
7208 ioc->alt_ioc, MPT_IOC_POST_RESET);
7209 }
7210 }
7211exit:
7212 dtmprintk(ioc,
7213 printk(MYIOC_s_DEBUG_FMT
7214 "HardResetHandler: completed (%d seconds): %s\n", ioc->name,
7215 jiffies_to_msecs(jiffies - time_count)/1000, ((rc == 0) ?
7216 "SUCCESS" : "FAILED")));
7217
7218 return rc;
7219}
7220
7221#ifdef CONFIG_FUSION_LOGGING
7222static void
7223mpt_display_event_info(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply)
7224{
7225 char *ds = NULL;
7226 u32 evData0;
7227 int ii;
7228 u8 event;
7229 char *evStr = ioc->evStr;
7230
7231 event = le32_to_cpu(pEventReply->Event) & 0xFF;
7232 evData0 = le32_to_cpu(pEventReply->Data[0]);
7233
7234 switch(event) {
7235 case MPI_EVENT_NONE:
7236 ds = "None";
7237 break;
7238 case MPI_EVENT_LOG_DATA:
7239 ds = "Log Data";
7240 break;
7241 case MPI_EVENT_STATE_CHANGE:
7242 ds = "State Change";
7243 break;
7244 case MPI_EVENT_UNIT_ATTENTION:
7245 ds = "Unit Attention";
7246 break;
7247 case MPI_EVENT_IOC_BUS_RESET:
7248 ds = "IOC Bus Reset";
7249 break;
7250 case MPI_EVENT_EXT_BUS_RESET:
7251 ds = "External Bus Reset";
7252 break;
7253 case MPI_EVENT_RESCAN:
7254 ds = "Bus Rescan Event";
7255 break;
7256 case MPI_EVENT_LINK_STATUS_CHANGE:
7257 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
7258 ds = "Link Status(FAILURE) Change";
7259 else
7260 ds = "Link Status(ACTIVE) Change";
7261 break;
7262 case MPI_EVENT_LOOP_STATE_CHANGE:
7263 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
7264 ds = "Loop State(LIP) Change";
7265 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
7266 ds = "Loop State(LPE) Change";
7267 else
7268 ds = "Loop State(LPB) Change";
7269 break;
7270 case MPI_EVENT_LOGOUT:
7271 ds = "Logout";
7272 break;
7273 case MPI_EVENT_EVENT_CHANGE:
7274 if (evData0)
7275 ds = "Events ON";
7276 else
7277 ds = "Events OFF";
7278 break;
7279 case MPI_EVENT_INTEGRATED_RAID:
7280 {
7281 u8 ReasonCode = (u8)(evData0 >> 16);
7282 switch (ReasonCode) {
7283 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
7284 ds = "Integrated Raid: Volume Created";
7285 break;
7286 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
7287 ds = "Integrated Raid: Volume Deleted";
7288 break;
7289 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
7290 ds = "Integrated Raid: Volume Settings Changed";
7291 break;
7292 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
7293 ds = "Integrated Raid: Volume Status Changed";
7294 break;
7295 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
7296 ds = "Integrated Raid: Volume Physdisk Changed";
7297 break;
7298 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
7299 ds = "Integrated Raid: Physdisk Created";
7300 break;
7301 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
7302 ds = "Integrated Raid: Physdisk Deleted";
7303 break;
7304 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
7305 ds = "Integrated Raid: Physdisk Settings Changed";
7306 break;
7307 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
7308 ds = "Integrated Raid: Physdisk Status Changed";
7309 break;
7310 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
7311 ds = "Integrated Raid: Domain Validation Needed";
7312 break;
7313 case MPI_EVENT_RAID_RC_SMART_DATA :
7314 ds = "Integrated Raid; Smart Data";
7315 break;
7316 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
7317 ds = "Integrated Raid: Replace Action Started";
7318 break;
7319 default:
7320 ds = "Integrated Raid";
7321 break;
7322 }
7323 break;
7324 }
7325 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
7326 ds = "SCSI Device Status Change";
7327 break;
7328 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
7329 {
7330 u8 id = (u8)(evData0);
7331 u8 channel = (u8)(evData0 >> 8);
7332 u8 ReasonCode = (u8)(evData0 >> 16);
7333 switch (ReasonCode) {
7334 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
7335 snprintf(evStr, EVENT_DESCR_STR_SZ,
7336 "SAS Device Status Change: Added: "
7337 "id=%d channel=%d", id, channel);
7338 break;
7339 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
7340 snprintf(evStr, EVENT_DESCR_STR_SZ,
7341 "SAS Device Status Change: Deleted: "
7342 "id=%d channel=%d", id, channel);
7343 break;
7344 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
7345 snprintf(evStr, EVENT_DESCR_STR_SZ,
7346 "SAS Device Status Change: SMART Data: "
7347 "id=%d channel=%d", id, channel);
7348 break;
7349 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
7350 snprintf(evStr, EVENT_DESCR_STR_SZ,
7351 "SAS Device Status Change: No Persistency: "
7352 "id=%d channel=%d", id, channel);
7353 break;
7354 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
7355 snprintf(evStr, EVENT_DESCR_STR_SZ,
7356 "SAS Device Status Change: Unsupported Device "
7357 "Discovered : id=%d channel=%d", id, channel);
7358 break;
7359 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
7360 snprintf(evStr, EVENT_DESCR_STR_SZ,
7361 "SAS Device Status Change: Internal Device "
7362 "Reset : id=%d channel=%d", id, channel);
7363 break;
7364 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
7365 snprintf(evStr, EVENT_DESCR_STR_SZ,
7366 "SAS Device Status Change: Internal Task "
7367 "Abort : id=%d channel=%d", id, channel);
7368 break;
7369 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
7370 snprintf(evStr, EVENT_DESCR_STR_SZ,
7371 "SAS Device Status Change: Internal Abort "
7372 "Task Set : id=%d channel=%d", id, channel);
7373 break;
7374 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
7375 snprintf(evStr, EVENT_DESCR_STR_SZ,
7376 "SAS Device Status Change: Internal Clear "
7377 "Task Set : id=%d channel=%d", id, channel);
7378 break;
7379 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
7380 snprintf(evStr, EVENT_DESCR_STR_SZ,
7381 "SAS Device Status Change: Internal Query "
7382 "Task : id=%d channel=%d", id, channel);
7383 break;
7384 default:
7385 snprintf(evStr, EVENT_DESCR_STR_SZ,
7386 "SAS Device Status Change: Unknown: "
7387 "id=%d channel=%d", id, channel);
7388 break;
7389 }
7390 break;
7391 }
7392 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
7393 ds = "Bus Timer Expired";
7394 break;
7395 case MPI_EVENT_QUEUE_FULL:
7396 {
7397 u16 curr_depth = (u16)(evData0 >> 16);
7398 u8 channel = (u8)(evData0 >> 8);
7399 u8 id = (u8)(evData0);
7400
7401 snprintf(evStr, EVENT_DESCR_STR_SZ,
7402 "Queue Full: channel=%d id=%d depth=%d",
7403 channel, id, curr_depth);
7404 break;
7405 }
7406 case MPI_EVENT_SAS_SES:
7407 ds = "SAS SES Event";
7408 break;
7409 case MPI_EVENT_PERSISTENT_TABLE_FULL:
7410 ds = "Persistent Table Full";
7411 break;
7412 case MPI_EVENT_SAS_PHY_LINK_STATUS:
7413 {
7414 u8 LinkRates = (u8)(evData0 >> 8);
7415 u8 PhyNumber = (u8)(evData0);
7416 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
7417 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
7418 switch (LinkRates) {
7419 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
7420 snprintf(evStr, EVENT_DESCR_STR_SZ,
7421 "SAS PHY Link Status: Phy=%d:"
7422 " Rate Unknown",PhyNumber);
7423 break;
7424 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
7425 snprintf(evStr, EVENT_DESCR_STR_SZ,
7426 "SAS PHY Link Status: Phy=%d:"
7427 " Phy Disabled",PhyNumber);
7428 break;
7429 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
7430 snprintf(evStr, EVENT_DESCR_STR_SZ,
7431 "SAS PHY Link Status: Phy=%d:"
7432 " Failed Speed Nego",PhyNumber);
7433 break;
7434 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
7435 snprintf(evStr, EVENT_DESCR_STR_SZ,
7436 "SAS PHY Link Status: Phy=%d:"
7437 " Sata OOB Completed",PhyNumber);
7438 break;
7439 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
7440 snprintf(evStr, EVENT_DESCR_STR_SZ,
7441 "SAS PHY Link Status: Phy=%d:"
7442 " Rate 1.5 Gbps",PhyNumber);
7443 break;
7444 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
7445 snprintf(evStr, EVENT_DESCR_STR_SZ,
7446 "SAS PHY Link Status: Phy=%d:"
7447 " Rate 3.0 Gbps", PhyNumber);
7448 break;
7449 case MPI_EVENT_SAS_PLS_LR_RATE_6_0:
7450 snprintf(evStr, EVENT_DESCR_STR_SZ,
7451 "SAS PHY Link Status: Phy=%d:"
7452 " Rate 6.0 Gbps", PhyNumber);
7453 break;
7454 default:
7455 snprintf(evStr, EVENT_DESCR_STR_SZ,
7456 "SAS PHY Link Status: Phy=%d", PhyNumber);
7457 break;
7458 }
7459 break;
7460 }
7461 case MPI_EVENT_SAS_DISCOVERY_ERROR:
7462 ds = "SAS Discovery Error";
7463 break;
7464 case MPI_EVENT_IR_RESYNC_UPDATE:
7465 {
7466 u8 resync_complete = (u8)(evData0 >> 16);
7467 snprintf(evStr, EVENT_DESCR_STR_SZ,
7468 "IR Resync Update: Complete = %d:",resync_complete);
7469 break;
7470 }
7471 case MPI_EVENT_IR2:
7472 {
7473 u8 id = (u8)(evData0);
7474 u8 channel = (u8)(evData0 >> 8);
7475 u8 phys_num = (u8)(evData0 >> 24);
7476 u8 ReasonCode = (u8)(evData0 >> 16);
7477
7478 switch (ReasonCode) {
7479 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
7480 snprintf(evStr, EVENT_DESCR_STR_SZ,
7481 "IR2: LD State Changed: "
7482 "id=%d channel=%d phys_num=%d",
7483 id, channel, phys_num);
7484 break;
7485 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
7486 snprintf(evStr, EVENT_DESCR_STR_SZ,
7487 "IR2: PD State Changed "
7488 "id=%d channel=%d phys_num=%d",
7489 id, channel, phys_num);
7490 break;
7491 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
7492 snprintf(evStr, EVENT_DESCR_STR_SZ,
7493 "IR2: Bad Block Table Full: "
7494 "id=%d channel=%d phys_num=%d",
7495 id, channel, phys_num);
7496 break;
7497 case MPI_EVENT_IR2_RC_PD_INSERTED:
7498 snprintf(evStr, EVENT_DESCR_STR_SZ,
7499 "IR2: PD Inserted: "
7500 "id=%d channel=%d phys_num=%d",
7501 id, channel, phys_num);
7502 break;
7503 case MPI_EVENT_IR2_RC_PD_REMOVED:
7504 snprintf(evStr, EVENT_DESCR_STR_SZ,
7505 "IR2: PD Removed: "
7506 "id=%d channel=%d phys_num=%d",
7507 id, channel, phys_num);
7508 break;
7509 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
7510 snprintf(evStr, EVENT_DESCR_STR_SZ,
7511 "IR2: Foreign CFG Detected: "
7512 "id=%d channel=%d phys_num=%d",
7513 id, channel, phys_num);
7514 break;
7515 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
7516 snprintf(evStr, EVENT_DESCR_STR_SZ,
7517 "IR2: Rebuild Medium Error: "
7518 "id=%d channel=%d phys_num=%d",
7519 id, channel, phys_num);
7520 break;
7521 case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED:
7522 snprintf(evStr, EVENT_DESCR_STR_SZ,
7523 "IR2: Dual Port Added: "
7524 "id=%d channel=%d phys_num=%d",
7525 id, channel, phys_num);
7526 break;
7527 case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED:
7528 snprintf(evStr, EVENT_DESCR_STR_SZ,
7529 "IR2: Dual Port Removed: "
7530 "id=%d channel=%d phys_num=%d",
7531 id, channel, phys_num);
7532 break;
7533 default:
7534 ds = "IR2";
7535 break;
7536 }
7537 break;
7538 }
7539 case MPI_EVENT_SAS_DISCOVERY:
7540 {
7541 if (evData0)
7542 ds = "SAS Discovery: Start";
7543 else
7544 ds = "SAS Discovery: Stop";
7545 break;
7546 }
7547 case MPI_EVENT_LOG_ENTRY_ADDED:
7548 ds = "SAS Log Entry Added";
7549 break;
7550
7551 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
7552 {
7553 u8 phy_num = (u8)(evData0);
7554 u8 port_num = (u8)(evData0 >> 8);
7555 u8 port_width = (u8)(evData0 >> 16);
7556 u8 primitive = (u8)(evData0 >> 24);
7557 snprintf(evStr, EVENT_DESCR_STR_SZ,
7558 "SAS Broadcast Primitive: phy=%d port=%d "
7559 "width=%d primitive=0x%02x",
7560 phy_num, port_num, port_width, primitive);
7561 break;
7562 }
7563
7564 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
7565 {
7566 u8 reason = (u8)(evData0);
7567
7568 switch (reason) {
7569 case MPI_EVENT_SAS_INIT_RC_ADDED:
7570 ds = "SAS Initiator Status Change: Added";
7571 break;
7572 case MPI_EVENT_SAS_INIT_RC_REMOVED:
7573 ds = "SAS Initiator Status Change: Deleted";
7574 break;
7575 default:
7576 ds = "SAS Initiator Status Change";
7577 break;
7578 }
7579 break;
7580 }
7581
7582 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
7583 {
7584 u8 max_init = (u8)(evData0);
7585 u8 current_init = (u8)(evData0 >> 8);
7586
7587 snprintf(evStr, EVENT_DESCR_STR_SZ,
7588 "SAS Initiator Device Table Overflow: max initiators=%02d "
7589 "current initiators=%02d",
7590 max_init, current_init);
7591 break;
7592 }
7593 case MPI_EVENT_SAS_SMP_ERROR:
7594 {
7595 u8 status = (u8)(evData0);
7596 u8 port_num = (u8)(evData0 >> 8);
7597 u8 result = (u8)(evData0 >> 16);
7598
7599 if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
7600 snprintf(evStr, EVENT_DESCR_STR_SZ,
7601 "SAS SMP Error: port=%d result=0x%02x",
7602 port_num, result);
7603 else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
7604 snprintf(evStr, EVENT_DESCR_STR_SZ,
7605 "SAS SMP Error: port=%d : CRC Error",
7606 port_num);
7607 else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
7608 snprintf(evStr, EVENT_DESCR_STR_SZ,
7609 "SAS SMP Error: port=%d : Timeout",
7610 port_num);
7611 else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
7612 snprintf(evStr, EVENT_DESCR_STR_SZ,
7613 "SAS SMP Error: port=%d : No Destination",
7614 port_num);
7615 else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
7616 snprintf(evStr, EVENT_DESCR_STR_SZ,
7617 "SAS SMP Error: port=%d : Bad Destination",
7618 port_num);
7619 else
7620 snprintf(evStr, EVENT_DESCR_STR_SZ,
7621 "SAS SMP Error: port=%d : status=0x%02x",
7622 port_num, status);
7623 break;
7624 }
7625
7626 case MPI_EVENT_SAS_EXPANDER_STATUS_CHANGE:
7627 {
7628 u8 reason = (u8)(evData0);
7629
7630 switch (reason) {
7631 case MPI_EVENT_SAS_EXP_RC_ADDED:
7632 ds = "Expander Status Change: Added";
7633 break;
7634 case MPI_EVENT_SAS_EXP_RC_NOT_RESPONDING:
7635 ds = "Expander Status Change: Deleted";
7636 break;
7637 default:
7638 ds = "Expander Status Change";
7639 break;
7640 }
7641 break;
7642 }
7643
7644 /*
7645 * MPT base "custom" events may be added here...
7646 */
7647 default:
7648 ds = "Unknown";
7649 break;
7650 }
7651 if (ds)
7652 strlcpy(evStr, ds, EVENT_DESCR_STR_SZ);
7653
7654
7655 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7656 "MPT event:(%02Xh) : %s\n",
7657 ioc->name, event, evStr));
7658
7659 devtverboseprintk(ioc, printk(KERN_DEBUG MYNAM
7660 ": Event data:\n"));
7661 for (ii = 0; ii < le16_to_cpu(pEventReply->EventDataLength); ii++)
7662 devtverboseprintk(ioc, printk(" %08x",
7663 le32_to_cpu(pEventReply->Data[ii])));
7664 devtverboseprintk(ioc, printk(KERN_DEBUG "\n"));
7665}
7666#endif
7667/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7668/**
7669 * ProcessEventNotification - Route EventNotificationReply to all event handlers
7670 * @ioc: Pointer to MPT_ADAPTER structure
7671 * @pEventReply: Pointer to EventNotification reply frame
7672 * @evHandlers: Pointer to integer, number of event handlers
7673 *
7674 * Routes a received EventNotificationReply to all currently registered
7675 * event handlers.
7676 * Returns sum of event handlers return values.
7677 */
7678static int
7679ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
7680{
7681 u16 evDataLen;
7682 u32 evData0 = 0;
7683 int ii;
7684 u8 cb_idx;
7685 int r = 0;
7686 int handlers = 0;
7687 u8 event;
7688
7689 /*
7690 * Do platform normalization of values
7691 */
7692 event = le32_to_cpu(pEventReply->Event) & 0xFF;
7693 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
7694 if (evDataLen) {
7695 evData0 = le32_to_cpu(pEventReply->Data[0]);
7696 }
7697
7698#ifdef CONFIG_FUSION_LOGGING
7699 if (evDataLen)
7700 mpt_display_event_info(ioc, pEventReply);
7701#endif
7702
7703 /*
7704 * Do general / base driver event processing
7705 */
7706 switch(event) {
7707 case MPI_EVENT_EVENT_CHANGE: /* 0A */
7708 if (evDataLen) {
7709 u8 evState = evData0 & 0xFF;
7710
7711 /* CHECKME! What if evState unexpectedly says OFF (0)? */
7712
7713 /* Update EventState field in cached IocFacts */
7714 if (ioc->facts.Function) {
7715 ioc->facts.EventState = evState;
7716 }
7717 }
7718 break;
7719 case MPI_EVENT_INTEGRATED_RAID:
7720 mptbase_raid_process_event_data(ioc,
7721 (MpiEventDataRaid_t *)pEventReply->Data);
7722 break;
7723 default:
7724 break;
7725 }
7726
7727 /*
7728 * Should this event be logged? Events are written sequentially.
7729 * When buffer is full, start again at the top.
7730 */
7731 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
7732 int idx;
7733
7734 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
7735
7736 ioc->events[idx].event = event;
7737 ioc->events[idx].eventContext = ioc->eventContext;
7738
7739 for (ii = 0; ii < 2; ii++) {
7740 if (ii < evDataLen)
7741 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
7742 else
7743 ioc->events[idx].data[ii] = 0;
7744 }
7745
7746 ioc->eventContext++;
7747 }
7748
7749
7750 /*
7751 * Call each currently registered protocol event handler.
7752 */
7753 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
7754 if (MptEvHandlers[cb_idx]) {
7755 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7756 "Routing Event to event handler #%d\n",
7757 ioc->name, cb_idx));
7758 r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply);
7759 handlers++;
7760 }
7761 }
7762 /* FIXME? Examine results here? */
7763
7764 /*
7765 * If needed, send (a single) EventAck.
7766 */
7767 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
7768 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
7769 "EventAck required\n",ioc->name));
7770 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
7771 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SendEventAck returned %d\n",
7772 ioc->name, ii));
7773 }
7774 }
7775
7776 *evHandlers = handlers;
7777 return r;
7778}
7779
7780/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7781/**
7782 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
7783 * @ioc: Pointer to MPT_ADAPTER structure
7784 * @log_info: U32 LogInfo reply word from the IOC
7785 *
7786 * Refer to lsi/mpi_log_fc.h.
7787 */
7788static void
7789mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
7790{
7791 char *desc = "unknown";
7792
7793 switch (log_info & 0xFF000000) {
7794 case MPI_IOCLOGINFO_FC_INIT_BASE:
7795 desc = "FCP Initiator";
7796 break;
7797 case MPI_IOCLOGINFO_FC_TARGET_BASE:
7798 desc = "FCP Target";
7799 break;
7800 case MPI_IOCLOGINFO_FC_LAN_BASE:
7801 desc = "LAN";
7802 break;
7803 case MPI_IOCLOGINFO_FC_MSG_BASE:
7804 desc = "MPI Message Layer";
7805 break;
7806 case MPI_IOCLOGINFO_FC_LINK_BASE:
7807 desc = "FC Link";
7808 break;
7809 case MPI_IOCLOGINFO_FC_CTX_BASE:
7810 desc = "Context Manager";
7811 break;
7812 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
7813 desc = "Invalid Field Offset";
7814 break;
7815 case MPI_IOCLOGINFO_FC_STATE_CHANGE:
7816 desc = "State Change Info";
7817 break;
7818 }
7819
7820 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
7821 ioc->name, log_info, desc, (log_info & 0xFFFFFF));
7822}
7823
7824/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7825/**
7826 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
7827 * @ioc: Pointer to MPT_ADAPTER structure
7828 * @log_info: U32 LogInfo word from the IOC
7829 *
7830 * Refer to lsi/sp_log.h.
7831 */
7832static void
7833mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
7834{
7835 u32 info = log_info & 0x00FF0000;
7836 char *desc = "unknown";
7837
7838 switch (info) {
7839 case 0x00010000:
7840 desc = "bug! MID not found";
7841 break;
7842
7843 case 0x00020000:
7844 desc = "Parity Error";
7845 break;
7846
7847 case 0x00030000:
7848 desc = "ASYNC Outbound Overrun";
7849 break;
7850
7851 case 0x00040000:
7852 desc = "SYNC Offset Error";
7853 break;
7854
7855 case 0x00050000:
7856 desc = "BM Change";
7857 break;
7858
7859 case 0x00060000:
7860 desc = "Msg In Overflow";
7861 break;
7862
7863 case 0x00070000:
7864 desc = "DMA Error";
7865 break;
7866
7867 case 0x00080000:
7868 desc = "Outbound DMA Overrun";
7869 break;
7870
7871 case 0x00090000:
7872 desc = "Task Management";
7873 break;
7874
7875 case 0x000A0000:
7876 desc = "Device Problem";
7877 break;
7878
7879 case 0x000B0000:
7880 desc = "Invalid Phase Change";
7881 break;
7882
7883 case 0x000C0000:
7884 desc = "Untagged Table Size";
7885 break;
7886
7887 }
7888
7889 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
7890}
7891
7892/* strings for sas loginfo */
7893 static char *originator_str[] = {
7894 "IOP", /* 00h */
7895 "PL", /* 01h */
7896 "IR" /* 02h */
7897 };
7898 static char *iop_code_str[] = {
7899 NULL, /* 00h */
7900 "Invalid SAS Address", /* 01h */
7901 NULL, /* 02h */
7902 "Invalid Page", /* 03h */
7903 "Diag Message Error", /* 04h */
7904 "Task Terminated", /* 05h */
7905 "Enclosure Management", /* 06h */
7906 "Target Mode" /* 07h */
7907 };
7908 static char *pl_code_str[] = {
7909 NULL, /* 00h */
7910 "Open Failure", /* 01h */
7911 "Invalid Scatter Gather List", /* 02h */
7912 "Wrong Relative Offset or Frame Length", /* 03h */
7913 "Frame Transfer Error", /* 04h */
7914 "Transmit Frame Connected Low", /* 05h */
7915 "SATA Non-NCQ RW Error Bit Set", /* 06h */
7916 "SATA Read Log Receive Data Error", /* 07h */
7917 "SATA NCQ Fail All Commands After Error", /* 08h */
7918 "SATA Error in Receive Set Device Bit FIS", /* 09h */
7919 "Receive Frame Invalid Message", /* 0Ah */
7920 "Receive Context Message Valid Error", /* 0Bh */
7921 "Receive Frame Current Frame Error", /* 0Ch */
7922 "SATA Link Down", /* 0Dh */
7923 "Discovery SATA Init W IOS", /* 0Eh */
7924 "Config Invalid Page", /* 0Fh */
7925 "Discovery SATA Init Timeout", /* 10h */
7926 "Reset", /* 11h */
7927 "Abort", /* 12h */
7928 "IO Not Yet Executed", /* 13h */
7929 "IO Executed", /* 14h */
7930 "Persistent Reservation Out Not Affiliation "
7931 "Owner", /* 15h */
7932 "Open Transmit DMA Abort", /* 16h */
7933 "IO Device Missing Delay Retry", /* 17h */
7934 "IO Cancelled Due to Receive Error", /* 18h */
7935 NULL, /* 19h */
7936 NULL, /* 1Ah */
7937 NULL, /* 1Bh */
7938 NULL, /* 1Ch */
7939 NULL, /* 1Dh */
7940 NULL, /* 1Eh */
7941 NULL, /* 1Fh */
7942 "Enclosure Management" /* 20h */
7943 };
7944 static char *ir_code_str[] = {
7945 "Raid Action Error", /* 00h */
7946 NULL, /* 00h */
7947 NULL, /* 01h */
7948 NULL, /* 02h */
7949 NULL, /* 03h */
7950 NULL, /* 04h */
7951 NULL, /* 05h */
7952 NULL, /* 06h */
7953 NULL /* 07h */
7954 };
7955 static char *raid_sub_code_str[] = {
7956 NULL, /* 00h */
7957 "Volume Creation Failed: Data Passed too "
7958 "Large", /* 01h */
7959 "Volume Creation Failed: Duplicate Volumes "
7960 "Attempted", /* 02h */
7961 "Volume Creation Failed: Max Number "
7962 "Supported Volumes Exceeded", /* 03h */
7963 "Volume Creation Failed: DMA Error", /* 04h */
7964 "Volume Creation Failed: Invalid Volume Type", /* 05h */
7965 "Volume Creation Failed: Error Reading "
7966 "MFG Page 4", /* 06h */
7967 "Volume Creation Failed: Creating Internal "
7968 "Structures", /* 07h */
7969 NULL, /* 08h */
7970 NULL, /* 09h */
7971 NULL, /* 0Ah */
7972 NULL, /* 0Bh */
7973 NULL, /* 0Ch */
7974 NULL, /* 0Dh */
7975 NULL, /* 0Eh */
7976 NULL, /* 0Fh */
7977 "Activation failed: Already Active Volume", /* 10h */
7978 "Activation failed: Unsupported Volume Type", /* 11h */
7979 "Activation failed: Too Many Active Volumes", /* 12h */
7980 "Activation failed: Volume ID in Use", /* 13h */
7981 "Activation failed: Reported Failure", /* 14h */
7982 "Activation failed: Importing a Volume", /* 15h */
7983 NULL, /* 16h */
7984 NULL, /* 17h */
7985 NULL, /* 18h */
7986 NULL, /* 19h */
7987 NULL, /* 1Ah */
7988 NULL, /* 1Bh */
7989 NULL, /* 1Ch */
7990 NULL, /* 1Dh */
7991 NULL, /* 1Eh */
7992 NULL, /* 1Fh */
7993 "Phys Disk failed: Too Many Phys Disks", /* 20h */
7994 "Phys Disk failed: Data Passed too Large", /* 21h */
7995 "Phys Disk failed: DMA Error", /* 22h */
7996 "Phys Disk failed: Invalid <channel:id>", /* 23h */
7997 "Phys Disk failed: Creating Phys Disk Config "
7998 "Page", /* 24h */
7999 NULL, /* 25h */
8000 NULL, /* 26h */
8001 NULL, /* 27h */
8002 NULL, /* 28h */
8003 NULL, /* 29h */
8004 NULL, /* 2Ah */
8005 NULL, /* 2Bh */
8006 NULL, /* 2Ch */
8007 NULL, /* 2Dh */
8008 NULL, /* 2Eh */
8009 NULL, /* 2Fh */
8010 "Compatibility Error: IR Disabled", /* 30h */
8011 "Compatibility Error: Inquiry Command Failed", /* 31h */
8012 "Compatibility Error: Device not Direct Access "
8013 "Device ", /* 32h */
8014 "Compatibility Error: Removable Device Found", /* 33h */
8015 "Compatibility Error: Device SCSI Version not "
8016 "2 or Higher", /* 34h */
8017 "Compatibility Error: SATA Device, 48 BIT LBA "
8018 "not Supported", /* 35h */
8019 "Compatibility Error: Device doesn't have "
8020 "512 Byte Block Sizes", /* 36h */
8021 "Compatibility Error: Volume Type Check Failed", /* 37h */
8022 "Compatibility Error: Volume Type is "
8023 "Unsupported by FW", /* 38h */
8024 "Compatibility Error: Disk Drive too Small for "
8025 "use in Volume", /* 39h */
8026 "Compatibility Error: Phys Disk for Create "
8027 "Volume not Found", /* 3Ah */
8028 "Compatibility Error: Too Many or too Few "
8029 "Disks for Volume Type", /* 3Bh */
8030 "Compatibility Error: Disk stripe Sizes "
8031 "Must be 64KB", /* 3Ch */
8032 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
8033 };
8034
8035/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8036/**
8037 * mpt_sas_log_info - Log information returned from SAS IOC.
8038 * @ioc: Pointer to MPT_ADAPTER structure
8039 * @log_info: U32 LogInfo reply word from the IOC
8040 * @cb_idx: callback function's handle
8041 *
8042 * Refer to lsi/mpi_log_sas.h.
8043 **/
8044static void
8045mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info, u8 cb_idx)
8046{
8047 union loginfo_type {
8048 u32 loginfo;
8049 struct {
8050 u32 subcode:16;
8051 u32 code:8;
8052 u32 originator:4;
8053 u32 bus_type:4;
8054 } dw;
8055 };
8056 union loginfo_type sas_loginfo;
8057 char *originator_desc = NULL;
8058 char *code_desc = NULL;
8059 char *sub_code_desc = NULL;
8060
8061 sas_loginfo.loginfo = log_info;
8062 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
8063 (sas_loginfo.dw.originator < ARRAY_SIZE(originator_str)))
8064 return;
8065
8066 originator_desc = originator_str[sas_loginfo.dw.originator];
8067
8068 switch (sas_loginfo.dw.originator) {
8069
8070 case 0: /* IOP */
8071 if (sas_loginfo.dw.code <
8072 ARRAY_SIZE(iop_code_str))
8073 code_desc = iop_code_str[sas_loginfo.dw.code];
8074 break;
8075 case 1: /* PL */
8076 if (sas_loginfo.dw.code <
8077 ARRAY_SIZE(pl_code_str))
8078 code_desc = pl_code_str[sas_loginfo.dw.code];
8079 break;
8080 case 2: /* IR */
8081 if (sas_loginfo.dw.code >=
8082 ARRAY_SIZE(ir_code_str))
8083 break;
8084 code_desc = ir_code_str[sas_loginfo.dw.code];
8085 if (sas_loginfo.dw.subcode >=
8086 ARRAY_SIZE(raid_sub_code_str))
8087 break;
8088 if (sas_loginfo.dw.code == 0)
8089 sub_code_desc =
8090 raid_sub_code_str[sas_loginfo.dw.subcode];
8091 break;
8092 default:
8093 return;
8094 }
8095
8096 if (sub_code_desc != NULL)
8097 printk(MYIOC_s_INFO_FMT
8098 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
8099 " SubCode={%s} cb_idx %s\n",
8100 ioc->name, log_info, originator_desc, code_desc,
8101 sub_code_desc, MptCallbacksName[cb_idx]);
8102 else if (code_desc != NULL)
8103 printk(MYIOC_s_INFO_FMT
8104 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
8105 " SubCode(0x%04x) cb_idx %s\n",
8106 ioc->name, log_info, originator_desc, code_desc,
8107 sas_loginfo.dw.subcode, MptCallbacksName[cb_idx]);
8108 else
8109 printk(MYIOC_s_INFO_FMT
8110 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
8111 " SubCode(0x%04x) cb_idx %s\n",
8112 ioc->name, log_info, originator_desc,
8113 sas_loginfo.dw.code, sas_loginfo.dw.subcode,
8114 MptCallbacksName[cb_idx]);
8115}
8116
8117/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8118/**
8119 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
8120 * @ioc: Pointer to MPT_ADAPTER structure
8121 * @ioc_status: U32 IOCStatus word from IOC
8122 * @mf: Pointer to MPT request frame
8123 *
8124 * Refer to lsi/mpi.h.
8125 **/
8126static void
8127mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
8128{
8129 Config_t *pReq = (Config_t *)mf;
8130 char extend_desc[EVENT_DESCR_STR_SZ];
8131 char *desc = NULL;
8132 u32 form;
8133 u8 page_type;
8134
8135 if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
8136 page_type = pReq->ExtPageType;
8137 else
8138 page_type = pReq->Header.PageType;
8139
8140 /*
8141 * ignore invalid page messages for GET_NEXT_HANDLE
8142 */
8143 form = le32_to_cpu(pReq->PageAddress);
8144 if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
8145 if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
8146 page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
8147 page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
8148 if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
8149 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
8150 return;
8151 }
8152 if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
8153 if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
8154 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
8155 return;
8156 }
8157
8158 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
8159 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
8160 page_type, pReq->Header.PageNumber, pReq->Action, form);
8161
8162 switch (ioc_status) {
8163
8164 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
8165 desc = "Config Page Invalid Action";
8166 break;
8167
8168 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
8169 desc = "Config Page Invalid Type";
8170 break;
8171
8172 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
8173 desc = "Config Page Invalid Page";
8174 break;
8175
8176 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
8177 desc = "Config Page Invalid Data";
8178 break;
8179
8180 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
8181 desc = "Config Page No Defaults";
8182 break;
8183
8184 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
8185 desc = "Config Page Can't Commit";
8186 break;
8187 }
8188
8189 if (!desc)
8190 return;
8191
8192 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s: %s\n",
8193 ioc->name, ioc_status, desc, extend_desc));
8194}
8195
8196/**
8197 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
8198 * @ioc: Pointer to MPT_ADAPTER structure
8199 * @ioc_status: U32 IOCStatus word from IOC
8200 * @mf: Pointer to MPT request frame
8201 *
8202 * Refer to lsi/mpi.h.
8203 **/
8204static void
8205mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
8206{
8207 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
8208 char *desc = NULL;
8209
8210 switch (status) {
8211
8212/****************************************************************************/
8213/* Common IOCStatus values for all replies */
8214/****************************************************************************/
8215
8216 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
8217 desc = "Invalid Function";
8218 break;
8219
8220 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
8221 desc = "Busy";
8222 break;
8223
8224 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
8225 desc = "Invalid SGL";
8226 break;
8227
8228 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
8229 desc = "Internal Error";
8230 break;
8231
8232 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
8233 desc = "Reserved";
8234 break;
8235
8236 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
8237 desc = "Insufficient Resources";
8238 break;
8239
8240 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
8241 desc = "Invalid Field";
8242 break;
8243
8244 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
8245 desc = "Invalid State";
8246 break;
8247
8248/****************************************************************************/
8249/* Config IOCStatus values */
8250/****************************************************************************/
8251
8252 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
8253 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
8254 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
8255 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
8256 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
8257 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
8258 mpt_iocstatus_info_config(ioc, status, mf);
8259 break;
8260
8261/****************************************************************************/
8262/* SCSIIO Reply (SPI, FCP, SAS) initiator values */
8263/* */
8264/* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
8265/* */
8266/****************************************************************************/
8267
8268 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
8269 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
8270 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
8271 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
8272 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
8273 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
8274 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
8275 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
8276 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
8277 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
8278 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
8279 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
8280 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
8281 break;
8282
8283/****************************************************************************/
8284/* SCSI Target values */
8285/****************************************************************************/
8286
8287 case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
8288 desc = "Target: Priority IO";
8289 break;
8290
8291 case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
8292 desc = "Target: Invalid Port";
8293 break;
8294
8295 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
8296 desc = "Target Invalid IO Index:";
8297 break;
8298
8299 case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
8300 desc = "Target: Aborted";
8301 break;
8302
8303 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
8304 desc = "Target: No Conn Retryable";
8305 break;
8306
8307 case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
8308 desc = "Target: No Connection";
8309 break;
8310
8311 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
8312 desc = "Target: Transfer Count Mismatch";
8313 break;
8314
8315 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
8316 desc = "Target: STS Data not Sent";
8317 break;
8318
8319 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
8320 desc = "Target: Data Offset Error";
8321 break;
8322
8323 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
8324 desc = "Target: Too Much Write Data";
8325 break;
8326
8327 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
8328 desc = "Target: IU Too Short";
8329 break;
8330
8331 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
8332 desc = "Target: ACK NAK Timeout";
8333 break;
8334
8335 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
8336 desc = "Target: Nak Received";
8337 break;
8338
8339/****************************************************************************/
8340/* Fibre Channel Direct Access values */
8341/****************************************************************************/
8342
8343 case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
8344 desc = "FC: Aborted";
8345 break;
8346
8347 case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
8348 desc = "FC: RX ID Invalid";
8349 break;
8350
8351 case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
8352 desc = "FC: DID Invalid";
8353 break;
8354
8355 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
8356 desc = "FC: Node Logged Out";
8357 break;
8358
8359 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
8360 desc = "FC: Exchange Canceled";
8361 break;
8362
8363/****************************************************************************/
8364/* LAN values */
8365/****************************************************************************/
8366
8367 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
8368 desc = "LAN: Device not Found";
8369 break;
8370
8371 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
8372 desc = "LAN: Device Failure";
8373 break;
8374
8375 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
8376 desc = "LAN: Transmit Error";
8377 break;
8378
8379 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
8380 desc = "LAN: Transmit Aborted";
8381 break;
8382
8383 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
8384 desc = "LAN: Receive Error";
8385 break;
8386
8387 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
8388 desc = "LAN: Receive Aborted";
8389 break;
8390
8391 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
8392 desc = "LAN: Partial Packet";
8393 break;
8394
8395 case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
8396 desc = "LAN: Canceled";
8397 break;
8398
8399/****************************************************************************/
8400/* Serial Attached SCSI values */
8401/****************************************************************************/
8402
8403 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
8404 desc = "SAS: SMP Request Failed";
8405 break;
8406
8407 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
8408 desc = "SAS: SMP Data Overrun";
8409 break;
8410
8411 default:
8412 desc = "Others";
8413 break;
8414 }
8415
8416 if (!desc)
8417 return;
8418
8419 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s\n",
8420 ioc->name, status, desc));
8421}
8422
8423/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8424EXPORT_SYMBOL(mpt_attach);
8425EXPORT_SYMBOL(mpt_detach);
8426#ifdef CONFIG_PM
8427EXPORT_SYMBOL(mpt_resume);
8428EXPORT_SYMBOL(mpt_suspend);
8429#endif
8430EXPORT_SYMBOL(ioc_list);
8431EXPORT_SYMBOL(mpt_register);
8432EXPORT_SYMBOL(mpt_deregister);
8433EXPORT_SYMBOL(mpt_event_register);
8434EXPORT_SYMBOL(mpt_event_deregister);
8435EXPORT_SYMBOL(mpt_reset_register);
8436EXPORT_SYMBOL(mpt_reset_deregister);
8437EXPORT_SYMBOL(mpt_device_driver_register);
8438EXPORT_SYMBOL(mpt_device_driver_deregister);
8439EXPORT_SYMBOL(mpt_get_msg_frame);
8440EXPORT_SYMBOL(mpt_put_msg_frame);
8441EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri);
8442EXPORT_SYMBOL(mpt_free_msg_frame);
8443EXPORT_SYMBOL(mpt_send_handshake_request);
8444EXPORT_SYMBOL(mpt_verify_adapter);
8445EXPORT_SYMBOL(mpt_GetIocState);
8446EXPORT_SYMBOL(mpt_print_ioc_summary);
8447EXPORT_SYMBOL(mpt_HardResetHandler);
8448EXPORT_SYMBOL(mpt_config);
8449EXPORT_SYMBOL(mpt_findImVolumes);
8450EXPORT_SYMBOL(mpt_alloc_fw_memory);
8451EXPORT_SYMBOL(mpt_free_fw_memory);
8452EXPORT_SYMBOL(mptbase_sas_persist_operation);
8453EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
8454
8455/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8456/**
8457 * fusion_init - Fusion MPT base driver initialization routine.
8458 *
8459 * Returns 0 for success, non-zero for failure.
8460 */
8461static int __init
8462fusion_init(void)
8463{
8464 u8 cb_idx;
8465
8466 show_mptmod_ver(my_NAME, my_VERSION);
8467 printk(KERN_INFO COPYRIGHT "\n");
8468
8469 for (cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
8470 MptCallbacks[cb_idx] = NULL;
8471 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
8472 MptEvHandlers[cb_idx] = NULL;
8473 MptResetHandlers[cb_idx] = NULL;
8474 }
8475
8476 /* Register ourselves (mptbase) in order to facilitate
8477 * EventNotification handling.
8478 */
8479 mpt_base_index = mpt_register(mptbase_reply, MPTBASE_DRIVER,
8480 "mptbase_reply");
8481
8482 /* Register for hard reset handling callbacks.
8483 */
8484 mpt_reset_register(mpt_base_index, mpt_ioc_reset);
8485
8486#ifdef CONFIG_PROC_FS
8487 (void) procmpt_create();
8488#endif
8489 return 0;
8490}
8491
8492/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
8493/**
8494 * fusion_exit - Perform driver unload cleanup.
8495 *
8496 * This routine frees all resources associated with each MPT adapter
8497 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
8498 */
8499static void __exit
8500fusion_exit(void)
8501{
8502
8503 mpt_reset_deregister(mpt_base_index);
8504
8505#ifdef CONFIG_PROC_FS
8506 procmpt_destroy();
8507#endif
8508}
8509
8510module_init(fusion_init);
8511module_exit(fusion_exit);