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