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