aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/fusion/mptscsih.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/message/fusion/mptscsih.c
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/message/fusion/mptscsih.c')
-rw-r--r--drivers/message/fusion/mptscsih.c6021
1 files changed, 6021 insertions, 0 deletions
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
new file mode 100644
index 000000000000..c98d6257ec02
--- /dev/null
+++ b/drivers/message/fusion/mptscsih.c
@@ -0,0 +1,6021 @@
1/*
2 * linux/drivers/message/fusion/mptscsih.c
3 * High performance SCSI / Fibre Channel SCSI Host device driver.
4 * For use with PCI chip/adapter(s):
5 * LSIFC9xx/LSI409xx Fibre Channel
6 * running LSI Logic Fusion MPT (Message Passing Technology) firmware.
7 *
8 * Credits:
9 * This driver would not exist if not for Alan Cox's development
10 * of the linux i2o driver.
11 *
12 * A special thanks to Pamela Delaney (LSI Logic) for tons of work
13 * and countless enhancements while adding support for the 1030
14 * chip family. Pam has been instrumental in the development of
15 * of the 2.xx.xx series fusion drivers, and her contributions are
16 * far too numerous to hope to list in one place.
17 *
18 * A huge debt of gratitude is owed to David S. Miller (DaveM)
19 * for fixing much of the stupid and broken stuff in the early
20 * driver while porting to sparc64 platform. THANK YOU!
21 *
22 * (see mptbase.c)
23 *
24 * Copyright (c) 1999-2004 LSI Logic Corporation
25 * Original author: Steven J. Ralston
26 * (mailto:sjralston1@netscape.net)
27 * (mailto:mpt_linux_developer@lsil.com)
28 *
29 * $Id: mptscsih.c,v 1.104 2002/12/03 21:26:34 pdelaney Exp $
30 */
31/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
32/*
33 This program is free software; you can redistribute it and/or modify
34 it under the terms of the GNU General Public License as published by
35 the Free Software Foundation; version 2 of the License.
36
37 This program is distributed in the hope that it will be useful,
38 but WITHOUT ANY WARRANTY; without even the implied warranty of
39 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40 GNU General Public License for more details.
41
42 NO WARRANTY
43 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
44 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
45 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
46 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
47 solely responsible for determining the appropriateness of using and
48 distributing the Program and assumes all risks associated with its
49 exercise of rights under this Agreement, including but not limited to
50 the risks and costs of program errors, damage to or loss of data,
51 programs or equipment, and unavailability or interruption of operations.
52
53 DISCLAIMER OF LIABILITY
54 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
55 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
57 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
58 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
59 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
60 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
61
62 You should have received a copy of the GNU General Public License
63 along with this program; if not, write to the Free Software
64 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
65*/
66/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
67
68#include "linux_compat.h" /* linux-2.6 tweaks */
69#include <linux/module.h>
70#include <linux/kernel.h>
71#include <linux/init.h>
72#include <linux/errno.h>
73#include <linux/kdev_t.h>
74#include <linux/blkdev.h>
75#include <linux/delay.h> /* for mdelay */
76#include <linux/interrupt.h> /* needed for in_interrupt() proto */
77#include <linux/reboot.h> /* notifier code */
78#include <linux/sched.h>
79#include <linux/workqueue.h>
80
81#include <scsi/scsi.h>
82#include <scsi/scsi_cmnd.h>
83#include <scsi/scsi_device.h>
84#include <scsi/scsi_host.h>
85#include <scsi/scsi_tcq.h>
86
87#include "mptbase.h"
88#include "mptscsih.h"
89
90/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
91#define my_NAME "Fusion MPT SCSI Host driver"
92#define my_VERSION MPT_LINUX_VERSION_COMMON
93#define MYNAM "mptscsih"
94
95MODULE_AUTHOR(MODULEAUTHOR);
96MODULE_DESCRIPTION(my_NAME);
97MODULE_LICENSE("GPL");
98
99/* Command line args */
100static int mpt_dv = MPTSCSIH_DOMAIN_VALIDATION;
101MODULE_PARM(mpt_dv, "i");
102MODULE_PARM_DESC(mpt_dv, " DV Algorithm: enhanced=1, basic=0 (default=MPTSCSIH_DOMAIN_VALIDATION=1)");
103
104static int mpt_width = MPTSCSIH_MAX_WIDTH;
105MODULE_PARM(mpt_width, "i");
106MODULE_PARM_DESC(mpt_width, " Max Bus Width: wide=1, narrow=0 (default=MPTSCSIH_MAX_WIDTH=1)");
107
108static int mpt_factor = MPTSCSIH_MIN_SYNC;
109MODULE_PARM(mpt_factor, "h");
110MODULE_PARM_DESC(mpt_factor, " Min Sync Factor (default=MPTSCSIH_MIN_SYNC=0x08)");
111
112static int mpt_saf_te = MPTSCSIH_SAF_TE;
113MODULE_PARM(mpt_saf_te, "i");
114MODULE_PARM_DESC(mpt_saf_te, " Force enabling SEP Processor: enable=1 (default=MPTSCSIH_SAF_TE=0)");
115
116static int mpt_pq_filter = 0;
117MODULE_PARM(mpt_pq_filter, "i");
118MODULE_PARM_DESC(mpt_pq_filter, " Enable peripheral qualifier filter: enable=1 (default=0)");
119
120/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
121
122typedef struct _BIG_SENSE_BUF {
123 u8 data[MPT_SENSE_BUFFER_ALLOC];
124} BIG_SENSE_BUF;
125
126#define MPT_SCANDV_GOOD (0x00000000) /* must be 0 */
127#define MPT_SCANDV_DID_RESET (0x00000001)
128#define MPT_SCANDV_SENSE (0x00000002)
129#define MPT_SCANDV_SOME_ERROR (0x00000004)
130#define MPT_SCANDV_SELECTION_TIMEOUT (0x00000008)
131#define MPT_SCANDV_ISSUE_SENSE (0x00000010)
132#define MPT_SCANDV_FALLBACK (0x00000020)
133
134#define MPT_SCANDV_MAX_RETRIES (10)
135
136#define MPT_ICFLAG_BUF_CAP 0x01 /* ReadBuffer Read Capacity format */
137#define MPT_ICFLAG_ECHO 0x02 /* ReadBuffer Echo buffer format */
138#define MPT_ICFLAG_PHYS_DISK 0x04 /* Any SCSI IO but do Phys Disk Format */
139#define MPT_ICFLAG_TAGGED_CMD 0x08 /* Do tagged IO */
140#define MPT_ICFLAG_DID_RESET 0x20 /* Bus Reset occurred with this command */
141#define MPT_ICFLAG_RESERVED 0x40 /* Reserved has been issued */
142
143typedef struct _internal_cmd {
144 char *data; /* data pointer */
145 dma_addr_t data_dma; /* data dma address */
146 int size; /* transfer size */
147 u8 cmd; /* SCSI Op Code */
148 u8 bus; /* bus number */
149 u8 id; /* SCSI ID (virtual) */
150 u8 lun;
151 u8 flags; /* Bit Field - See above */
152 u8 physDiskNum; /* Phys disk number, -1 else */
153 u8 rsvd2;
154 u8 rsvd;
155} INTERNAL_CMD;
156
157typedef struct _negoparms {
158 u8 width;
159 u8 offset;
160 u8 factor;
161 u8 flags;
162} NEGOPARMS;
163
164typedef struct _dv_parameters {
165 NEGOPARMS max;
166 NEGOPARMS now;
167 u8 cmd;
168 u8 id;
169 u16 pad1;
170} DVPARAMETERS;
171
172
173/*
174 * Other private/forward protos...
175 */
176static int mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
177static void mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq);
178static int mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
179
180static int mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
181 SCSIIORequest_t *pReq, int req_idx);
182static void mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
183static void copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
184static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd);
185static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout );
186static u32 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
187
188static int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
189static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
190
191static int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
192static int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
193
194static void mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen);
195static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56);
196static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq);
197static void mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags);
198static void mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id);
199static int mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target, int flags);
200static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus);
201static int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
202static void mptscsih_timer_expired(unsigned long data);
203static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
204static int mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum);
205
206#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
207static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io);
208static void mptscsih_domainValidation(void *hd);
209static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id);
210static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id);
211static int mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target);
212static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage);
213static void mptscsih_fillbuf(char *buffer, int size, int index, int width);
214#endif
215/* module entry point */
216static int __init mptscsih_init (void);
217static void __exit mptscsih_exit (void);
218
219static int mptscsih_probe (struct pci_dev *, const struct pci_device_id *);
220static void mptscsih_remove(struct pci_dev *);
221static void mptscsih_shutdown(struct device *);
222#ifdef CONFIG_PM
223static int mptscsih_suspend(struct pci_dev *pdev, u32 state);
224static int mptscsih_resume(struct pci_dev *pdev);
225#endif
226
227
228/*
229 * Private data...
230 */
231
232static int mpt_scsi_hosts = 0;
233
234static int ScsiDoneCtx = -1;
235static int ScsiTaskCtx = -1;
236static int ScsiScanDvCtx = -1; /* Used only for bus scan and dv */
237
238#define SNS_LEN(scp) sizeof((scp)->sense_buffer)
239
240#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
241/*
242 * Domain Validation task structure
243 */
244static DEFINE_SPINLOCK(dvtaskQ_lock);
245static int dvtaskQ_active = 0;
246static int dvtaskQ_release = 0;
247static struct work_struct mptscsih_dvTask;
248#endif
249
250/*
251 * Wait Queue setup
252 */
253static DECLARE_WAIT_QUEUE_HEAD (scandv_waitq);
254static int scandv_wait_done = 1;
255
256
257/* Driver command line structure
258 */
259static struct scsi_host_template driver_template;
260
261/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
262/**
263 * mptscsih_add_sge - Place a simple SGE at address pAddr.
264 * @pAddr: virtual address for SGE
265 * @flagslength: SGE flags and data transfer length
266 * @dma_addr: Physical address
267 *
268 * This routine places a MPT request frame back on the MPT adapter's
269 * FreeQ.
270 */
271static inline void
272mptscsih_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
273{
274 if (sizeof(dma_addr_t) == sizeof(u64)) {
275 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
276 u32 tmp = dma_addr & 0xFFFFFFFF;
277
278 pSge->FlagsLength = cpu_to_le32(flagslength);
279 pSge->Address.Low = cpu_to_le32(tmp);
280 tmp = (u32) ((u64)dma_addr >> 32);
281 pSge->Address.High = cpu_to_le32(tmp);
282
283 } else {
284 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
285 pSge->FlagsLength = cpu_to_le32(flagslength);
286 pSge->Address = cpu_to_le32(dma_addr);
287 }
288} /* mptscsih_add_sge() */
289
290/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
291/**
292 * mptscsih_add_chain - Place a chain SGE at address pAddr.
293 * @pAddr: virtual address for SGE
294 * @next: nextChainOffset value (u32's)
295 * @length: length of next SGL segment
296 * @dma_addr: Physical address
297 *
298 * This routine places a MPT request frame back on the MPT adapter's
299 * FreeQ.
300 */
301static inline void
302mptscsih_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
303{
304 if (sizeof(dma_addr_t) == sizeof(u64)) {
305 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
306 u32 tmp = dma_addr & 0xFFFFFFFF;
307
308 pChain->Length = cpu_to_le16(length);
309 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
310
311 pChain->NextChainOffset = next;
312
313 pChain->Address.Low = cpu_to_le32(tmp);
314 tmp = (u32) ((u64)dma_addr >> 32);
315 pChain->Address.High = cpu_to_le32(tmp);
316 } else {
317 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
318 pChain->Length = cpu_to_le16(length);
319 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
320 pChain->NextChainOffset = next;
321 pChain->Address = cpu_to_le32(dma_addr);
322 }
323} /* mptscsih_add_chain() */
324
325/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
326/*
327 * mptscsih_getFreeChainBuffer - Function to get a free chain
328 * from the MPT_SCSI_HOST FreeChainQ.
329 * @ioc: Pointer to MPT_ADAPTER structure
330 * @req_idx: Index of the SCSI IO request frame. (output)
331 *
332 * return SUCCESS or FAILED
333 */
334static inline int
335mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex)
336{
337 MPT_FRAME_HDR *chainBuf;
338 unsigned long flags;
339 int rc;
340 int chain_idx;
341
342 dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer called\n",
343 ioc->name));
344 spin_lock_irqsave(&ioc->FreeQlock, flags);
345 if (!list_empty(&ioc->FreeChainQ)) {
346 int offset;
347
348 chainBuf = list_entry(ioc->FreeChainQ.next, MPT_FRAME_HDR,
349 u.frame.linkage.list);
350 list_del(&chainBuf->u.frame.linkage.list);
351 offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer;
352 chain_idx = offset / ioc->req_sz;
353 rc = SUCCESS;
354 dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer (index %d), got buf=%p\n",
355 ioc->name, *retIndex, chainBuf));
356 } else {
357 rc = FAILED;
358 chain_idx = MPT_HOST_NO_CHAIN;
359 dfailprintk((MYIOC_s_ERR_FMT "getFreeChainBuffer failed\n",
360 ioc->name));
361 }
362 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
363
364 *retIndex = chain_idx;
365 return rc;
366} /* mptscsih_getFreeChainBuffer() */
367
368/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
369/*
370 * mptscsih_AddSGE - Add a SGE (plus chain buffers) to the
371 * SCSIIORequest_t Message Frame.
372 * @ioc: Pointer to MPT_ADAPTER structure
373 * @SCpnt: Pointer to scsi_cmnd structure
374 * @pReq: Pointer to SCSIIORequest_t structure
375 *
376 * Returns ...
377 */
378static int
379mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
380 SCSIIORequest_t *pReq, int req_idx)
381{
382 char *psge;
383 char *chainSge;
384 struct scatterlist *sg;
385 int frm_sz;
386 int sges_left, sg_done;
387 int chain_idx = MPT_HOST_NO_CHAIN;
388 int sgeOffset;
389 int numSgeSlots, numSgeThisFrame;
390 u32 sgflags, sgdir, thisxfer = 0;
391 int chain_dma_off = 0;
392 int newIndex;
393 int ii;
394 dma_addr_t v2;
395 u32 RequestNB;
396
397 sgdir = le32_to_cpu(pReq->Control) & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK;
398 if (sgdir == MPI_SCSIIO_CONTROL_WRITE) {
399 sgdir = MPT_TRANSFER_HOST_TO_IOC;
400 } else {
401 sgdir = MPT_TRANSFER_IOC_TO_HOST;
402 }
403
404 psge = (char *) &pReq->SGL;
405 frm_sz = ioc->req_sz;
406
407 /* Map the data portion, if any.
408 * sges_left = 0 if no data transfer.
409 */
410 if ( (sges_left = SCpnt->use_sg) ) {
411 sges_left = pci_map_sg(ioc->pcidev,
412 (struct scatterlist *) SCpnt->request_buffer,
413 SCpnt->use_sg,
414 SCpnt->sc_data_direction);
415 if (sges_left == 0)
416 return FAILED;
417 } else if (SCpnt->request_bufflen) {
418 SCpnt->SCp.dma_handle = pci_map_single(ioc->pcidev,
419 SCpnt->request_buffer,
420 SCpnt->request_bufflen,
421 SCpnt->sc_data_direction);
422 dsgprintk((MYIOC_s_INFO_FMT "SG: non-SG for %p, len=%d\n",
423 ioc->name, SCpnt, SCpnt->request_bufflen));
424 mptscsih_add_sge((char *) &pReq->SGL,
425 0xD1000000|MPT_SGE_FLAGS_ADDRESSING|sgdir|SCpnt->request_bufflen,
426 SCpnt->SCp.dma_handle);
427
428 return SUCCESS;
429 }
430
431 /* Handle the SG case.
432 */
433 sg = (struct scatterlist *) SCpnt->request_buffer;
434 sg_done = 0;
435 sgeOffset = sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION);
436 chainSge = NULL;
437
438 /* Prior to entering this loop - the following must be set
439 * current MF: sgeOffset (bytes)
440 * chainSge (Null if original MF is not a chain buffer)
441 * sg_done (num SGE done for this MF)
442 */
443
444nextSGEset:
445 numSgeSlots = ((frm_sz - sgeOffset) / (sizeof(u32) + sizeof(dma_addr_t)) );
446 numSgeThisFrame = (sges_left < numSgeSlots) ? sges_left : numSgeSlots;
447
448 sgflags = MPT_SGE_FLAGS_SIMPLE_ELEMENT | MPT_SGE_FLAGS_ADDRESSING | sgdir;
449
450 /* Get first (num - 1) SG elements
451 * Skip any SG entries with a length of 0
452 * NOTE: at finish, sg and psge pointed to NEXT data/location positions
453 */
454 for (ii=0; ii < (numSgeThisFrame-1); ii++) {
455 thisxfer = sg_dma_len(sg);
456 if (thisxfer == 0) {
457 sg ++; /* Get next SG element from the OS */
458 sg_done++;
459 continue;
460 }
461
462 v2 = sg_dma_address(sg);
463 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
464
465 sg++; /* Get next SG element from the OS */
466 psge += (sizeof(u32) + sizeof(dma_addr_t));
467 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
468 sg_done++;
469 }
470
471 if (numSgeThisFrame == sges_left) {
472 /* Add last element, end of buffer and end of list flags.
473 */
474 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT |
475 MPT_SGE_FLAGS_END_OF_BUFFER |
476 MPT_SGE_FLAGS_END_OF_LIST;
477
478 /* Add last SGE and set termination flags.
479 * Note: Last SGE may have a length of 0 - which should be ok.
480 */
481 thisxfer = sg_dma_len(sg);
482
483 v2 = sg_dma_address(sg);
484 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
485 /*
486 sg++;
487 psge += (sizeof(u32) + sizeof(dma_addr_t));
488 */
489 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
490 sg_done++;
491
492 if (chainSge) {
493 /* The current buffer is a chain buffer,
494 * but there is not another one.
495 * Update the chain element
496 * Offset and Length fields.
497 */
498 mptscsih_add_chain((char *)chainSge, 0, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
499 } else {
500 /* The current buffer is the original MF
501 * and there is no Chain buffer.
502 */
503 pReq->ChainOffset = 0;
504 RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
505 dsgprintk((MYIOC_s_ERR_FMT
506 "Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
507 ioc->RequestNB[req_idx] = RequestNB;
508 }
509 } else {
510 /* At least one chain buffer is needed.
511 * Complete the first MF
512 * - last SGE element, set the LastElement bit
513 * - set ChainOffset (words) for orig MF
514 * (OR finish previous MF chain buffer)
515 * - update MFStructPtr ChainIndex
516 * - Populate chain element
517 * Also
518 * Loop until done.
519 */
520
521 dsgprintk((MYIOC_s_INFO_FMT "SG: Chain Required! sg done %d\n",
522 ioc->name, sg_done));
523
524 /* Set LAST_ELEMENT flag for last non-chain element
525 * in the buffer. Since psge points at the NEXT
526 * SGE element, go back one SGE element, update the flags
527 * and reset the pointer. (Note: sgflags & thisxfer are already
528 * set properly).
529 */
530 if (sg_done) {
531 u32 *ptmp = (u32 *) (psge - (sizeof(u32) + sizeof(dma_addr_t)));
532 sgflags = le32_to_cpu(*ptmp);
533 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT;
534 *ptmp = cpu_to_le32(sgflags);
535 }
536
537 if (chainSge) {
538 /* The current buffer is a chain buffer.
539 * chainSge points to the previous Chain Element.
540 * Update its chain element Offset and Length (must
541 * include chain element size) fields.
542 * Old chain element is now complete.
543 */
544 u8 nextChain = (u8) (sgeOffset >> 2);
545 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
546 mptscsih_add_chain((char *)chainSge, nextChain, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
547 } else {
548 /* The original MF buffer requires a chain buffer -
549 * set the offset.
550 * Last element in this MF is a chain element.
551 */
552 pReq->ChainOffset = (u8) (sgeOffset >> 2);
553 RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
554 dsgprintk((MYIOC_s_ERR_FMT "Chain Buffer Needed, RequestNB=%x sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
555 ioc->RequestNB[req_idx] = RequestNB;
556 }
557
558 sges_left -= sg_done;
559
560
561 /* NOTE: psge points to the beginning of the chain element
562 * in current buffer. Get a chain buffer.
563 */
564 dsgprintk((MYIOC_s_INFO_FMT
565 "calling getFreeChainBuffer SCSI cmd=%02x (%p)\n",
566 ioc->name, pReq->CDB[0], SCpnt));
567 if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED)
568 return FAILED;
569
570 /* Update the tracking arrays.
571 * If chainSge == NULL, update ReqToChain, else ChainToChain
572 */
573 if (chainSge) {
574 ioc->ChainToChain[chain_idx] = newIndex;
575 } else {
576 ioc->ReqToChain[req_idx] = newIndex;
577 }
578 chain_idx = newIndex;
579 chain_dma_off = ioc->req_sz * chain_idx;
580
581 /* Populate the chainSGE for the current buffer.
582 * - Set chain buffer pointer to psge and fill
583 * out the Address and Flags fields.
584 */
585 chainSge = (char *) psge;
586 dsgprintk((KERN_INFO " Current buff @ %p (index 0x%x)",
587 psge, req_idx));
588
589 /* Start the SGE for the next buffer
590 */
591 psge = (char *) (ioc->ChainBuffer + chain_dma_off);
592 sgeOffset = 0;
593 sg_done = 0;
594
595 dsgprintk((KERN_INFO " Chain buff @ %p (index 0x%x)\n",
596 psge, chain_idx));
597
598 /* Start the SGE for the next buffer
599 */
600
601 goto nextSGEset;
602 }
603
604 return SUCCESS;
605} /* mptscsih_AddSGE() */
606
607/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
608/*
609 * mptscsih_io_done - Main SCSI IO callback routine registered to
610 * Fusion MPT (base) driver
611 * @ioc: Pointer to MPT_ADAPTER structure
612 * @mf: Pointer to original MPT request frame
613 * @r: Pointer to MPT reply frame (NULL if TurboReply)
614 *
615 * This routine is called from mpt.c::mpt_interrupt() at the completion
616 * of any SCSI IO request.
617 * This routine is registered with the Fusion MPT (base) driver at driver
618 * load/init time via the mpt_register() API call.
619 *
620 * Returns 1 indicating alloc'd request frame ptr should be freed.
621 */
622static int
623mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
624{
625 struct scsi_cmnd *sc;
626 MPT_SCSI_HOST *hd;
627 SCSIIORequest_t *pScsiReq;
628 SCSIIOReply_t *pScsiReply;
629 u16 req_idx;
630
631 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
632
633 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
634 sc = hd->ScsiLookup[req_idx];
635 if (sc == NULL) {
636 MPIHeader_t *hdr = (MPIHeader_t *)mf;
637
638 /* Remark: writeSDP1 will use the ScsiDoneCtx
639 * If a SCSI I/O cmd, device disabled by OS and
640 * completion done. Cannot touch sc struct. Just free mem.
641 */
642 if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST)
643 printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n",
644 ioc->name);
645
646 mptscsih_freeChainBuffers(ioc, req_idx);
647 return 1;
648 }
649
650 dmfprintk((MYIOC_s_INFO_FMT
651 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
652 ioc->name, mf, mr, sc, req_idx));
653
654 sc->result = DID_OK << 16; /* Set default reply as OK */
655 pScsiReq = (SCSIIORequest_t *) mf;
656 pScsiReply = (SCSIIOReply_t *) mr;
657
658 if (pScsiReply == NULL) {
659 /* special context reply handling */
660 ;
661 } else {
662 u32 xfer_cnt;
663 u16 status;
664 u8 scsi_state, scsi_status;
665
666 status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
667 scsi_state = pScsiReply->SCSIState;
668 scsi_status = pScsiReply->SCSIStatus;
669 xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
670 sc->resid = sc->request_bufflen - xfer_cnt;
671
672 dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n"
673 "IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n"
674 "resid=%d bufflen=%d xfer_cnt=%d\n",
675 ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1],
676 status, scsi_state, scsi_status, sc->resid,
677 sc->request_bufflen, xfer_cnt));
678
679 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
680 copy_sense_data(sc, hd, mf, pScsiReply);
681
682 /*
683 * Look for + dump FCP ResponseInfo[]!
684 */
685 if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID) {
686 printk(KERN_NOTICE " FCP_ResponseInfo=%08xh\n",
687 le32_to_cpu(pScsiReply->ResponseInfo));
688 }
689
690 switch(status) {
691 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
692 /* CHECKME!
693 * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
694 * But not: DID_BUS_BUSY lest one risk
695 * killing interrupt handler:-(
696 */
697 sc->result = SAM_STAT_BUSY;
698 break;
699
700 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
701 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
702 sc->result = DID_BAD_TARGET << 16;
703 break;
704
705 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
706 /* Spoof to SCSI Selection Timeout! */
707 sc->result = DID_NO_CONNECT << 16;
708
709 if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
710 hd->sel_timeout[pScsiReq->TargetID]++;
711 break;
712
713 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
714 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
715 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
716 /* Linux handles an unsolicited DID_RESET better
717 * than an unsolicited DID_ABORT.
718 */
719 sc->result = DID_RESET << 16;
720
721 /* GEM Workaround. */
722 if (ioc->bus_type == SCSI)
723 mptscsih_no_negotiate(hd, sc->device->id);
724 break;
725
726 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
727 if ( xfer_cnt >= sc->underflow ) {
728 /* Sufficient data transfer occurred */
729 sc->result = (DID_OK << 16) | scsi_status;
730 } else if ( xfer_cnt == 0 ) {
731 /* A CRC Error causes this condition; retry */
732 sc->result = (DRIVER_SENSE << 24) | (DID_OK << 16) |
733 (CHECK_CONDITION << 1);
734 sc->sense_buffer[0] = 0x70;
735 sc->sense_buffer[2] = NO_SENSE;
736 sc->sense_buffer[12] = 0;
737 sc->sense_buffer[13] = 0;
738 } else {
739 sc->result = DID_SOFT_ERROR << 16;
740 }
741 dreplyprintk((KERN_NOTICE "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->target));
742 break;
743
744 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
745 /*
746 * Do upfront check for valid SenseData and give it
747 * precedence!
748 */
749 sc->result = (DID_OK << 16) | scsi_status;
750 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
751 /* Have already saved the status and sense data
752 */
753 ;
754 } else {
755 if (xfer_cnt < sc->underflow) {
756 sc->result = DID_SOFT_ERROR << 16;
757 }
758 if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
759 /* What to do?
760 */
761 sc->result = DID_SOFT_ERROR << 16;
762 }
763 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
764 /* Not real sure here either... */
765 sc->result = DID_RESET << 16;
766 }
767 }
768
769 dreplyprintk((KERN_NOTICE " sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
770 sc->underflow));
771 dreplyprintk((KERN_NOTICE " ActBytesXferd=%02xh\n", xfer_cnt));
772 /* Report Queue Full
773 */
774 if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
775 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
776
777 break;
778
779 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
780 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
781 scsi_status = pScsiReply->SCSIStatus;
782 sc->result = (DID_OK << 16) | scsi_status;
783 if (scsi_state == 0) {
784 ;
785 } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
786 /*
787 * If running against circa 200003dd 909 MPT f/w,
788 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
789 * (QUEUE_FULL) returned from device! --> get 0x0000?128
790 * and with SenseBytes set to 0.
791 */
792 if (pScsiReply->SCSIStatus == MPI_SCSI_STATUS_TASK_SET_FULL)
793 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
794
795 }
796 else if (scsi_state &
797 (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)
798 ) {
799 /*
800 * What to do?
801 */
802 sc->result = DID_SOFT_ERROR << 16;
803 }
804 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
805 /* Not real sure here either... */
806 sc->result = DID_RESET << 16;
807 }
808 else if (scsi_state & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) {
809 /* Device Inq. data indicates that it supports
810 * QTags, but rejects QTag messages.
811 * This command completed OK.
812 *
813 * Not real sure here either so do nothing... */
814 }
815
816 if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
817 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
818
819 /* Add handling of:
820 * Reservation Conflict, Busy,
821 * Command Terminated, CHECK
822 */
823 break;
824
825 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
826 sc->result = DID_SOFT_ERROR << 16;
827 break;
828
829 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
830 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
831 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
832 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
833 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
834 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
835 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
836 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
837 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
838 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
839 default:
840 /*
841 * What to do?
842 */
843 sc->result = DID_SOFT_ERROR << 16;
844 break;
845
846 } /* switch(status) */
847
848 dreplyprintk((KERN_NOTICE " sc->result is %08xh\n", sc->result));
849 } /* end of address reply case */
850
851 /* Unmap the DMA buffers, if any. */
852 if (sc->use_sg) {
853 pci_unmap_sg(ioc->pcidev, (struct scatterlist *) sc->request_buffer,
854 sc->use_sg, sc->sc_data_direction);
855 } else if (sc->request_bufflen) {
856 pci_unmap_single(ioc->pcidev, sc->SCp.dma_handle,
857 sc->request_bufflen, sc->sc_data_direction);
858 }
859
860 hd->ScsiLookup[req_idx] = NULL;
861
862 sc->scsi_done(sc); /* Issue the command callback */
863
864 /* Free Chain buffers */
865 mptscsih_freeChainBuffers(ioc, req_idx);
866 return 1;
867}
868
869
870/*
871 * mptscsih_flush_running_cmds - For each command found, search
872 * Scsi_Host instance taskQ and reply to OS.
873 * Called only if recovering from a FW reload.
874 * @hd: Pointer to a SCSI HOST structure
875 *
876 * Returns: None.
877 *
878 * Must be called while new I/Os are being queued.
879 */
880static void
881mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
882{
883 MPT_ADAPTER *ioc = hd->ioc;
884 struct scsi_cmnd *SCpnt;
885 MPT_FRAME_HDR *mf;
886 int ii;
887 int max = ioc->req_depth;
888
889 dprintk((KERN_INFO MYNAM ": flush_ScsiLookup called\n"));
890 for (ii= 0; ii < max; ii++) {
891 if ((SCpnt = hd->ScsiLookup[ii]) != NULL) {
892
893 /* Command found.
894 */
895
896 /* Null ScsiLookup index
897 */
898 hd->ScsiLookup[ii] = NULL;
899
900 mf = MPT_INDEX_2_MFPTR(ioc, ii);
901 dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",
902 mf, SCpnt));
903
904 /* Set status, free OS resources (SG DMA buffers)
905 * Do OS callback
906 * Free driver resources (chain, msg buffers)
907 */
908 if (scsi_device_online(SCpnt->device)) {
909 if (SCpnt->use_sg) {
910 pci_unmap_sg(ioc->pcidev,
911 (struct scatterlist *) SCpnt->request_buffer,
912 SCpnt->use_sg,
913 SCpnt->sc_data_direction);
914 } else if (SCpnt->request_bufflen) {
915 pci_unmap_single(ioc->pcidev,
916 SCpnt->SCp.dma_handle,
917 SCpnt->request_bufflen,
918 SCpnt->sc_data_direction);
919 }
920 }
921 SCpnt->result = DID_RESET << 16;
922 SCpnt->host_scribble = NULL;
923
924 /* Free Chain buffers */
925 mptscsih_freeChainBuffers(ioc, ii);
926
927 /* Free Message frames */
928 mpt_free_msg_frame(ioc, mf);
929
930 SCpnt->scsi_done(SCpnt); /* Issue the command callback */
931 }
932 }
933
934 return;
935}
936
937/*
938 * mptscsih_search_running_cmds - Delete any commands associated
939 * with the specified target and lun. Function called only
940 * when a lun is disable by mid-layer.
941 * Do NOT access the referenced scsi_cmnd structure or
942 * members. Will cause either a paging or NULL ptr error.
943 * @hd: Pointer to a SCSI HOST structure
944 * @target: target id
945 * @lun: lun
946 *
947 * Returns: None.
948 *
949 * Called from slave_destroy.
950 */
951static void
952mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun)
953{
954 SCSIIORequest_t *mf = NULL;
955 int ii;
956 int max = hd->ioc->req_depth;
957
958 dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n",
959 target, lun, max));
960
961 for (ii=0; ii < max; ii++) {
962 if (hd->ScsiLookup[ii] != NULL) {
963
964 mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii);
965
966 dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
967 hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1]));
968
969 if ((mf->TargetID != ((u8)target)) || (mf->LUN[1] != ((u8) lun)))
970 continue;
971
972 /* Cleanup
973 */
974 hd->ScsiLookup[ii] = NULL;
975 mptscsih_freeChainBuffers(hd->ioc, ii);
976 mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf);
977 }
978 }
979
980 return;
981}
982
983/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
984/*
985 * Hack! It might be nice to report if a device is returning QUEUE_FULL
986 * but maybe not each and every time...
987 */
988static long last_queue_full = 0;
989
990/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
991/*
992 * mptscsih_report_queue_full - Report QUEUE_FULL status returned
993 * from a SCSI target device.
994 * @sc: Pointer to scsi_cmnd structure
995 * @pScsiReply: Pointer to SCSIIOReply_t
996 * @pScsiReq: Pointer to original SCSI request
997 *
998 * This routine periodically reports QUEUE_FULL status returned from a
999 * SCSI target device. It reports this to the console via kernel
1000 * printk() API call, not more than once every 10 seconds.
1001 */
1002static void
1003mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
1004{
1005 long time = jiffies;
1006
1007 if (time - last_queue_full > 10 * HZ) {
1008 char *ioc_str = "ioc?";
1009
1010 if (sc->device && sc->device->host != NULL && sc->device->host->hostdata != NULL)
1011 ioc_str = ((MPT_SCSI_HOST *)sc->device->host->hostdata)->ioc->name;
1012 dprintk((MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
1013 ioc_str, 0, sc->device->id, sc->device->lun));
1014 last_queue_full = time;
1015 }
1016}
1017
1018/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1019static char *info_kbuf = NULL;
1020
1021/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1022/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1023/*
1024 * mptscsih_probe - Installs scsi devices per bus.
1025 * @pdev: Pointer to pci_dev structure
1026 *
1027 * Returns 0 for success, non-zero for failure.
1028 *
1029 */
1030
1031static int
1032mptscsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1033{
1034 struct Scsi_Host *sh;
1035 MPT_SCSI_HOST *hd;
1036 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1037 unsigned long flags;
1038 int sz, ii;
1039 int numSGE = 0;
1040 int scale;
1041 int ioc_cap;
1042 u8 *mem;
1043 int error=0;
1044
1045
1046 /* 20010202 -sralston
1047 * Added sanity check on readiness of the MPT adapter.
1048 */
1049 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
1050 printk(MYIOC_s_WARN_FMT
1051 "Skipping because it's not operational!\n",
1052 ioc->name);
1053 return -ENODEV;
1054 }
1055
1056 if (!ioc->active) {
1057 printk(MYIOC_s_WARN_FMT "Skipping because it's disabled!\n",
1058 ioc->name);
1059 return -ENODEV;
1060 }
1061
1062 /* Sanity check - ensure at least 1 port is INITIATOR capable
1063 */
1064 ioc_cap = 0;
1065 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) {
1066 if (ioc->pfacts[ii].ProtocolFlags &
1067 MPI_PORTFACTS_PROTOCOL_INITIATOR)
1068 ioc_cap ++;
1069 }
1070
1071 if (!ioc_cap) {
1072 printk(MYIOC_s_WARN_FMT
1073 "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
1074 ioc->name, ioc);
1075 return -ENODEV;
1076 }
1077
1078 sh = scsi_host_alloc(&driver_template, sizeof(MPT_SCSI_HOST));
1079
1080 if (!sh) {
1081 printk(MYIOC_s_WARN_FMT
1082 "Unable to register controller with SCSI subsystem\n",
1083 ioc->name);
1084 return -1;
1085 }
1086
1087 spin_lock_irqsave(&ioc->FreeQlock, flags);
1088
1089 /* Attach the SCSI Host to the IOC structure
1090 */
1091 ioc->sh = sh;
1092
1093 sh->io_port = 0;
1094 sh->n_io_port = 0;
1095 sh->irq = 0;
1096
1097 /* set 16 byte cdb's */
1098 sh->max_cmd_len = 16;
1099
1100 /* Yikes! This is important!
1101 * Otherwise, by default, linux
1102 * only scans target IDs 0-7!
1103 * pfactsN->MaxDevices unreliable
1104 * (not supported in early
1105 * versions of the FW).
1106 * max_id = 1 + actual max id,
1107 * max_lun = 1 + actual last lun,
1108 * see hosts.h :o(
1109 */
1110 if (ioc->bus_type == SCSI) {
1111 sh->max_id = MPT_MAX_SCSI_DEVICES;
1112 } else {
1113 /* For FC, increase the queue depth
1114 * from MPT_SCSI_CAN_QUEUE (31)
1115 * to MPT_FC_CAN_QUEUE (63).
1116 */
1117 sh->can_queue = MPT_FC_CAN_QUEUE;
1118 sh->max_id =
1119 MPT_MAX_FC_DEVICES<256 ? MPT_MAX_FC_DEVICES : 255;
1120 }
1121
1122 sh->max_lun = MPT_LAST_LUN + 1;
1123 sh->max_channel = 0;
1124 sh->this_id = ioc->pfacts[0].PortSCSIID;
1125
1126 /* Required entry.
1127 */
1128 sh->unique_id = ioc->id;
1129
1130 /* Verify that we won't exceed the maximum
1131 * number of chain buffers
1132 * We can optimize: ZZ = req_sz/sizeof(SGE)
1133 * For 32bit SGE's:
1134 * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
1135 * + (req_sz - 64)/sizeof(SGE)
1136 * A slightly different algorithm is required for
1137 * 64bit SGEs.
1138 */
1139 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
1140 if (sizeof(dma_addr_t) == sizeof(u64)) {
1141 numSGE = (scale - 1) *
1142 (ioc->facts.MaxChainDepth-1) + scale +
1143 (ioc->req_sz - 60) / (sizeof(dma_addr_t) +
1144 sizeof(u32));
1145 } else {
1146 numSGE = 1 + (scale - 1) *
1147 (ioc->facts.MaxChainDepth-1) + scale +
1148 (ioc->req_sz - 64) / (sizeof(dma_addr_t) +
1149 sizeof(u32));
1150 }
1151
1152 if (numSGE < sh->sg_tablesize) {
1153 /* Reset this value */
1154 dprintk((MYIOC_s_INFO_FMT
1155 "Resetting sg_tablesize to %d from %d\n",
1156 ioc->name, numSGE, sh->sg_tablesize));
1157 sh->sg_tablesize = numSGE;
1158 }
1159
1160 /* Set the pci device pointer in Scsi_Host structure.
1161 */
1162 scsi_set_device(sh, &ioc->pcidev->dev);
1163
1164 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1165
1166 hd = (MPT_SCSI_HOST *) sh->hostdata;
1167 hd->ioc = ioc;
1168
1169 /* SCSI needs scsi_cmnd lookup table!
1170 * (with size equal to req_depth*PtrSz!)
1171 */
1172 sz = ioc->req_depth * sizeof(void *);
1173 mem = kmalloc(sz, GFP_ATOMIC);
1174 if (mem == NULL) {
1175 error = -ENOMEM;
1176 goto mptscsih_probe_failed;
1177 }
1178
1179 memset(mem, 0, sz);
1180 hd->ScsiLookup = (struct scsi_cmnd **) mem;
1181
1182 dprintk((MYIOC_s_INFO_FMT "ScsiLookup @ %p, sz=%d\n",
1183 ioc->name, hd->ScsiLookup, sz));
1184
1185 /* Allocate memory for the device structures.
1186 * A non-Null pointer at an offset
1187 * indicates a device exists.
1188 * max_id = 1 + maximum id (hosts.h)
1189 */
1190 sz = sh->max_id * sizeof(void *);
1191 mem = kmalloc(sz, GFP_ATOMIC);
1192 if (mem == NULL) {
1193 error = -ENOMEM;
1194 goto mptscsih_probe_failed;
1195 }
1196
1197 memset(mem, 0, sz);
1198 hd->Targets = (VirtDevice **) mem;
1199
1200 dprintk((KERN_INFO
1201 " Targets @ %p, sz=%d\n", hd->Targets, sz));
1202
1203 /* Clear the TM flags
1204 */
1205 hd->tmPending = 0;
1206 hd->tmState = TM_STATE_NONE;
1207 hd->resetPending = 0;
1208 hd->abortSCpnt = NULL;
1209
1210 /* Clear the pointer used to store
1211 * single-threaded commands, i.e., those
1212 * issued during a bus scan, dv and
1213 * configuration pages.
1214 */
1215 hd->cmdPtr = NULL;
1216
1217 /* Initialize this SCSI Hosts' timers
1218 * To use, set the timer expires field
1219 * and add_timer
1220 */
1221 init_timer(&hd->timer);
1222 hd->timer.data = (unsigned long) hd;
1223 hd->timer.function = mptscsih_timer_expired;
1224
1225 if (ioc->bus_type == SCSI) {
1226 /* Update with the driver setup
1227 * values.
1228 */
1229 if (ioc->spi_data.maxBusWidth > mpt_width)
1230 ioc->spi_data.maxBusWidth = mpt_width;
1231 if (ioc->spi_data.minSyncFactor < mpt_factor)
1232 ioc->spi_data.minSyncFactor = mpt_factor;
1233
1234 if (ioc->spi_data.minSyncFactor == MPT_ASYNC) {
1235 ioc->spi_data.maxSyncOffset = 0;
1236 }
1237
1238 ioc->spi_data.Saf_Te = mpt_saf_te;
1239
1240 hd->negoNvram = 0;
1241#ifndef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1242 hd->negoNvram = MPT_SCSICFG_USE_NVRAM;
1243#endif
1244 ioc->spi_data.forceDv = 0;
1245 ioc->spi_data.noQas = 0;
1246 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
1247 ioc->spi_data.dvStatus[ii] =
1248 MPT_SCSICFG_NEGOTIATE;
1249 }
1250
1251 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++)
1252 ioc->spi_data.dvStatus[ii] |=
1253 MPT_SCSICFG_DV_NOT_DONE;
1254
1255 dinitprintk((MYIOC_s_INFO_FMT
1256 "dv %x width %x factor %x saf_te %x\n",
1257 ioc->name, mpt_dv,
1258 mpt_width,
1259 mpt_factor,
1260 mpt_saf_te));
1261 }
1262
1263 mpt_scsi_hosts++;
1264
1265 error = scsi_add_host (sh, &ioc->pcidev->dev);
1266 if(error) {
1267 dprintk((KERN_ERR MYNAM
1268 "scsi_add_host failed\n"));
1269 goto mptscsih_probe_failed;
1270 }
1271
1272 scsi_scan_host(sh);
1273 return 0;
1274
1275mptscsih_probe_failed:
1276
1277 mptscsih_remove(pdev);
1278 return error;
1279
1280}
1281
1282/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1283/*
1284 * mptscsih_remove - Removed scsi devices
1285 * @pdev: Pointer to pci_dev structure
1286 *
1287 *
1288 */
1289static void
1290mptscsih_remove(struct pci_dev *pdev)
1291{
1292 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1293 struct Scsi_Host *host = ioc->sh;
1294 MPT_SCSI_HOST *hd;
1295 int count;
1296 unsigned long flags;
1297
1298 if(!host)
1299 return;
1300
1301 scsi_remove_host(host);
1302
1303#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1304 /* Check DV thread active */
1305 count = 10 * HZ;
1306 spin_lock_irqsave(&dvtaskQ_lock, flags);
1307 if (dvtaskQ_active) {
1308 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
1309 while(dvtaskQ_active && --count) {
1310 set_current_state(TASK_INTERRUPTIBLE);
1311 schedule_timeout(1);
1312 }
1313 } else {
1314 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
1315 }
1316 if (!count)
1317 printk(KERN_ERR MYNAM ": ERROR - DV thread still active!\n");
1318#if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
1319 else
1320 printk(KERN_ERR MYNAM ": DV thread orig %d, count %d\n", 10 * HZ, count);
1321#endif
1322#endif
1323
1324 hd = (MPT_SCSI_HOST *)host->hostdata;
1325 if (hd != NULL) {
1326 int sz1;
1327
1328 mptscsih_shutdown(&pdev->dev);
1329
1330 sz1=0;
1331
1332 if (hd->ScsiLookup != NULL) {
1333 sz1 = hd->ioc->req_depth * sizeof(void *);
1334 kfree(hd->ScsiLookup);
1335 hd->ScsiLookup = NULL;
1336 }
1337
1338 if (hd->Targets != NULL) {
1339 /*
1340 * Free pointer array.
1341 */
1342 kfree(hd->Targets);
1343 hd->Targets = NULL;
1344 }
1345
1346 dprintk((MYIOC_s_INFO_FMT
1347 "Free'd ScsiLookup (%d) memory\n",
1348 hd->ioc->name, sz1));
1349
1350 /* NULL the Scsi_Host pointer
1351 */
1352 hd->ioc->sh = NULL;
1353 }
1354
1355 scsi_host_put(host);
1356 mpt_scsi_hosts--;
1357
1358}
1359
1360/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1361/*
1362 * mptscsih_shutdown - reboot notifier
1363 *
1364 */
1365static void
1366mptscsih_shutdown(struct device * dev)
1367{
1368 MPT_ADAPTER *ioc = pci_get_drvdata(to_pci_dev(dev));
1369 struct Scsi_Host *host = ioc->sh;
1370 MPT_SCSI_HOST *hd;
1371
1372 if(!host)
1373 return;
1374
1375 hd = (MPT_SCSI_HOST *)host->hostdata;
1376
1377 /* Flush the cache of this adapter
1378 */
1379 if(hd != NULL)
1380 mptscsih_synchronize_cache(hd, 0);
1381
1382}
1383
1384#ifdef CONFIG_PM
1385/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1386/*
1387 * mptscsih_suspend - Fusion MPT scsie driver suspend routine.
1388 *
1389 *
1390 */
1391static int
1392mptscsih_suspend(struct pci_dev *pdev, u32 state)
1393{
1394 mptscsih_shutdown(&pdev->dev);
1395 return 0;
1396}
1397
1398/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1399/*
1400 * mptscsih_resume - Fusion MPT scsi driver resume routine.
1401 *
1402 *
1403 */
1404static int
1405mptscsih_resume(struct pci_dev *pdev)
1406{
1407 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1408 struct Scsi_Host *host = ioc->sh;
1409 MPT_SCSI_HOST *hd;
1410
1411 if(!host)
1412 return 0;
1413
1414 hd = (MPT_SCSI_HOST *)host->hostdata;
1415 if(!hd)
1416 return 0;
1417
1418#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1419 {
1420 unsigned long lflags;
1421 spin_lock_irqsave(&dvtaskQ_lock, lflags);
1422 if (!dvtaskQ_active) {
1423 dvtaskQ_active = 1;
1424 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1425 INIT_WORK(&mptscsih_dvTask,
1426 mptscsih_domainValidation, (void *) hd);
1427 schedule_work(&mptscsih_dvTask);
1428 } else {
1429 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1430 }
1431 }
1432#endif
1433 return 0;
1434}
1435
1436#endif
1437
1438static struct mpt_pci_driver mptscsih_driver = {
1439 .probe = mptscsih_probe,
1440 .remove = mptscsih_remove,
1441 .shutdown = mptscsih_shutdown,
1442#ifdef CONFIG_PM
1443 .suspend = mptscsih_suspend,
1444 .resume = mptscsih_resume,
1445#endif
1446};
1447
1448/* SCSI host fops start here... */
1449/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1450/**
1451 * mptscsih_init - Register MPT adapter(s) as SCSI host(s) with
1452 * linux scsi mid-layer.
1453 *
1454 * Returns 0 for success, non-zero for failure.
1455 */
1456static int __init
1457mptscsih_init(void)
1458{
1459
1460 show_mptmod_ver(my_NAME, my_VERSION);
1461
1462 ScsiDoneCtx = mpt_register(mptscsih_io_done, MPTSCSIH_DRIVER);
1463 ScsiTaskCtx = mpt_register(mptscsih_taskmgmt_complete, MPTSCSIH_DRIVER);
1464 ScsiScanDvCtx = mpt_register(mptscsih_scandv_complete, MPTSCSIH_DRIVER);
1465
1466 if (mpt_event_register(ScsiDoneCtx, mptscsih_event_process) == 0) {
1467 devtprintk((KERN_INFO MYNAM
1468 ": Registered for IOC event notifications\n"));
1469 }
1470
1471 if (mpt_reset_register(ScsiDoneCtx, mptscsih_ioc_reset) == 0) {
1472 dprintk((KERN_INFO MYNAM
1473 ": Registered for IOC reset notifications\n"));
1474 }
1475
1476 if(mpt_device_driver_register(&mptscsih_driver,
1477 MPTSCSIH_DRIVER) != 0 ) {
1478 dprintk((KERN_INFO MYNAM
1479 ": failed to register dd callbacks\n"));
1480 }
1481
1482 return 0;
1483
1484}
1485
1486/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1487/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1488/**
1489 * mptscsih_exit - Unregisters MPT adapter(s)
1490 *
1491 */
1492static void __exit
1493mptscsih_exit(void)
1494{
1495 mpt_device_driver_deregister(MPTSCSIH_DRIVER);
1496
1497 mpt_reset_deregister(ScsiDoneCtx);
1498 dprintk((KERN_INFO MYNAM
1499 ": Deregistered for IOC reset notifications\n"));
1500
1501 mpt_event_deregister(ScsiDoneCtx);
1502 dprintk((KERN_INFO MYNAM
1503 ": Deregistered for IOC event notifications\n"));
1504
1505 mpt_deregister(ScsiScanDvCtx);
1506 mpt_deregister(ScsiTaskCtx);
1507 mpt_deregister(ScsiDoneCtx);
1508
1509 if (info_kbuf != NULL)
1510 kfree(info_kbuf);
1511
1512}
1513
1514/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1515/**
1516 * mptscsih_info - Return information about MPT adapter
1517 * @SChost: Pointer to Scsi_Host structure
1518 *
1519 * (linux scsi_host_template.info routine)
1520 *
1521 * Returns pointer to buffer where information was written.
1522 */
1523static const char *
1524mptscsih_info(struct Scsi_Host *SChost)
1525{
1526 MPT_SCSI_HOST *h;
1527 int size = 0;
1528
1529 if (info_kbuf == NULL)
1530 if ((info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
1531 return info_kbuf;
1532
1533 h = (MPT_SCSI_HOST *)SChost->hostdata;
1534 info_kbuf[0] = '\0';
1535 if (h) {
1536 mpt_print_ioc_summary(h->ioc, info_kbuf, &size, 0, 0);
1537 info_kbuf[size-1] = '\0';
1538 }
1539
1540 return info_kbuf;
1541}
1542
1543struct info_str {
1544 char *buffer;
1545 int length;
1546 int offset;
1547 int pos;
1548};
1549
1550static void copy_mem_info(struct info_str *info, char *data, int len)
1551{
1552 if (info->pos + len > info->length)
1553 len = info->length - info->pos;
1554
1555 if (info->pos + len < info->offset) {
1556 info->pos += len;
1557 return;
1558 }
1559
1560 if (info->pos < info->offset) {
1561 data += (info->offset - info->pos);
1562 len -= (info->offset - info->pos);
1563 }
1564
1565 if (len > 0) {
1566 memcpy(info->buffer + info->pos, data, len);
1567 info->pos += len;
1568 }
1569}
1570
1571static int copy_info(struct info_str *info, char *fmt, ...)
1572{
1573 va_list args;
1574 char buf[81];
1575 int len;
1576
1577 va_start(args, fmt);
1578 len = vsprintf(buf, fmt, args);
1579 va_end(args);
1580
1581 copy_mem_info(info, buf, len);
1582 return len;
1583}
1584
1585static int mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
1586{
1587 struct info_str info;
1588
1589 info.buffer = pbuf;
1590 info.length = len;
1591 info.offset = offset;
1592 info.pos = 0;
1593
1594 copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);
1595 copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1596 copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);
1597 copy_info(&info, "MaxQ=%d\n", ioc->req_depth);
1598
1599 return ((info.pos > info.offset) ? info.pos - info.offset : 0);
1600}
1601
1602/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1603/**
1604 * mptscsih_proc_info - Return information about MPT adapter
1605 *
1606 * (linux scsi_host_template.info routine)
1607 *
1608 * buffer: if write, user data; if read, buffer for user
1609 * length: if write, return length;
1610 * offset: if write, 0; if read, the current offset into the buffer from
1611 * the previous read.
1612 * hostno: scsi host number
1613 * func: if write = 1; if read = 0
1614 */
1615static int
1616mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1617 int length, int func)
1618{
1619 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
1620 MPT_ADAPTER *ioc = hd->ioc;
1621 int size = 0;
1622
1623 if (func) {
1624 /*
1625 * write is not supported
1626 */
1627 } else {
1628 if (start)
1629 *start = buffer;
1630
1631 size = mptscsih_host_info(ioc, buffer, offset, length);
1632 }
1633
1634 return size;
1635}
1636
1637/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1638#define ADD_INDEX_LOG(req_ent) do { } while(0)
1639
1640/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1641/**
1642 * mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1643 * @SCpnt: Pointer to scsi_cmnd structure
1644 * @done: Pointer SCSI mid-layer IO completion function
1645 *
1646 * (linux scsi_host_template.queuecommand routine)
1647 * This is the primary SCSI IO start routine. Create a MPI SCSIIORequest
1648 * from a linux scsi_cmnd request and send it to the IOC.
1649 *
1650 * Returns 0. (rtn value discarded by linux scsi mid-layer)
1651 */
1652static int
1653mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1654{
1655 MPT_SCSI_HOST *hd;
1656 MPT_FRAME_HDR *mf;
1657 SCSIIORequest_t *pScsiReq;
1658 VirtDevice *pTarget;
1659 int target;
1660 int lun;
1661 u32 datalen;
1662 u32 scsictl;
1663 u32 scsidir;
1664 u32 cmd_len;
1665 int my_idx;
1666 int ii;
1667
1668 hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata;
1669 target = SCpnt->device->id;
1670 lun = SCpnt->device->lun;
1671 SCpnt->scsi_done = done;
1672
1673 pTarget = hd->Targets[target];
1674
1675 dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n",
1676 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done));
1677
1678 if (hd->resetPending) {
1679 dtmprintk((MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n",
1680 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt));
1681 return SCSI_MLQUEUE_HOST_BUSY;
1682 }
1683
1684 /*
1685 * Put together a MPT SCSI request...
1686 */
1687 if ((mf = mpt_get_msg_frame(ScsiDoneCtx, hd->ioc)) == NULL) {
1688 dprintk((MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1689 hd->ioc->name));
1690 return SCSI_MLQUEUE_HOST_BUSY;
1691 }
1692
1693 pScsiReq = (SCSIIORequest_t *) mf;
1694
1695 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1696
1697 ADD_INDEX_LOG(my_idx);
1698
1699 /* BUG FIX! 19991030 -sralston
1700 * TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1701 * Seems we may receive a buffer (datalen>0) even when there
1702 * will be no data transfer! GRRRRR...
1703 */
1704 if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1705 datalen = SCpnt->request_bufflen;
1706 scsidir = MPI_SCSIIO_CONTROL_READ; /* DATA IN (host<--ioc<--dev) */
1707 } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1708 datalen = SCpnt->request_bufflen;
1709 scsidir = MPI_SCSIIO_CONTROL_WRITE; /* DATA OUT (host-->ioc-->dev) */
1710 } else {
1711 datalen = 0;
1712 scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1713 }
1714
1715 /* Default to untagged. Once a target structure has been allocated,
1716 * use the Inquiry data to determine if device supports tagged.
1717 */
1718 if ( pTarget
1719 && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
1720 && (SCpnt->device->tagged_supported)) {
1721 scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1722 } else {
1723 scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1724 }
1725
1726 /* Use the above information to set up the message frame
1727 */
1728 pScsiReq->TargetID = (u8) target;
1729 pScsiReq->Bus = (u8) SCpnt->device->channel;
1730 pScsiReq->ChainOffset = 0;
1731 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1732 pScsiReq->CDBLength = SCpnt->cmd_len;
1733 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1734 pScsiReq->Reserved = 0;
1735 pScsiReq->MsgFlags = mpt_msg_flags();
1736 pScsiReq->LUN[0] = 0;
1737 pScsiReq->LUN[1] = lun;
1738 pScsiReq->LUN[2] = 0;
1739 pScsiReq->LUN[3] = 0;
1740 pScsiReq->LUN[4] = 0;
1741 pScsiReq->LUN[5] = 0;
1742 pScsiReq->LUN[6] = 0;
1743 pScsiReq->LUN[7] = 0;
1744 pScsiReq->Control = cpu_to_le32(scsictl);
1745
1746 /*
1747 * Write SCSI CDB into the message
1748 */
1749 cmd_len = SCpnt->cmd_len;
1750 for (ii=0; ii < cmd_len; ii++)
1751 pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1752
1753 for (ii=cmd_len; ii < 16; ii++)
1754 pScsiReq->CDB[ii] = 0;
1755
1756 /* DataLength */
1757 pScsiReq->DataLength = cpu_to_le32(datalen);
1758
1759 /* SenseBuffer low address */
1760 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
1761 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
1762
1763 /* Now add the SG list
1764 * Always have a SGE even if null length.
1765 */
1766 if (datalen == 0) {
1767 /* Add a NULL SGE */
1768 mptscsih_add_sge((char *)&pScsiReq->SGL, MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1769 (dma_addr_t) -1);
1770 } else {
1771 /* Add a 32 or 64 bit SGE */
1772 if (mptscsih_AddSGE(hd->ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
1773 goto fail;
1774 }
1775
1776 hd->ScsiLookup[my_idx] = SCpnt;
1777 SCpnt->host_scribble = NULL;
1778
1779#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1780 if (hd->ioc->bus_type == SCSI) {
1781 int dvStatus = hd->ioc->spi_data.dvStatus[target];
1782 int issueCmd = 1;
1783
1784 if (dvStatus || hd->ioc->spi_data.forceDv) {
1785
1786 if ((dvStatus & MPT_SCSICFG_NEED_DV) ||
1787 (hd->ioc->spi_data.forceDv & MPT_SCSICFG_NEED_DV)) {
1788 unsigned long lflags;
1789 /* Schedule DV if necessary */
1790 spin_lock_irqsave(&dvtaskQ_lock, lflags);
1791 if (!dvtaskQ_active) {
1792 dvtaskQ_active = 1;
1793 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1794 INIT_WORK(&mptscsih_dvTask, mptscsih_domainValidation, (void *) hd);
1795
1796 schedule_work(&mptscsih_dvTask);
1797 } else {
1798 spin_unlock_irqrestore(&dvtaskQ_lock, lflags);
1799 }
1800 hd->ioc->spi_data.forceDv &= ~MPT_SCSICFG_NEED_DV;
1801 }
1802
1803 /* Trying to do DV to this target, extend timeout.
1804 * Wait to issue until flag is clear
1805 */
1806 if (dvStatus & MPT_SCSICFG_DV_PENDING) {
1807 mod_timer(&SCpnt->eh_timeout, jiffies + 40 * HZ);
1808 issueCmd = 0;
1809 }
1810
1811 /* Set the DV flags.
1812 */
1813 if (dvStatus & MPT_SCSICFG_DV_NOT_DONE)
1814 mptscsih_set_dvflags(hd, pScsiReq);
1815
1816 if (!issueCmd)
1817 goto fail;
1818 }
1819 }
1820#endif
1821
1822 mpt_put_msg_frame(ScsiDoneCtx, hd->ioc, mf);
1823 dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1824 hd->ioc->name, SCpnt, mf, my_idx));
1825 DBG_DUMP_REQUEST_FRAME(mf)
1826 return 0;
1827
1828 fail:
1829 mptscsih_freeChainBuffers(hd->ioc, my_idx);
1830 mpt_free_msg_frame(hd->ioc, mf);
1831 return SCSI_MLQUEUE_HOST_BUSY;
1832}
1833
1834/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1835/*
1836 * mptscsih_freeChainBuffers - Function to free chain buffers associated
1837 * with a SCSI IO request
1838 * @hd: Pointer to the MPT_SCSI_HOST instance
1839 * @req_idx: Index of the SCSI IO request frame.
1840 *
1841 * Called if SG chain buffer allocation fails and mptscsih callbacks.
1842 * No return.
1843 */
1844static void
1845mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1846{
1847 MPT_FRAME_HDR *chain;
1848 unsigned long flags;
1849 int chain_idx;
1850 int next;
1851
1852 /* Get the first chain index and reset
1853 * tracker state.
1854 */
1855 chain_idx = ioc->ReqToChain[req_idx];
1856 ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
1857
1858 while (chain_idx != MPT_HOST_NO_CHAIN) {
1859
1860 /* Save the next chain buffer index */
1861 next = ioc->ChainToChain[chain_idx];
1862
1863 /* Free this chain buffer and reset
1864 * tracker
1865 */
1866 ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
1867
1868 chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
1869 + (chain_idx * ioc->req_sz));
1870
1871 spin_lock_irqsave(&ioc->FreeQlock, flags);
1872 list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
1873 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1874
1875 dmfprintk((MYIOC_s_INFO_FMT "FreeChainBuffers (index %d)\n",
1876 ioc->name, chain_idx));
1877
1878 /* handle next */
1879 chain_idx = next;
1880 }
1881 return;
1882}
1883
1884/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1885/*
1886 * Reset Handling
1887 */
1888
1889/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1890/*
1891 * mptscsih_TMHandler - Generic handler for SCSI Task Management.
1892 * Fall through to mpt_HardResetHandler if: not operational, too many
1893 * failed TM requests or handshake failure.
1894 *
1895 * @ioc: Pointer to MPT_ADAPTER structure
1896 * @type: Task Management type
1897 * @target: Logical Target ID for reset (if appropriate)
1898 * @lun: Logical Unit for reset (if appropriate)
1899 * @ctx2abort: Context for the task to be aborted (if appropriate)
1900 *
1901 * Remark: Currently invoked from a non-interrupt thread (_bh).
1902 *
1903 * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
1904 * will be active.
1905 *
1906 * Returns 0 for SUCCESS or -1 if FAILED.
1907 */
1908static int
1909mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
1910{
1911 MPT_ADAPTER *ioc;
1912 int rc = -1;
1913 int doTask = 1;
1914 u32 ioc_raw_state;
1915 unsigned long flags;
1916
1917 /* If FW is being reloaded currently, return success to
1918 * the calling function.
1919 */
1920 if (hd == NULL)
1921 return 0;
1922
1923 ioc = hd->ioc;
1924 if (ioc == NULL) {
1925 printk(KERN_ERR MYNAM " TMHandler" " NULL ioc!\n");
1926 return FAILED;
1927 }
1928 dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
1929
1930 // SJR - CHECKME - Can we avoid this here?
1931 // (mpt_HardResetHandler has this check...)
1932 spin_lock_irqsave(&ioc->diagLock, flags);
1933 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) {
1934 spin_unlock_irqrestore(&ioc->diagLock, flags);
1935 return FAILED;
1936 }
1937 spin_unlock_irqrestore(&ioc->diagLock, flags);
1938
1939 /* Wait a fixed amount of time for the TM pending flag to be cleared.
1940 * If we time out and not bus reset, then we return a FAILED status to the caller.
1941 * The call to mptscsih_tm_pending_wait() will set the pending flag if we are
1942 * successful. Otherwise, reload the FW.
1943 */
1944 if (mptscsih_tm_pending_wait(hd) == FAILED) {
1945 if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1946 dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler abort: "
1947 "Timed out waiting for last TM (%d) to complete! \n",
1948 hd->ioc->name, hd->tmPending));
1949 return FAILED;
1950 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
1951 dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler target reset: "
1952 "Timed out waiting for last TM (%d) to complete! \n",
1953 hd->ioc->name, hd->tmPending));
1954 return FAILED;
1955 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
1956 dtmprintk((KERN_WARNING MYNAM ": %s: TMHandler bus reset: "
1957 "Timed out waiting for last TM (%d) to complete! \n",
1958 hd->ioc->name, hd->tmPending));
1959 if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS))
1960 return FAILED;
1961
1962 doTask = 0;
1963 }
1964 } else {
1965 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1966 hd->tmPending |= (1 << type);
1967 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1968 }
1969
1970 /* Is operational?
1971 */
1972 ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
1973
1974#ifdef MPT_DEBUG_RESET
1975 if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1976 printk(MYIOC_s_WARN_FMT
1977 "TM Handler: IOC Not operational(0x%x)!\n",
1978 hd->ioc->name, ioc_raw_state);
1979 }
1980#endif
1981
1982 if (doTask && ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL)
1983 && !(ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
1984
1985 /* Isse the Task Mgmt request.
1986 */
1987 if (hd->hard_resets < -1)
1988 hd->hard_resets++;
1989 rc = mptscsih_IssueTaskMgmt(hd, type, channel, target, lun, ctx2abort, timeout);
1990 if (rc) {
1991 printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name);
1992 } else {
1993 dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name));
1994 }
1995 }
1996
1997 /* Only fall through to the HRH if this is a bus reset
1998 */
1999 if ((type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && (rc ||
2000 ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) {
2001 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
2002 hd->ioc->name));
2003 rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
2004 }
2005
2006 dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
2007
2008 return rc;
2009}
2010
2011
2012/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2013/*
2014 * mptscsih_IssueTaskMgmt - Generic send Task Management function.
2015 * @hd: Pointer to MPT_SCSI_HOST structure
2016 * @type: Task Management type
2017 * @target: Logical Target ID for reset (if appropriate)
2018 * @lun: Logical Unit for reset (if appropriate)
2019 * @ctx2abort: Context for the task to be aborted (if appropriate)
2020 *
2021 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
2022 * or a non-interrupt thread. In the former, must not call schedule().
2023 *
2024 * Not all fields are meaningfull for all task types.
2025 *
2026 * Returns 0 for SUCCESS, -999 for "no msg frames",
2027 * else other non-zero value returned.
2028 */
2029static int
2030mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
2031{
2032 MPT_FRAME_HDR *mf;
2033 SCSITaskMgmt_t *pScsiTm;
2034 int ii;
2035 int retval;
2036
2037 /* Return Fail to calling function if no message frames available.
2038 */
2039 if ((mf = mpt_get_msg_frame(ScsiTaskCtx, hd->ioc)) == NULL) {
2040 dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n",
2041 hd->ioc->name));
2042 //return FAILED;
2043 return -999;
2044 }
2045 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n",
2046 hd->ioc->name, mf));
2047
2048 /* Format the Request
2049 */
2050 pScsiTm = (SCSITaskMgmt_t *) mf;
2051 pScsiTm->TargetID = target;
2052 pScsiTm->Bus = channel;
2053 pScsiTm->ChainOffset = 0;
2054 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
2055
2056 pScsiTm->Reserved = 0;
2057 pScsiTm->TaskType = type;
2058 pScsiTm->Reserved1 = 0;
2059 pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
2060 ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
2061
2062 for (ii= 0; ii < 8; ii++) {
2063 pScsiTm->LUN[ii] = 0;
2064 }
2065 pScsiTm->LUN[1] = lun;
2066
2067 for (ii=0; ii < 7; ii++)
2068 pScsiTm->Reserved2[ii] = 0;
2069
2070 pScsiTm->TaskMsgContext = ctx2abort;
2071
2072 dtmprintk((MYIOC_s_INFO_FMT
2073 "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
2074 hd->ioc->name, ctx2abort, type));
2075
2076 DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
2077
2078 if ((retval = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc,
2079 sizeof(SCSITaskMgmt_t), (u32*)pScsiTm,
2080 CAN_SLEEP)) != 0) {
2081 dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!"
2082 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
2083 hd->ioc, mf));
2084 mpt_free_msg_frame(hd->ioc, mf);
2085 return retval;
2086 }
2087
2088 if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) {
2089 dfailprintk((MYIOC_s_ERR_FMT "_wait_for_completion FAILED!"
2090 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
2091 hd->ioc, mf));
2092 mpt_free_msg_frame(hd->ioc, mf);
2093 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
2094 hd->ioc->name));
2095 retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
2096 }
2097
2098 return retval;
2099}
2100
2101/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2102/**
2103 * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
2104 * @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
2105 *
2106 * (linux scsi_host_template.eh_abort_handler routine)
2107 *
2108 * Returns SUCCESS or FAILED.
2109 */
2110static int
2111mptscsih_abort(struct scsi_cmnd * SCpnt)
2112{
2113 MPT_SCSI_HOST *hd;
2114 MPT_ADAPTER *ioc;
2115 MPT_FRAME_HDR *mf;
2116 u32 ctx2abort;
2117 int scpnt_idx;
2118 spinlock_t *host_lock = SCpnt->device->host->host_lock;
2119
2120 /* If we can't locate our host adapter structure, return FAILED status.
2121 */
2122 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) {
2123 SCpnt->result = DID_RESET << 16;
2124 SCpnt->scsi_done(SCpnt);
2125 dfailprintk((KERN_WARNING MYNAM ": mptscsih_abort: "
2126 "Can't locate host! (sc=%p)\n",
2127 SCpnt));
2128 return FAILED;
2129 }
2130
2131 ioc = hd->ioc;
2132 if (hd->resetPending)
2133 return FAILED;
2134
2135 printk(KERN_WARNING MYNAM ": %s: >> Attempting task abort! (sc=%p)\n",
2136 hd->ioc->name, SCpnt);
2137
2138 if (hd->timeouts < -1)
2139 hd->timeouts++;
2140
2141 /* Find this command
2142 */
2143 if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
2144 /* Cmd not found in ScsiLookup.
2145 * Do OS callback.
2146 */
2147 SCpnt->result = DID_RESET << 16;
2148 dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_abort: "
2149 "Command not in the active list! (sc=%p)\n",
2150 hd->ioc->name, SCpnt));
2151 return SUCCESS;
2152 }
2153
2154 /* Most important! Set TaskMsgContext to SCpnt's MsgContext!
2155 * (the IO to be ABORT'd)
2156 *
2157 * NOTE: Since we do not byteswap MsgContext, we do not
2158 * swap it here either. It is an opaque cookie to
2159 * the controller, so it does not matter. -DaveM
2160 */
2161 mf = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx);
2162 ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
2163
2164 hd->abortSCpnt = SCpnt;
2165
2166 spin_unlock_irq(host_lock);
2167 if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
2168 SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun,
2169 ctx2abort, 2 /* 2 second timeout */)
2170 < 0) {
2171
2172 /* The TM request failed and the subsequent FW-reload failed!
2173 * Fatal error case.
2174 */
2175 printk(MYIOC_s_WARN_FMT "Error issuing abort task! (sc=%p)\n",
2176 hd->ioc->name, SCpnt);
2177
2178 /* We must clear our pending flag before clearing our state.
2179 */
2180 hd->tmPending = 0;
2181 hd->tmState = TM_STATE_NONE;
2182
2183 spin_lock_irq(host_lock);
2184
2185 /* Unmap the DMA buffers, if any. */
2186 if (SCpnt->use_sg) {
2187 pci_unmap_sg(ioc->pcidev, (struct scatterlist *) SCpnt->request_buffer,
2188 SCpnt->use_sg, SCpnt->sc_data_direction);
2189 } else if (SCpnt->request_bufflen) {
2190 pci_unmap_single(ioc->pcidev, SCpnt->SCp.dma_handle,
2191 SCpnt->request_bufflen, SCpnt->sc_data_direction);
2192 }
2193 hd->ScsiLookup[scpnt_idx] = NULL;
2194 SCpnt->result = DID_RESET << 16;
2195 SCpnt->scsi_done(SCpnt); /* Issue the command callback */
2196 mptscsih_freeChainBuffers(ioc, scpnt_idx);
2197 mpt_free_msg_frame(ioc, mf);
2198 return FAILED;
2199 }
2200 spin_lock_irq(host_lock);
2201 return SUCCESS;
2202}
2203
2204/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2205/**
2206 * mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant
2207 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
2208 *
2209 * (linux scsi_host_template.eh_dev_reset_handler routine)
2210 *
2211 * Returns SUCCESS or FAILED.
2212 */
2213static int
2214mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
2215{
2216 MPT_SCSI_HOST *hd;
2217 spinlock_t *host_lock = SCpnt->device->host->host_lock;
2218
2219 /* If we can't locate our host adapter structure, return FAILED status.
2220 */
2221 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
2222 dtmprintk((KERN_WARNING MYNAM ": mptscsih_dev_reset: "
2223 "Can't locate host! (sc=%p)\n",
2224 SCpnt));
2225 return FAILED;
2226 }
2227
2228 if (hd->resetPending)
2229 return FAILED;
2230
2231 printk(KERN_WARNING MYNAM ": %s: >> Attempting target reset! (sc=%p)\n",
2232 hd->ioc->name, SCpnt);
2233
2234 spin_unlock_irq(host_lock);
2235 if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
2236 SCpnt->device->channel, SCpnt->device->id,
2237 0, 0, 5 /* 5 second timeout */)
2238 < 0){
2239 /* The TM request failed and the subsequent FW-reload failed!
2240 * Fatal error case.
2241 */
2242 printk(MYIOC_s_WARN_FMT "Error processing TaskMgmt request (sc=%p)\n",
2243 hd->ioc->name, SCpnt);
2244 hd->tmPending = 0;
2245 hd->tmState = TM_STATE_NONE;
2246 spin_lock_irq(host_lock);
2247 return FAILED;
2248 }
2249 spin_lock_irq(host_lock);
2250 return SUCCESS;
2251
2252}
2253
2254/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2255/**
2256 * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
2257 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
2258 *
2259 * (linux scsi_host_template.eh_bus_reset_handler routine)
2260 *
2261 * Returns SUCCESS or FAILED.
2262 */
2263static int
2264mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
2265{
2266 MPT_SCSI_HOST *hd;
2267 spinlock_t *host_lock = SCpnt->device->host->host_lock;
2268
2269 /* If we can't locate our host adapter structure, return FAILED status.
2270 */
2271 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
2272 dtmprintk((KERN_WARNING MYNAM ": mptscsih_bus_reset: "
2273 "Can't locate host! (sc=%p)\n",
2274 SCpnt ) );
2275 return FAILED;
2276 }
2277
2278 printk(KERN_WARNING MYNAM ": %s: >> Attempting bus reset! (sc=%p)\n",
2279 hd->ioc->name, SCpnt);
2280
2281 if (hd->timeouts < -1)
2282 hd->timeouts++;
2283
2284 /* We are now ready to execute the task management request. */
2285 spin_unlock_irq(host_lock);
2286 if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
2287 SCpnt->device->channel, 0, 0, 0, 5 /* 5 second timeout */)
2288 < 0){
2289
2290 /* The TM request failed and the subsequent FW-reload failed!
2291 * Fatal error case.
2292 */
2293 printk(MYIOC_s_WARN_FMT
2294 "Error processing TaskMgmt request (sc=%p)\n",
2295 hd->ioc->name, SCpnt);
2296 hd->tmPending = 0;
2297 hd->tmState = TM_STATE_NONE;
2298 spin_lock_irq(host_lock);
2299 return FAILED;
2300 }
2301 spin_lock_irq(host_lock);
2302 return SUCCESS;
2303}
2304
2305/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2306/**
2307 * mptscsih_host_reset - Perform a SCSI host adapter RESET!
2308 * new_eh variant
2309 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
2310 *
2311 * (linux scsi_host_template.eh_host_reset_handler routine)
2312 *
2313 * Returns SUCCESS or FAILED.
2314 */
2315static int
2316mptscsih_host_reset(struct scsi_cmnd *SCpnt)
2317{
2318 MPT_SCSI_HOST * hd;
2319 int status = SUCCESS;
2320 spinlock_t *host_lock = SCpnt->device->host->host_lock;
2321
2322 /* If we can't locate the host to reset, then we failed. */
2323 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
2324 dtmprintk( ( KERN_WARNING MYNAM ": mptscsih_host_reset: "
2325 "Can't locate host! (sc=%p)\n",
2326 SCpnt ) );
2327 return FAILED;
2328 }
2329
2330 printk(KERN_WARNING MYNAM ": %s: >> Attempting host reset! (sc=%p)\n",
2331 hd->ioc->name, SCpnt);
2332
2333 /* If our attempts to reset the host failed, then return a failed
2334 * status. The host will be taken off line by the SCSI mid-layer.
2335 */
2336 spin_unlock_irq(host_lock);
2337 if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){
2338 status = FAILED;
2339 } else {
2340 /* Make sure TM pending is cleared and TM state is set to
2341 * NONE.
2342 */
2343 hd->tmPending = 0;
2344 hd->tmState = TM_STATE_NONE;
2345 }
2346 spin_lock_irq(host_lock);
2347
2348
2349 dtmprintk( ( KERN_WARNING MYNAM ": mptscsih_host_reset: "
2350 "Status = %s\n",
2351 (status == SUCCESS) ? "SUCCESS" : "FAILED" ) );
2352
2353 return status;
2354}
2355
2356/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2357/**
2358 * mptscsih_tm_pending_wait - wait for pending task management request to
2359 * complete.
2360 * @hd: Pointer to MPT host structure.
2361 *
2362 * Returns {SUCCESS,FAILED}.
2363 */
2364static int
2365mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
2366{
2367 unsigned long flags;
2368 int loop_count = 4 * 10; /* Wait 10 seconds */
2369 int status = FAILED;
2370
2371 do {
2372 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
2373 if (hd->tmState == TM_STATE_NONE) {
2374 hd->tmState = TM_STATE_IN_PROGRESS;
2375 hd->tmPending = 1;
2376 status = SUCCESS;
2377 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2378 break;
2379 }
2380 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2381 msleep(250);
2382 } while (--loop_count);
2383
2384 return status;
2385}
2386
2387/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2388/**
2389 * mptscsih_tm_wait_for_completion - wait for completion of TM task
2390 * @hd: Pointer to MPT host structure.
2391 *
2392 * Returns {SUCCESS,FAILED}.
2393 */
2394static int
2395mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
2396{
2397 unsigned long flags;
2398 int loop_count = 4 * timeout;
2399 int status = FAILED;
2400
2401 do {
2402 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
2403 if(hd->tmPending == 0) {
2404 status = SUCCESS;
2405 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2406 break;
2407 }
2408 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
2409 msleep_interruptible(250);
2410 } while (--loop_count);
2411
2412 return status;
2413}
2414
2415/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2416/**
2417 * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2418 * @ioc: Pointer to MPT_ADAPTER structure
2419 * @mf: Pointer to SCSI task mgmt request frame
2420 * @mr: Pointer to SCSI task mgmt reply frame
2421 *
2422 * This routine is called from mptbase.c::mpt_interrupt() at the completion
2423 * of any SCSI task management request.
2424 * This routine is registered with the MPT (base) driver at driver
2425 * load/init time via the mpt_register() API call.
2426 *
2427 * Returns 1 indicating alloc'd request frame ptr should be freed.
2428 */
2429static int
2430mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2431{
2432 SCSITaskMgmtReply_t *pScsiTmReply;
2433 SCSITaskMgmt_t *pScsiTmReq;
2434 MPT_SCSI_HOST *hd;
2435 unsigned long flags;
2436 u16 iocstatus;
2437 u8 tmType;
2438
2439 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
2440 ioc->name, mf, mr));
2441 if (ioc->sh) {
2442 /* Depending on the thread, a timer is activated for
2443 * the TM request. Delete this timer on completion of TM.
2444 * Decrement count of outstanding TM requests.
2445 */
2446 hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
2447 } else {
2448 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n",
2449 ioc->name));
2450 return 1;
2451 }
2452
2453 if (mr == NULL) {
2454 dtmprintk((MYIOC_s_WARN_FMT "ERROR! TaskMgmt Reply: NULL Request %p\n",
2455 ioc->name, mf));
2456 return 1;
2457 } else {
2458 pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
2459 pScsiTmReq = (SCSITaskMgmt_t*)mf;
2460
2461 /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
2462 tmType = pScsiTmReq->TaskType;
2463
2464 dtmprintk((MYIOC_s_WARN_FMT " TaskType = %d, TerminationCount=%d\n",
2465 ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount)));
2466 DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
2467
2468 iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2469 dtmprintk((MYIOC_s_WARN_FMT " SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",
2470 ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo)));
2471 /* Error? (anything non-zero?) */
2472 if (iocstatus) {
2473
2474 /* clear flags and continue.
2475 */
2476 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
2477 hd->abortSCpnt = NULL;
2478
2479 /* If an internal command is present
2480 * or the TM failed - reload the FW.
2481 * FC FW may respond FAILED to an ABORT
2482 */
2483 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
2484 if ((hd->cmdPtr) ||
2485 (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED)) {
2486 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {
2487 printk((KERN_WARNING
2488 " Firmware Reload FAILED!!\n"));
2489 }
2490 }
2491 }
2492 } else {
2493 dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
2494
2495 hd->abortSCpnt = NULL;
2496
2497 }
2498 }
2499
2500 spin_lock_irqsave(&ioc->FreeQlock, flags);
2501 hd->tmPending = 0;
2502 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2503 hd->tmState = TM_STATE_NONE;
2504
2505 return 1;
2506}
2507
2508/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2509/*
2510 * This is anyones guess quite frankly.
2511 */
2512static int
2513mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2514 sector_t capacity, int geom[])
2515{
2516 int heads;
2517 int sectors;
2518 sector_t cylinders;
2519 ulong dummy;
2520
2521 heads = 64;
2522 sectors = 32;
2523
2524 dummy = heads * sectors;
2525 cylinders = capacity;
2526 sector_div(cylinders,dummy);
2527
2528 /*
2529 * Handle extended translation size for logical drives
2530 * > 1Gb
2531 */
2532 if ((ulong)capacity >= 0x200000) {
2533 heads = 255;
2534 sectors = 63;
2535 dummy = heads * sectors;
2536 cylinders = capacity;
2537 sector_div(cylinders,dummy);
2538 }
2539
2540 /* return result */
2541 geom[0] = heads;
2542 geom[1] = sectors;
2543 geom[2] = cylinders;
2544
2545 dprintk((KERN_NOTICE
2546 ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
2547 sdev->id, sdev->lun,sdev->channel,(int)cylinders,heads,sectors));
2548
2549 return 0;
2550}
2551
2552/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2553/*
2554 * OS entry point to allow host driver to alloc memory
2555 * for each scsi device. Called once per device the bus scan.
2556 * Return non-zero if allocation fails.
2557 * Init memory once per id (not LUN).
2558 */
2559static int
2560mptscsih_slave_alloc(struct scsi_device *device)
2561{
2562 struct Scsi_Host *host = device->host;
2563 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2564 VirtDevice *vdev;
2565 uint target = device->id;
2566
2567 if (hd == NULL)
2568 return -ENODEV;
2569
2570 if ((vdev = hd->Targets[target]) != NULL)
2571 goto out;
2572
2573 vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
2574 if (!vdev) {
2575 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
2576 hd->ioc->name, sizeof(VirtDevice));
2577 return -ENOMEM;
2578 }
2579
2580 memset(vdev, 0, sizeof(VirtDevice));
2581 vdev->tflags = MPT_TARGET_FLAGS_Q_YES;
2582 vdev->ioc_id = hd->ioc->id;
2583 vdev->target_id = device->id;
2584 vdev->bus_id = device->channel;
2585 vdev->raidVolume = 0;
2586 hd->Targets[device->id] = vdev;
2587 if (hd->ioc->bus_type == SCSI) {
2588 if (hd->ioc->spi_data.isRaid & (1 << device->id)) {
2589 vdev->raidVolume = 1;
2590 ddvtprintk((KERN_INFO
2591 "RAID Volume @ id %d\n", device->id));
2592 }
2593 } else {
2594 vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2595 }
2596
2597 out:
2598 vdev->num_luns++;
2599 return 0;
2600}
2601
2602static int mptscsih_is_raid_volume(MPT_SCSI_HOST *hd, uint id)
2603{
2604 int i;
2605
2606 if (!hd->ioc->spi_data.isRaid || !hd->ioc->spi_data.pIocPg3)
2607 return 0;
2608
2609 for (i = 0; i < hd->ioc->spi_data.pIocPg3->NumPhysDisks; i++) {
2610 if (id == hd->ioc->spi_data.pIocPg3->PhysDisk[i].PhysDiskID)
2611 return 1;
2612 }
2613
2614 return 0;
2615}
2616
2617/*
2618 * OS entry point to allow for host driver to free allocated memory
2619 * Called if no device present or device being unloaded
2620 */
2621static void
2622mptscsih_slave_destroy(struct scsi_device *device)
2623{
2624 struct Scsi_Host *host = device->host;
2625 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2626 VirtDevice *vdev;
2627 uint target = device->id;
2628 uint lun = device->lun;
2629
2630 if (hd == NULL)
2631 return;
2632
2633 mptscsih_search_running_cmds(hd, target, lun);
2634
2635 vdev = hd->Targets[target];
2636 vdev->luns[0] &= ~(1 << lun);
2637 if (--vdev->num_luns)
2638 return;
2639
2640 kfree(hd->Targets[target]);
2641 hd->Targets[target] = NULL;
2642
2643 if (hd->ioc->bus_type == SCSI) {
2644 if (mptscsih_is_raid_volume(hd, target)) {
2645 hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
2646 } else {
2647 hd->ioc->spi_data.dvStatus[target] =
2648 MPT_SCSICFG_NEGOTIATE;
2649
2650 if (!hd->negoNvram) {
2651 hd->ioc->spi_data.dvStatus[target] |=
2652 MPT_SCSICFG_DV_NOT_DONE;
2653 }
2654 }
2655 }
2656}
2657
2658static void
2659mptscsih_set_queue_depth(struct scsi_device *device, MPT_SCSI_HOST *hd,
2660 VirtDevice *pTarget, int qdepth)
2661{
2662 int max_depth;
2663 int tagged;
2664
2665 if (hd->ioc->bus_type == SCSI) {
2666 if (pTarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
2667 if (!(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2668 max_depth = 1;
2669 else if (((pTarget->inq_data[0] & 0x1f) == 0x00) &&
2670 (pTarget->minSyncFactor <= MPT_ULTRA160 ))
2671 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2672 else
2673 max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2674 } else {
2675 /* error case - No Inq. Data */
2676 max_depth = 1;
2677 }
2678 } else
2679 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2680
2681 if (qdepth > max_depth)
2682 qdepth = max_depth;
2683 if (qdepth == 1)
2684 tagged = 0;
2685 else
2686 tagged = MSG_SIMPLE_TAG;
2687
2688 scsi_adjust_queue_depth(device, tagged, qdepth);
2689}
2690
2691
2692/*
2693 * OS entry point to adjust the queue_depths on a per-device basis.
2694 * Called once per device the bus scan. Use it to force the queue_depth
2695 * member to 1 if a device does not support Q tags.
2696 * Return non-zero if fails.
2697 */
2698static int
2699mptscsih_slave_configure(struct scsi_device *device)
2700{
2701 struct Scsi_Host *sh = device->host;
2702 VirtDevice *pTarget;
2703 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata;
2704
2705 if ((hd == NULL) || (hd->Targets == NULL)) {
2706 return 0;
2707 }
2708
2709 dsprintk((MYIOC_s_INFO_FMT
2710 "device @ %p, id=%d, LUN=%d, channel=%d\n",
2711 hd->ioc->name, device, device->id, device->lun, device->channel));
2712 dsprintk((MYIOC_s_INFO_FMT
2713 "sdtr %d wdtr %d ppr %d inq length=%d\n",
2714 hd->ioc->name, device->sdtr, device->wdtr,
2715 device->ppr, device->inquiry_len));
2716
2717 if (device->id > sh->max_id) {
2718 /* error case, should never happen */
2719 scsi_adjust_queue_depth(device, 0, 1);
2720 goto slave_configure_exit;
2721 }
2722
2723 pTarget = hd->Targets[device->id];
2724
2725 if (pTarget == NULL) {
2726 /* Driver doesn't know about this device.
2727 * Kernel may generate a "Dummy Lun 0" which
2728 * may become a real Lun if a
2729 * "scsi add-single-device" command is executed
2730 * while the driver is active (hot-plug a
2731 * device). LSI Raid controllers need
2732 * queue_depth set to DEV_HIGH for this reason.
2733 */
2734 scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
2735 MPT_SCSI_CMD_PER_DEV_HIGH);
2736 goto slave_configure_exit;
2737 }
2738
2739 mptscsih_initTarget(hd, device->channel, device->id, device->lun,
2740 device->inquiry, device->inquiry_len );
2741 mptscsih_set_queue_depth(device, hd, pTarget, MPT_SCSI_CMD_PER_DEV_HIGH);
2742
2743 dsprintk((MYIOC_s_INFO_FMT
2744 "Queue depth=%d, tflags=%x\n",
2745 hd->ioc->name, device->queue_depth, pTarget->tflags));
2746
2747 dsprintk((MYIOC_s_INFO_FMT
2748 "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2749 hd->ioc->name, pTarget->negoFlags, pTarget->maxOffset, pTarget->minSyncFactor));
2750
2751slave_configure_exit:
2752
2753 dsprintk((MYIOC_s_INFO_FMT
2754 "tagged %d, simple %d, ordered %d\n",
2755 hd->ioc->name,device->tagged_supported, device->simple_tags,
2756 device->ordered_tags));
2757
2758 return 0;
2759}
2760
2761static ssize_t
2762mptscsih_store_queue_depth(struct device *dev, const char *buf, size_t count)
2763{
2764 int depth;
2765 struct scsi_device *sdev = to_scsi_device(dev);
2766 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) sdev->host->hostdata;
2767 VirtDevice *pTarget;
2768
2769 depth = simple_strtoul(buf, NULL, 0);
2770 if (depth == 0)
2771 return -EINVAL;
2772 pTarget = hd->Targets[sdev->id];
2773 if (pTarget == NULL)
2774 return -EINVAL;
2775 mptscsih_set_queue_depth(sdev, (MPT_SCSI_HOST *) sdev->host->hostdata,
2776 pTarget, depth);
2777 return count;
2778}
2779
2780/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2781/*
2782 * Private routines...
2783 */
2784
2785/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2786/* Utility function to copy sense data from the scsi_cmnd buffer
2787 * to the FC and SCSI target structures.
2788 *
2789 */
2790static void
2791copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2792{
2793 VirtDevice *target;
2794 SCSIIORequest_t *pReq;
2795 u32 sense_count = le32_to_cpu(pScsiReply->SenseCount);
2796 int index;
2797
2798 /* Get target structure
2799 */
2800 pReq = (SCSIIORequest_t *) mf;
2801 index = (int) pReq->TargetID;
2802 target = hd->Targets[index];
2803
2804 if (sense_count) {
2805 u8 *sense_data;
2806 int req_index;
2807
2808 /* Copy the sense received into the scsi command block. */
2809 req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2810 sense_data = ((u8 *)hd->ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2811 memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
2812
2813 /* Log SMART data (asc = 0x5D, non-IM case only) if required.
2814 */
2815 if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2816 if ((sense_data[12] == 0x5D) && (target->raidVolume == 0)) {
2817 int idx;
2818 MPT_ADAPTER *ioc = hd->ioc;
2819
2820 idx = ioc->eventContext % ioc->eventLogSize;
2821 ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2822 ioc->events[idx].eventContext = ioc->eventContext;
2823
2824 ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
2825 (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
2826 (pReq->Bus << 8) || pReq->TargetID;
2827
2828 ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
2829
2830 ioc->eventContext++;
2831 }
2832 }
2833 } else {
2834 dprintk((MYIOC_s_INFO_FMT "Hmmm... SenseData len=0! (?)\n",
2835 hd->ioc->name));
2836 }
2837}
2838
2839static u32
2840SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
2841{
2842 MPT_SCSI_HOST *hd;
2843 int i;
2844
2845 hd = (MPT_SCSI_HOST *) sc->device->host->hostdata;
2846
2847 for (i = 0; i < hd->ioc->req_depth; i++) {
2848 if (hd->ScsiLookup[i] == sc) {
2849 return i;
2850 }
2851 }
2852
2853 return -1;
2854}
2855
2856/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2857static int
2858mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2859{
2860 MPT_SCSI_HOST *hd;
2861 unsigned long flags;
2862
2863 dtmprintk((KERN_WARNING MYNAM
2864 ": IOC %s_reset routed to SCSI host driver!\n",
2865 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
2866 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
2867
2868 /* If a FW reload request arrives after base installed but
2869 * before all scsi hosts have been attached, then an alt_ioc
2870 * may have a NULL sh pointer.
2871 */
2872 if ((ioc->sh == NULL) || (ioc->sh->hostdata == NULL))
2873 return 0;
2874 else
2875 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2876
2877 if (reset_phase == MPT_IOC_SETUP_RESET) {
2878 dtmprintk((MYIOC_s_WARN_FMT "Setup-Diag Reset\n", ioc->name));
2879
2880 /* Clean Up:
2881 * 1. Set Hard Reset Pending Flag
2882 * All new commands go to doneQ
2883 */
2884 hd->resetPending = 1;
2885
2886 } else if (reset_phase == MPT_IOC_PRE_RESET) {
2887 dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name));
2888
2889 /* 2. Flush running commands
2890 * Clean ScsiLookup (and associated memory)
2891 * AND clean mytaskQ
2892 */
2893
2894 /* 2b. Reply to OS all known outstanding I/O commands.
2895 */
2896 mptscsih_flush_running_cmds(hd);
2897
2898 /* 2c. If there was an internal command that
2899 * has not completed, configuration or io request,
2900 * free these resources.
2901 */
2902 if (hd->cmdPtr) {
2903 del_timer(&hd->timer);
2904 mpt_free_msg_frame(ioc, hd->cmdPtr);
2905 }
2906
2907 dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name));
2908
2909 } else {
2910 dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name));
2911
2912 /* Once a FW reload begins, all new OS commands are
2913 * redirected to the doneQ w/ a reset status.
2914 * Init all control structures.
2915 */
2916
2917 /* ScsiLookup initialization
2918 */
2919 {
2920 int ii;
2921 for (ii=0; ii < hd->ioc->req_depth; ii++)
2922 hd->ScsiLookup[ii] = NULL;
2923 }
2924
2925 /* 2. Chain Buffer initialization
2926 */
2927
2928 /* 4. Renegotiate to all devices, if SCSI
2929 */
2930 if (ioc->bus_type == SCSI) {
2931 dnegoprintk(("writeSDP1: ALL_IDS USE_NVRAM\n"));
2932 mptscsih_writeSDP1(hd, 0, 0, MPT_SCSICFG_ALL_IDS | MPT_SCSICFG_USE_NVRAM);
2933 }
2934
2935 /* 5. Enable new commands to be posted
2936 */
2937 spin_lock_irqsave(&ioc->FreeQlock, flags);
2938 hd->tmPending = 0;
2939 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2940 hd->resetPending = 0;
2941 hd->tmState = TM_STATE_NONE;
2942
2943 /* 6. If there was an internal command,
2944 * wake this process up.
2945 */
2946 if (hd->cmdPtr) {
2947 /*
2948 * Wake up the original calling thread
2949 */
2950 hd->pLocal = &hd->localReply;
2951 hd->pLocal->completion = MPT_SCANDV_DID_RESET;
2952 scandv_wait_done = 1;
2953 wake_up(&scandv_waitq);
2954 hd->cmdPtr = NULL;
2955 }
2956
2957 /* 7. Set flag to force DV and re-read IOC Page 3
2958 */
2959 if (ioc->bus_type == SCSI) {
2960 ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
2961 ddvtprintk(("Set reload IOC Pg3 Flag\n"));
2962 }
2963
2964 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
2965
2966 }
2967
2968 return 1; /* currently means nothing really */
2969}
2970
2971/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2972static int
2973mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2974{
2975 MPT_SCSI_HOST *hd;
2976 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2977
2978 devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
2979 ioc->name, event));
2980
2981 switch (event) {
2982 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
2983 /* FIXME! */
2984 break;
2985 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
2986 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
2987 hd = NULL;
2988 if (ioc->sh) {
2989 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2990 if (hd && (ioc->bus_type == SCSI) && (hd->soft_resets < -1))
2991 hd->soft_resets++;
2992 }
2993 break;
2994 case MPI_EVENT_LOGOUT: /* 09 */
2995 /* FIXME! */
2996 break;
2997
2998 /*
2999 * CHECKME! Don't think we need to do
3000 * anything for these, but...
3001 */
3002 case MPI_EVENT_RESCAN: /* 06 */
3003 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
3004 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
3005 /*
3006 * CHECKME! Falling thru...
3007 */
3008 break;
3009
3010 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
3011#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3012 /* negoNvram set to 0 if DV enabled and to USE_NVRAM if
3013 * if DV disabled. Need to check for target mode.
3014 */
3015 hd = NULL;
3016 if (ioc->sh)
3017 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
3018
3019 if (hd && (ioc->bus_type == SCSI) && (hd->negoNvram == 0)) {
3020 ScsiCfgData *pSpi;
3021 Ioc3PhysDisk_t *pPDisk;
3022 int numPDisk;
3023 u8 reason;
3024 u8 physDiskNum;
3025
3026 reason = (le32_to_cpu(pEvReply->Data[0]) & 0x00FF0000) >> 16;
3027 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
3028 /* New or replaced disk.
3029 * Set DV flag and schedule DV.
3030 */
3031 pSpi = &ioc->spi_data;
3032 physDiskNum = (le32_to_cpu(pEvReply->Data[0]) & 0xFF000000) >> 24;
3033 ddvtprintk(("DV requested for phys disk id %d\n", physDiskNum));
3034 if (pSpi->pIocPg3) {
3035 pPDisk = pSpi->pIocPg3->PhysDisk;
3036 numPDisk =pSpi->pIocPg3->NumPhysDisks;
3037
3038 while (numPDisk) {
3039 if (physDiskNum == pPDisk->PhysDiskNum) {
3040 pSpi->dvStatus[pPDisk->PhysDiskID] = (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
3041 pSpi->forceDv = MPT_SCSICFG_NEED_DV;
3042 ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
3043 break;
3044 }
3045 pPDisk++;
3046 numPDisk--;
3047 }
3048
3049 if (numPDisk == 0) {
3050 /* The physical disk that needs DV was not found
3051 * in the stored IOC Page 3. The driver must reload
3052 * this page. DV routine will set the NEED_DV flag for
3053 * all phys disks that have DV_NOT_DONE set.
3054 */
3055 pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
3056 ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n", physDiskNum));
3057 }
3058 }
3059 }
3060 }
3061#endif
3062
3063#if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
3064 printk("Raid Event RF: ");
3065 {
3066 u32 *m = (u32 *)pEvReply;
3067 int ii;
3068 int n = (int)pEvReply->MsgLength;
3069 for (ii=6; ii < n; ii++)
3070 printk(" %08x", le32_to_cpu(m[ii]));
3071 printk("\n");
3072 }
3073#endif
3074 break;
3075
3076 case MPI_EVENT_NONE: /* 00 */
3077 case MPI_EVENT_LOG_DATA: /* 01 */
3078 case MPI_EVENT_STATE_CHANGE: /* 02 */
3079 case MPI_EVENT_EVENT_CHANGE: /* 0A */
3080 default:
3081 dprintk((KERN_INFO " Ignoring event (=%02Xh)\n", event));
3082 break;
3083 }
3084
3085 return 1; /* currently means nothing really */
3086}
3087
3088static struct device_attribute mptscsih_queue_depth_attr = {
3089 .attr = {
3090 .name = "queue_depth",
3091 .mode = S_IWUSR,
3092 },
3093 .store = mptscsih_store_queue_depth,
3094};
3095
3096static struct device_attribute *mptscsih_dev_attrs[] = {
3097 &mptscsih_queue_depth_attr,
3098 NULL,
3099};
3100
3101static struct scsi_host_template driver_template = {
3102 .proc_name = "mptscsih",
3103 .proc_info = mptscsih_proc_info,
3104 .name = "MPT SCSI Host",
3105 .info = mptscsih_info,
3106 .queuecommand = mptscsih_qcmd,
3107 .slave_alloc = mptscsih_slave_alloc,
3108 .slave_configure = mptscsih_slave_configure,
3109 .slave_destroy = mptscsih_slave_destroy,
3110 .eh_abort_handler = mptscsih_abort,
3111 .eh_device_reset_handler = mptscsih_dev_reset,
3112 .eh_bus_reset_handler = mptscsih_bus_reset,
3113 .eh_host_reset_handler = mptscsih_host_reset,
3114 .bios_param = mptscsih_bios_param,
3115 .can_queue = MPT_SCSI_CAN_QUEUE,
3116 .this_id = -1,
3117 .sg_tablesize = MPT_SCSI_SG_DEPTH,
3118 .max_sectors = 8192,
3119 .cmd_per_lun = 7,
3120 .use_clustering = ENABLE_CLUSTERING,
3121 .sdev_attrs = mptscsih_dev_attrs,
3122};
3123
3124/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3125/*
3126 * mptscsih_initTarget - Target, LUN alloc/free functionality.
3127 * @hd: Pointer to MPT_SCSI_HOST structure
3128 * @bus_id: Bus number (?)
3129 * @target_id: SCSI target id
3130 * @lun: SCSI LUN id
3131 * @data: Pointer to data
3132 * @dlen: Number of INQUIRY bytes
3133 *
3134 * NOTE: It's only SAFE to call this routine if data points to
3135 * sane & valid STANDARD INQUIRY data!
3136 *
3137 * Allocate and initialize memory for this target.
3138 * Save inquiry data.
3139 *
3140 */
3141static void
3142mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen)
3143{
3144 int indexed_lun, lun_index;
3145 VirtDevice *vdev;
3146 ScsiCfgData *pSpi;
3147 char data_56;
3148
3149 dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
3150 hd->ioc->name, bus_id, target_id, lun, hd));
3151
3152 /*
3153 * If the peripheral qualifier filter is enabled then if the target reports a 0x1
3154 * (i.e. The targer is capable of supporting the specified peripheral device type
3155 * on this logical unit; however, the physical device is not currently connected
3156 * to this logical unit) it will be converted to a 0x3 (i.e. The target is not
3157 * capable of supporting a physical device on this logical unit). This is to work
3158 * around a bug in th emid-layer in some distributions in which the mid-layer will
3159 * continue to try to communicate to the LUN and evntually create a dummy LUN.
3160 */
3161 if (mpt_pq_filter && dlen && (data[0] & 0xE0))
3162 data[0] |= 0x40;
3163
3164 /* Is LUN supported? If so, upper 2 bits will be 0
3165 * in first byte of inquiry data.
3166 */
3167 if (data[0] & 0xe0)
3168 return;
3169
3170 if ((vdev = hd->Targets[target_id]) == NULL) {
3171 return;
3172 }
3173
3174 lun_index = (lun >> 5); /* 32 luns per lun_index */
3175 indexed_lun = (lun % 32);
3176 vdev->luns[lun_index] |= (1 << indexed_lun);
3177
3178 if (hd->ioc->bus_type == SCSI) {
3179 if ((data[0] == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
3180 /* Treat all Processors as SAF-TE if
3181 * command line option is set */
3182 vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
3183 mptscsih_writeIOCPage4(hd, target_id, bus_id);
3184 }else if ((data[0] == TYPE_PROCESSOR) &&
3185 !(vdev->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
3186 if ( dlen > 49 ) {
3187 vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
3188 if ( data[44] == 'S' &&
3189 data[45] == 'A' &&
3190 data[46] == 'F' &&
3191 data[47] == '-' &&
3192 data[48] == 'T' &&
3193 data[49] == 'E' ) {
3194 vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
3195 mptscsih_writeIOCPage4(hd, target_id, bus_id);
3196 }
3197 }
3198 }
3199 if (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
3200 if ( dlen > 8 ) {
3201 memcpy (vdev->inq_data, data, 8);
3202 } else {
3203 memcpy (vdev->inq_data, data, dlen);
3204 }
3205
3206 /* If have not done DV, set the DV flag.
3207 */
3208 pSpi = &hd->ioc->spi_data;
3209 if ((data[0] == TYPE_TAPE) || (data[0] == TYPE_PROCESSOR)) {
3210 if (pSpi->dvStatus[target_id] & MPT_SCSICFG_DV_NOT_DONE)
3211 pSpi->dvStatus[target_id] |= MPT_SCSICFG_NEED_DV;
3212 }
3213
3214 vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
3215
3216
3217 data_56 = 0x0F; /* Default to full capabilities if Inq data length is < 57 */
3218 if (dlen > 56) {
3219 if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
3220 /* Update the target capabilities
3221 */
3222 data_56 = data[56];
3223 vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
3224 }
3225 }
3226 mptscsih_setTargetNegoParms(hd, vdev, data_56);
3227 } else {
3228 /* Initial Inquiry may not request enough data bytes to
3229 * obtain byte 57. DV will; if target doesn't return
3230 * at least 57 bytes, data[56] will be zero. */
3231 if (dlen > 56) {
3232 if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
3233 /* Update the target capabilities
3234 */
3235 data_56 = data[56];
3236 vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
3237 mptscsih_setTargetNegoParms(hd, vdev, data_56);
3238 }
3239 }
3240 }
3241 }
3242}
3243
3244/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3245/*
3246 * Update the target negotiation parameters based on the
3247 * the Inquiry data, adapter capabilities, and NVRAM settings.
3248 *
3249 */
3250static void
3251mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
3252{
3253 ScsiCfgData *pspi_data = &hd->ioc->spi_data;
3254 int id = (int) target->target_id;
3255 int nvram;
3256 VirtDevice *vdev;
3257 int ii;
3258 u8 width = MPT_NARROW;
3259 u8 factor = MPT_ASYNC;
3260 u8 offset = 0;
3261 u8 version, nfactor;
3262 u8 noQas = 1;
3263
3264 target->negoFlags = pspi_data->noQas;
3265
3266 /* noQas == 0 => device supports QAS. Need byte 56 of Inq to determine
3267 * support. If available, default QAS to off and allow enabling.
3268 * If not available, default QAS to on, turn off for non-disks.
3269 */
3270
3271 /* Set flags based on Inquiry data
3272 */
3273 version = target->inq_data[2] & 0x07;
3274 if (version < 2) {
3275 width = 0;
3276 factor = MPT_ULTRA2;
3277 offset = pspi_data->maxSyncOffset;
3278 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
3279 } else {
3280 if (target->inq_data[7] & 0x20) {
3281 width = 1;
3282 }
3283
3284 if (target->inq_data[7] & 0x10) {
3285 factor = pspi_data->minSyncFactor;
3286 if (target->tflags & MPT_TARGET_FLAGS_VALID_56) {
3287 /* bits 2 & 3 show Clocking support */
3288 if ((byte56 & 0x0C) == 0)
3289 factor = MPT_ULTRA2;
3290 else {
3291 if ((byte56 & 0x03) == 0)
3292 factor = MPT_ULTRA160;
3293 else {
3294 factor = MPT_ULTRA320;
3295 if (byte56 & 0x02)
3296 {
3297 ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", byte56, id));
3298 noQas = 0;
3299 }
3300 if (target->inq_data[0] == TYPE_TAPE) {
3301 if (byte56 & 0x01)
3302 target->negoFlags |= MPT_TAPE_NEGO_IDP;
3303 }
3304 }
3305 }
3306 } else {
3307 ddvtprintk((KERN_INFO "Enabling QAS on id=%d due to ~TARGET_FLAGS_VALID_56!\n", id));
3308 noQas = 0;
3309 }
3310
3311 offset = pspi_data->maxSyncOffset;
3312
3313 /* If RAID, never disable QAS
3314 * else if non RAID, do not disable
3315 * QAS if bit 1 is set
3316 * bit 1 QAS support, non-raid only
3317 * bit 0 IU support
3318 */
3319 if (target->raidVolume == 1) {
3320 noQas = 0;
3321 }
3322 } else {
3323 factor = MPT_ASYNC;
3324 offset = 0;
3325 }
3326 }
3327
3328 if ( (target->inq_data[7] & 0x02) == 0) {
3329 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
3330 }
3331
3332 /* Update tflags based on NVRAM settings. (SCSI only)
3333 */
3334 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
3335 nvram = pspi_data->nvram[id];
3336 nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
3337
3338 if (width)
3339 width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
3340
3341 if (offset > 0) {
3342 /* Ensure factor is set to the
3343 * maximum of: adapter, nvram, inquiry
3344 */
3345 if (nfactor) {
3346 if (nfactor < pspi_data->minSyncFactor )
3347 nfactor = pspi_data->minSyncFactor;
3348
3349 factor = max(factor, nfactor);
3350 if (factor == MPT_ASYNC)
3351 offset = 0;
3352 } else {
3353 offset = 0;
3354 factor = MPT_ASYNC;
3355 }
3356 } else {
3357 factor = MPT_ASYNC;
3358 }
3359 }
3360
3361 /* Make sure data is consistent
3362 */
3363 if ((!width) && (factor < MPT_ULTRA2)) {
3364 factor = MPT_ULTRA2;
3365 }
3366
3367 /* Save the data to the target structure.
3368 */
3369 target->minSyncFactor = factor;
3370 target->maxOffset = offset;
3371 target->maxWidth = width;
3372
3373 target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
3374
3375 /* Disable unused features.
3376 */
3377 if (!width)
3378 target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
3379
3380 if (!offset)
3381 target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
3382
3383 if ( factor > MPT_ULTRA320 )
3384 noQas = 0;
3385
3386 /* GEM, processor WORKAROUND
3387 */
3388 if ((target->inq_data[0] == TYPE_PROCESSOR) || (target->inq_data[0] > 0x08)) {
3389 target->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC);
3390 pspi_data->dvStatus[id] |= MPT_SCSICFG_BLK_NEGO;
3391 } else {
3392 if (noQas && (pspi_data->noQas == 0)) {
3393 pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
3394 target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
3395
3396 /* Disable QAS in a mixed configuration case
3397 */
3398
3399 ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
3400 for (ii = 0; ii < id; ii++) {
3401 if ( (vdev = hd->Targets[ii]) ) {
3402 vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
3403 mptscsih_writeSDP1(hd, 0, ii, vdev->negoFlags);
3404 }
3405 }
3406 }
3407 }
3408
3409 /* Write SDP1 on this I/O to this target */
3410 if (pspi_data->dvStatus[id] & MPT_SCSICFG_NEGOTIATE) {
3411 ddvtprintk((KERN_INFO "MPT_SCSICFG_NEGOTIATE on id=%d!\n", id));
3412 mptscsih_writeSDP1(hd, 0, id, hd->negoNvram);
3413 pspi_data->dvStatus[id] &= ~MPT_SCSICFG_NEGOTIATE;
3414 } else if (pspi_data->dvStatus[id] & MPT_SCSICFG_BLK_NEGO) {
3415 ddvtprintk((KERN_INFO "MPT_SCSICFG_BLK_NEGO on id=%d!\n", id));
3416 mptscsih_writeSDP1(hd, 0, id, MPT_SCSICFG_BLK_NEGO);
3417 pspi_data->dvStatus[id] &= ~MPT_SCSICFG_BLK_NEGO;
3418 }
3419}
3420
3421/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3422/* If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return.
3423 * Else set the NEED_DV flag after Read Capacity Issued (disks)
3424 * or Mode Sense (cdroms).
3425 *
3426 * Tapes, initTarget will set this flag on completion of Inquiry command.
3427 * Called only if DV_NOT_DONE flag is set
3428 */
3429static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
3430{
3431 u8 cmd;
3432 ScsiCfgData *pSpi;
3433
3434 ddvtprintk((" set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
3435 pReq->TargetID, pReq->LUN[1], hd->negoNvram, pReq->CDB[0]));
3436
3437 if ((pReq->LUN[1] != 0) || (hd->negoNvram != 0))
3438 return;
3439
3440 cmd = pReq->CDB[0];
3441
3442 if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) {
3443 pSpi = &hd->ioc->spi_data;
3444 if ((pSpi->isRaid & (1 << pReq->TargetID)) && pSpi->pIocPg3) {
3445 /* Set NEED_DV for all hidden disks
3446 */
3447 Ioc3PhysDisk_t *pPDisk = pSpi->pIocPg3->PhysDisk;
3448 int numPDisk = pSpi->pIocPg3->NumPhysDisks;
3449
3450 while (numPDisk) {
3451 pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
3452 ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
3453 pPDisk++;
3454 numPDisk--;
3455 }
3456 }
3457 pSpi->dvStatus[pReq->TargetID] |= MPT_SCSICFG_NEED_DV;
3458 ddvtprintk(("NEED_DV set for visible disk id %d\n", pReq->TargetID));
3459 }
3460}
3461
3462/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3463/*
3464 * If no Target, bus reset on 1st I/O. Set the flag to
3465 * prevent any future negotiations to this device.
3466 */
3467static void mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id)
3468{
3469
3470 if ((hd->Targets) && (hd->Targets[target_id] == NULL))
3471 hd->ioc->spi_data.dvStatus[target_id] |= MPT_SCSICFG_BLK_NEGO;
3472
3473 return;
3474}
3475
3476/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3477/*
3478 * SCSI Config Page functionality ...
3479 */
3480/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3481/* mptscsih_setDevicePage1Flags - add Requested and Configuration fields flags
3482 * based on width, factor and offset parameters.
3483 * @width: bus width
3484 * @factor: sync factor
3485 * @offset: sync offset
3486 * @requestedPtr: pointer to requested values (updated)
3487 * @configurationPtr: pointer to configuration values (updated)
3488 * @flags: flags to block WDTR or SDTR negotiation
3489 *
3490 * Return: None.
3491 *
3492 * Remark: Called by writeSDP1 and _dv_params
3493 */
3494static void
3495mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags)
3496{
3497 u8 nowide = flags & MPT_TARGET_NO_NEGO_WIDE;
3498 u8 nosync = flags & MPT_TARGET_NO_NEGO_SYNC;
3499
3500 *configurationPtr = 0;
3501 *requestedPtr = width ? MPI_SCSIDEVPAGE1_RP_WIDE : 0;
3502 *requestedPtr |= (offset << 16) | (factor << 8);
3503
3504 if (width && offset && !nowide && !nosync) {
3505 if (factor < MPT_ULTRA160) {
3506 *requestedPtr |= (MPI_SCSIDEVPAGE1_RP_IU + MPI_SCSIDEVPAGE1_RP_DT);
3507 if ((flags & MPT_TARGET_NO_NEGO_QAS) == 0)
3508 *requestedPtr |= MPI_SCSIDEVPAGE1_RP_QAS;
3509 if (flags & MPT_TAPE_NEGO_IDP)
3510 *requestedPtr |= 0x08000000;
3511 } else if (factor < MPT_ULTRA2) {
3512 *requestedPtr |= MPI_SCSIDEVPAGE1_RP_DT;
3513 }
3514 }
3515
3516 if (nowide)
3517 *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_WDTR_DISALLOWED;
3518
3519 if (nosync)
3520 *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_SDTR_DISALLOWED;
3521
3522 return;
3523}
3524
3525/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3526/* mptscsih_writeSDP1 - write SCSI Device Page 1
3527 * @hd: Pointer to a SCSI Host Strucutre
3528 * @portnum: IOC port number
3529 * @target_id: writeSDP1 for single ID
3530 * @flags: MPT_SCSICFG_ALL_IDS, MPT_SCSICFG_USE_NVRAM, MPT_SCSICFG_BLK_NEGO
3531 *
3532 * Return: -EFAULT if read of config page header fails
3533 * or 0 if success.
3534 *
3535 * Remark: If a target has been found, the settings from the
3536 * target structure are used, else the device is set
3537 * to async/narrow.
3538 *
3539 * Remark: Called during init and after a FW reload.
3540 * Remark: We do not wait for a return, write pages sequentially.
3541 */
3542static int
3543mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
3544{
3545 MPT_ADAPTER *ioc = hd->ioc;
3546 Config_t *pReq;
3547 SCSIDevicePage1_t *pData;
3548 VirtDevice *pTarget;
3549 MPT_FRAME_HDR *mf;
3550 dma_addr_t dataDma;
3551 u16 req_idx;
3552 u32 frameOffset;
3553 u32 requested, configuration, flagsLength;
3554 int ii, nvram;
3555 int id = 0, maxid = 0;
3556 u8 width;
3557 u8 factor;
3558 u8 offset;
3559 u8 bus = 0;
3560 u8 negoFlags;
3561 u8 maxwidth, maxoffset, maxfactor;
3562
3563 if (ioc->spi_data.sdp1length == 0)
3564 return 0;
3565
3566 if (flags & MPT_SCSICFG_ALL_IDS) {
3567 id = 0;
3568 maxid = ioc->sh->max_id - 1;
3569 } else if (ioc->sh) {
3570 id = target_id;
3571 maxid = min_t(int, id, ioc->sh->max_id - 1);
3572 }
3573
3574 for (; id <= maxid; id++) {
3575
3576 if (id == ioc->pfacts[portnum].PortSCSIID)
3577 continue;
3578
3579 /* Use NVRAM to get adapter and target maximums
3580 * Data over-riden by target structure information, if present
3581 */
3582 maxwidth = ioc->spi_data.maxBusWidth;
3583 maxoffset = ioc->spi_data.maxSyncOffset;
3584 maxfactor = ioc->spi_data.minSyncFactor;
3585 if (ioc->spi_data.nvram && (ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
3586 nvram = ioc->spi_data.nvram[id];
3587
3588 if (maxwidth)
3589 maxwidth = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
3590
3591 if (maxoffset > 0) {
3592 maxfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
3593 if (maxfactor == 0) {
3594 /* Key for async */
3595 maxfactor = MPT_ASYNC;
3596 maxoffset = 0;
3597 } else if (maxfactor < ioc->spi_data.minSyncFactor) {
3598 maxfactor = ioc->spi_data.minSyncFactor;
3599 }
3600 } else
3601 maxfactor = MPT_ASYNC;
3602 }
3603
3604 /* Set the negotiation flags.
3605 */
3606 negoFlags = ioc->spi_data.noQas;
3607 if (!maxwidth)
3608 negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
3609
3610 if (!maxoffset)
3611 negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
3612
3613 if (flags & MPT_SCSICFG_USE_NVRAM) {
3614 width = maxwidth;
3615 factor = maxfactor;
3616 offset = maxoffset;
3617 } else {
3618 width = 0;
3619 factor = MPT_ASYNC;
3620 offset = 0;
3621 //negoFlags = 0;
3622 //negoFlags = MPT_TARGET_NO_NEGO_SYNC;
3623 }
3624
3625 /* If id is not a raid volume, get the updated
3626 * transmission settings from the target structure.
3627 */
3628 if (hd->Targets && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
3629 width = pTarget->maxWidth;
3630 factor = pTarget->minSyncFactor;
3631 offset = pTarget->maxOffset;
3632 negoFlags = pTarget->negoFlags;
3633 }
3634
3635#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3636 /* Force to async and narrow if DV has not been executed
3637 * for this ID
3638 */
3639 if ((hd->ioc->spi_data.dvStatus[id] & MPT_SCSICFG_DV_NOT_DONE) != 0) {
3640 width = 0;
3641 factor = MPT_ASYNC;
3642 offset = 0;
3643 }
3644#endif
3645
3646 if (flags & MPT_SCSICFG_BLK_NEGO)
3647 negoFlags = MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC;
3648
3649 mptscsih_setDevicePage1Flags(width, factor, offset,
3650 &requested, &configuration, negoFlags);
3651 dnegoprintk(("writeSDP1: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
3652 target_id, width, factor, offset, negoFlags, requested, configuration));
3653
3654 /* Get a MF for this command.
3655 */
3656 if ((mf = mpt_get_msg_frame(ScsiDoneCtx, ioc)) == NULL) {
3657 dprintk((MYIOC_s_WARN_FMT "write SDP1: no msg frames!\n",
3658 ioc->name));
3659 return -EAGAIN;
3660 }
3661
3662 ddvprintk((MYIOC_s_INFO_FMT "WriteSDP1 (mf=%p, id=%d, req=0x%x, cfg=0x%x)\n",
3663 hd->ioc->name, mf, id, requested, configuration));
3664
3665
3666 /* Set the request and the data pointers.
3667 * Request takes: 36 bytes (32 bit SGE)
3668 * SCSI Device Page 1 requires 16 bytes
3669 * 40 + 16 <= size of SCSI IO Request = 56 bytes
3670 * and MF size >= 64 bytes.
3671 * Place data at end of MF.
3672 */
3673 pReq = (Config_t *)mf;
3674
3675 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3676 frameOffset = ioc->req_sz - sizeof(SCSIDevicePage1_t);
3677
3678 pData = (SCSIDevicePage1_t *)((u8 *) mf + frameOffset);
3679 dataDma = ioc->req_frames_dma + (req_idx * ioc->req_sz) + frameOffset;
3680
3681 /* Complete the request frame (same for all requests).
3682 */
3683 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3684 pReq->Reserved = 0;
3685 pReq->ChainOffset = 0;
3686 pReq->Function = MPI_FUNCTION_CONFIG;
3687 pReq->ExtPageLength = 0;
3688 pReq->ExtPageType = 0;
3689 pReq->MsgFlags = 0;
3690 for (ii=0; ii < 8; ii++) {
3691 pReq->Reserved2[ii] = 0;
3692 }
3693 pReq->Header.PageVersion = ioc->spi_data.sdp1version;
3694 pReq->Header.PageLength = ioc->spi_data.sdp1length;
3695 pReq->Header.PageNumber = 1;
3696 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
3697 pReq->PageAddress = cpu_to_le32(id | (bus << 8 ));
3698
3699 /* Add a SGE to the config request.
3700 */
3701 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE | ioc->spi_data.sdp1length * 4;
3702
3703 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
3704
3705 /* Set up the common data portion
3706 */
3707 pData->Header.PageVersion = pReq->Header.PageVersion;
3708 pData->Header.PageLength = pReq->Header.PageLength;
3709 pData->Header.PageNumber = pReq->Header.PageNumber;
3710 pData->Header.PageType = pReq->Header.PageType;
3711 pData->RequestedParameters = cpu_to_le32(requested);
3712 pData->Reserved = 0;
3713 pData->Configuration = cpu_to_le32(configuration);
3714
3715 dprintk((MYIOC_s_INFO_FMT
3716 "write SDP1: id %d pgaddr 0x%x req 0x%x config 0x%x\n",
3717 ioc->name, id, (id | (bus<<8)),
3718 requested, configuration));
3719
3720 mpt_put_msg_frame(ScsiDoneCtx, ioc, mf);
3721 }
3722
3723 return 0;
3724}
3725
3726/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3727/* mptscsih_writeIOCPage4 - write IOC Page 4
3728 * @hd: Pointer to a SCSI Host Structure
3729 * @target_id: write IOC Page4 for this ID & Bus
3730 *
3731 * Return: -EAGAIN if unable to obtain a Message Frame
3732 * or 0 if success.
3733 *
3734 * Remark: We do not wait for a return, write pages sequentially.
3735 */
3736static int
3737mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
3738{
3739 MPT_ADAPTER *ioc = hd->ioc;
3740 Config_t *pReq;
3741 IOCPage4_t *IOCPage4Ptr;
3742 MPT_FRAME_HDR *mf;
3743 dma_addr_t dataDma;
3744 u16 req_idx;
3745 u32 frameOffset;
3746 u32 flagsLength;
3747 int ii;
3748
3749 /* Get a MF for this command.
3750 */
3751 if ((mf = mpt_get_msg_frame(ScsiDoneCtx, ioc)) == NULL) {
3752 dprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
3753 ioc->name));
3754 return -EAGAIN;
3755 }
3756
3757 /* Set the request and the data pointers.
3758 * Place data at end of MF.
3759 */
3760 pReq = (Config_t *)mf;
3761
3762 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3763 frameOffset = ioc->req_sz - sizeof(IOCPage4_t);
3764
3765 /* Complete the request frame (same for all requests).
3766 */
3767 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3768 pReq->Reserved = 0;
3769 pReq->ChainOffset = 0;
3770 pReq->Function = MPI_FUNCTION_CONFIG;
3771 pReq->ExtPageLength = 0;
3772 pReq->ExtPageType = 0;
3773 pReq->MsgFlags = 0;
3774 for (ii=0; ii < 8; ii++) {
3775 pReq->Reserved2[ii] = 0;
3776 }
3777
3778 IOCPage4Ptr = ioc->spi_data.pIocPg4;
3779 dataDma = ioc->spi_data.IocPg4_dma;
3780 ii = IOCPage4Ptr->ActiveSEP++;
3781 IOCPage4Ptr->SEP[ii].SEPTargetID = target_id;
3782 IOCPage4Ptr->SEP[ii].SEPBus = bus;
3783 pReq->Header = IOCPage4Ptr->Header;
3784 pReq->PageAddress = cpu_to_le32(target_id | (bus << 8 ));
3785
3786 /* Add a SGE to the config request.
3787 */
3788 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE |
3789 (IOCPage4Ptr->Header.PageLength + ii) * 4;
3790
3791 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
3792
3793 dinitprintk((MYIOC_s_INFO_FMT
3794 "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
3795 ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, target_id, bus));
3796
3797 mpt_put_msg_frame(ScsiDoneCtx, ioc, mf);
3798
3799 return 0;
3800}
3801
3802/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3803/*
3804 * Bus Scan and Domain Validation functionality ...
3805 */
3806
3807/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3808/*
3809 * mptscsih_scandv_complete - Scan and DV callback routine registered
3810 * to Fustion MPT (base) driver.
3811 *
3812 * @ioc: Pointer to MPT_ADAPTER structure
3813 * @mf: Pointer to original MPT request frame
3814 * @mr: Pointer to MPT reply frame (NULL if TurboReply)
3815 *
3816 * This routine is called from mpt.c::mpt_interrupt() at the completion
3817 * of any SCSI IO request.
3818 * This routine is registered with the Fusion MPT (base) driver at driver
3819 * load/init time via the mpt_register() API call.
3820 *
3821 * Returns 1 indicating alloc'd request frame ptr should be freed.
3822 *
3823 * Remark: Sets a completion code and (possibly) saves sense data
3824 * in the IOC member localReply structure.
3825 * Used ONLY for DV and other internal commands.
3826 */
3827static int
3828mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
3829{
3830 MPT_SCSI_HOST *hd;
3831 SCSIIORequest_t *pReq;
3832 int completionCode;
3833 u16 req_idx;
3834
3835 if ((mf == NULL) ||
3836 (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
3837 printk(MYIOC_s_ERR_FMT
3838 "ScanDvComplete, %s req frame ptr! (=%p)\n",
3839 ioc->name, mf?"BAD":"NULL", (void *) mf);
3840 goto wakeup;
3841 }
3842
3843 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
3844 del_timer(&hd->timer);
3845 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3846 hd->ScsiLookup[req_idx] = NULL;
3847 pReq = (SCSIIORequest_t *) mf;
3848
3849 if (mf != hd->cmdPtr) {
3850 printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
3851 hd->ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx);
3852 }
3853 hd->cmdPtr = NULL;
3854
3855 ddvprintk((MYIOC_s_INFO_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
3856 hd->ioc->name, mf, mr, req_idx));
3857
3858 hd->pLocal = &hd->localReply;
3859 hd->pLocal->scsiStatus = 0;
3860
3861 /* If target struct exists, clear sense valid flag.
3862 */
3863 if (mr == NULL) {
3864 completionCode = MPT_SCANDV_GOOD;
3865 } else {
3866 SCSIIOReply_t *pReply;
3867 u16 status;
3868 u8 scsi_status;
3869
3870 pReply = (SCSIIOReply_t *) mr;
3871
3872 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
3873 scsi_status = pReply->SCSIStatus;
3874
3875 ddvtprintk((KERN_NOTICE " IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
3876 status, pReply->SCSIState, scsi_status,
3877 le32_to_cpu(pReply->IOCLogInfo)));
3878
3879 switch(status) {
3880
3881 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
3882 completionCode = MPT_SCANDV_SELECTION_TIMEOUT;
3883 break;
3884
3885 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
3886 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
3887 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
3888 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
3889 completionCode = MPT_SCANDV_DID_RESET;
3890 break;
3891
3892 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
3893 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
3894 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
3895 if (pReply->Function == MPI_FUNCTION_CONFIG) {
3896 ConfigReply_t *pr = (ConfigReply_t *)mr;
3897 completionCode = MPT_SCANDV_GOOD;
3898 hd->pLocal->header.PageVersion = pr->Header.PageVersion;
3899 hd->pLocal->header.PageLength = pr->Header.PageLength;
3900 hd->pLocal->header.PageNumber = pr->Header.PageNumber;
3901 hd->pLocal->header.PageType = pr->Header.PageType;
3902
3903 } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
3904 /* If the RAID Volume request is successful,
3905 * return GOOD, else indicate that
3906 * some type of error occurred.
3907 */
3908 MpiRaidActionReply_t *pr = (MpiRaidActionReply_t *)mr;
3909 if (pr->ActionStatus == MPI_RAID_ACTION_ASTATUS_SUCCESS)
3910 completionCode = MPT_SCANDV_GOOD;
3911 else
3912 completionCode = MPT_SCANDV_SOME_ERROR;
3913
3914 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
3915 u8 *sense_data;
3916 int sz;
3917
3918 /* save sense data in global structure
3919 */
3920 completionCode = MPT_SCANDV_SENSE;
3921 hd->pLocal->scsiStatus = scsi_status;
3922 sense_data = ((u8 *)hd->ioc->sense_buf_pool +
3923 (req_idx * MPT_SENSE_BUFFER_ALLOC));
3924
3925 sz = min_t(int, pReq->SenseBufferLength,
3926 SCSI_STD_SENSE_BYTES);
3927 memcpy(hd->pLocal->sense, sense_data, sz);
3928
3929 ddvprintk((KERN_NOTICE " Check Condition, sense ptr %p\n",
3930 sense_data));
3931 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
3932 if (pReq->CDB[0] == INQUIRY)
3933 completionCode = MPT_SCANDV_ISSUE_SENSE;
3934 else
3935 completionCode = MPT_SCANDV_DID_RESET;
3936 }
3937 else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
3938 completionCode = MPT_SCANDV_DID_RESET;
3939 else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3940 completionCode = MPT_SCANDV_DID_RESET;
3941 else {
3942 completionCode = MPT_SCANDV_GOOD;
3943 hd->pLocal->scsiStatus = scsi_status;
3944 }
3945 break;
3946
3947 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
3948 if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3949 completionCode = MPT_SCANDV_DID_RESET;
3950 else
3951 completionCode = MPT_SCANDV_SOME_ERROR;
3952 break;
3953
3954 default:
3955 completionCode = MPT_SCANDV_SOME_ERROR;
3956 break;
3957
3958 } /* switch(status) */
3959
3960 ddvtprintk((KERN_NOTICE " completionCode set to %08xh\n",
3961 completionCode));
3962 } /* end of address reply case */
3963
3964 hd->pLocal->completion = completionCode;
3965
3966 /* MF and RF are freed in mpt_interrupt
3967 */
3968wakeup:
3969 /* Free Chain buffers (will never chain) in scan or dv */
3970 //mptscsih_freeChainBuffers(ioc, req_idx);
3971
3972 /*
3973 * Wake up the original calling thread
3974 */
3975 scandv_wait_done = 1;
3976 wake_up(&scandv_waitq);
3977
3978 return 1;
3979}
3980
3981/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3982/* mptscsih_timer_expired - Call back for timer process.
3983 * Used only for dv functionality.
3984 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
3985 *
3986 */
3987static void mptscsih_timer_expired(unsigned long data)
3988{
3989 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
3990
3991 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired! Cmd %p\n", hd->ioc->name, hd->cmdPtr));
3992
3993 if (hd->cmdPtr) {
3994 MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr;
3995
3996 if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
3997 /* Desire to issue a task management request here.
3998 * TM requests MUST be single threaded.
3999 * If old eh code and no TM current, issue request.
4000 * If new eh code, do nothing. Wait for OS cmd timeout
4001 * for bus reset.
4002 */
4003 ddvtprintk((MYIOC_s_NOTE_FMT "DV Cmd Timeout: NoOp\n", hd->ioc->name));
4004 } else {
4005 /* Perform a FW reload */
4006 if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0) {
4007 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", hd->ioc->name);
4008 }
4009 }
4010 } else {
4011 /* This should NEVER happen */
4012 printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", hd->ioc->name);
4013 }
4014
4015 /* No more processing.
4016 * TM call will generate an interrupt for SCSI TM Management.
4017 * The FW will reply to all outstanding commands, callback will finish cleanup.
4018 * Hard reset clean-up will free all resources.
4019 */
4020 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired Complete!\n", hd->ioc->name));
4021
4022 return;
4023}
4024
4025#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
4026/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4027/* mptscsih_do_raid - Format and Issue a RAID volume request message.
4028 * @hd: Pointer to scsi host structure
4029 * @action: What do be done.
4030 * @id: Logical target id.
4031 * @bus: Target locations bus.
4032 *
4033 * Returns: < 0 on a fatal error
4034 * 0 on success
4035 *
4036 * Remark: Wait to return until reply processed by the ISR.
4037 */
4038static int
4039mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io)
4040{
4041 MpiRaidActionRequest_t *pReq;
4042 MPT_FRAME_HDR *mf;
4043 int in_isr;
4044
4045 in_isr = in_interrupt();
4046 if (in_isr) {
4047 dprintk((MYIOC_s_WARN_FMT "Internal raid request not allowed in ISR context!\n",
4048 hd->ioc->name));
4049 return -EPERM;
4050 }
4051
4052 /* Get and Populate a free Frame
4053 */
4054 if ((mf = mpt_get_msg_frame(ScsiScanDvCtx, hd->ioc)) == NULL) {
4055 ddvprintk((MYIOC_s_WARN_FMT "_do_raid: no msg frames!\n",
4056 hd->ioc->name));
4057 return -EAGAIN;
4058 }
4059 pReq = (MpiRaidActionRequest_t *)mf;
4060 pReq->Action = action;
4061 pReq->Reserved1 = 0;
4062 pReq->ChainOffset = 0;
4063 pReq->Function = MPI_FUNCTION_RAID_ACTION;
4064 pReq->VolumeID = io->id;
4065 pReq->VolumeBus = io->bus;
4066 pReq->PhysDiskNum = io->physDiskNum;
4067 pReq->MsgFlags = 0;
4068 pReq->Reserved2 = 0;
4069 pReq->ActionDataWord = 0; /* Reserved for this action */
4070 //pReq->ActionDataSGE = 0;
4071
4072 mpt_add_sge((char *)&pReq->ActionDataSGE,
4073 MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1);
4074
4075 ddvprintk((MYIOC_s_INFO_FMT "RAID Volume action %x id %d\n",
4076 hd->ioc->name, action, io->id));
4077
4078 hd->pLocal = NULL;
4079 hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */
4080 scandv_wait_done = 0;
4081
4082 /* Save cmd pointer, for resource free if timeout or
4083 * FW reload occurs
4084 */
4085 hd->cmdPtr = mf;
4086
4087 add_timer(&hd->timer);
4088 mpt_put_msg_frame(ScsiScanDvCtx, hd->ioc, mf);
4089 wait_event(scandv_waitq, scandv_wait_done);
4090
4091 if ((hd->pLocal == NULL) || (hd->pLocal->completion != MPT_SCANDV_GOOD))
4092 return -1;
4093
4094 return 0;
4095}
4096#endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
4097
4098/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4099/**
4100 * mptscsih_do_cmd - Do internal command.
4101 * @hd: MPT_SCSI_HOST pointer
4102 * @io: INTERNAL_CMD pointer.
4103 *
4104 * Issue the specified internally generated command and do command
4105 * specific cleanup. For bus scan / DV only.
4106 * NOTES: If command is Inquiry and status is good,
4107 * initialize a target structure, save the data
4108 *
4109 * Remark: Single threaded access only.
4110 *
4111 * Return:
4112 * < 0 if an illegal command or no resources
4113 *
4114 * 0 if good
4115 *
4116 * > 0 if command complete but some type of completion error.
4117 */
4118static int
4119mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
4120{
4121 MPT_FRAME_HDR *mf;
4122 SCSIIORequest_t *pScsiReq;
4123 SCSIIORequest_t ReqCopy;
4124 int my_idx, ii, dir;
4125 int rc, cmdTimeout;
4126 int in_isr;
4127 char cmdLen;
4128 char CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
4129 char cmd = io->cmd;
4130
4131 in_isr = in_interrupt();
4132 if (in_isr) {
4133 dprintk((MYIOC_s_WARN_FMT "Internal SCSI IO request not allowed in ISR context!\n",
4134 hd->ioc->name));
4135 return -EPERM;
4136 }
4137
4138
4139 /* Set command specific information
4140 */
4141 switch (cmd) {
4142 case INQUIRY:
4143 cmdLen = 6;
4144 dir = MPI_SCSIIO_CONTROL_READ;
4145 CDB[0] = cmd;
4146 CDB[4] = io->size;
4147 cmdTimeout = 10;
4148 break;
4149
4150 case TEST_UNIT_READY:
4151 cmdLen = 6;
4152 dir = MPI_SCSIIO_CONTROL_READ;
4153 cmdTimeout = 10;
4154 break;
4155
4156 case START_STOP:
4157 cmdLen = 6;
4158 dir = MPI_SCSIIO_CONTROL_READ;
4159 CDB[0] = cmd;
4160 CDB[4] = 1; /*Spin up the disk */
4161 cmdTimeout = 15;
4162 break;
4163
4164 case REQUEST_SENSE:
4165 cmdLen = 6;
4166 CDB[0] = cmd;
4167 CDB[4] = io->size;
4168 dir = MPI_SCSIIO_CONTROL_READ;
4169 cmdTimeout = 10;
4170 break;
4171
4172 case READ_BUFFER:
4173 cmdLen = 10;
4174 dir = MPI_SCSIIO_CONTROL_READ;
4175 CDB[0] = cmd;
4176 if (io->flags & MPT_ICFLAG_ECHO) {
4177 CDB[1] = 0x0A;
4178 } else {
4179 CDB[1] = 0x02;
4180 }
4181
4182 if (io->flags & MPT_ICFLAG_BUF_CAP) {
4183 CDB[1] |= 0x01;
4184 }
4185 CDB[6] = (io->size >> 16) & 0xFF;
4186 CDB[7] = (io->size >> 8) & 0xFF;
4187 CDB[8] = io->size & 0xFF;
4188 cmdTimeout = 10;
4189 break;
4190
4191 case WRITE_BUFFER:
4192 cmdLen = 10;
4193 dir = MPI_SCSIIO_CONTROL_WRITE;
4194 CDB[0] = cmd;
4195 if (io->flags & MPT_ICFLAG_ECHO) {
4196 CDB[1] = 0x0A;
4197 } else {
4198 CDB[1] = 0x02;
4199 }
4200 CDB[6] = (io->size >> 16) & 0xFF;
4201 CDB[7] = (io->size >> 8) & 0xFF;
4202 CDB[8] = io->size & 0xFF;
4203 cmdTimeout = 10;
4204 break;
4205
4206 case RESERVE:
4207 cmdLen = 6;
4208 dir = MPI_SCSIIO_CONTROL_READ;
4209 CDB[0] = cmd;
4210 cmdTimeout = 10;
4211 break;
4212
4213 case RELEASE:
4214 cmdLen = 6;
4215 dir = MPI_SCSIIO_CONTROL_READ;
4216 CDB[0] = cmd;
4217 cmdTimeout = 10;
4218 break;
4219
4220 case SYNCHRONIZE_CACHE:
4221 cmdLen = 10;
4222 dir = MPI_SCSIIO_CONTROL_READ;
4223 CDB[0] = cmd;
4224// CDB[1] = 0x02; /* set immediate bit */
4225 cmdTimeout = 10;
4226 break;
4227
4228 default:
4229 /* Error Case */
4230 return -EFAULT;
4231 }
4232
4233 /* Get and Populate a free Frame
4234 */
4235 if ((mf = mpt_get_msg_frame(ScsiScanDvCtx, hd->ioc)) == NULL) {
4236 ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n",
4237 hd->ioc->name));
4238 return -EBUSY;
4239 }
4240
4241 pScsiReq = (SCSIIORequest_t *) mf;
4242
4243 /* Get the request index */
4244 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
4245 ADD_INDEX_LOG(my_idx); /* for debug */
4246
4247 if (io->flags & MPT_ICFLAG_PHYS_DISK) {
4248 pScsiReq->TargetID = io->physDiskNum;
4249 pScsiReq->Bus = 0;
4250 pScsiReq->ChainOffset = 0;
4251 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
4252 } else {
4253 pScsiReq->TargetID = io->id;
4254 pScsiReq->Bus = io->bus;
4255 pScsiReq->ChainOffset = 0;
4256 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
4257 }
4258
4259 pScsiReq->CDBLength = cmdLen;
4260 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
4261
4262 pScsiReq->Reserved = 0;
4263
4264 pScsiReq->MsgFlags = mpt_msg_flags();
4265 /* MsgContext set in mpt_get_msg_fram call */
4266
4267 for (ii=0; ii < 8; ii++)
4268 pScsiReq->LUN[ii] = 0;
4269 pScsiReq->LUN[1] = io->lun;
4270
4271 if (io->flags & MPT_ICFLAG_TAGGED_CMD)
4272 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
4273 else
4274 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
4275
4276 if (cmd == REQUEST_SENSE) {
4277 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
4278 ddvprintk((MYIOC_s_INFO_FMT "Untagged! 0x%2x\n",
4279 hd->ioc->name, cmd));
4280 }
4281
4282 for (ii=0; ii < 16; ii++)
4283 pScsiReq->CDB[ii] = CDB[ii];
4284
4285 pScsiReq->DataLength = cpu_to_le32(io->size);
4286 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
4287 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
4288
4289 ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n",
4290 hd->ioc->name, cmd, io->bus, io->id, io->lun));
4291
4292 if (dir == MPI_SCSIIO_CONTROL_READ) {
4293 mpt_add_sge((char *) &pScsiReq->SGL,
4294 MPT_SGE_FLAGS_SSIMPLE_READ | io->size,
4295 io->data_dma);
4296 } else {
4297 mpt_add_sge((char *) &pScsiReq->SGL,
4298 MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size,
4299 io->data_dma);
4300 }
4301
4302 /* The ISR will free the request frame, but we need
4303 * the information to initialize the target. Duplicate.
4304 */
4305 memcpy(&ReqCopy, pScsiReq, sizeof(SCSIIORequest_t));
4306
4307 /* Issue this command after:
4308 * finish init
4309 * add timer
4310 * Wait until the reply has been received
4311 * ScsiScanDvCtx callback function will
4312 * set hd->pLocal;
4313 * set scandv_wait_done and call wake_up
4314 */
4315 hd->pLocal = NULL;
4316 hd->timer.expires = jiffies + HZ*cmdTimeout;
4317 scandv_wait_done = 0;
4318
4319 /* Save cmd pointer, for resource free if timeout or
4320 * FW reload occurs
4321 */
4322 hd->cmdPtr = mf;
4323
4324 add_timer(&hd->timer);
4325 mpt_put_msg_frame(ScsiScanDvCtx, hd->ioc, mf);
4326 wait_event(scandv_waitq, scandv_wait_done);
4327
4328 if (hd->pLocal) {
4329 rc = hd->pLocal->completion;
4330 hd->pLocal->skip = 0;
4331
4332 /* Always set fatal error codes in some cases.
4333 */
4334 if (rc == MPT_SCANDV_SELECTION_TIMEOUT)
4335 rc = -ENXIO;
4336 else if (rc == MPT_SCANDV_SOME_ERROR)
4337 rc = -rc;
4338 } else {
4339 rc = -EFAULT;
4340 /* This should never happen. */
4341 ddvprintk((MYIOC_s_INFO_FMT "_do_cmd: Null pLocal!!!\n",
4342 hd->ioc->name));
4343 }
4344
4345 return rc;
4346}
4347
4348/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4349/**
4350 * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
4351 * @hd: Pointer to MPT_SCSI_HOST structure
4352 * @portnum: IOC port number
4353 *
4354 * Uses the ISR, but with special processing.
4355 * MUST be single-threaded.
4356 *
4357 * Return: 0 on completion
4358 */
4359static int
4360mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
4361{
4362 MPT_ADAPTER *ioc= hd->ioc;
4363 VirtDevice *pTarget;
4364 SCSIDevicePage1_t *pcfg1Data = NULL;
4365 INTERNAL_CMD iocmd;
4366 CONFIGPARMS cfg;
4367 dma_addr_t cfg1_dma_addr = -1;
4368 ConfigPageHeader_t header1;
4369 int bus = 0;
4370 int id = 0;
4371 int lun;
4372 int indexed_lun, lun_index;
4373 int hostId = ioc->pfacts[portnum].PortSCSIID;
4374 int max_id;
4375 int requested, configuration, data;
4376 int doConfig = 0;
4377 u8 flags, factor;
4378
4379 max_id = ioc->sh->max_id - 1;
4380
4381 /* Following parameters will not change
4382 * in this routine.
4383 */
4384 iocmd.cmd = SYNCHRONIZE_CACHE;
4385 iocmd.flags = 0;
4386 iocmd.physDiskNum = -1;
4387 iocmd.data = NULL;
4388 iocmd.data_dma = -1;
4389 iocmd.size = 0;
4390 iocmd.rsvd = iocmd.rsvd2 = 0;
4391
4392 /* No SCSI hosts
4393 */
4394 if (hd->Targets == NULL)
4395 return 0;
4396
4397 /* Skip the host
4398 */
4399 if (id == hostId)
4400 id++;
4401
4402 /* Write SDP1 for all SCSI devices
4403 * Alloc memory and set up config buffer
4404 */
4405 if (ioc->bus_type == SCSI) {
4406 if (ioc->spi_data.sdp1length > 0) {
4407 pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev,
4408 ioc->spi_data.sdp1length * 4, &cfg1_dma_addr);
4409
4410 if (pcfg1Data != NULL) {
4411 doConfig = 1;
4412 header1.PageVersion = ioc->spi_data.sdp1version;
4413 header1.PageLength = ioc->spi_data.sdp1length;
4414 header1.PageNumber = 1;
4415 header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4416 cfg.hdr = &header1;
4417 cfg.physAddr = cfg1_dma_addr;
4418 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4419 cfg.dir = 1;
4420 cfg.timeout = 0;
4421 }
4422 }
4423 }
4424
4425 /* loop through all devices on this port
4426 */
4427 while (bus < MPT_MAX_BUS) {
4428 iocmd.bus = bus;
4429 iocmd.id = id;
4430 pTarget = hd->Targets[(int)id];
4431
4432 if (doConfig) {
4433
4434 /* Set the negotiation flags */
4435 if (pTarget && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
4436 flags = pTarget->negoFlags;
4437 } else {
4438 flags = hd->ioc->spi_data.noQas;
4439 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
4440 data = hd->ioc->spi_data.nvram[id];
4441
4442 if (data & MPT_NVRAM_WIDE_DISABLE)
4443 flags |= MPT_TARGET_NO_NEGO_WIDE;
4444
4445 factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
4446 if ((factor == 0) || (factor == MPT_ASYNC))
4447 flags |= MPT_TARGET_NO_NEGO_SYNC;
4448 }
4449 }
4450
4451 /* Force to async, narrow */
4452 mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
4453 &configuration, flags);
4454 dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
4455 "offset=0 negoFlags=%x request=%x config=%x\n",
4456 id, flags, requested, configuration));
4457 pcfg1Data->RequestedParameters = le32_to_cpu(requested);
4458 pcfg1Data->Reserved = 0;
4459 pcfg1Data->Configuration = le32_to_cpu(configuration);
4460 cfg.pageAddr = (bus<<8) | id;
4461 mpt_config(hd->ioc, &cfg);
4462 }
4463
4464 /* If target Ptr NULL or if this target is NOT a disk, skip.
4465 */
4466 if ((pTarget) && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)){
4467 for (lun=0; lun <= MPT_LAST_LUN; lun++) {
4468 /* If LUN present, issue the command
4469 */
4470 lun_index = (lun >> 5); /* 32 luns per lun_index */
4471 indexed_lun = (lun % 32);
4472 if (pTarget->luns[lun_index] & (1<<indexed_lun)) {
4473 iocmd.lun = lun;
4474 (void) mptscsih_do_cmd(hd, &iocmd);
4475 }
4476 }
4477 }
4478
4479 /* get next relevant device */
4480 id++;
4481
4482 if (id == hostId)
4483 id++;
4484
4485 if (id > max_id) {
4486 id = 0;
4487 bus++;
4488 }
4489 }
4490
4491 if (pcfg1Data) {
4492 pci_free_consistent(ioc->pcidev, header1.PageLength * 4, pcfg1Data, cfg1_dma_addr);
4493 }
4494
4495 return 0;
4496}
4497
4498#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
4499/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4500/**
4501 * mptscsih_domainValidation - Top level handler for domain validation.
4502 * @hd: Pointer to MPT_SCSI_HOST structure.
4503 *
4504 * Uses the ISR, but with special processing.
4505 * Called from schedule, should not be in interrupt mode.
4506 * While thread alive, do dv for all devices needing dv
4507 *
4508 * Return: None.
4509 */
4510static void
4511mptscsih_domainValidation(void *arg)
4512{
4513 MPT_SCSI_HOST *hd;
4514 MPT_ADAPTER *ioc;
4515 unsigned long flags;
4516 int id, maxid, dvStatus, did;
4517 int ii, isPhysDisk;
4518
4519 spin_lock_irqsave(&dvtaskQ_lock, flags);
4520 dvtaskQ_active = 1;
4521 if (dvtaskQ_release) {
4522 dvtaskQ_active = 0;
4523 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4524 return;
4525 }
4526 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4527
4528 /* For this ioc, loop through all devices and do dv to each device.
4529 * When complete with this ioc, search through the ioc list, and
4530 * for each scsi ioc found, do dv for all devices. Exit when no
4531 * device needs dv.
4532 */
4533 did = 1;
4534 while (did) {
4535 did = 0;
4536 list_for_each_entry(ioc, &ioc_list, list) {
4537 spin_lock_irqsave(&dvtaskQ_lock, flags);
4538 if (dvtaskQ_release) {
4539 dvtaskQ_active = 0;
4540 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4541 return;
4542 }
4543 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4544
4545 msleep(250);
4546
4547 /* DV only to SCSI adapters */
4548 if (ioc->bus_type != SCSI)
4549 continue;
4550
4551 /* Make sure everything looks ok */
4552 if (ioc->sh == NULL)
4553 continue;
4554
4555 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
4556 if (hd == NULL)
4557 continue;
4558
4559 if ((ioc->spi_data.forceDv & MPT_SCSICFG_RELOAD_IOC_PG3) != 0) {
4560 mpt_read_ioc_pg_3(ioc);
4561 if (ioc->spi_data.pIocPg3) {
4562 Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
4563 int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
4564
4565 while (numPDisk) {
4566 if (ioc->spi_data.dvStatus[pPDisk->PhysDiskID] & MPT_SCSICFG_DV_NOT_DONE)
4567 ioc->spi_data.dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
4568
4569 pPDisk++;
4570 numPDisk--;
4571 }
4572 }
4573 ioc->spi_data.forceDv &= ~MPT_SCSICFG_RELOAD_IOC_PG3;
4574 }
4575
4576 maxid = min_t(int, ioc->sh->max_id, MPT_MAX_SCSI_DEVICES);
4577
4578 for (id = 0; id < maxid; id++) {
4579 spin_lock_irqsave(&dvtaskQ_lock, flags);
4580 if (dvtaskQ_release) {
4581 dvtaskQ_active = 0;
4582 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4583 return;
4584 }
4585 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4586 dvStatus = hd->ioc->spi_data.dvStatus[id];
4587
4588 if (dvStatus & MPT_SCSICFG_NEED_DV) {
4589 did++;
4590 hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_DV_PENDING;
4591 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_NEED_DV;
4592
4593 msleep(250);
4594
4595 /* If hidden phys disk, block IO's to all
4596 * raid volumes
4597 * else, process normally
4598 */
4599 isPhysDisk = mptscsih_is_phys_disk(ioc, id);
4600 if (isPhysDisk) {
4601 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4602 if (hd->ioc->spi_data.isRaid & (1 << ii)) {
4603 hd->ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_DV_PENDING;
4604 }
4605 }
4606 }
4607
4608 if (mptscsih_doDv(hd, 0, id) == 1) {
4609 /* Untagged device was busy, try again
4610 */
4611 hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_NEED_DV;
4612 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_PENDING;
4613 } else {
4614 /* DV is complete. Clear flags.
4615 */
4616 hd->ioc->spi_data.dvStatus[id] &= ~(MPT_SCSICFG_DV_NOT_DONE | MPT_SCSICFG_DV_PENDING);
4617 }
4618
4619 if (isPhysDisk) {
4620 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4621 if (hd->ioc->spi_data.isRaid & (1 << ii)) {
4622 hd->ioc->spi_data.dvStatus[ii] &= ~MPT_SCSICFG_DV_PENDING;
4623 }
4624 }
4625 }
4626
4627 if (hd->ioc->spi_data.noQas)
4628 mptscsih_qas_check(hd, id);
4629 }
4630 }
4631 }
4632 }
4633
4634 spin_lock_irqsave(&dvtaskQ_lock, flags);
4635 dvtaskQ_active = 0;
4636 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4637
4638 return;
4639}
4640
4641/* Search IOC page 3 to determine if this is hidden physical disk
4642 */
4643static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
4644{
4645 if (ioc->spi_data.pIocPg3) {
4646 Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
4647 int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
4648
4649 while (numPDisk) {
4650 if (pPDisk->PhysDiskID == id) {
4651 return 1;
4652 }
4653 pPDisk++;
4654 numPDisk--;
4655 }
4656 }
4657 return 0;
4658}
4659
4660/* Write SDP1 if no QAS has been enabled
4661 */
4662static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id)
4663{
4664 VirtDevice *pTarget;
4665 int ii;
4666
4667 if (hd->Targets == NULL)
4668 return;
4669
4670 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4671 if (ii == id)
4672 continue;
4673
4674 if ((hd->ioc->spi_data.dvStatus[ii] & MPT_SCSICFG_DV_NOT_DONE) != 0)
4675 continue;
4676
4677 pTarget = hd->Targets[ii];
4678
4679 if ((pTarget != NULL) && (!pTarget->raidVolume)) {
4680 if ((pTarget->negoFlags & hd->ioc->spi_data.noQas) == 0) {
4681 pTarget->negoFlags |= hd->ioc->spi_data.noQas;
4682 dnegoprintk(("writeSDP1: id=%d flags=0\n", id));
4683 mptscsih_writeSDP1(hd, 0, ii, 0);
4684 }
4685 } else {
4686 if (mptscsih_is_phys_disk(hd->ioc, ii) == 1) {
4687 dnegoprintk(("writeSDP1: id=%d SCSICFG_USE_NVRAM\n", id));
4688 mptscsih_writeSDP1(hd, 0, ii, MPT_SCSICFG_USE_NVRAM);
4689 }
4690 }
4691 }
4692 return;
4693}
4694
4695
4696
4697#define MPT_GET_NVRAM_VALS 0x01
4698#define MPT_UPDATE_MAX 0x02
4699#define MPT_SET_MAX 0x04
4700#define MPT_SET_MIN 0x08
4701#define MPT_FALLBACK 0x10
4702#define MPT_SAVE 0x20
4703
4704/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4705/**
4706 * mptscsih_doDv - Perform domain validation to a target.
4707 * @hd: Pointer to MPT_SCSI_HOST structure.
4708 * @portnum: IOC port number.
4709 * @target: Physical ID of this target
4710 *
4711 * Uses the ISR, but with special processing.
4712 * MUST be single-threaded.
4713 * Test will exit if target is at async & narrow.
4714 *
4715 * Return: None.
4716 */
4717static int
4718mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4719{
4720 MPT_ADAPTER *ioc = hd->ioc;
4721 VirtDevice *pTarget;
4722 SCSIDevicePage1_t *pcfg1Data;
4723 SCSIDevicePage0_t *pcfg0Data;
4724 u8 *pbuf1;
4725 u8 *pbuf2;
4726 u8 *pDvBuf;
4727 dma_addr_t dvbuf_dma = -1;
4728 dma_addr_t buf1_dma = -1;
4729 dma_addr_t buf2_dma = -1;
4730 dma_addr_t cfg1_dma_addr = -1;
4731 dma_addr_t cfg0_dma_addr = -1;
4732 ConfigPageHeader_t header1;
4733 ConfigPageHeader_t header0;
4734 DVPARAMETERS dv;
4735 INTERNAL_CMD iocmd;
4736 CONFIGPARMS cfg;
4737 int dv_alloc = 0;
4738 int rc, sz = 0;
4739 int bufsize = 0;
4740 int dataBufSize = 0;
4741 int echoBufSize = 0;
4742 int notDone;
4743 int patt;
4744 int repeat;
4745 int retcode = 0;
4746 int nfactor = MPT_ULTRA320;
4747 char firstPass = 1;
4748 char doFallback = 0;
4749 char readPage0;
4750 char bus, lun;
4751 char inq0 = 0;
4752
4753 if (ioc->spi_data.sdp1length == 0)
4754 return 0;
4755
4756 if (ioc->spi_data.sdp0length == 0)
4757 return 0;
4758
4759 /* If multiple buses are used, require that the initiator
4760 * id be the same on all buses.
4761 */
4762 if (id == ioc->pfacts[0].PortSCSIID)
4763 return 0;
4764
4765 lun = 0;
4766 bus = (u8) bus_number;
4767 ddvtprintk((MYIOC_s_NOTE_FMT
4768 "DV started: bus=%d, id=%d dv @ %p\n",
4769 ioc->name, bus, id, &dv));
4770
4771 /* Prep DV structure
4772 */
4773 memset (&dv, 0, sizeof(DVPARAMETERS));
4774 dv.id = id;
4775
4776 /* Populate tmax with the current maximum
4777 * transfer parameters for this target.
4778 * Exit if narrow and async.
4779 */
4780 dv.cmd = MPT_GET_NVRAM_VALS;
4781 mptscsih_dv_parms(hd, &dv, NULL);
4782
4783 /* Prep SCSI IO structure
4784 */
4785 iocmd.id = id;
4786 iocmd.bus = bus;
4787 iocmd.lun = lun;
4788 iocmd.flags = 0;
4789 iocmd.physDiskNum = -1;
4790 iocmd.rsvd = iocmd.rsvd2 = 0;
4791
4792 pTarget = hd->Targets[id];
4793
4794 /* Use tagged commands if possible.
4795 */
4796 if (pTarget) {
4797 if (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
4798 iocmd.flags |= MPT_ICFLAG_TAGGED_CMD;
4799 else {
4800 if (hd->ioc->facts.FWVersion.Word < 0x01000600)
4801 return 0;
4802
4803 if ((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
4804 (hd->ioc->facts.FWVersion.Word < 0x01010B00))
4805 return 0;
4806 }
4807 }
4808
4809 /* Prep cfg structure
4810 */
4811 cfg.pageAddr = (bus<<8) | id;
4812 cfg.hdr = NULL;
4813
4814 /* Prep SDP0 header
4815 */
4816 header0.PageVersion = ioc->spi_data.sdp0version;
4817 header0.PageLength = ioc->spi_data.sdp0length;
4818 header0.PageNumber = 0;
4819 header0.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4820
4821 /* Prep SDP1 header
4822 */
4823 header1.PageVersion = ioc->spi_data.sdp1version;
4824 header1.PageLength = ioc->spi_data.sdp1length;
4825 header1.PageNumber = 1;
4826 header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4827
4828 if (header0.PageLength & 1)
4829 dv_alloc = (header0.PageLength * 4) + 4;
4830
4831 dv_alloc += (2048 + (header1.PageLength * 4));
4832
4833 pDvBuf = pci_alloc_consistent(ioc->pcidev, dv_alloc, &dvbuf_dma);
4834 if (pDvBuf == NULL)
4835 return 0;
4836
4837 sz = 0;
4838 pbuf1 = (u8 *)pDvBuf;
4839 buf1_dma = dvbuf_dma;
4840 sz +=1024;
4841
4842 pbuf2 = (u8 *) (pDvBuf + sz);
4843 buf2_dma = dvbuf_dma + sz;
4844 sz +=1024;
4845
4846 pcfg0Data = (SCSIDevicePage0_t *) (pDvBuf + sz);
4847 cfg0_dma_addr = dvbuf_dma + sz;
4848 sz += header0.PageLength * 4;
4849
4850 /* 8-byte alignment
4851 */
4852 if (header0.PageLength & 1)
4853 sz += 4;
4854
4855 pcfg1Data = (SCSIDevicePage1_t *) (pDvBuf + sz);
4856 cfg1_dma_addr = dvbuf_dma + sz;
4857
4858 /* Skip this ID? Set cfg.hdr to force config page write
4859 */
4860 {
4861 ScsiCfgData *pspi_data = &hd->ioc->spi_data;
4862 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
4863 /* Set the factor from nvram */
4864 nfactor = (pspi_data->nvram[id] & MPT_NVRAM_SYNC_MASK) >> 8;
4865 if (nfactor < pspi_data->minSyncFactor )
4866 nfactor = pspi_data->minSyncFactor;
4867
4868 if (!(pspi_data->nvram[id] & MPT_NVRAM_ID_SCAN_ENABLE) ||
4869 (pspi_data->PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_OFF_DV) ) {
4870
4871 ddvprintk((MYIOC_s_NOTE_FMT "DV Skipped: bus, id, lun (%d, %d, %d)\n",
4872 ioc->name, bus, id, lun));
4873
4874 dv.cmd = MPT_SET_MAX;
4875 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4876 cfg.hdr = &header1;
4877
4878 /* Save the final negotiated settings to
4879 * SCSI device page 1.
4880 */
4881 cfg.physAddr = cfg1_dma_addr;
4882 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4883 cfg.dir = 1;
4884 mpt_config(hd->ioc, &cfg);
4885 goto target_done;
4886 }
4887 }
4888 }
4889
4890 /* Finish iocmd inititialization - hidden or visible disk? */
4891 if (ioc->spi_data.pIocPg3) {
4892 /* Search IOC page 3 for matching id
4893 */
4894 Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
4895 int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
4896
4897 while (numPDisk) {
4898 if (pPDisk->PhysDiskID == id) {
4899 /* match */
4900 iocmd.flags |= MPT_ICFLAG_PHYS_DISK;
4901 iocmd.physDiskNum = pPDisk->PhysDiskNum;
4902
4903 /* Quiesce the IM
4904 */
4905 if (mptscsih_do_raid(hd, MPI_RAID_ACTION_QUIESCE_PHYS_IO, &iocmd) < 0) {
4906 ddvprintk((MYIOC_s_ERR_FMT "RAID Queisce FAILED!\n", ioc->name));
4907 goto target_done;
4908 }
4909 break;
4910 }
4911 pPDisk++;
4912 numPDisk--;
4913 }
4914 }
4915
4916 /* RAID Volume ID's may double for a physical device. If RAID but
4917 * not a physical ID as well, skip DV.
4918 */
4919 if ((hd->ioc->spi_data.isRaid & (1 << id)) && !(iocmd.flags & MPT_ICFLAG_PHYS_DISK))
4920 goto target_done;
4921
4922
4923 /* Basic Test.
4924 * Async & Narrow - Inquiry
4925 * Async & Narrow - Inquiry
4926 * Maximum transfer rate - Inquiry
4927 * Compare buffers:
4928 * If compare, test complete.
4929 * If miscompare and first pass, repeat
4930 * If miscompare and not first pass, fall back and repeat
4931 */
4932 hd->pLocal = NULL;
4933 readPage0 = 0;
4934 sz = SCSI_MAX_INQUIRY_BYTES;
4935 rc = MPT_SCANDV_GOOD;
4936 while (1) {
4937 ddvprintk((MYIOC_s_NOTE_FMT "DV: Start Basic test on id=%d\n", ioc->name, id));
4938 retcode = 0;
4939 dv.cmd = MPT_SET_MIN;
4940 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4941
4942 cfg.hdr = &header1;
4943 cfg.physAddr = cfg1_dma_addr;
4944 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4945 cfg.dir = 1;
4946 if (mpt_config(hd->ioc, &cfg) != 0)
4947 goto target_done;
4948
4949 /* Wide - narrow - wide workaround case
4950 */
4951 if ((rc == MPT_SCANDV_ISSUE_SENSE) && dv.max.width) {
4952 /* Send an untagged command to reset disk Qs corrupted
4953 * when a parity error occurs on a Request Sense.
4954 */
4955 if ((hd->ioc->facts.FWVersion.Word >= 0x01000600) ||
4956 ((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
4957 (hd->ioc->facts.FWVersion.Word < 0x01010B00)) ) {
4958
4959 iocmd.cmd = REQUEST_SENSE;
4960 iocmd.data_dma = buf1_dma;
4961 iocmd.data = pbuf1;
4962 iocmd.size = 0x12;
4963 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4964 goto target_done;
4965 else {
4966 if (hd->pLocal == NULL)
4967 goto target_done;
4968 rc = hd->pLocal->completion;
4969 if ((rc == MPT_SCANDV_GOOD) || (rc == MPT_SCANDV_SENSE)) {
4970 dv.max.width = 0;
4971 doFallback = 0;
4972 } else
4973 goto target_done;
4974 }
4975 } else
4976 goto target_done;
4977 }
4978
4979 iocmd.cmd = INQUIRY;
4980 iocmd.data_dma = buf1_dma;
4981 iocmd.data = pbuf1;
4982 iocmd.size = sz;
4983 memset(pbuf1, 0x00, sz);
4984 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4985 goto target_done;
4986 else {
4987 if (hd->pLocal == NULL)
4988 goto target_done;
4989 rc = hd->pLocal->completion;
4990 if (rc == MPT_SCANDV_GOOD) {
4991 if (hd->pLocal->scsiStatus == SAM_STAT_BUSY) {
4992 if ((iocmd.flags & MPT_ICFLAG_TAGGED_CMD) == 0)
4993 retcode = 1;
4994 else
4995 retcode = 0;
4996
4997 goto target_done;
4998 }
4999 } else if (rc == MPT_SCANDV_SENSE) {
5000 ;
5001 } else {
5002 /* If first command doesn't complete
5003 * with a good status or with a check condition,
5004 * exit.
5005 */
5006 goto target_done;
5007 }
5008 }
5009
5010 /* Reset the size for disks
5011 */
5012 inq0 = (*pbuf1) & 0x1F;
5013 if ((inq0 == 0) && pTarget && !pTarget->raidVolume) {
5014 sz = 0x40;
5015 iocmd.size = sz;
5016 }
5017
5018 /* Another GEM workaround. Check peripheral device type,
5019 * if PROCESSOR, quit DV.
5020 */
5021 if (inq0 == TYPE_PROCESSOR) {
5022 mptscsih_initTarget(hd,
5023 bus,
5024 id,
5025 lun,
5026 pbuf1,
5027 sz);
5028 goto target_done;
5029 }
5030
5031 if (inq0 > 0x08)
5032 goto target_done;
5033
5034 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5035 goto target_done;
5036
5037 if (sz == 0x40) {
5038 if ((pTarget->maxWidth == 1) && (pTarget->maxOffset) && (nfactor < 0x0A)
5039 && (pTarget->minSyncFactor > 0x09)) {
5040 if ((pbuf1[56] & 0x04) == 0)
5041 ;
5042 else if ((pbuf1[56] & 0x01) == 1) {
5043 pTarget->minSyncFactor =
5044 nfactor > MPT_ULTRA320 ? nfactor : MPT_ULTRA320;
5045 } else {
5046 pTarget->minSyncFactor =
5047 nfactor > MPT_ULTRA160 ? nfactor : MPT_ULTRA160;
5048 }
5049
5050 dv.max.factor = pTarget->minSyncFactor;
5051
5052 if ((pbuf1[56] & 0x02) == 0) {
5053 pTarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
5054 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
5055 ddvprintk((MYIOC_s_NOTE_FMT
5056 "DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n",
5057 ioc->name, id, pbuf1[56]));
5058 }
5059 }
5060 }
5061
5062 if (doFallback)
5063 dv.cmd = MPT_FALLBACK;
5064 else
5065 dv.cmd = MPT_SET_MAX;
5066
5067 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5068 if (mpt_config(hd->ioc, &cfg) != 0)
5069 goto target_done;
5070
5071 if ((!dv.now.width) && (!dv.now.offset))
5072 goto target_done;
5073
5074 iocmd.cmd = INQUIRY;
5075 iocmd.data_dma = buf2_dma;
5076 iocmd.data = pbuf2;
5077 iocmd.size = sz;
5078 memset(pbuf2, 0x00, sz);
5079 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5080 goto target_done;
5081 else if (hd->pLocal == NULL)
5082 goto target_done;
5083 else {
5084 /* Save the return code.
5085 * If this is the first pass,
5086 * read SCSI Device Page 0
5087 * and update the target max parameters.
5088 */
5089 rc = hd->pLocal->completion;
5090 doFallback = 0;
5091 if (rc == MPT_SCANDV_GOOD) {
5092 if (!readPage0) {
5093 u32 sdp0_info;
5094 u32 sdp0_nego;
5095
5096 cfg.hdr = &header0;
5097 cfg.physAddr = cfg0_dma_addr;
5098 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5099 cfg.dir = 0;
5100
5101 if (mpt_config(hd->ioc, &cfg) != 0)
5102 goto target_done;
5103
5104 sdp0_info = le32_to_cpu(pcfg0Data->Information) & 0x0E;
5105 sdp0_nego = (le32_to_cpu(pcfg0Data->NegotiatedParameters) & 0xFF00 ) >> 8;
5106
5107 /* Quantum and Fujitsu workarounds.
5108 * Quantum: PPR U320 -> PPR reply with Ultra2 and wide
5109 * Fujitsu: PPR U320 -> Msg Reject and Ultra2 and wide
5110 * Resetart with a request for U160.
5111 */
5112 if ((dv.now.factor == MPT_ULTRA320) && (sdp0_nego == MPT_ULTRA2)) {
5113 doFallback = 1;
5114 } else {
5115 dv.cmd = MPT_UPDATE_MAX;
5116 mptscsih_dv_parms(hd, &dv, (void *)pcfg0Data);
5117 /* Update the SCSI device page 1 area
5118 */
5119 pcfg1Data->RequestedParameters = pcfg0Data->NegotiatedParameters;
5120 readPage0 = 1;
5121 }
5122 }
5123
5124 /* Quantum workaround. Restart this test will the fallback
5125 * flag set.
5126 */
5127 if (doFallback == 0) {
5128 if (memcmp(pbuf1, pbuf2, sz) != 0) {
5129 if (!firstPass)
5130 doFallback = 1;
5131 } else {
5132 ddvprintk((MYIOC_s_NOTE_FMT
5133 "DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id));
5134 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE;
5135 mptscsih_initTarget(hd,
5136 bus,
5137 id,
5138 lun,
5139 pbuf1,
5140 sz);
5141 break; /* test complete */
5142 }
5143 }
5144
5145
5146 } else if (rc == MPT_SCANDV_ISSUE_SENSE)
5147 doFallback = 1; /* set fallback flag */
5148 else if ((rc == MPT_SCANDV_DID_RESET) ||
5149 (rc == MPT_SCANDV_SENSE) ||
5150 (rc == MPT_SCANDV_FALLBACK))
5151 doFallback = 1; /* set fallback flag */
5152 else
5153 goto target_done;
5154
5155 firstPass = 0;
5156 }
5157 }
5158 ddvprintk((MYIOC_s_NOTE_FMT "DV: Basic test on id=%d completed OK.\n", ioc->name, id));
5159
5160 if (mpt_dv == 0)
5161 goto target_done;
5162
5163 inq0 = (*pbuf1) & 0x1F;
5164
5165 /* Continue only for disks
5166 */
5167 if (inq0 != 0)
5168 goto target_done;
5169
5170 if ( ioc->spi_data.PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_BASIC_DV_ONLY )
5171 goto target_done;
5172
5173 /* Start the Enhanced Test.
5174 * 0) issue TUR to clear out check conditions
5175 * 1) read capacity of echo (regular) buffer
5176 * 2) reserve device
5177 * 3) do write-read-compare data pattern test
5178 * 4) release
5179 * 5) update nego parms to target struct
5180 */
5181 cfg.hdr = &header1;
5182 cfg.physAddr = cfg1_dma_addr;
5183 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5184 cfg.dir = 1;
5185
5186 iocmd.cmd = TEST_UNIT_READY;
5187 iocmd.data_dma = -1;
5188 iocmd.data = NULL;
5189 iocmd.size = 0;
5190 notDone = 1;
5191 while (notDone) {
5192 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5193 goto target_done;
5194
5195 if (hd->pLocal == NULL)
5196 goto target_done;
5197
5198 rc = hd->pLocal->completion;
5199 if (rc == MPT_SCANDV_GOOD)
5200 notDone = 0;
5201 else if (rc == MPT_SCANDV_SENSE) {
5202 u8 skey = hd->pLocal->sense[2] & 0x0F;
5203 u8 asc = hd->pLocal->sense[12];
5204 u8 ascq = hd->pLocal->sense[13];
5205 ddvprintk((MYIOC_s_INFO_FMT
5206 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
5207 ioc->name, skey, asc, ascq));
5208
5209 if (skey == UNIT_ATTENTION)
5210 notDone++; /* repeat */
5211 else if ((skey == NOT_READY) &&
5212 (asc == 0x04)&&(ascq == 0x01)) {
5213 /* wait then repeat */
5214 mdelay (2000);
5215 notDone++;
5216 } else if ((skey == NOT_READY) && (asc == 0x3A)) {
5217 /* no medium, try read test anyway */
5218 notDone = 0;
5219 } else {
5220 /* All other errors are fatal.
5221 */
5222 ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
5223 ioc->name));
5224 goto target_done;
5225 }
5226 } else
5227 goto target_done;
5228 }
5229
5230 iocmd.cmd = READ_BUFFER;
5231 iocmd.data_dma = buf1_dma;
5232 iocmd.data = pbuf1;
5233 iocmd.size = 4;
5234 iocmd.flags |= MPT_ICFLAG_BUF_CAP;
5235
5236 dataBufSize = 0;
5237 echoBufSize = 0;
5238 for (patt = 0; patt < 2; patt++) {
5239 if (patt == 0)
5240 iocmd.flags |= MPT_ICFLAG_ECHO;
5241 else
5242 iocmd.flags &= ~MPT_ICFLAG_ECHO;
5243
5244 notDone = 1;
5245 while (notDone) {
5246 bufsize = 0;
5247
5248 /* If not ready after 8 trials,
5249 * give up on this device.
5250 */
5251 if (notDone > 8)
5252 goto target_done;
5253
5254 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5255 goto target_done;
5256 else if (hd->pLocal == NULL)
5257 goto target_done;
5258 else {
5259 rc = hd->pLocal->completion;
5260 ddvprintk(("ReadBuffer Comp Code %d", rc));
5261 ddvprintk((" buff: %0x %0x %0x %0x\n",
5262 pbuf1[0], pbuf1[1], pbuf1[2], pbuf1[3]));
5263
5264 if (rc == MPT_SCANDV_GOOD) {
5265 notDone = 0;
5266 if (iocmd.flags & MPT_ICFLAG_ECHO) {
5267 bufsize = ((pbuf1[2] & 0x1F) <<8) | pbuf1[3];
5268 } else {
5269 bufsize = pbuf1[1]<<16 | pbuf1[2]<<8 | pbuf1[3];
5270 }
5271 } else if (rc == MPT_SCANDV_SENSE) {
5272 u8 skey = hd->pLocal->sense[2] & 0x0F;
5273 u8 asc = hd->pLocal->sense[12];
5274 u8 ascq = hd->pLocal->sense[13];
5275 ddvprintk((MYIOC_s_INFO_FMT
5276 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
5277 ioc->name, skey, asc, ascq));
5278 if (skey == ILLEGAL_REQUEST) {
5279 notDone = 0;
5280 } else if (skey == UNIT_ATTENTION) {
5281 notDone++; /* repeat */
5282 } else if ((skey == NOT_READY) &&
5283 (asc == 0x04)&&(ascq == 0x01)) {
5284 /* wait then repeat */
5285 mdelay (2000);
5286 notDone++;
5287 } else {
5288 /* All other errors are fatal.
5289 */
5290 ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
5291 ioc->name));
5292 goto target_done;
5293 }
5294 } else {
5295 /* All other errors are fatal
5296 */
5297 goto target_done;
5298 }
5299 }
5300 }
5301
5302 if (iocmd.flags & MPT_ICFLAG_ECHO)
5303 echoBufSize = bufsize;
5304 else
5305 dataBufSize = bufsize;
5306 }
5307 sz = 0;
5308 iocmd.flags &= ~MPT_ICFLAG_BUF_CAP;
5309
5310 /* Use echo buffers if possible,
5311 * Exit if both buffers are 0.
5312 */
5313 if (echoBufSize > 0) {
5314 iocmd.flags |= MPT_ICFLAG_ECHO;
5315 if (dataBufSize > 0)
5316 bufsize = min(echoBufSize, dataBufSize);
5317 else
5318 bufsize = echoBufSize;
5319 } else if (dataBufSize == 0)
5320 goto target_done;
5321
5322 ddvprintk((MYIOC_s_INFO_FMT "%s Buffer Capacity %d\n", ioc->name,
5323 (iocmd.flags & MPT_ICFLAG_ECHO) ? "Echo" : " ", bufsize));
5324
5325 /* Data buffers for write-read-compare test max 1K.
5326 */
5327 sz = min(bufsize, 1024);
5328
5329 /* --- loop ----
5330 * On first pass, always issue a reserve.
5331 * On additional loops, only if a reset has occurred.
5332 * iocmd.flags indicates if echo or regular buffer
5333 */
5334 for (patt = 0; patt < 4; patt++) {
5335 ddvprintk(("Pattern %d\n", patt));
5336 if ((iocmd.flags & MPT_ICFLAG_RESERVED) && (iocmd.flags & MPT_ICFLAG_DID_RESET)) {
5337 iocmd.cmd = TEST_UNIT_READY;
5338 iocmd.data_dma = -1;
5339 iocmd.data = NULL;
5340 iocmd.size = 0;
5341 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5342 goto target_done;
5343
5344 iocmd.cmd = RELEASE;
5345 iocmd.data_dma = -1;
5346 iocmd.data = NULL;
5347 iocmd.size = 0;
5348 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5349 goto target_done;
5350 else if (hd->pLocal == NULL)
5351 goto target_done;
5352 else {
5353 rc = hd->pLocal->completion;
5354 ddvprintk(("Release rc %d\n", rc));
5355 if (rc == MPT_SCANDV_GOOD)
5356 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
5357 else
5358 goto target_done;
5359 }
5360 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
5361 }
5362 iocmd.flags &= ~MPT_ICFLAG_DID_RESET;
5363
5364 repeat = 5;
5365 while (repeat && (!(iocmd.flags & MPT_ICFLAG_RESERVED))) {
5366 iocmd.cmd = RESERVE;
5367 iocmd.data_dma = -1;
5368 iocmd.data = NULL;
5369 iocmd.size = 0;
5370 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5371 goto target_done;
5372 else if (hd->pLocal == NULL)
5373 goto target_done;
5374 else {
5375 rc = hd->pLocal->completion;
5376 if (rc == MPT_SCANDV_GOOD) {
5377 iocmd.flags |= MPT_ICFLAG_RESERVED;
5378 } else if (rc == MPT_SCANDV_SENSE) {
5379 /* Wait if coming ready
5380 */
5381 u8 skey = hd->pLocal->sense[2] & 0x0F;
5382 u8 asc = hd->pLocal->sense[12];
5383 u8 ascq = hd->pLocal->sense[13];
5384 ddvprintk((MYIOC_s_INFO_FMT
5385 "DV: Reserve Failed: ", ioc->name));
5386 ddvprintk(("SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
5387 skey, asc, ascq));
5388
5389 if ((skey == NOT_READY) && (asc == 0x04)&&
5390 (ascq == 0x01)) {
5391 /* wait then repeat */
5392 mdelay (2000);
5393 notDone++;
5394 } else {
5395 ddvprintk((MYIOC_s_INFO_FMT
5396 "DV: Reserved Failed.", ioc->name));
5397 goto target_done;
5398 }
5399 } else {
5400 ddvprintk((MYIOC_s_INFO_FMT "DV: Reserved Failed.",
5401 ioc->name));
5402 goto target_done;
5403 }
5404 }
5405 }
5406
5407 mptscsih_fillbuf(pbuf1, sz, patt, 1);
5408 iocmd.cmd = WRITE_BUFFER;
5409 iocmd.data_dma = buf1_dma;
5410 iocmd.data = pbuf1;
5411 iocmd.size = sz;
5412 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5413 goto target_done;
5414 else if (hd->pLocal == NULL)
5415 goto target_done;
5416 else {
5417 rc = hd->pLocal->completion;
5418 if (rc == MPT_SCANDV_GOOD)
5419 ; /* Issue read buffer */
5420 else if (rc == MPT_SCANDV_DID_RESET) {
5421 /* If using echo buffers, reset to data buffers.
5422 * Else do Fallback and restart
5423 * this test (re-issue reserve
5424 * because of bus reset).
5425 */
5426 if ((iocmd.flags & MPT_ICFLAG_ECHO) && (dataBufSize >= bufsize)) {
5427 iocmd.flags &= ~MPT_ICFLAG_ECHO;
5428 } else {
5429 dv.cmd = MPT_FALLBACK;
5430 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5431
5432 if (mpt_config(hd->ioc, &cfg) != 0)
5433 goto target_done;
5434
5435 if ((!dv.now.width) && (!dv.now.offset))
5436 goto target_done;
5437 }
5438
5439 iocmd.flags |= MPT_ICFLAG_DID_RESET;
5440 patt = -1;
5441 continue;
5442 } else if (rc == MPT_SCANDV_SENSE) {
5443 /* Restart data test if UA, else quit.
5444 */
5445 u8 skey = hd->pLocal->sense[2] & 0x0F;
5446 ddvprintk((MYIOC_s_INFO_FMT
5447 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
5448 hd->pLocal->sense[12], hd->pLocal->sense[13]));
5449 if (skey == UNIT_ATTENTION) {
5450 patt = -1;
5451 continue;
5452 } else if (skey == ILLEGAL_REQUEST) {
5453 if (iocmd.flags & MPT_ICFLAG_ECHO) {
5454 if (dataBufSize >= bufsize) {
5455 iocmd.flags &= ~MPT_ICFLAG_ECHO;
5456 patt = -1;
5457 continue;
5458 }
5459 }
5460 goto target_done;
5461 }
5462 else
5463 goto target_done;
5464 } else {
5465 /* fatal error */
5466 goto target_done;
5467 }
5468 }
5469
5470 iocmd.cmd = READ_BUFFER;
5471 iocmd.data_dma = buf2_dma;
5472 iocmd.data = pbuf2;
5473 iocmd.size = sz;
5474 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5475 goto target_done;
5476 else if (hd->pLocal == NULL)
5477 goto target_done;
5478 else {
5479 rc = hd->pLocal->completion;
5480 if (rc == MPT_SCANDV_GOOD) {
5481 /* If buffers compare,
5482 * go to next pattern,
5483 * else, do a fallback and restart
5484 * data transfer test.
5485 */
5486 if (memcmp (pbuf1, pbuf2, sz) == 0) {
5487 ; /* goto next pattern */
5488 } else {
5489 /* Miscompare with Echo buffer, go to data buffer,
5490 * if that buffer exists.
5491 * Miscompare with Data buffer, check first 4 bytes,
5492 * some devices return capacity. Exit in this case.
5493 */
5494 if (iocmd.flags & MPT_ICFLAG_ECHO) {
5495 if (dataBufSize >= bufsize)
5496 iocmd.flags &= ~MPT_ICFLAG_ECHO;
5497 else
5498 goto target_done;
5499 } else {
5500 if (dataBufSize == (pbuf2[1]<<16 | pbuf2[2]<<8 | pbuf2[3])) {
5501 /* Argh. Device returning wrong data.
5502 * Quit DV for this device.
5503 */
5504 goto target_done;
5505 }
5506
5507 /* Had an actual miscompare. Slow down.*/
5508 dv.cmd = MPT_FALLBACK;
5509 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5510
5511 if (mpt_config(hd->ioc, &cfg) != 0)
5512 goto target_done;
5513
5514 if ((!dv.now.width) && (!dv.now.offset))
5515 goto target_done;
5516 }
5517
5518 patt = -1;
5519 continue;
5520 }
5521 } else if (rc == MPT_SCANDV_DID_RESET) {
5522 /* Do Fallback and restart
5523 * this test (re-issue reserve
5524 * because of bus reset).
5525 */
5526 dv.cmd = MPT_FALLBACK;
5527 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5528
5529 if (mpt_config(hd->ioc, &cfg) != 0)
5530 goto target_done;
5531
5532 if ((!dv.now.width) && (!dv.now.offset))
5533 goto target_done;
5534
5535 iocmd.flags |= MPT_ICFLAG_DID_RESET;
5536 patt = -1;
5537 continue;
5538 } else if (rc == MPT_SCANDV_SENSE) {
5539 /* Restart data test if UA, else quit.
5540 */
5541 u8 skey = hd->pLocal->sense[2] & 0x0F;
5542 ddvprintk((MYIOC_s_INFO_FMT
5543 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
5544 hd->pLocal->sense[12], hd->pLocal->sense[13]));
5545 if (skey == UNIT_ATTENTION) {
5546 patt = -1;
5547 continue;
5548 }
5549 else
5550 goto target_done;
5551 } else {
5552 /* fatal error */
5553 goto target_done;
5554 }
5555 }
5556
5557 } /* --- end of patt loop ---- */
5558
5559target_done:
5560 if (iocmd.flags & MPT_ICFLAG_RESERVED) {
5561 iocmd.cmd = RELEASE;
5562 iocmd.data_dma = -1;
5563 iocmd.data = NULL;
5564 iocmd.size = 0;
5565 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5566 printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
5567 ioc->name, id);
5568 else if (hd->pLocal) {
5569 if (hd->pLocal->completion == MPT_SCANDV_GOOD)
5570 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
5571 } else {
5572 printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
5573 ioc->name, id);
5574 }
5575 }
5576
5577
5578 /* Set if cfg1_dma_addr contents is valid
5579 */
5580 if ((cfg.hdr != NULL) && (retcode == 0)){
5581 /* If disk, not U320, disable QAS
5582 */
5583 if ((inq0 == 0) && (dv.now.factor > MPT_ULTRA320)) {
5584 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
5585 ddvprintk((MYIOC_s_NOTE_FMT
5586 "noQas set due to id=%d has factor=%x\n", ioc->name, id, dv.now.factor));
5587 }
5588
5589 dv.cmd = MPT_SAVE;
5590 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5591
5592 /* Double writes to SDP1 can cause problems,
5593 * skip save of the final negotiated settings to
5594 * SCSI device page 1.
5595 *
5596 cfg.hdr = &header1;
5597 cfg.physAddr = cfg1_dma_addr;
5598 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5599 cfg.dir = 1;
5600 mpt_config(hd->ioc, &cfg);
5601 */
5602 }
5603
5604 /* If this is a RAID Passthrough, enable internal IOs
5605 */
5606 if (iocmd.flags & MPT_ICFLAG_PHYS_DISK) {
5607 if (mptscsih_do_raid(hd, MPI_RAID_ACTION_ENABLE_PHYS_IO, &iocmd) < 0)
5608 ddvprintk((MYIOC_s_ERR_FMT "RAID Enable FAILED!\n", ioc->name));
5609 }
5610
5611 /* Done with the DV scan of the current target
5612 */
5613 if (pDvBuf)
5614 pci_free_consistent(ioc->pcidev, dv_alloc, pDvBuf, dvbuf_dma);
5615
5616 ddvtprintk((MYIOC_s_INFO_FMT "DV Done id=%d\n",
5617 ioc->name, id));
5618
5619 return retcode;
5620}
5621
5622/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5623/* mptscsih_dv_parms - perform a variety of operations on the
5624 * parameters used for negotiation.
5625 * @hd: Pointer to a SCSI host.
5626 * @dv: Pointer to a structure that contains the maximum and current
5627 * negotiated parameters.
5628 */
5629static void
5630mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
5631{
5632 VirtDevice *pTarget;
5633 SCSIDevicePage0_t *pPage0;
5634 SCSIDevicePage1_t *pPage1;
5635 int val = 0, data, configuration;
5636 u8 width = 0;
5637 u8 offset = 0;
5638 u8 factor = 0;
5639 u8 negoFlags = 0;
5640 u8 cmd = dv->cmd;
5641 u8 id = dv->id;
5642
5643 switch (cmd) {
5644 case MPT_GET_NVRAM_VALS:
5645 ddvprintk((MYIOC_s_NOTE_FMT "Getting NVRAM: ",
5646 hd->ioc->name));
5647 /* Get the NVRAM values and save in tmax
5648 * If not an LVD bus, the adapter minSyncFactor has been
5649 * already throttled back.
5650 */
5651 if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume) {
5652 width = pTarget->maxWidth;
5653 offset = pTarget->maxOffset;
5654 factor = pTarget->minSyncFactor;
5655 negoFlags = pTarget->negoFlags;
5656 } else {
5657 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
5658 data = hd->ioc->spi_data.nvram[id];
5659 width = data & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
5660 if ((offset = hd->ioc->spi_data.maxSyncOffset) == 0)
5661 factor = MPT_ASYNC;
5662 else {
5663 factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
5664 if ((factor == 0) || (factor == MPT_ASYNC)){
5665 factor = MPT_ASYNC;
5666 offset = 0;
5667 }
5668 }
5669 } else {
5670 width = MPT_NARROW;
5671 offset = 0;
5672 factor = MPT_ASYNC;
5673 }
5674
5675 /* Set the negotiation flags */
5676 negoFlags = hd->ioc->spi_data.noQas;
5677 if (!width)
5678 negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
5679
5680 if (!offset)
5681 negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
5682 }
5683
5684 /* limit by adapter capabilities */
5685 width = min(width, hd->ioc->spi_data.maxBusWidth);
5686 offset = min(offset, hd->ioc->spi_data.maxSyncOffset);
5687 factor = max(factor, hd->ioc->spi_data.minSyncFactor);
5688
5689 /* Check Consistency */
5690 if (offset && (factor < MPT_ULTRA2) && !width)
5691 factor = MPT_ULTRA2;
5692
5693 dv->max.width = width;
5694 dv->max.offset = offset;
5695 dv->max.factor = factor;
5696 dv->max.flags = negoFlags;
5697 ddvprintk((" id=%d width=%d factor=%x offset=%x flags=%x\n",
5698 id, width, factor, offset, negoFlags));
5699 break;
5700
5701 case MPT_UPDATE_MAX:
5702 ddvprintk((MYIOC_s_NOTE_FMT
5703 "Updating with SDP0 Data: ", hd->ioc->name));
5704 /* Update tmax values with those from Device Page 0.*/
5705 pPage0 = (SCSIDevicePage0_t *) pPage;
5706 if (pPage0) {
5707 val = cpu_to_le32(pPage0->NegotiatedParameters);
5708 dv->max.width = val & MPI_SCSIDEVPAGE0_NP_WIDE ? 1 : 0;
5709 dv->max.offset = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) >> 16;
5710 dv->max.factor = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8;
5711 }
5712
5713 dv->now.width = dv->max.width;
5714 dv->now.offset = dv->max.offset;
5715 dv->now.factor = dv->max.factor;
5716 ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x\n",
5717 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
5718 break;
5719
5720 case MPT_SET_MAX:
5721 ddvprintk((MYIOC_s_NOTE_FMT "Setting Max: ",
5722 hd->ioc->name));
5723 /* Set current to the max values. Update the config page.*/
5724 dv->now.width = dv->max.width;
5725 dv->now.offset = dv->max.offset;
5726 dv->now.factor = dv->max.factor;
5727 dv->now.flags = dv->max.flags;
5728
5729 pPage1 = (SCSIDevicePage1_t *)pPage;
5730 if (pPage1) {
5731 mptscsih_setDevicePage1Flags (dv->now.width, dv->now.factor,
5732 dv->now.offset, &val, &configuration, dv->now.flags);
5733 dnegoprintk(("Setting Max: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
5734 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
5735 pPage1->RequestedParameters = le32_to_cpu(val);
5736 pPage1->Reserved = 0;
5737 pPage1->Configuration = le32_to_cpu(configuration);
5738 }
5739
5740 ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x request=%x configuration=%x\n",
5741 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
5742 break;
5743
5744 case MPT_SET_MIN:
5745 ddvprintk((MYIOC_s_NOTE_FMT "Setting Min: ",
5746 hd->ioc->name));
5747 /* Set page to asynchronous and narrow
5748 * Do not update now, breaks fallback routine. */
5749 width = MPT_NARROW;
5750 offset = 0;
5751 factor = MPT_ASYNC;
5752 negoFlags = dv->max.flags;
5753
5754 pPage1 = (SCSIDevicePage1_t *)pPage;
5755 if (pPage1) {
5756 mptscsih_setDevicePage1Flags (width, factor,
5757 offset, &val, &configuration, negoFlags);
5758 dnegoprintk(("Setting Min: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
5759 id, width, factor, offset, negoFlags, val, configuration));
5760 pPage1->RequestedParameters = le32_to_cpu(val);
5761 pPage1->Reserved = 0;
5762 pPage1->Configuration = le32_to_cpu(configuration);
5763 }
5764 ddvprintk(("id=%d width=%d factor=%x offset=%x request=%x config=%x negoFlags=%x\n",
5765 id, width, factor, offset, val, configuration, negoFlags));
5766 break;
5767
5768 case MPT_FALLBACK:
5769 ddvprintk((MYIOC_s_NOTE_FMT
5770 "Fallback: Start: offset %d, factor %x, width %d \n",
5771 hd->ioc->name, dv->now.offset,
5772 dv->now.factor, dv->now.width));
5773 width = dv->now.width;
5774 offset = dv->now.offset;
5775 factor = dv->now.factor;
5776 if ((offset) && (dv->max.width)) {
5777 if (factor < MPT_ULTRA160)
5778 factor = MPT_ULTRA160;
5779 else if (factor < MPT_ULTRA2) {
5780 factor = MPT_ULTRA2;
5781 width = MPT_WIDE;
5782 } else if ((factor == MPT_ULTRA2) && width) {
5783 factor = MPT_ULTRA2;
5784 width = MPT_NARROW;
5785 } else if (factor < MPT_ULTRA) {
5786 factor = MPT_ULTRA;
5787 width = MPT_WIDE;
5788 } else if ((factor == MPT_ULTRA) && width) {
5789 width = MPT_NARROW;
5790 } else if (factor < MPT_FAST) {
5791 factor = MPT_FAST;
5792 width = MPT_WIDE;
5793 } else if ((factor == MPT_FAST) && width) {
5794 factor = MPT_FAST;
5795 width = MPT_NARROW;
5796 } else if (factor < MPT_SCSI) {
5797 factor = MPT_SCSI;
5798 width = MPT_WIDE;
5799 } else if ((factor == MPT_SCSI) && width) {
5800 factor = MPT_SCSI;
5801 width = MPT_NARROW;
5802 } else {
5803 factor = MPT_ASYNC;
5804 offset = 0;
5805 }
5806
5807 } else if (offset) {
5808 width = MPT_NARROW;
5809 if (factor < MPT_ULTRA)
5810 factor = MPT_ULTRA;
5811 else if (factor < MPT_FAST)
5812 factor = MPT_FAST;
5813 else if (factor < MPT_SCSI)
5814 factor = MPT_SCSI;
5815 else {
5816 factor = MPT_ASYNC;
5817 offset = 0;
5818 }
5819
5820 } else {
5821 width = MPT_NARROW;
5822 factor = MPT_ASYNC;
5823 }
5824 dv->max.flags |= MPT_TARGET_NO_NEGO_QAS;
5825 dv->max.flags &= ~MPT_TAPE_NEGO_IDP;
5826
5827 dv->now.width = width;
5828 dv->now.offset = offset;
5829 dv->now.factor = factor;
5830 dv->now.flags = dv->max.flags;
5831
5832 pPage1 = (SCSIDevicePage1_t *)pPage;
5833 if (pPage1) {
5834 mptscsih_setDevicePage1Flags (width, factor, offset, &val,
5835 &configuration, dv->now.flags);
5836 dnegoprintk(("Finish: id=%d width=%d offset=%d factor=%x flags=%x request=%x config=%x\n",
5837 id, width, offset, factor, dv->now.flags, val, configuration));
5838
5839 pPage1->RequestedParameters = le32_to_cpu(val);
5840 pPage1->Reserved = 0;
5841 pPage1->Configuration = le32_to_cpu(configuration);
5842 }
5843
5844 ddvprintk(("Finish: id=%d offset=%d factor=%x width=%d request=%x config=%x\n",
5845 id, dv->now.offset, dv->now.factor, dv->now.width, val, configuration));
5846 break;
5847
5848 case MPT_SAVE:
5849 ddvprintk((MYIOC_s_NOTE_FMT
5850 "Saving to Target structure: ", hd->ioc->name));
5851 ddvprintk(("id=%d width=%x factor=%x offset=%d flags=%x\n",
5852 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
5853
5854 /* Save these values to target structures
5855 * or overwrite nvram (phys disks only).
5856 */
5857
5858 if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume ) {
5859 pTarget->maxWidth = dv->now.width;
5860 pTarget->maxOffset = dv->now.offset;
5861 pTarget->minSyncFactor = dv->now.factor;
5862 pTarget->negoFlags = dv->now.flags;
5863 } else {
5864 /* Preserv all flags, use
5865 * read-modify-write algorithm
5866 */
5867 if (hd->ioc->spi_data.nvram) {
5868 data = hd->ioc->spi_data.nvram[id];
5869
5870 if (dv->now.width)
5871 data &= ~MPT_NVRAM_WIDE_DISABLE;
5872 else
5873 data |= MPT_NVRAM_WIDE_DISABLE;
5874
5875 if (!dv->now.offset)
5876 factor = MPT_ASYNC;
5877
5878 data &= ~MPT_NVRAM_SYNC_MASK;
5879 data |= (dv->now.factor << MPT_NVRAM_SYNC_SHIFT) & MPT_NVRAM_SYNC_MASK;
5880
5881 hd->ioc->spi_data.nvram[id] = data;
5882 }
5883 }
5884 break;
5885 }
5886}
5887
5888/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5889/* mptscsih_fillbuf - fill a buffer with a special data pattern
5890 * cleanup. For bus scan only.
5891 *
5892 * @buffer: Pointer to data buffer to be filled.
5893 * @size: Number of bytes to fill
5894 * @index: Pattern index
5895 * @width: bus width, 0 (8 bits) or 1 (16 bits)
5896 */
5897static void
5898mptscsih_fillbuf(char *buffer, int size, int index, int width)
5899{
5900 char *ptr = buffer;
5901 int ii;
5902 char byte;
5903 short val;
5904
5905 switch (index) {
5906 case 0:
5907
5908 if (width) {
5909 /* Pattern: 0000 FFFF 0000 FFFF
5910 */
5911 for (ii=0; ii < size; ii++, ptr++) {
5912 if (ii & 0x02)
5913 *ptr = 0xFF;
5914 else
5915 *ptr = 0x00;
5916 }
5917 } else {
5918 /* Pattern: 00 FF 00 FF
5919 */
5920 for (ii=0; ii < size; ii++, ptr++) {
5921 if (ii & 0x01)
5922 *ptr = 0xFF;
5923 else
5924 *ptr = 0x00;
5925 }
5926 }
5927 break;
5928
5929 case 1:
5930 if (width) {
5931 /* Pattern: 5555 AAAA 5555 AAAA 5555
5932 */
5933 for (ii=0; ii < size; ii++, ptr++) {
5934 if (ii & 0x02)
5935 *ptr = 0xAA;
5936 else
5937 *ptr = 0x55;
5938 }
5939 } else {
5940 /* Pattern: 55 AA 55 AA 55
5941 */
5942 for (ii=0; ii < size; ii++, ptr++) {
5943 if (ii & 0x01)
5944 *ptr = 0xAA;
5945 else
5946 *ptr = 0x55;
5947 }
5948 }
5949 break;
5950
5951 case 2:
5952 /* Pattern: 00 01 02 03 04 05
5953 * ... FE FF 00 01..
5954 */
5955 for (ii=0; ii < size; ii++, ptr++)
5956 *ptr = (char) ii;
5957 break;
5958
5959 case 3:
5960 if (width) {
5961 /* Wide Pattern: FFFE 0001 FFFD 0002
5962 * ... 4000 DFFF 8000 EFFF
5963 */
5964 byte = 0;
5965 for (ii=0; ii < size/2; ii++) {
5966 /* Create the base pattern
5967 */
5968 val = (1 << byte);
5969 /* every 64 (0x40) bytes flip the pattern
5970 * since we fill 2 bytes / iteration,
5971 * test for ii = 0x20
5972 */
5973 if (ii & 0x20)
5974 val = ~(val);
5975
5976 if (ii & 0x01) {
5977 *ptr = (char)( (val & 0xFF00) >> 8);
5978 ptr++;
5979 *ptr = (char)(val & 0xFF);
5980 byte++;
5981 byte &= 0x0F;
5982 } else {
5983 val = ~val;
5984 *ptr = (char)( (val & 0xFF00) >> 8);
5985 ptr++;
5986 *ptr = (char)(val & 0xFF);
5987 }
5988
5989 ptr++;
5990 }
5991 } else {
5992 /* Narrow Pattern: FE 01 FD 02 FB 04
5993 * .. 7F 80 01 FE 02 FD ... 80 7F
5994 */
5995 byte = 0;
5996 for (ii=0; ii < size; ii++, ptr++) {
5997 /* Base pattern - first 32 bytes
5998 */
5999 if (ii & 0x01) {
6000 *ptr = (1 << byte);
6001 byte++;
6002 byte &= 0x07;
6003 } else {
6004 *ptr = (char) (~(1 << byte));
6005 }
6006
6007 /* Flip the pattern every 32 bytes
6008 */
6009 if (ii & 0x20)
6010 *ptr = ~(*ptr);
6011 }
6012 }
6013 break;
6014 }
6015}
6016#endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
6017
6018/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6019
6020module_init(mptscsih_init);
6021module_exit(mptscsih_exit);