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