2 * linux/drivers/message/fusion/mptscsih.c
3 * High performance SCSI / Fibre Channel SCSI Host device driver.
4 * For use with PCI chip/adapter(s):
5 * LSIFC9xx/LSI409xx Fibre Channel
6 * running LSI Logic Fusion MPT (Message Passing Technology) firmware.
9 * This driver would not exist if not for Alan Cox's development
10 * of the linux i2o driver.
12 * A special thanks to Pamela Delaney (LSI Logic) for tons of work
13 * and countless enhancements while adding support for the 1030
14 * chip family. Pam has been instrumental in the development of
15 * of the 2.xx.xx series fusion drivers, and her contributions are
16 * far too numerous to hope to list in one place.
18 * A huge debt of gratitude is owed to David S. Miller (DaveM)
19 * for fixing much of the stupid and broken stuff in the early
20 * driver while porting to sparc64 platform. THANK YOU!
24 * Copyright (c) 1999-2004 LSI Logic Corporation
25 * Original author: Steven J. Ralston
26 * (mailto:sjralston1@netscape.net)
27 * (mailto:mpt_linux_developer@lsil.com)
29 * $Id: mptscsih.c,v 1.104 2002/12/03 21:26:34 pdelaney Exp $
31 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
33 This program is free software; you can redistribute it and/or modify
34 it under the terms of the GNU General Public License as published by
35 the Free Software Foundation; version 2 of the License.
37 This program is distributed in the hope that it will be useful,
38 but WITHOUT ANY WARRANTY; without even the implied warranty of
39 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
40 GNU General Public License for more details.
43 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
44 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
45 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
46 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
47 solely responsible for determining the appropriateness of using and
48 distributing the Program and assumes all risks associated with its
49 exercise of rights under this Agreement, including but not limited to
50 the risks and costs of program errors, damage to or loss of data,
51 programs or equipment, and unavailability or interruption of operations.
53 DISCLAIMER OF LIABILITY
54 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
55 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
57 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
58 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
59 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
60 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
62 You should have received a copy of the GNU General Public License
63 along with this program; if not, write to the Free Software
64 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
66 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
68 #include "linux_compat.h" /* linux-2.6 tweaks */
69 #include <linux/module.h>
70 #include <linux/kernel.h>
71 #include <linux/init.h>
72 #include <linux/errno.h>
73 #include <linux/kdev_t.h>
74 #include <linux/blkdev.h>
75 #include <linux/delay.h> /* for mdelay */
76 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
77 #include <linux/reboot.h> /* notifier code */
78 #include <linux/sched.h>
79 #include <linux/workqueue.h>
81 #include <scsi/scsi.h>
82 #include <scsi/scsi_cmnd.h>
83 #include <scsi/scsi_device.h>
84 #include <scsi/scsi_host.h>
85 #include <scsi/scsi_tcq.h>
90 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
91 #define my_NAME "Fusion MPT SCSI Host driver"
92 #define my_VERSION MPT_LINUX_VERSION_COMMON
93 #define MYNAM "mptscsih"
95 MODULE_AUTHOR(MODULEAUTHOR
);
96 MODULE_DESCRIPTION(my_NAME
);
97 MODULE_LICENSE("GPL");
99 /* Command line args */
100 static int mpt_dv
= MPTSCSIH_DOMAIN_VALIDATION
;
101 MODULE_PARM(mpt_dv
, "i");
102 MODULE_PARM_DESC(mpt_dv
, " DV Algorithm: enhanced=1, basic=0 (default=MPTSCSIH_DOMAIN_VALIDATION=1)");
104 static int mpt_width
= MPTSCSIH_MAX_WIDTH
;
105 MODULE_PARM(mpt_width
, "i");
106 MODULE_PARM_DESC(mpt_width
, " Max Bus Width: wide=1, narrow=0 (default=MPTSCSIH_MAX_WIDTH=1)");
108 static int mpt_factor
= MPTSCSIH_MIN_SYNC
;
109 MODULE_PARM(mpt_factor
, "h");
110 MODULE_PARM_DESC(mpt_factor
, " Min Sync Factor (default=MPTSCSIH_MIN_SYNC=0x08)");
112 static int mpt_saf_te
= MPTSCSIH_SAF_TE
;
113 MODULE_PARM(mpt_saf_te
, "i");
114 MODULE_PARM_DESC(mpt_saf_te
, " Force enabling SEP Processor: enable=1 (default=MPTSCSIH_SAF_TE=0)");
116 static int mpt_pq_filter
= 0;
117 MODULE_PARM(mpt_pq_filter
, "i");
118 MODULE_PARM_DESC(mpt_pq_filter
, " Enable peripheral qualifier filter: enable=1 (default=0)");
120 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
122 typedef struct _BIG_SENSE_BUF
{
123 u8 data
[MPT_SENSE_BUFFER_ALLOC
];
126 #define MPT_SCANDV_GOOD (0x00000000) /* must be 0 */
127 #define MPT_SCANDV_DID_RESET (0x00000001)
128 #define MPT_SCANDV_SENSE (0x00000002)
129 #define MPT_SCANDV_SOME_ERROR (0x00000004)
130 #define MPT_SCANDV_SELECTION_TIMEOUT (0x00000008)
131 #define MPT_SCANDV_ISSUE_SENSE (0x00000010)
132 #define MPT_SCANDV_FALLBACK (0x00000020)
134 #define MPT_SCANDV_MAX_RETRIES (10)
136 #define MPT_ICFLAG_BUF_CAP 0x01 /* ReadBuffer Read Capacity format */
137 #define MPT_ICFLAG_ECHO 0x02 /* ReadBuffer Echo buffer format */
138 #define MPT_ICFLAG_PHYS_DISK 0x04 /* Any SCSI IO but do Phys Disk Format */
139 #define MPT_ICFLAG_TAGGED_CMD 0x08 /* Do tagged IO */
140 #define MPT_ICFLAG_DID_RESET 0x20 /* Bus Reset occurred with this command */
141 #define MPT_ICFLAG_RESERVED 0x40 /* Reserved has been issued */
143 typedef struct _internal_cmd
{
144 char *data
; /* data pointer */
145 dma_addr_t data_dma
; /* data dma address */
146 int size
; /* transfer size */
147 u8 cmd
; /* SCSI Op Code */
148 u8 bus
; /* bus number */
149 u8 id
; /* SCSI ID (virtual) */
151 u8 flags
; /* Bit Field - See above */
152 u8 physDiskNum
; /* Phys disk number, -1 else */
157 typedef struct _negoparms
{
164 typedef struct _dv_parameters
{
174 * Other private/forward protos...
176 static int mptscsih_io_done(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
, MPT_FRAME_HDR
*r
);
177 static void mptscsih_report_queue_full(struct scsi_cmnd
*sc
, SCSIIOReply_t
*pScsiReply
, SCSIIORequest_t
*pScsiReq
);
178 static int mptscsih_taskmgmt_complete(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
, MPT_FRAME_HDR
*r
);
180 static int mptscsih_AddSGE(MPT_ADAPTER
*ioc
, struct scsi_cmnd
*SCpnt
,
181 SCSIIORequest_t
*pReq
, int req_idx
);
182 static void mptscsih_freeChainBuffers(MPT_ADAPTER
*ioc
, int req_idx
);
183 static void copy_sense_data(struct scsi_cmnd
*sc
, MPT_SCSI_HOST
*hd
, MPT_FRAME_HDR
*mf
, SCSIIOReply_t
*pScsiReply
);
184 static int mptscsih_tm_pending_wait(MPT_SCSI_HOST
* hd
);
185 static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST
* hd
, ulong timeout
);
186 static u32
SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd
*sc
);
188 static int mptscsih_TMHandler(MPT_SCSI_HOST
*hd
, u8 type
, u8 channel
, u8 target
, u8 lun
, int ctx2abort
, ulong timeout
);
189 static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST
*hd
, u8 type
, u8 channel
, u8 target
, u8 lun
, int ctx2abort
, ulong timeout
);
191 static int mptscsih_ioc_reset(MPT_ADAPTER
*ioc
, int post_reset
);
192 static int mptscsih_event_process(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*pEvReply
);
194 static void mptscsih_initTarget(MPT_SCSI_HOST
*hd
, int bus_id
, int target_id
, u8 lun
, char *data
, int dlen
);
195 static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST
*hd
, VirtDevice
*target
, char byte56
);
196 static void mptscsih_set_dvflags(MPT_SCSI_HOST
*hd
, SCSIIORequest_t
*pReq
);
197 static void mptscsih_setDevicePage1Flags (u8 width
, u8 factor
, u8 offset
, int *requestedPtr
, int *configurationPtr
, u8 flags
);
198 static void mptscsih_no_negotiate(MPT_SCSI_HOST
*hd
, int target_id
);
199 static int mptscsih_writeSDP1(MPT_SCSI_HOST
*hd
, int portnum
, int target
, int flags
);
200 static int mptscsih_writeIOCPage4(MPT_SCSI_HOST
*hd
, int target_id
, int bus
);
201 static int mptscsih_scandv_complete(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
, MPT_FRAME_HDR
*r
);
202 static void mptscsih_timer_expired(unsigned long data
);
203 static int mptscsih_do_cmd(MPT_SCSI_HOST
*hd
, INTERNAL_CMD
*iocmd
);
204 static int mptscsih_synchronize_cache(MPT_SCSI_HOST
*hd
, int portnum
);
206 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
207 static int mptscsih_do_raid(MPT_SCSI_HOST
*hd
, u8 action
, INTERNAL_CMD
*io
);
208 static void mptscsih_domainValidation(void *hd
);
209 static int mptscsih_is_phys_disk(MPT_ADAPTER
*ioc
, int id
);
210 static void mptscsih_qas_check(MPT_SCSI_HOST
*hd
, int id
);
211 static int mptscsih_doDv(MPT_SCSI_HOST
*hd
, int channel
, int target
);
212 static void mptscsih_dv_parms(MPT_SCSI_HOST
*hd
, DVPARAMETERS
*dv
,void *pPage
);
213 static void mptscsih_fillbuf(char *buffer
, int size
, int index
, int width
);
215 /* module entry point */
216 static int __init
mptscsih_init (void);
217 static void __exit
mptscsih_exit (void);
219 static int mptscsih_probe (struct pci_dev
*, const struct pci_device_id
*);
220 static void mptscsih_remove(struct pci_dev
*);
221 static void mptscsih_shutdown(struct device
*);
223 static int mptscsih_suspend(struct pci_dev
*pdev
, pm_message_t state
);
224 static int mptscsih_resume(struct pci_dev
*pdev
);
232 static int mpt_scsi_hosts
= 0;
234 static int ScsiDoneCtx
= -1;
235 static int ScsiTaskCtx
= -1;
236 static int ScsiScanDvCtx
= -1; /* Used only for bus scan and dv */
238 #define SNS_LEN(scp) sizeof((scp)->sense_buffer)
240 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
242 * Domain Validation task structure
244 static DEFINE_SPINLOCK(dvtaskQ_lock
);
245 static int dvtaskQ_active
= 0;
246 static int dvtaskQ_release
= 0;
247 static struct work_struct mptscsih_dvTask
;
253 static DECLARE_WAIT_QUEUE_HEAD (scandv_waitq
);
254 static int scandv_wait_done
= 1;
257 /* Driver command line structure
259 static struct scsi_host_template driver_template
;
261 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
263 * mptscsih_add_sge - Place a simple SGE at address pAddr.
264 * @pAddr: virtual address for SGE
265 * @flagslength: SGE flags and data transfer length
266 * @dma_addr: Physical address
268 * This routine places a MPT request frame back on the MPT adapter's
272 mptscsih_add_sge(char *pAddr
, u32 flagslength
, dma_addr_t dma_addr
)
274 if (sizeof(dma_addr_t
) == sizeof(u64
)) {
275 SGESimple64_t
*pSge
= (SGESimple64_t
*) pAddr
;
276 u32 tmp
= dma_addr
& 0xFFFFFFFF;
278 pSge
->FlagsLength
= cpu_to_le32(flagslength
);
279 pSge
->Address
.Low
= cpu_to_le32(tmp
);
280 tmp
= (u32
) ((u64
)dma_addr
>> 32);
281 pSge
->Address
.High
= cpu_to_le32(tmp
);
284 SGESimple32_t
*pSge
= (SGESimple32_t
*) pAddr
;
285 pSge
->FlagsLength
= cpu_to_le32(flagslength
);
286 pSge
->Address
= cpu_to_le32(dma_addr
);
288 } /* mptscsih_add_sge() */
290 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
292 * mptscsih_add_chain - Place a chain SGE at address pAddr.
293 * @pAddr: virtual address for SGE
294 * @next: nextChainOffset value (u32's)
295 * @length: length of next SGL segment
296 * @dma_addr: Physical address
298 * This routine places a MPT request frame back on the MPT adapter's
302 mptscsih_add_chain(char *pAddr
, u8 next
, u16 length
, dma_addr_t dma_addr
)
304 if (sizeof(dma_addr_t
) == sizeof(u64
)) {
305 SGEChain64_t
*pChain
= (SGEChain64_t
*) pAddr
;
306 u32 tmp
= dma_addr
& 0xFFFFFFFF;
308 pChain
->Length
= cpu_to_le16(length
);
309 pChain
->Flags
= MPI_SGE_FLAGS_CHAIN_ELEMENT
| mpt_addr_size();
311 pChain
->NextChainOffset
= next
;
313 pChain
->Address
.Low
= cpu_to_le32(tmp
);
314 tmp
= (u32
) ((u64
)dma_addr
>> 32);
315 pChain
->Address
.High
= cpu_to_le32(tmp
);
317 SGEChain32_t
*pChain
= (SGEChain32_t
*) pAddr
;
318 pChain
->Length
= cpu_to_le16(length
);
319 pChain
->Flags
= MPI_SGE_FLAGS_CHAIN_ELEMENT
| mpt_addr_size();
320 pChain
->NextChainOffset
= next
;
321 pChain
->Address
= cpu_to_le32(dma_addr
);
323 } /* mptscsih_add_chain() */
325 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
327 * mptscsih_getFreeChainBuffer - Function to get a free chain
328 * from the MPT_SCSI_HOST FreeChainQ.
329 * @ioc: Pointer to MPT_ADAPTER structure
330 * @req_idx: Index of the SCSI IO request frame. (output)
332 * return SUCCESS or FAILED
335 mptscsih_getFreeChainBuffer(MPT_ADAPTER
*ioc
, int *retIndex
)
337 MPT_FRAME_HDR
*chainBuf
;
342 dsgprintk((MYIOC_s_INFO_FMT
"getFreeChainBuffer called\n",
344 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
345 if (!list_empty(&ioc
->FreeChainQ
)) {
348 chainBuf
= list_entry(ioc
->FreeChainQ
.next
, MPT_FRAME_HDR
,
349 u
.frame
.linkage
.list
);
350 list_del(&chainBuf
->u
.frame
.linkage
.list
);
351 offset
= (u8
*)chainBuf
- (u8
*)ioc
->ChainBuffer
;
352 chain_idx
= offset
/ ioc
->req_sz
;
354 dsgprintk((MYIOC_s_INFO_FMT
"getFreeChainBuffer (index %d), got buf=%p\n",
355 ioc
->name
, *retIndex
, chainBuf
));
358 chain_idx
= MPT_HOST_NO_CHAIN
;
359 dfailprintk((MYIOC_s_ERR_FMT
"getFreeChainBuffer failed\n",
362 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
364 *retIndex
= chain_idx
;
366 } /* mptscsih_getFreeChainBuffer() */
368 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
370 * mptscsih_AddSGE - Add a SGE (plus chain buffers) to the
371 * SCSIIORequest_t Message Frame.
372 * @ioc: Pointer to MPT_ADAPTER structure
373 * @SCpnt: Pointer to scsi_cmnd structure
374 * @pReq: Pointer to SCSIIORequest_t structure
379 mptscsih_AddSGE(MPT_ADAPTER
*ioc
, struct scsi_cmnd
*SCpnt
,
380 SCSIIORequest_t
*pReq
, int req_idx
)
384 struct scatterlist
*sg
;
386 int sges_left
, sg_done
;
387 int chain_idx
= MPT_HOST_NO_CHAIN
;
389 int numSgeSlots
, numSgeThisFrame
;
390 u32 sgflags
, sgdir
, thisxfer
= 0;
391 int chain_dma_off
= 0;
397 sgdir
= le32_to_cpu(pReq
->Control
) & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK
;
398 if (sgdir
== MPI_SCSIIO_CONTROL_WRITE
) {
399 sgdir
= MPT_TRANSFER_HOST_TO_IOC
;
401 sgdir
= MPT_TRANSFER_IOC_TO_HOST
;
404 psge
= (char *) &pReq
->SGL
;
405 frm_sz
= ioc
->req_sz
;
407 /* Map the data portion, if any.
408 * sges_left = 0 if no data transfer.
410 if ( (sges_left
= SCpnt
->use_sg
) ) {
411 sges_left
= pci_map_sg(ioc
->pcidev
,
412 (struct scatterlist
*) SCpnt
->request_buffer
,
414 SCpnt
->sc_data_direction
);
417 } else if (SCpnt
->request_bufflen
) {
418 SCpnt
->SCp
.dma_handle
= pci_map_single(ioc
->pcidev
,
419 SCpnt
->request_buffer
,
420 SCpnt
->request_bufflen
,
421 SCpnt
->sc_data_direction
);
422 dsgprintk((MYIOC_s_INFO_FMT
"SG: non-SG for %p, len=%d\n",
423 ioc
->name
, SCpnt
, SCpnt
->request_bufflen
));
424 mptscsih_add_sge((char *) &pReq
->SGL
,
425 0xD1000000|MPT_SGE_FLAGS_ADDRESSING
|sgdir
|SCpnt
->request_bufflen
,
426 SCpnt
->SCp
.dma_handle
);
431 /* Handle the SG case.
433 sg
= (struct scatterlist
*) SCpnt
->request_buffer
;
435 sgeOffset
= sizeof(SCSIIORequest_t
) - sizeof(SGE_IO_UNION
);
438 /* Prior to entering this loop - the following must be set
439 * current MF: sgeOffset (bytes)
440 * chainSge (Null if original MF is not a chain buffer)
441 * sg_done (num SGE done for this MF)
445 numSgeSlots
= ((frm_sz
- sgeOffset
) / (sizeof(u32
) + sizeof(dma_addr_t
)) );
446 numSgeThisFrame
= (sges_left
< numSgeSlots
) ? sges_left
: numSgeSlots
;
448 sgflags
= MPT_SGE_FLAGS_SIMPLE_ELEMENT
| MPT_SGE_FLAGS_ADDRESSING
| sgdir
;
450 /* Get first (num - 1) SG elements
451 * Skip any SG entries with a length of 0
452 * NOTE: at finish, sg and psge pointed to NEXT data/location positions
454 for (ii
=0; ii
< (numSgeThisFrame
-1); ii
++) {
455 thisxfer
= sg_dma_len(sg
);
457 sg
++; /* Get next SG element from the OS */
462 v2
= sg_dma_address(sg
);
463 mptscsih_add_sge(psge
, sgflags
| thisxfer
, v2
);
465 sg
++; /* Get next SG element from the OS */
466 psge
+= (sizeof(u32
) + sizeof(dma_addr_t
));
467 sgeOffset
+= (sizeof(u32
) + sizeof(dma_addr_t
));
471 if (numSgeThisFrame
== sges_left
) {
472 /* Add last element, end of buffer and end of list flags.
474 sgflags
|= MPT_SGE_FLAGS_LAST_ELEMENT
|
475 MPT_SGE_FLAGS_END_OF_BUFFER
|
476 MPT_SGE_FLAGS_END_OF_LIST
;
478 /* Add last SGE and set termination flags.
479 * Note: Last SGE may have a length of 0 - which should be ok.
481 thisxfer
= sg_dma_len(sg
);
483 v2
= sg_dma_address(sg
);
484 mptscsih_add_sge(psge
, sgflags
| thisxfer
, v2
);
487 psge += (sizeof(u32) + sizeof(dma_addr_t));
489 sgeOffset
+= (sizeof(u32
) + sizeof(dma_addr_t
));
493 /* The current buffer is a chain buffer,
494 * but there is not another one.
495 * Update the chain element
496 * Offset and Length fields.
498 mptscsih_add_chain((char *)chainSge
, 0, sgeOffset
, ioc
->ChainBufferDMA
+ chain_dma_off
);
500 /* The current buffer is the original MF
501 * and there is no Chain buffer.
503 pReq
->ChainOffset
= 0;
504 RequestNB
= (((sgeOffset
- 1) >> ioc
->NBShiftFactor
) + 1) & 0x03;
505 dsgprintk((MYIOC_s_ERR_FMT
506 "Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc
->name
, RequestNB
, sgeOffset
));
507 ioc
->RequestNB
[req_idx
] = RequestNB
;
510 /* At least one chain buffer is needed.
511 * Complete the first MF
512 * - last SGE element, set the LastElement bit
513 * - set ChainOffset (words) for orig MF
514 * (OR finish previous MF chain buffer)
515 * - update MFStructPtr ChainIndex
516 * - Populate chain element
521 dsgprintk((MYIOC_s_INFO_FMT
"SG: Chain Required! sg done %d\n",
522 ioc
->name
, sg_done
));
524 /* Set LAST_ELEMENT flag for last non-chain element
525 * in the buffer. Since psge points at the NEXT
526 * SGE element, go back one SGE element, update the flags
527 * and reset the pointer. (Note: sgflags & thisxfer are already
531 u32
*ptmp
= (u32
*) (psge
- (sizeof(u32
) + sizeof(dma_addr_t
)));
532 sgflags
= le32_to_cpu(*ptmp
);
533 sgflags
|= MPT_SGE_FLAGS_LAST_ELEMENT
;
534 *ptmp
= cpu_to_le32(sgflags
);
538 /* The current buffer is a chain buffer.
539 * chainSge points to the previous Chain Element.
540 * Update its chain element Offset and Length (must
541 * include chain element size) fields.
542 * Old chain element is now complete.
544 u8 nextChain
= (u8
) (sgeOffset
>> 2);
545 sgeOffset
+= (sizeof(u32
) + sizeof(dma_addr_t
));
546 mptscsih_add_chain((char *)chainSge
, nextChain
, sgeOffset
, ioc
->ChainBufferDMA
+ chain_dma_off
);
548 /* The original MF buffer requires a chain buffer -
550 * Last element in this MF is a chain element.
552 pReq
->ChainOffset
= (u8
) (sgeOffset
>> 2);
553 RequestNB
= (((sgeOffset
- 1) >> ioc
->NBShiftFactor
) + 1) & 0x03;
554 dsgprintk((MYIOC_s_ERR_FMT
"Chain Buffer Needed, RequestNB=%x sgeOffset=%d\n", ioc
->name
, RequestNB
, sgeOffset
));
555 ioc
->RequestNB
[req_idx
] = RequestNB
;
558 sges_left
-= sg_done
;
561 /* NOTE: psge points to the beginning of the chain element
562 * in current buffer. Get a chain buffer.
564 dsgprintk((MYIOC_s_INFO_FMT
565 "calling getFreeChainBuffer SCSI cmd=%02x (%p)\n",
566 ioc
->name
, pReq
->CDB
[0], SCpnt
));
567 if ((mptscsih_getFreeChainBuffer(ioc
, &newIndex
)) == FAILED
)
570 /* Update the tracking arrays.
571 * If chainSge == NULL, update ReqToChain, else ChainToChain
574 ioc
->ChainToChain
[chain_idx
] = newIndex
;
576 ioc
->ReqToChain
[req_idx
] = newIndex
;
578 chain_idx
= newIndex
;
579 chain_dma_off
= ioc
->req_sz
* chain_idx
;
581 /* Populate the chainSGE for the current buffer.
582 * - Set chain buffer pointer to psge and fill
583 * out the Address and Flags fields.
585 chainSge
= (char *) psge
;
586 dsgprintk((KERN_INFO
" Current buff @ %p (index 0x%x)",
589 /* Start the SGE for the next buffer
591 psge
= (char *) (ioc
->ChainBuffer
+ chain_dma_off
);
595 dsgprintk((KERN_INFO
" Chain buff @ %p (index 0x%x)\n",
598 /* Start the SGE for the next buffer
605 } /* mptscsih_AddSGE() */
607 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
609 * mptscsih_io_done - Main SCSI IO callback routine registered to
610 * Fusion MPT (base) driver
611 * @ioc: Pointer to MPT_ADAPTER structure
612 * @mf: Pointer to original MPT request frame
613 * @r: Pointer to MPT reply frame (NULL if TurboReply)
615 * This routine is called from mpt.c::mpt_interrupt() at the completion
616 * of any SCSI IO request.
617 * This routine is registered with the Fusion MPT (base) driver at driver
618 * load/init time via the mpt_register() API call.
620 * Returns 1 indicating alloc'd request frame ptr should be freed.
623 mptscsih_io_done(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
, MPT_FRAME_HDR
*mr
)
625 struct scsi_cmnd
*sc
;
627 SCSIIORequest_t
*pScsiReq
;
628 SCSIIOReply_t
*pScsiReply
;
631 hd
= (MPT_SCSI_HOST
*) ioc
->sh
->hostdata
;
633 req_idx
= le16_to_cpu(mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
);
634 sc
= hd
->ScsiLookup
[req_idx
];
636 MPIHeader_t
*hdr
= (MPIHeader_t
*)mf
;
638 /* Remark: writeSDP1 will use the ScsiDoneCtx
639 * If a SCSI I/O cmd, device disabled by OS and
640 * completion done. Cannot touch sc struct. Just free mem.
642 if (hdr
->Function
== MPI_FUNCTION_SCSI_IO_REQUEST
)
643 printk(MYIOC_s_ERR_FMT
"NULL ScsiCmd ptr!\n",
646 mptscsih_freeChainBuffers(ioc
, req_idx
);
650 dmfprintk((MYIOC_s_INFO_FMT
651 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
652 ioc
->name
, mf
, mr
, sc
, req_idx
));
654 sc
->result
= DID_OK
<< 16; /* Set default reply as OK */
655 pScsiReq
= (SCSIIORequest_t
*) mf
;
656 pScsiReply
= (SCSIIOReply_t
*) mr
;
658 if (pScsiReply
== NULL
) {
659 /* special context reply handling */
664 u8 scsi_state
, scsi_status
;
666 status
= le16_to_cpu(pScsiReply
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
667 scsi_state
= pScsiReply
->SCSIState
;
668 scsi_status
= pScsiReply
->SCSIStatus
;
669 xfer_cnt
= le32_to_cpu(pScsiReply
->TransferCount
);
670 sc
->resid
= sc
->request_bufflen
- xfer_cnt
;
672 dreplyprintk((KERN_NOTICE
"Reply ha=%d id=%d lun=%d:\n"
673 "IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n"
674 "resid=%d bufflen=%d xfer_cnt=%d\n",
675 ioc
->id
, pScsiReq
->TargetID
, pScsiReq
->LUN
[1],
676 status
, scsi_state
, scsi_status
, sc
->resid
,
677 sc
->request_bufflen
, xfer_cnt
));
679 if (scsi_state
& MPI_SCSI_STATE_AUTOSENSE_VALID
)
680 copy_sense_data(sc
, hd
, mf
, pScsiReply
);
683 * Look for + dump FCP ResponseInfo[]!
685 if (scsi_state
& MPI_SCSI_STATE_RESPONSE_INFO_VALID
) {
686 printk(KERN_NOTICE
" FCP_ResponseInfo=%08xh\n",
687 le32_to_cpu(pScsiReply
->ResponseInfo
));
691 case MPI_IOCSTATUS_BUSY
: /* 0x0002 */
693 * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
694 * But not: DID_BUS_BUSY lest one risk
695 * killing interrupt handler:-(
697 sc
->result
= SAM_STAT_BUSY
;
700 case MPI_IOCSTATUS_SCSI_INVALID_BUS
: /* 0x0041 */
701 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID
: /* 0x0042 */
702 sc
->result
= DID_BAD_TARGET
<< 16;
705 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE
: /* 0x0043 */
706 /* Spoof to SCSI Selection Timeout! */
707 sc
->result
= DID_NO_CONNECT
<< 16;
709 if (hd
->sel_timeout
[pScsiReq
->TargetID
] < 0xFFFF)
710 hd
->sel_timeout
[pScsiReq
->TargetID
]++;
713 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED
: /* 0x0048 */
714 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED
: /* 0x004B */
715 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED
: /* 0x004C */
716 /* Linux handles an unsolicited DID_RESET better
717 * than an unsolicited DID_ABORT.
719 sc
->result
= DID_RESET
<< 16;
721 /* GEM Workaround. */
722 if (ioc
->bus_type
== SCSI
)
723 mptscsih_no_negotiate(hd
, sc
->device
->id
);
726 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH
: /* 0x0049 */
727 if ( xfer_cnt
>= sc
->underflow
) {
728 /* Sufficient data transfer occurred */
729 sc
->result
= (DID_OK
<< 16) | scsi_status
;
730 } else if ( xfer_cnt
== 0 ) {
731 /* A CRC Error causes this condition; retry */
732 sc
->result
= (DRIVER_SENSE
<< 24) | (DID_OK
<< 16) |
733 (CHECK_CONDITION
<< 1);
734 sc
->sense_buffer
[0] = 0x70;
735 sc
->sense_buffer
[2] = NO_SENSE
;
736 sc
->sense_buffer
[12] = 0;
737 sc
->sense_buffer
[13] = 0;
739 sc
->result
= DID_SOFT_ERROR
<< 16;
741 dreplyprintk((KERN_NOTICE
"RESIDUAL_MISMATCH: result=%x on id=%d\n", sc
->result
, sc
->target
));
744 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN
: /* 0x0045 */
746 * Do upfront check for valid SenseData and give it
749 sc
->result
= (DID_OK
<< 16) | scsi_status
;
750 if (scsi_state
& MPI_SCSI_STATE_AUTOSENSE_VALID
) {
751 /* Have already saved the status and sense data
755 if (xfer_cnt
< sc
->underflow
) {
756 sc
->result
= DID_SOFT_ERROR
<< 16;
758 if (scsi_state
& (MPI_SCSI_STATE_AUTOSENSE_FAILED
| MPI_SCSI_STATE_NO_SCSI_STATUS
)) {
761 sc
->result
= DID_SOFT_ERROR
<< 16;
763 else if (scsi_state
& MPI_SCSI_STATE_TERMINATED
) {
764 /* Not real sure here either... */
765 sc
->result
= DID_RESET
<< 16;
769 dreplyprintk((KERN_NOTICE
" sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
771 dreplyprintk((KERN_NOTICE
" ActBytesXferd=%02xh\n", xfer_cnt
));
774 if (scsi_status
== MPI_SCSI_STATUS_TASK_SET_FULL
)
775 mptscsih_report_queue_full(sc
, pScsiReply
, pScsiReq
);
779 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR
: /* 0x0040 */
780 case MPI_IOCSTATUS_SUCCESS
: /* 0x0000 */
781 scsi_status
= pScsiReply
->SCSIStatus
;
782 sc
->result
= (DID_OK
<< 16) | scsi_status
;
783 if (scsi_state
== 0) {
785 } else if (scsi_state
& MPI_SCSI_STATE_AUTOSENSE_VALID
) {
787 * If running against circa 200003dd 909 MPT f/w,
788 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
789 * (QUEUE_FULL) returned from device! --> get 0x0000?128
790 * and with SenseBytes set to 0.
792 if (pScsiReply
->SCSIStatus
== MPI_SCSI_STATUS_TASK_SET_FULL
)
793 mptscsih_report_queue_full(sc
, pScsiReply
, pScsiReq
);
796 else if (scsi_state
&
797 (MPI_SCSI_STATE_AUTOSENSE_FAILED
| MPI_SCSI_STATE_NO_SCSI_STATUS
)
802 sc
->result
= DID_SOFT_ERROR
<< 16;
804 else if (scsi_state
& MPI_SCSI_STATE_TERMINATED
) {
805 /* Not real sure here either... */
806 sc
->result
= DID_RESET
<< 16;
808 else if (scsi_state
& MPI_SCSI_STATE_QUEUE_TAG_REJECTED
) {
809 /* Device Inq. data indicates that it supports
810 * QTags, but rejects QTag messages.
811 * This command completed OK.
813 * Not real sure here either so do nothing... */
816 if (sc
->result
== MPI_SCSI_STATUS_TASK_SET_FULL
)
817 mptscsih_report_queue_full(sc
, pScsiReply
, pScsiReq
);
820 * Reservation Conflict, Busy,
821 * Command Terminated, CHECK
825 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR
: /* 0x0047 */
826 sc
->result
= DID_SOFT_ERROR
<< 16;
829 case MPI_IOCSTATUS_INVALID_FUNCTION
: /* 0x0001 */
830 case MPI_IOCSTATUS_INVALID_SGL
: /* 0x0003 */
831 case MPI_IOCSTATUS_INTERNAL_ERROR
: /* 0x0004 */
832 case MPI_IOCSTATUS_RESERVED
: /* 0x0005 */
833 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES
: /* 0x0006 */
834 case MPI_IOCSTATUS_INVALID_FIELD
: /* 0x0007 */
835 case MPI_IOCSTATUS_INVALID_STATE
: /* 0x0008 */
836 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN
: /* 0x0044 */
837 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR
: /* 0x0046 */
838 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED
: /* 0x004A */
843 sc
->result
= DID_SOFT_ERROR
<< 16;
846 } /* switch(status) */
848 dreplyprintk((KERN_NOTICE
" sc->result is %08xh\n", sc
->result
));
849 } /* end of address reply case */
851 /* Unmap the DMA buffers, if any. */
853 pci_unmap_sg(ioc
->pcidev
, (struct scatterlist
*) sc
->request_buffer
,
854 sc
->use_sg
, sc
->sc_data_direction
);
855 } else if (sc
->request_bufflen
) {
856 pci_unmap_single(ioc
->pcidev
, sc
->SCp
.dma_handle
,
857 sc
->request_bufflen
, sc
->sc_data_direction
);
860 hd
->ScsiLookup
[req_idx
] = NULL
;
862 sc
->scsi_done(sc
); /* Issue the command callback */
864 /* Free Chain buffers */
865 mptscsih_freeChainBuffers(ioc
, req_idx
);
871 * mptscsih_flush_running_cmds - For each command found, search
872 * Scsi_Host instance taskQ and reply to OS.
873 * Called only if recovering from a FW reload.
874 * @hd: Pointer to a SCSI HOST structure
878 * Must be called while new I/Os are being queued.
881 mptscsih_flush_running_cmds(MPT_SCSI_HOST
*hd
)
883 MPT_ADAPTER
*ioc
= hd
->ioc
;
884 struct scsi_cmnd
*SCpnt
;
887 int max
= ioc
->req_depth
;
889 dprintk((KERN_INFO MYNAM
": flush_ScsiLookup called\n"));
890 for (ii
= 0; ii
< max
; ii
++) {
891 if ((SCpnt
= hd
->ScsiLookup
[ii
]) != NULL
) {
896 /* Null ScsiLookup index
898 hd
->ScsiLookup
[ii
] = NULL
;
900 mf
= MPT_INDEX_2_MFPTR(ioc
, ii
);
901 dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n",
904 /* Set status, free OS resources (SG DMA buffers)
906 * Free driver resources (chain, msg buffers)
908 if (scsi_device_online(SCpnt
->device
)) {
910 pci_unmap_sg(ioc
->pcidev
,
911 (struct scatterlist
*) SCpnt
->request_buffer
,
913 SCpnt
->sc_data_direction
);
914 } else if (SCpnt
->request_bufflen
) {
915 pci_unmap_single(ioc
->pcidev
,
916 SCpnt
->SCp
.dma_handle
,
917 SCpnt
->request_bufflen
,
918 SCpnt
->sc_data_direction
);
921 SCpnt
->result
= DID_RESET
<< 16;
922 SCpnt
->host_scribble
= NULL
;
924 /* Free Chain buffers */
925 mptscsih_freeChainBuffers(ioc
, ii
);
927 /* Free Message frames */
928 mpt_free_msg_frame(ioc
, mf
);
930 SCpnt
->scsi_done(SCpnt
); /* Issue the command callback */
938 * mptscsih_search_running_cmds - Delete any commands associated
939 * with the specified target and lun. Function called only
940 * when a lun is disable by mid-layer.
941 * Do NOT access the referenced scsi_cmnd structure or
942 * members. Will cause either a paging or NULL ptr error.
943 * @hd: Pointer to a SCSI HOST structure
949 * Called from slave_destroy.
952 mptscsih_search_running_cmds(MPT_SCSI_HOST
*hd
, uint target
, uint lun
)
954 SCSIIORequest_t
*mf
= NULL
;
956 int max
= hd
->ioc
->req_depth
;
958 dsprintk((KERN_INFO MYNAM
": search_running target %d lun %d max %d\n",
961 for (ii
=0; ii
< max
; ii
++) {
962 if (hd
->ScsiLookup
[ii
] != NULL
) {
964 mf
= (SCSIIORequest_t
*)MPT_INDEX_2_MFPTR(hd
->ioc
, ii
);
966 dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n",
967 hd
->ScsiLookup
[ii
], mf
, mf
->TargetID
, mf
->LUN
[1]));
969 if ((mf
->TargetID
!= ((u8
)target
)) || (mf
->LUN
[1] != ((u8
) lun
)))
974 hd
->ScsiLookup
[ii
] = NULL
;
975 mptscsih_freeChainBuffers(hd
->ioc
, ii
);
976 mpt_free_msg_frame(hd
->ioc
, (MPT_FRAME_HDR
*)mf
);
983 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
985 * Hack! It might be nice to report if a device is returning QUEUE_FULL
986 * but maybe not each and every time...
988 static long last_queue_full
= 0;
990 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
992 * mptscsih_report_queue_full - Report QUEUE_FULL status returned
993 * from a SCSI target device.
994 * @sc: Pointer to scsi_cmnd structure
995 * @pScsiReply: Pointer to SCSIIOReply_t
996 * @pScsiReq: Pointer to original SCSI request
998 * This routine periodically reports QUEUE_FULL status returned from a
999 * SCSI target device. It reports this to the console via kernel
1000 * printk() API call, not more than once every 10 seconds.
1003 mptscsih_report_queue_full(struct scsi_cmnd
*sc
, SCSIIOReply_t
*pScsiReply
, SCSIIORequest_t
*pScsiReq
)
1005 long time
= jiffies
;
1007 if (time
- last_queue_full
> 10 * HZ
) {
1008 char *ioc_str
= "ioc?";
1010 if (sc
->device
&& sc
->device
->host
!= NULL
&& sc
->device
->host
->hostdata
!= NULL
)
1011 ioc_str
= ((MPT_SCSI_HOST
*)sc
->device
->host
->hostdata
)->ioc
->name
;
1012 dprintk((MYIOC_s_WARN_FMT
"Device (%d:%d:%d) reported QUEUE_FULL!\n",
1013 ioc_str
, 0, sc
->device
->id
, sc
->device
->lun
));
1014 last_queue_full
= time
;
1018 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1019 static char *info_kbuf
= NULL
;
1021 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1022 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1024 * mptscsih_probe - Installs scsi devices per bus.
1025 * @pdev: Pointer to pci_dev structure
1027 * Returns 0 for success, non-zero for failure.
1032 mptscsih_probe(struct pci_dev
*pdev
, const struct pci_device_id
*id
)
1034 struct Scsi_Host
*sh
;
1036 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
1037 unsigned long flags
;
1046 /* 20010202 -sralston
1047 * Added sanity check on readiness of the MPT adapter.
1049 if (ioc
->last_state
!= MPI_IOC_STATE_OPERATIONAL
) {
1050 printk(MYIOC_s_WARN_FMT
1051 "Skipping because it's not operational!\n",
1057 printk(MYIOC_s_WARN_FMT
"Skipping because it's disabled!\n",
1062 /* Sanity check - ensure at least 1 port is INITIATOR capable
1065 for (ii
=0; ii
< ioc
->facts
.NumberOfPorts
; ii
++) {
1066 if (ioc
->pfacts
[ii
].ProtocolFlags
&
1067 MPI_PORTFACTS_PROTOCOL_INITIATOR
)
1072 printk(MYIOC_s_WARN_FMT
1073 "Skipping ioc=%p because SCSI Initiator mode is NOT enabled!\n",
1078 sh
= scsi_host_alloc(&driver_template
, sizeof(MPT_SCSI_HOST
));
1081 printk(MYIOC_s_WARN_FMT
1082 "Unable to register controller with SCSI subsystem\n",
1087 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
1089 /* Attach the SCSI Host to the IOC structure
1097 /* set 16 byte cdb's */
1098 sh
->max_cmd_len
= 16;
1100 /* Yikes! This is important!
1101 * Otherwise, by default, linux
1102 * only scans target IDs 0-7!
1103 * pfactsN->MaxDevices unreliable
1104 * (not supported in early
1105 * versions of the FW).
1106 * max_id = 1 + actual max id,
1107 * max_lun = 1 + actual last lun,
1110 if (ioc
->bus_type
== SCSI
) {
1111 sh
->max_id
= MPT_MAX_SCSI_DEVICES
;
1113 /* For FC, increase the queue depth
1114 * from MPT_SCSI_CAN_QUEUE (31)
1115 * to MPT_FC_CAN_QUEUE (63).
1117 sh
->can_queue
= MPT_FC_CAN_QUEUE
;
1119 MPT_MAX_FC_DEVICES
<256 ? MPT_MAX_FC_DEVICES
: 255;
1122 sh
->max_lun
= MPT_LAST_LUN
+ 1;
1123 sh
->max_channel
= 0;
1124 sh
->this_id
= ioc
->pfacts
[0].PortSCSIID
;
1128 sh
->unique_id
= ioc
->id
;
1130 /* Verify that we won't exceed the maximum
1131 * number of chain buffers
1132 * We can optimize: ZZ = req_sz/sizeof(SGE)
1134 * numSGE = 1 + (ZZ-1)*(maxChain -1) + ZZ
1135 * + (req_sz - 64)/sizeof(SGE)
1136 * A slightly different algorithm is required for
1139 scale
= ioc
->req_sz
/(sizeof(dma_addr_t
) + sizeof(u32
));
1140 if (sizeof(dma_addr_t
) == sizeof(u64
)) {
1141 numSGE
= (scale
- 1) *
1142 (ioc
->facts
.MaxChainDepth
-1) + scale
+
1143 (ioc
->req_sz
- 60) / (sizeof(dma_addr_t
) +
1146 numSGE
= 1 + (scale
- 1) *
1147 (ioc
->facts
.MaxChainDepth
-1) + scale
+
1148 (ioc
->req_sz
- 64) / (sizeof(dma_addr_t
) +
1152 if (numSGE
< sh
->sg_tablesize
) {
1153 /* Reset this value */
1154 dprintk((MYIOC_s_INFO_FMT
1155 "Resetting sg_tablesize to %d from %d\n",
1156 ioc
->name
, numSGE
, sh
->sg_tablesize
));
1157 sh
->sg_tablesize
= numSGE
;
1160 /* Set the pci device pointer in Scsi_Host structure.
1162 scsi_set_device(sh
, &ioc
->pcidev
->dev
);
1164 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
1166 hd
= (MPT_SCSI_HOST
*) sh
->hostdata
;
1169 /* SCSI needs scsi_cmnd lookup table!
1170 * (with size equal to req_depth*PtrSz!)
1172 sz
= ioc
->req_depth
* sizeof(void *);
1173 mem
= kmalloc(sz
, GFP_ATOMIC
);
1176 goto mptscsih_probe_failed
;
1180 hd
->ScsiLookup
= (struct scsi_cmnd
**) mem
;
1182 dprintk((MYIOC_s_INFO_FMT
"ScsiLookup @ %p, sz=%d\n",
1183 ioc
->name
, hd
->ScsiLookup
, sz
));
1185 /* Allocate memory for the device structures.
1186 * A non-Null pointer at an offset
1187 * indicates a device exists.
1188 * max_id = 1 + maximum id (hosts.h)
1190 sz
= sh
->max_id
* sizeof(void *);
1191 mem
= kmalloc(sz
, GFP_ATOMIC
);
1194 goto mptscsih_probe_failed
;
1198 hd
->Targets
= (VirtDevice
**) mem
;
1201 " Targets @ %p, sz=%d\n", hd
->Targets
, sz
));
1203 /* Clear the TM flags
1206 hd
->tmState
= TM_STATE_NONE
;
1207 hd
->resetPending
= 0;
1208 hd
->abortSCpnt
= NULL
;
1210 /* Clear the pointer used to store
1211 * single-threaded commands, i.e., those
1212 * issued during a bus scan, dv and
1213 * configuration pages.
1217 /* Initialize this SCSI Hosts' timers
1218 * To use, set the timer expires field
1221 init_timer(&hd
->timer
);
1222 hd
->timer
.data
= (unsigned long) hd
;
1223 hd
->timer
.function
= mptscsih_timer_expired
;
1225 if (ioc
->bus_type
== SCSI
) {
1226 /* Update with the driver setup
1229 if (ioc
->spi_data
.maxBusWidth
> mpt_width
)
1230 ioc
->spi_data
.maxBusWidth
= mpt_width
;
1231 if (ioc
->spi_data
.minSyncFactor
< mpt_factor
)
1232 ioc
->spi_data
.minSyncFactor
= mpt_factor
;
1234 if (ioc
->spi_data
.minSyncFactor
== MPT_ASYNC
) {
1235 ioc
->spi_data
.maxSyncOffset
= 0;
1238 ioc
->spi_data
.Saf_Te
= mpt_saf_te
;
1241 #ifndef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1242 hd
->negoNvram
= MPT_SCSICFG_USE_NVRAM
;
1244 ioc
->spi_data
.forceDv
= 0;
1245 ioc
->spi_data
.noQas
= 0;
1246 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
1247 ioc
->spi_data
.dvStatus
[ii
] =
1248 MPT_SCSICFG_NEGOTIATE
;
1251 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++)
1252 ioc
->spi_data
.dvStatus
[ii
] |=
1253 MPT_SCSICFG_DV_NOT_DONE
;
1255 dinitprintk((MYIOC_s_INFO_FMT
1256 "dv %x width %x factor %x saf_te %x\n",
1265 error
= scsi_add_host (sh
, &ioc
->pcidev
->dev
);
1267 dprintk((KERN_ERR MYNAM
1268 "scsi_add_host failed\n"));
1269 goto mptscsih_probe_failed
;
1275 mptscsih_probe_failed
:
1277 mptscsih_remove(pdev
);
1282 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1284 * mptscsih_remove - Removed scsi devices
1285 * @pdev: Pointer to pci_dev structure
1290 mptscsih_remove(struct pci_dev
*pdev
)
1292 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
1293 struct Scsi_Host
*host
= ioc
->sh
;
1296 unsigned long flags
;
1301 scsi_remove_host(host
);
1303 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1304 /* Check DV thread active */
1306 spin_lock_irqsave(&dvtaskQ_lock
, flags
);
1307 if (dvtaskQ_active
) {
1308 spin_unlock_irqrestore(&dvtaskQ_lock
, flags
);
1309 while(dvtaskQ_active
&& --count
) {
1310 set_current_state(TASK_INTERRUPTIBLE
);
1311 schedule_timeout(1);
1314 spin_unlock_irqrestore(&dvtaskQ_lock
, flags
);
1317 printk(KERN_ERR MYNAM
": ERROR - DV thread still active!\n");
1318 #if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
1320 printk(KERN_ERR MYNAM
": DV thread orig %d, count %d\n", 10 * HZ
, count
);
1324 hd
= (MPT_SCSI_HOST
*)host
->hostdata
;
1328 mptscsih_shutdown(&pdev
->dev
);
1332 if (hd
->ScsiLookup
!= NULL
) {
1333 sz1
= hd
->ioc
->req_depth
* sizeof(void *);
1334 kfree(hd
->ScsiLookup
);
1335 hd
->ScsiLookup
= NULL
;
1338 if (hd
->Targets
!= NULL
) {
1340 * Free pointer array.
1346 dprintk((MYIOC_s_INFO_FMT
1347 "Free'd ScsiLookup (%d) memory\n",
1348 hd
->ioc
->name
, sz1
));
1350 /* NULL the Scsi_Host pointer
1355 scsi_host_put(host
);
1360 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1362 * mptscsih_shutdown - reboot notifier
1366 mptscsih_shutdown(struct device
* dev
)
1368 MPT_ADAPTER
*ioc
= pci_get_drvdata(to_pci_dev(dev
));
1369 struct Scsi_Host
*host
= ioc
->sh
;
1375 hd
= (MPT_SCSI_HOST
*)host
->hostdata
;
1377 /* Flush the cache of this adapter
1380 mptscsih_synchronize_cache(hd
, 0);
1385 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1387 * mptscsih_suspend - Fusion MPT scsie driver suspend routine.
1392 mptscsih_suspend(struct pci_dev
*pdev
, pm_message_t state
)
1394 mptscsih_shutdown(&pdev
->dev
);
1398 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1400 * mptscsih_resume - Fusion MPT scsi driver resume routine.
1405 mptscsih_resume(struct pci_dev
*pdev
)
1407 MPT_ADAPTER
*ioc
= pci_get_drvdata(pdev
);
1408 struct Scsi_Host
*host
= ioc
->sh
;
1414 hd
= (MPT_SCSI_HOST
*)host
->hostdata
;
1418 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1420 unsigned long lflags
;
1421 spin_lock_irqsave(&dvtaskQ_lock
, lflags
);
1422 if (!dvtaskQ_active
) {
1424 spin_unlock_irqrestore(&dvtaskQ_lock
, lflags
);
1425 INIT_WORK(&mptscsih_dvTask
,
1426 mptscsih_domainValidation
, (void *) hd
);
1427 schedule_work(&mptscsih_dvTask
);
1429 spin_unlock_irqrestore(&dvtaskQ_lock
, lflags
);
1438 static struct mpt_pci_driver mptscsih_driver
= {
1439 .probe
= mptscsih_probe
,
1440 .remove
= mptscsih_remove
,
1441 .shutdown
= mptscsih_shutdown
,
1443 .suspend
= mptscsih_suspend
,
1444 .resume
= mptscsih_resume
,
1448 /* SCSI host fops start here... */
1449 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1451 * mptscsih_init - Register MPT adapter(s) as SCSI host(s) with
1452 * linux scsi mid-layer.
1454 * Returns 0 for success, non-zero for failure.
1460 show_mptmod_ver(my_NAME
, my_VERSION
);
1462 ScsiDoneCtx
= mpt_register(mptscsih_io_done
, MPTSCSIH_DRIVER
);
1463 ScsiTaskCtx
= mpt_register(mptscsih_taskmgmt_complete
, MPTSCSIH_DRIVER
);
1464 ScsiScanDvCtx
= mpt_register(mptscsih_scandv_complete
, MPTSCSIH_DRIVER
);
1466 if (mpt_event_register(ScsiDoneCtx
, mptscsih_event_process
) == 0) {
1467 devtprintk((KERN_INFO MYNAM
1468 ": Registered for IOC event notifications\n"));
1471 if (mpt_reset_register(ScsiDoneCtx
, mptscsih_ioc_reset
) == 0) {
1472 dprintk((KERN_INFO MYNAM
1473 ": Registered for IOC reset notifications\n"));
1476 if(mpt_device_driver_register(&mptscsih_driver
,
1477 MPTSCSIH_DRIVER
) != 0 ) {
1478 dprintk((KERN_INFO MYNAM
1479 ": failed to register dd callbacks\n"));
1486 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1487 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1489 * mptscsih_exit - Unregisters MPT adapter(s)
1495 mpt_device_driver_deregister(MPTSCSIH_DRIVER
);
1497 mpt_reset_deregister(ScsiDoneCtx
);
1498 dprintk((KERN_INFO MYNAM
1499 ": Deregistered for IOC reset notifications\n"));
1501 mpt_event_deregister(ScsiDoneCtx
);
1502 dprintk((KERN_INFO MYNAM
1503 ": Deregistered for IOC event notifications\n"));
1505 mpt_deregister(ScsiScanDvCtx
);
1506 mpt_deregister(ScsiTaskCtx
);
1507 mpt_deregister(ScsiDoneCtx
);
1509 if (info_kbuf
!= NULL
)
1514 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1516 * mptscsih_info - Return information about MPT adapter
1517 * @SChost: Pointer to Scsi_Host structure
1519 * (linux scsi_host_template.info routine)
1521 * Returns pointer to buffer where information was written.
1524 mptscsih_info(struct Scsi_Host
*SChost
)
1529 if (info_kbuf
== NULL
)
1530 if ((info_kbuf
= kmalloc(0x1000 /* 4Kb */, GFP_KERNEL
)) == NULL
)
1533 h
= (MPT_SCSI_HOST
*)SChost
->hostdata
;
1534 info_kbuf
[0] = '\0';
1536 mpt_print_ioc_summary(h
->ioc
, info_kbuf
, &size
, 0, 0);
1537 info_kbuf
[size
-1] = '\0';
1550 static void copy_mem_info(struct info_str
*info
, char *data
, int len
)
1552 if (info
->pos
+ len
> info
->length
)
1553 len
= info
->length
- info
->pos
;
1555 if (info
->pos
+ len
< info
->offset
) {
1560 if (info
->pos
< info
->offset
) {
1561 data
+= (info
->offset
- info
->pos
);
1562 len
-= (info
->offset
- info
->pos
);
1566 memcpy(info
->buffer
+ info
->pos
, data
, len
);
1571 static int copy_info(struct info_str
*info
, char *fmt
, ...)
1577 va_start(args
, fmt
);
1578 len
= vsprintf(buf
, fmt
, args
);
1581 copy_mem_info(info
, buf
, len
);
1585 static int mptscsih_host_info(MPT_ADAPTER
*ioc
, char *pbuf
, off_t offset
, int len
)
1587 struct info_str info
;
1591 info
.offset
= offset
;
1594 copy_info(&info
, "%s: %s, ", ioc
->name
, ioc
->prod_name
);
1595 copy_info(&info
, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING
, ioc
->facts
.FWVersion
.Word
);
1596 copy_info(&info
, "Ports=%d, ", ioc
->facts
.NumberOfPorts
);
1597 copy_info(&info
, "MaxQ=%d\n", ioc
->req_depth
);
1599 return ((info
.pos
> info
.offset
) ? info
.pos
- info
.offset
: 0);
1602 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1604 * mptscsih_proc_info - Return information about MPT adapter
1606 * (linux scsi_host_template.info routine)
1608 * buffer: if write, user data; if read, buffer for user
1609 * length: if write, return length;
1610 * offset: if write, 0; if read, the current offset into the buffer from
1611 * the previous read.
1612 * hostno: scsi host number
1613 * func: if write = 1; if read = 0
1616 mptscsih_proc_info(struct Scsi_Host
*host
, char *buffer
, char **start
, off_t offset
,
1617 int length
, int func
)
1619 MPT_SCSI_HOST
*hd
= (MPT_SCSI_HOST
*)host
->hostdata
;
1620 MPT_ADAPTER
*ioc
= hd
->ioc
;
1625 * write is not supported
1631 size
= mptscsih_host_info(ioc
, buffer
, offset
, length
);
1637 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1638 #define ADD_INDEX_LOG(req_ent) do { } while(0)
1640 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1642 * mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1643 * @SCpnt: Pointer to scsi_cmnd structure
1644 * @done: Pointer SCSI mid-layer IO completion function
1646 * (linux scsi_host_template.queuecommand routine)
1647 * This is the primary SCSI IO start routine. Create a MPI SCSIIORequest
1648 * from a linux scsi_cmnd request and send it to the IOC.
1650 * Returns 0. (rtn value discarded by linux scsi mid-layer)
1653 mptscsih_qcmd(struct scsi_cmnd
*SCpnt
, void (*done
)(struct scsi_cmnd
*))
1657 SCSIIORequest_t
*pScsiReq
;
1658 VirtDevice
*pTarget
;
1668 hd
= (MPT_SCSI_HOST
*) SCpnt
->device
->host
->hostdata
;
1669 target
= SCpnt
->device
->id
;
1670 lun
= SCpnt
->device
->lun
;
1671 SCpnt
->scsi_done
= done
;
1673 pTarget
= hd
->Targets
[target
];
1675 dmfprintk((MYIOC_s_INFO_FMT
"qcmd: SCpnt=%p, done()=%p\n",
1676 (hd
&& hd
->ioc
) ? hd
->ioc
->name
: "ioc?", SCpnt
, done
));
1678 if (hd
->resetPending
) {
1679 dtmprintk((MYIOC_s_WARN_FMT
"qcmd: SCpnt=%p timeout + 60HZ\n",
1680 (hd
&& hd
->ioc
) ? hd
->ioc
->name
: "ioc?", SCpnt
));
1681 return SCSI_MLQUEUE_HOST_BUSY
;
1685 * Put together a MPT SCSI request...
1687 if ((mf
= mpt_get_msg_frame(ScsiDoneCtx
, hd
->ioc
)) == NULL
) {
1688 dprintk((MYIOC_s_WARN_FMT
"QueueCmd, no msg frames!!\n",
1690 return SCSI_MLQUEUE_HOST_BUSY
;
1693 pScsiReq
= (SCSIIORequest_t
*) mf
;
1695 my_idx
= le16_to_cpu(mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
);
1697 ADD_INDEX_LOG(my_idx
);
1699 /* BUG FIX! 19991030 -sralston
1700 * TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1701 * Seems we may receive a buffer (datalen>0) even when there
1702 * will be no data transfer! GRRRRR...
1704 if (SCpnt
->sc_data_direction
== DMA_FROM_DEVICE
) {
1705 datalen
= SCpnt
->request_bufflen
;
1706 scsidir
= MPI_SCSIIO_CONTROL_READ
; /* DATA IN (host<--ioc<--dev) */
1707 } else if (SCpnt
->sc_data_direction
== DMA_TO_DEVICE
) {
1708 datalen
= SCpnt
->request_bufflen
;
1709 scsidir
= MPI_SCSIIO_CONTROL_WRITE
; /* DATA OUT (host-->ioc-->dev) */
1712 scsidir
= MPI_SCSIIO_CONTROL_NODATATRANSFER
;
1715 /* Default to untagged. Once a target structure has been allocated,
1716 * use the Inquiry data to determine if device supports tagged.
1719 && (pTarget
->tflags
& MPT_TARGET_FLAGS_Q_YES
)
1720 && (SCpnt
->device
->tagged_supported
)) {
1721 scsictl
= scsidir
| MPI_SCSIIO_CONTROL_SIMPLEQ
;
1723 scsictl
= scsidir
| MPI_SCSIIO_CONTROL_UNTAGGED
;
1726 /* Use the above information to set up the message frame
1728 pScsiReq
->TargetID
= (u8
) target
;
1729 pScsiReq
->Bus
= (u8
) SCpnt
->device
->channel
;
1730 pScsiReq
->ChainOffset
= 0;
1731 pScsiReq
->Function
= MPI_FUNCTION_SCSI_IO_REQUEST
;
1732 pScsiReq
->CDBLength
= SCpnt
->cmd_len
;
1733 pScsiReq
->SenseBufferLength
= MPT_SENSE_BUFFER_SIZE
;
1734 pScsiReq
->Reserved
= 0;
1735 pScsiReq
->MsgFlags
= mpt_msg_flags();
1736 pScsiReq
->LUN
[0] = 0;
1737 pScsiReq
->LUN
[1] = lun
;
1738 pScsiReq
->LUN
[2] = 0;
1739 pScsiReq
->LUN
[3] = 0;
1740 pScsiReq
->LUN
[4] = 0;
1741 pScsiReq
->LUN
[5] = 0;
1742 pScsiReq
->LUN
[6] = 0;
1743 pScsiReq
->LUN
[7] = 0;
1744 pScsiReq
->Control
= cpu_to_le32(scsictl
);
1747 * Write SCSI CDB into the message
1749 cmd_len
= SCpnt
->cmd_len
;
1750 for (ii
=0; ii
< cmd_len
; ii
++)
1751 pScsiReq
->CDB
[ii
] = SCpnt
->cmnd
[ii
];
1753 for (ii
=cmd_len
; ii
< 16; ii
++)
1754 pScsiReq
->CDB
[ii
] = 0;
1757 pScsiReq
->DataLength
= cpu_to_le32(datalen
);
1759 /* SenseBuffer low address */
1760 pScsiReq
->SenseBufferLowAddr
= cpu_to_le32(hd
->ioc
->sense_buf_low_dma
1761 + (my_idx
* MPT_SENSE_BUFFER_ALLOC
));
1763 /* Now add the SG list
1764 * Always have a SGE even if null length.
1767 /* Add a NULL SGE */
1768 mptscsih_add_sge((char *)&pScsiReq
->SGL
, MPT_SGE_FLAGS_SSIMPLE_READ
| 0,
1771 /* Add a 32 or 64 bit SGE */
1772 if (mptscsih_AddSGE(hd
->ioc
, SCpnt
, pScsiReq
, my_idx
) != SUCCESS
)
1776 hd
->ScsiLookup
[my_idx
] = SCpnt
;
1777 SCpnt
->host_scribble
= NULL
;
1779 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
1780 if (hd
->ioc
->bus_type
== SCSI
) {
1781 int dvStatus
= hd
->ioc
->spi_data
.dvStatus
[target
];
1784 if (dvStatus
|| hd
->ioc
->spi_data
.forceDv
) {
1786 if ((dvStatus
& MPT_SCSICFG_NEED_DV
) ||
1787 (hd
->ioc
->spi_data
.forceDv
& MPT_SCSICFG_NEED_DV
)) {
1788 unsigned long lflags
;
1789 /* Schedule DV if necessary */
1790 spin_lock_irqsave(&dvtaskQ_lock
, lflags
);
1791 if (!dvtaskQ_active
) {
1793 spin_unlock_irqrestore(&dvtaskQ_lock
, lflags
);
1794 INIT_WORK(&mptscsih_dvTask
, mptscsih_domainValidation
, (void *) hd
);
1796 schedule_work(&mptscsih_dvTask
);
1798 spin_unlock_irqrestore(&dvtaskQ_lock
, lflags
);
1800 hd
->ioc
->spi_data
.forceDv
&= ~MPT_SCSICFG_NEED_DV
;
1803 /* Trying to do DV to this target, extend timeout.
1804 * Wait to issue until flag is clear
1806 if (dvStatus
& MPT_SCSICFG_DV_PENDING
) {
1807 mod_timer(&SCpnt
->eh_timeout
, jiffies
+ 40 * HZ
);
1811 /* Set the DV flags.
1813 if (dvStatus
& MPT_SCSICFG_DV_NOT_DONE
)
1814 mptscsih_set_dvflags(hd
, pScsiReq
);
1822 mpt_put_msg_frame(ScsiDoneCtx
, hd
->ioc
, mf
);
1823 dmfprintk((MYIOC_s_INFO_FMT
"Issued SCSI cmd (%p) mf=%p idx=%d\n",
1824 hd
->ioc
->name
, SCpnt
, mf
, my_idx
));
1825 DBG_DUMP_REQUEST_FRAME(mf
)
1829 mptscsih_freeChainBuffers(hd
->ioc
, my_idx
);
1830 mpt_free_msg_frame(hd
->ioc
, mf
);
1831 return SCSI_MLQUEUE_HOST_BUSY
;
1834 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1836 * mptscsih_freeChainBuffers - Function to free chain buffers associated
1837 * with a SCSI IO request
1838 * @hd: Pointer to the MPT_SCSI_HOST instance
1839 * @req_idx: Index of the SCSI IO request frame.
1841 * Called if SG chain buffer allocation fails and mptscsih callbacks.
1845 mptscsih_freeChainBuffers(MPT_ADAPTER
*ioc
, int req_idx
)
1847 MPT_FRAME_HDR
*chain
;
1848 unsigned long flags
;
1852 /* Get the first chain index and reset
1855 chain_idx
= ioc
->ReqToChain
[req_idx
];
1856 ioc
->ReqToChain
[req_idx
] = MPT_HOST_NO_CHAIN
;
1858 while (chain_idx
!= MPT_HOST_NO_CHAIN
) {
1860 /* Save the next chain buffer index */
1861 next
= ioc
->ChainToChain
[chain_idx
];
1863 /* Free this chain buffer and reset
1866 ioc
->ChainToChain
[chain_idx
] = MPT_HOST_NO_CHAIN
;
1868 chain
= (MPT_FRAME_HDR
*) (ioc
->ChainBuffer
1869 + (chain_idx
* ioc
->req_sz
));
1871 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
1872 list_add_tail(&chain
->u
.frame
.linkage
.list
, &ioc
->FreeChainQ
);
1873 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
1875 dmfprintk((MYIOC_s_INFO_FMT
"FreeChainBuffers (index %d)\n",
1876 ioc
->name
, chain_idx
));
1884 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1889 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1891 * mptscsih_TMHandler - Generic handler for SCSI Task Management.
1892 * Fall through to mpt_HardResetHandler if: not operational, too many
1893 * failed TM requests or handshake failure.
1895 * @ioc: Pointer to MPT_ADAPTER structure
1896 * @type: Task Management type
1897 * @target: Logical Target ID for reset (if appropriate)
1898 * @lun: Logical Unit for reset (if appropriate)
1899 * @ctx2abort: Context for the task to be aborted (if appropriate)
1901 * Remark: Currently invoked from a non-interrupt thread (_bh).
1903 * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
1906 * Returns 0 for SUCCESS or -1 if FAILED.
1909 mptscsih_TMHandler(MPT_SCSI_HOST
*hd
, u8 type
, u8 channel
, u8 target
, u8 lun
, int ctx2abort
, ulong timeout
)
1915 unsigned long flags
;
1917 /* If FW is being reloaded currently, return success to
1918 * the calling function.
1925 printk(KERN_ERR MYNAM
" TMHandler" " NULL ioc!\n");
1928 dtmprintk((MYIOC_s_INFO_FMT
"TMHandler Entered!\n", ioc
->name
));
1930 // SJR - CHECKME - Can we avoid this here?
1931 // (mpt_HardResetHandler has this check...)
1932 spin_lock_irqsave(&ioc
->diagLock
, flags
);
1933 if ((ioc
->diagPending
) || (ioc
->alt_ioc
&& ioc
->alt_ioc
->diagPending
)) {
1934 spin_unlock_irqrestore(&ioc
->diagLock
, flags
);
1937 spin_unlock_irqrestore(&ioc
->diagLock
, flags
);
1939 /* Wait a fixed amount of time for the TM pending flag to be cleared.
1940 * If we time out and not bus reset, then we return a FAILED status to the caller.
1941 * The call to mptscsih_tm_pending_wait() will set the pending flag if we are
1942 * successful. Otherwise, reload the FW.
1944 if (mptscsih_tm_pending_wait(hd
) == FAILED
) {
1945 if (type
== MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK
) {
1946 dtmprintk((KERN_WARNING MYNAM
": %s: TMHandler abort: "
1947 "Timed out waiting for last TM (%d) to complete! \n",
1948 hd
->ioc
->name
, hd
->tmPending
));
1950 } else if (type
== MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET
) {
1951 dtmprintk((KERN_WARNING MYNAM
": %s: TMHandler target reset: "
1952 "Timed out waiting for last TM (%d) to complete! \n",
1953 hd
->ioc
->name
, hd
->tmPending
));
1955 } else if (type
== MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS
) {
1956 dtmprintk((KERN_WARNING MYNAM
": %s: TMHandler bus reset: "
1957 "Timed out waiting for last TM (%d) to complete! \n",
1958 hd
->ioc
->name
, hd
->tmPending
));
1959 if (hd
->tmPending
& (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS
))
1965 spin_lock_irqsave(&hd
->ioc
->FreeQlock
, flags
);
1966 hd
->tmPending
|= (1 << type
);
1967 spin_unlock_irqrestore(&hd
->ioc
->FreeQlock
, flags
);
1972 ioc_raw_state
= mpt_GetIocState(hd
->ioc
, 0);
1974 #ifdef MPT_DEBUG_RESET
1975 if ((ioc_raw_state
& MPI_IOC_STATE_MASK
) != MPI_IOC_STATE_OPERATIONAL
) {
1976 printk(MYIOC_s_WARN_FMT
1977 "TM Handler: IOC Not operational(0x%x)!\n",
1978 hd
->ioc
->name
, ioc_raw_state
);
1982 if (doTask
&& ((ioc_raw_state
& MPI_IOC_STATE_MASK
) == MPI_IOC_STATE_OPERATIONAL
)
1983 && !(ioc_raw_state
& MPI_DOORBELL_ACTIVE
)) {
1985 /* Isse the Task Mgmt request.
1987 if (hd
->hard_resets
< -1)
1989 rc
= mptscsih_IssueTaskMgmt(hd
, type
, channel
, target
, lun
, ctx2abort
, timeout
);
1991 printk(MYIOC_s_INFO_FMT
"Issue of TaskMgmt failed!\n", hd
->ioc
->name
);
1993 dtmprintk((MYIOC_s_INFO_FMT
"Issue of TaskMgmt Successful!\n", hd
->ioc
->name
));
1997 /* Only fall through to the HRH if this is a bus reset
1999 if ((type
== MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS
) && (rc
||
2000 ioc
->reload_fw
|| (ioc
->alt_ioc
&& ioc
->alt_ioc
->reload_fw
))) {
2001 dtmprintk((MYIOC_s_INFO_FMT
"Calling HardReset! \n",
2003 rc
= mpt_HardResetHandler(hd
->ioc
, CAN_SLEEP
);
2006 dtmprintk((MYIOC_s_INFO_FMT
"TMHandler rc = %d!\n", hd
->ioc
->name
, rc
));
2012 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2014 * mptscsih_IssueTaskMgmt - Generic send Task Management function.
2015 * @hd: Pointer to MPT_SCSI_HOST structure
2016 * @type: Task Management type
2017 * @target: Logical Target ID for reset (if appropriate)
2018 * @lun: Logical Unit for reset (if appropriate)
2019 * @ctx2abort: Context for the task to be aborted (if appropriate)
2021 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
2022 * or a non-interrupt thread. In the former, must not call schedule().
2024 * Not all fields are meaningfull for all task types.
2026 * Returns 0 for SUCCESS, -999 for "no msg frames",
2027 * else other non-zero value returned.
2030 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST
*hd
, u8 type
, u8 channel
, u8 target
, u8 lun
, int ctx2abort
, ulong timeout
)
2033 SCSITaskMgmt_t
*pScsiTm
;
2037 /* Return Fail to calling function if no message frames available.
2039 if ((mf
= mpt_get_msg_frame(ScsiTaskCtx
, hd
->ioc
)) == NULL
) {
2040 dfailprintk((MYIOC_s_ERR_FMT
"IssueTaskMgmt, no msg frames!!\n",
2045 dtmprintk((MYIOC_s_INFO_FMT
"IssueTaskMgmt request @ %p\n",
2046 hd
->ioc
->name
, mf
));
2048 /* Format the Request
2050 pScsiTm
= (SCSITaskMgmt_t
*) mf
;
2051 pScsiTm
->TargetID
= target
;
2052 pScsiTm
->Bus
= channel
;
2053 pScsiTm
->ChainOffset
= 0;
2054 pScsiTm
->Function
= MPI_FUNCTION_SCSI_TASK_MGMT
;
2056 pScsiTm
->Reserved
= 0;
2057 pScsiTm
->TaskType
= type
;
2058 pScsiTm
->Reserved1
= 0;
2059 pScsiTm
->MsgFlags
= (type
== MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS
)
2060 ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION
: 0;
2062 for (ii
= 0; ii
< 8; ii
++) {
2063 pScsiTm
->LUN
[ii
] = 0;
2065 pScsiTm
->LUN
[1] = lun
;
2067 for (ii
=0; ii
< 7; ii
++)
2068 pScsiTm
->Reserved2
[ii
] = 0;
2070 pScsiTm
->TaskMsgContext
= ctx2abort
;
2072 dtmprintk((MYIOC_s_INFO_FMT
2073 "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
2074 hd
->ioc
->name
, ctx2abort
, type
));
2076 DBG_DUMP_TM_REQUEST_FRAME((u32
*)pScsiTm
);
2078 if ((retval
= mpt_send_handshake_request(ScsiTaskCtx
, hd
->ioc
,
2079 sizeof(SCSITaskMgmt_t
), (u32
*)pScsiTm
,
2081 dfailprintk((MYIOC_s_ERR_FMT
"_send_handshake FAILED!"
2082 " (hd %p, ioc %p, mf %p) \n", hd
->ioc
->name
, hd
,
2084 mpt_free_msg_frame(hd
->ioc
, mf
);
2088 if(mptscsih_tm_wait_for_completion(hd
, timeout
) == FAILED
) {
2089 dfailprintk((MYIOC_s_ERR_FMT
"_wait_for_completion FAILED!"
2090 " (hd %p, ioc %p, mf %p) \n", hd
->ioc
->name
, hd
,
2092 mpt_free_msg_frame(hd
->ioc
, mf
);
2093 dtmprintk((MYIOC_s_INFO_FMT
"Calling HardReset! \n",
2095 retval
= mpt_HardResetHandler(hd
->ioc
, CAN_SLEEP
);
2101 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2103 * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
2104 * @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
2106 * (linux scsi_host_template.eh_abort_handler routine)
2108 * Returns SUCCESS or FAILED.
2111 mptscsih_abort(struct scsi_cmnd
* SCpnt
)
2118 spinlock_t
*host_lock
= SCpnt
->device
->host
->host_lock
;
2120 /* If we can't locate our host adapter structure, return FAILED status.
2122 if ((hd
= (MPT_SCSI_HOST
*) SCpnt
->device
->host
->hostdata
) == NULL
) {
2123 SCpnt
->result
= DID_RESET
<< 16;
2124 SCpnt
->scsi_done(SCpnt
);
2125 dfailprintk((KERN_WARNING MYNAM
": mptscsih_abort: "
2126 "Can't locate host! (sc=%p)\n",
2132 if (hd
->resetPending
)
2135 printk(KERN_WARNING MYNAM
": %s: >> Attempting task abort! (sc=%p)\n",
2136 hd
->ioc
->name
, SCpnt
);
2138 if (hd
->timeouts
< -1)
2141 /* Find this command
2143 if ((scpnt_idx
= SCPNT_TO_LOOKUP_IDX(SCpnt
)) < 0) {
2144 /* Cmd not found in ScsiLookup.
2147 SCpnt
->result
= DID_RESET
<< 16;
2148 dtmprintk((KERN_WARNING MYNAM
": %s: mptscsih_abort: "
2149 "Command not in the active list! (sc=%p)\n",
2150 hd
->ioc
->name
, SCpnt
));
2154 /* Most important! Set TaskMsgContext to SCpnt's MsgContext!
2155 * (the IO to be ABORT'd)
2157 * NOTE: Since we do not byteswap MsgContext, we do not
2158 * swap it here either. It is an opaque cookie to
2159 * the controller, so it does not matter. -DaveM
2161 mf
= MPT_INDEX_2_MFPTR(hd
->ioc
, scpnt_idx
);
2162 ctx2abort
= mf
->u
.frame
.hwhdr
.msgctxu
.MsgContext
;
2164 hd
->abortSCpnt
= SCpnt
;
2166 spin_unlock_irq(host_lock
);
2167 if (mptscsih_TMHandler(hd
, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK
,
2168 SCpnt
->device
->channel
, SCpnt
->device
->id
, SCpnt
->device
->lun
,
2169 ctx2abort
, 2 /* 2 second timeout */)
2172 /* The TM request failed and the subsequent FW-reload failed!
2175 printk(MYIOC_s_WARN_FMT
"Error issuing abort task! (sc=%p)\n",
2176 hd
->ioc
->name
, SCpnt
);
2178 /* We must clear our pending flag before clearing our state.
2181 hd
->tmState
= TM_STATE_NONE
;
2183 spin_lock_irq(host_lock
);
2185 /* Unmap the DMA buffers, if any. */
2186 if (SCpnt
->use_sg
) {
2187 pci_unmap_sg(ioc
->pcidev
, (struct scatterlist
*) SCpnt
->request_buffer
,
2188 SCpnt
->use_sg
, SCpnt
->sc_data_direction
);
2189 } else if (SCpnt
->request_bufflen
) {
2190 pci_unmap_single(ioc
->pcidev
, SCpnt
->SCp
.dma_handle
,
2191 SCpnt
->request_bufflen
, SCpnt
->sc_data_direction
);
2193 hd
->ScsiLookup
[scpnt_idx
] = NULL
;
2194 SCpnt
->result
= DID_RESET
<< 16;
2195 SCpnt
->scsi_done(SCpnt
); /* Issue the command callback */
2196 mptscsih_freeChainBuffers(ioc
, scpnt_idx
);
2197 mpt_free_msg_frame(ioc
, mf
);
2200 spin_lock_irq(host_lock
);
2204 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2206 * mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant
2207 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
2209 * (linux scsi_host_template.eh_dev_reset_handler routine)
2211 * Returns SUCCESS or FAILED.
2214 mptscsih_dev_reset(struct scsi_cmnd
* SCpnt
)
2217 spinlock_t
*host_lock
= SCpnt
->device
->host
->host_lock
;
2219 /* If we can't locate our host adapter structure, return FAILED status.
2221 if ((hd
= (MPT_SCSI_HOST
*) SCpnt
->device
->host
->hostdata
) == NULL
){
2222 dtmprintk((KERN_WARNING MYNAM
": mptscsih_dev_reset: "
2223 "Can't locate host! (sc=%p)\n",
2228 if (hd
->resetPending
)
2231 printk(KERN_WARNING MYNAM
": %s: >> Attempting target reset! (sc=%p)\n",
2232 hd
->ioc
->name
, SCpnt
);
2234 spin_unlock_irq(host_lock
);
2235 if (mptscsih_TMHandler(hd
, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET
,
2236 SCpnt
->device
->channel
, SCpnt
->device
->id
,
2237 0, 0, 5 /* 5 second timeout */)
2239 /* The TM request failed and the subsequent FW-reload failed!
2242 printk(MYIOC_s_WARN_FMT
"Error processing TaskMgmt request (sc=%p)\n",
2243 hd
->ioc
->name
, SCpnt
);
2245 hd
->tmState
= TM_STATE_NONE
;
2246 spin_lock_irq(host_lock
);
2249 spin_lock_irq(host_lock
);
2254 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2256 * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
2257 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
2259 * (linux scsi_host_template.eh_bus_reset_handler routine)
2261 * Returns SUCCESS or FAILED.
2264 mptscsih_bus_reset(struct scsi_cmnd
* SCpnt
)
2267 spinlock_t
*host_lock
= SCpnt
->device
->host
->host_lock
;
2269 /* If we can't locate our host adapter structure, return FAILED status.
2271 if ((hd
= (MPT_SCSI_HOST
*) SCpnt
->device
->host
->hostdata
) == NULL
){
2272 dtmprintk((KERN_WARNING MYNAM
": mptscsih_bus_reset: "
2273 "Can't locate host! (sc=%p)\n",
2278 printk(KERN_WARNING MYNAM
": %s: >> Attempting bus reset! (sc=%p)\n",
2279 hd
->ioc
->name
, SCpnt
);
2281 if (hd
->timeouts
< -1)
2284 /* We are now ready to execute the task management request. */
2285 spin_unlock_irq(host_lock
);
2286 if (mptscsih_TMHandler(hd
, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS
,
2287 SCpnt
->device
->channel
, 0, 0, 0, 5 /* 5 second timeout */)
2290 /* The TM request failed and the subsequent FW-reload failed!
2293 printk(MYIOC_s_WARN_FMT
2294 "Error processing TaskMgmt request (sc=%p)\n",
2295 hd
->ioc
->name
, SCpnt
);
2297 hd
->tmState
= TM_STATE_NONE
;
2298 spin_lock_irq(host_lock
);
2301 spin_lock_irq(host_lock
);
2305 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2307 * mptscsih_host_reset - Perform a SCSI host adapter RESET!
2309 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
2311 * (linux scsi_host_template.eh_host_reset_handler routine)
2313 * Returns SUCCESS or FAILED.
2316 mptscsih_host_reset(struct scsi_cmnd
*SCpnt
)
2319 int status
= SUCCESS
;
2320 spinlock_t
*host_lock
= SCpnt
->device
->host
->host_lock
;
2322 /* If we can't locate the host to reset, then we failed. */
2323 if ((hd
= (MPT_SCSI_HOST
*) SCpnt
->device
->host
->hostdata
) == NULL
){
2324 dtmprintk( ( KERN_WARNING MYNAM
": mptscsih_host_reset: "
2325 "Can't locate host! (sc=%p)\n",
2330 printk(KERN_WARNING MYNAM
": %s: >> Attempting host reset! (sc=%p)\n",
2331 hd
->ioc
->name
, SCpnt
);
2333 /* If our attempts to reset the host failed, then return a failed
2334 * status. The host will be taken off line by the SCSI mid-layer.
2336 spin_unlock_irq(host_lock
);
2337 if (mpt_HardResetHandler(hd
->ioc
, CAN_SLEEP
) < 0){
2340 /* Make sure TM pending is cleared and TM state is set to
2344 hd
->tmState
= TM_STATE_NONE
;
2346 spin_lock_irq(host_lock
);
2349 dtmprintk( ( KERN_WARNING MYNAM
": mptscsih_host_reset: "
2351 (status
== SUCCESS
) ? "SUCCESS" : "FAILED" ) );
2356 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2358 * mptscsih_tm_pending_wait - wait for pending task management request to
2360 * @hd: Pointer to MPT host structure.
2362 * Returns {SUCCESS,FAILED}.
2365 mptscsih_tm_pending_wait(MPT_SCSI_HOST
* hd
)
2367 unsigned long flags
;
2368 int loop_count
= 4 * 10; /* Wait 10 seconds */
2369 int status
= FAILED
;
2372 spin_lock_irqsave(&hd
->ioc
->FreeQlock
, flags
);
2373 if (hd
->tmState
== TM_STATE_NONE
) {
2374 hd
->tmState
= TM_STATE_IN_PROGRESS
;
2377 spin_unlock_irqrestore(&hd
->ioc
->FreeQlock
, flags
);
2380 spin_unlock_irqrestore(&hd
->ioc
->FreeQlock
, flags
);
2382 } while (--loop_count
);
2387 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2389 * mptscsih_tm_wait_for_completion - wait for completion of TM task
2390 * @hd: Pointer to MPT host structure.
2392 * Returns {SUCCESS,FAILED}.
2395 mptscsih_tm_wait_for_completion(MPT_SCSI_HOST
* hd
, ulong timeout
)
2397 unsigned long flags
;
2398 int loop_count
= 4 * timeout
;
2399 int status
= FAILED
;
2402 spin_lock_irqsave(&hd
->ioc
->FreeQlock
, flags
);
2403 if(hd
->tmPending
== 0) {
2405 spin_unlock_irqrestore(&hd
->ioc
->FreeQlock
, flags
);
2408 spin_unlock_irqrestore(&hd
->ioc
->FreeQlock
, flags
);
2409 msleep_interruptible(250);
2410 } while (--loop_count
);
2415 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2417 * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2418 * @ioc: Pointer to MPT_ADAPTER structure
2419 * @mf: Pointer to SCSI task mgmt request frame
2420 * @mr: Pointer to SCSI task mgmt reply frame
2422 * This routine is called from mptbase.c::mpt_interrupt() at the completion
2423 * of any SCSI task management request.
2424 * This routine is registered with the MPT (base) driver at driver
2425 * load/init time via the mpt_register() API call.
2427 * Returns 1 indicating alloc'd request frame ptr should be freed.
2430 mptscsih_taskmgmt_complete(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
, MPT_FRAME_HDR
*mr
)
2432 SCSITaskMgmtReply_t
*pScsiTmReply
;
2433 SCSITaskMgmt_t
*pScsiTmReq
;
2435 unsigned long flags
;
2439 dtmprintk((MYIOC_s_WARN_FMT
"TaskMgmt completed (mf=%p,mr=%p)\n",
2440 ioc
->name
, mf
, mr
));
2442 /* Depending on the thread, a timer is activated for
2443 * the TM request. Delete this timer on completion of TM.
2444 * Decrement count of outstanding TM requests.
2446 hd
= (MPT_SCSI_HOST
*)ioc
->sh
->hostdata
;
2448 dtmprintk((MYIOC_s_WARN_FMT
"TaskMgmt Complete: NULL Scsi Host Ptr\n",
2454 dtmprintk((MYIOC_s_WARN_FMT
"ERROR! TaskMgmt Reply: NULL Request %p\n",
2458 pScsiTmReply
= (SCSITaskMgmtReply_t
*)mr
;
2459 pScsiTmReq
= (SCSITaskMgmt_t
*)mf
;
2461 /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
2462 tmType
= pScsiTmReq
->TaskType
;
2464 dtmprintk((MYIOC_s_WARN_FMT
" TaskType = %d, TerminationCount=%d\n",
2465 ioc
->name
, tmType
, le32_to_cpu(pScsiTmReply
->TerminationCount
)));
2466 DBG_DUMP_TM_REPLY_FRAME((u32
*)pScsiTmReply
);
2468 iocstatus
= le16_to_cpu(pScsiTmReply
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
2469 dtmprintk((MYIOC_s_WARN_FMT
" SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",
2470 ioc
->name
, tmType
, iocstatus
, le32_to_cpu(pScsiTmReply
->IOCLogInfo
)));
2471 /* Error? (anything non-zero?) */
2474 /* clear flags and continue.
2476 if (tmType
== MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK
)
2477 hd
->abortSCpnt
= NULL
;
2479 /* If an internal command is present
2480 * or the TM failed - reload the FW.
2481 * FC FW may respond FAILED to an ABORT
2483 if (tmType
== MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS
) {
2485 (iocstatus
== MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED
)) {
2486 if (mpt_HardResetHandler(ioc
, NO_SLEEP
) < 0) {
2487 printk((KERN_WARNING
2488 " Firmware Reload FAILED!!\n"));
2493 dtmprintk((MYIOC_s_WARN_FMT
" TaskMgmt SUCCESS\n", ioc
->name
));
2495 hd
->abortSCpnt
= NULL
;
2500 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
2502 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
2503 hd
->tmState
= TM_STATE_NONE
;
2508 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2510 * This is anyones guess quite frankly.
2513 mptscsih_bios_param(struct scsi_device
* sdev
, struct block_device
*bdev
,
2514 sector_t capacity
, int geom
[])
2524 dummy
= heads
* sectors
;
2525 cylinders
= capacity
;
2526 sector_div(cylinders
,dummy
);
2529 * Handle extended translation size for logical drives
2532 if ((ulong
)capacity
>= 0x200000) {
2535 dummy
= heads
* sectors
;
2536 cylinders
= capacity
;
2537 sector_div(cylinders
,dummy
);
2543 geom
[2] = cylinders
;
2545 dprintk((KERN_NOTICE
2546 ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
2547 sdev
->id
, sdev
->lun
,sdev
->channel
,(int)cylinders
,heads
,sectors
));
2552 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2554 * OS entry point to allow host driver to alloc memory
2555 * for each scsi device. Called once per device the bus scan.
2556 * Return non-zero if allocation fails.
2557 * Init memory once per id (not LUN).
2560 mptscsih_slave_alloc(struct scsi_device
*device
)
2562 struct Scsi_Host
*host
= device
->host
;
2563 MPT_SCSI_HOST
*hd
= (MPT_SCSI_HOST
*)host
->hostdata
;
2565 uint target
= device
->id
;
2570 if ((vdev
= hd
->Targets
[target
]) != NULL
)
2573 vdev
= kmalloc(sizeof(VirtDevice
), GFP_KERNEL
);
2575 printk(MYIOC_s_ERR_FMT
"slave_alloc kmalloc(%zd) FAILED!\n",
2576 hd
->ioc
->name
, sizeof(VirtDevice
));
2580 memset(vdev
, 0, sizeof(VirtDevice
));
2581 vdev
->tflags
= MPT_TARGET_FLAGS_Q_YES
;
2582 vdev
->ioc_id
= hd
->ioc
->id
;
2583 vdev
->target_id
= device
->id
;
2584 vdev
->bus_id
= device
->channel
;
2585 vdev
->raidVolume
= 0;
2586 hd
->Targets
[device
->id
] = vdev
;
2587 if (hd
->ioc
->bus_type
== SCSI
) {
2588 if (hd
->ioc
->spi_data
.isRaid
& (1 << device
->id
)) {
2589 vdev
->raidVolume
= 1;
2590 ddvtprintk((KERN_INFO
2591 "RAID Volume @ id %d\n", device
->id
));
2594 vdev
->tflags
|= MPT_TARGET_FLAGS_VALID_INQUIRY
;
2602 static int mptscsih_is_raid_volume(MPT_SCSI_HOST
*hd
, uint id
)
2606 if (!hd
->ioc
->spi_data
.isRaid
|| !hd
->ioc
->spi_data
.pIocPg3
)
2609 for (i
= 0; i
< hd
->ioc
->spi_data
.pIocPg3
->NumPhysDisks
; i
++) {
2610 if (id
== hd
->ioc
->spi_data
.pIocPg3
->PhysDisk
[i
].PhysDiskID
)
2618 * OS entry point to allow for host driver to free allocated memory
2619 * Called if no device present or device being unloaded
2622 mptscsih_slave_destroy(struct scsi_device
*device
)
2624 struct Scsi_Host
*host
= device
->host
;
2625 MPT_SCSI_HOST
*hd
= (MPT_SCSI_HOST
*)host
->hostdata
;
2627 uint target
= device
->id
;
2628 uint lun
= device
->lun
;
2633 mptscsih_search_running_cmds(hd
, target
, lun
);
2635 vdev
= hd
->Targets
[target
];
2636 vdev
->luns
[0] &= ~(1 << lun
);
2637 if (--vdev
->num_luns
)
2640 kfree(hd
->Targets
[target
]);
2641 hd
->Targets
[target
] = NULL
;
2643 if (hd
->ioc
->bus_type
== SCSI
) {
2644 if (mptscsih_is_raid_volume(hd
, target
)) {
2645 hd
->ioc
->spi_data
.forceDv
|= MPT_SCSICFG_RELOAD_IOC_PG3
;
2647 hd
->ioc
->spi_data
.dvStatus
[target
] =
2648 MPT_SCSICFG_NEGOTIATE
;
2650 if (!hd
->negoNvram
) {
2651 hd
->ioc
->spi_data
.dvStatus
[target
] |=
2652 MPT_SCSICFG_DV_NOT_DONE
;
2659 mptscsih_set_queue_depth(struct scsi_device
*device
, MPT_SCSI_HOST
*hd
,
2660 VirtDevice
*pTarget
, int qdepth
)
2665 if (hd
->ioc
->bus_type
== SCSI
) {
2666 if (pTarget
->tflags
& MPT_TARGET_FLAGS_VALID_INQUIRY
) {
2667 if (!(pTarget
->tflags
& MPT_TARGET_FLAGS_Q_YES
))
2669 else if (((pTarget
->inq_data
[0] & 0x1f) == 0x00) &&
2670 (pTarget
->minSyncFactor
<= MPT_ULTRA160
))
2671 max_depth
= MPT_SCSI_CMD_PER_DEV_HIGH
;
2673 max_depth
= MPT_SCSI_CMD_PER_DEV_LOW
;
2675 /* error case - No Inq. Data */
2679 max_depth
= MPT_SCSI_CMD_PER_DEV_HIGH
;
2681 if (qdepth
> max_depth
)
2686 tagged
= MSG_SIMPLE_TAG
;
2688 scsi_adjust_queue_depth(device
, tagged
, qdepth
);
2693 * OS entry point to adjust the queue_depths on a per-device basis.
2694 * Called once per device the bus scan. Use it to force the queue_depth
2695 * member to 1 if a device does not support Q tags.
2696 * Return non-zero if fails.
2699 mptscsih_slave_configure(struct scsi_device
*device
)
2701 struct Scsi_Host
*sh
= device
->host
;
2702 VirtDevice
*pTarget
;
2703 MPT_SCSI_HOST
*hd
= (MPT_SCSI_HOST
*)sh
->hostdata
;
2705 if ((hd
== NULL
) || (hd
->Targets
== NULL
)) {
2709 dsprintk((MYIOC_s_INFO_FMT
2710 "device @ %p, id=%d, LUN=%d, channel=%d\n",
2711 hd
->ioc
->name
, device
, device
->id
, device
->lun
, device
->channel
));
2712 dsprintk((MYIOC_s_INFO_FMT
2713 "sdtr %d wdtr %d ppr %d inq length=%d\n",
2714 hd
->ioc
->name
, device
->sdtr
, device
->wdtr
,
2715 device
->ppr
, device
->inquiry_len
));
2717 if (device
->id
> sh
->max_id
) {
2718 /* error case, should never happen */
2719 scsi_adjust_queue_depth(device
, 0, 1);
2720 goto slave_configure_exit
;
2723 pTarget
= hd
->Targets
[device
->id
];
2725 if (pTarget
== NULL
) {
2726 /* Driver doesn't know about this device.
2727 * Kernel may generate a "Dummy Lun 0" which
2728 * may become a real Lun if a
2729 * "scsi add-single-device" command is executed
2730 * while the driver is active (hot-plug a
2731 * device). LSI Raid controllers need
2732 * queue_depth set to DEV_HIGH for this reason.
2734 scsi_adjust_queue_depth(device
, MSG_SIMPLE_TAG
,
2735 MPT_SCSI_CMD_PER_DEV_HIGH
);
2736 goto slave_configure_exit
;
2739 mptscsih_initTarget(hd
, device
->channel
, device
->id
, device
->lun
,
2740 device
->inquiry
, device
->inquiry_len
);
2741 mptscsih_set_queue_depth(device
, hd
, pTarget
, MPT_SCSI_CMD_PER_DEV_HIGH
);
2743 dsprintk((MYIOC_s_INFO_FMT
2744 "Queue depth=%d, tflags=%x\n",
2745 hd
->ioc
->name
, device
->queue_depth
, pTarget
->tflags
));
2747 dsprintk((MYIOC_s_INFO_FMT
2748 "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2749 hd
->ioc
->name
, pTarget
->negoFlags
, pTarget
->maxOffset
, pTarget
->minSyncFactor
));
2751 slave_configure_exit
:
2753 dsprintk((MYIOC_s_INFO_FMT
2754 "tagged %d, simple %d, ordered %d\n",
2755 hd
->ioc
->name
,device
->tagged_supported
, device
->simple_tags
,
2756 device
->ordered_tags
));
2762 mptscsih_store_queue_depth(struct device
*dev
, const char *buf
, size_t count
)
2765 struct scsi_device
*sdev
= to_scsi_device(dev
);
2766 MPT_SCSI_HOST
*hd
= (MPT_SCSI_HOST
*) sdev
->host
->hostdata
;
2767 VirtDevice
*pTarget
;
2769 depth
= simple_strtoul(buf
, NULL
, 0);
2772 pTarget
= hd
->Targets
[sdev
->id
];
2773 if (pTarget
== NULL
)
2775 mptscsih_set_queue_depth(sdev
, (MPT_SCSI_HOST
*) sdev
->host
->hostdata
,
2780 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2782 * Private routines...
2785 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2786 /* Utility function to copy sense data from the scsi_cmnd buffer
2787 * to the FC and SCSI target structures.
2791 copy_sense_data(struct scsi_cmnd
*sc
, MPT_SCSI_HOST
*hd
, MPT_FRAME_HDR
*mf
, SCSIIOReply_t
*pScsiReply
)
2794 SCSIIORequest_t
*pReq
;
2795 u32 sense_count
= le32_to_cpu(pScsiReply
->SenseCount
);
2798 /* Get target structure
2800 pReq
= (SCSIIORequest_t
*) mf
;
2801 index
= (int) pReq
->TargetID
;
2802 target
= hd
->Targets
[index
];
2808 /* Copy the sense received into the scsi command block. */
2809 req_index
= le16_to_cpu(mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
);
2810 sense_data
= ((u8
*)hd
->ioc
->sense_buf_pool
+ (req_index
* MPT_SENSE_BUFFER_ALLOC
));
2811 memcpy(sc
->sense_buffer
, sense_data
, SNS_LEN(sc
));
2813 /* Log SMART data (asc = 0x5D, non-IM case only) if required.
2815 if ((hd
->ioc
->events
) && (hd
->ioc
->eventTypes
& (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE
))) {
2816 if ((sense_data
[12] == 0x5D) && (target
->raidVolume
== 0)) {
2818 MPT_ADAPTER
*ioc
= hd
->ioc
;
2820 idx
= ioc
->eventContext
% ioc
->eventLogSize
;
2821 ioc
->events
[idx
].event
= MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE
;
2822 ioc
->events
[idx
].eventContext
= ioc
->eventContext
;
2824 ioc
->events
[idx
].data
[0] = (pReq
->LUN
[1] << 24) ||
2825 (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA
<< 16) ||
2826 (pReq
->Bus
<< 8) || pReq
->TargetID
;
2828 ioc
->events
[idx
].data
[1] = (sense_data
[13] << 8) || sense_data
[12];
2830 ioc
->eventContext
++;
2834 dprintk((MYIOC_s_INFO_FMT
"Hmmm... SenseData len=0! (?)\n",
2840 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd
*sc
)
2845 hd
= (MPT_SCSI_HOST
*) sc
->device
->host
->hostdata
;
2847 for (i
= 0; i
< hd
->ioc
->req_depth
; i
++) {
2848 if (hd
->ScsiLookup
[i
] == sc
) {
2856 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2858 mptscsih_ioc_reset(MPT_ADAPTER
*ioc
, int reset_phase
)
2861 unsigned long flags
;
2863 dtmprintk((KERN_WARNING MYNAM
2864 ": IOC %s_reset routed to SCSI host driver!\n",
2865 reset_phase
==MPT_IOC_SETUP_RESET
? "setup" : (
2866 reset_phase
==MPT_IOC_PRE_RESET
? "pre" : "post")));
2868 /* If a FW reload request arrives after base installed but
2869 * before all scsi hosts have been attached, then an alt_ioc
2870 * may have a NULL sh pointer.
2872 if ((ioc
->sh
== NULL
) || (ioc
->sh
->hostdata
== NULL
))
2875 hd
= (MPT_SCSI_HOST
*) ioc
->sh
->hostdata
;
2877 if (reset_phase
== MPT_IOC_SETUP_RESET
) {
2878 dtmprintk((MYIOC_s_WARN_FMT
"Setup-Diag Reset\n", ioc
->name
));
2881 * 1. Set Hard Reset Pending Flag
2882 * All new commands go to doneQ
2884 hd
->resetPending
= 1;
2886 } else if (reset_phase
== MPT_IOC_PRE_RESET
) {
2887 dtmprintk((MYIOC_s_WARN_FMT
"Pre-Diag Reset\n", ioc
->name
));
2889 /* 2. Flush running commands
2890 * Clean ScsiLookup (and associated memory)
2894 /* 2b. Reply to OS all known outstanding I/O commands.
2896 mptscsih_flush_running_cmds(hd
);
2898 /* 2c. If there was an internal command that
2899 * has not completed, configuration or io request,
2900 * free these resources.
2903 del_timer(&hd
->timer
);
2904 mpt_free_msg_frame(ioc
, hd
->cmdPtr
);
2907 dtmprintk((MYIOC_s_WARN_FMT
"Pre-Reset complete.\n", ioc
->name
));
2910 dtmprintk((MYIOC_s_WARN_FMT
"Post-Diag Reset\n", ioc
->name
));
2912 /* Once a FW reload begins, all new OS commands are
2913 * redirected to the doneQ w/ a reset status.
2914 * Init all control structures.
2917 /* ScsiLookup initialization
2921 for (ii
=0; ii
< hd
->ioc
->req_depth
; ii
++)
2922 hd
->ScsiLookup
[ii
] = NULL
;
2925 /* 2. Chain Buffer initialization
2928 /* 4. Renegotiate to all devices, if SCSI
2930 if (ioc
->bus_type
== SCSI
) {
2931 dnegoprintk(("writeSDP1: ALL_IDS USE_NVRAM\n"));
2932 mptscsih_writeSDP1(hd
, 0, 0, MPT_SCSICFG_ALL_IDS
| MPT_SCSICFG_USE_NVRAM
);
2935 /* 5. Enable new commands to be posted
2937 spin_lock_irqsave(&ioc
->FreeQlock
, flags
);
2939 spin_unlock_irqrestore(&ioc
->FreeQlock
, flags
);
2940 hd
->resetPending
= 0;
2941 hd
->tmState
= TM_STATE_NONE
;
2943 /* 6. If there was an internal command,
2944 * wake this process up.
2948 * Wake up the original calling thread
2950 hd
->pLocal
= &hd
->localReply
;
2951 hd
->pLocal
->completion
= MPT_SCANDV_DID_RESET
;
2952 scandv_wait_done
= 1;
2953 wake_up(&scandv_waitq
);
2957 /* 7. Set flag to force DV and re-read IOC Page 3
2959 if (ioc
->bus_type
== SCSI
) {
2960 ioc
->spi_data
.forceDv
= MPT_SCSICFG_NEED_DV
| MPT_SCSICFG_RELOAD_IOC_PG3
;
2961 ddvtprintk(("Set reload IOC Pg3 Flag\n"));
2964 dtmprintk((MYIOC_s_WARN_FMT
"Post-Reset complete.\n", ioc
->name
));
2968 return 1; /* currently means nothing really */
2971 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2973 mptscsih_event_process(MPT_ADAPTER
*ioc
, EventNotificationReply_t
*pEvReply
)
2976 u8 event
= le32_to_cpu(pEvReply
->Event
) & 0xFF;
2978 devtprintk((MYIOC_s_INFO_FMT
"MPT event (=%02Xh) routed to SCSI host driver!\n",
2982 case MPI_EVENT_UNIT_ATTENTION
: /* 03 */
2985 case MPI_EVENT_IOC_BUS_RESET
: /* 04 */
2986 case MPI_EVENT_EXT_BUS_RESET
: /* 05 */
2989 hd
= (MPT_SCSI_HOST
*) ioc
->sh
->hostdata
;
2990 if (hd
&& (ioc
->bus_type
== SCSI
) && (hd
->soft_resets
< -1))
2994 case MPI_EVENT_LOGOUT
: /* 09 */
2999 * CHECKME! Don't think we need to do
3000 * anything for these, but...
3002 case MPI_EVENT_RESCAN
: /* 06 */
3003 case MPI_EVENT_LINK_STATUS_CHANGE
: /* 07 */
3004 case MPI_EVENT_LOOP_STATE_CHANGE
: /* 08 */
3006 * CHECKME! Falling thru...
3010 case MPI_EVENT_INTEGRATED_RAID
: /* 0B */
3011 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3012 /* negoNvram set to 0 if DV enabled and to USE_NVRAM if
3013 * if DV disabled. Need to check for target mode.
3017 hd
= (MPT_SCSI_HOST
*) ioc
->sh
->hostdata
;
3019 if (hd
&& (ioc
->bus_type
== SCSI
) && (hd
->negoNvram
== 0)) {
3021 Ioc3PhysDisk_t
*pPDisk
;
3026 reason
= (le32_to_cpu(pEvReply
->Data
[0]) & 0x00FF0000) >> 16;
3027 if (reason
== MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED
) {
3028 /* New or replaced disk.
3029 * Set DV flag and schedule DV.
3031 pSpi
= &ioc
->spi_data
;
3032 physDiskNum
= (le32_to_cpu(pEvReply
->Data
[0]) & 0xFF000000) >> 24;
3033 ddvtprintk(("DV requested for phys disk id %d\n", physDiskNum
));
3034 if (pSpi
->pIocPg3
) {
3035 pPDisk
= pSpi
->pIocPg3
->PhysDisk
;
3036 numPDisk
=pSpi
->pIocPg3
->NumPhysDisks
;
3039 if (physDiskNum
== pPDisk
->PhysDiskNum
) {
3040 pSpi
->dvStatus
[pPDisk
->PhysDiskID
] = (MPT_SCSICFG_NEED_DV
| MPT_SCSICFG_DV_NOT_DONE
);
3041 pSpi
->forceDv
= MPT_SCSICFG_NEED_DV
;
3042 ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk
->PhysDiskID
));
3049 if (numPDisk
== 0) {
3050 /* The physical disk that needs DV was not found
3051 * in the stored IOC Page 3. The driver must reload
3052 * this page. DV routine will set the NEED_DV flag for
3053 * all phys disks that have DV_NOT_DONE set.
3055 pSpi
->forceDv
= MPT_SCSICFG_NEED_DV
| MPT_SCSICFG_RELOAD_IOC_PG3
;
3056 ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n", physDiskNum
));
3063 #if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
3064 printk("Raid Event RF: ");
3066 u32
*m
= (u32
*)pEvReply
;
3068 int n
= (int)pEvReply
->MsgLength
;
3069 for (ii
=6; ii
< n
; ii
++)
3070 printk(" %08x", le32_to_cpu(m
[ii
]));
3076 case MPI_EVENT_NONE
: /* 00 */
3077 case MPI_EVENT_LOG_DATA
: /* 01 */
3078 case MPI_EVENT_STATE_CHANGE
: /* 02 */
3079 case MPI_EVENT_EVENT_CHANGE
: /* 0A */
3081 dprintk((KERN_INFO
" Ignoring event (=%02Xh)\n", event
));
3085 return 1; /* currently means nothing really */
3088 static struct device_attribute mptscsih_queue_depth_attr
= {
3090 .name
= "queue_depth",
3093 .store
= mptscsih_store_queue_depth
,
3096 static struct device_attribute
*mptscsih_dev_attrs
[] = {
3097 &mptscsih_queue_depth_attr
,
3101 static struct scsi_host_template driver_template
= {
3102 .proc_name
= "mptscsih",
3103 .proc_info
= mptscsih_proc_info
,
3104 .name
= "MPT SCSI Host",
3105 .info
= mptscsih_info
,
3106 .queuecommand
= mptscsih_qcmd
,
3107 .slave_alloc
= mptscsih_slave_alloc
,
3108 .slave_configure
= mptscsih_slave_configure
,
3109 .slave_destroy
= mptscsih_slave_destroy
,
3110 .eh_abort_handler
= mptscsih_abort
,
3111 .eh_device_reset_handler
= mptscsih_dev_reset
,
3112 .eh_bus_reset_handler
= mptscsih_bus_reset
,
3113 .eh_host_reset_handler
= mptscsih_host_reset
,
3114 .bios_param
= mptscsih_bios_param
,
3115 .can_queue
= MPT_SCSI_CAN_QUEUE
,
3117 .sg_tablesize
= MPT_SCSI_SG_DEPTH
,
3118 .max_sectors
= 8192,
3120 .use_clustering
= ENABLE_CLUSTERING
,
3121 .sdev_attrs
= mptscsih_dev_attrs
,
3124 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3126 * mptscsih_initTarget - Target, LUN alloc/free functionality.
3127 * @hd: Pointer to MPT_SCSI_HOST structure
3128 * @bus_id: Bus number (?)
3129 * @target_id: SCSI target id
3131 * @data: Pointer to data
3132 * @dlen: Number of INQUIRY bytes
3134 * NOTE: It's only SAFE to call this routine if data points to
3135 * sane & valid STANDARD INQUIRY data!
3137 * Allocate and initialize memory for this target.
3138 * Save inquiry data.
3142 mptscsih_initTarget(MPT_SCSI_HOST
*hd
, int bus_id
, int target_id
, u8 lun
, char *data
, int dlen
)
3144 int indexed_lun
, lun_index
;
3149 dinitprintk((MYIOC_s_INFO_FMT
"initTarget bus=%d id=%d lun=%d hd=%p\n",
3150 hd
->ioc
->name
, bus_id
, target_id
, lun
, hd
));
3153 * If the peripheral qualifier filter is enabled then if the target reports a 0x1
3154 * (i.e. The targer is capable of supporting the specified peripheral device type
3155 * on this logical unit; however, the physical device is not currently connected
3156 * to this logical unit) it will be converted to a 0x3 (i.e. The target is not
3157 * capable of supporting a physical device on this logical unit). This is to work
3158 * around a bug in th emid-layer in some distributions in which the mid-layer will
3159 * continue to try to communicate to the LUN and evntually create a dummy LUN.
3161 if (mpt_pq_filter
&& dlen
&& (data
[0] & 0xE0))
3164 /* Is LUN supported? If so, upper 2 bits will be 0
3165 * in first byte of inquiry data.
3170 if ((vdev
= hd
->Targets
[target_id
]) == NULL
) {
3174 lun_index
= (lun
>> 5); /* 32 luns per lun_index */
3175 indexed_lun
= (lun
% 32);
3176 vdev
->luns
[lun_index
] |= (1 << indexed_lun
);
3178 if (hd
->ioc
->bus_type
== SCSI
) {
3179 if ((data
[0] == TYPE_PROCESSOR
) && (hd
->ioc
->spi_data
.Saf_Te
)) {
3180 /* Treat all Processors as SAF-TE if
3181 * command line option is set */
3182 vdev
->tflags
|= MPT_TARGET_FLAGS_SAF_TE_ISSUED
;
3183 mptscsih_writeIOCPage4(hd
, target_id
, bus_id
);
3184 }else if ((data
[0] == TYPE_PROCESSOR
) &&
3185 !(vdev
->tflags
& MPT_TARGET_FLAGS_SAF_TE_ISSUED
)) {
3187 vdev
->tflags
|= MPT_TARGET_FLAGS_VALID_INQUIRY
;
3188 if ( data
[44] == 'S' &&
3194 vdev
->tflags
|= MPT_TARGET_FLAGS_SAF_TE_ISSUED
;
3195 mptscsih_writeIOCPage4(hd
, target_id
, bus_id
);
3199 if (!(vdev
->tflags
& MPT_TARGET_FLAGS_VALID_INQUIRY
)) {
3201 memcpy (vdev
->inq_data
, data
, 8);
3203 memcpy (vdev
->inq_data
, data
, dlen
);
3206 /* If have not done DV, set the DV flag.
3208 pSpi
= &hd
->ioc
->spi_data
;
3209 if ((data
[0] == TYPE_TAPE
) || (data
[0] == TYPE_PROCESSOR
)) {
3210 if (pSpi
->dvStatus
[target_id
] & MPT_SCSICFG_DV_NOT_DONE
)
3211 pSpi
->dvStatus
[target_id
] |= MPT_SCSICFG_NEED_DV
;
3214 vdev
->tflags
|= MPT_TARGET_FLAGS_VALID_INQUIRY
;
3217 data_56
= 0x0F; /* Default to full capabilities if Inq data length is < 57 */
3219 if ( (!(vdev
->tflags
& MPT_TARGET_FLAGS_VALID_56
))) {
3220 /* Update the target capabilities
3223 vdev
->tflags
|= MPT_TARGET_FLAGS_VALID_56
;
3226 mptscsih_setTargetNegoParms(hd
, vdev
, data_56
);
3228 /* Initial Inquiry may not request enough data bytes to
3229 * obtain byte 57. DV will; if target doesn't return
3230 * at least 57 bytes, data[56] will be zero. */
3232 if ( (!(vdev
->tflags
& MPT_TARGET_FLAGS_VALID_56
))) {
3233 /* Update the target capabilities
3236 vdev
->tflags
|= MPT_TARGET_FLAGS_VALID_56
;
3237 mptscsih_setTargetNegoParms(hd
, vdev
, data_56
);
3244 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3246 * Update the target negotiation parameters based on the
3247 * the Inquiry data, adapter capabilities, and NVRAM settings.
3251 mptscsih_setTargetNegoParms(MPT_SCSI_HOST
*hd
, VirtDevice
*target
, char byte56
)
3253 ScsiCfgData
*pspi_data
= &hd
->ioc
->spi_data
;
3254 int id
= (int) target
->target_id
;
3258 u8 width
= MPT_NARROW
;
3259 u8 factor
= MPT_ASYNC
;
3261 u8 version
, nfactor
;
3264 target
->negoFlags
= pspi_data
->noQas
;
3266 /* noQas == 0 => device supports QAS. Need byte 56 of Inq to determine
3267 * support. If available, default QAS to off and allow enabling.
3268 * If not available, default QAS to on, turn off for non-disks.
3271 /* Set flags based on Inquiry data
3273 version
= target
->inq_data
[2] & 0x07;
3276 factor
= MPT_ULTRA2
;
3277 offset
= pspi_data
->maxSyncOffset
;
3278 target
->tflags
&= ~MPT_TARGET_FLAGS_Q_YES
;
3280 if (target
->inq_data
[7] & 0x20) {
3284 if (target
->inq_data
[7] & 0x10) {
3285 factor
= pspi_data
->minSyncFactor
;
3286 if (target
->tflags
& MPT_TARGET_FLAGS_VALID_56
) {
3287 /* bits 2 & 3 show Clocking support */
3288 if ((byte56
& 0x0C) == 0)
3289 factor
= MPT_ULTRA2
;
3291 if ((byte56
& 0x03) == 0)
3292 factor
= MPT_ULTRA160
;
3294 factor
= MPT_ULTRA320
;
3297 ddvtprintk((KERN_INFO
"Enabling QAS due to byte56=%02x on id=%d!\n", byte56
, id
));
3300 if (target
->inq_data
[0] == TYPE_TAPE
) {
3302 target
->negoFlags
|= MPT_TAPE_NEGO_IDP
;
3307 ddvtprintk((KERN_INFO
"Enabling QAS on id=%d due to ~TARGET_FLAGS_VALID_56!\n", id
));
3311 offset
= pspi_data
->maxSyncOffset
;
3313 /* If RAID, never disable QAS
3314 * else if non RAID, do not disable
3315 * QAS if bit 1 is set
3316 * bit 1 QAS support, non-raid only
3319 if (target
->raidVolume
== 1) {
3328 if ( (target
->inq_data
[7] & 0x02) == 0) {
3329 target
->tflags
&= ~MPT_TARGET_FLAGS_Q_YES
;
3332 /* Update tflags based on NVRAM settings. (SCSI only)
3334 if (pspi_data
->nvram
&& (pspi_data
->nvram
[id
] != MPT_HOST_NVRAM_INVALID
)) {
3335 nvram
= pspi_data
->nvram
[id
];
3336 nfactor
= (nvram
& MPT_NVRAM_SYNC_MASK
) >> 8;
3339 width
= nvram
& MPT_NVRAM_WIDE_DISABLE
? 0 : 1;
3342 /* Ensure factor is set to the
3343 * maximum of: adapter, nvram, inquiry
3346 if (nfactor
< pspi_data
->minSyncFactor
)
3347 nfactor
= pspi_data
->minSyncFactor
;
3349 factor
= max(factor
, nfactor
);
3350 if (factor
== MPT_ASYNC
)
3361 /* Make sure data is consistent
3363 if ((!width
) && (factor
< MPT_ULTRA2
)) {
3364 factor
= MPT_ULTRA2
;
3367 /* Save the data to the target structure.
3369 target
->minSyncFactor
= factor
;
3370 target
->maxOffset
= offset
;
3371 target
->maxWidth
= width
;
3373 target
->tflags
|= MPT_TARGET_FLAGS_VALID_NEGO
;
3375 /* Disable unused features.
3378 target
->negoFlags
|= MPT_TARGET_NO_NEGO_WIDE
;
3381 target
->negoFlags
|= MPT_TARGET_NO_NEGO_SYNC
;
3383 if ( factor
> MPT_ULTRA320
)
3386 /* GEM, processor WORKAROUND
3388 if ((target
->inq_data
[0] == TYPE_PROCESSOR
) || (target
->inq_data
[0] > 0x08)) {
3389 target
->negoFlags
|= (MPT_TARGET_NO_NEGO_WIDE
| MPT_TARGET_NO_NEGO_SYNC
);
3390 pspi_data
->dvStatus
[id
] |= MPT_SCSICFG_BLK_NEGO
;
3392 if (noQas
&& (pspi_data
->noQas
== 0)) {
3393 pspi_data
->noQas
|= MPT_TARGET_NO_NEGO_QAS
;
3394 target
->negoFlags
|= MPT_TARGET_NO_NEGO_QAS
;
3396 /* Disable QAS in a mixed configuration case
3399 ddvtprintk((KERN_INFO
"Disabling QAS due to noQas=%02x on id=%d!\n", noQas
, id
));
3400 for (ii
= 0; ii
< id
; ii
++) {
3401 if ( (vdev
= hd
->Targets
[ii
]) ) {
3402 vdev
->negoFlags
|= MPT_TARGET_NO_NEGO_QAS
;
3403 mptscsih_writeSDP1(hd
, 0, ii
, vdev
->negoFlags
);
3409 /* Write SDP1 on this I/O to this target */
3410 if (pspi_data
->dvStatus
[id
] & MPT_SCSICFG_NEGOTIATE
) {
3411 ddvtprintk((KERN_INFO
"MPT_SCSICFG_NEGOTIATE on id=%d!\n", id
));
3412 mptscsih_writeSDP1(hd
, 0, id
, hd
->negoNvram
);
3413 pspi_data
->dvStatus
[id
] &= ~MPT_SCSICFG_NEGOTIATE
;
3414 } else if (pspi_data
->dvStatus
[id
] & MPT_SCSICFG_BLK_NEGO
) {
3415 ddvtprintk((KERN_INFO
"MPT_SCSICFG_BLK_NEGO on id=%d!\n", id
));
3416 mptscsih_writeSDP1(hd
, 0, id
, MPT_SCSICFG_BLK_NEGO
);
3417 pspi_data
->dvStatus
[id
] &= ~MPT_SCSICFG_BLK_NEGO
;
3421 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3422 /* If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return.
3423 * Else set the NEED_DV flag after Read Capacity Issued (disks)
3424 * or Mode Sense (cdroms).
3426 * Tapes, initTarget will set this flag on completion of Inquiry command.
3427 * Called only if DV_NOT_DONE flag is set
3429 static void mptscsih_set_dvflags(MPT_SCSI_HOST
*hd
, SCSIIORequest_t
*pReq
)
3434 ddvtprintk((" set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
3435 pReq
->TargetID
, pReq
->LUN
[1], hd
->negoNvram
, pReq
->CDB
[0]));
3437 if ((pReq
->LUN
[1] != 0) || (hd
->negoNvram
!= 0))
3442 if ((cmd
== READ_CAPACITY
) || (cmd
== MODE_SENSE
)) {
3443 pSpi
= &hd
->ioc
->spi_data
;
3444 if ((pSpi
->isRaid
& (1 << pReq
->TargetID
)) && pSpi
->pIocPg3
) {
3445 /* Set NEED_DV for all hidden disks
3447 Ioc3PhysDisk_t
*pPDisk
= pSpi
->pIocPg3
->PhysDisk
;
3448 int numPDisk
= pSpi
->pIocPg3
->NumPhysDisks
;
3451 pSpi
->dvStatus
[pPDisk
->PhysDiskID
] |= MPT_SCSICFG_NEED_DV
;
3452 ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk
->PhysDiskID
));
3457 pSpi
->dvStatus
[pReq
->TargetID
] |= MPT_SCSICFG_NEED_DV
;
3458 ddvtprintk(("NEED_DV set for visible disk id %d\n", pReq
->TargetID
));
3462 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3464 * If no Target, bus reset on 1st I/O. Set the flag to
3465 * prevent any future negotiations to this device.
3467 static void mptscsih_no_negotiate(MPT_SCSI_HOST
*hd
, int target_id
)
3470 if ((hd
->Targets
) && (hd
->Targets
[target_id
] == NULL
))
3471 hd
->ioc
->spi_data
.dvStatus
[target_id
] |= MPT_SCSICFG_BLK_NEGO
;
3476 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3478 * SCSI Config Page functionality ...
3480 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3481 /* mptscsih_setDevicePage1Flags - add Requested and Configuration fields flags
3482 * based on width, factor and offset parameters.
3484 * @factor: sync factor
3485 * @offset: sync offset
3486 * @requestedPtr: pointer to requested values (updated)
3487 * @configurationPtr: pointer to configuration values (updated)
3488 * @flags: flags to block WDTR or SDTR negotiation
3492 * Remark: Called by writeSDP1 and _dv_params
3495 mptscsih_setDevicePage1Flags (u8 width
, u8 factor
, u8 offset
, int *requestedPtr
, int *configurationPtr
, u8 flags
)
3497 u8 nowide
= flags
& MPT_TARGET_NO_NEGO_WIDE
;
3498 u8 nosync
= flags
& MPT_TARGET_NO_NEGO_SYNC
;
3500 *configurationPtr
= 0;
3501 *requestedPtr
= width
? MPI_SCSIDEVPAGE1_RP_WIDE
: 0;
3502 *requestedPtr
|= (offset
<< 16) | (factor
<< 8);
3504 if (width
&& offset
&& !nowide
&& !nosync
) {
3505 if (factor
< MPT_ULTRA160
) {
3506 *requestedPtr
|= (MPI_SCSIDEVPAGE1_RP_IU
+ MPI_SCSIDEVPAGE1_RP_DT
);
3507 if ((flags
& MPT_TARGET_NO_NEGO_QAS
) == 0)
3508 *requestedPtr
|= MPI_SCSIDEVPAGE1_RP_QAS
;
3509 if (flags
& MPT_TAPE_NEGO_IDP
)
3510 *requestedPtr
|= 0x08000000;
3511 } else if (factor
< MPT_ULTRA2
) {
3512 *requestedPtr
|= MPI_SCSIDEVPAGE1_RP_DT
;
3517 *configurationPtr
|= MPI_SCSIDEVPAGE1_CONF_WDTR_DISALLOWED
;
3520 *configurationPtr
|= MPI_SCSIDEVPAGE1_CONF_SDTR_DISALLOWED
;
3525 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3526 /* mptscsih_writeSDP1 - write SCSI Device Page 1
3527 * @hd: Pointer to a SCSI Host Strucutre
3528 * @portnum: IOC port number
3529 * @target_id: writeSDP1 for single ID
3530 * @flags: MPT_SCSICFG_ALL_IDS, MPT_SCSICFG_USE_NVRAM, MPT_SCSICFG_BLK_NEGO
3532 * Return: -EFAULT if read of config page header fails
3535 * Remark: If a target has been found, the settings from the
3536 * target structure are used, else the device is set
3539 * Remark: Called during init and after a FW reload.
3540 * Remark: We do not wait for a return, write pages sequentially.
3543 mptscsih_writeSDP1(MPT_SCSI_HOST
*hd
, int portnum
, int target_id
, int flags
)
3545 MPT_ADAPTER
*ioc
= hd
->ioc
;
3547 SCSIDevicePage1_t
*pData
;
3548 VirtDevice
*pTarget
;
3553 u32 requested
, configuration
, flagsLength
;
3555 int id
= 0, maxid
= 0;
3561 u8 maxwidth
, maxoffset
, maxfactor
;
3563 if (ioc
->spi_data
.sdp1length
== 0)
3566 if (flags
& MPT_SCSICFG_ALL_IDS
) {
3568 maxid
= ioc
->sh
->max_id
- 1;
3569 } else if (ioc
->sh
) {
3571 maxid
= min_t(int, id
, ioc
->sh
->max_id
- 1);
3574 for (; id
<= maxid
; id
++) {
3576 if (id
== ioc
->pfacts
[portnum
].PortSCSIID
)
3579 /* Use NVRAM to get adapter and target maximums
3580 * Data over-riden by target structure information, if present
3582 maxwidth
= ioc
->spi_data
.maxBusWidth
;
3583 maxoffset
= ioc
->spi_data
.maxSyncOffset
;
3584 maxfactor
= ioc
->spi_data
.minSyncFactor
;
3585 if (ioc
->spi_data
.nvram
&& (ioc
->spi_data
.nvram
[id
] != MPT_HOST_NVRAM_INVALID
)) {
3586 nvram
= ioc
->spi_data
.nvram
[id
];
3589 maxwidth
= nvram
& MPT_NVRAM_WIDE_DISABLE
? 0 : 1;
3591 if (maxoffset
> 0) {
3592 maxfactor
= (nvram
& MPT_NVRAM_SYNC_MASK
) >> 8;
3593 if (maxfactor
== 0) {
3595 maxfactor
= MPT_ASYNC
;
3597 } else if (maxfactor
< ioc
->spi_data
.minSyncFactor
) {
3598 maxfactor
= ioc
->spi_data
.minSyncFactor
;
3601 maxfactor
= MPT_ASYNC
;
3604 /* Set the negotiation flags.
3606 negoFlags
= ioc
->spi_data
.noQas
;
3608 negoFlags
|= MPT_TARGET_NO_NEGO_WIDE
;
3611 negoFlags
|= MPT_TARGET_NO_NEGO_SYNC
;
3613 if (flags
& MPT_SCSICFG_USE_NVRAM
) {
3622 //negoFlags = MPT_TARGET_NO_NEGO_SYNC;
3625 /* If id is not a raid volume, get the updated
3626 * transmission settings from the target structure.
3628 if (hd
->Targets
&& (pTarget
= hd
->Targets
[id
]) && !pTarget
->raidVolume
) {
3629 width
= pTarget
->maxWidth
;
3630 factor
= pTarget
->minSyncFactor
;
3631 offset
= pTarget
->maxOffset
;
3632 negoFlags
= pTarget
->negoFlags
;
3635 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3636 /* Force to async and narrow if DV has not been executed
3639 if ((hd
->ioc
->spi_data
.dvStatus
[id
] & MPT_SCSICFG_DV_NOT_DONE
) != 0) {
3646 if (flags
& MPT_SCSICFG_BLK_NEGO
)
3647 negoFlags
= MPT_TARGET_NO_NEGO_WIDE
| MPT_TARGET_NO_NEGO_SYNC
;
3649 mptscsih_setDevicePage1Flags(width
, factor
, offset
,
3650 &requested
, &configuration
, negoFlags
);
3651 dnegoprintk(("writeSDP1: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
3652 target_id
, width
, factor
, offset
, negoFlags
, requested
, configuration
));
3654 /* Get a MF for this command.
3656 if ((mf
= mpt_get_msg_frame(ScsiDoneCtx
, ioc
)) == NULL
) {
3657 dprintk((MYIOC_s_WARN_FMT
"write SDP1: no msg frames!\n",
3662 ddvprintk((MYIOC_s_INFO_FMT
"WriteSDP1 (mf=%p, id=%d, req=0x%x, cfg=0x%x)\n",
3663 hd
->ioc
->name
, mf
, id
, requested
, configuration
));
3666 /* Set the request and the data pointers.
3667 * Request takes: 36 bytes (32 bit SGE)
3668 * SCSI Device Page 1 requires 16 bytes
3669 * 40 + 16 <= size of SCSI IO Request = 56 bytes
3670 * and MF size >= 64 bytes.
3671 * Place data at end of MF.
3673 pReq
= (Config_t
*)mf
;
3675 req_idx
= le16_to_cpu(mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
);
3676 frameOffset
= ioc
->req_sz
- sizeof(SCSIDevicePage1_t
);
3678 pData
= (SCSIDevicePage1_t
*)((u8
*) mf
+ frameOffset
);
3679 dataDma
= ioc
->req_frames_dma
+ (req_idx
* ioc
->req_sz
) + frameOffset
;
3681 /* Complete the request frame (same for all requests).
3683 pReq
->Action
= MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT
;
3685 pReq
->ChainOffset
= 0;
3686 pReq
->Function
= MPI_FUNCTION_CONFIG
;
3687 pReq
->ExtPageLength
= 0;
3688 pReq
->ExtPageType
= 0;
3690 for (ii
=0; ii
< 8; ii
++) {
3691 pReq
->Reserved2
[ii
] = 0;
3693 pReq
->Header
.PageVersion
= ioc
->spi_data
.sdp1version
;
3694 pReq
->Header
.PageLength
= ioc
->spi_data
.sdp1length
;
3695 pReq
->Header
.PageNumber
= 1;
3696 pReq
->Header
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_DEVICE
;
3697 pReq
->PageAddress
= cpu_to_le32(id
| (bus
<< 8 ));
3699 /* Add a SGE to the config request.
3701 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_WRITE
| ioc
->spi_data
.sdp1length
* 4;
3703 mpt_add_sge((char *)&pReq
->PageBufferSGE
, flagsLength
, dataDma
);
3705 /* Set up the common data portion
3707 pData
->Header
.PageVersion
= pReq
->Header
.PageVersion
;
3708 pData
->Header
.PageLength
= pReq
->Header
.PageLength
;
3709 pData
->Header
.PageNumber
= pReq
->Header
.PageNumber
;
3710 pData
->Header
.PageType
= pReq
->Header
.PageType
;
3711 pData
->RequestedParameters
= cpu_to_le32(requested
);
3712 pData
->Reserved
= 0;
3713 pData
->Configuration
= cpu_to_le32(configuration
);
3715 dprintk((MYIOC_s_INFO_FMT
3716 "write SDP1: id %d pgaddr 0x%x req 0x%x config 0x%x\n",
3717 ioc
->name
, id
, (id
| (bus
<<8)),
3718 requested
, configuration
));
3720 mpt_put_msg_frame(ScsiDoneCtx
, ioc
, mf
);
3726 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3727 /* mptscsih_writeIOCPage4 - write IOC Page 4
3728 * @hd: Pointer to a SCSI Host Structure
3729 * @target_id: write IOC Page4 for this ID & Bus
3731 * Return: -EAGAIN if unable to obtain a Message Frame
3734 * Remark: We do not wait for a return, write pages sequentially.
3737 mptscsih_writeIOCPage4(MPT_SCSI_HOST
*hd
, int target_id
, int bus
)
3739 MPT_ADAPTER
*ioc
= hd
->ioc
;
3741 IOCPage4_t
*IOCPage4Ptr
;
3749 /* Get a MF for this command.
3751 if ((mf
= mpt_get_msg_frame(ScsiDoneCtx
, ioc
)) == NULL
) {
3752 dprintk((MYIOC_s_WARN_FMT
"writeIOCPage4 : no msg frames!\n",
3757 /* Set the request and the data pointers.
3758 * Place data at end of MF.
3760 pReq
= (Config_t
*)mf
;
3762 req_idx
= le16_to_cpu(mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
);
3763 frameOffset
= ioc
->req_sz
- sizeof(IOCPage4_t
);
3765 /* Complete the request frame (same for all requests).
3767 pReq
->Action
= MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT
;
3769 pReq
->ChainOffset
= 0;
3770 pReq
->Function
= MPI_FUNCTION_CONFIG
;
3771 pReq
->ExtPageLength
= 0;
3772 pReq
->ExtPageType
= 0;
3774 for (ii
=0; ii
< 8; ii
++) {
3775 pReq
->Reserved2
[ii
] = 0;
3778 IOCPage4Ptr
= ioc
->spi_data
.pIocPg4
;
3779 dataDma
= ioc
->spi_data
.IocPg4_dma
;
3780 ii
= IOCPage4Ptr
->ActiveSEP
++;
3781 IOCPage4Ptr
->SEP
[ii
].SEPTargetID
= target_id
;
3782 IOCPage4Ptr
->SEP
[ii
].SEPBus
= bus
;
3783 pReq
->Header
= IOCPage4Ptr
->Header
;
3784 pReq
->PageAddress
= cpu_to_le32(target_id
| (bus
<< 8 ));
3786 /* Add a SGE to the config request.
3788 flagsLength
= MPT_SGE_FLAGS_SSIMPLE_WRITE
|
3789 (IOCPage4Ptr
->Header
.PageLength
+ ii
) * 4;
3791 mpt_add_sge((char *)&pReq
->PageBufferSGE
, flagsLength
, dataDma
);
3793 dinitprintk((MYIOC_s_INFO_FMT
3794 "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
3795 ioc
->name
, IOCPage4Ptr
->MaxSEP
, IOCPage4Ptr
->ActiveSEP
, target_id
, bus
));
3797 mpt_put_msg_frame(ScsiDoneCtx
, ioc
, mf
);
3802 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3804 * Bus Scan and Domain Validation functionality ...
3807 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3809 * mptscsih_scandv_complete - Scan and DV callback routine registered
3810 * to Fustion MPT (base) driver.
3812 * @ioc: Pointer to MPT_ADAPTER structure
3813 * @mf: Pointer to original MPT request frame
3814 * @mr: Pointer to MPT reply frame (NULL if TurboReply)
3816 * This routine is called from mpt.c::mpt_interrupt() at the completion
3817 * of any SCSI IO request.
3818 * This routine is registered with the Fusion MPT (base) driver at driver
3819 * load/init time via the mpt_register() API call.
3821 * Returns 1 indicating alloc'd request frame ptr should be freed.
3823 * Remark: Sets a completion code and (possibly) saves sense data
3824 * in the IOC member localReply structure.
3825 * Used ONLY for DV and other internal commands.
3828 mptscsih_scandv_complete(MPT_ADAPTER
*ioc
, MPT_FRAME_HDR
*mf
, MPT_FRAME_HDR
*mr
)
3831 SCSIIORequest_t
*pReq
;
3836 (mf
>= MPT_INDEX_2_MFPTR(ioc
, ioc
->req_depth
))) {
3837 printk(MYIOC_s_ERR_FMT
3838 "ScanDvComplete, %s req frame ptr! (=%p)\n",
3839 ioc
->name
, mf
?"BAD":"NULL", (void *) mf
);
3843 hd
= (MPT_SCSI_HOST
*) ioc
->sh
->hostdata
;
3844 del_timer(&hd
->timer
);
3845 req_idx
= le16_to_cpu(mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
);
3846 hd
->ScsiLookup
[req_idx
] = NULL
;
3847 pReq
= (SCSIIORequest_t
*) mf
;
3849 if (mf
!= hd
->cmdPtr
) {
3850 printk(MYIOC_s_WARN_FMT
"ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
3851 hd
->ioc
->name
, (void *)mf
, (void *) hd
->cmdPtr
, req_idx
);
3855 ddvprintk((MYIOC_s_INFO_FMT
"ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
3856 hd
->ioc
->name
, mf
, mr
, req_idx
));
3858 hd
->pLocal
= &hd
->localReply
;
3859 hd
->pLocal
->scsiStatus
= 0;
3861 /* If target struct exists, clear sense valid flag.
3864 completionCode
= MPT_SCANDV_GOOD
;
3866 SCSIIOReply_t
*pReply
;
3870 pReply
= (SCSIIOReply_t
*) mr
;
3872 status
= le16_to_cpu(pReply
->IOCStatus
) & MPI_IOCSTATUS_MASK
;
3873 scsi_status
= pReply
->SCSIStatus
;
3875 ddvtprintk((KERN_NOTICE
" IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
3876 status
, pReply
->SCSIState
, scsi_status
,
3877 le32_to_cpu(pReply
->IOCLogInfo
)));
3881 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE
: /* 0x0043 */
3882 completionCode
= MPT_SCANDV_SELECTION_TIMEOUT
;
3885 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR
: /* 0x0046 */
3886 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED
: /* 0x0048 */
3887 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED
: /* 0x004B */
3888 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED
: /* 0x004C */
3889 completionCode
= MPT_SCANDV_DID_RESET
;
3892 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN
: /* 0x0045 */
3893 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR
: /* 0x0040 */
3894 case MPI_IOCSTATUS_SUCCESS
: /* 0x0000 */
3895 if (pReply
->Function
== MPI_FUNCTION_CONFIG
) {
3896 ConfigReply_t
*pr
= (ConfigReply_t
*)mr
;
3897 completionCode
= MPT_SCANDV_GOOD
;
3898 hd
->pLocal
->header
.PageVersion
= pr
->Header
.PageVersion
;
3899 hd
->pLocal
->header
.PageLength
= pr
->Header
.PageLength
;
3900 hd
->pLocal
->header
.PageNumber
= pr
->Header
.PageNumber
;
3901 hd
->pLocal
->header
.PageType
= pr
->Header
.PageType
;
3903 } else if (pReply
->Function
== MPI_FUNCTION_RAID_ACTION
) {
3904 /* If the RAID Volume request is successful,
3905 * return GOOD, else indicate that
3906 * some type of error occurred.
3908 MpiRaidActionReply_t
*pr
= (MpiRaidActionReply_t
*)mr
;
3909 if (pr
->ActionStatus
== MPI_RAID_ACTION_ASTATUS_SUCCESS
)
3910 completionCode
= MPT_SCANDV_GOOD
;
3912 completionCode
= MPT_SCANDV_SOME_ERROR
;
3914 } else if (pReply
->SCSIState
& MPI_SCSI_STATE_AUTOSENSE_VALID
) {
3918 /* save sense data in global structure
3920 completionCode
= MPT_SCANDV_SENSE
;
3921 hd
->pLocal
->scsiStatus
= scsi_status
;
3922 sense_data
= ((u8
*)hd
->ioc
->sense_buf_pool
+
3923 (req_idx
* MPT_SENSE_BUFFER_ALLOC
));
3925 sz
= min_t(int, pReq
->SenseBufferLength
,
3926 SCSI_STD_SENSE_BYTES
);
3927 memcpy(hd
->pLocal
->sense
, sense_data
, sz
);
3929 ddvprintk((KERN_NOTICE
" Check Condition, sense ptr %p\n",
3931 } else if (pReply
->SCSIState
& MPI_SCSI_STATE_AUTOSENSE_FAILED
) {
3932 if (pReq
->CDB
[0] == INQUIRY
)
3933 completionCode
= MPT_SCANDV_ISSUE_SENSE
;
3935 completionCode
= MPT_SCANDV_DID_RESET
;
3937 else if (pReply
->SCSIState
& MPI_SCSI_STATE_NO_SCSI_STATUS
)
3938 completionCode
= MPT_SCANDV_DID_RESET
;
3939 else if (pReply
->SCSIState
& MPI_SCSI_STATE_TERMINATED
)
3940 completionCode
= MPT_SCANDV_DID_RESET
;
3942 completionCode
= MPT_SCANDV_GOOD
;
3943 hd
->pLocal
->scsiStatus
= scsi_status
;
3947 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR
: /* 0x0047 */
3948 if (pReply
->SCSIState
& MPI_SCSI_STATE_TERMINATED
)
3949 completionCode
= MPT_SCANDV_DID_RESET
;
3951 completionCode
= MPT_SCANDV_SOME_ERROR
;
3955 completionCode
= MPT_SCANDV_SOME_ERROR
;
3958 } /* switch(status) */
3960 ddvtprintk((KERN_NOTICE
" completionCode set to %08xh\n",
3962 } /* end of address reply case */
3964 hd
->pLocal
->completion
= completionCode
;
3966 /* MF and RF are freed in mpt_interrupt
3969 /* Free Chain buffers (will never chain) in scan or dv */
3970 //mptscsih_freeChainBuffers(ioc, req_idx);
3973 * Wake up the original calling thread
3975 scandv_wait_done
= 1;
3976 wake_up(&scandv_waitq
);
3981 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3982 /* mptscsih_timer_expired - Call back for timer process.
3983 * Used only for dv functionality.
3984 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
3987 static void mptscsih_timer_expired(unsigned long data
)
3989 MPT_SCSI_HOST
*hd
= (MPT_SCSI_HOST
*) data
;
3991 ddvprintk((MYIOC_s_WARN_FMT
"Timer Expired! Cmd %p\n", hd
->ioc
->name
, hd
->cmdPtr
));
3994 MPIHeader_t
*cmd
= (MPIHeader_t
*)hd
->cmdPtr
;
3996 if (cmd
->Function
== MPI_FUNCTION_SCSI_IO_REQUEST
) {
3997 /* Desire to issue a task management request here.
3998 * TM requests MUST be single threaded.
3999 * If old eh code and no TM current, issue request.
4000 * If new eh code, do nothing. Wait for OS cmd timeout
4003 ddvtprintk((MYIOC_s_NOTE_FMT
"DV Cmd Timeout: NoOp\n", hd
->ioc
->name
));
4005 /* Perform a FW reload */
4006 if (mpt_HardResetHandler(hd
->ioc
, NO_SLEEP
) < 0) {
4007 printk(MYIOC_s_WARN_FMT
"Firmware Reload FAILED!\n", hd
->ioc
->name
);
4011 /* This should NEVER happen */
4012 printk(MYIOC_s_WARN_FMT
"Null cmdPtr!!!!\n", hd
->ioc
->name
);
4015 /* No more processing.
4016 * TM call will generate an interrupt for SCSI TM Management.
4017 * The FW will reply to all outstanding commands, callback will finish cleanup.
4018 * Hard reset clean-up will free all resources.
4020 ddvprintk((MYIOC_s_WARN_FMT
"Timer Expired Complete!\n", hd
->ioc
->name
));
4025 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
4026 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4027 /* mptscsih_do_raid - Format and Issue a RAID volume request message.
4028 * @hd: Pointer to scsi host structure
4029 * @action: What do be done.
4030 * @id: Logical target id.
4031 * @bus: Target locations bus.
4033 * Returns: < 0 on a fatal error
4036 * Remark: Wait to return until reply processed by the ISR.
4039 mptscsih_do_raid(MPT_SCSI_HOST
*hd
, u8 action
, INTERNAL_CMD
*io
)
4041 MpiRaidActionRequest_t
*pReq
;
4045 in_isr
= in_interrupt();
4047 dprintk((MYIOC_s_WARN_FMT
"Internal raid request not allowed in ISR context!\n",
4052 /* Get and Populate a free Frame
4054 if ((mf
= mpt_get_msg_frame(ScsiScanDvCtx
, hd
->ioc
)) == NULL
) {
4055 ddvprintk((MYIOC_s_WARN_FMT
"_do_raid: no msg frames!\n",
4059 pReq
= (MpiRaidActionRequest_t
*)mf
;
4060 pReq
->Action
= action
;
4061 pReq
->Reserved1
= 0;
4062 pReq
->ChainOffset
= 0;
4063 pReq
->Function
= MPI_FUNCTION_RAID_ACTION
;
4064 pReq
->VolumeID
= io
->id
;
4065 pReq
->VolumeBus
= io
->bus
;
4066 pReq
->PhysDiskNum
= io
->physDiskNum
;
4068 pReq
->Reserved2
= 0;
4069 pReq
->ActionDataWord
= 0; /* Reserved for this action */
4070 //pReq->ActionDataSGE = 0;
4072 mpt_add_sge((char *)&pReq
->ActionDataSGE
,
4073 MPT_SGE_FLAGS_SSIMPLE_READ
| 0, (dma_addr_t
) -1);
4075 ddvprintk((MYIOC_s_INFO_FMT
"RAID Volume action %x id %d\n",
4076 hd
->ioc
->name
, action
, io
->id
));
4079 hd
->timer
.expires
= jiffies
+ HZ
*10; /* 10 second timeout */
4080 scandv_wait_done
= 0;
4082 /* Save cmd pointer, for resource free if timeout or
4087 add_timer(&hd
->timer
);
4088 mpt_put_msg_frame(ScsiScanDvCtx
, hd
->ioc
, mf
);
4089 wait_event(scandv_waitq
, scandv_wait_done
);
4091 if ((hd
->pLocal
== NULL
) || (hd
->pLocal
->completion
!= MPT_SCANDV_GOOD
))
4096 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
4098 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4100 * mptscsih_do_cmd - Do internal command.
4101 * @hd: MPT_SCSI_HOST pointer
4102 * @io: INTERNAL_CMD pointer.
4104 * Issue the specified internally generated command and do command
4105 * specific cleanup. For bus scan / DV only.
4106 * NOTES: If command is Inquiry and status is good,
4107 * initialize a target structure, save the data
4109 * Remark: Single threaded access only.
4112 * < 0 if an illegal command or no resources
4116 * > 0 if command complete but some type of completion error.
4119 mptscsih_do_cmd(MPT_SCSI_HOST
*hd
, INTERNAL_CMD
*io
)
4122 SCSIIORequest_t
*pScsiReq
;
4123 SCSIIORequest_t ReqCopy
;
4124 int my_idx
, ii
, dir
;
4128 char CDB
[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
4131 in_isr
= in_interrupt();
4133 dprintk((MYIOC_s_WARN_FMT
"Internal SCSI IO request not allowed in ISR context!\n",
4139 /* Set command specific information
4144 dir
= MPI_SCSIIO_CONTROL_READ
;
4150 case TEST_UNIT_READY
:
4152 dir
= MPI_SCSIIO_CONTROL_READ
;
4158 dir
= MPI_SCSIIO_CONTROL_READ
;
4160 CDB
[4] = 1; /*Spin up the disk */
4168 dir
= MPI_SCSIIO_CONTROL_READ
;
4174 dir
= MPI_SCSIIO_CONTROL_READ
;
4176 if (io
->flags
& MPT_ICFLAG_ECHO
) {
4182 if (io
->flags
& MPT_ICFLAG_BUF_CAP
) {
4185 CDB
[6] = (io
->size
>> 16) & 0xFF;
4186 CDB
[7] = (io
->size
>> 8) & 0xFF;
4187 CDB
[8] = io
->size
& 0xFF;
4193 dir
= MPI_SCSIIO_CONTROL_WRITE
;
4195 if (io
->flags
& MPT_ICFLAG_ECHO
) {
4200 CDB
[6] = (io
->size
>> 16) & 0xFF;
4201 CDB
[7] = (io
->size
>> 8) & 0xFF;
4202 CDB
[8] = io
->size
& 0xFF;
4208 dir
= MPI_SCSIIO_CONTROL_READ
;
4215 dir
= MPI_SCSIIO_CONTROL_READ
;
4220 case SYNCHRONIZE_CACHE
:
4222 dir
= MPI_SCSIIO_CONTROL_READ
;
4224 // CDB[1] = 0x02; /* set immediate bit */
4233 /* Get and Populate a free Frame
4235 if ((mf
= mpt_get_msg_frame(ScsiScanDvCtx
, hd
->ioc
)) == NULL
) {
4236 ddvprintk((MYIOC_s_WARN_FMT
"No msg frames!\n",
4241 pScsiReq
= (SCSIIORequest_t
*) mf
;
4243 /* Get the request index */
4244 my_idx
= le16_to_cpu(mf
->u
.frame
.hwhdr
.msgctxu
.fld
.req_idx
);
4245 ADD_INDEX_LOG(my_idx
); /* for debug */
4247 if (io
->flags
& MPT_ICFLAG_PHYS_DISK
) {
4248 pScsiReq
->TargetID
= io
->physDiskNum
;
4250 pScsiReq
->ChainOffset
= 0;
4251 pScsiReq
->Function
= MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH
;
4253 pScsiReq
->TargetID
= io
->id
;
4254 pScsiReq
->Bus
= io
->bus
;
4255 pScsiReq
->ChainOffset
= 0;
4256 pScsiReq
->Function
= MPI_FUNCTION_SCSI_IO_REQUEST
;
4259 pScsiReq
->CDBLength
= cmdLen
;
4260 pScsiReq
->SenseBufferLength
= MPT_SENSE_BUFFER_SIZE
;
4262 pScsiReq
->Reserved
= 0;
4264 pScsiReq
->MsgFlags
= mpt_msg_flags();
4265 /* MsgContext set in mpt_get_msg_fram call */
4267 for (ii
=0; ii
< 8; ii
++)
4268 pScsiReq
->LUN
[ii
] = 0;
4269 pScsiReq
->LUN
[1] = io
->lun
;
4271 if (io
->flags
& MPT_ICFLAG_TAGGED_CMD
)
4272 pScsiReq
->Control
= cpu_to_le32(dir
| MPI_SCSIIO_CONTROL_SIMPLEQ
);
4274 pScsiReq
->Control
= cpu_to_le32(dir
| MPI_SCSIIO_CONTROL_UNTAGGED
);
4276 if (cmd
== REQUEST_SENSE
) {
4277 pScsiReq
->Control
= cpu_to_le32(dir
| MPI_SCSIIO_CONTROL_UNTAGGED
);
4278 ddvprintk((MYIOC_s_INFO_FMT
"Untagged! 0x%2x\n",
4279 hd
->ioc
->name
, cmd
));
4282 for (ii
=0; ii
< 16; ii
++)
4283 pScsiReq
->CDB
[ii
] = CDB
[ii
];
4285 pScsiReq
->DataLength
= cpu_to_le32(io
->size
);
4286 pScsiReq
->SenseBufferLowAddr
= cpu_to_le32(hd
->ioc
->sense_buf_low_dma
4287 + (my_idx
* MPT_SENSE_BUFFER_ALLOC
));
4289 ddvprintk((MYIOC_s_INFO_FMT
"Sending Command 0x%x for (%d:%d:%d)\n",
4290 hd
->ioc
->name
, cmd
, io
->bus
, io
->id
, io
->lun
));
4292 if (dir
== MPI_SCSIIO_CONTROL_READ
) {
4293 mpt_add_sge((char *) &pScsiReq
->SGL
,
4294 MPT_SGE_FLAGS_SSIMPLE_READ
| io
->size
,
4297 mpt_add_sge((char *) &pScsiReq
->SGL
,
4298 MPT_SGE_FLAGS_SSIMPLE_WRITE
| io
->size
,
4302 /* The ISR will free the request frame, but we need
4303 * the information to initialize the target. Duplicate.
4305 memcpy(&ReqCopy
, pScsiReq
, sizeof(SCSIIORequest_t
));
4307 /* Issue this command after:
4310 * Wait until the reply has been received
4311 * ScsiScanDvCtx callback function will
4313 * set scandv_wait_done and call wake_up
4316 hd
->timer
.expires
= jiffies
+ HZ
*cmdTimeout
;
4317 scandv_wait_done
= 0;
4319 /* Save cmd pointer, for resource free if timeout or
4324 add_timer(&hd
->timer
);
4325 mpt_put_msg_frame(ScsiScanDvCtx
, hd
->ioc
, mf
);
4326 wait_event(scandv_waitq
, scandv_wait_done
);
4329 rc
= hd
->pLocal
->completion
;
4330 hd
->pLocal
->skip
= 0;
4332 /* Always set fatal error codes in some cases.
4334 if (rc
== MPT_SCANDV_SELECTION_TIMEOUT
)
4336 else if (rc
== MPT_SCANDV_SOME_ERROR
)
4340 /* This should never happen. */
4341 ddvprintk((MYIOC_s_INFO_FMT
"_do_cmd: Null pLocal!!!\n",
4348 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4350 * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
4351 * @hd: Pointer to MPT_SCSI_HOST structure
4352 * @portnum: IOC port number
4354 * Uses the ISR, but with special processing.
4355 * MUST be single-threaded.
4357 * Return: 0 on completion
4360 mptscsih_synchronize_cache(MPT_SCSI_HOST
*hd
, int portnum
)
4362 MPT_ADAPTER
*ioc
= hd
->ioc
;
4363 VirtDevice
*pTarget
;
4364 SCSIDevicePage1_t
*pcfg1Data
= NULL
;
4367 dma_addr_t cfg1_dma_addr
= -1;
4368 ConfigPageHeader_t header1
;
4372 int indexed_lun
, lun_index
;
4373 int hostId
= ioc
->pfacts
[portnum
].PortSCSIID
;
4375 int requested
, configuration
, data
;
4379 max_id
= ioc
->sh
->max_id
- 1;
4381 /* Following parameters will not change
4384 iocmd
.cmd
= SYNCHRONIZE_CACHE
;
4386 iocmd
.physDiskNum
= -1;
4388 iocmd
.data_dma
= -1;
4390 iocmd
.rsvd
= iocmd
.rsvd2
= 0;
4394 if (hd
->Targets
== NULL
)
4402 /* Write SDP1 for all SCSI devices
4403 * Alloc memory and set up config buffer
4405 if (ioc
->bus_type
== SCSI
) {
4406 if (ioc
->spi_data
.sdp1length
> 0) {
4407 pcfg1Data
= (SCSIDevicePage1_t
*)pci_alloc_consistent(ioc
->pcidev
,
4408 ioc
->spi_data
.sdp1length
* 4, &cfg1_dma_addr
);
4410 if (pcfg1Data
!= NULL
) {
4412 header1
.PageVersion
= ioc
->spi_data
.sdp1version
;
4413 header1
.PageLength
= ioc
->spi_data
.sdp1length
;
4414 header1
.PageNumber
= 1;
4415 header1
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_DEVICE
;
4417 cfg
.physAddr
= cfg1_dma_addr
;
4418 cfg
.action
= MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT
;
4425 /* loop through all devices on this port
4427 while (bus
< MPT_MAX_BUS
) {
4430 pTarget
= hd
->Targets
[(int)id
];
4434 /* Set the negotiation flags */
4435 if (pTarget
&& (pTarget
= hd
->Targets
[id
]) && !pTarget
->raidVolume
) {
4436 flags
= pTarget
->negoFlags
;
4438 flags
= hd
->ioc
->spi_data
.noQas
;
4439 if (hd
->ioc
->spi_data
.nvram
&& (hd
->ioc
->spi_data
.nvram
[id
] != MPT_HOST_NVRAM_INVALID
)) {
4440 data
= hd
->ioc
->spi_data
.nvram
[id
];
4442 if (data
& MPT_NVRAM_WIDE_DISABLE
)
4443 flags
|= MPT_TARGET_NO_NEGO_WIDE
;
4445 factor
= (data
& MPT_NVRAM_SYNC_MASK
) >> MPT_NVRAM_SYNC_SHIFT
;
4446 if ((factor
== 0) || (factor
== MPT_ASYNC
))
4447 flags
|= MPT_TARGET_NO_NEGO_SYNC
;
4451 /* Force to async, narrow */
4452 mptscsih_setDevicePage1Flags(0, MPT_ASYNC
, 0, &requested
,
4453 &configuration
, flags
);
4454 dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
4455 "offset=0 negoFlags=%x request=%x config=%x\n",
4456 id
, flags
, requested
, configuration
));
4457 pcfg1Data
->RequestedParameters
= le32_to_cpu(requested
);
4458 pcfg1Data
->Reserved
= 0;
4459 pcfg1Data
->Configuration
= le32_to_cpu(configuration
);
4460 cfg
.pageAddr
= (bus
<<8) | id
;
4461 mpt_config(hd
->ioc
, &cfg
);
4464 /* If target Ptr NULL or if this target is NOT a disk, skip.
4466 if ((pTarget
) && (pTarget
->tflags
& MPT_TARGET_FLAGS_Q_YES
)){
4467 for (lun
=0; lun
<= MPT_LAST_LUN
; lun
++) {
4468 /* If LUN present, issue the command
4470 lun_index
= (lun
>> 5); /* 32 luns per lun_index */
4471 indexed_lun
= (lun
% 32);
4472 if (pTarget
->luns
[lun_index
] & (1<<indexed_lun
)) {
4474 (void) mptscsih_do_cmd(hd
, &iocmd
);
4479 /* get next relevant device */
4492 pci_free_consistent(ioc
->pcidev
, header1
.PageLength
* 4, pcfg1Data
, cfg1_dma_addr
);
4498 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
4499 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4501 * mptscsih_domainValidation - Top level handler for domain validation.
4502 * @hd: Pointer to MPT_SCSI_HOST structure.
4504 * Uses the ISR, but with special processing.
4505 * Called from schedule, should not be in interrupt mode.
4506 * While thread alive, do dv for all devices needing dv
4511 mptscsih_domainValidation(void *arg
)
4515 unsigned long flags
;
4516 int id
, maxid
, dvStatus
, did
;
4519 spin_lock_irqsave(&dvtaskQ_lock
, flags
);
4521 if (dvtaskQ_release
) {
4523 spin_unlock_irqrestore(&dvtaskQ_lock
, flags
);
4526 spin_unlock_irqrestore(&dvtaskQ_lock
, flags
);
4528 /* For this ioc, loop through all devices and do dv to each device.
4529 * When complete with this ioc, search through the ioc list, and
4530 * for each scsi ioc found, do dv for all devices. Exit when no
4536 list_for_each_entry(ioc
, &ioc_list
, list
) {
4537 spin_lock_irqsave(&dvtaskQ_lock
, flags
);
4538 if (dvtaskQ_release
) {
4540 spin_unlock_irqrestore(&dvtaskQ_lock
, flags
);
4543 spin_unlock_irqrestore(&dvtaskQ_lock
, flags
);
4547 /* DV only to SCSI adapters */
4548 if (ioc
->bus_type
!= SCSI
)
4551 /* Make sure everything looks ok */
4552 if (ioc
->sh
== NULL
)
4555 hd
= (MPT_SCSI_HOST
*) ioc
->sh
->hostdata
;
4559 if ((ioc
->spi_data
.forceDv
& MPT_SCSICFG_RELOAD_IOC_PG3
) != 0) {
4560 mpt_read_ioc_pg_3(ioc
);
4561 if (ioc
->spi_data
.pIocPg3
) {
4562 Ioc3PhysDisk_t
*pPDisk
= ioc
->spi_data
.pIocPg3
->PhysDisk
;
4563 int numPDisk
= ioc
->spi_data
.pIocPg3
->NumPhysDisks
;
4566 if (ioc
->spi_data
.dvStatus
[pPDisk
->PhysDiskID
] & MPT_SCSICFG_DV_NOT_DONE
)
4567 ioc
->spi_data
.dvStatus
[pPDisk
->PhysDiskID
] |= MPT_SCSICFG_NEED_DV
;
4573 ioc
->spi_data
.forceDv
&= ~MPT_SCSICFG_RELOAD_IOC_PG3
;
4576 maxid
= min_t(int, ioc
->sh
->max_id
, MPT_MAX_SCSI_DEVICES
);
4578 for (id
= 0; id
< maxid
; id
++) {
4579 spin_lock_irqsave(&dvtaskQ_lock
, flags
);
4580 if (dvtaskQ_release
) {
4582 spin_unlock_irqrestore(&dvtaskQ_lock
, flags
);
4585 spin_unlock_irqrestore(&dvtaskQ_lock
, flags
);
4586 dvStatus
= hd
->ioc
->spi_data
.dvStatus
[id
];
4588 if (dvStatus
& MPT_SCSICFG_NEED_DV
) {
4590 hd
->ioc
->spi_data
.dvStatus
[id
] |= MPT_SCSICFG_DV_PENDING
;
4591 hd
->ioc
->spi_data
.dvStatus
[id
] &= ~MPT_SCSICFG_NEED_DV
;
4595 /* If hidden phys disk, block IO's to all
4597 * else, process normally
4599 isPhysDisk
= mptscsih_is_phys_disk(ioc
, id
);
4601 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
4602 if (hd
->ioc
->spi_data
.isRaid
& (1 << ii
)) {
4603 hd
->ioc
->spi_data
.dvStatus
[ii
] |= MPT_SCSICFG_DV_PENDING
;
4608 if (mptscsih_doDv(hd
, 0, id
) == 1) {
4609 /* Untagged device was busy, try again
4611 hd
->ioc
->spi_data
.dvStatus
[id
] |= MPT_SCSICFG_NEED_DV
;
4612 hd
->ioc
->spi_data
.dvStatus
[id
] &= ~MPT_SCSICFG_DV_PENDING
;
4614 /* DV is complete. Clear flags.
4616 hd
->ioc
->spi_data
.dvStatus
[id
] &= ~(MPT_SCSICFG_DV_NOT_DONE
| MPT_SCSICFG_DV_PENDING
);
4620 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
4621 if (hd
->ioc
->spi_data
.isRaid
& (1 << ii
)) {
4622 hd
->ioc
->spi_data
.dvStatus
[ii
] &= ~MPT_SCSICFG_DV_PENDING
;
4627 if (hd
->ioc
->spi_data
.noQas
)
4628 mptscsih_qas_check(hd
, id
);
4634 spin_lock_irqsave(&dvtaskQ_lock
, flags
);
4636 spin_unlock_irqrestore(&dvtaskQ_lock
, flags
);
4641 /* Search IOC page 3 to determine if this is hidden physical disk
4643 static int mptscsih_is_phys_disk(MPT_ADAPTER
*ioc
, int id
)
4645 if (ioc
->spi_data
.pIocPg3
) {
4646 Ioc3PhysDisk_t
*pPDisk
= ioc
->spi_data
.pIocPg3
->PhysDisk
;
4647 int numPDisk
= ioc
->spi_data
.pIocPg3
->NumPhysDisks
;
4650 if (pPDisk
->PhysDiskID
== id
) {
4660 /* Write SDP1 if no QAS has been enabled
4662 static void mptscsih_qas_check(MPT_SCSI_HOST
*hd
, int id
)
4664 VirtDevice
*pTarget
;
4667 if (hd
->Targets
== NULL
)
4670 for (ii
=0; ii
< MPT_MAX_SCSI_DEVICES
; ii
++) {
4674 if ((hd
->ioc
->spi_data
.dvStatus
[ii
] & MPT_SCSICFG_DV_NOT_DONE
) != 0)
4677 pTarget
= hd
->Targets
[ii
];
4679 if ((pTarget
!= NULL
) && (!pTarget
->raidVolume
)) {
4680 if ((pTarget
->negoFlags
& hd
->ioc
->spi_data
.noQas
) == 0) {
4681 pTarget
->negoFlags
|= hd
->ioc
->spi_data
.noQas
;
4682 dnegoprintk(("writeSDP1: id=%d flags=0\n", id
));
4683 mptscsih_writeSDP1(hd
, 0, ii
, 0);
4686 if (mptscsih_is_phys_disk(hd
->ioc
, ii
) == 1) {
4687 dnegoprintk(("writeSDP1: id=%d SCSICFG_USE_NVRAM\n", id
));
4688 mptscsih_writeSDP1(hd
, 0, ii
, MPT_SCSICFG_USE_NVRAM
);
4697 #define MPT_GET_NVRAM_VALS 0x01
4698 #define MPT_UPDATE_MAX 0x02
4699 #define MPT_SET_MAX 0x04
4700 #define MPT_SET_MIN 0x08
4701 #define MPT_FALLBACK 0x10
4702 #define MPT_SAVE 0x20
4704 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4706 * mptscsih_doDv - Perform domain validation to a target.
4707 * @hd: Pointer to MPT_SCSI_HOST structure.
4708 * @portnum: IOC port number.
4709 * @target: Physical ID of this target
4711 * Uses the ISR, but with special processing.
4712 * MUST be single-threaded.
4713 * Test will exit if target is at async & narrow.
4718 mptscsih_doDv(MPT_SCSI_HOST
*hd
, int bus_number
, int id
)
4720 MPT_ADAPTER
*ioc
= hd
->ioc
;
4721 VirtDevice
*pTarget
;
4722 SCSIDevicePage1_t
*pcfg1Data
;
4723 SCSIDevicePage0_t
*pcfg0Data
;
4727 dma_addr_t dvbuf_dma
= -1;
4728 dma_addr_t buf1_dma
= -1;
4729 dma_addr_t buf2_dma
= -1;
4730 dma_addr_t cfg1_dma_addr
= -1;
4731 dma_addr_t cfg0_dma_addr
= -1;
4732 ConfigPageHeader_t header1
;
4733 ConfigPageHeader_t header0
;
4740 int dataBufSize
= 0;
4741 int echoBufSize
= 0;
4746 int nfactor
= MPT_ULTRA320
;
4748 char doFallback
= 0;
4753 if (ioc
->spi_data
.sdp1length
== 0)
4756 if (ioc
->spi_data
.sdp0length
== 0)
4759 /* If multiple buses are used, require that the initiator
4760 * id be the same on all buses.
4762 if (id
== ioc
->pfacts
[0].PortSCSIID
)
4766 bus
= (u8
) bus_number
;
4767 ddvtprintk((MYIOC_s_NOTE_FMT
4768 "DV started: bus=%d, id=%d dv @ %p\n",
4769 ioc
->name
, bus
, id
, &dv
));
4771 /* Prep DV structure
4773 memset (&dv
, 0, sizeof(DVPARAMETERS
));
4776 /* Populate tmax with the current maximum
4777 * transfer parameters for this target.
4778 * Exit if narrow and async.
4780 dv
.cmd
= MPT_GET_NVRAM_VALS
;
4781 mptscsih_dv_parms(hd
, &dv
, NULL
);
4783 /* Prep SCSI IO structure
4789 iocmd
.physDiskNum
= -1;
4790 iocmd
.rsvd
= iocmd
.rsvd2
= 0;
4792 pTarget
= hd
->Targets
[id
];
4794 /* Use tagged commands if possible.
4797 if (pTarget
->tflags
& MPT_TARGET_FLAGS_Q_YES
)
4798 iocmd
.flags
|= MPT_ICFLAG_TAGGED_CMD
;
4800 if (hd
->ioc
->facts
.FWVersion
.Word
< 0x01000600)
4803 if ((hd
->ioc
->facts
.FWVersion
.Word
>= 0x01010000) &&
4804 (hd
->ioc
->facts
.FWVersion
.Word
< 0x01010B00))
4809 /* Prep cfg structure
4811 cfg
.pageAddr
= (bus
<<8) | id
;
4816 header0
.PageVersion
= ioc
->spi_data
.sdp0version
;
4817 header0
.PageLength
= ioc
->spi_data
.sdp0length
;
4818 header0
.PageNumber
= 0;
4819 header0
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_DEVICE
;
4823 header1
.PageVersion
= ioc
->spi_data
.sdp1version
;
4824 header1
.PageLength
= ioc
->spi_data
.sdp1length
;
4825 header1
.PageNumber
= 1;
4826 header1
.PageType
= MPI_CONFIG_PAGETYPE_SCSI_DEVICE
;
4828 if (header0
.PageLength
& 1)
4829 dv_alloc
= (header0
.PageLength
* 4) + 4;
4831 dv_alloc
+= (2048 + (header1
.PageLength
* 4));
4833 pDvBuf
= pci_alloc_consistent(ioc
->pcidev
, dv_alloc
, &dvbuf_dma
);
4838 pbuf1
= (u8
*)pDvBuf
;
4839 buf1_dma
= dvbuf_dma
;
4842 pbuf2
= (u8
*) (pDvBuf
+ sz
);
4843 buf2_dma
= dvbuf_dma
+ sz
;
4846 pcfg0Data
= (SCSIDevicePage0_t
*) (pDvBuf
+ sz
);
4847 cfg0_dma_addr
= dvbuf_dma
+ sz
;
4848 sz
+= header0
.PageLength
* 4;
4852 if (header0
.PageLength
& 1)
4855 pcfg1Data
= (SCSIDevicePage1_t
*) (pDvBuf
+ sz
);
4856 cfg1_dma_addr
= dvbuf_dma
+ sz
;
4858 /* Skip this ID? Set cfg.hdr to force config page write
4861 ScsiCfgData
*pspi_data
= &hd
->ioc
->spi_data
;
4862 if (pspi_data
->nvram
&& (pspi_data
->nvram
[id
] != MPT_HOST_NVRAM_INVALID
)) {
4863 /* Set the factor from nvram */
4864 nfactor
= (pspi_data
->nvram
[id
] & MPT_NVRAM_SYNC_MASK
) >> 8;
4865 if (nfactor
< pspi_data
->minSyncFactor
)
4866 nfactor
= pspi_data
->minSyncFactor
;
4868 if (!(pspi_data
->nvram
[id
] & MPT_NVRAM_ID_SCAN_ENABLE
) ||
4869 (pspi_data
->PortFlags
== MPI_SCSIPORTPAGE2_PORT_FLAGS_OFF_DV
) ) {
4871 ddvprintk((MYIOC_s_NOTE_FMT
"DV Skipped: bus, id, lun (%d, %d, %d)\n",
4872 ioc
->name
, bus
, id
, lun
));
4874 dv
.cmd
= MPT_SET_MAX
;
4875 mptscsih_dv_parms(hd
, &dv
, (void *)pcfg1Data
);
4878 /* Save the final negotiated settings to
4879 * SCSI device page 1.
4881 cfg
.physAddr
= cfg1_dma_addr
;
4882 cfg
.action
= MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT
;
4884 mpt_config(hd
->ioc
, &cfg
);
4890 /* Finish iocmd inititialization - hidden or visible disk? */
4891 if (ioc
->spi_data
.pIocPg3
) {
4892 /* Search IOC page 3 for matching id
4894 Ioc3PhysDisk_t
*pPDisk
= ioc
->spi_data
.pIocPg3
->PhysDisk
;
4895 int numPDisk
= ioc
->spi_data
.pIocPg3
->NumPhysDisks
;
4898 if (pPDisk
->PhysDiskID
== id
) {
4900 iocmd
.flags
|= MPT_ICFLAG_PHYS_DISK
;
4901 iocmd
.physDiskNum
= pPDisk
->PhysDiskNum
;
4905 if (mptscsih_do_raid(hd
, MPI_RAID_ACTION_QUIESCE_PHYS_IO
, &iocmd
) < 0) {
4906 ddvprintk((MYIOC_s_ERR_FMT
"RAID Queisce FAILED!\n", ioc
->name
));
4916 /* RAID Volume ID's may double for a physical device. If RAID but
4917 * not a physical ID as well, skip DV.
4919 if ((hd
->ioc
->spi_data
.isRaid
& (1 << id
)) && !(iocmd
.flags
& MPT_ICFLAG_PHYS_DISK
))
4924 * Async & Narrow - Inquiry
4925 * Async & Narrow - Inquiry
4926 * Maximum transfer rate - Inquiry
4928 * If compare, test complete.
4929 * If miscompare and first pass, repeat
4930 * If miscompare and not first pass, fall back and repeat
4934 sz
= SCSI_MAX_INQUIRY_BYTES
;
4935 rc
= MPT_SCANDV_GOOD
;
4937 ddvprintk((MYIOC_s_NOTE_FMT
"DV: Start Basic test on id=%d\n", ioc
->name
, id
));
4939 dv
.cmd
= MPT_SET_MIN
;
4940 mptscsih_dv_parms(hd
, &dv
, (void *)pcfg1Data
);
4943 cfg
.physAddr
= cfg1_dma_addr
;
4944 cfg
.action
= MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT
;
4946 if (mpt_config(hd
->ioc
, &cfg
) != 0)
4949 /* Wide - narrow - wide workaround case
4951 if ((rc
== MPT_SCANDV_ISSUE_SENSE
) && dv
.max
.width
) {
4952 /* Send an untagged command to reset disk Qs corrupted
4953 * when a parity error occurs on a Request Sense.
4955 if ((hd
->ioc
->facts
.FWVersion
.Word
>= 0x01000600) ||
4956 ((hd
->ioc
->facts
.FWVersion
.Word
>= 0x01010000) &&
4957 (hd
->ioc
->facts
.FWVersion
.Word
< 0x01010B00)) ) {
4959 iocmd
.cmd
= REQUEST_SENSE
;
4960 iocmd
.data_dma
= buf1_dma
;
4963 if (mptscsih_do_cmd(hd
, &iocmd
) < 0)
4966 if (hd
->pLocal
== NULL
)
4968 rc
= hd
->pLocal
->completion
;
4969 if ((rc
== MPT_SCANDV_GOOD
) || (rc
== MPT_SCANDV_SENSE
)) {
4979 iocmd
.cmd
= INQUIRY
;
4980 iocmd
.data_dma
= buf1_dma
;
4983 memset(pbuf1
, 0x00, sz
);
4984 if (mptscsih_do_cmd(hd
, &iocmd
) < 0)
4987 if (hd
->pLocal
== NULL
)
4989 rc
= hd
->pLocal
->completion
;
4990 if (rc
== MPT_SCANDV_GOOD
) {
4991 if (hd
->pLocal
->scsiStatus
== SAM_STAT_BUSY
) {
4992 if ((iocmd
.flags
& MPT_ICFLAG_TAGGED_CMD
) == 0)
4999 } else if (rc
== MPT_SCANDV_SENSE
) {
5002 /* If first command doesn't complete
5003 * with a good status or with a check condition,
5010 /* Reset the size for disks
5012 inq0
= (*pbuf1
) & 0x1F;
5013 if ((inq0
== 0) && pTarget
&& !pTarget
->raidVolume
) {
5018 /* Another GEM workaround. Check peripheral device type,
5019 * if PROCESSOR, quit DV.
5021 if (inq0
== TYPE_PROCESSOR
) {
5022 mptscsih_initTarget(hd
,
5034 if (mptscsih_do_cmd(hd
, &iocmd
) < 0)
5038 if ((pTarget
->maxWidth
== 1) && (pTarget
->maxOffset
) && (nfactor
< 0x0A)
5039 && (pTarget
->minSyncFactor
> 0x09)) {
5040 if ((pbuf1
[56] & 0x04) == 0)
5042 else if ((pbuf1
[56] & 0x01) == 1) {
5043 pTarget
->minSyncFactor
=
5044 nfactor
> MPT_ULTRA320
? nfactor
: MPT_ULTRA320
;
5046 pTarget
->minSyncFactor
=
5047 nfactor
> MPT_ULTRA160
? nfactor
: MPT_ULTRA160
;
5050 dv
.max
.factor
= pTarget
->minSyncFactor
;
5052 if ((pbuf1
[56] & 0x02) == 0) {
5053 pTarget
->negoFlags
|= MPT_TARGET_NO_NEGO_QAS
;
5054 hd
->ioc
->spi_data
.noQas
= MPT_TARGET_NO_NEGO_QAS
;
5055 ddvprintk((MYIOC_s_NOTE_FMT
5056 "DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n",
5057 ioc
->name
, id
, pbuf1
[56]));
5063 dv
.cmd
= MPT_FALLBACK
;
5065 dv
.cmd
= MPT_SET_MAX
;
5067 mptscsih_dv_parms(hd
, &dv
, (void *)pcfg1Data
);
5068 if (mpt_config(hd
->ioc
, &cfg
) != 0)
5071 if ((!dv
.now
.width
) && (!dv
.now
.offset
))
5074 iocmd
.cmd
= INQUIRY
;
5075 iocmd
.data_dma
= buf2_dma
;
5078 memset(pbuf2
, 0x00, sz
);
5079 if (mptscsih_do_cmd(hd
, &iocmd
) < 0)
5081 else if (hd
->pLocal
== NULL
)
5084 /* Save the return code.
5085 * If this is the first pass,
5086 * read SCSI Device Page 0
5087 * and update the target max parameters.
5089 rc
= hd
->pLocal
->completion
;
5091 if (rc
== MPT_SCANDV_GOOD
) {
5097 cfg
.physAddr
= cfg0_dma_addr
;
5098 cfg
.action
= MPI_CONFIG_ACTION_PAGE_READ_CURRENT
;
5101 if (mpt_config(hd
->ioc
, &cfg
) != 0)
5104 sdp0_info
= le32_to_cpu(pcfg0Data
->Information
) & 0x0E;
5105 sdp0_nego
= (le32_to_cpu(pcfg0Data
->NegotiatedParameters
) & 0xFF00 ) >> 8;
5107 /* Quantum and Fujitsu workarounds.
5108 * Quantum: PPR U320 -> PPR reply with Ultra2 and wide
5109 * Fujitsu: PPR U320 -> Msg Reject and Ultra2 and wide
5110 * Resetart with a request for U160.
5112 if ((dv
.now
.factor
== MPT_ULTRA320
) && (sdp0_nego
== MPT_ULTRA2
)) {
5115 dv
.cmd
= MPT_UPDATE_MAX
;
5116 mptscsih_dv_parms(hd
, &dv
, (void *)pcfg0Data
);
5117 /* Update the SCSI device page 1 area
5119 pcfg1Data
->RequestedParameters
= pcfg0Data
->NegotiatedParameters
;
5124 /* Quantum workaround. Restart this test will the fallback
5127 if (doFallback
== 0) {
5128 if (memcmp(pbuf1
, pbuf2
, sz
) != 0) {
5132 ddvprintk((MYIOC_s_NOTE_FMT
5133 "DV:Inquiry compared id=%d, calling initTarget\n", ioc
->name
, id
));
5134 hd
->ioc
->spi_data
.dvStatus
[id
] &= ~MPT_SCSICFG_DV_NOT_DONE
;
5135 mptscsih_initTarget(hd
,
5141 break; /* test complete */
5146 } else if (rc
== MPT_SCANDV_ISSUE_SENSE
)
5147 doFallback
= 1; /* set fallback flag */
5148 else if ((rc
== MPT_SCANDV_DID_RESET
) ||
5149 (rc
== MPT_SCANDV_SENSE
) ||
5150 (rc
== MPT_SCANDV_FALLBACK
))
5151 doFallback
= 1; /* set fallback flag */
5158 ddvprintk((MYIOC_s_NOTE_FMT
"DV: Basic test on id=%d completed OK.\n", ioc
->name
, id
));
5163 inq0
= (*pbuf1
) & 0x1F;
5165 /* Continue only for disks
5170 if ( ioc
->spi_data
.PortFlags
== MPI_SCSIPORTPAGE2_PORT_FLAGS_BASIC_DV_ONLY
)
5173 /* Start the Enhanced Test.
5174 * 0) issue TUR to clear out check conditions
5175 * 1) read capacity of echo (regular) buffer
5177 * 3) do write-read-compare data pattern test
5179 * 5) update nego parms to target struct
5182 cfg
.physAddr
= cfg1_dma_addr
;
5183 cfg
.action
= MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT
;
5186 iocmd
.cmd
= TEST_UNIT_READY
;
5187 iocmd
.data_dma
= -1;
5192 if (mptscsih_do_cmd(hd
, &iocmd
) < 0)
5195 if (hd
->pLocal
== NULL
)
5198 rc
= hd
->pLocal
->completion
;
5199 if (rc
== MPT_SCANDV_GOOD
)
5201 else if (rc
== MPT_SCANDV_SENSE
) {
5202 u8 skey
= hd
->pLocal
->sense
[2] & 0x0F;
5203 u8 asc
= hd
->pLocal
->sense
[12];
5204 u8 ascq
= hd
->pLocal
->sense
[13];
5205 ddvprintk((MYIOC_s_INFO_FMT
5206 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
5207 ioc
->name
, skey
, asc
, ascq
));
5209 if (skey
== UNIT_ATTENTION
)
5210 notDone
++; /* repeat */
5211 else if ((skey
== NOT_READY
) &&
5212 (asc
== 0x04)&&(ascq
== 0x01)) {
5213 /* wait then repeat */
5216 } else if ((skey
== NOT_READY
) && (asc
== 0x3A)) {
5217 /* no medium, try read test anyway */
5220 /* All other errors are fatal.
5222 ddvprintk((MYIOC_s_INFO_FMT
"DV: fatal error.",
5230 iocmd
.cmd
= READ_BUFFER
;
5231 iocmd
.data_dma
= buf1_dma
;
5234 iocmd
.flags
|= MPT_ICFLAG_BUF_CAP
;
5238 for (patt
= 0; patt
< 2; patt
++) {
5240 iocmd
.flags
|= MPT_ICFLAG_ECHO
;
5242 iocmd
.flags
&= ~MPT_ICFLAG_ECHO
;
5248 /* If not ready after 8 trials,
5249 * give up on this device.
5254 if (mptscsih_do_cmd(hd
, &iocmd
) < 0)
5256 else if (hd
->pLocal
== NULL
)
5259 rc
= hd
->pLocal
->completion
;
5260 ddvprintk(("ReadBuffer Comp Code %d", rc
));
5261 ddvprintk((" buff: %0x %0x %0x %0x\n",
5262 pbuf1
[0], pbuf1
[1], pbuf1
[2], pbuf1
[3]));
5264 if (rc
== MPT_SCANDV_GOOD
) {
5266 if (iocmd
.flags
& MPT_ICFLAG_ECHO
) {
5267 bufsize
= ((pbuf1
[2] & 0x1F) <<8) | pbuf1
[3];
5269 bufsize
= pbuf1
[1]<<16 | pbuf1
[2]<<8 | pbuf1
[3];
5271 } else if (rc
== MPT_SCANDV_SENSE
) {
5272 u8 skey
= hd
->pLocal
->sense
[2] & 0x0F;
5273 u8 asc
= hd
->pLocal
->sense
[12];
5274 u8 ascq
= hd
->pLocal
->sense
[13];
5275 ddvprintk((MYIOC_s_INFO_FMT
5276 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
5277 ioc
->name
, skey
, asc
, ascq
));
5278 if (skey
== ILLEGAL_REQUEST
) {
5280 } else if (skey
== UNIT_ATTENTION
) {
5281 notDone
++; /* repeat */
5282 } else if ((skey
== NOT_READY
) &&
5283 (asc
== 0x04)&&(ascq
== 0x01)) {
5284 /* wait then repeat */
5288 /* All other errors are fatal.
5290 ddvprintk((MYIOC_s_INFO_FMT
"DV: fatal error.",
5295 /* All other errors are fatal
5302 if (iocmd
.flags
& MPT_ICFLAG_ECHO
)
5303 echoBufSize
= bufsize
;
5305 dataBufSize
= bufsize
;
5308 iocmd
.flags
&= ~MPT_ICFLAG_BUF_CAP
;
5310 /* Use echo buffers if possible,
5311 * Exit if both buffers are 0.
5313 if (echoBufSize
> 0) {
5314 iocmd
.flags
|= MPT_ICFLAG_ECHO
;
5315 if (dataBufSize
> 0)
5316 bufsize
= min(echoBufSize
, dataBufSize
);
5318 bufsize
= echoBufSize
;
5319 } else if (dataBufSize
== 0)
5322 ddvprintk((MYIOC_s_INFO_FMT
"%s Buffer Capacity %d\n", ioc
->name
,
5323 (iocmd
.flags
& MPT_ICFLAG_ECHO
) ? "Echo" : " ", bufsize
));
5325 /* Data buffers for write-read-compare test max 1K.
5327 sz
= min(bufsize
, 1024);
5330 * On first pass, always issue a reserve.
5331 * On additional loops, only if a reset has occurred.
5332 * iocmd.flags indicates if echo or regular buffer
5334 for (patt
= 0; patt
< 4; patt
++) {
5335 ddvprintk(("Pattern %d\n", patt
));
5336 if ((iocmd
.flags
& MPT_ICFLAG_RESERVED
) && (iocmd
.flags
& MPT_ICFLAG_DID_RESET
)) {
5337 iocmd
.cmd
= TEST_UNIT_READY
;
5338 iocmd
.data_dma
= -1;
5341 if (mptscsih_do_cmd(hd
, &iocmd
) < 0)
5344 iocmd
.cmd
= RELEASE
;
5345 iocmd
.data_dma
= -1;
5348 if (mptscsih_do_cmd(hd
, &iocmd
) < 0)
5350 else if (hd
->pLocal
== NULL
)
5353 rc
= hd
->pLocal
->completion
;
5354 ddvprintk(("Release rc %d\n", rc
));
5355 if (rc
== MPT_SCANDV_GOOD
)
5356 iocmd
.flags
&= ~MPT_ICFLAG_RESERVED
;
5360 iocmd
.flags
&= ~MPT_ICFLAG_RESERVED
;
5362 iocmd
.flags
&= ~MPT_ICFLAG_DID_RESET
;
5365 while (repeat
&& (!(iocmd
.flags
& MPT_ICFLAG_RESERVED
))) {
5366 iocmd
.cmd
= RESERVE
;
5367 iocmd
.data_dma
= -1;
5370 if (mptscsih_do_cmd(hd
, &iocmd
) < 0)
5372 else if (hd
->pLocal
== NULL
)
5375 rc
= hd
->pLocal
->completion
;
5376 if (rc
== MPT_SCANDV_GOOD
) {
5377 iocmd
.flags
|= MPT_ICFLAG_RESERVED
;
5378 } else if (rc
== MPT_SCANDV_SENSE
) {
5379 /* Wait if coming ready
5381 u8 skey
= hd
->pLocal
->sense
[2] & 0x0F;
5382 u8 asc
= hd
->pLocal
->sense
[12];
5383 u8 ascq
= hd
->pLocal
->sense
[13];
5384 ddvprintk((MYIOC_s_INFO_FMT
5385 "DV: Reserve Failed: ", ioc
->name
));
5386 ddvprintk(("SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
5389 if ((skey
== NOT_READY
) && (asc
== 0x04)&&
5391 /* wait then repeat */
5395 ddvprintk((MYIOC_s_INFO_FMT
5396 "DV: Reserved Failed.", ioc
->name
));
5400 ddvprintk((MYIOC_s_INFO_FMT
"DV: Reserved Failed.",
5407 mptscsih_fillbuf(pbuf1
, sz
, patt
, 1);
5408 iocmd
.cmd
= WRITE_BUFFER
;
5409 iocmd
.data_dma
= buf1_dma
;
5412 if (mptscsih_do_cmd(hd
, &iocmd
) < 0)
5414 else if (hd
->pLocal
== NULL
)
5417 rc
= hd
->pLocal
->completion
;
5418 if (rc
== MPT_SCANDV_GOOD
)
5419 ; /* Issue read buffer */
5420 else if (rc
== MPT_SCANDV_DID_RESET
) {
5421 /* If using echo buffers, reset to data buffers.
5422 * Else do Fallback and restart
5423 * this test (re-issue reserve
5424 * because of bus reset).
5426 if ((iocmd
.flags
& MPT_ICFLAG_ECHO
) && (dataBufSize
>= bufsize
)) {
5427 iocmd
.flags
&= ~MPT_ICFLAG_ECHO
;
5429 dv
.cmd
= MPT_FALLBACK
;
5430 mptscsih_dv_parms(hd
, &dv
, (void *)pcfg1Data
);
5432 if (mpt_config(hd
->ioc
, &cfg
) != 0)
5435 if ((!dv
.now
.width
) && (!dv
.now
.offset
))
5439 iocmd
.flags
|= MPT_ICFLAG_DID_RESET
;
5442 } else if (rc
== MPT_SCANDV_SENSE
) {
5443 /* Restart data test if UA, else quit.
5445 u8 skey
= hd
->pLocal
->sense
[2] & 0x0F;
5446 ddvprintk((MYIOC_s_INFO_FMT
5447 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc
->name
, skey
,
5448 hd
->pLocal
->sense
[12], hd
->pLocal
->sense
[13]));
5449 if (skey
== UNIT_ATTENTION
) {
5452 } else if (skey
== ILLEGAL_REQUEST
) {
5453 if (iocmd
.flags
& MPT_ICFLAG_ECHO
) {
5454 if (dataBufSize
>= bufsize
) {
5455 iocmd
.flags
&= ~MPT_ICFLAG_ECHO
;
5470 iocmd
.cmd
= READ_BUFFER
;
5471 iocmd
.data_dma
= buf2_dma
;
5474 if (mptscsih_do_cmd(hd
, &iocmd
) < 0)
5476 else if (hd
->pLocal
== NULL
)
5479 rc
= hd
->pLocal
->completion
;
5480 if (rc
== MPT_SCANDV_GOOD
) {
5481 /* If buffers compare,
5482 * go to next pattern,
5483 * else, do a fallback and restart
5484 * data transfer test.
5486 if (memcmp (pbuf1
, pbuf2
, sz
) == 0) {
5487 ; /* goto next pattern */
5489 /* Miscompare with Echo buffer, go to data buffer,
5490 * if that buffer exists.
5491 * Miscompare with Data buffer, check first 4 bytes,
5492 * some devices return capacity. Exit in this case.
5494 if (iocmd
.flags
& MPT_ICFLAG_ECHO
) {
5495 if (dataBufSize
>= bufsize
)
5496 iocmd
.flags
&= ~MPT_ICFLAG_ECHO
;
5500 if (dataBufSize
== (pbuf2
[1]<<16 | pbuf2
[2]<<8 | pbuf2
[3])) {
5501 /* Argh. Device returning wrong data.
5502 * Quit DV for this device.
5507 /* Had an actual miscompare. Slow down.*/
5508 dv
.cmd
= MPT_FALLBACK
;
5509 mptscsih_dv_parms(hd
, &dv
, (void *)pcfg1Data
);
5511 if (mpt_config(hd
->ioc
, &cfg
) != 0)
5514 if ((!dv
.now
.width
) && (!dv
.now
.offset
))
5521 } else if (rc
== MPT_SCANDV_DID_RESET
) {
5522 /* Do Fallback and restart
5523 * this test (re-issue reserve
5524 * because of bus reset).
5526 dv
.cmd
= MPT_FALLBACK
;
5527 mptscsih_dv_parms(hd
, &dv
, (void *)pcfg1Data
);
5529 if (mpt_config(hd
->ioc
, &cfg
) != 0)
5532 if ((!dv
.now
.width
) && (!dv
.now
.offset
))
5535 iocmd
.flags
|= MPT_ICFLAG_DID_RESET
;
5538 } else if (rc
== MPT_SCANDV_SENSE
) {
5539 /* Restart data test if UA, else quit.
5541 u8 skey
= hd
->pLocal
->sense
[2] & 0x0F;
5542 ddvprintk((MYIOC_s_INFO_FMT
5543 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc
->name
, skey
,
5544 hd
->pLocal
->sense
[12], hd
->pLocal
->sense
[13]));
5545 if (skey
== UNIT_ATTENTION
) {
5557 } /* --- end of patt loop ---- */
5560 if (iocmd
.flags
& MPT_ICFLAG_RESERVED
) {
5561 iocmd
.cmd
= RELEASE
;
5562 iocmd
.data_dma
= -1;
5565 if (mptscsih_do_cmd(hd
, &iocmd
) < 0)
5566 printk(MYIOC_s_INFO_FMT
"DV: Release failed. id %d",
5568 else if (hd
->pLocal
) {
5569 if (hd
->pLocal
->completion
== MPT_SCANDV_GOOD
)
5570 iocmd
.flags
&= ~MPT_ICFLAG_RESERVED
;
5572 printk(MYIOC_s_INFO_FMT
"DV: Release failed. id %d",
5578 /* Set if cfg1_dma_addr contents is valid
5580 if ((cfg
.hdr
!= NULL
) && (retcode
== 0)){
5581 /* If disk, not U320, disable QAS
5583 if ((inq0
== 0) && (dv
.now
.factor
> MPT_ULTRA320
)) {
5584 hd
->ioc
->spi_data
.noQas
= MPT_TARGET_NO_NEGO_QAS
;
5585 ddvprintk((MYIOC_s_NOTE_FMT
5586 "noQas set due to id=%d has factor=%x\n", ioc
->name
, id
, dv
.now
.factor
));
5590 mptscsih_dv_parms(hd
, &dv
, (void *)pcfg1Data
);
5592 /* Double writes to SDP1 can cause problems,
5593 * skip save of the final negotiated settings to
5594 * SCSI device page 1.
5597 cfg.physAddr = cfg1_dma_addr;
5598 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5600 mpt_config(hd->ioc, &cfg);
5604 /* If this is a RAID Passthrough, enable internal IOs
5606 if (iocmd
.flags
& MPT_ICFLAG_PHYS_DISK
) {
5607 if (mptscsih_do_raid(hd
, MPI_RAID_ACTION_ENABLE_PHYS_IO
, &iocmd
) < 0)
5608 ddvprintk((MYIOC_s_ERR_FMT
"RAID Enable FAILED!\n", ioc
->name
));
5611 /* Done with the DV scan of the current target
5614 pci_free_consistent(ioc
->pcidev
, dv_alloc
, pDvBuf
, dvbuf_dma
);
5616 ddvtprintk((MYIOC_s_INFO_FMT
"DV Done id=%d\n",
5622 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5623 /* mptscsih_dv_parms - perform a variety of operations on the
5624 * parameters used for negotiation.
5625 * @hd: Pointer to a SCSI host.
5626 * @dv: Pointer to a structure that contains the maximum and current
5627 * negotiated parameters.
5630 mptscsih_dv_parms(MPT_SCSI_HOST
*hd
, DVPARAMETERS
*dv
,void *pPage
)
5632 VirtDevice
*pTarget
;
5633 SCSIDevicePage0_t
*pPage0
;
5634 SCSIDevicePage1_t
*pPage1
;
5635 int val
= 0, data
, configuration
;
5644 case MPT_GET_NVRAM_VALS
:
5645 ddvprintk((MYIOC_s_NOTE_FMT
"Getting NVRAM: ",
5647 /* Get the NVRAM values and save in tmax
5648 * If not an LVD bus, the adapter minSyncFactor has been
5649 * already throttled back.
5651 if ((hd
->Targets
)&&((pTarget
= hd
->Targets
[(int)id
]) != NULL
) && !pTarget
->raidVolume
) {
5652 width
= pTarget
->maxWidth
;
5653 offset
= pTarget
->maxOffset
;
5654 factor
= pTarget
->minSyncFactor
;
5655 negoFlags
= pTarget
->negoFlags
;
5657 if (hd
->ioc
->spi_data
.nvram
&& (hd
->ioc
->spi_data
.nvram
[id
] != MPT_HOST_NVRAM_INVALID
)) {
5658 data
= hd
->ioc
->spi_data
.nvram
[id
];
5659 width
= data
& MPT_NVRAM_WIDE_DISABLE
? 0 : 1;
5660 if ((offset
= hd
->ioc
->spi_data
.maxSyncOffset
) == 0)
5663 factor
= (data
& MPT_NVRAM_SYNC_MASK
) >> MPT_NVRAM_SYNC_SHIFT
;
5664 if ((factor
== 0) || (factor
== MPT_ASYNC
)){
5675 /* Set the negotiation flags */
5676 negoFlags
= hd
->ioc
->spi_data
.noQas
;
5678 negoFlags
|= MPT_TARGET_NO_NEGO_WIDE
;
5681 negoFlags
|= MPT_TARGET_NO_NEGO_SYNC
;
5684 /* limit by adapter capabilities */
5685 width
= min(width
, hd
->ioc
->spi_data
.maxBusWidth
);
5686 offset
= min(offset
, hd
->ioc
->spi_data
.maxSyncOffset
);
5687 factor
= max(factor
, hd
->ioc
->spi_data
.minSyncFactor
);
5689 /* Check Consistency */
5690 if (offset
&& (factor
< MPT_ULTRA2
) && !width
)
5691 factor
= MPT_ULTRA2
;
5693 dv
->max
.width
= width
;
5694 dv
->max
.offset
= offset
;
5695 dv
->max
.factor
= factor
;
5696 dv
->max
.flags
= negoFlags
;
5697 ddvprintk((" id=%d width=%d factor=%x offset=%x flags=%x\n",
5698 id
, width
, factor
, offset
, negoFlags
));
5701 case MPT_UPDATE_MAX
:
5702 ddvprintk((MYIOC_s_NOTE_FMT
5703 "Updating with SDP0 Data: ", hd
->ioc
->name
));
5704 /* Update tmax values with those from Device Page 0.*/
5705 pPage0
= (SCSIDevicePage0_t
*) pPage
;
5707 val
= cpu_to_le32(pPage0
->NegotiatedParameters
);
5708 dv
->max
.width
= val
& MPI_SCSIDEVPAGE0_NP_WIDE
? 1 : 0;
5709 dv
->max
.offset
= (val
&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK
) >> 16;
5710 dv
->max
.factor
= (val
&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK
) >> 8;
5713 dv
->now
.width
= dv
->max
.width
;
5714 dv
->now
.offset
= dv
->max
.offset
;
5715 dv
->now
.factor
= dv
->max
.factor
;
5716 ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x\n",
5717 id
, dv
->now
.width
, dv
->now
.factor
, dv
->now
.offset
, dv
->now
.flags
));
5721 ddvprintk((MYIOC_s_NOTE_FMT
"Setting Max: ",
5723 /* Set current to the max values. Update the config page.*/
5724 dv
->now
.width
= dv
->max
.width
;
5725 dv
->now
.offset
= dv
->max
.offset
;
5726 dv
->now
.factor
= dv
->max
.factor
;
5727 dv
->now
.flags
= dv
->max
.flags
;
5729 pPage1
= (SCSIDevicePage1_t
*)pPage
;
5731 mptscsih_setDevicePage1Flags (dv
->now
.width
, dv
->now
.factor
,
5732 dv
->now
.offset
, &val
, &configuration
, dv
->now
.flags
);
5733 dnegoprintk(("Setting Max: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
5734 id
, dv
->now
.width
, dv
->now
.factor
, dv
->now
.offset
, dv
->now
.flags
, val
, configuration
));
5735 pPage1
->RequestedParameters
= le32_to_cpu(val
);
5736 pPage1
->Reserved
= 0;
5737 pPage1
->Configuration
= le32_to_cpu(configuration
);
5740 ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x request=%x configuration=%x\n",
5741 id
, dv
->now
.width
, dv
->now
.factor
, dv
->now
.offset
, dv
->now
.flags
, val
, configuration
));
5745 ddvprintk((MYIOC_s_NOTE_FMT
"Setting Min: ",
5747 /* Set page to asynchronous and narrow
5748 * Do not update now, breaks fallback routine. */
5752 negoFlags
= dv
->max
.flags
;
5754 pPage1
= (SCSIDevicePage1_t
*)pPage
;
5756 mptscsih_setDevicePage1Flags (width
, factor
,
5757 offset
, &val
, &configuration
, negoFlags
);
5758 dnegoprintk(("Setting Min: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
5759 id
, width
, factor
, offset
, negoFlags
, val
, configuration
));
5760 pPage1
->RequestedParameters
= le32_to_cpu(val
);
5761 pPage1
->Reserved
= 0;
5762 pPage1
->Configuration
= le32_to_cpu(configuration
);
5764 ddvprintk(("id=%d width=%d factor=%x offset=%x request=%x config=%x negoFlags=%x\n",
5765 id
, width
, factor
, offset
, val
, configuration
, negoFlags
));
5769 ddvprintk((MYIOC_s_NOTE_FMT
5770 "Fallback: Start: offset %d, factor %x, width %d \n",
5771 hd
->ioc
->name
, dv
->now
.offset
,
5772 dv
->now
.factor
, dv
->now
.width
));
5773 width
= dv
->now
.width
;
5774 offset
= dv
->now
.offset
;
5775 factor
= dv
->now
.factor
;
5776 if ((offset
) && (dv
->max
.width
)) {
5777 if (factor
< MPT_ULTRA160
)
5778 factor
= MPT_ULTRA160
;
5779 else if (factor
< MPT_ULTRA2
) {
5780 factor
= MPT_ULTRA2
;
5782 } else if ((factor
== MPT_ULTRA2
) && width
) {
5783 factor
= MPT_ULTRA2
;
5785 } else if (factor
< MPT_ULTRA
) {
5788 } else if ((factor
== MPT_ULTRA
) && width
) {
5790 } else if (factor
< MPT_FAST
) {
5793 } else if ((factor
== MPT_FAST
) && width
) {
5796 } else if (factor
< MPT_SCSI
) {
5799 } else if ((factor
== MPT_SCSI
) && width
) {
5807 } else if (offset
) {
5809 if (factor
< MPT_ULTRA
)
5811 else if (factor
< MPT_FAST
)
5813 else if (factor
< MPT_SCSI
)
5824 dv
->max
.flags
|= MPT_TARGET_NO_NEGO_QAS
;
5825 dv
->max
.flags
&= ~MPT_TAPE_NEGO_IDP
;
5827 dv
->now
.width
= width
;
5828 dv
->now
.offset
= offset
;
5829 dv
->now
.factor
= factor
;
5830 dv
->now
.flags
= dv
->max
.flags
;
5832 pPage1
= (SCSIDevicePage1_t
*)pPage
;
5834 mptscsih_setDevicePage1Flags (width
, factor
, offset
, &val
,
5835 &configuration
, dv
->now
.flags
);
5836 dnegoprintk(("Finish: id=%d width=%d offset=%d factor=%x flags=%x request=%x config=%x\n",
5837 id
, width
, offset
, factor
, dv
->now
.flags
, val
, configuration
));
5839 pPage1
->RequestedParameters
= le32_to_cpu(val
);
5840 pPage1
->Reserved
= 0;
5841 pPage1
->Configuration
= le32_to_cpu(configuration
);
5844 ddvprintk(("Finish: id=%d offset=%d factor=%x width=%d request=%x config=%x\n",
5845 id
, dv
->now
.offset
, dv
->now
.factor
, dv
->now
.width
, val
, configuration
));
5849 ddvprintk((MYIOC_s_NOTE_FMT
5850 "Saving to Target structure: ", hd
->ioc
->name
));
5851 ddvprintk(("id=%d width=%x factor=%x offset=%d flags=%x\n",
5852 id
, dv
->now
.width
, dv
->now
.factor
, dv
->now
.offset
, dv
->now
.flags
));
5854 /* Save these values to target structures
5855 * or overwrite nvram (phys disks only).
5858 if ((hd
->Targets
)&&((pTarget
= hd
->Targets
[(int)id
]) != NULL
) && !pTarget
->raidVolume
) {
5859 pTarget
->maxWidth
= dv
->now
.width
;
5860 pTarget
->maxOffset
= dv
->now
.offset
;
5861 pTarget
->minSyncFactor
= dv
->now
.factor
;
5862 pTarget
->negoFlags
= dv
->now
.flags
;
5864 /* Preserv all flags, use
5865 * read-modify-write algorithm
5867 if (hd
->ioc
->spi_data
.nvram
) {
5868 data
= hd
->ioc
->spi_data
.nvram
[id
];
5871 data
&= ~MPT_NVRAM_WIDE_DISABLE
;
5873 data
|= MPT_NVRAM_WIDE_DISABLE
;
5875 if (!dv
->now
.offset
)
5878 data
&= ~MPT_NVRAM_SYNC_MASK
;
5879 data
|= (dv
->now
.factor
<< MPT_NVRAM_SYNC_SHIFT
) & MPT_NVRAM_SYNC_MASK
;
5881 hd
->ioc
->spi_data
.nvram
[id
] = data
;
5888 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5889 /* mptscsih_fillbuf - fill a buffer with a special data pattern
5890 * cleanup. For bus scan only.
5892 * @buffer: Pointer to data buffer to be filled.
5893 * @size: Number of bytes to fill
5894 * @index: Pattern index
5895 * @width: bus width, 0 (8 bits) or 1 (16 bits)
5898 mptscsih_fillbuf(char *buffer
, int size
, int index
, int width
)
5909 /* Pattern: 0000 FFFF 0000 FFFF
5911 for (ii
=0; ii
< size
; ii
++, ptr
++) {
5918 /* Pattern: 00 FF 00 FF
5920 for (ii
=0; ii
< size
; ii
++, ptr
++) {
5931 /* Pattern: 5555 AAAA 5555 AAAA 5555
5933 for (ii
=0; ii
< size
; ii
++, ptr
++) {
5940 /* Pattern: 55 AA 55 AA 55
5942 for (ii
=0; ii
< size
; ii
++, ptr
++) {
5952 /* Pattern: 00 01 02 03 04 05
5955 for (ii
=0; ii
< size
; ii
++, ptr
++)
5961 /* Wide Pattern: FFFE 0001 FFFD 0002
5962 * ... 4000 DFFF 8000 EFFF
5965 for (ii
=0; ii
< size
/2; ii
++) {
5966 /* Create the base pattern
5969 /* every 64 (0x40) bytes flip the pattern
5970 * since we fill 2 bytes / iteration,
5971 * test for ii = 0x20
5977 *ptr
= (char)( (val
& 0xFF00) >> 8);
5979 *ptr
= (char)(val
& 0xFF);
5984 *ptr
= (char)( (val
& 0xFF00) >> 8);
5986 *ptr
= (char)(val
& 0xFF);
5992 /* Narrow Pattern: FE 01 FD 02 FB 04
5993 * .. 7F 80 01 FE 02 FD ... 80 7F
5996 for (ii
=0; ii
< size
; ii
++, ptr
++) {
5997 /* Base pattern - first 32 bytes
6004 *ptr
= (char) (~(1 << byte
));
6007 /* Flip the pattern every 32 bytes
6016 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
6018 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6020 module_init(mptscsih_init
);
6021 module_exit(mptscsih_exit
);