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