efae9be453706a4c53c0070f23ae9aa9bdc0eba8
[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 if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1869 SCpnt->device->channel, 0, 0, 0, 5 /* 5 second timeout */)
1870 < 0){
1871
1872 /* The TM request failed and the subsequent FW-reload failed!
1873 * Fatal error case.
1874 */
1875 printk(MYIOC_s_WARN_FMT
1876 "Error processing TaskMgmt request (sc=%p)\n",
1877 hd->ioc->name, SCpnt);
1878 hd->tmPending = 0;
1879 hd->tmState = TM_STATE_NONE;
1880 spin_lock_irq(host_lock);
1881 return FAILED;
1882 }
1883
1884 return SUCCESS;
1885 }
1886
1887 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1888 /**
1889 * mptscsih_host_reset - Perform a SCSI host adapter RESET!
1890 * new_eh variant
1891 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1892 *
1893 * (linux scsi_host_template.eh_host_reset_handler routine)
1894 *
1895 * Returns SUCCESS or FAILED.
1896 */
1897 int
1898 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
1899 {
1900 MPT_SCSI_HOST * hd;
1901 int status = SUCCESS;
1902 spinlock_t *host_lock = SCpnt->device->host->host_lock;
1903
1904 /* If we can't locate the host to reset, then we failed. */
1905 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){
1906 dtmprintk( ( KERN_WARNING MYNAM ": mptscsih_host_reset: "
1907 "Can't locate host! (sc=%p)\n",
1908 SCpnt ) );
1909 return FAILED;
1910 }
1911
1912 printk(KERN_WARNING MYNAM ": %s: >> Attempting host reset! (sc=%p)\n",
1913 hd->ioc->name, SCpnt);
1914
1915 /* If our attempts to reset the host failed, then return a failed
1916 * status. The host will be taken off line by the SCSI mid-layer.
1917 */
1918 spin_unlock_irq(host_lock);
1919 if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){
1920 status = FAILED;
1921 } else {
1922 /* Make sure TM pending is cleared and TM state is set to
1923 * NONE.
1924 */
1925 hd->tmPending = 0;
1926 hd->tmState = TM_STATE_NONE;
1927 }
1928 spin_lock_irq(host_lock);
1929
1930
1931 dtmprintk( ( KERN_WARNING MYNAM ": mptscsih_host_reset: "
1932 "Status = %s\n",
1933 (status == SUCCESS) ? "SUCCESS" : "FAILED" ) );
1934
1935 return status;
1936 }
1937
1938 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1939 /**
1940 * mptscsih_tm_pending_wait - wait for pending task management request to
1941 * complete.
1942 * @hd: Pointer to MPT host structure.
1943 *
1944 * Returns {SUCCESS,FAILED}.
1945 */
1946 static int
1947 mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
1948 {
1949 unsigned long flags;
1950 int loop_count = 4 * 10; /* Wait 10 seconds */
1951 int status = FAILED;
1952
1953 do {
1954 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1955 if (hd->tmState == TM_STATE_NONE) {
1956 hd->tmState = TM_STATE_IN_PROGRESS;
1957 hd->tmPending = 1;
1958 status = SUCCESS;
1959 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1960 break;
1961 }
1962 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1963 msleep(250);
1964 } while (--loop_count);
1965
1966 return status;
1967 }
1968
1969 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1970 /**
1971 * mptscsih_tm_wait_for_completion - wait for completion of TM task
1972 * @hd: Pointer to MPT host structure.
1973 *
1974 * Returns {SUCCESS,FAILED}.
1975 */
1976 static int
1977 mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
1978 {
1979 unsigned long flags;
1980 int loop_count = 4 * timeout;
1981 int status = FAILED;
1982
1983 do {
1984 spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
1985 if(hd->tmPending == 0) {
1986 status = SUCCESS;
1987 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1988 break;
1989 }
1990 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
1991 msleep_interruptible(250);
1992 } while (--loop_count);
1993
1994 return status;
1995 }
1996
1997 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1998 /**
1999 * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2000 * @ioc: Pointer to MPT_ADAPTER structure
2001 * @mf: Pointer to SCSI task mgmt request frame
2002 * @mr: Pointer to SCSI task mgmt reply frame
2003 *
2004 * This routine is called from mptbase.c::mpt_interrupt() at the completion
2005 * of any SCSI task management request.
2006 * This routine is registered with the MPT (base) driver at driver
2007 * load/init time via the mpt_register() API call.
2008 *
2009 * Returns 1 indicating alloc'd request frame ptr should be freed.
2010 */
2011 int
2012 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2013 {
2014 SCSITaskMgmtReply_t *pScsiTmReply;
2015 SCSITaskMgmt_t *pScsiTmReq;
2016 MPT_SCSI_HOST *hd;
2017 unsigned long flags;
2018 u16 iocstatus;
2019 u8 tmType;
2020
2021 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
2022 ioc->name, mf, mr));
2023 if (ioc->sh) {
2024 /* Depending on the thread, a timer is activated for
2025 * the TM request. Delete this timer on completion of TM.
2026 * Decrement count of outstanding TM requests.
2027 */
2028 hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
2029 } else {
2030 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n",
2031 ioc->name));
2032 return 1;
2033 }
2034
2035 if (mr == NULL) {
2036 dtmprintk((MYIOC_s_WARN_FMT "ERROR! TaskMgmt Reply: NULL Request %p\n",
2037 ioc->name, mf));
2038 return 1;
2039 } else {
2040 pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
2041 pScsiTmReq = (SCSITaskMgmt_t*)mf;
2042
2043 /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
2044 tmType = pScsiTmReq->TaskType;
2045
2046 dtmprintk((MYIOC_s_WARN_FMT " TaskType = %d, TerminationCount=%d\n",
2047 ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount)));
2048 DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
2049
2050 iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2051 dtmprintk((MYIOC_s_WARN_FMT " SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",
2052 ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo)));
2053 /* Error? (anything non-zero?) */
2054 if (iocstatus) {
2055
2056 /* clear flags and continue.
2057 */
2058 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
2059 hd->abortSCpnt = NULL;
2060
2061 /* If an internal command is present
2062 * or the TM failed - reload the FW.
2063 * FC FW may respond FAILED to an ABORT
2064 */
2065 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
2066 if ((hd->cmdPtr) ||
2067 (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED)) {
2068 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {
2069 printk((KERN_WARNING
2070 " Firmware Reload FAILED!!\n"));
2071 }
2072 }
2073 }
2074 } else {
2075 dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
2076
2077 hd->abortSCpnt = NULL;
2078
2079 }
2080 }
2081
2082 spin_lock_irqsave(&ioc->FreeQlock, flags);
2083 hd->tmPending = 0;
2084 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2085 hd->tmState = TM_STATE_NONE;
2086
2087 return 1;
2088 }
2089
2090 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2091 /*
2092 * This is anyones guess quite frankly.
2093 */
2094 int
2095 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2096 sector_t capacity, int geom[])
2097 {
2098 int heads;
2099 int sectors;
2100 sector_t cylinders;
2101 ulong dummy;
2102
2103 heads = 64;
2104 sectors = 32;
2105
2106 dummy = heads * sectors;
2107 cylinders = capacity;
2108 sector_div(cylinders,dummy);
2109
2110 /*
2111 * Handle extended translation size for logical drives
2112 * > 1Gb
2113 */
2114 if ((ulong)capacity >= 0x200000) {
2115 heads = 255;
2116 sectors = 63;
2117 dummy = heads * sectors;
2118 cylinders = capacity;
2119 sector_div(cylinders,dummy);
2120 }
2121
2122 /* return result */
2123 geom[0] = heads;
2124 geom[1] = sectors;
2125 geom[2] = cylinders;
2126
2127 dprintk((KERN_NOTICE
2128 ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n",
2129 sdev->id, sdev->lun,sdev->channel,(int)cylinders,heads,sectors));
2130
2131 return 0;
2132 }
2133
2134 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2135 /*
2136 * OS entry point to allow host driver to alloc memory
2137 * for each scsi device. Called once per device the bus scan.
2138 * Return non-zero if allocation fails.
2139 * Init memory once per id (not LUN).
2140 */
2141 int
2142 mptscsih_slave_alloc(struct scsi_device *device)
2143 {
2144 struct Scsi_Host *host = device->host;
2145 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2146 VirtDevice *vdev;
2147 uint target = device->id;
2148
2149 if (hd == NULL)
2150 return -ENODEV;
2151
2152 if ((vdev = hd->Targets[target]) != NULL)
2153 goto out;
2154
2155 vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
2156 if (!vdev) {
2157 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
2158 hd->ioc->name, sizeof(VirtDevice));
2159 return -ENOMEM;
2160 }
2161
2162 memset(vdev, 0, sizeof(VirtDevice));
2163 vdev->tflags = MPT_TARGET_FLAGS_Q_YES;
2164 vdev->ioc_id = hd->ioc->id;
2165 vdev->target_id = device->id;
2166 vdev->bus_id = device->channel;
2167 vdev->raidVolume = 0;
2168 hd->Targets[device->id] = vdev;
2169 if (hd->ioc->bus_type == SCSI) {
2170 if (hd->ioc->spi_data.isRaid & (1 << device->id)) {
2171 vdev->raidVolume = 1;
2172 ddvtprintk((KERN_INFO
2173 "RAID Volume @ id %d\n", device->id));
2174 }
2175 } else {
2176 vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2177 }
2178
2179 out:
2180 vdev->num_luns++;
2181 return 0;
2182 }
2183
2184 static int
2185 mptscsih_is_raid_volume(MPT_SCSI_HOST *hd, uint id)
2186 {
2187 int i;
2188
2189 if (!hd->ioc->spi_data.isRaid || !hd->ioc->spi_data.pIocPg3)
2190 return 0;
2191
2192 for (i = 0; i < hd->ioc->spi_data.pIocPg3->NumPhysDisks; i++) {
2193 if (id == hd->ioc->spi_data.pIocPg3->PhysDisk[i].PhysDiskID)
2194 return 1;
2195 }
2196
2197 return 0;
2198 }
2199
2200 /*
2201 * OS entry point to allow for host driver to free allocated memory
2202 * Called if no device present or device being unloaded
2203 */
2204 void
2205 mptscsih_slave_destroy(struct scsi_device *device)
2206 {
2207 struct Scsi_Host *host = device->host;
2208 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata;
2209 VirtDevice *vdev;
2210 uint target = device->id;
2211 uint lun = device->lun;
2212
2213 if (hd == NULL)
2214 return;
2215
2216 mptscsih_search_running_cmds(hd, target, lun);
2217
2218 vdev = hd->Targets[target];
2219 vdev->luns[0] &= ~(1 << lun);
2220 if (--vdev->num_luns)
2221 return;
2222
2223 kfree(hd->Targets[target]);
2224 hd->Targets[target] = NULL;
2225
2226 if (hd->ioc->bus_type == SCSI) {
2227 if (mptscsih_is_raid_volume(hd, target)) {
2228 hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3;
2229 } else {
2230 hd->ioc->spi_data.dvStatus[target] =
2231 MPT_SCSICFG_NEGOTIATE;
2232
2233 if (!hd->negoNvram) {
2234 hd->ioc->spi_data.dvStatus[target] |=
2235 MPT_SCSICFG_DV_NOT_DONE;
2236 }
2237 }
2238 }
2239 }
2240
2241 static void
2242 mptscsih_set_queue_depth(struct scsi_device *device, MPT_SCSI_HOST *hd,
2243 VirtDevice *pTarget, int qdepth)
2244 {
2245 int max_depth;
2246 int tagged;
2247
2248 if (hd->ioc->bus_type == SCSI) {
2249 if (pTarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) {
2250 if (!(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2251 max_depth = 1;
2252 else if (((pTarget->inq_data[0] & 0x1f) == 0x00) &&
2253 (pTarget->minSyncFactor <= MPT_ULTRA160 ))
2254 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2255 else
2256 max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2257 } else {
2258 /* error case - No Inq. Data */
2259 max_depth = 1;
2260 }
2261 } else
2262 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2263
2264 if (qdepth > max_depth)
2265 qdepth = max_depth;
2266 if (qdepth == 1)
2267 tagged = 0;
2268 else
2269 tagged = MSG_SIMPLE_TAG;
2270
2271 scsi_adjust_queue_depth(device, tagged, qdepth);
2272 }
2273
2274
2275 /*
2276 * OS entry point to adjust the queue_depths on a per-device basis.
2277 * Called once per device the bus scan. Use it to force the queue_depth
2278 * member to 1 if a device does not support Q tags.
2279 * Return non-zero if fails.
2280 */
2281 int
2282 mptscsih_slave_configure(struct scsi_device *device)
2283 {
2284 struct Scsi_Host *sh = device->host;
2285 VirtDevice *pTarget;
2286 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata;
2287
2288 if ((hd == NULL) || (hd->Targets == NULL)) {
2289 return 0;
2290 }
2291
2292 dsprintk((MYIOC_s_INFO_FMT
2293 "device @ %p, id=%d, LUN=%d, channel=%d\n",
2294 hd->ioc->name, device, device->id, device->lun, device->channel));
2295 dsprintk((MYIOC_s_INFO_FMT
2296 "sdtr %d wdtr %d ppr %d inq length=%d\n",
2297 hd->ioc->name, device->sdtr, device->wdtr,
2298 device->ppr, device->inquiry_len));
2299
2300 if (device->id > sh->max_id) {
2301 /* error case, should never happen */
2302 scsi_adjust_queue_depth(device, 0, 1);
2303 goto slave_configure_exit;
2304 }
2305
2306 pTarget = hd->Targets[device->id];
2307
2308 if (pTarget == NULL) {
2309 /* Driver doesn't know about this device.
2310 * Kernel may generate a "Dummy Lun 0" which
2311 * may become a real Lun if a
2312 * "scsi add-single-device" command is executed
2313 * while the driver is active (hot-plug a
2314 * device). LSI Raid controllers need
2315 * queue_depth set to DEV_HIGH for this reason.
2316 */
2317 scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
2318 MPT_SCSI_CMD_PER_DEV_HIGH);
2319 goto slave_configure_exit;
2320 }
2321
2322 mptscsih_initTarget(hd, device->channel, device->id, device->lun,
2323 device->inquiry, device->inquiry_len );
2324 mptscsih_set_queue_depth(device, hd, pTarget, MPT_SCSI_CMD_PER_DEV_HIGH);
2325
2326 dsprintk((MYIOC_s_INFO_FMT
2327 "Queue depth=%d, tflags=%x\n",
2328 hd->ioc->name, device->queue_depth, pTarget->tflags));
2329
2330 dsprintk((MYIOC_s_INFO_FMT
2331 "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2332 hd->ioc->name, pTarget->negoFlags, pTarget->maxOffset, pTarget->minSyncFactor));
2333
2334 slave_configure_exit:
2335
2336 dsprintk((MYIOC_s_INFO_FMT
2337 "tagged %d, simple %d, ordered %d\n",
2338 hd->ioc->name,device->tagged_supported, device->simple_tags,
2339 device->ordered_tags));
2340
2341 return 0;
2342 }
2343
2344 ssize_t
2345 mptscsih_store_queue_depth(struct device *dev, const char *buf, size_t count)
2346 {
2347 int depth;
2348 struct scsi_device *sdev = to_scsi_device(dev);
2349 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) sdev->host->hostdata;
2350 VirtDevice *pTarget;
2351
2352 depth = simple_strtoul(buf, NULL, 0);
2353 if (depth == 0)
2354 return -EINVAL;
2355 pTarget = hd->Targets[sdev->id];
2356 if (pTarget == NULL)
2357 return -EINVAL;
2358 mptscsih_set_queue_depth(sdev, (MPT_SCSI_HOST *) sdev->host->hostdata,
2359 pTarget, depth);
2360 return count;
2361 }
2362
2363 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2364 /*
2365 * Private routines...
2366 */
2367
2368 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2369 /* Utility function to copy sense data from the scsi_cmnd buffer
2370 * to the FC and SCSI target structures.
2371 *
2372 */
2373 static void
2374 mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2375 {
2376 VirtDevice *target;
2377 SCSIIORequest_t *pReq;
2378 u32 sense_count = le32_to_cpu(pScsiReply->SenseCount);
2379 int index;
2380
2381 /* Get target structure
2382 */
2383 pReq = (SCSIIORequest_t *) mf;
2384 index = (int) pReq->TargetID;
2385 target = hd->Targets[index];
2386
2387 if (sense_count) {
2388 u8 *sense_data;
2389 int req_index;
2390
2391 /* Copy the sense received into the scsi command block. */
2392 req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2393 sense_data = ((u8 *)hd->ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2394 memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
2395
2396 /* Log SMART data (asc = 0x5D, non-IM case only) if required.
2397 */
2398 if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2399 if ((sense_data[12] == 0x5D) && (target->raidVolume == 0)) {
2400 int idx;
2401 MPT_ADAPTER *ioc = hd->ioc;
2402
2403 idx = ioc->eventContext % ioc->eventLogSize;
2404 ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2405 ioc->events[idx].eventContext = ioc->eventContext;
2406
2407 ioc->events[idx].data[0] = (pReq->LUN[1] << 24) ||
2408 (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) ||
2409 (pReq->Bus << 8) || pReq->TargetID;
2410
2411 ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12];
2412
2413 ioc->eventContext++;
2414 }
2415 }
2416 } else {
2417 dprintk((MYIOC_s_INFO_FMT "Hmmm... SenseData len=0! (?)\n",
2418 hd->ioc->name));
2419 }
2420 }
2421
2422 static u32
2423 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
2424 {
2425 MPT_SCSI_HOST *hd;
2426 int i;
2427
2428 hd = (MPT_SCSI_HOST *) sc->device->host->hostdata;
2429
2430 for (i = 0; i < hd->ioc->req_depth; i++) {
2431 if (hd->ScsiLookup[i] == sc) {
2432 return i;
2433 }
2434 }
2435
2436 return -1;
2437 }
2438
2439 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2440 int
2441 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2442 {
2443 MPT_SCSI_HOST *hd;
2444 unsigned long flags;
2445
2446 dtmprintk((KERN_WARNING MYNAM
2447 ": IOC %s_reset routed to SCSI host driver!\n",
2448 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
2449 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
2450
2451 /* If a FW reload request arrives after base installed but
2452 * before all scsi hosts have been attached, then an alt_ioc
2453 * may have a NULL sh pointer.
2454 */
2455 if ((ioc->sh == NULL) || (ioc->sh->hostdata == NULL))
2456 return 0;
2457 else
2458 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2459
2460 if (reset_phase == MPT_IOC_SETUP_RESET) {
2461 dtmprintk((MYIOC_s_WARN_FMT "Setup-Diag Reset\n", ioc->name));
2462
2463 /* Clean Up:
2464 * 1. Set Hard Reset Pending Flag
2465 * All new commands go to doneQ
2466 */
2467 hd->resetPending = 1;
2468
2469 } else if (reset_phase == MPT_IOC_PRE_RESET) {
2470 dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name));
2471
2472 /* 2. Flush running commands
2473 * Clean ScsiLookup (and associated memory)
2474 * AND clean mytaskQ
2475 */
2476
2477 /* 2b. Reply to OS all known outstanding I/O commands.
2478 */
2479 mptscsih_flush_running_cmds(hd);
2480
2481 /* 2c. If there was an internal command that
2482 * has not completed, configuration or io request,
2483 * free these resources.
2484 */
2485 if (hd->cmdPtr) {
2486 del_timer(&hd->timer);
2487 mpt_free_msg_frame(ioc, hd->cmdPtr);
2488 }
2489
2490 dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name));
2491
2492 } else {
2493 dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name));
2494
2495 /* Once a FW reload begins, all new OS commands are
2496 * redirected to the doneQ w/ a reset status.
2497 * Init all control structures.
2498 */
2499
2500 /* ScsiLookup initialization
2501 */
2502 {
2503 int ii;
2504 for (ii=0; ii < hd->ioc->req_depth; ii++)
2505 hd->ScsiLookup[ii] = NULL;
2506 }
2507
2508 /* 2. Chain Buffer initialization
2509 */
2510
2511 /* 4. Renegotiate to all devices, if SCSI
2512 */
2513 if (ioc->bus_type == SCSI) {
2514 dnegoprintk(("writeSDP1: ALL_IDS USE_NVRAM\n"));
2515 mptscsih_writeSDP1(hd, 0, 0, MPT_SCSICFG_ALL_IDS | MPT_SCSICFG_USE_NVRAM);
2516 }
2517
2518 /* 5. Enable new commands to be posted
2519 */
2520 spin_lock_irqsave(&ioc->FreeQlock, flags);
2521 hd->tmPending = 0;
2522 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2523 hd->resetPending = 0;
2524 hd->tmState = TM_STATE_NONE;
2525
2526 /* 6. If there was an internal command,
2527 * wake this process up.
2528 */
2529 if (hd->cmdPtr) {
2530 /*
2531 * Wake up the original calling thread
2532 */
2533 hd->pLocal = &hd->localReply;
2534 hd->pLocal->completion = MPT_SCANDV_DID_RESET;
2535 hd->scandv_wait_done = 1;
2536 wake_up(&hd->scandv_waitq);
2537 hd->cmdPtr = NULL;
2538 }
2539
2540 /* 7. Set flag to force DV and re-read IOC Page 3
2541 */
2542 if (ioc->bus_type == SCSI) {
2543 ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
2544 ddvtprintk(("Set reload IOC Pg3 Flag\n"));
2545 }
2546
2547 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
2548
2549 }
2550
2551 return 1; /* currently means nothing really */
2552 }
2553
2554 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2555 int
2556 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2557 {
2558 MPT_SCSI_HOST *hd;
2559 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2560
2561 devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
2562 ioc->name, event));
2563
2564 switch (event) {
2565 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
2566 /* FIXME! */
2567 break;
2568 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
2569 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
2570 hd = NULL;
2571 if (ioc->sh) {
2572 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2573 if (hd && (ioc->bus_type == SCSI) && (hd->soft_resets < -1))
2574 hd->soft_resets++;
2575 }
2576 break;
2577 case MPI_EVENT_LOGOUT: /* 09 */
2578 /* FIXME! */
2579 break;
2580
2581 /*
2582 * CHECKME! Don't think we need to do
2583 * anything for these, but...
2584 */
2585 case MPI_EVENT_RESCAN: /* 06 */
2586 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
2587 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
2588 /*
2589 * CHECKME! Falling thru...
2590 */
2591 break;
2592
2593 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
2594 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
2595 /* negoNvram set to 0 if DV enabled and to USE_NVRAM if
2596 * if DV disabled. Need to check for target mode.
2597 */
2598 hd = NULL;
2599 if (ioc->sh)
2600 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
2601
2602 if (hd && (ioc->bus_type == SCSI) && (hd->negoNvram == 0)) {
2603 ScsiCfgData *pSpi;
2604 Ioc3PhysDisk_t *pPDisk;
2605 int numPDisk;
2606 u8 reason;
2607 u8 physDiskNum;
2608
2609 reason = (le32_to_cpu(pEvReply->Data[0]) & 0x00FF0000) >> 16;
2610 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
2611 /* New or replaced disk.
2612 * Set DV flag and schedule DV.
2613 */
2614 pSpi = &ioc->spi_data;
2615 physDiskNum = (le32_to_cpu(pEvReply->Data[0]) & 0xFF000000) >> 24;
2616 ddvtprintk(("DV requested for phys disk id %d\n", physDiskNum));
2617 if (pSpi->pIocPg3) {
2618 pPDisk = pSpi->pIocPg3->PhysDisk;
2619 numPDisk =pSpi->pIocPg3->NumPhysDisks;
2620
2621 while (numPDisk) {
2622 if (physDiskNum == pPDisk->PhysDiskNum) {
2623 pSpi->dvStatus[pPDisk->PhysDiskID] = (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE);
2624 pSpi->forceDv = MPT_SCSICFG_NEED_DV;
2625 ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
2626 break;
2627 }
2628 pPDisk++;
2629 numPDisk--;
2630 }
2631
2632 if (numPDisk == 0) {
2633 /* The physical disk that needs DV was not found
2634 * in the stored IOC Page 3. The driver must reload
2635 * this page. DV routine will set the NEED_DV flag for
2636 * all phys disks that have DV_NOT_DONE set.
2637 */
2638 pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
2639 ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n", physDiskNum));
2640 }
2641 }
2642 }
2643 }
2644 #endif
2645
2646 #if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY)
2647 printk("Raid Event RF: ");
2648 {
2649 u32 *m = (u32 *)pEvReply;
2650 int ii;
2651 int n = (int)pEvReply->MsgLength;
2652 for (ii=6; ii < n; ii++)
2653 printk(" %08x", le32_to_cpu(m[ii]));
2654 printk("\n");
2655 }
2656 #endif
2657 break;
2658
2659 case MPI_EVENT_NONE: /* 00 */
2660 case MPI_EVENT_LOG_DATA: /* 01 */
2661 case MPI_EVENT_STATE_CHANGE: /* 02 */
2662 case MPI_EVENT_EVENT_CHANGE: /* 0A */
2663 default:
2664 dprintk((KERN_INFO " Ignoring event (=%02Xh)\n", event));
2665 break;
2666 }
2667
2668 return 1; /* currently means nothing really */
2669 }
2670
2671 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2672 /*
2673 * mptscsih_initTarget - Target, LUN alloc/free functionality.
2674 * @hd: Pointer to MPT_SCSI_HOST structure
2675 * @bus_id: Bus number (?)
2676 * @target_id: SCSI target id
2677 * @lun: SCSI LUN id
2678 * @data: Pointer to data
2679 * @dlen: Number of INQUIRY bytes
2680 *
2681 * NOTE: It's only SAFE to call this routine if data points to
2682 * sane & valid STANDARD INQUIRY data!
2683 *
2684 * Allocate and initialize memory for this target.
2685 * Save inquiry data.
2686 *
2687 */
2688 static void
2689 mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen)
2690 {
2691 int indexed_lun, lun_index;
2692 VirtDevice *vdev;
2693 ScsiCfgData *pSpi;
2694 char data_56;
2695
2696 dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n",
2697 hd->ioc->name, bus_id, target_id, lun, hd));
2698
2699 /*
2700 * If the peripheral qualifier filter is enabled then if the target reports a 0x1
2701 * (i.e. The targer is capable of supporting the specified peripheral device type
2702 * on this logical unit; however, the physical device is not currently connected
2703 * to this logical unit) it will be converted to a 0x3 (i.e. The target is not
2704 * capable of supporting a physical device on this logical unit). This is to work
2705 * around a bug in th emid-layer in some distributions in which the mid-layer will
2706 * continue to try to communicate to the LUN and evntually create a dummy LUN.
2707 */
2708 if (hd->mpt_pq_filter && dlen && (data[0] & 0xE0))
2709 data[0] |= 0x40;
2710
2711 /* Is LUN supported? If so, upper 2 bits will be 0
2712 * in first byte of inquiry data.
2713 */
2714 if (data[0] & 0xe0)
2715 return;
2716
2717 if ((vdev = hd->Targets[target_id]) == NULL) {
2718 return;
2719 }
2720
2721 lun_index = (lun >> 5); /* 32 luns per lun_index */
2722 indexed_lun = (lun % 32);
2723 vdev->luns[lun_index] |= (1 << indexed_lun);
2724
2725 if (hd->ioc->bus_type == SCSI) {
2726 if ((data[0] == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) {
2727 /* Treat all Processors as SAF-TE if
2728 * command line option is set */
2729 vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2730 mptscsih_writeIOCPage4(hd, target_id, bus_id);
2731 }else if ((data[0] == TYPE_PROCESSOR) &&
2732 !(vdev->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) {
2733 if ( dlen > 49 ) {
2734 vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2735 if ( data[44] == 'S' &&
2736 data[45] == 'A' &&
2737 data[46] == 'F' &&
2738 data[47] == '-' &&
2739 data[48] == 'T' &&
2740 data[49] == 'E' ) {
2741 vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED;
2742 mptscsih_writeIOCPage4(hd, target_id, bus_id);
2743 }
2744 }
2745 }
2746 if (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) {
2747 if ( dlen > 8 ) {
2748 memcpy (vdev->inq_data, data, 8);
2749 } else {
2750 memcpy (vdev->inq_data, data, dlen);
2751 }
2752
2753 /* If have not done DV, set the DV flag.
2754 */
2755 pSpi = &hd->ioc->spi_data;
2756 if ((data[0] == TYPE_TAPE) || (data[0] == TYPE_PROCESSOR)) {
2757 if (pSpi->dvStatus[target_id] & MPT_SCSICFG_DV_NOT_DONE)
2758 pSpi->dvStatus[target_id] |= MPT_SCSICFG_NEED_DV;
2759 }
2760
2761 vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY;
2762
2763
2764 data_56 = 0x0F; /* Default to full capabilities if Inq data length is < 57 */
2765 if (dlen > 56) {
2766 if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
2767 /* Update the target capabilities
2768 */
2769 data_56 = data[56];
2770 vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
2771 }
2772 }
2773 mptscsih_setTargetNegoParms(hd, vdev, data_56);
2774 } else {
2775 /* Initial Inquiry may not request enough data bytes to
2776 * obtain byte 57. DV will; if target doesn't return
2777 * at least 57 bytes, data[56] will be zero. */
2778 if (dlen > 56) {
2779 if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) {
2780 /* Update the target capabilities
2781 */
2782 data_56 = data[56];
2783 vdev->tflags |= MPT_TARGET_FLAGS_VALID_56;
2784 mptscsih_setTargetNegoParms(hd, vdev, data_56);
2785 }
2786 }
2787 }
2788 }
2789 }
2790
2791 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2792 /*
2793 * Update the target negotiation parameters based on the
2794 * the Inquiry data, adapter capabilities, and NVRAM settings.
2795 *
2796 */
2797 static void
2798 mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56)
2799 {
2800 ScsiCfgData *pspi_data = &hd->ioc->spi_data;
2801 int id = (int) target->target_id;
2802 int nvram;
2803 VirtDevice *vdev;
2804 int ii;
2805 u8 width = MPT_NARROW;
2806 u8 factor = MPT_ASYNC;
2807 u8 offset = 0;
2808 u8 version, nfactor;
2809 u8 noQas = 1;
2810
2811 target->negoFlags = pspi_data->noQas;
2812
2813 /* noQas == 0 => device supports QAS. Need byte 56 of Inq to determine
2814 * support. If available, default QAS to off and allow enabling.
2815 * If not available, default QAS to on, turn off for non-disks.
2816 */
2817
2818 /* Set flags based on Inquiry data
2819 */
2820 version = target->inq_data[2] & 0x07;
2821 if (version < 2) {
2822 width = 0;
2823 factor = MPT_ULTRA2;
2824 offset = pspi_data->maxSyncOffset;
2825 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2826 } else {
2827 if (target->inq_data[7] & 0x20) {
2828 width = 1;
2829 }
2830
2831 if (target->inq_data[7] & 0x10) {
2832 factor = pspi_data->minSyncFactor;
2833 if (target->tflags & MPT_TARGET_FLAGS_VALID_56) {
2834 /* bits 2 & 3 show Clocking support */
2835 if ((byte56 & 0x0C) == 0)
2836 factor = MPT_ULTRA2;
2837 else {
2838 if ((byte56 & 0x03) == 0)
2839 factor = MPT_ULTRA160;
2840 else {
2841 factor = MPT_ULTRA320;
2842 if (byte56 & 0x02)
2843 {
2844 ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", byte56, id));
2845 noQas = 0;
2846 }
2847 if (target->inq_data[0] == TYPE_TAPE) {
2848 if (byte56 & 0x01)
2849 target->negoFlags |= MPT_TAPE_NEGO_IDP;
2850 }
2851 }
2852 }
2853 } else {
2854 ddvtprintk((KERN_INFO "Enabling QAS on id=%d due to ~TARGET_FLAGS_VALID_56!\n", id));
2855 noQas = 0;
2856 }
2857
2858 offset = pspi_data->maxSyncOffset;
2859
2860 /* If RAID, never disable QAS
2861 * else if non RAID, do not disable
2862 * QAS if bit 1 is set
2863 * bit 1 QAS support, non-raid only
2864 * bit 0 IU support
2865 */
2866 if (target->raidVolume == 1) {
2867 noQas = 0;
2868 }
2869 } else {
2870 factor = MPT_ASYNC;
2871 offset = 0;
2872 }
2873 }
2874
2875 if ( (target->inq_data[7] & 0x02) == 0) {
2876 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES;
2877 }
2878
2879 /* Update tflags based on NVRAM settings. (SCSI only)
2880 */
2881 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
2882 nvram = pspi_data->nvram[id];
2883 nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
2884
2885 if (width)
2886 width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
2887
2888 if (offset > 0) {
2889 /* Ensure factor is set to the
2890 * maximum of: adapter, nvram, inquiry
2891 */
2892 if (nfactor) {
2893 if (nfactor < pspi_data->minSyncFactor )
2894 nfactor = pspi_data->minSyncFactor;
2895
2896 factor = max(factor, nfactor);
2897 if (factor == MPT_ASYNC)
2898 offset = 0;
2899 } else {
2900 offset = 0;
2901 factor = MPT_ASYNC;
2902 }
2903 } else {
2904 factor = MPT_ASYNC;
2905 }
2906 }
2907
2908 /* Make sure data is consistent
2909 */
2910 if ((!width) && (factor < MPT_ULTRA2)) {
2911 factor = MPT_ULTRA2;
2912 }
2913
2914 /* Save the data to the target structure.
2915 */
2916 target->minSyncFactor = factor;
2917 target->maxOffset = offset;
2918 target->maxWidth = width;
2919
2920 target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO;
2921
2922 /* Disable unused features.
2923 */
2924 if (!width)
2925 target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
2926
2927 if (!offset)
2928 target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
2929
2930 if ( factor > MPT_ULTRA320 )
2931 noQas = 0;
2932
2933 /* GEM, processor WORKAROUND
2934 */
2935 if ((target->inq_data[0] == TYPE_PROCESSOR) || (target->inq_data[0] > 0x08)) {
2936 target->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC);
2937 pspi_data->dvStatus[id] |= MPT_SCSICFG_BLK_NEGO;
2938 } else {
2939 if (noQas && (pspi_data->noQas == 0)) {
2940 pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS;
2941 target->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
2942
2943 /* Disable QAS in a mixed configuration case
2944 */
2945
2946 ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id));
2947 for (ii = 0; ii < id; ii++) {
2948 if ( (vdev = hd->Targets[ii]) ) {
2949 vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
2950 mptscsih_writeSDP1(hd, 0, ii, vdev->negoFlags);
2951 }
2952 }
2953 }
2954 }
2955
2956 /* Write SDP1 on this I/O to this target */
2957 if (pspi_data->dvStatus[id] & MPT_SCSICFG_NEGOTIATE) {
2958 ddvtprintk((KERN_INFO "MPT_SCSICFG_NEGOTIATE on id=%d!\n", id));
2959 mptscsih_writeSDP1(hd, 0, id, hd->negoNvram);
2960 pspi_data->dvStatus[id] &= ~MPT_SCSICFG_NEGOTIATE;
2961 } else if (pspi_data->dvStatus[id] & MPT_SCSICFG_BLK_NEGO) {
2962 ddvtprintk((KERN_INFO "MPT_SCSICFG_BLK_NEGO on id=%d!\n", id));
2963 mptscsih_writeSDP1(hd, 0, id, MPT_SCSICFG_BLK_NEGO);
2964 pspi_data->dvStatus[id] &= ~MPT_SCSICFG_BLK_NEGO;
2965 }
2966 }
2967
2968 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2969 /* If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return.
2970 * Else set the NEED_DV flag after Read Capacity Issued (disks)
2971 * or Mode Sense (cdroms).
2972 *
2973 * Tapes, initTarget will set this flag on completion of Inquiry command.
2974 * Called only if DV_NOT_DONE flag is set
2975 */
2976 static void
2977 mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq)
2978 {
2979 u8 cmd;
2980 ScsiCfgData *pSpi;
2981
2982 ddvtprintk((" set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n",
2983 pReq->TargetID, pReq->LUN[1], hd->negoNvram, pReq->CDB[0]));
2984
2985 if ((pReq->LUN[1] != 0) || (hd->negoNvram != 0))
2986 return;
2987
2988 cmd = pReq->CDB[0];
2989
2990 if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) {
2991 pSpi = &hd->ioc->spi_data;
2992 if ((pSpi->isRaid & (1 << pReq->TargetID)) && pSpi->pIocPg3) {
2993 /* Set NEED_DV for all hidden disks
2994 */
2995 Ioc3PhysDisk_t *pPDisk = pSpi->pIocPg3->PhysDisk;
2996 int numPDisk = pSpi->pIocPg3->NumPhysDisks;
2997
2998 while (numPDisk) {
2999 pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
3000 ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID));
3001 pPDisk++;
3002 numPDisk--;
3003 }
3004 }
3005 pSpi->dvStatus[pReq->TargetID] |= MPT_SCSICFG_NEED_DV;
3006 ddvtprintk(("NEED_DV set for visible disk id %d\n", pReq->TargetID));
3007 }
3008 }
3009
3010 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3011 /*
3012 * If no Target, bus reset on 1st I/O. Set the flag to
3013 * prevent any future negotiations to this device.
3014 */
3015 static void
3016 mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id)
3017 {
3018
3019 if ((hd->Targets) && (hd->Targets[target_id] == NULL))
3020 hd->ioc->spi_data.dvStatus[target_id] |= MPT_SCSICFG_BLK_NEGO;
3021
3022 return;
3023 }
3024
3025 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3026 /*
3027 * SCSI Config Page functionality ...
3028 */
3029 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3030 /* mptscsih_setDevicePage1Flags - add Requested and Configuration fields flags
3031 * based on width, factor and offset parameters.
3032 * @width: bus width
3033 * @factor: sync factor
3034 * @offset: sync offset
3035 * @requestedPtr: pointer to requested values (updated)
3036 * @configurationPtr: pointer to configuration values (updated)
3037 * @flags: flags to block WDTR or SDTR negotiation
3038 *
3039 * Return: None.
3040 *
3041 * Remark: Called by writeSDP1 and _dv_params
3042 */
3043 static void
3044 mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags)
3045 {
3046 u8 nowide = flags & MPT_TARGET_NO_NEGO_WIDE;
3047 u8 nosync = flags & MPT_TARGET_NO_NEGO_SYNC;
3048
3049 *configurationPtr = 0;
3050 *requestedPtr = width ? MPI_SCSIDEVPAGE1_RP_WIDE : 0;
3051 *requestedPtr |= (offset << 16) | (factor << 8);
3052
3053 if (width && offset && !nowide && !nosync) {
3054 if (factor < MPT_ULTRA160) {
3055 *requestedPtr |= (MPI_SCSIDEVPAGE1_RP_IU + MPI_SCSIDEVPAGE1_RP_DT);
3056 if ((flags & MPT_TARGET_NO_NEGO_QAS) == 0)
3057 *requestedPtr |= MPI_SCSIDEVPAGE1_RP_QAS;
3058 if (flags & MPT_TAPE_NEGO_IDP)
3059 *requestedPtr |= 0x08000000;
3060 } else if (factor < MPT_ULTRA2) {
3061 *requestedPtr |= MPI_SCSIDEVPAGE1_RP_DT;
3062 }
3063 }
3064
3065 if (nowide)
3066 *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_WDTR_DISALLOWED;
3067
3068 if (nosync)
3069 *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_SDTR_DISALLOWED;
3070
3071 return;
3072 }
3073
3074 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3075 /* mptscsih_writeSDP1 - write SCSI Device Page 1
3076 * @hd: Pointer to a SCSI Host Strucutre
3077 * @portnum: IOC port number
3078 * @target_id: writeSDP1 for single ID
3079 * @flags: MPT_SCSICFG_ALL_IDS, MPT_SCSICFG_USE_NVRAM, MPT_SCSICFG_BLK_NEGO
3080 *
3081 * Return: -EFAULT if read of config page header fails
3082 * or 0 if success.
3083 *
3084 * Remark: If a target has been found, the settings from the
3085 * target structure are used, else the device is set
3086 * to async/narrow.
3087 *
3088 * Remark: Called during init and after a FW reload.
3089 * Remark: We do not wait for a return, write pages sequentially.
3090 */
3091 static int
3092 mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags)
3093 {
3094 MPT_ADAPTER *ioc = hd->ioc;
3095 Config_t *pReq;
3096 SCSIDevicePage1_t *pData;
3097 VirtDevice *pTarget;
3098 MPT_FRAME_HDR *mf;
3099 dma_addr_t dataDma;
3100 u16 req_idx;
3101 u32 frameOffset;
3102 u32 requested, configuration, flagsLength;
3103 int ii, nvram;
3104 int id = 0, maxid = 0;
3105 u8 width;
3106 u8 factor;
3107 u8 offset;
3108 u8 bus = 0;
3109 u8 negoFlags;
3110 u8 maxwidth, maxoffset, maxfactor;
3111
3112 if (ioc->spi_data.sdp1length == 0)
3113 return 0;
3114
3115 if (flags & MPT_SCSICFG_ALL_IDS) {
3116 id = 0;
3117 maxid = ioc->sh->max_id - 1;
3118 } else if (ioc->sh) {
3119 id = target_id;
3120 maxid = min_t(int, id, ioc->sh->max_id - 1);
3121 }
3122
3123 for (; id <= maxid; id++) {
3124
3125 if (id == ioc->pfacts[portnum].PortSCSIID)
3126 continue;
3127
3128 /* Use NVRAM to get adapter and target maximums
3129 * Data over-riden by target structure information, if present
3130 */
3131 maxwidth = ioc->spi_data.maxBusWidth;
3132 maxoffset = ioc->spi_data.maxSyncOffset;
3133 maxfactor = ioc->spi_data.minSyncFactor;
3134 if (ioc->spi_data.nvram && (ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
3135 nvram = ioc->spi_data.nvram[id];
3136
3137 if (maxwidth)
3138 maxwidth = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
3139
3140 if (maxoffset > 0) {
3141 maxfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8;
3142 if (maxfactor == 0) {
3143 /* Key for async */
3144 maxfactor = MPT_ASYNC;
3145 maxoffset = 0;
3146 } else if (maxfactor < ioc->spi_data.minSyncFactor) {
3147 maxfactor = ioc->spi_data.minSyncFactor;
3148 }
3149 } else
3150 maxfactor = MPT_ASYNC;
3151 }
3152
3153 /* Set the negotiation flags.
3154 */
3155 negoFlags = ioc->spi_data.noQas;
3156 if (!maxwidth)
3157 negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
3158
3159 if (!maxoffset)
3160 negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
3161
3162 if (flags & MPT_SCSICFG_USE_NVRAM) {
3163 width = maxwidth;
3164 factor = maxfactor;
3165 offset = maxoffset;
3166 } else {
3167 width = 0;
3168 factor = MPT_ASYNC;
3169 offset = 0;
3170 //negoFlags = 0;
3171 //negoFlags = MPT_TARGET_NO_NEGO_SYNC;
3172 }
3173
3174 /* If id is not a raid volume, get the updated
3175 * transmission settings from the target structure.
3176 */
3177 if (hd->Targets && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
3178 width = pTarget->maxWidth;
3179 factor = pTarget->minSyncFactor;
3180 offset = pTarget->maxOffset;
3181 negoFlags = pTarget->negoFlags;
3182 }
3183
3184 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3185 /* Force to async and narrow if DV has not been executed
3186 * for this ID
3187 */
3188 if ((hd->ioc->spi_data.dvStatus[id] & MPT_SCSICFG_DV_NOT_DONE) != 0) {
3189 width = 0;
3190 factor = MPT_ASYNC;
3191 offset = 0;
3192 }
3193 #endif
3194
3195 if (flags & MPT_SCSICFG_BLK_NEGO)
3196 negoFlags = MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC;
3197
3198 mptscsih_setDevicePage1Flags(width, factor, offset,
3199 &requested, &configuration, negoFlags);
3200 dnegoprintk(("writeSDP1: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
3201 target_id, width, factor, offset, negoFlags, requested, configuration));
3202
3203 /* Get a MF for this command.
3204 */
3205 if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
3206 dprintk((MYIOC_s_WARN_FMT "write SDP1: no msg frames!\n",
3207 ioc->name));
3208 return -EAGAIN;
3209 }
3210
3211 ddvprintk((MYIOC_s_INFO_FMT "WriteSDP1 (mf=%p, id=%d, req=0x%x, cfg=0x%x)\n",
3212 hd->ioc->name, mf, id, requested, configuration));
3213
3214
3215 /* Set the request and the data pointers.
3216 * Request takes: 36 bytes (32 bit SGE)
3217 * SCSI Device Page 1 requires 16 bytes
3218 * 40 + 16 <= size of SCSI IO Request = 56 bytes
3219 * and MF size >= 64 bytes.
3220 * Place data at end of MF.
3221 */
3222 pReq = (Config_t *)mf;
3223
3224 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3225 frameOffset = ioc->req_sz - sizeof(SCSIDevicePage1_t);
3226
3227 pData = (SCSIDevicePage1_t *)((u8 *) mf + frameOffset);
3228 dataDma = ioc->req_frames_dma + (req_idx * ioc->req_sz) + frameOffset;
3229
3230 /* Complete the request frame (same for all requests).
3231 */
3232 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3233 pReq->Reserved = 0;
3234 pReq->ChainOffset = 0;
3235 pReq->Function = MPI_FUNCTION_CONFIG;
3236 pReq->ExtPageLength = 0;
3237 pReq->ExtPageType = 0;
3238 pReq->MsgFlags = 0;
3239 for (ii=0; ii < 8; ii++) {
3240 pReq->Reserved2[ii] = 0;
3241 }
3242 pReq->Header.PageVersion = ioc->spi_data.sdp1version;
3243 pReq->Header.PageLength = ioc->spi_data.sdp1length;
3244 pReq->Header.PageNumber = 1;
3245 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
3246 pReq->PageAddress = cpu_to_le32(id | (bus << 8 ));
3247
3248 /* Add a SGE to the config request.
3249 */
3250 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE | ioc->spi_data.sdp1length * 4;
3251
3252 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
3253
3254 /* Set up the common data portion
3255 */
3256 pData->Header.PageVersion = pReq->Header.PageVersion;
3257 pData->Header.PageLength = pReq->Header.PageLength;
3258 pData->Header.PageNumber = pReq->Header.PageNumber;
3259 pData->Header.PageType = pReq->Header.PageType;
3260 pData->RequestedParameters = cpu_to_le32(requested);
3261 pData->Reserved = 0;
3262 pData->Configuration = cpu_to_le32(configuration);
3263
3264 dprintk((MYIOC_s_INFO_FMT
3265 "write SDP1: id %d pgaddr 0x%x req 0x%x config 0x%x\n",
3266 ioc->name, id, (id | (bus<<8)),
3267 requested, configuration));
3268
3269 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
3270 }
3271
3272 return 0;
3273 }
3274
3275 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3276 /* mptscsih_writeIOCPage4 - write IOC Page 4
3277 * @hd: Pointer to a SCSI Host Structure
3278 * @target_id: write IOC Page4 for this ID & Bus
3279 *
3280 * Return: -EAGAIN if unable to obtain a Message Frame
3281 * or 0 if success.
3282 *
3283 * Remark: We do not wait for a return, write pages sequentially.
3284 */
3285 static int
3286 mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
3287 {
3288 MPT_ADAPTER *ioc = hd->ioc;
3289 Config_t *pReq;
3290 IOCPage4_t *IOCPage4Ptr;
3291 MPT_FRAME_HDR *mf;
3292 dma_addr_t dataDma;
3293 u16 req_idx;
3294 u32 frameOffset;
3295 u32 flagsLength;
3296 int ii;
3297
3298 /* Get a MF for this command.
3299 */
3300 if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
3301 dprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n",
3302 ioc->name));
3303 return -EAGAIN;
3304 }
3305
3306 /* Set the request and the data pointers.
3307 * Place data at end of MF.
3308 */
3309 pReq = (Config_t *)mf;
3310
3311 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3312 frameOffset = ioc->req_sz - sizeof(IOCPage4_t);
3313
3314 /* Complete the request frame (same for all requests).
3315 */
3316 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3317 pReq->Reserved = 0;
3318 pReq->ChainOffset = 0;
3319 pReq->Function = MPI_FUNCTION_CONFIG;
3320 pReq->ExtPageLength = 0;
3321 pReq->ExtPageType = 0;
3322 pReq->MsgFlags = 0;
3323 for (ii=0; ii < 8; ii++) {
3324 pReq->Reserved2[ii] = 0;
3325 }
3326
3327 IOCPage4Ptr = ioc->spi_data.pIocPg4;
3328 dataDma = ioc->spi_data.IocPg4_dma;
3329 ii = IOCPage4Ptr->ActiveSEP++;
3330 IOCPage4Ptr->SEP[ii].SEPTargetID = target_id;
3331 IOCPage4Ptr->SEP[ii].SEPBus = bus;
3332 pReq->Header = IOCPage4Ptr->Header;
3333 pReq->PageAddress = cpu_to_le32(target_id | (bus << 8 ));
3334
3335 /* Add a SGE to the config request.
3336 */
3337 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE |
3338 (IOCPage4Ptr->Header.PageLength + ii) * 4;
3339
3340 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma);
3341
3342 dinitprintk((MYIOC_s_INFO_FMT
3343 "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n",
3344 ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, target_id, bus));
3345
3346 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
3347
3348 return 0;
3349 }
3350
3351 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3352 /*
3353 * Bus Scan and Domain Validation functionality ...
3354 */
3355
3356 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3357 /*
3358 * mptscsih_scandv_complete - Scan and DV callback routine registered
3359 * to Fustion MPT (base) driver.
3360 *
3361 * @ioc: Pointer to MPT_ADAPTER structure
3362 * @mf: Pointer to original MPT request frame
3363 * @mr: Pointer to MPT reply frame (NULL if TurboReply)
3364 *
3365 * This routine is called from mpt.c::mpt_interrupt() at the completion
3366 * of any SCSI IO request.
3367 * This routine is registered with the Fusion MPT (base) driver at driver
3368 * load/init time via the mpt_register() API call.
3369 *
3370 * Returns 1 indicating alloc'd request frame ptr should be freed.
3371 *
3372 * Remark: Sets a completion code and (possibly) saves sense data
3373 * in the IOC member localReply structure.
3374 * Used ONLY for DV and other internal commands.
3375 */
3376 int
3377 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
3378 {
3379 MPT_SCSI_HOST *hd;
3380 SCSIIORequest_t *pReq;
3381 int completionCode;
3382 u16 req_idx;
3383
3384 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
3385
3386 if ((mf == NULL) ||
3387 (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
3388 printk(MYIOC_s_ERR_FMT
3389 "ScanDvComplete, %s req frame ptr! (=%p)\n",
3390 ioc->name, mf?"BAD":"NULL", (void *) mf);
3391 goto wakeup;
3392 }
3393
3394 del_timer(&hd->timer);
3395 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3396 hd->ScsiLookup[req_idx] = NULL;
3397 pReq = (SCSIIORequest_t *) mf;
3398
3399 if (mf != hd->cmdPtr) {
3400 printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
3401 hd->ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx);
3402 }
3403 hd->cmdPtr = NULL;
3404
3405 ddvprintk((MYIOC_s_INFO_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
3406 hd->ioc->name, mf, mr, req_idx));
3407
3408 hd->pLocal = &hd->localReply;
3409 hd->pLocal->scsiStatus = 0;
3410
3411 /* If target struct exists, clear sense valid flag.
3412 */
3413 if (mr == NULL) {
3414 completionCode = MPT_SCANDV_GOOD;
3415 } else {
3416 SCSIIOReply_t *pReply;
3417 u16 status;
3418 u8 scsi_status;
3419
3420 pReply = (SCSIIOReply_t *) mr;
3421
3422 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
3423 scsi_status = pReply->SCSIStatus;
3424
3425 ddvtprintk((KERN_NOTICE " IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh, IOCLogInfo=%08xh\n",
3426 status, pReply->SCSIState, scsi_status,
3427 le32_to_cpu(pReply->IOCLogInfo)));
3428
3429 switch(status) {
3430
3431 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
3432 completionCode = MPT_SCANDV_SELECTION_TIMEOUT;
3433 break;
3434
3435 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
3436 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
3437 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
3438 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
3439 completionCode = MPT_SCANDV_DID_RESET;
3440 break;
3441
3442 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
3443 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
3444 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
3445 if (pReply->Function == MPI_FUNCTION_CONFIG) {
3446 ConfigReply_t *pr = (ConfigReply_t *)mr;
3447 completionCode = MPT_SCANDV_GOOD;
3448 hd->pLocal->header.PageVersion = pr->Header.PageVersion;
3449 hd->pLocal->header.PageLength = pr->Header.PageLength;
3450 hd->pLocal->header.PageNumber = pr->Header.PageNumber;
3451 hd->pLocal->header.PageType = pr->Header.PageType;
3452
3453 } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
3454 /* If the RAID Volume request is successful,
3455 * return GOOD, else indicate that
3456 * some type of error occurred.
3457 */
3458 MpiRaidActionReply_t *pr = (MpiRaidActionReply_t *)mr;
3459 if (pr->ActionStatus == MPI_RAID_ACTION_ASTATUS_SUCCESS)
3460 completionCode = MPT_SCANDV_GOOD;
3461 else
3462 completionCode = MPT_SCANDV_SOME_ERROR;
3463
3464 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
3465 u8 *sense_data;
3466 int sz;
3467
3468 /* save sense data in global structure
3469 */
3470 completionCode = MPT_SCANDV_SENSE;
3471 hd->pLocal->scsiStatus = scsi_status;
3472 sense_data = ((u8 *)hd->ioc->sense_buf_pool +
3473 (req_idx * MPT_SENSE_BUFFER_ALLOC));
3474
3475 sz = min_t(int, pReq->SenseBufferLength,
3476 SCSI_STD_SENSE_BYTES);
3477 memcpy(hd->pLocal->sense, sense_data, sz);
3478
3479 ddvprintk((KERN_NOTICE " Check Condition, sense ptr %p\n",
3480 sense_data));
3481 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
3482 if (pReq->CDB[0] == INQUIRY)
3483 completionCode = MPT_SCANDV_ISSUE_SENSE;
3484 else
3485 completionCode = MPT_SCANDV_DID_RESET;
3486 }
3487 else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
3488 completionCode = MPT_SCANDV_DID_RESET;
3489 else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3490 completionCode = MPT_SCANDV_DID_RESET;
3491 else {
3492 completionCode = MPT_SCANDV_GOOD;
3493 hd->pLocal->scsiStatus = scsi_status;
3494 }
3495 break;
3496
3497 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
3498 if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
3499 completionCode = MPT_SCANDV_DID_RESET;
3500 else
3501 completionCode = MPT_SCANDV_SOME_ERROR;
3502 break;
3503
3504 default:
3505 completionCode = MPT_SCANDV_SOME_ERROR;
3506 break;
3507
3508 } /* switch(status) */
3509
3510 ddvtprintk((KERN_NOTICE " completionCode set to %08xh\n",
3511 completionCode));
3512 } /* end of address reply case */
3513
3514 hd->pLocal->completion = completionCode;
3515
3516 /* MF and RF are freed in mpt_interrupt
3517 */
3518 wakeup:
3519 /* Free Chain buffers (will never chain) in scan or dv */
3520 //mptscsih_freeChainBuffers(ioc, req_idx);
3521
3522 /*
3523 * Wake up the original calling thread
3524 */
3525 hd->scandv_wait_done = 1;
3526 wake_up(&hd->scandv_waitq);
3527
3528 return 1;
3529 }
3530
3531 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3532 /* mptscsih_timer_expired - Call back for timer process.
3533 * Used only for dv functionality.
3534 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
3535 *
3536 */
3537 void
3538 mptscsih_timer_expired(unsigned long data)
3539 {
3540 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
3541
3542 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired! Cmd %p\n", hd->ioc->name, hd->cmdPtr));
3543
3544 if (hd->cmdPtr) {
3545 MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr;
3546
3547 if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
3548 /* Desire to issue a task management request here.
3549 * TM requests MUST be single threaded.
3550 * If old eh code and no TM current, issue request.
3551 * If new eh code, do nothing. Wait for OS cmd timeout
3552 * for bus reset.
3553 */
3554 ddvtprintk((MYIOC_s_NOTE_FMT "DV Cmd Timeout: NoOp\n", hd->ioc->name));
3555 } else {
3556 /* Perform a FW reload */
3557 if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0) {
3558 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", hd->ioc->name);
3559 }
3560 }
3561 } else {
3562 /* This should NEVER happen */
3563 printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", hd->ioc->name);
3564 }
3565
3566 /* No more processing.
3567 * TM call will generate an interrupt for SCSI TM Management.
3568 * The FW will reply to all outstanding commands, callback will finish cleanup.
3569 * Hard reset clean-up will free all resources.
3570 */
3571 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired Complete!\n", hd->ioc->name));
3572
3573 return;
3574 }
3575
3576 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
3577 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3578 /* mptscsih_do_raid - Format and Issue a RAID volume request message.
3579 * @hd: Pointer to scsi host structure
3580 * @action: What do be done.
3581 * @id: Logical target id.
3582 * @bus: Target locations bus.
3583 *
3584 * Returns: < 0 on a fatal error
3585 * 0 on success
3586 *
3587 * Remark: Wait to return until reply processed by the ISR.
3588 */
3589 static int
3590 mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io)
3591 {
3592 MpiRaidActionRequest_t *pReq;
3593 MPT_FRAME_HDR *mf;
3594 int in_isr;
3595
3596 in_isr = in_interrupt();
3597 if (in_isr) {
3598 dprintk((MYIOC_s_WARN_FMT "Internal raid request not allowed in ISR context!\n",
3599 hd->ioc->name));
3600 return -EPERM;
3601 }
3602
3603 /* Get and Populate a free Frame
3604 */
3605 if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
3606 ddvprintk((MYIOC_s_WARN_FMT "_do_raid: no msg frames!\n",
3607 hd->ioc->name));
3608 return -EAGAIN;
3609 }
3610 pReq = (MpiRaidActionRequest_t *)mf;
3611 pReq->Action = action;
3612 pReq->Reserved1 = 0;
3613 pReq->ChainOffset = 0;
3614 pReq->Function = MPI_FUNCTION_RAID_ACTION;
3615 pReq->VolumeID = io->id;
3616 pReq->VolumeBus = io->bus;
3617 pReq->PhysDiskNum = io->physDiskNum;
3618 pReq->MsgFlags = 0;
3619 pReq->Reserved2 = 0;
3620 pReq->ActionDataWord = 0; /* Reserved for this action */
3621 //pReq->ActionDataSGE = 0;
3622
3623 mpt_add_sge((char *)&pReq->ActionDataSGE,
3624 MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1);
3625
3626 ddvprintk((MYIOC_s_INFO_FMT "RAID Volume action %x id %d\n",
3627 hd->ioc->name, action, io->id));
3628
3629 hd->pLocal = NULL;
3630 hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */
3631 hd->scandv_wait_done = 0;
3632
3633 /* Save cmd pointer, for resource free if timeout or
3634 * FW reload occurs
3635 */
3636 hd->cmdPtr = mf;
3637
3638 add_timer(&hd->timer);
3639 mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
3640 wait_event(hd->scandv_waitq, hd->scandv_wait_done);
3641
3642 if ((hd->pLocal == NULL) || (hd->pLocal->completion != MPT_SCANDV_GOOD))
3643 return -1;
3644
3645 return 0;
3646 }
3647 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
3648
3649 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3650 /**
3651 * mptscsih_do_cmd - Do internal command.
3652 * @hd: MPT_SCSI_HOST pointer
3653 * @io: INTERNAL_CMD pointer.
3654 *
3655 * Issue the specified internally generated command and do command
3656 * specific cleanup. For bus scan / DV only.
3657 * NOTES: If command is Inquiry and status is good,
3658 * initialize a target structure, save the data
3659 *
3660 * Remark: Single threaded access only.
3661 *
3662 * Return:
3663 * < 0 if an illegal command or no resources
3664 *
3665 * 0 if good
3666 *
3667 * > 0 if command complete but some type of completion error.
3668 */
3669 static int
3670 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
3671 {
3672 MPT_FRAME_HDR *mf;
3673 SCSIIORequest_t *pScsiReq;
3674 SCSIIORequest_t ReqCopy;
3675 int my_idx, ii, dir;
3676 int rc, cmdTimeout;
3677 int in_isr;
3678 char cmdLen;
3679 char CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
3680 char cmd = io->cmd;
3681
3682 in_isr = in_interrupt();
3683 if (in_isr) {
3684 dprintk((MYIOC_s_WARN_FMT "Internal SCSI IO request not allowed in ISR context!\n",
3685 hd->ioc->name));
3686 return -EPERM;
3687 }
3688
3689
3690 /* Set command specific information
3691 */
3692 switch (cmd) {
3693 case INQUIRY:
3694 cmdLen = 6;
3695 dir = MPI_SCSIIO_CONTROL_READ;
3696 CDB[0] = cmd;
3697 CDB[4] = io->size;
3698 cmdTimeout = 10;
3699 break;
3700
3701 case TEST_UNIT_READY:
3702 cmdLen = 6;
3703 dir = MPI_SCSIIO_CONTROL_READ;
3704 cmdTimeout = 10;
3705 break;
3706
3707 case START_STOP:
3708 cmdLen = 6;
3709 dir = MPI_SCSIIO_CONTROL_READ;
3710 CDB[0] = cmd;
3711 CDB[4] = 1; /*Spin up the disk */
3712 cmdTimeout = 15;
3713 break;
3714
3715 case REQUEST_SENSE:
3716 cmdLen = 6;
3717 CDB[0] = cmd;
3718 CDB[4] = io->size;
3719 dir = MPI_SCSIIO_CONTROL_READ;
3720 cmdTimeout = 10;
3721 break;
3722
3723 case READ_BUFFER:
3724 cmdLen = 10;
3725 dir = MPI_SCSIIO_CONTROL_READ;
3726 CDB[0] = cmd;
3727 if (io->flags & MPT_ICFLAG_ECHO) {
3728 CDB[1] = 0x0A;
3729 } else {
3730 CDB[1] = 0x02;
3731 }
3732
3733 if (io->flags & MPT_ICFLAG_BUF_CAP) {
3734 CDB[1] |= 0x01;
3735 }
3736 CDB[6] = (io->size >> 16) & 0xFF;
3737 CDB[7] = (io->size >> 8) & 0xFF;
3738 CDB[8] = io->size & 0xFF;
3739 cmdTimeout = 10;
3740 break;
3741
3742 case WRITE_BUFFER:
3743 cmdLen = 10;
3744 dir = MPI_SCSIIO_CONTROL_WRITE;
3745 CDB[0] = cmd;
3746 if (io->flags & MPT_ICFLAG_ECHO) {
3747 CDB[1] = 0x0A;
3748 } else {
3749 CDB[1] = 0x02;
3750 }
3751 CDB[6] = (io->size >> 16) & 0xFF;
3752 CDB[7] = (io->size >> 8) & 0xFF;
3753 CDB[8] = io->size & 0xFF;
3754 cmdTimeout = 10;
3755 break;
3756
3757 case RESERVE:
3758 cmdLen = 6;
3759 dir = MPI_SCSIIO_CONTROL_READ;
3760 CDB[0] = cmd;
3761 cmdTimeout = 10;
3762 break;
3763
3764 case RELEASE:
3765 cmdLen = 6;
3766 dir = MPI_SCSIIO_CONTROL_READ;
3767 CDB[0] = cmd;
3768 cmdTimeout = 10;
3769 break;
3770
3771 case SYNCHRONIZE_CACHE:
3772 cmdLen = 10;
3773 dir = MPI_SCSIIO_CONTROL_READ;
3774 CDB[0] = cmd;
3775 // CDB[1] = 0x02; /* set immediate bit */
3776 cmdTimeout = 10;
3777 break;
3778
3779 default:
3780 /* Error Case */
3781 return -EFAULT;
3782 }
3783
3784 /* Get and Populate a free Frame
3785 */
3786 if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) {
3787 ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n",
3788 hd->ioc->name));
3789 return -EBUSY;
3790 }
3791
3792 pScsiReq = (SCSIIORequest_t *) mf;
3793
3794 /* Get the request index */
3795 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3796 ADD_INDEX_LOG(my_idx); /* for debug */
3797
3798 if (io->flags & MPT_ICFLAG_PHYS_DISK) {
3799 pScsiReq->TargetID = io->physDiskNum;
3800 pScsiReq->Bus = 0;
3801 pScsiReq->ChainOffset = 0;
3802 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
3803 } else {
3804 pScsiReq->TargetID = io->id;
3805 pScsiReq->Bus = io->bus;
3806 pScsiReq->ChainOffset = 0;
3807 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
3808 }
3809
3810 pScsiReq->CDBLength = cmdLen;
3811 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
3812
3813 pScsiReq->Reserved = 0;
3814
3815 pScsiReq->MsgFlags = mpt_msg_flags();
3816 /* MsgContext set in mpt_get_msg_fram call */
3817
3818 for (ii=0; ii < 8; ii++)
3819 pScsiReq->LUN[ii] = 0;
3820 pScsiReq->LUN[1] = io->lun;
3821
3822 if (io->flags & MPT_ICFLAG_TAGGED_CMD)
3823 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
3824 else
3825 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3826
3827 if (cmd == REQUEST_SENSE) {
3828 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3829 ddvprintk((MYIOC_s_INFO_FMT "Untagged! 0x%2x\n",
3830 hd->ioc->name, cmd));
3831 }
3832
3833 for (ii=0; ii < 16; ii++)
3834 pScsiReq->CDB[ii] = CDB[ii];
3835
3836 pScsiReq->DataLength = cpu_to_le32(io->size);
3837 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma
3838 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
3839
3840 ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n",
3841 hd->ioc->name, cmd, io->bus, io->id, io->lun));
3842
3843 if (dir == MPI_SCSIIO_CONTROL_READ) {
3844 mpt_add_sge((char *) &pScsiReq->SGL,
3845 MPT_SGE_FLAGS_SSIMPLE_READ | io->size,
3846 io->data_dma);
3847 } else {
3848 mpt_add_sge((char *) &pScsiReq->SGL,
3849 MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size,
3850 io->data_dma);
3851 }
3852
3853 /* The ISR will free the request frame, but we need
3854 * the information to initialize the target. Duplicate.
3855 */
3856 memcpy(&ReqCopy, pScsiReq, sizeof(SCSIIORequest_t));
3857
3858 /* Issue this command after:
3859 * finish init
3860 * add timer
3861 * Wait until the reply has been received
3862 * ScsiScanDvCtx callback function will
3863 * set hd->pLocal;
3864 * set scandv_wait_done and call wake_up
3865 */
3866 hd->pLocal = NULL;
3867 hd->timer.expires = jiffies + HZ*cmdTimeout;
3868 hd->scandv_wait_done = 0;
3869
3870 /* Save cmd pointer, for resource free if timeout or
3871 * FW reload occurs
3872 */
3873 hd->cmdPtr = mf;
3874
3875 add_timer(&hd->timer);
3876 mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf);
3877 wait_event(hd->scandv_waitq, hd->scandv_wait_done);
3878
3879 if (hd->pLocal) {
3880 rc = hd->pLocal->completion;
3881 hd->pLocal->skip = 0;
3882
3883 /* Always set fatal error codes in some cases.
3884 */
3885 if (rc == MPT_SCANDV_SELECTION_TIMEOUT)
3886 rc = -ENXIO;
3887 else if (rc == MPT_SCANDV_SOME_ERROR)
3888 rc = -rc;
3889 } else {
3890 rc = -EFAULT;
3891 /* This should never happen. */
3892 ddvprintk((MYIOC_s_INFO_FMT "_do_cmd: Null pLocal!!!\n",
3893 hd->ioc->name));
3894 }
3895
3896 return rc;
3897 }
3898
3899 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3900 /**
3901 * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3902 * @hd: Pointer to MPT_SCSI_HOST structure
3903 * @portnum: IOC port number
3904 *
3905 * Uses the ISR, but with special processing.
3906 * MUST be single-threaded.
3907 *
3908 * Return: 0 on completion
3909 */
3910 static int
3911 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum)
3912 {
3913 MPT_ADAPTER *ioc= hd->ioc;
3914 VirtDevice *pTarget;
3915 SCSIDevicePage1_t *pcfg1Data = NULL;
3916 INTERNAL_CMD iocmd;
3917 CONFIGPARMS cfg;
3918 dma_addr_t cfg1_dma_addr = -1;
3919 ConfigPageHeader_t header1;
3920 int bus = 0;
3921 int id = 0;
3922 int lun;
3923 int indexed_lun, lun_index;
3924 int hostId = ioc->pfacts[portnum].PortSCSIID;
3925 int max_id;
3926 int requested, configuration, data;
3927 int doConfig = 0;
3928 u8 flags, factor;
3929
3930 max_id = ioc->sh->max_id - 1;
3931
3932 /* Following parameters will not change
3933 * in this routine.
3934 */
3935 iocmd.cmd = SYNCHRONIZE_CACHE;
3936 iocmd.flags = 0;
3937 iocmd.physDiskNum = -1;
3938 iocmd.data = NULL;
3939 iocmd.data_dma = -1;
3940 iocmd.size = 0;
3941 iocmd.rsvd = iocmd.rsvd2 = 0;
3942
3943 /* No SCSI hosts
3944 */
3945 if (hd->Targets == NULL)
3946 return 0;
3947
3948 /* Skip the host
3949 */
3950 if (id == hostId)
3951 id++;
3952
3953 /* Write SDP1 for all SCSI devices
3954 * Alloc memory and set up config buffer
3955 */
3956 if (ioc->bus_type == SCSI) {
3957 if (ioc->spi_data.sdp1length > 0) {
3958 pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev,
3959 ioc->spi_data.sdp1length * 4, &cfg1_dma_addr);
3960
3961 if (pcfg1Data != NULL) {
3962 doConfig = 1;
3963 header1.PageVersion = ioc->spi_data.sdp1version;
3964 header1.PageLength = ioc->spi_data.sdp1length;
3965 header1.PageNumber = 1;
3966 header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
3967 cfg.hdr = &header1;
3968 cfg.physAddr = cfg1_dma_addr;
3969 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
3970 cfg.dir = 1;
3971 cfg.timeout = 0;
3972 }
3973 }
3974 }
3975
3976 /* loop through all devices on this port
3977 */
3978 while (bus < MPT_MAX_BUS) {
3979 iocmd.bus = bus;
3980 iocmd.id = id;
3981 pTarget = hd->Targets[(int)id];
3982
3983 if (doConfig) {
3984
3985 /* Set the negotiation flags */
3986 if (pTarget && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) {
3987 flags = pTarget->negoFlags;
3988 } else {
3989 flags = hd->ioc->spi_data.noQas;
3990 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
3991 data = hd->ioc->spi_data.nvram[id];
3992
3993 if (data & MPT_NVRAM_WIDE_DISABLE)
3994 flags |= MPT_TARGET_NO_NEGO_WIDE;
3995
3996 factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
3997 if ((factor == 0) || (factor == MPT_ASYNC))
3998 flags |= MPT_TARGET_NO_NEGO_SYNC;
3999 }
4000 }
4001
4002 /* Force to async, narrow */
4003 mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested,
4004 &configuration, flags);
4005 dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC "
4006 "offset=0 negoFlags=%x request=%x config=%x\n",
4007 id, flags, requested, configuration));
4008 pcfg1Data->RequestedParameters = le32_to_cpu(requested);
4009 pcfg1Data->Reserved = 0;
4010 pcfg1Data->Configuration = le32_to_cpu(configuration);
4011 cfg.pageAddr = (bus<<8) | id;
4012 mpt_config(hd->ioc, &cfg);
4013 }
4014
4015 /* If target Ptr NULL or if this target is NOT a disk, skip.
4016 */
4017 if ((pTarget) && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)){
4018 for (lun=0; lun <= MPT_LAST_LUN; lun++) {
4019 /* If LUN present, issue the command
4020 */
4021 lun_index = (lun >> 5); /* 32 luns per lun_index */
4022 indexed_lun = (lun % 32);
4023 if (pTarget->luns[lun_index] & (1<<indexed_lun)) {
4024 iocmd.lun = lun;
4025 (void) mptscsih_do_cmd(hd, &iocmd);
4026 }
4027 }
4028 }
4029
4030 /* get next relevant device */
4031 id++;
4032
4033 if (id == hostId)
4034 id++;
4035
4036 if (id > max_id) {
4037 id = 0;
4038 bus++;
4039 }
4040 }
4041
4042 if (pcfg1Data) {
4043 pci_free_consistent(ioc->pcidev, header1.PageLength * 4, pcfg1Data, cfg1_dma_addr);
4044 }
4045
4046 return 0;
4047 }
4048
4049 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
4050 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4051 /**
4052 * mptscsih_domainValidation - Top level handler for domain validation.
4053 * @hd: Pointer to MPT_SCSI_HOST structure.
4054 *
4055 * Uses the ISR, but with special processing.
4056 * Called from schedule, should not be in interrupt mode.
4057 * While thread alive, do dv for all devices needing dv
4058 *
4059 * Return: None.
4060 */
4061 static void
4062 mptscsih_domainValidation(void *arg)
4063 {
4064 MPT_SCSI_HOST *hd;
4065 MPT_ADAPTER *ioc;
4066 unsigned long flags;
4067 int id, maxid, dvStatus, did;
4068 int ii, isPhysDisk;
4069
4070 spin_lock_irqsave(&dvtaskQ_lock, flags);
4071 dvtaskQ_active = 1;
4072 if (dvtaskQ_release) {
4073 dvtaskQ_active = 0;
4074 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4075 return;
4076 }
4077 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4078
4079 /* For this ioc, loop through all devices and do dv to each device.
4080 * When complete with this ioc, search through the ioc list, and
4081 * for each scsi ioc found, do dv for all devices. Exit when no
4082 * device needs dv.
4083 */
4084 did = 1;
4085 while (did) {
4086 did = 0;
4087 list_for_each_entry(ioc, &ioc_list, list) {
4088 spin_lock_irqsave(&dvtaskQ_lock, flags);
4089 if (dvtaskQ_release) {
4090 dvtaskQ_active = 0;
4091 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4092 return;
4093 }
4094 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4095
4096 msleep(250);
4097
4098 /* DV only to SCSI adapters */
4099 if (ioc->bus_type != SCSI)
4100 continue;
4101
4102 /* Make sure everything looks ok */
4103 if (ioc->sh == NULL)
4104 continue;
4105
4106 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata;
4107 if (hd == NULL)
4108 continue;
4109
4110 if ((ioc->spi_data.forceDv & MPT_SCSICFG_RELOAD_IOC_PG3) != 0) {
4111 mpt_read_ioc_pg_3(ioc);
4112 if (ioc->spi_data.pIocPg3) {
4113 Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
4114 int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
4115
4116 while (numPDisk) {
4117 if (ioc->spi_data.dvStatus[pPDisk->PhysDiskID] & MPT_SCSICFG_DV_NOT_DONE)
4118 ioc->spi_data.dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV;
4119
4120 pPDisk++;
4121 numPDisk--;
4122 }
4123 }
4124 ioc->spi_data.forceDv &= ~MPT_SCSICFG_RELOAD_IOC_PG3;
4125 }
4126
4127 maxid = min_t(int, ioc->sh->max_id, MPT_MAX_SCSI_DEVICES);
4128
4129 for (id = 0; id < maxid; id++) {
4130 spin_lock_irqsave(&dvtaskQ_lock, flags);
4131 if (dvtaskQ_release) {
4132 dvtaskQ_active = 0;
4133 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4134 return;
4135 }
4136 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4137 dvStatus = hd->ioc->spi_data.dvStatus[id];
4138
4139 if (dvStatus & MPT_SCSICFG_NEED_DV) {
4140 did++;
4141 hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_DV_PENDING;
4142 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_NEED_DV;
4143
4144 msleep(250);
4145
4146 /* If hidden phys disk, block IO's to all
4147 * raid volumes
4148 * else, process normally
4149 */
4150 isPhysDisk = mptscsih_is_phys_disk(ioc, id);
4151 if (isPhysDisk) {
4152 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4153 if (hd->ioc->spi_data.isRaid & (1 << ii)) {
4154 hd->ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_DV_PENDING;
4155 }
4156 }
4157 }
4158
4159 if (mptscsih_doDv(hd, 0, id) == 1) {
4160 /* Untagged device was busy, try again
4161 */
4162 hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_NEED_DV;
4163 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_PENDING;
4164 } else {
4165 /* DV is complete. Clear flags.
4166 */
4167 hd->ioc->spi_data.dvStatus[id] &= ~(MPT_SCSICFG_DV_NOT_DONE | MPT_SCSICFG_DV_PENDING);
4168 }
4169
4170 if (isPhysDisk) {
4171 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4172 if (hd->ioc->spi_data.isRaid & (1 << ii)) {
4173 hd->ioc->spi_data.dvStatus[ii] &= ~MPT_SCSICFG_DV_PENDING;
4174 }
4175 }
4176 }
4177
4178 if (hd->ioc->spi_data.noQas)
4179 mptscsih_qas_check(hd, id);
4180 }
4181 }
4182 }
4183 }
4184
4185 spin_lock_irqsave(&dvtaskQ_lock, flags);
4186 dvtaskQ_active = 0;
4187 spin_unlock_irqrestore(&dvtaskQ_lock, flags);
4188
4189 return;
4190 }
4191
4192 /* Search IOC page 3 to determine if this is hidden physical disk
4193 */
4194 static int
4195 mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id)
4196 {
4197 if (ioc->spi_data.pIocPg3) {
4198 Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
4199 int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
4200
4201 while (numPDisk) {
4202 if (pPDisk->PhysDiskID == id) {
4203 return 1;
4204 }
4205 pPDisk++;
4206 numPDisk--;
4207 }
4208 }
4209 return 0;
4210 }
4211
4212 /* Write SDP1 if no QAS has been enabled
4213 */
4214 static void
4215 mptscsih_qas_check(MPT_SCSI_HOST *hd, int id)
4216 {
4217 VirtDevice *pTarget;
4218 int ii;
4219
4220 if (hd->Targets == NULL)
4221 return;
4222
4223 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
4224 if (ii == id)
4225 continue;
4226
4227 if ((hd->ioc->spi_data.dvStatus[ii] & MPT_SCSICFG_DV_NOT_DONE) != 0)
4228 continue;
4229
4230 pTarget = hd->Targets[ii];
4231
4232 if ((pTarget != NULL) && (!pTarget->raidVolume)) {
4233 if ((pTarget->negoFlags & hd->ioc->spi_data.noQas) == 0) {
4234 pTarget->negoFlags |= hd->ioc->spi_data.noQas;
4235 dnegoprintk(("writeSDP1: id=%d flags=0\n", id));
4236 mptscsih_writeSDP1(hd, 0, ii, 0);
4237 }
4238 } else {
4239 if (mptscsih_is_phys_disk(hd->ioc, ii) == 1) {
4240 dnegoprintk(("writeSDP1: id=%d SCSICFG_USE_NVRAM\n", id));
4241 mptscsih_writeSDP1(hd, 0, ii, MPT_SCSICFG_USE_NVRAM);
4242 }
4243 }
4244 }
4245 return;
4246 }
4247
4248
4249
4250 #define MPT_GET_NVRAM_VALS 0x01
4251 #define MPT_UPDATE_MAX 0x02
4252 #define MPT_SET_MAX 0x04
4253 #define MPT_SET_MIN 0x08
4254 #define MPT_FALLBACK 0x10
4255 #define MPT_SAVE 0x20
4256
4257 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4258 /**
4259 * mptscsih_doDv - Perform domain validation to a target.
4260 * @hd: Pointer to MPT_SCSI_HOST structure.
4261 * @portnum: IOC port number.
4262 * @target: Physical ID of this target
4263 *
4264 * Uses the ISR, but with special processing.
4265 * MUST be single-threaded.
4266 * Test will exit if target is at async & narrow.
4267 *
4268 * Return: None.
4269 */
4270 static int
4271 mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id)
4272 {
4273 MPT_ADAPTER *ioc = hd->ioc;
4274 VirtDevice *pTarget;
4275 SCSIDevicePage1_t *pcfg1Data;
4276 SCSIDevicePage0_t *pcfg0Data;
4277 u8 *pbuf1;
4278 u8 *pbuf2;
4279 u8 *pDvBuf;
4280 dma_addr_t dvbuf_dma = -1;
4281 dma_addr_t buf1_dma = -1;
4282 dma_addr_t buf2_dma = -1;
4283 dma_addr_t cfg1_dma_addr = -1;
4284 dma_addr_t cfg0_dma_addr = -1;
4285 ConfigPageHeader_t header1;
4286 ConfigPageHeader_t header0;
4287 DVPARAMETERS dv;
4288 INTERNAL_CMD iocmd;
4289 CONFIGPARMS cfg;
4290 int dv_alloc = 0;
4291 int rc, sz = 0;
4292 int bufsize = 0;
4293 int dataBufSize = 0;
4294 int echoBufSize = 0;
4295 int notDone;
4296 int patt;
4297 int repeat;
4298 int retcode = 0;
4299 int nfactor = MPT_ULTRA320;
4300 char firstPass = 1;
4301 char doFallback = 0;
4302 char readPage0;
4303 char bus, lun;
4304 char inq0 = 0;
4305
4306 if (ioc->spi_data.sdp1length == 0)
4307 return 0;
4308
4309 if (ioc->spi_data.sdp0length == 0)
4310 return 0;
4311
4312 /* If multiple buses are used, require that the initiator
4313 * id be the same on all buses.
4314 */
4315 if (id == ioc->pfacts[0].PortSCSIID)
4316 return 0;
4317
4318 lun = 0;
4319 bus = (u8) bus_number;
4320 ddvtprintk((MYIOC_s_NOTE_FMT
4321 "DV started: bus=%d, id=%d dv @ %p\n",
4322 ioc->name, bus, id, &dv));
4323
4324 /* Prep DV structure
4325 */
4326 memset (&dv, 0, sizeof(DVPARAMETERS));
4327 dv.id = id;
4328
4329 /* Populate tmax with the current maximum
4330 * transfer parameters for this target.
4331 * Exit if narrow and async.
4332 */
4333 dv.cmd = MPT_GET_NVRAM_VALS;
4334 mptscsih_dv_parms(hd, &dv, NULL);
4335
4336 /* Prep SCSI IO structure
4337 */
4338 iocmd.id = id;
4339 iocmd.bus = bus;
4340 iocmd.lun = lun;
4341 iocmd.flags = 0;
4342 iocmd.physDiskNum = -1;
4343 iocmd.rsvd = iocmd.rsvd2 = 0;
4344
4345 pTarget = hd->Targets[id];
4346
4347 /* Use tagged commands if possible.
4348 */
4349 if (pTarget) {
4350 if (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)
4351 iocmd.flags |= MPT_ICFLAG_TAGGED_CMD;
4352 else {
4353 if (hd->ioc->facts.FWVersion.Word < 0x01000600)
4354 return 0;
4355
4356 if ((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
4357 (hd->ioc->facts.FWVersion.Word < 0x01010B00))
4358 return 0;
4359 }
4360 }
4361
4362 /* Prep cfg structure
4363 */
4364 cfg.pageAddr = (bus<<8) | id;
4365 cfg.hdr = NULL;
4366
4367 /* Prep SDP0 header
4368 */
4369 header0.PageVersion = ioc->spi_data.sdp0version;
4370 header0.PageLength = ioc->spi_data.sdp0length;
4371 header0.PageNumber = 0;
4372 header0.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4373
4374 /* Prep SDP1 header
4375 */
4376 header1.PageVersion = ioc->spi_data.sdp1version;
4377 header1.PageLength = ioc->spi_data.sdp1length;
4378 header1.PageNumber = 1;
4379 header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
4380
4381 if (header0.PageLength & 1)
4382 dv_alloc = (header0.PageLength * 4) + 4;
4383
4384 dv_alloc += (2048 + (header1.PageLength * 4));
4385
4386 pDvBuf = pci_alloc_consistent(ioc->pcidev, dv_alloc, &dvbuf_dma);
4387 if (pDvBuf == NULL)
4388 return 0;
4389
4390 sz = 0;
4391 pbuf1 = (u8 *)pDvBuf;
4392 buf1_dma = dvbuf_dma;
4393 sz +=1024;
4394
4395 pbuf2 = (u8 *) (pDvBuf + sz);
4396 buf2_dma = dvbuf_dma + sz;
4397 sz +=1024;
4398
4399 pcfg0Data = (SCSIDevicePage0_t *) (pDvBuf + sz);
4400 cfg0_dma_addr = dvbuf_dma + sz;
4401 sz += header0.PageLength * 4;
4402
4403 /* 8-byte alignment
4404 */
4405 if (header0.PageLength & 1)
4406 sz += 4;
4407
4408 pcfg1Data = (SCSIDevicePage1_t *) (pDvBuf + sz);
4409 cfg1_dma_addr = dvbuf_dma + sz;
4410
4411 /* Skip this ID? Set cfg.hdr to force config page write
4412 */
4413 {
4414 ScsiCfgData *pspi_data = &hd->ioc->spi_data;
4415 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) {
4416 /* Set the factor from nvram */
4417 nfactor = (pspi_data->nvram[id] & MPT_NVRAM_SYNC_MASK) >> 8;
4418 if (nfactor < pspi_data->minSyncFactor )
4419 nfactor = pspi_data->minSyncFactor;
4420
4421 if (!(pspi_data->nvram[id] & MPT_NVRAM_ID_SCAN_ENABLE) ||
4422 (pspi_data->PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_OFF_DV) ) {
4423
4424 ddvprintk((MYIOC_s_NOTE_FMT "DV Skipped: bus, id, lun (%d, %d, %d)\n",
4425 ioc->name, bus, id, lun));
4426
4427 dv.cmd = MPT_SET_MAX;
4428 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4429 cfg.hdr = &header1;
4430
4431 /* Save the final negotiated settings to
4432 * SCSI device page 1.
4433 */
4434 cfg.physAddr = cfg1_dma_addr;
4435 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4436 cfg.dir = 1;
4437 mpt_config(hd->ioc, &cfg);
4438 goto target_done;
4439 }
4440 }
4441 }
4442
4443 /* Finish iocmd inititialization - hidden or visible disk? */
4444 if (ioc->spi_data.pIocPg3) {
4445 /* Search IOC page 3 for matching id
4446 */
4447 Ioc3PhysDisk_t *pPDisk = ioc->spi_data.pIocPg3->PhysDisk;
4448 int numPDisk = ioc->spi_data.pIocPg3->NumPhysDisks;
4449
4450 while (numPDisk) {
4451 if (pPDisk->PhysDiskID == id) {
4452 /* match */
4453 iocmd.flags |= MPT_ICFLAG_PHYS_DISK;
4454 iocmd.physDiskNum = pPDisk->PhysDiskNum;
4455
4456 /* Quiesce the IM
4457 */
4458 if (mptscsih_do_raid(hd, MPI_RAID_ACTION_QUIESCE_PHYS_IO, &iocmd) < 0) {
4459 ddvprintk((MYIOC_s_ERR_FMT "RAID Queisce FAILED!\n", ioc->name));
4460 goto target_done;
4461 }
4462 break;
4463 }
4464 pPDisk++;
4465 numPDisk--;
4466 }
4467 }
4468
4469 /* RAID Volume ID's may double for a physical device. If RAID but
4470 * not a physical ID as well, skip DV.
4471 */
4472 if ((hd->ioc->spi_data.isRaid & (1 << id)) && !(iocmd.flags & MPT_ICFLAG_PHYS_DISK))
4473 goto target_done;
4474
4475
4476 /* Basic Test.
4477 * Async & Narrow - Inquiry
4478 * Async & Narrow - Inquiry
4479 * Maximum transfer rate - Inquiry
4480 * Compare buffers:
4481 * If compare, test complete.
4482 * If miscompare and first pass, repeat
4483 * If miscompare and not first pass, fall back and repeat
4484 */
4485 hd->pLocal = NULL;
4486 readPage0 = 0;
4487 sz = SCSI_MAX_INQUIRY_BYTES;
4488 rc = MPT_SCANDV_GOOD;
4489 while (1) {
4490 ddvprintk((MYIOC_s_NOTE_FMT "DV: Start Basic test on id=%d\n", ioc->name, id));
4491 retcode = 0;
4492 dv.cmd = MPT_SET_MIN;
4493 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4494
4495 cfg.hdr = &header1;
4496 cfg.physAddr = cfg1_dma_addr;
4497 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4498 cfg.dir = 1;
4499 if (mpt_config(hd->ioc, &cfg) != 0)
4500 goto target_done;
4501
4502 /* Wide - narrow - wide workaround case
4503 */
4504 if ((rc == MPT_SCANDV_ISSUE_SENSE) && dv.max.width) {
4505 /* Send an untagged command to reset disk Qs corrupted
4506 * when a parity error occurs on a Request Sense.
4507 */
4508 if ((hd->ioc->facts.FWVersion.Word >= 0x01000600) ||
4509 ((hd->ioc->facts.FWVersion.Word >= 0x01010000) &&
4510 (hd->ioc->facts.FWVersion.Word < 0x01010B00)) ) {
4511
4512 iocmd.cmd = REQUEST_SENSE;
4513 iocmd.data_dma = buf1_dma;
4514 iocmd.data = pbuf1;
4515 iocmd.size = 0x12;
4516 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4517 goto target_done;
4518 else {
4519 if (hd->pLocal == NULL)
4520 goto target_done;
4521 rc = hd->pLocal->completion;
4522 if ((rc == MPT_SCANDV_GOOD) || (rc == MPT_SCANDV_SENSE)) {
4523 dv.max.width = 0;
4524 doFallback = 0;
4525 } else
4526 goto target_done;
4527 }
4528 } else
4529 goto target_done;
4530 }
4531
4532 iocmd.cmd = INQUIRY;
4533 iocmd.data_dma = buf1_dma;
4534 iocmd.data = pbuf1;
4535 iocmd.size = sz;
4536 memset(pbuf1, 0x00, sz);
4537 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4538 goto target_done;
4539 else {
4540 if (hd->pLocal == NULL)
4541 goto target_done;
4542 rc = hd->pLocal->completion;
4543 if (rc == MPT_SCANDV_GOOD) {
4544 if (hd->pLocal->scsiStatus == SAM_STAT_BUSY) {
4545 if ((iocmd.flags & MPT_ICFLAG_TAGGED_CMD) == 0)
4546 retcode = 1;
4547 else
4548 retcode = 0;
4549
4550 goto target_done;
4551 }
4552 } else if (rc == MPT_SCANDV_SENSE) {
4553 ;
4554 } else {
4555 /* If first command doesn't complete
4556 * with a good status or with a check condition,
4557 * exit.
4558 */
4559 goto target_done;
4560 }
4561 }
4562
4563 /* Reset the size for disks
4564 */
4565 inq0 = (*pbuf1) & 0x1F;
4566 if ((inq0 == 0) && pTarget && !pTarget->raidVolume) {
4567 sz = 0x40;
4568 iocmd.size = sz;
4569 }
4570
4571 /* Another GEM workaround. Check peripheral device type,
4572 * if PROCESSOR, quit DV.
4573 */
4574 if (inq0 == TYPE_PROCESSOR) {
4575 mptscsih_initTarget(hd,
4576 bus,
4577 id,
4578 lun,
4579 pbuf1,
4580 sz);
4581 goto target_done;
4582 }
4583
4584 if (inq0 > 0x08)
4585 goto target_done;
4586
4587 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4588 goto target_done;
4589
4590 if (sz == 0x40) {
4591 if ((pTarget->maxWidth == 1) && (pTarget->maxOffset) && (nfactor < 0x0A)
4592 && (pTarget->minSyncFactor > 0x09)) {
4593 if ((pbuf1[56] & 0x04) == 0)
4594 ;
4595 else if ((pbuf1[56] & 0x01) == 1) {
4596 pTarget->minSyncFactor =
4597 nfactor > MPT_ULTRA320 ? nfactor : MPT_ULTRA320;
4598 } else {
4599 pTarget->minSyncFactor =
4600 nfactor > MPT_ULTRA160 ? nfactor : MPT_ULTRA160;
4601 }
4602
4603 dv.max.factor = pTarget->minSyncFactor;
4604
4605 if ((pbuf1[56] & 0x02) == 0) {
4606 pTarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS;
4607 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
4608 ddvprintk((MYIOC_s_NOTE_FMT
4609 "DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n",
4610 ioc->name, id, pbuf1[56]));
4611 }
4612 }
4613 }
4614
4615 if (doFallback)
4616 dv.cmd = MPT_FALLBACK;
4617 else
4618 dv.cmd = MPT_SET_MAX;
4619
4620 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4621 if (mpt_config(hd->ioc, &cfg) != 0)
4622 goto target_done;
4623
4624 if ((!dv.now.width) && (!dv.now.offset))
4625 goto target_done;
4626
4627 iocmd.cmd = INQUIRY;
4628 iocmd.data_dma = buf2_dma;
4629 iocmd.data = pbuf2;
4630 iocmd.size = sz;
4631 memset(pbuf2, 0x00, sz);
4632 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4633 goto target_done;
4634 else if (hd->pLocal == NULL)
4635 goto target_done;
4636 else {
4637 /* Save the return code.
4638 * If this is the first pass,
4639 * read SCSI Device Page 0
4640 * and update the target max parameters.
4641 */
4642 rc = hd->pLocal->completion;
4643 doFallback = 0;
4644 if (rc == MPT_SCANDV_GOOD) {
4645 if (!readPage0) {
4646 u32 sdp0_info;
4647 u32 sdp0_nego;
4648
4649 cfg.hdr = &header0;
4650 cfg.physAddr = cfg0_dma_addr;
4651 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4652 cfg.dir = 0;
4653
4654 if (mpt_config(hd->ioc, &cfg) != 0)
4655 goto target_done;
4656
4657 sdp0_info = le32_to_cpu(pcfg0Data->Information) & 0x0E;
4658 sdp0_nego = (le32_to_cpu(pcfg0Data->NegotiatedParameters) & 0xFF00 ) >> 8;
4659
4660 /* Quantum and Fujitsu workarounds.
4661 * Quantum: PPR U320 -> PPR reply with Ultra2 and wide
4662 * Fujitsu: PPR U320 -> Msg Reject and Ultra2 and wide
4663 * Resetart with a request for U160.
4664 */
4665 if ((dv.now.factor == MPT_ULTRA320) && (sdp0_nego == MPT_ULTRA2)) {
4666 doFallback = 1;
4667 } else {
4668 dv.cmd = MPT_UPDATE_MAX;
4669 mptscsih_dv_parms(hd, &dv, (void *)pcfg0Data);
4670 /* Update the SCSI device page 1 area
4671 */
4672 pcfg1Data->RequestedParameters = pcfg0Data->NegotiatedParameters;
4673 readPage0 = 1;
4674 }
4675 }
4676
4677 /* Quantum workaround. Restart this test will the fallback
4678 * flag set.
4679 */
4680 if (doFallback == 0) {
4681 if (memcmp(pbuf1, pbuf2, sz) != 0) {
4682 if (!firstPass)
4683 doFallback = 1;
4684 } else {
4685 ddvprintk((MYIOC_s_NOTE_FMT
4686 "DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id));
4687 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE;
4688 mptscsih_initTarget(hd,
4689 bus,
4690 id,
4691 lun,
4692 pbuf1,
4693 sz);
4694 break; /* test complete */
4695 }
4696 }
4697
4698
4699 } else if (rc == MPT_SCANDV_ISSUE_SENSE)
4700 doFallback = 1; /* set fallback flag */
4701 else if ((rc == MPT_SCANDV_DID_RESET) ||
4702 (rc == MPT_SCANDV_SENSE) ||
4703 (rc == MPT_SCANDV_FALLBACK))
4704 doFallback = 1; /* set fallback flag */
4705 else
4706 goto target_done;
4707
4708 firstPass = 0;
4709 }
4710 }
4711 ddvprintk((MYIOC_s_NOTE_FMT "DV: Basic test on id=%d completed OK.\n", ioc->name, id));
4712
4713 if (ioc->spi_data.mpt_dv == 0)
4714 goto target_done;
4715
4716 inq0 = (*pbuf1) & 0x1F;
4717
4718 /* Continue only for disks
4719 */
4720 if (inq0 != 0)
4721 goto target_done;
4722
4723 if ( ioc->spi_data.PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_BASIC_DV_ONLY )
4724 goto target_done;
4725
4726 /* Start the Enhanced Test.
4727 * 0) issue TUR to clear out check conditions
4728 * 1) read capacity of echo (regular) buffer
4729 * 2) reserve device
4730 * 3) do write-read-compare data pattern test
4731 * 4) release
4732 * 5) update nego parms to target struct
4733 */
4734 cfg.hdr = &header1;
4735 cfg.physAddr = cfg1_dma_addr;
4736 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
4737 cfg.dir = 1;
4738
4739 iocmd.cmd = TEST_UNIT_READY;
4740 iocmd.data_dma = -1;
4741 iocmd.data = NULL;
4742 iocmd.size = 0;
4743 notDone = 1;
4744 while (notDone) {
4745 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4746 goto target_done;
4747
4748 if (hd->pLocal == NULL)
4749 goto target_done;
4750
4751 rc = hd->pLocal->completion;
4752 if (rc == MPT_SCANDV_GOOD)
4753 notDone = 0;
4754 else if (rc == MPT_SCANDV_SENSE) {
4755 u8 skey = hd->pLocal->sense[2] & 0x0F;
4756 u8 asc = hd->pLocal->sense[12];
4757 u8 ascq = hd->pLocal->sense[13];
4758 ddvprintk((MYIOC_s_INFO_FMT
4759 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
4760 ioc->name, skey, asc, ascq));
4761
4762 if (skey == UNIT_ATTENTION)
4763 notDone++; /* repeat */
4764 else if ((skey == NOT_READY) &&
4765 (asc == 0x04)&&(ascq == 0x01)) {
4766 /* wait then repeat */
4767 mdelay (2000);
4768 notDone++;
4769 } else if ((skey == NOT_READY) && (asc == 0x3A)) {
4770 /* no medium, try read test anyway */
4771 notDone = 0;
4772 } else {
4773 /* All other errors are fatal.
4774 */
4775 ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
4776 ioc->name));
4777 goto target_done;
4778 }
4779 } else
4780 goto target_done;
4781 }
4782
4783 iocmd.cmd = READ_BUFFER;
4784 iocmd.data_dma = buf1_dma;
4785 iocmd.data = pbuf1;
4786 iocmd.size = 4;
4787 iocmd.flags |= MPT_ICFLAG_BUF_CAP;
4788
4789 dataBufSize = 0;
4790 echoBufSize = 0;
4791 for (patt = 0; patt < 2; patt++) {
4792 if (patt == 0)
4793 iocmd.flags |= MPT_ICFLAG_ECHO;
4794 else
4795 iocmd.flags &= ~MPT_ICFLAG_ECHO;
4796
4797 notDone = 1;
4798 while (notDone) {
4799 bufsize = 0;
4800
4801 /* If not ready after 8 trials,
4802 * give up on this device.
4803 */
4804 if (notDone > 8)
4805 goto target_done;
4806
4807 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4808 goto target_done;
4809 else if (hd->pLocal == NULL)
4810 goto target_done;
4811 else {
4812 rc = hd->pLocal->completion;
4813 ddvprintk(("ReadBuffer Comp Code %d", rc));
4814 ddvprintk((" buff: %0x %0x %0x %0x\n",
4815 pbuf1[0], pbuf1[1], pbuf1[2], pbuf1[3]));
4816
4817 if (rc == MPT_SCANDV_GOOD) {
4818 notDone = 0;
4819 if (iocmd.flags & MPT_ICFLAG_ECHO) {
4820 bufsize = ((pbuf1[2] & 0x1F) <<8) | pbuf1[3];
4821 } else {
4822 bufsize = pbuf1[1]<<16 | pbuf1[2]<<8 | pbuf1[3];
4823 }
4824 } else if (rc == MPT_SCANDV_SENSE) {
4825 u8 skey = hd->pLocal->sense[2] & 0x0F;
4826 u8 asc = hd->pLocal->sense[12];
4827 u8 ascq = hd->pLocal->sense[13];
4828 ddvprintk((MYIOC_s_INFO_FMT
4829 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
4830 ioc->name, skey, asc, ascq));
4831 if (skey == ILLEGAL_REQUEST) {
4832 notDone = 0;
4833 } else if (skey == UNIT_ATTENTION) {
4834 notDone++; /* repeat */
4835 } else if ((skey == NOT_READY) &&
4836 (asc == 0x04)&&(ascq == 0x01)) {
4837 /* wait then repeat */
4838 mdelay (2000);
4839 notDone++;
4840 } else {
4841 /* All other errors are fatal.
4842 */
4843 ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.",
4844 ioc->name));
4845 goto target_done;
4846 }
4847 } else {
4848 /* All other errors are fatal
4849 */
4850 goto target_done;
4851 }
4852 }
4853 }
4854
4855 if (iocmd.flags & MPT_ICFLAG_ECHO)
4856 echoBufSize = bufsize;
4857 else
4858 dataBufSize = bufsize;
4859 }
4860 sz = 0;
4861 iocmd.flags &= ~MPT_ICFLAG_BUF_CAP;
4862
4863 /* Use echo buffers if possible,
4864 * Exit if both buffers are 0.
4865 */
4866 if (echoBufSize > 0) {
4867 iocmd.flags |= MPT_ICFLAG_ECHO;
4868 if (dataBufSize > 0)
4869 bufsize = min(echoBufSize, dataBufSize);
4870 else
4871 bufsize = echoBufSize;
4872 } else if (dataBufSize == 0)
4873 goto target_done;
4874
4875 ddvprintk((MYIOC_s_INFO_FMT "%s Buffer Capacity %d\n", ioc->name,
4876 (iocmd.flags & MPT_ICFLAG_ECHO) ? "Echo" : " ", bufsize));
4877
4878 /* Data buffers for write-read-compare test max 1K.
4879 */
4880 sz = min(bufsize, 1024);
4881
4882 /* --- loop ----
4883 * On first pass, always issue a reserve.
4884 * On additional loops, only if a reset has occurred.
4885 * iocmd.flags indicates if echo or regular buffer
4886 */
4887 for (patt = 0; patt < 4; patt++) {
4888 ddvprintk(("Pattern %d\n", patt));
4889 if ((iocmd.flags & MPT_ICFLAG_RESERVED) && (iocmd.flags & MPT_ICFLAG_DID_RESET)) {
4890 iocmd.cmd = TEST_UNIT_READY;
4891 iocmd.data_dma = -1;
4892 iocmd.data = NULL;
4893 iocmd.size = 0;
4894 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4895 goto target_done;
4896
4897 iocmd.cmd = RELEASE;
4898 iocmd.data_dma = -1;
4899 iocmd.data = NULL;
4900 iocmd.size = 0;
4901 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4902 goto target_done;
4903 else if (hd->pLocal == NULL)
4904 goto target_done;
4905 else {
4906 rc = hd->pLocal->completion;
4907 ddvprintk(("Release rc %d\n", rc));
4908 if (rc == MPT_SCANDV_GOOD)
4909 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
4910 else
4911 goto target_done;
4912 }
4913 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
4914 }
4915 iocmd.flags &= ~MPT_ICFLAG_DID_RESET;
4916
4917 repeat = 5;
4918 while (repeat && (!(iocmd.flags & MPT_ICFLAG_RESERVED))) {
4919 iocmd.cmd = RESERVE;
4920 iocmd.data_dma = -1;
4921 iocmd.data = NULL;
4922 iocmd.size = 0;
4923 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4924 goto target_done;
4925 else if (hd->pLocal == NULL)
4926 goto target_done;
4927 else {
4928 rc = hd->pLocal->completion;
4929 if (rc == MPT_SCANDV_GOOD) {
4930 iocmd.flags |= MPT_ICFLAG_RESERVED;
4931 } else if (rc == MPT_SCANDV_SENSE) {
4932 /* Wait if coming ready
4933 */
4934 u8 skey = hd->pLocal->sense[2] & 0x0F;
4935 u8 asc = hd->pLocal->sense[12];
4936 u8 ascq = hd->pLocal->sense[13];
4937 ddvprintk((MYIOC_s_INFO_FMT
4938 "DV: Reserve Failed: ", ioc->name));
4939 ddvprintk(("SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n",
4940 skey, asc, ascq));
4941
4942 if ((skey == NOT_READY) && (asc == 0x04)&&
4943 (ascq == 0x01)) {
4944 /* wait then repeat */
4945 mdelay (2000);
4946 notDone++;
4947 } else {
4948 ddvprintk((MYIOC_s_INFO_FMT
4949 "DV: Reserved Failed.", ioc->name));
4950 goto target_done;
4951 }
4952 } else {
4953 ddvprintk((MYIOC_s_INFO_FMT "DV: Reserved Failed.",
4954 ioc->name));
4955 goto target_done;
4956 }
4957 }
4958 }
4959
4960 mptscsih_fillbuf(pbuf1, sz, patt, 1);
4961 iocmd.cmd = WRITE_BUFFER;
4962 iocmd.data_dma = buf1_dma;
4963 iocmd.data = pbuf1;
4964 iocmd.size = sz;
4965 if (mptscsih_do_cmd(hd, &iocmd) < 0)
4966 goto target_done;
4967 else if (hd->pLocal == NULL)
4968 goto target_done;
4969 else {
4970 rc = hd->pLocal->completion;
4971 if (rc == MPT_SCANDV_GOOD)
4972 ; /* Issue read buffer */
4973 else if (rc == MPT_SCANDV_DID_RESET) {
4974 /* If using echo buffers, reset to data buffers.
4975 * Else do Fallback and restart
4976 * this test (re-issue reserve
4977 * because of bus reset).
4978 */
4979 if ((iocmd.flags & MPT_ICFLAG_ECHO) && (dataBufSize >= bufsize)) {
4980 iocmd.flags &= ~MPT_ICFLAG_ECHO;
4981 } else {
4982 dv.cmd = MPT_FALLBACK;
4983 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
4984
4985 if (mpt_config(hd->ioc, &cfg) != 0)
4986 goto target_done;
4987
4988 if ((!dv.now.width) && (!dv.now.offset))
4989 goto target_done;
4990 }
4991
4992 iocmd.flags |= MPT_ICFLAG_DID_RESET;
4993 patt = -1;
4994 continue;
4995 } else if (rc == MPT_SCANDV_SENSE) {
4996 /* Restart data test if UA, else quit.
4997 */
4998 u8 skey = hd->pLocal->sense[2] & 0x0F;
4999 ddvprintk((MYIOC_s_INFO_FMT
5000 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
5001 hd->pLocal->sense[12], hd->pLocal->sense[13]));
5002 if (skey == UNIT_ATTENTION) {
5003 patt = -1;
5004 continue;
5005 } else if (skey == ILLEGAL_REQUEST) {
5006 if (iocmd.flags & MPT_ICFLAG_ECHO) {
5007 if (dataBufSize >= bufsize) {
5008 iocmd.flags &= ~MPT_ICFLAG_ECHO;
5009 patt = -1;
5010 continue;
5011 }
5012 }
5013 goto target_done;
5014 }
5015 else
5016 goto target_done;
5017 } else {
5018 /* fatal error */
5019 goto target_done;
5020 }
5021 }
5022
5023 iocmd.cmd = READ_BUFFER;
5024 iocmd.data_dma = buf2_dma;
5025 iocmd.data = pbuf2;
5026 iocmd.size = sz;
5027 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5028 goto target_done;
5029 else if (hd->pLocal == NULL)
5030 goto target_done;
5031 else {
5032 rc = hd->pLocal->completion;
5033 if (rc == MPT_SCANDV_GOOD) {
5034 /* If buffers compare,
5035 * go to next pattern,
5036 * else, do a fallback and restart
5037 * data transfer test.
5038 */
5039 if (memcmp (pbuf1, pbuf2, sz) == 0) {
5040 ; /* goto next pattern */
5041 } else {
5042 /* Miscompare with Echo buffer, go to data buffer,
5043 * if that buffer exists.
5044 * Miscompare with Data buffer, check first 4 bytes,
5045 * some devices return capacity. Exit in this case.
5046 */
5047 if (iocmd.flags & MPT_ICFLAG_ECHO) {
5048 if (dataBufSize >= bufsize)
5049 iocmd.flags &= ~MPT_ICFLAG_ECHO;
5050 else
5051 goto target_done;
5052 } else {
5053 if (dataBufSize == (pbuf2[1]<<16 | pbuf2[2]<<8 | pbuf2[3])) {
5054 /* Argh. Device returning wrong data.
5055 * Quit DV for this device.
5056 */
5057 goto target_done;
5058 }
5059
5060 /* Had an actual miscompare. Slow down.*/
5061 dv.cmd = MPT_FALLBACK;
5062 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5063
5064 if (mpt_config(hd->ioc, &cfg) != 0)
5065 goto target_done;
5066
5067 if ((!dv.now.width) && (!dv.now.offset))
5068 goto target_done;
5069 }
5070
5071 patt = -1;
5072 continue;
5073 }
5074 } else if (rc == MPT_SCANDV_DID_RESET) {
5075 /* Do Fallback and restart
5076 * this test (re-issue reserve
5077 * because of bus reset).
5078 */
5079 dv.cmd = MPT_FALLBACK;
5080 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5081
5082 if (mpt_config(hd->ioc, &cfg) != 0)
5083 goto target_done;
5084
5085 if ((!dv.now.width) && (!dv.now.offset))
5086 goto target_done;
5087
5088 iocmd.flags |= MPT_ICFLAG_DID_RESET;
5089 patt = -1;
5090 continue;
5091 } else if (rc == MPT_SCANDV_SENSE) {
5092 /* Restart data test if UA, else quit.
5093 */
5094 u8 skey = hd->pLocal->sense[2] & 0x0F;
5095 ddvprintk((MYIOC_s_INFO_FMT
5096 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey,
5097 hd->pLocal->sense[12], hd->pLocal->sense[13]));
5098 if (skey == UNIT_ATTENTION) {
5099 patt = -1;
5100 continue;
5101 }
5102 else
5103 goto target_done;
5104 } else {
5105 /* fatal error */
5106 goto target_done;
5107 }
5108 }
5109
5110 } /* --- end of patt loop ---- */
5111
5112 target_done:
5113 if (iocmd.flags & MPT_ICFLAG_RESERVED) {
5114 iocmd.cmd = RELEASE;
5115 iocmd.data_dma = -1;
5116 iocmd.data = NULL;
5117 iocmd.size = 0;
5118 if (mptscsih_do_cmd(hd, &iocmd) < 0)
5119 printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
5120 ioc->name, id);
5121 else if (hd->pLocal) {
5122 if (hd->pLocal->completion == MPT_SCANDV_GOOD)
5123 iocmd.flags &= ~MPT_ICFLAG_RESERVED;
5124 } else {
5125 printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d",
5126 ioc->name, id);
5127 }
5128 }
5129
5130
5131 /* Set if cfg1_dma_addr contents is valid
5132 */
5133 if ((cfg.hdr != NULL) && (retcode == 0)){
5134 /* If disk, not U320, disable QAS
5135 */
5136 if ((inq0 == 0) && (dv.now.factor > MPT_ULTRA320)) {
5137 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS;
5138 ddvprintk((MYIOC_s_NOTE_FMT
5139 "noQas set due to id=%d has factor=%x\n", ioc->name, id, dv.now.factor));
5140 }
5141
5142 dv.cmd = MPT_SAVE;
5143 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data);
5144
5145 /* Double writes to SDP1 can cause problems,
5146 * skip save of the final negotiated settings to
5147 * SCSI device page 1.
5148 *
5149 cfg.hdr = &header1;
5150 cfg.physAddr = cfg1_dma_addr;
5151 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5152 cfg.dir = 1;
5153 mpt_config(hd->ioc, &cfg);
5154 */
5155 }
5156
5157 /* If this is a RAID Passthrough, enable internal IOs
5158 */
5159 if (iocmd.flags & MPT_ICFLAG_PHYS_DISK) {
5160 if (mptscsih_do_raid(hd, MPI_RAID_ACTION_ENABLE_PHYS_IO, &iocmd) < 0)
5161 ddvprintk((MYIOC_s_ERR_FMT "RAID Enable FAILED!\n", ioc->name));
5162 }
5163
5164 /* Done with the DV scan of the current target
5165 */
5166 if (pDvBuf)
5167 pci_free_consistent(ioc->pcidev, dv_alloc, pDvBuf, dvbuf_dma);
5168
5169 ddvtprintk((MYIOC_s_INFO_FMT "DV Done id=%d\n",
5170 ioc->name, id));
5171
5172 return retcode;
5173 }
5174
5175 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5176 /* mptscsih_dv_parms - perform a variety of operations on the
5177 * parameters used for negotiation.
5178 * @hd: Pointer to a SCSI host.
5179 * @dv: Pointer to a structure that contains the maximum and current
5180 * negotiated parameters.
5181 */
5182 static void
5183 mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage)
5184 {
5185 VirtDevice *pTarget;
5186 SCSIDevicePage0_t *pPage0;
5187 SCSIDevicePage1_t *pPage1;
5188 int val = 0, data, configuration;
5189 u8 width = 0;
5190 u8 offset = 0;
5191 u8 factor = 0;
5192 u8 negoFlags = 0;
5193 u8 cmd = dv->cmd;
5194 u8 id = dv->id;
5195
5196 switch (cmd) {
5197 case MPT_GET_NVRAM_VALS:
5198 ddvprintk((MYIOC_s_NOTE_FMT "Getting NVRAM: ",
5199 hd->ioc->name));
5200 /* Get the NVRAM values and save in tmax
5201 * If not an LVD bus, the adapter minSyncFactor has been
5202 * already throttled back.
5203 */
5204 if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume) {
5205 width = pTarget->maxWidth;
5206 offset = pTarget->maxOffset;
5207 factor = pTarget->minSyncFactor;
5208 negoFlags = pTarget->negoFlags;
5209 } else {
5210 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) {
5211 data = hd->ioc->spi_data.nvram[id];
5212 width = data & MPT_NVRAM_WIDE_DISABLE ? 0 : 1;
5213 if ((offset = hd->ioc->spi_data.maxSyncOffset) == 0)
5214 factor = MPT_ASYNC;
5215 else {
5216 factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT;
5217 if ((factor == 0) || (factor == MPT_ASYNC)){
5218 factor = MPT_ASYNC;
5219 offset = 0;
5220 }
5221 }
5222 } else {
5223 width = MPT_NARROW;
5224 offset = 0;
5225 factor = MPT_ASYNC;
5226 }
5227
5228 /* Set the negotiation flags */
5229 negoFlags = hd->ioc->spi_data.noQas;
5230 if (!width)
5231 negoFlags |= MPT_TARGET_NO_NEGO_WIDE;
5232
5233 if (!offset)
5234 negoFlags |= MPT_TARGET_NO_NEGO_SYNC;
5235 }
5236
5237 /* limit by adapter capabilities */
5238 width = min(width, hd->ioc->spi_data.maxBusWidth);
5239 offset = min(offset, hd->ioc->spi_data.maxSyncOffset);
5240 factor = max(factor, hd->ioc->spi_data.minSyncFactor);
5241
5242 /* Check Consistency */
5243 if (offset && (factor < MPT_ULTRA2) && !width)
5244 factor = MPT_ULTRA2;
5245
5246 dv->max.width = width;
5247 dv->max.offset = offset;
5248 dv->max.factor = factor;
5249 dv->max.flags = negoFlags;
5250 ddvprintk((" id=%d width=%d factor=%x offset=%x flags=%x\n",
5251 id, width, factor, offset, negoFlags));
5252 break;
5253
5254 case MPT_UPDATE_MAX:
5255 ddvprintk((MYIOC_s_NOTE_FMT
5256 "Updating with SDP0 Data: ", hd->ioc->name));
5257 /* Update tmax values with those from Device Page 0.*/
5258 pPage0 = (SCSIDevicePage0_t *) pPage;
5259 if (pPage0) {
5260 val = cpu_to_le32(pPage0->NegotiatedParameters);
5261 dv->max.width = val & MPI_SCSIDEVPAGE0_NP_WIDE ? 1 : 0;
5262 dv->max.offset = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) >> 16;
5263 dv->max.factor = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8;
5264 }
5265
5266 dv->now.width = dv->max.width;
5267 dv->now.offset = dv->max.offset;
5268 dv->now.factor = dv->max.factor;
5269 ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x\n",
5270 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
5271 break;
5272
5273 case MPT_SET_MAX:
5274 ddvprintk((MYIOC_s_NOTE_FMT "Setting Max: ",
5275 hd->ioc->name));
5276 /* Set current to the max values. Update the config page.*/
5277 dv->now.width = dv->max.width;
5278 dv->now.offset = dv->max.offset;
5279 dv->now.factor = dv->max.factor;
5280 dv->now.flags = dv->max.flags;
5281
5282 pPage1 = (SCSIDevicePage1_t *)pPage;
5283 if (pPage1) {
5284 mptscsih_setDevicePage1Flags (dv->now.width, dv->now.factor,
5285 dv->now.offset, &val, &configuration, dv->now.flags);
5286 dnegoprintk(("Setting Max: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
5287 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
5288 pPage1->RequestedParameters = le32_to_cpu(val);
5289 pPage1->Reserved = 0;
5290 pPage1->Configuration = le32_to_cpu(configuration);
5291 }
5292
5293 ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x request=%x configuration=%x\n",
5294 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration));
5295 break;
5296
5297 case MPT_SET_MIN:
5298 ddvprintk((MYIOC_s_NOTE_FMT "Setting Min: ",
5299 hd->ioc->name));
5300 /* Set page to asynchronous and narrow
5301 * Do not update now, breaks fallback routine. */
5302 width = MPT_NARROW;
5303 offset = 0;
5304 factor = MPT_ASYNC;
5305 negoFlags = dv->max.flags;
5306
5307 pPage1 = (SCSIDevicePage1_t *)pPage;
5308 if (pPage1) {
5309 mptscsih_setDevicePage1Flags (width, factor,
5310 offset, &val, &configuration, negoFlags);
5311 dnegoprintk(("Setting Min: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n",
5312 id, width, factor, offset, negoFlags, val, configuration));
5313 pPage1->RequestedParameters = le32_to_cpu(val);
5314 pPage1->Reserved = 0;
5315 pPage1->Configuration = le32_to_cpu(configuration);
5316 }
5317 ddvprintk(("id=%d width=%d factor=%x offset=%x request=%x config=%x negoFlags=%x\n",
5318 id, width, factor, offset, val, configuration, negoFlags));
5319 break;
5320
5321 case MPT_FALLBACK:
5322 ddvprintk((MYIOC_s_NOTE_FMT
5323 "Fallback: Start: offset %d, factor %x, width %d \n",
5324 hd->ioc->name, dv->now.offset,
5325 dv->now.factor, dv->now.width));
5326 width = dv->now.width;
5327 offset = dv->now.offset;
5328 factor = dv->now.factor;
5329 if ((offset) && (dv->max.width)) {
5330 if (factor < MPT_ULTRA160)
5331 factor = MPT_ULTRA160;
5332 else if (factor < MPT_ULTRA2) {
5333 factor = MPT_ULTRA2;
5334 width = MPT_WIDE;
5335 } else if ((factor == MPT_ULTRA2) && width) {
5336 factor = MPT_ULTRA2;
5337 width = MPT_NARROW;
5338 } else if (factor < MPT_ULTRA) {
5339 factor = MPT_ULTRA;
5340 width = MPT_WIDE;
5341 } else if ((factor == MPT_ULTRA) && width) {
5342 width = MPT_NARROW;
5343 } else if (factor < MPT_FAST) {
5344 factor = MPT_FAST;
5345 width = MPT_WIDE;
5346 } else if ((factor == MPT_FAST) && width) {
5347 factor = MPT_FAST;
5348 width = MPT_NARROW;
5349 } else if (factor < MPT_SCSI) {
5350 factor = MPT_SCSI;
5351 width = MPT_WIDE;
5352 } else if ((factor == MPT_SCSI) && width) {
5353 factor = MPT_SCSI;
5354 width = MPT_NARROW;
5355 } else {
5356 factor = MPT_ASYNC;
5357 offset = 0;
5358 }
5359
5360 } else if (offset) {
5361 width = MPT_NARROW;
5362 if (factor < MPT_ULTRA)
5363 factor = MPT_ULTRA;
5364 else if (factor < MPT_FAST)
5365 factor = MPT_FAST;
5366 else if (factor < MPT_SCSI)
5367 factor = MPT_SCSI;
5368 else {
5369 factor = MPT_ASYNC;
5370 offset = 0;
5371 }
5372
5373 } else {
5374 width = MPT_NARROW;
5375 factor = MPT_ASYNC;
5376 }
5377 dv->max.flags |= MPT_TARGET_NO_NEGO_QAS;
5378 dv->max.flags &= ~MPT_TAPE_NEGO_IDP;
5379
5380 dv->now.width = width;
5381 dv->now.offset = offset;
5382 dv->now.factor = factor;
5383 dv->now.flags = dv->max.flags;
5384
5385 pPage1 = (SCSIDevicePage1_t *)pPage;
5386 if (pPage1) {
5387 mptscsih_setDevicePage1Flags (width, factor, offset, &val,
5388 &configuration, dv->now.flags);
5389 dnegoprintk(("Finish: id=%d width=%d offset=%d factor=%x flags=%x request=%x config=%x\n",
5390 id, width, offset, factor, dv->now.flags, val, configuration));
5391
5392 pPage1->RequestedParameters = le32_to_cpu(val);
5393 pPage1->Reserved = 0;
5394 pPage1->Configuration = le32_to_cpu(configuration);
5395 }
5396
5397 ddvprintk(("Finish: id=%d offset=%d factor=%x width=%d request=%x config=%x\n",
5398 id, dv->now.offset, dv->now.factor, dv->now.width, val, configuration));
5399 break;
5400
5401 case MPT_SAVE:
5402 ddvprintk((MYIOC_s_NOTE_FMT
5403 "Saving to Target structure: ", hd->ioc->name));
5404 ddvprintk(("id=%d width=%x factor=%x offset=%d flags=%x\n",
5405 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags));
5406
5407 /* Save these values to target structures
5408 * or overwrite nvram (phys disks only).
5409 */
5410
5411 if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume ) {
5412 pTarget->maxWidth = dv->now.width;
5413 pTarget->maxOffset = dv->now.offset;
5414 pTarget->minSyncFactor = dv->now.factor;
5415 pTarget->negoFlags = dv->now.flags;
5416 } else {
5417 /* Preserv all flags, use
5418 * read-modify-write algorithm
5419 */
5420 if (hd->ioc->spi_data.nvram) {
5421 data = hd->ioc->spi_data.nvram[id];
5422
5423 if (dv->now.width)
5424 data &= ~MPT_NVRAM_WIDE_DISABLE;
5425 else
5426 data |= MPT_NVRAM_WIDE_DISABLE;
5427
5428 if (!dv->now.offset)
5429 factor = MPT_ASYNC;
5430
5431 data &= ~MPT_NVRAM_SYNC_MASK;
5432 data |= (dv->now.factor << MPT_NVRAM_SYNC_SHIFT) & MPT_NVRAM_SYNC_MASK;
5433
5434 hd->ioc->spi_data.nvram[id] = data;
5435 }
5436 }
5437 break;
5438 }
5439 }
5440
5441 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5442 /* mptscsih_fillbuf - fill a buffer with a special data pattern
5443 * cleanup. For bus scan only.
5444 *
5445 * @buffer: Pointer to data buffer to be filled.
5446 * @size: Number of bytes to fill
5447 * @index: Pattern index
5448 * @width: bus width, 0 (8 bits) or 1 (16 bits)
5449 */
5450 static void
5451 mptscsih_fillbuf(char *buffer, int size, int index, int width)
5452 {
5453 char *ptr = buffer;
5454 int ii;
5455 char byte;
5456 short val;
5457
5458 switch (index) {
5459 case 0:
5460
5461 if (width) {
5462 /* Pattern: 0000 FFFF 0000 FFFF
5463 */
5464 for (ii=0; ii < size; ii++, ptr++) {
5465 if (ii & 0x02)
5466 *ptr = 0xFF;
5467 else
5468 *ptr = 0x00;
5469 }
5470 } else {
5471 /* Pattern: 00 FF 00 FF
5472 */
5473 for (ii=0; ii < size; ii++, ptr++) {
5474 if (ii & 0x01)
5475 *ptr = 0xFF;
5476 else
5477 *ptr = 0x00;
5478 }
5479 }
5480 break;
5481
5482 case 1:
5483 if (width) {
5484 /* Pattern: 5555 AAAA 5555 AAAA 5555
5485 */
5486 for (ii=0; ii < size; ii++, ptr++) {
5487 if (ii & 0x02)
5488 *ptr = 0xAA;
5489 else
5490 *ptr = 0x55;
5491 }
5492 } else {
5493 /* Pattern: 55 AA 55 AA 55
5494 */
5495 for (ii=0; ii < size; ii++, ptr++) {
5496 if (ii & 0x01)
5497 *ptr = 0xAA;
5498 else
5499 *ptr = 0x55;
5500 }
5501 }
5502 break;
5503
5504 case 2:
5505 /* Pattern: 00 01 02 03 04 05
5506 * ... FE FF 00 01..
5507 */
5508 for (ii=0; ii < size; ii++, ptr++)
5509 *ptr = (char) ii;
5510 break;
5511
5512 case 3:
5513 if (width) {
5514 /* Wide Pattern: FFFE 0001 FFFD 0002
5515 * ... 4000 DFFF 8000 EFFF
5516 */
5517 byte = 0;
5518 for (ii=0; ii < size/2; ii++) {
5519 /* Create the base pattern
5520 */
5521 val = (1 << byte);
5522 /* every 64 (0x40) bytes flip the pattern
5523 * since we fill 2 bytes / iteration,
5524 * test for ii = 0x20
5525 */
5526 if (ii & 0x20)
5527 val = ~(val);
5528
5529 if (ii & 0x01) {
5530 *ptr = (char)( (val & 0xFF00) >> 8);
5531 ptr++;
5532 *ptr = (char)(val & 0xFF);
5533 byte++;
5534 byte &= 0x0F;
5535 } else {
5536 val = ~val;
5537 *ptr = (char)( (val & 0xFF00) >> 8);
5538 ptr++;
5539 *ptr = (char)(val & 0xFF);
5540 }
5541
5542 ptr++;
5543 }
5544 } else {
5545 /* Narrow Pattern: FE 01 FD 02 FB 04
5546 * .. 7F 80 01 FE 02 FD ... 80 7F
5547 */
5548 byte = 0;
5549 for (ii=0; ii < size; ii++, ptr++) {
5550 /* Base pattern - first 32 bytes
5551 */
5552 if (ii & 0x01) {
5553 *ptr = (1 << byte);
5554 byte++;
5555 byte &= 0x07;
5556 } else {
5557 *ptr = (char) (~(1 << byte));
5558 }
5559
5560 /* Flip the pattern every 32 bytes
5561 */
5562 if (ii & 0x20)
5563 *ptr = ~(*ptr);
5564 }
5565 }
5566 break;
5567 }
5568 }
5569 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */
5570
5571 EXPORT_SYMBOL(mptscsih_remove);
5572 EXPORT_SYMBOL(mptscsih_shutdown);
5573 #ifdef CONFIG_PM
5574 EXPORT_SYMBOL(mptscsih_suspend);
5575 EXPORT_SYMBOL(mptscsih_resume);
5576 #endif
5577 EXPORT_SYMBOL(mptscsih_proc_info);
5578 EXPORT_SYMBOL(mptscsih_info);
5579 EXPORT_SYMBOL(mptscsih_qcmd);
5580 EXPORT_SYMBOL(mptscsih_slave_alloc);
5581 EXPORT_SYMBOL(mptscsih_slave_destroy);
5582 EXPORT_SYMBOL(mptscsih_slave_configure);
5583 EXPORT_SYMBOL(mptscsih_abort);
5584 EXPORT_SYMBOL(mptscsih_dev_reset);
5585 EXPORT_SYMBOL(mptscsih_bus_reset);
5586 EXPORT_SYMBOL(mptscsih_host_reset);
5587 EXPORT_SYMBOL(mptscsih_bios_param);
5588 EXPORT_SYMBOL(mptscsih_io_done);
5589 EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
5590 EXPORT_SYMBOL(mptscsih_scandv_complete);
5591 EXPORT_SYMBOL(mptscsih_event_process);
5592 EXPORT_SYMBOL(mptscsih_ioc_reset);
5593 EXPORT_SYMBOL(mptscsih_store_queue_depth);
5594 EXPORT_SYMBOL(mptscsih_timer_expired);
5595
5596 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
This page took 0.208381 seconds and 4 git commands to generate.