]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blob - drivers/message/fusion/mptscsih.c
[SCSI] mpt fusion: add use of shost_priv and remove all the typecasting
[mirror_ubuntu-zesty-kernel.git] / drivers / message / fusion / mptscsih.c
1 /*
2 * linux/drivers/message/fusion/mptscsih.c
3 * For use with LSI PCI chip/adapter(s)
4 * running LSI Fusion MPT (Message Passing Technology) firmware.
5 *
6 * Copyright (c) 1999-2007 LSI Corporation
7 * (mailto:DL-MPTFusionLinux@lsi.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/module.h>
48 #include <linux/kernel.h>
49 #include <linux/init.h>
50 #include <linux/errno.h>
51 #include <linux/kdev_t.h>
52 #include <linux/blkdev.h>
53 #include <linux/delay.h> /* for mdelay */
54 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
55 #include <linux/reboot.h> /* notifier code */
56 #include <linux/workqueue.h>
57
58 #include <scsi/scsi.h>
59 #include <scsi/scsi_cmnd.h>
60 #include <scsi/scsi_device.h>
61 #include <scsi/scsi_host.h>
62 #include <scsi/scsi_tcq.h>
63 #include <scsi/scsi_dbg.h>
64
65 #include "mptbase.h"
66 #include "mptscsih.h"
67 #include "lsi/mpi_log_sas.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 MODULE_VERSION(my_VERSION);
78
79 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
80 /*
81 * Other private/forward protos...
82 */
83 int mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
84 static void mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq);
85 int mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
86
87 static int mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
88 SCSIIORequest_t *pReq, int req_idx);
89 static void mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
90 static void mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
91 static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd);
92 static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout );
93 static int SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
94
95 static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout);
96
97 int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
98 int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
99
100 int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
101 static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
102 static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
103
104 void mptscsih_remove(struct pci_dev *);
105 void mptscsih_shutdown(struct pci_dev *);
106 #ifdef CONFIG_PM
107 int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state);
108 int mptscsih_resume(struct pci_dev *pdev);
109 #endif
110
111 #define SNS_LEN(scp) sizeof((scp)->sense_buffer)
112
113 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
114 /**
115 * mptscsih_add_sge - Place a simple SGE at address pAddr.
116 * @pAddr: virtual address for SGE
117 * @flagslength: SGE flags and data transfer length
118 * @dma_addr: Physical address
119 *
120 * This routine places a MPT request frame back on the MPT adapter's
121 * FreeQ.
122 */
123 static inline void
124 mptscsih_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
125 {
126 if (sizeof(dma_addr_t) == sizeof(u64)) {
127 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
128 u32 tmp = dma_addr & 0xFFFFFFFF;
129
130 pSge->FlagsLength = cpu_to_le32(flagslength);
131 pSge->Address.Low = cpu_to_le32(tmp);
132 tmp = (u32) ((u64)dma_addr >> 32);
133 pSge->Address.High = cpu_to_le32(tmp);
134
135 } else {
136 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
137 pSge->FlagsLength = cpu_to_le32(flagslength);
138 pSge->Address = cpu_to_le32(dma_addr);
139 }
140 } /* mptscsih_add_sge() */
141
142 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
143 /**
144 * mptscsih_add_chain - Place a chain SGE at address pAddr.
145 * @pAddr: virtual address for SGE
146 * @next: nextChainOffset value (u32's)
147 * @length: length of next SGL segment
148 * @dma_addr: Physical address
149 *
150 * This routine places a MPT request frame back on the MPT adapter's
151 * FreeQ.
152 */
153 static inline void
154 mptscsih_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr)
155 {
156 if (sizeof(dma_addr_t) == sizeof(u64)) {
157 SGEChain64_t *pChain = (SGEChain64_t *) pAddr;
158 u32 tmp = dma_addr & 0xFFFFFFFF;
159
160 pChain->Length = cpu_to_le16(length);
161 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
162
163 pChain->NextChainOffset = next;
164
165 pChain->Address.Low = cpu_to_le32(tmp);
166 tmp = (u32) ((u64)dma_addr >> 32);
167 pChain->Address.High = cpu_to_le32(tmp);
168 } else {
169 SGEChain32_t *pChain = (SGEChain32_t *) pAddr;
170 pChain->Length = cpu_to_le16(length);
171 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size();
172 pChain->NextChainOffset = next;
173 pChain->Address = cpu_to_le32(dma_addr);
174 }
175 } /* mptscsih_add_chain() */
176
177 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
178 /*
179 * mptscsih_getFreeChainBuffer - Function to get a free chain
180 * from the MPT_SCSI_HOST FreeChainQ.
181 * @ioc: Pointer to MPT_ADAPTER structure
182 * @req_idx: Index of the SCSI IO request frame. (output)
183 *
184 * return SUCCESS or FAILED
185 */
186 static inline int
187 mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex)
188 {
189 MPT_FRAME_HDR *chainBuf;
190 unsigned long flags;
191 int rc;
192 int chain_idx;
193
194 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "getFreeChainBuffer called\n",
195 ioc->name));
196 spin_lock_irqsave(&ioc->FreeQlock, flags);
197 if (!list_empty(&ioc->FreeChainQ)) {
198 int offset;
199
200 chainBuf = list_entry(ioc->FreeChainQ.next, MPT_FRAME_HDR,
201 u.frame.linkage.list);
202 list_del(&chainBuf->u.frame.linkage.list);
203 offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer;
204 chain_idx = offset / ioc->req_sz;
205 rc = SUCCESS;
206 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT
207 "getFreeChainBuffer chainBuf=%p ChainBuffer=%p offset=%d chain_idx=%d\n",
208 ioc->name, chainBuf, ioc->ChainBuffer, offset, chain_idx));
209 } else {
210 rc = FAILED;
211 chain_idx = MPT_HOST_NO_CHAIN;
212 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "getFreeChainBuffer failed\n",
213 ioc->name));
214 }
215 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
216
217 *retIndex = chain_idx;
218 return rc;
219 } /* mptscsih_getFreeChainBuffer() */
220
221 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
222 /*
223 * mptscsih_AddSGE - Add a SGE (plus chain buffers) to the
224 * SCSIIORequest_t Message Frame.
225 * @ioc: Pointer to MPT_ADAPTER structure
226 * @SCpnt: Pointer to scsi_cmnd structure
227 * @pReq: Pointer to SCSIIORequest_t structure
228 *
229 * Returns ...
230 */
231 static int
232 mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
233 SCSIIORequest_t *pReq, int req_idx)
234 {
235 char *psge;
236 char *chainSge;
237 struct scatterlist *sg;
238 int frm_sz;
239 int sges_left, sg_done;
240 int chain_idx = MPT_HOST_NO_CHAIN;
241 int sgeOffset;
242 int numSgeSlots, numSgeThisFrame;
243 u32 sgflags, sgdir, thisxfer = 0;
244 int chain_dma_off = 0;
245 int newIndex;
246 int ii;
247 dma_addr_t v2;
248 u32 RequestNB;
249
250 sgdir = le32_to_cpu(pReq->Control) & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK;
251 if (sgdir == MPI_SCSIIO_CONTROL_WRITE) {
252 sgdir = MPT_TRANSFER_HOST_TO_IOC;
253 } else {
254 sgdir = MPT_TRANSFER_IOC_TO_HOST;
255 }
256
257 psge = (char *) &pReq->SGL;
258 frm_sz = ioc->req_sz;
259
260 /* Map the data portion, if any.
261 * sges_left = 0 if no data transfer.
262 */
263 sges_left = scsi_dma_map(SCpnt);
264 if (sges_left < 0)
265 return FAILED;
266
267 /* Handle the SG case.
268 */
269 sg = scsi_sglist(SCpnt);
270 sg_done = 0;
271 sgeOffset = sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION);
272 chainSge = NULL;
273
274 /* Prior to entering this loop - the following must be set
275 * current MF: sgeOffset (bytes)
276 * chainSge (Null if original MF is not a chain buffer)
277 * sg_done (num SGE done for this MF)
278 */
279
280 nextSGEset:
281 numSgeSlots = ((frm_sz - sgeOffset) / (sizeof(u32) + sizeof(dma_addr_t)) );
282 numSgeThisFrame = (sges_left < numSgeSlots) ? sges_left : numSgeSlots;
283
284 sgflags = MPT_SGE_FLAGS_SIMPLE_ELEMENT | MPT_SGE_FLAGS_ADDRESSING | sgdir;
285
286 /* Get first (num - 1) SG elements
287 * Skip any SG entries with a length of 0
288 * NOTE: at finish, sg and psge pointed to NEXT data/location positions
289 */
290 for (ii=0; ii < (numSgeThisFrame-1); ii++) {
291 thisxfer = sg_dma_len(sg);
292 if (thisxfer == 0) {
293 sg ++; /* Get next SG element from the OS */
294 sg_done++;
295 continue;
296 }
297
298 v2 = sg_dma_address(sg);
299 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
300
301 sg++; /* Get next SG element from the OS */
302 psge += (sizeof(u32) + sizeof(dma_addr_t));
303 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
304 sg_done++;
305 }
306
307 if (numSgeThisFrame == sges_left) {
308 /* Add last element, end of buffer and end of list flags.
309 */
310 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT |
311 MPT_SGE_FLAGS_END_OF_BUFFER |
312 MPT_SGE_FLAGS_END_OF_LIST;
313
314 /* Add last SGE and set termination flags.
315 * Note: Last SGE may have a length of 0 - which should be ok.
316 */
317 thisxfer = sg_dma_len(sg);
318
319 v2 = sg_dma_address(sg);
320 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
321 /*
322 sg++;
323 psge += (sizeof(u32) + sizeof(dma_addr_t));
324 */
325 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
326 sg_done++;
327
328 if (chainSge) {
329 /* The current buffer is a chain buffer,
330 * but there is not another one.
331 * Update the chain element
332 * Offset and Length fields.
333 */
334 mptscsih_add_chain((char *)chainSge, 0, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
335 } else {
336 /* The current buffer is the original MF
337 * and there is no Chain buffer.
338 */
339 pReq->ChainOffset = 0;
340 RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
341 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT
342 "Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
343 ioc->RequestNB[req_idx] = RequestNB;
344 }
345 } else {
346 /* At least one chain buffer is needed.
347 * Complete the first MF
348 * - last SGE element, set the LastElement bit
349 * - set ChainOffset (words) for orig MF
350 * (OR finish previous MF chain buffer)
351 * - update MFStructPtr ChainIndex
352 * - Populate chain element
353 * Also
354 * Loop until done.
355 */
356
357 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SG: Chain Required! sg done %d\n",
358 ioc->name, sg_done));
359
360 /* Set LAST_ELEMENT flag for last non-chain element
361 * in the buffer. Since psge points at the NEXT
362 * SGE element, go back one SGE element, update the flags
363 * and reset the pointer. (Note: sgflags & thisxfer are already
364 * set properly).
365 */
366 if (sg_done) {
367 u32 *ptmp = (u32 *) (psge - (sizeof(u32) + sizeof(dma_addr_t)));
368 sgflags = le32_to_cpu(*ptmp);
369 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT;
370 *ptmp = cpu_to_le32(sgflags);
371 }
372
373 if (chainSge) {
374 /* The current buffer is a chain buffer.
375 * chainSge points to the previous Chain Element.
376 * Update its chain element Offset and Length (must
377 * include chain element size) fields.
378 * Old chain element is now complete.
379 */
380 u8 nextChain = (u8) (sgeOffset >> 2);
381 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
382 mptscsih_add_chain((char *)chainSge, nextChain, sgeOffset, ioc->ChainBufferDMA + chain_dma_off);
383 } else {
384 /* The original MF buffer requires a chain buffer -
385 * set the offset.
386 * Last element in this MF is a chain element.
387 */
388 pReq->ChainOffset = (u8) (sgeOffset >> 2);
389 RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03;
390 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Chain Buffer Needed, RequestNB=%x sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset));
391 ioc->RequestNB[req_idx] = RequestNB;
392 }
393
394 sges_left -= sg_done;
395
396
397 /* NOTE: psge points to the beginning of the chain element
398 * in current buffer. Get a chain buffer.
399 */
400 if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED) {
401 dfailprintk(ioc, printk(MYIOC_s_DEBUG_FMT
402 "getFreeChainBuffer FAILED SCSI cmd=%02x (%p)\n",
403 ioc->name, pReq->CDB[0], SCpnt));
404 return FAILED;
405 }
406
407 /* Update the tracking arrays.
408 * If chainSge == NULL, update ReqToChain, else ChainToChain
409 */
410 if (chainSge) {
411 ioc->ChainToChain[chain_idx] = newIndex;
412 } else {
413 ioc->ReqToChain[req_idx] = newIndex;
414 }
415 chain_idx = newIndex;
416 chain_dma_off = ioc->req_sz * chain_idx;
417
418 /* Populate the chainSGE for the current buffer.
419 * - Set chain buffer pointer to psge and fill
420 * out the Address and Flags fields.
421 */
422 chainSge = (char *) psge;
423 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT " Current buff @ %p (index 0x%x)",
424 ioc->name, psge, req_idx));
425
426 /* Start the SGE for the next buffer
427 */
428 psge = (char *) (ioc->ChainBuffer + chain_dma_off);
429 sgeOffset = 0;
430 sg_done = 0;
431
432 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT " Chain buff @ %p (index 0x%x)\n",
433 ioc->name, psge, chain_idx));
434
435 /* Start the SGE for the next buffer
436 */
437
438 goto nextSGEset;
439 }
440
441 return SUCCESS;
442 } /* mptscsih_AddSGE() */
443
444 static void
445 mptscsih_issue_sep_command(MPT_ADAPTER *ioc, VirtTarget *vtarget,
446 U32 SlotStatus)
447 {
448 MPT_FRAME_HDR *mf;
449 SEPRequest_t *SEPMsg;
450
451 if (ioc->bus_type != SAS)
452 return;
453
454 /* Not supported for hidden raid components
455 */
456 if (vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
457 return;
458
459 if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
460 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: no msg frames!!\n",
461 ioc->name,__FUNCTION__));
462 return;
463 }
464
465 SEPMsg = (SEPRequest_t *)mf;
466 SEPMsg->Function = MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR;
467 SEPMsg->Bus = vtarget->channel;
468 SEPMsg->TargetID = vtarget->id;
469 SEPMsg->Action = MPI_SEP_REQ_ACTION_WRITE_STATUS;
470 SEPMsg->SlotStatus = SlotStatus;
471 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
472 "Sending SEP cmd=%x channel=%d id=%d\n",
473 ioc->name, SlotStatus, SEPMsg->Bus, SEPMsg->TargetID));
474 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
475 }
476
477 #ifdef CONFIG_FUSION_LOGGING
478 /**
479 * mptscsih_info_scsiio - debug print info on reply frame
480 * @ioc: Pointer to MPT_ADAPTER structure
481 * @sc: original scsi cmnd pointer
482 * @pScsiReply: Pointer to MPT reply frame
483 *
484 * MPT_DEBUG_REPLY needs to be enabled to obtain this info
485 *
486 * Refer to lsi/mpi.h.
487 **/
488 static void
489 mptscsih_info_scsiio(MPT_ADAPTER *ioc, struct scsi_cmnd *sc, SCSIIOReply_t * pScsiReply)
490 {
491 char *desc = NULL;
492 char *desc1 = NULL;
493 u16 ioc_status;
494 u8 skey, asc, ascq;
495
496 ioc_status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
497
498 switch (ioc_status) {
499
500 case MPI_IOCSTATUS_SUCCESS:
501 desc = "success";
502 break;
503 case MPI_IOCSTATUS_SCSI_INVALID_BUS:
504 desc = "invalid bus";
505 break;
506 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID:
507 desc = "invalid target_id";
508 break;
509 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE:
510 desc = "device not there";
511 break;
512 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN:
513 desc = "data overrun";
514 break;
515 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN:
516 desc = "data underrun";
517 break;
518 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR:
519 desc = "I/O data error";
520 break;
521 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR:
522 desc = "protocol error";
523 break;
524 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED:
525 desc = "task terminated";
526 break;
527 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH:
528 desc = "residual mismatch";
529 break;
530 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED:
531 desc = "task management failed";
532 break;
533 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED:
534 desc = "IOC terminated";
535 break;
536 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED:
537 desc = "ext terminated";
538 break;
539 default:
540 desc = "";
541 break;
542 }
543
544 switch (pScsiReply->SCSIStatus)
545 {
546
547 case MPI_SCSI_STATUS_SUCCESS:
548 desc1 = "success";
549 break;
550 case MPI_SCSI_STATUS_CHECK_CONDITION:
551 desc1 = "check condition";
552 break;
553 case MPI_SCSI_STATUS_CONDITION_MET:
554 desc1 = "condition met";
555 break;
556 case MPI_SCSI_STATUS_BUSY:
557 desc1 = "busy";
558 break;
559 case MPI_SCSI_STATUS_INTERMEDIATE:
560 desc1 = "intermediate";
561 break;
562 case MPI_SCSI_STATUS_INTERMEDIATE_CONDMET:
563 desc1 = "intermediate condmet";
564 break;
565 case MPI_SCSI_STATUS_RESERVATION_CONFLICT:
566 desc1 = "reservation conflict";
567 break;
568 case MPI_SCSI_STATUS_COMMAND_TERMINATED:
569 desc1 = "command terminated";
570 break;
571 case MPI_SCSI_STATUS_TASK_SET_FULL:
572 desc1 = "task set full";
573 break;
574 case MPI_SCSI_STATUS_ACA_ACTIVE:
575 desc1 = "aca active";
576 break;
577 case MPI_SCSI_STATUS_FCPEXT_DEVICE_LOGGED_OUT:
578 desc1 = "fcpext device logged out";
579 break;
580 case MPI_SCSI_STATUS_FCPEXT_NO_LINK:
581 desc1 = "fcpext no link";
582 break;
583 case MPI_SCSI_STATUS_FCPEXT_UNASSIGNED:
584 desc1 = "fcpext unassigned";
585 break;
586 default:
587 desc1 = "";
588 break;
589 }
590
591 scsi_print_command(sc);
592 printk(MYIOC_s_DEBUG_FMT "\tfw_channel = %d, fw_id = %d\n",
593 ioc->name, pScsiReply->Bus, pScsiReply->TargetID);
594 printk(MYIOC_s_DEBUG_FMT "\trequest_len = %d, underflow = %d, "
595 "resid = %d\n", ioc->name, scsi_bufflen(sc), sc->underflow,
596 scsi_get_resid(sc));
597 printk(MYIOC_s_DEBUG_FMT "\ttag = %d, transfer_count = %d, "
598 "sc->result = %08X\n", ioc->name, le16_to_cpu(pScsiReply->TaskTag),
599 le32_to_cpu(pScsiReply->TransferCount), sc->result);
600 printk(MYIOC_s_DEBUG_FMT "\tiocstatus = %s (0x%04x), "
601 "scsi_status = %s (0x%02x), scsi_state = (0x%02x)\n",
602 ioc->name, desc, ioc_status, desc1, pScsiReply->SCSIStatus,
603 pScsiReply->SCSIState);
604
605 if (pScsiReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
606 skey = sc->sense_buffer[2] & 0x0F;
607 asc = sc->sense_buffer[12];
608 ascq = sc->sense_buffer[13];
609
610 printk(MYIOC_s_DEBUG_FMT "\t[sense_key,asc,ascq]: "
611 "[0x%02x,0x%02x,0x%02x]\n", ioc->name, skey, asc, ascq);
612 }
613
614 /*
615 * Look for + dump FCP ResponseInfo[]!
616 */
617 if (pScsiReply->SCSIState & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
618 pScsiReply->ResponseInfo)
619 printk(MYIOC_s_DEBUG_FMT "response_info = %08xh\n",
620 ioc->name, le32_to_cpu(pScsiReply->ResponseInfo));
621 }
622 #endif
623
624 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
625 /*
626 * mptscsih_io_done - Main SCSI IO callback routine registered to
627 * Fusion MPT (base) driver
628 * @ioc: Pointer to MPT_ADAPTER structure
629 * @mf: Pointer to original MPT request frame
630 * @r: Pointer to MPT reply frame (NULL if TurboReply)
631 *
632 * This routine is called from mpt.c::mpt_interrupt() at the completion
633 * of any SCSI IO request.
634 * This routine is registered with the Fusion MPT (base) driver at driver
635 * load/init time via the mpt_register() API call.
636 *
637 * Returns 1 indicating alloc'd request frame ptr should be freed.
638 */
639 int
640 mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
641 {
642 struct scsi_cmnd *sc;
643 MPT_SCSI_HOST *hd;
644 SCSIIORequest_t *pScsiReq;
645 SCSIIOReply_t *pScsiReply;
646 u16 req_idx, req_idx_MR;
647 VirtDevice *vdevice;
648 VirtTarget *vtarget;
649
650 hd = shost_priv(ioc->sh);
651 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
652 req_idx_MR = (mr != NULL) ?
653 le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx) : req_idx;
654 if ((req_idx != req_idx_MR) ||
655 (mf->u.frame.linkage.arg1 == 0xdeadbeaf)) {
656 printk(MYIOC_s_ERR_FMT "Received a mf that was already freed\n",
657 ioc->name);
658 printk (MYIOC_s_ERR_FMT
659 "req_idx=%x req_idx_MR=%x mf=%p mr=%p sc=%p\n",
660 ioc->name, req_idx, req_idx_MR, mf, mr,
661 hd->ScsiLookup[req_idx_MR]);
662 return 0;
663 }
664
665 sc = hd->ScsiLookup[req_idx];
666 hd->ScsiLookup[req_idx] = NULL;
667 if (sc == NULL) {
668 MPIHeader_t *hdr = (MPIHeader_t *)mf;
669
670 /* Remark: writeSDP1 will use the ScsiDoneCtx
671 * If a SCSI I/O cmd, device disabled by OS and
672 * completion done. Cannot touch sc struct. Just free mem.
673 */
674 if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST)
675 printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n",
676 ioc->name);
677
678 mptscsih_freeChainBuffers(ioc, req_idx);
679 return 1;
680 }
681
682 if ((unsigned char *)mf != sc->host_scribble) {
683 mptscsih_freeChainBuffers(ioc, req_idx);
684 return 1;
685 }
686
687 sc->host_scribble = NULL;
688 sc->result = DID_OK << 16; /* Set default reply as OK */
689 pScsiReq = (SCSIIORequest_t *) mf;
690 pScsiReply = (SCSIIOReply_t *) mr;
691
692 if((ioc->facts.MsgVersion >= MPI_VERSION_01_05) && pScsiReply){
693 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT
694 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d,task-tag=%d)\n",
695 ioc->name, mf, mr, sc, req_idx, pScsiReply->TaskTag));
696 }else{
697 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT
698 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n",
699 ioc->name, mf, mr, sc, req_idx));
700 }
701
702 if (pScsiReply == NULL) {
703 /* special context reply handling */
704 ;
705 } else {
706 u32 xfer_cnt;
707 u16 status;
708 u8 scsi_state, scsi_status;
709 u32 log_info;
710
711 status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK;
712 scsi_state = pScsiReply->SCSIState;
713 scsi_status = pScsiReply->SCSIStatus;
714 xfer_cnt = le32_to_cpu(pScsiReply->TransferCount);
715 scsi_set_resid(sc, scsi_bufflen(sc) - xfer_cnt);
716 log_info = le32_to_cpu(pScsiReply->IOCLogInfo);
717
718 /*
719 * if we get a data underrun indication, yet no data was
720 * transferred and the SCSI status indicates that the
721 * command was never started, change the data underrun
722 * to success
723 */
724 if (status == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 &&
725 (scsi_status == MPI_SCSI_STATUS_BUSY ||
726 scsi_status == MPI_SCSI_STATUS_RESERVATION_CONFLICT ||
727 scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)) {
728 status = MPI_IOCSTATUS_SUCCESS;
729 }
730
731 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID)
732 mptscsih_copy_sense_data(sc, hd, mf, pScsiReply);
733
734 /*
735 * Look for + dump FCP ResponseInfo[]!
736 */
737 if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID &&
738 pScsiReply->ResponseInfo) {
739 printk(MYIOC_s_NOTE_FMT "[%d:%d:%d:%d] "
740 "FCP_ResponseInfo=%08xh\n", ioc->name,
741 sc->device->host->host_no, sc->device->channel,
742 sc->device->id, sc->device->lun,
743 le32_to_cpu(pScsiReply->ResponseInfo));
744 }
745
746 switch(status) {
747 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
748 /* CHECKME!
749 * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry)
750 * But not: DID_BUS_BUSY lest one risk
751 * killing interrupt handler:-(
752 */
753 sc->result = SAM_STAT_BUSY;
754 break;
755
756 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
757 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
758 sc->result = DID_BAD_TARGET << 16;
759 break;
760
761 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
762 /* Spoof to SCSI Selection Timeout! */
763 if (ioc->bus_type != FC)
764 sc->result = DID_NO_CONNECT << 16;
765 /* else fibre, just stall until rescan event */
766 else
767 sc->result = DID_REQUEUE << 16;
768
769 if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
770 hd->sel_timeout[pScsiReq->TargetID]++;
771
772 vdevice = sc->device->hostdata;
773 if (!vdevice)
774 break;
775 vtarget = vdevice->vtarget;
776 if (vtarget->tflags & MPT_TARGET_FLAGS_LED_ON) {
777 mptscsih_issue_sep_command(ioc, vtarget,
778 MPI_SEP_REQ_SLOTSTATUS_UNCONFIGURED);
779 vtarget->tflags &= ~MPT_TARGET_FLAGS_LED_ON;
780 }
781 break;
782
783 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
784 if ( ioc->bus_type == SAS ) {
785 u16 ioc_status = le16_to_cpu(pScsiReply->IOCStatus);
786 if (ioc_status & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
787 if ((log_info & SAS_LOGINFO_MASK)
788 == SAS_LOGINFO_NEXUS_LOSS) {
789 sc->result = (DID_BUS_BUSY << 16);
790 break;
791 }
792 }
793 } else if (ioc->bus_type == FC) {
794 /*
795 * The FC IOC may kill a request for variety of
796 * reasons, some of which may be recovered by a
797 * retry, some which are unlikely to be
798 * recovered. Return DID_ERROR instead of
799 * DID_RESET to permit retry of the command,
800 * just not an infinite number of them
801 */
802 sc->result = DID_ERROR << 16;
803 break;
804 }
805
806 /*
807 * Allow non-SAS & non-NEXUS_LOSS to drop into below code
808 */
809
810 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
811 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
812 /* Linux handles an unsolicited DID_RESET better
813 * than an unsolicited DID_ABORT.
814 */
815 sc->result = DID_RESET << 16;
816
817 break;
818
819 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
820 scsi_set_resid(sc, scsi_bufflen(sc) - xfer_cnt);
821 if((xfer_cnt==0)||(sc->underflow > xfer_cnt))
822 sc->result=DID_SOFT_ERROR << 16;
823 else /* Sufficient data transfer occurred */
824 sc->result = (DID_OK << 16) | scsi_status;
825 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT
826 "RESIDUAL_MISMATCH: result=%x on channel=%d id=%d\n",
827 ioc->name, sc->result, sc->device->channel, sc->device->id));
828 break;
829
830 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
831 /*
832 * Do upfront check for valid SenseData and give it
833 * precedence!
834 */
835 sc->result = (DID_OK << 16) | scsi_status;
836 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
837 /* Have already saved the status and sense data
838 */
839 ;
840 } else {
841 if (xfer_cnt < sc->underflow) {
842 if (scsi_status == SAM_STAT_BUSY)
843 sc->result = SAM_STAT_BUSY;
844 else
845 sc->result = DID_SOFT_ERROR << 16;
846 }
847 if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) {
848 /* What to do?
849 */
850 sc->result = DID_SOFT_ERROR << 16;
851 }
852 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
853 /* Not real sure here either... */
854 sc->result = DID_RESET << 16;
855 }
856 }
857
858
859 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT
860 " sc->underflow={report ERR if < %02xh bytes xfer'd}\n",
861 ioc->name, sc->underflow));
862 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT
863 " ActBytesXferd=%02xh\n", ioc->name, xfer_cnt));
864
865 /* Report Queue Full
866 */
867 if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)
868 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
869
870 break;
871
872 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
873 scsi_set_resid(sc, 0);
874 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
875 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
876 sc->result = (DID_OK << 16) | scsi_status;
877 if (scsi_state == 0) {
878 ;
879 } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) {
880 /*
881 * If running against circa 200003dd 909 MPT f/w,
882 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL
883 * (QUEUE_FULL) returned from device! --> get 0x0000?128
884 * and with SenseBytes set to 0.
885 */
886 if (pScsiReply->SCSIStatus == MPI_SCSI_STATUS_TASK_SET_FULL)
887 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
888
889 }
890 else if (scsi_state &
891 (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)
892 ) {
893 /*
894 * What to do?
895 */
896 sc->result = DID_SOFT_ERROR << 16;
897 }
898 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) {
899 /* Not real sure here either... */
900 sc->result = DID_RESET << 16;
901 }
902 else if (scsi_state & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) {
903 /* Device Inq. data indicates that it supports
904 * QTags, but rejects QTag messages.
905 * This command completed OK.
906 *
907 * Not real sure here either so do nothing... */
908 }
909
910 if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL)
911 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq);
912
913 /* Add handling of:
914 * Reservation Conflict, Busy,
915 * Command Terminated, CHECK
916 */
917 break;
918
919 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
920 sc->result = DID_SOFT_ERROR << 16;
921 break;
922
923 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
924 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
925 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
926 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
927 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
928 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
929 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
930 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
931 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
932 default:
933 /*
934 * What to do?
935 */
936 sc->result = DID_SOFT_ERROR << 16;
937 break;
938
939 } /* switch(status) */
940
941 #ifdef CONFIG_FUSION_LOGGING
942 if (sc->result && (ioc->debug_level & MPT_DEBUG_REPLY))
943 mptscsih_info_scsiio(ioc, sc, pScsiReply);
944 #endif
945
946 } /* end of address reply case */
947
948 /* Unmap the DMA buffers, if any. */
949 scsi_dma_unmap(sc);
950
951 sc->scsi_done(sc); /* Issue the command callback */
952
953 /* Free Chain buffers */
954 mptscsih_freeChainBuffers(ioc, req_idx);
955 return 1;
956 }
957
958 /*
959 * mptscsih_flush_running_cmds - For each command found, search
960 * Scsi_Host instance taskQ and reply to OS.
961 * Called only if recovering from a FW reload.
962 * @hd: Pointer to a SCSI HOST structure
963 *
964 * Returns: None.
965 *
966 * Must be called while new I/Os are being queued.
967 */
968 static void
969 mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
970 {
971 MPT_ADAPTER *ioc = hd->ioc;
972 struct scsi_cmnd *SCpnt;
973 MPT_FRAME_HDR *mf;
974 int ii;
975 int max = ioc->req_depth;
976
977 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": flush_ScsiLookup called\n", ioc->name));
978 for (ii= 0; ii < max; ii++) {
979 if ((SCpnt = hd->ScsiLookup[ii]) != NULL) {
980
981 /* Command found.
982 */
983
984 /* Null ScsiLookup index
985 */
986 hd->ScsiLookup[ii] = NULL;
987
988 mf = MPT_INDEX_2_MFPTR(ioc, ii);
989 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": flush: ScsiDone (mf=%p,sc=%p)\n",
990 ioc->name, mf, SCpnt));
991
992 /* Free Chain buffers */
993 mptscsih_freeChainBuffers(ioc, ii);
994
995 /* Free Message frames */
996 mpt_free_msg_frame(ioc, mf);
997
998 if ((unsigned char *)mf != SCpnt->host_scribble)
999 continue;
1000
1001 /* Set status, free OS resources (SG DMA buffers)
1002 * Do OS callback
1003 */
1004 scsi_dma_unmap(SCpnt);
1005
1006 SCpnt->result = DID_RESET << 16;
1007 SCpnt->host_scribble = NULL;
1008
1009 SCpnt->scsi_done(SCpnt); /* Issue the command callback */
1010 }
1011 }
1012
1013 return;
1014 }
1015
1016 /*
1017 * mptscsih_search_running_cmds - Delete any commands associated
1018 * with the specified target and lun. Function called only
1019 * when a lun is disable by mid-layer.
1020 * Do NOT access the referenced scsi_cmnd structure or
1021 * members. Will cause either a paging or NULL ptr error.
1022 * (BUT, BUT, BUT, the code does reference it! - mdr)
1023 * @hd: Pointer to a SCSI HOST structure
1024 * @vdevice: per device private data
1025 *
1026 * Returns: None.
1027 *
1028 * Called from slave_destroy.
1029 */
1030 static void
1031 mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
1032 {
1033 SCSIIORequest_t *mf = NULL;
1034 int ii;
1035 int max = hd->ioc->req_depth;
1036 struct scsi_cmnd *sc;
1037 struct scsi_lun lun;
1038 MPT_ADAPTER *ioc = hd->ioc;
1039
1040 dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": search_running channel %d id %d lun %d max %d\n",
1041 ioc->name, vdevice->vtarget->channel, vdevice->vtarget->id, vdevice->lun, max));
1042
1043 for (ii=0; ii < max; ii++) {
1044 if ((sc = hd->ScsiLookup[ii]) != NULL) {
1045
1046 mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(ioc, ii);
1047 if (mf == NULL)
1048 continue;
1049 /* If the device is a hidden raid component, then its
1050 * expected that the mf->function will be RAID_SCSI_IO
1051 */
1052 if (vdevice->vtarget->tflags &
1053 MPT_TARGET_FLAGS_RAID_COMPONENT && mf->Function !=
1054 MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)
1055 continue;
1056
1057 int_to_scsilun(vdevice->lun, &lun);
1058 if ((mf->Bus != vdevice->vtarget->channel) ||
1059 (mf->TargetID != vdevice->vtarget->id) ||
1060 memcmp(lun.scsi_lun, mf->LUN, 8))
1061 continue;
1062
1063 /* Cleanup
1064 */
1065 hd->ScsiLookup[ii] = NULL;
1066 mptscsih_freeChainBuffers(ioc, ii);
1067 mpt_free_msg_frame(ioc, (MPT_FRAME_HDR *)mf);
1068 if ((unsigned char *)mf != sc->host_scribble)
1069 continue;
1070 scsi_dma_unmap(sc);
1071 sc->host_scribble = NULL;
1072 sc->result = DID_NO_CONNECT << 16;
1073 sdev_printk(MYIOC_s_INFO_FMT, sc->device, "completing cmds: fw_channel %d,"
1074 "fw_id %d, sc=%p, mf = %p, idx=%x\n", ioc->name, vdevice->vtarget->channel,
1075 vdevice->vtarget->id, sc, mf, ii);
1076 sc->scsi_done(sc);
1077 }
1078 }
1079 return;
1080 }
1081
1082 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1083
1084 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1085 /*
1086 * mptscsih_report_queue_full - Report QUEUE_FULL status returned
1087 * from a SCSI target device.
1088 * @sc: Pointer to scsi_cmnd structure
1089 * @pScsiReply: Pointer to SCSIIOReply_t
1090 * @pScsiReq: Pointer to original SCSI request
1091 *
1092 * This routine periodically reports QUEUE_FULL status returned from a
1093 * SCSI target device. It reports this to the console via kernel
1094 * printk() API call, not more than once every 10 seconds.
1095 */
1096 static void
1097 mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq)
1098 {
1099 long time = jiffies;
1100 MPT_SCSI_HOST *hd;
1101 MPT_ADAPTER *ioc;
1102
1103 if (sc->device == NULL)
1104 return;
1105 if (sc->device->host == NULL)
1106 return;
1107 if ((hd = shost_priv(sc->device->host)) == NULL)
1108 return;
1109 ioc = hd->ioc;
1110 if (time - hd->last_queue_full > 10 * HZ) {
1111 dprintk(ioc, printk(MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n",
1112 ioc->name, 0, sc->device->id, sc->device->lun));
1113 hd->last_queue_full = time;
1114 }
1115 }
1116
1117 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1118 /*
1119 * mptscsih_remove - Removed scsi devices
1120 * @pdev: Pointer to pci_dev structure
1121 *
1122 *
1123 */
1124 void
1125 mptscsih_remove(struct pci_dev *pdev)
1126 {
1127 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1128 struct Scsi_Host *host = ioc->sh;
1129 MPT_SCSI_HOST *hd;
1130 int sz1;
1131
1132 if(!host) {
1133 mpt_detach(pdev);
1134 return;
1135 }
1136
1137 scsi_remove_host(host);
1138
1139 if((hd = shost_priv(host)) == NULL)
1140 return;
1141
1142 mptscsih_shutdown(pdev);
1143
1144 sz1=0;
1145
1146 if (hd->ScsiLookup != NULL) {
1147 sz1 = ioc->req_depth * sizeof(void *);
1148 kfree(hd->ScsiLookup);
1149 hd->ScsiLookup = NULL;
1150 }
1151
1152 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1153 "Free'd ScsiLookup (%d) memory\n",
1154 ioc->name, sz1));
1155
1156 kfree(hd->info_kbuf);
1157
1158 /* NULL the Scsi_Host pointer
1159 */
1160 ioc->sh = NULL;
1161
1162 scsi_host_put(host);
1163
1164 mpt_detach(pdev);
1165
1166 }
1167
1168 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1169 /*
1170 * mptscsih_shutdown - reboot notifier
1171 *
1172 */
1173 void
1174 mptscsih_shutdown(struct pci_dev *pdev)
1175 {
1176 }
1177
1178 #ifdef CONFIG_PM
1179 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1180 /*
1181 * mptscsih_suspend - Fusion MPT scsi driver suspend routine.
1182 *
1183 *
1184 */
1185 int
1186 mptscsih_suspend(struct pci_dev *pdev, pm_message_t state)
1187 {
1188 mptscsih_shutdown(pdev);
1189 return mpt_suspend(pdev,state);
1190 }
1191
1192 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1193 /*
1194 * mptscsih_resume - Fusion MPT scsi driver resume routine.
1195 *
1196 *
1197 */
1198 int
1199 mptscsih_resume(struct pci_dev *pdev)
1200 {
1201 return mpt_resume(pdev);
1202 }
1203
1204 #endif
1205
1206 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1207 /**
1208 * mptscsih_info - Return information about MPT adapter
1209 * @SChost: Pointer to Scsi_Host structure
1210 *
1211 * (linux scsi_host_template.info routine)
1212 *
1213 * Returns pointer to buffer where information was written.
1214 */
1215 const char *
1216 mptscsih_info(struct Scsi_Host *SChost)
1217 {
1218 MPT_SCSI_HOST *h;
1219 int size = 0;
1220
1221 h = shost_priv(SChost);
1222
1223 if (h) {
1224 if (h->info_kbuf == NULL)
1225 if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL)
1226 return h->info_kbuf;
1227 h->info_kbuf[0] = '\0';
1228
1229 mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0);
1230 h->info_kbuf[size-1] = '\0';
1231 }
1232
1233 return h->info_kbuf;
1234 }
1235
1236 struct info_str {
1237 char *buffer;
1238 int length;
1239 int offset;
1240 int pos;
1241 };
1242
1243 static void
1244 mptscsih_copy_mem_info(struct info_str *info, char *data, int len)
1245 {
1246 if (info->pos + len > info->length)
1247 len = info->length - info->pos;
1248
1249 if (info->pos + len < info->offset) {
1250 info->pos += len;
1251 return;
1252 }
1253
1254 if (info->pos < info->offset) {
1255 data += (info->offset - info->pos);
1256 len -= (info->offset - info->pos);
1257 }
1258
1259 if (len > 0) {
1260 memcpy(info->buffer + info->pos, data, len);
1261 info->pos += len;
1262 }
1263 }
1264
1265 static int
1266 mptscsih_copy_info(struct info_str *info, char *fmt, ...)
1267 {
1268 va_list args;
1269 char buf[81];
1270 int len;
1271
1272 va_start(args, fmt);
1273 len = vsprintf(buf, fmt, args);
1274 va_end(args);
1275
1276 mptscsih_copy_mem_info(info, buf, len);
1277 return len;
1278 }
1279
1280 static int
1281 mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len)
1282 {
1283 struct info_str info;
1284
1285 info.buffer = pbuf;
1286 info.length = len;
1287 info.offset = offset;
1288 info.pos = 0;
1289
1290 mptscsih_copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name);
1291 mptscsih_copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word);
1292 mptscsih_copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts);
1293 mptscsih_copy_info(&info, "MaxQ=%d\n", ioc->req_depth);
1294
1295 return ((info.pos > info.offset) ? info.pos - info.offset : 0);
1296 }
1297
1298 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1299 /**
1300 * mptscsih_proc_info - Return information about MPT adapter
1301 * @host: scsi host struct
1302 * @buffer: if write, user data; if read, buffer for user
1303 * @start: returns the buffer address
1304 * @offset: if write, 0; if read, the current offset into the buffer from
1305 * the previous read.
1306 * @length: if write, return length;
1307 * @func: write = 1; read = 0
1308 *
1309 * (linux scsi_host_template.info routine)
1310 */
1311 int
1312 mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1313 int length, int func)
1314 {
1315 MPT_SCSI_HOST *hd = shost_priv(host);
1316 MPT_ADAPTER *ioc = hd->ioc;
1317 int size = 0;
1318
1319 if (func) {
1320 /*
1321 * write is not supported
1322 */
1323 } else {
1324 if (start)
1325 *start = buffer;
1326
1327 size = mptscsih_host_info(ioc, buffer, offset, length);
1328 }
1329
1330 return size;
1331 }
1332
1333 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1334 #define ADD_INDEX_LOG(req_ent) do { } while(0)
1335
1336 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1337 /**
1338 * mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine.
1339 * @SCpnt: Pointer to scsi_cmnd structure
1340 * @done: Pointer SCSI mid-layer IO completion function
1341 *
1342 * (linux scsi_host_template.queuecommand routine)
1343 * This is the primary SCSI IO start routine. Create a MPI SCSIIORequest
1344 * from a linux scsi_cmnd request and send it to the IOC.
1345 *
1346 * Returns 0. (rtn value discarded by linux scsi mid-layer)
1347 */
1348 int
1349 mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
1350 {
1351 MPT_SCSI_HOST *hd;
1352 MPT_FRAME_HDR *mf;
1353 SCSIIORequest_t *pScsiReq;
1354 VirtDevice *vdevice = SCpnt->device->hostdata;
1355 int lun;
1356 u32 datalen;
1357 u32 scsictl;
1358 u32 scsidir;
1359 u32 cmd_len;
1360 int my_idx;
1361 int ii;
1362 MPT_ADAPTER *ioc;
1363
1364 hd = shost_priv(SCpnt->device->host);
1365 ioc = hd->ioc;
1366 lun = SCpnt->device->lun;
1367 SCpnt->scsi_done = done;
1368
1369 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "qcmd: SCpnt=%p, done()=%p\n",
1370 ioc->name, SCpnt, done));
1371
1372 if (hd->resetPending) {
1373 dtmprintk(ioc, printk(MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n",
1374 ioc->name, SCpnt));
1375 return SCSI_MLQUEUE_HOST_BUSY;
1376 }
1377
1378 /*
1379 * Put together a MPT SCSI request...
1380 */
1381 if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) {
1382 dprintk(ioc, printk(MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n",
1383 ioc->name));
1384 return SCSI_MLQUEUE_HOST_BUSY;
1385 }
1386
1387 pScsiReq = (SCSIIORequest_t *) mf;
1388
1389 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
1390
1391 ADD_INDEX_LOG(my_idx);
1392
1393 /* TUR's being issued with scsictl=0x02000000 (DATA_IN)!
1394 * Seems we may receive a buffer (datalen>0) even when there
1395 * will be no data transfer! GRRRRR...
1396 */
1397 if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) {
1398 datalen = scsi_bufflen(SCpnt);
1399 scsidir = MPI_SCSIIO_CONTROL_READ; /* DATA IN (host<--ioc<--dev) */
1400 } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) {
1401 datalen = scsi_bufflen(SCpnt);
1402 scsidir = MPI_SCSIIO_CONTROL_WRITE; /* DATA OUT (host-->ioc-->dev) */
1403 } else {
1404 datalen = 0;
1405 scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER;
1406 }
1407
1408 /* Default to untagged. Once a target structure has been allocated,
1409 * use the Inquiry data to determine if device supports tagged.
1410 */
1411 if (vdevice
1412 && (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_Q_YES)
1413 && (SCpnt->device->tagged_supported)) {
1414 scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ;
1415 } else {
1416 scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED;
1417 }
1418
1419 /* Use the above information to set up the message frame
1420 */
1421 pScsiReq->TargetID = (u8) vdevice->vtarget->id;
1422 pScsiReq->Bus = vdevice->vtarget->channel;
1423 pScsiReq->ChainOffset = 0;
1424 if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
1425 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
1426 else
1427 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
1428 pScsiReq->CDBLength = SCpnt->cmd_len;
1429 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
1430 pScsiReq->Reserved = 0;
1431 pScsiReq->MsgFlags = mpt_msg_flags();
1432 int_to_scsilun(SCpnt->device->lun, (struct scsi_lun *)pScsiReq->LUN);
1433 pScsiReq->Control = cpu_to_le32(scsictl);
1434
1435 /*
1436 * Write SCSI CDB into the message
1437 */
1438 cmd_len = SCpnt->cmd_len;
1439 for (ii=0; ii < cmd_len; ii++)
1440 pScsiReq->CDB[ii] = SCpnt->cmnd[ii];
1441
1442 for (ii=cmd_len; ii < 16; ii++)
1443 pScsiReq->CDB[ii] = 0;
1444
1445 /* DataLength */
1446 pScsiReq->DataLength = cpu_to_le32(datalen);
1447
1448 /* SenseBuffer low address */
1449 pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma
1450 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
1451
1452 /* Now add the SG list
1453 * Always have a SGE even if null length.
1454 */
1455 if (datalen == 0) {
1456 /* Add a NULL SGE */
1457 mptscsih_add_sge((char *)&pScsiReq->SGL, MPT_SGE_FLAGS_SSIMPLE_READ | 0,
1458 (dma_addr_t) -1);
1459 } else {
1460 /* Add a 32 or 64 bit SGE */
1461 if (mptscsih_AddSGE(ioc, SCpnt, pScsiReq, my_idx) != SUCCESS)
1462 goto fail;
1463 }
1464
1465 SCpnt->host_scribble = (unsigned char *)mf;
1466 hd->ScsiLookup[my_idx] = SCpnt;
1467
1468 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf);
1469 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n",
1470 ioc->name, SCpnt, mf, my_idx));
1471 DBG_DUMP_REQUEST_FRAME(ioc, (u32 *)mf);
1472 return 0;
1473
1474 fail:
1475 hd->ScsiLookup[my_idx] = NULL;
1476 mptscsih_freeChainBuffers(ioc, my_idx);
1477 mpt_free_msg_frame(ioc, mf);
1478 return SCSI_MLQUEUE_HOST_BUSY;
1479 }
1480
1481 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1482 /*
1483 * mptscsih_freeChainBuffers - Function to free chain buffers associated
1484 * with a SCSI IO request
1485 * @hd: Pointer to the MPT_SCSI_HOST instance
1486 * @req_idx: Index of the SCSI IO request frame.
1487 *
1488 * Called if SG chain buffer allocation fails and mptscsih callbacks.
1489 * No return.
1490 */
1491 static void
1492 mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
1493 {
1494 MPT_FRAME_HDR *chain;
1495 unsigned long flags;
1496 int chain_idx;
1497 int next;
1498
1499 /* Get the first chain index and reset
1500 * tracker state.
1501 */
1502 chain_idx = ioc->ReqToChain[req_idx];
1503 ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN;
1504
1505 while (chain_idx != MPT_HOST_NO_CHAIN) {
1506
1507 /* Save the next chain buffer index */
1508 next = ioc->ChainToChain[chain_idx];
1509
1510 /* Free this chain buffer and reset
1511 * tracker
1512 */
1513 ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN;
1514
1515 chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer
1516 + (chain_idx * ioc->req_sz));
1517
1518 spin_lock_irqsave(&ioc->FreeQlock, flags);
1519 list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ);
1520 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1521
1522 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FreeChainBuffers (index %d)\n",
1523 ioc->name, chain_idx));
1524
1525 /* handle next */
1526 chain_idx = next;
1527 }
1528 return;
1529 }
1530
1531 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1532 /*
1533 * Reset Handling
1534 */
1535
1536 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1537 /**
1538 * mptscsih_TMHandler - Generic handler for SCSI Task Management.
1539 * @hd: Pointer to MPT SCSI HOST structure
1540 * @type: Task Management type
1541 * @channel: channel number for task management
1542 * @id: Logical Target ID for reset (if appropriate)
1543 * @lun: Logical Unit for reset (if appropriate)
1544 * @ctx2abort: Context for the task to be aborted (if appropriate)
1545 * @timeout: timeout for task management control
1546 *
1547 * Fall through to mpt_HardResetHandler if: not operational, too many
1548 * failed TM requests or handshake failure.
1549 *
1550 * Remark: Currently invoked from a non-interrupt thread (_bh).
1551 *
1552 * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
1553 * will be active.
1554 *
1555 * Returns 0 for SUCCESS, or %FAILED.
1556 **/
1557 int
1558 mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout)
1559 {
1560 MPT_ADAPTER *ioc;
1561 int rc = -1;
1562 u32 ioc_raw_state;
1563 unsigned long flags;
1564
1565 ioc = hd->ioc;
1566 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TMHandler Entered!\n", ioc->name));
1567
1568 // SJR - CHECKME - Can we avoid this here?
1569 // (mpt_HardResetHandler has this check...)
1570 spin_lock_irqsave(&ioc->diagLock, flags);
1571 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) {
1572 spin_unlock_irqrestore(&ioc->diagLock, flags);
1573 return FAILED;
1574 }
1575 spin_unlock_irqrestore(&ioc->diagLock, flags);
1576
1577 /* Wait a fixed amount of time for the TM pending flag to be cleared.
1578 * If we time out and not bus reset, then we return a FAILED status
1579 * to the caller.
1580 * The call to mptscsih_tm_pending_wait() will set the pending flag
1581 * if we are
1582 * successful. Otherwise, reload the FW.
1583 */
1584 if (mptscsih_tm_pending_wait(hd) == FAILED) {
1585 if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) {
1586 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TMHandler abort: "
1587 "Timed out waiting for last TM (%d) to complete! \n",
1588 ioc->name, hd->tmPending));
1589 return FAILED;
1590 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
1591 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TMHandler target "
1592 "reset: Timed out waiting for last TM (%d) "
1593 "to complete! \n", ioc->name,
1594 hd->tmPending));
1595 return FAILED;
1596 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
1597 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TMHandler bus reset: "
1598 "Timed out waiting for last TM (%d) to complete! \n",
1599 ioc->name, hd->tmPending));
1600 return FAILED;
1601 }
1602 } else {
1603 spin_lock_irqsave(&ioc->FreeQlock, flags);
1604 hd->tmPending |= (1 << type);
1605 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
1606 }
1607
1608 ioc_raw_state = mpt_GetIocState(ioc, 0);
1609
1610 if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
1611 printk(MYIOC_s_WARN_FMT
1612 "TM Handler for type=%x: IOC Not operational (0x%x)!\n",
1613 ioc->name, type, ioc_raw_state);
1614 printk(MYIOC_s_WARN_FMT " Issuing HardReset!!\n", ioc->name);
1615 if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0)
1616 printk(MYIOC_s_WARN_FMT "TMHandler: HardReset "
1617 "FAILED!!\n", ioc->name);
1618 return FAILED;
1619 }
1620
1621 if (ioc_raw_state & MPI_DOORBELL_ACTIVE) {
1622 printk(MYIOC_s_WARN_FMT
1623 "TM Handler for type=%x: ioc_state: "
1624 "DOORBELL_ACTIVE (0x%x)!\n",
1625 ioc->name, type, ioc_raw_state);
1626 return FAILED;
1627 }
1628
1629 /* Isse the Task Mgmt request.
1630 */
1631 if (hd->hard_resets < -1)
1632 hd->hard_resets++;
1633
1634 rc = mptscsih_IssueTaskMgmt(hd, type, channel, id, lun,
1635 ctx2abort, timeout);
1636 if (rc)
1637 printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n",
1638 ioc->name);
1639 else
1640 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Issue of TaskMgmt Successful!\n",
1641 ioc->name));
1642
1643 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1644 "TMHandler rc = %d!\n", ioc->name, rc));
1645
1646 return rc;
1647 }
1648
1649
1650 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1651 /**
1652 * mptscsih_IssueTaskMgmt - Generic send Task Management function.
1653 * @hd: Pointer to MPT_SCSI_HOST structure
1654 * @type: Task Management type
1655 * @channel: channel number for task management
1656 * @id: Logical Target ID for reset (if appropriate)
1657 * @lun: Logical Unit for reset (if appropriate)
1658 * @ctx2abort: Context for the task to be aborted (if appropriate)
1659 * @timeout: timeout for task management control
1660 *
1661 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
1662 * or a non-interrupt thread. In the former, must not call schedule().
1663 *
1664 * Not all fields are meaningfull for all task types.
1665 *
1666 * Returns 0 for SUCCESS, or FAILED.
1667 *
1668 **/
1669 static int
1670 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout)
1671 {
1672 MPT_FRAME_HDR *mf;
1673 SCSITaskMgmt_t *pScsiTm;
1674 int ii;
1675 int retval;
1676 MPT_ADAPTER *ioc = hd->ioc;
1677
1678 /* Return Fail to calling function if no message frames available.
1679 */
1680 if ((mf = mpt_get_msg_frame(ioc->TaskCtx, ioc)) == NULL) {
1681 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n",
1682 ioc->name));
1683 return FAILED;
1684 }
1685 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IssueTaskMgmt request @ %p\n",
1686 ioc->name, mf));
1687
1688 /* Format the Request
1689 */
1690 pScsiTm = (SCSITaskMgmt_t *) mf;
1691 pScsiTm->TargetID = id;
1692 pScsiTm->Bus = channel;
1693 pScsiTm->ChainOffset = 0;
1694 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
1695
1696 pScsiTm->Reserved = 0;
1697 pScsiTm->TaskType = type;
1698 pScsiTm->Reserved1 = 0;
1699 pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
1700 ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
1701
1702 int_to_scsilun(lun, (struct scsi_lun *)pScsiTm->LUN);
1703
1704 for (ii=0; ii < 7; ii++)
1705 pScsiTm->Reserved2[ii] = 0;
1706
1707 pScsiTm->TaskMsgContext = ctx2abort;
1708
1709 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IssueTaskMgmt: ctx2abort (0x%08x) "
1710 "type=%d\n", ioc->name, ctx2abort, type));
1711
1712 DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)pScsiTm);
1713
1714 if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) &&
1715 (ioc->facts.MsgVersion >= MPI_VERSION_01_05))
1716 mpt_put_msg_frame_hi_pri(ioc->TaskCtx, ioc, mf);
1717 else {
1718 retval = mpt_send_handshake_request(ioc->TaskCtx, ioc,
1719 sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP);
1720 if (retval) {
1721 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "send_handshake FAILED!"
1722 " (hd %p, ioc %p, mf %p, rc=%d) \n", ioc->name, hd,
1723 ioc, mf, retval));
1724 goto fail_out;
1725 }
1726 }
1727
1728 if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) {
1729 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "task management request TIMED OUT!"
1730 " (hd %p, ioc %p, mf %p) \n", ioc->name, hd,
1731 ioc, mf));
1732 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling HardReset! \n",
1733 ioc->name));
1734 retval = mpt_HardResetHandler(ioc, CAN_SLEEP);
1735 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "rc=%d \n",
1736 ioc->name, retval));
1737 goto fail_out;
1738 }
1739
1740 /*
1741 * Handle success case, see if theres a non-zero ioc_status.
1742 */
1743 if (hd->tm_iocstatus == MPI_IOCSTATUS_SUCCESS ||
1744 hd->tm_iocstatus == MPI_IOCSTATUS_SCSI_TASK_TERMINATED ||
1745 hd->tm_iocstatus == MPI_IOCSTATUS_SCSI_IOC_TERMINATED)
1746 retval = 0;
1747 else
1748 retval = FAILED;
1749
1750 return retval;
1751
1752 fail_out:
1753
1754 /*
1755 * Free task managment mf, and corresponding tm flags
1756 */
1757 mpt_free_msg_frame(ioc, mf);
1758 hd->tmPending = 0;
1759 hd->tmState = TM_STATE_NONE;
1760 return FAILED;
1761 }
1762
1763 static int
1764 mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
1765 {
1766 switch (ioc->bus_type) {
1767 case FC:
1768 return 40;
1769 case SAS:
1770 return 10;
1771 case SPI:
1772 default:
1773 return 2;
1774 }
1775 }
1776
1777 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1778 /**
1779 * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant
1780 * @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted
1781 *
1782 * (linux scsi_host_template.eh_abort_handler routine)
1783 *
1784 * Returns SUCCESS or FAILED.
1785 **/
1786 int
1787 mptscsih_abort(struct scsi_cmnd * SCpnt)
1788 {
1789 MPT_SCSI_HOST *hd;
1790 MPT_FRAME_HDR *mf;
1791 u32 ctx2abort;
1792 int scpnt_idx;
1793 int retval;
1794 VirtDevice *vdevice;
1795 ulong sn = SCpnt->serial_number;
1796 MPT_ADAPTER *ioc;
1797
1798 /* If we can't locate our host adapter structure, return FAILED status.
1799 */
1800 if ((hd = shost_priv(SCpnt->device->host)) == NULL) {
1801 SCpnt->result = DID_RESET << 16;
1802 SCpnt->scsi_done(SCpnt);
1803 printk(KERN_ERR MYNAM ": task abort: "
1804 "can't locate host! (sc=%p)\n", SCpnt);
1805 return FAILED;
1806 }
1807
1808 ioc = hd->ioc;
1809 printk(MYIOC_s_INFO_FMT "attempting task abort! (sc=%p)\n",
1810 ioc->name, SCpnt);
1811 scsi_print_command(SCpnt);
1812
1813 vdevice = SCpnt->device->hostdata;
1814 if (!vdevice || !vdevice->vtarget) {
1815 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1816 "task abort: device has been deleted (sc=%p)\n",
1817 ioc->name, SCpnt));
1818 SCpnt->result = DID_NO_CONNECT << 16;
1819 SCpnt->scsi_done(SCpnt);
1820 retval = 0;
1821 goto out;
1822 }
1823
1824 /* Task aborts are not supported for hidden raid components.
1825 */
1826 if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
1827 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1828 "task abort: hidden raid component (sc=%p)\n",
1829 ioc->name, SCpnt));
1830 SCpnt->result = DID_RESET << 16;
1831 retval = FAILED;
1832 goto out;
1833 }
1834
1835 /* Find this command
1836 */
1837 if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
1838 /* Cmd not found in ScsiLookup.
1839 * Do OS callback.
1840 */
1841 SCpnt->result = DID_RESET << 16;
1842 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "task abort: "
1843 "Command not in the active list! (sc=%p)\n", ioc->name,
1844 SCpnt));
1845 retval = 0;
1846 goto out;
1847 }
1848
1849 if (hd->resetPending) {
1850 retval = FAILED;
1851 goto out;
1852 }
1853
1854 if (hd->timeouts < -1)
1855 hd->timeouts++;
1856
1857 /* Most important! Set TaskMsgContext to SCpnt's MsgContext!
1858 * (the IO to be ABORT'd)
1859 *
1860 * NOTE: Since we do not byteswap MsgContext, we do not
1861 * swap it here either. It is an opaque cookie to
1862 * the controller, so it does not matter. -DaveM
1863 */
1864 mf = MPT_INDEX_2_MFPTR(ioc, scpnt_idx);
1865 ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
1866
1867 hd->abortSCpnt = SCpnt;
1868
1869 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1870 vdevice->vtarget->channel, vdevice->vtarget->id, vdevice->lun,
1871 ctx2abort, mptscsih_get_tm_timeout(ioc));
1872
1873 if (SCPNT_TO_LOOKUP_IDX(SCpnt) == scpnt_idx &&
1874 SCpnt->serial_number == sn)
1875 retval = FAILED;
1876
1877 out:
1878 printk(MYIOC_s_INFO_FMT "task abort: %s (sc=%p)\n",
1879 ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1880
1881 if (retval == 0)
1882 return SUCCESS;
1883 else
1884 return FAILED;
1885 }
1886
1887 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1888 /**
1889 * mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant
1890 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1891 *
1892 * (linux scsi_host_template.eh_dev_reset_handler routine)
1893 *
1894 * Returns SUCCESS or FAILED.
1895 **/
1896 int
1897 mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
1898 {
1899 MPT_SCSI_HOST *hd;
1900 int retval;
1901 VirtDevice *vdevice;
1902 MPT_ADAPTER *ioc;
1903
1904 /* If we can't locate our host adapter structure, return FAILED status.
1905 */
1906 if ((hd = shost_priv(SCpnt->device->host)) == NULL){
1907 printk(KERN_ERR MYNAM ": target reset: "
1908 "Can't locate host! (sc=%p)\n", SCpnt);
1909 return FAILED;
1910 }
1911
1912 ioc = hd->ioc;
1913 printk(MYIOC_s_INFO_FMT "attempting target reset! (sc=%p)\n",
1914 ioc->name, SCpnt);
1915 scsi_print_command(SCpnt);
1916
1917 if (hd->resetPending) {
1918 retval = FAILED;
1919 goto out;
1920 }
1921
1922 vdevice = SCpnt->device->hostdata;
1923 if (!vdevice || !vdevice->vtarget) {
1924 retval = 0;
1925 goto out;
1926 }
1927
1928 /* Target reset to hidden raid component is not supported
1929 */
1930 if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT) {
1931 retval = FAILED;
1932 goto out;
1933 }
1934
1935 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
1936 vdevice->vtarget->channel, vdevice->vtarget->id, 0, 0,
1937 mptscsih_get_tm_timeout(ioc));
1938
1939 out:
1940 printk (MYIOC_s_INFO_FMT "target reset: %s (sc=%p)\n",
1941 ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1942
1943 if (retval == 0)
1944 return SUCCESS;
1945 else
1946 return FAILED;
1947 }
1948
1949
1950 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1951 /**
1952 * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
1953 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
1954 *
1955 * (linux scsi_host_template.eh_bus_reset_handler routine)
1956 *
1957 * Returns SUCCESS or FAILED.
1958 **/
1959 int
1960 mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
1961 {
1962 MPT_SCSI_HOST *hd;
1963 int retval;
1964 VirtDevice *vdevice;
1965 MPT_ADAPTER *ioc;
1966
1967 /* If we can't locate our host adapter structure, return FAILED status.
1968 */
1969 if ((hd = shost_priv(SCpnt->device->host)) == NULL){
1970 printk(KERN_ERR MYNAM ": bus reset: "
1971 "Can't locate host! (sc=%p)\n", SCpnt);
1972 return FAILED;
1973 }
1974
1975 ioc = hd->ioc;
1976 printk(MYIOC_s_INFO_FMT "attempting bus reset! (sc=%p)\n",
1977 ioc->name, SCpnt);
1978 scsi_print_command(SCpnt);
1979
1980 if (hd->timeouts < -1)
1981 hd->timeouts++;
1982
1983 vdevice = SCpnt->device->hostdata;
1984 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
1985 vdevice->vtarget->channel, 0, 0, 0, mptscsih_get_tm_timeout(ioc));
1986
1987 printk(MYIOC_s_INFO_FMT "bus reset: %s (sc=%p)\n",
1988 ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
1989
1990 if (retval == 0)
1991 return SUCCESS;
1992 else
1993 return FAILED;
1994 }
1995
1996 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1997 /**
1998 * mptscsih_host_reset - Perform a SCSI host adapter RESET (new_eh variant)
1999 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to
2000 *
2001 * (linux scsi_host_template.eh_host_reset_handler routine)
2002 *
2003 * Returns SUCCESS or FAILED.
2004 */
2005 int
2006 mptscsih_host_reset(struct scsi_cmnd *SCpnt)
2007 {
2008 MPT_SCSI_HOST * hd;
2009 int retval;
2010 MPT_ADAPTER *ioc;
2011
2012 /* If we can't locate the host to reset, then we failed. */
2013 if ((hd = shost_priv(SCpnt->device->host)) == NULL){
2014 printk(KERN_ERR MYNAM ": host reset: "
2015 "Can't locate host! (sc=%p)\n", SCpnt);
2016 return FAILED;
2017 }
2018
2019 ioc = hd->ioc;
2020 printk(MYIOC_s_INFO_FMT "attempting host reset! (sc=%p)\n",
2021 ioc->name, SCpnt);
2022
2023 /* If our attempts to reset the host failed, then return a failed
2024 * status. The host will be taken off line by the SCSI mid-layer.
2025 */
2026 if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0) {
2027 retval = FAILED;
2028 } else {
2029 /* Make sure TM pending is cleared and TM state is set to
2030 * NONE.
2031 */
2032 retval = 0;
2033 hd->tmPending = 0;
2034 hd->tmState = TM_STATE_NONE;
2035 }
2036
2037 printk(MYIOC_s_INFO_FMT "host reset: %s (sc=%p)\n",
2038 ioc->name, ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt);
2039
2040 return retval;
2041 }
2042
2043 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2044 /**
2045 * mptscsih_tm_pending_wait - wait for pending task management request to complete
2046 * @hd: Pointer to MPT host structure.
2047 *
2048 * Returns {SUCCESS,FAILED}.
2049 */
2050 static int
2051 mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
2052 {
2053 unsigned long flags;
2054 int loop_count = 4 * 10; /* Wait 10 seconds */
2055 int status = FAILED;
2056 MPT_ADAPTER *ioc = hd->ioc;
2057
2058 do {
2059 spin_lock_irqsave(&ioc->FreeQlock, flags);
2060 if (hd->tmState == TM_STATE_NONE) {
2061 hd->tmState = TM_STATE_IN_PROGRESS;
2062 hd->tmPending = 1;
2063 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2064 status = SUCCESS;
2065 break;
2066 }
2067 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2068 msleep(250);
2069 } while (--loop_count);
2070
2071 return status;
2072 }
2073
2074 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2075 /**
2076 * mptscsih_tm_wait_for_completion - wait for completion of TM task
2077 * @hd: Pointer to MPT host structure.
2078 * @timeout: timeout value
2079 *
2080 * Returns {SUCCESS,FAILED}.
2081 */
2082 static int
2083 mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
2084 {
2085 unsigned long flags;
2086 int loop_count = 4 * timeout;
2087 int status = FAILED;
2088 MPT_ADAPTER *ioc = hd->ioc;
2089
2090 do {
2091 spin_lock_irqsave(&ioc->FreeQlock, flags);
2092 if(hd->tmPending == 0) {
2093 status = SUCCESS;
2094 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2095 break;
2096 }
2097 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2098 msleep(250);
2099 } while (--loop_count);
2100
2101 return status;
2102 }
2103
2104 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2105 static void
2106 mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
2107 {
2108 char *desc;
2109
2110 switch (response_code) {
2111 case MPI_SCSITASKMGMT_RSP_TM_COMPLETE:
2112 desc = "The task completed.";
2113 break;
2114 case MPI_SCSITASKMGMT_RSP_INVALID_FRAME:
2115 desc = "The IOC received an invalid frame status.";
2116 break;
2117 case MPI_SCSITASKMGMT_RSP_TM_NOT_SUPPORTED:
2118 desc = "The task type is not supported.";
2119 break;
2120 case MPI_SCSITASKMGMT_RSP_TM_FAILED:
2121 desc = "The requested task failed.";
2122 break;
2123 case MPI_SCSITASKMGMT_RSP_TM_SUCCEEDED:
2124 desc = "The task completed successfully.";
2125 break;
2126 case MPI_SCSITASKMGMT_RSP_TM_INVALID_LUN:
2127 desc = "The LUN request is invalid.";
2128 break;
2129 case MPI_SCSITASKMGMT_RSP_IO_QUEUED_ON_IOC:
2130 desc = "The task is in the IOC queue and has not been sent to target.";
2131 break;
2132 default:
2133 desc = "unknown";
2134 break;
2135 }
2136 printk(MYIOC_s_INFO_FMT "Response Code(0x%08x): F/W: %s\n",
2137 ioc->name, response_code, desc);
2138 }
2139
2140 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2141 /**
2142 * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
2143 * @ioc: Pointer to MPT_ADAPTER structure
2144 * @mf: Pointer to SCSI task mgmt request frame
2145 * @mr: Pointer to SCSI task mgmt reply frame
2146 *
2147 * This routine is called from mptbase.c::mpt_interrupt() at the completion
2148 * of any SCSI task management request.
2149 * This routine is registered with the MPT (base) driver at driver
2150 * load/init time via the mpt_register() API call.
2151 *
2152 * Returns 1 indicating alloc'd request frame ptr should be freed.
2153 **/
2154 int
2155 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2156 {
2157 SCSITaskMgmtReply_t *pScsiTmReply;
2158 SCSITaskMgmt_t *pScsiTmReq;
2159 MPT_SCSI_HOST *hd;
2160 unsigned long flags;
2161 u16 iocstatus;
2162 u8 tmType;
2163 u32 termination_count;
2164
2165 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
2166 ioc->name, mf, mr));
2167 if (!ioc->sh) {
2168 dtmprintk(ioc, printk(MYIOC_s_WARN_FMT
2169 "TaskMgmt Complete: NULL Scsi Host Ptr\n", ioc->name));
2170 return 1;
2171 }
2172
2173 if (mr == NULL) {
2174 dtmprintk(ioc, printk(MYIOC_s_WARN_FMT
2175 "ERROR! TaskMgmt Reply: NULL Request %p\n", ioc->name, mf));
2176 return 1;
2177 }
2178
2179 hd = shost_priv(ioc->sh);
2180 pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
2181 pScsiTmReq = (SCSITaskMgmt_t*)mf;
2182 tmType = pScsiTmReq->TaskType;
2183 iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2184 termination_count = le32_to_cpu(pScsiTmReply->TerminationCount);
2185
2186 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
2187 pScsiTmReply->ResponseCode)
2188 mptscsih_taskmgmt_response_code(ioc,
2189 pScsiTmReply->ResponseCode);
2190 DBG_DUMP_TM_REPLY_FRAME(ioc, (u32 *)pScsiTmReply);
2191
2192 #ifdef CONFIG_FUSION_LOGGING
2193 if ((ioc->debug_level & MPT_DEBUG_REPLY) ||
2194 (ioc->debug_level & MPT_DEBUG_TM ))
2195 printk("%s: ha=%d [%d:%d:0] task_type=0x%02X "
2196 "iocstatus=0x%04X\n\tloginfo=0x%08X response_code=0x%02X "
2197 "term_cmnds=%d\n", __FUNCTION__, ioc->id, pScsiTmReply->Bus,
2198 pScsiTmReply->TargetID, pScsiTmReq->TaskType,
2199 le16_to_cpu(pScsiTmReply->IOCStatus),
2200 le32_to_cpu(pScsiTmReply->IOCLogInfo),pScsiTmReply->ResponseCode,
2201 le32_to_cpu(pScsiTmReply->TerminationCount));
2202 #endif
2203 if (!iocstatus) {
2204 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT " TaskMgmt SUCCESS\n", ioc->name));
2205 hd->abortSCpnt = NULL;
2206 goto out;
2207 }
2208
2209 /* Error? (anything non-zero?) */
2210
2211 /* clear flags and continue.
2212 */
2213 switch (tmType) {
2214
2215 case MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK:
2216 if (termination_count == 1)
2217 iocstatus = MPI_IOCSTATUS_SCSI_TASK_TERMINATED;
2218 hd->abortSCpnt = NULL;
2219 break;
2220
2221 case MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS:
2222
2223 /* If an internal command is present
2224 * or the TM failed - reload the FW.
2225 * FC FW may respond FAILED to an ABORT
2226 */
2227 if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED ||
2228 hd->cmdPtr)
2229 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
2230 printk(MYIOC_s_WARN_FMT " Firmware Reload FAILED!!\n", ioc->name);
2231 break;
2232
2233 case MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
2234 default:
2235 break;
2236 }
2237
2238 out:
2239 spin_lock_irqsave(&ioc->FreeQlock, flags);
2240 hd->tmPending = 0;
2241 hd->tmState = TM_STATE_NONE;
2242 hd->tm_iocstatus = iocstatus;
2243 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2244
2245 return 1;
2246 }
2247
2248 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2249 /*
2250 * This is anyones guess quite frankly.
2251 */
2252 int
2253 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev,
2254 sector_t capacity, int geom[])
2255 {
2256 int heads;
2257 int sectors;
2258 sector_t cylinders;
2259 ulong dummy;
2260
2261 heads = 64;
2262 sectors = 32;
2263
2264 dummy = heads * sectors;
2265 cylinders = capacity;
2266 sector_div(cylinders,dummy);
2267
2268 /*
2269 * Handle extended translation size for logical drives
2270 * > 1Gb
2271 */
2272 if ((ulong)capacity >= 0x200000) {
2273 heads = 255;
2274 sectors = 63;
2275 dummy = heads * sectors;
2276 cylinders = capacity;
2277 sector_div(cylinders,dummy);
2278 }
2279
2280 /* return result */
2281 geom[0] = heads;
2282 geom[1] = sectors;
2283 geom[2] = cylinders;
2284
2285 return 0;
2286 }
2287
2288 /* Search IOC page 3 to determine if this is hidden physical disk
2289 *
2290 */
2291 int
2292 mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id)
2293 {
2294 struct inactive_raid_component_info *component_info;
2295 int i;
2296 int rc = 0;
2297
2298 if (!ioc->raid_data.pIocPg3)
2299 goto out;
2300 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2301 if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2302 (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2303 rc = 1;
2304 goto out;
2305 }
2306 }
2307
2308 /*
2309 * Check inactive list for matching phys disks
2310 */
2311 if (list_empty(&ioc->raid_data.inactive_list))
2312 goto out;
2313
2314 down(&ioc->raid_data.inactive_list_mutex);
2315 list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2316 list) {
2317 if ((component_info->d.PhysDiskID == id) &&
2318 (component_info->d.PhysDiskBus == channel))
2319 rc = 1;
2320 }
2321 up(&ioc->raid_data.inactive_list_mutex);
2322
2323 out:
2324 return rc;
2325 }
2326 EXPORT_SYMBOL(mptscsih_is_phys_disk);
2327
2328 u8
2329 mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
2330 {
2331 struct inactive_raid_component_info *component_info;
2332 int i;
2333 int rc = -ENXIO;
2334
2335 if (!ioc->raid_data.pIocPg3)
2336 goto out;
2337 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) {
2338 if ((id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) &&
2339 (channel == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskBus)) {
2340 rc = ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskNum;
2341 goto out;
2342 }
2343 }
2344
2345 /*
2346 * Check inactive list for matching phys disks
2347 */
2348 if (list_empty(&ioc->raid_data.inactive_list))
2349 goto out;
2350
2351 down(&ioc->raid_data.inactive_list_mutex);
2352 list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
2353 list) {
2354 if ((component_info->d.PhysDiskID == id) &&
2355 (component_info->d.PhysDiskBus == channel))
2356 rc = component_info->d.PhysDiskNum;
2357 }
2358 up(&ioc->raid_data.inactive_list_mutex);
2359
2360 out:
2361 return rc;
2362 }
2363 EXPORT_SYMBOL(mptscsih_raid_id_to_num);
2364
2365 /*
2366 * OS entry point to allow for host driver to free allocated memory
2367 * Called if no device present or device being unloaded
2368 */
2369 void
2370 mptscsih_slave_destroy(struct scsi_device *sdev)
2371 {
2372 struct Scsi_Host *host = sdev->host;
2373 MPT_SCSI_HOST *hd = shost_priv(host);
2374 VirtTarget *vtarget;
2375 VirtDevice *vdevice;
2376 struct scsi_target *starget;
2377
2378 starget = scsi_target(sdev);
2379 vtarget = starget->hostdata;
2380 vdevice = sdev->hostdata;
2381
2382 mptscsih_search_running_cmds(hd, vdevice);
2383 vtarget->num_luns--;
2384 mptscsih_synchronize_cache(hd, vdevice);
2385 kfree(vdevice);
2386 sdev->hostdata = NULL;
2387 }
2388
2389 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2390 /*
2391 * mptscsih_change_queue_depth - This function will set a devices queue depth
2392 * @sdev: per scsi_device pointer
2393 * @qdepth: requested queue depth
2394 *
2395 * Adding support for new 'change_queue_depth' api.
2396 */
2397 int
2398 mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth)
2399 {
2400 MPT_SCSI_HOST *hd = shost_priv(sdev->host);
2401 VirtTarget *vtarget;
2402 struct scsi_target *starget;
2403 int max_depth;
2404 int tagged;
2405 MPT_ADAPTER *ioc = hd->ioc;
2406
2407 starget = scsi_target(sdev);
2408 vtarget = starget->hostdata;
2409
2410 if (ioc->bus_type == SPI) {
2411 if (!(vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
2412 max_depth = 1;
2413 else if (sdev->type == TYPE_DISK &&
2414 vtarget->minSyncFactor <= MPT_ULTRA160)
2415 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2416 else
2417 max_depth = MPT_SCSI_CMD_PER_DEV_LOW;
2418 } else
2419 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH;
2420
2421 if (qdepth > max_depth)
2422 qdepth = max_depth;
2423 if (qdepth == 1)
2424 tagged = 0;
2425 else
2426 tagged = MSG_SIMPLE_TAG;
2427
2428 scsi_adjust_queue_depth(sdev, tagged, qdepth);
2429 return sdev->queue_depth;
2430 }
2431
2432 /*
2433 * OS entry point to adjust the queue_depths on a per-device basis.
2434 * Called once per device the bus scan. Use it to force the queue_depth
2435 * member to 1 if a device does not support Q tags.
2436 * Return non-zero if fails.
2437 */
2438 int
2439 mptscsih_slave_configure(struct scsi_device *sdev)
2440 {
2441 struct Scsi_Host *sh = sdev->host;
2442 VirtTarget *vtarget;
2443 VirtDevice *vdevice;
2444 struct scsi_target *starget;
2445 MPT_SCSI_HOST *hd = shost_priv(sh);
2446 MPT_ADAPTER *ioc = hd->ioc;
2447
2448 starget = scsi_target(sdev);
2449 vtarget = starget->hostdata;
2450 vdevice = sdev->hostdata;
2451
2452 dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2453 "device @ %p, channel=%d, id=%d, lun=%d\n",
2454 ioc->name, sdev, sdev->channel, sdev->id, sdev->lun));
2455 if (ioc->bus_type == SPI)
2456 dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2457 "sdtr %d wdtr %d ppr %d inq length=%d\n",
2458 ioc->name, sdev->sdtr, sdev->wdtr,
2459 sdev->ppr, sdev->inquiry_len));
2460
2461 if (sdev->id > sh->max_id) {
2462 /* error case, should never happen */
2463 scsi_adjust_queue_depth(sdev, 0, 1);
2464 goto slave_configure_exit;
2465 }
2466
2467 vdevice->configured_lun = 1;
2468 mptscsih_change_queue_depth(sdev, MPT_SCSI_CMD_PER_DEV_HIGH);
2469
2470 dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2471 "Queue depth=%d, tflags=%x\n",
2472 ioc->name, sdev->queue_depth, vtarget->tflags));
2473
2474 if (ioc->bus_type == SPI)
2475 dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2476 "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n",
2477 ioc->name, vtarget->negoFlags, vtarget->maxOffset,
2478 vtarget->minSyncFactor));
2479
2480 slave_configure_exit:
2481
2482 dsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2483 "tagged %d, simple %d, ordered %d\n",
2484 ioc->name,sdev->tagged_supported, sdev->simple_tags,
2485 sdev->ordered_tags));
2486
2487 return 0;
2488 }
2489
2490 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2491 /*
2492 * Private routines...
2493 */
2494
2495 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2496 /* Utility function to copy sense data from the scsi_cmnd buffer
2497 * to the FC and SCSI target structures.
2498 *
2499 */
2500 static void
2501 mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply)
2502 {
2503 VirtDevice *vdevice;
2504 SCSIIORequest_t *pReq;
2505 u32 sense_count = le32_to_cpu(pScsiReply->SenseCount);
2506 MPT_ADAPTER *ioc = hd->ioc;
2507
2508 /* Get target structure
2509 */
2510 pReq = (SCSIIORequest_t *) mf;
2511 vdevice = sc->device->hostdata;
2512
2513 if (sense_count) {
2514 u8 *sense_data;
2515 int req_index;
2516
2517 /* Copy the sense received into the scsi command block. */
2518 req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2519 sense_data = ((u8 *)ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
2520 memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc));
2521
2522 /* Log SMART data (asc = 0x5D, non-IM case only) if required.
2523 */
2524 if ((ioc->events) && (ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) {
2525 if ((sense_data[12] == 0x5D) && (vdevice->vtarget->raidVolume == 0)) {
2526 int idx;
2527
2528 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
2529 ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE;
2530 ioc->events[idx].eventContext = ioc->eventContext;
2531
2532 ioc->events[idx].data[0] = (pReq->LUN[1] << 24) |
2533 (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) |
2534 (sc->device->channel << 8) | sc->device->id;
2535
2536 ioc->events[idx].data[1] = (sense_data[13] << 8) | sense_data[12];
2537
2538 ioc->eventContext++;
2539 if (ioc->pcidev->vendor ==
2540 PCI_VENDOR_ID_IBM) {
2541 mptscsih_issue_sep_command(ioc,
2542 vdevice->vtarget, MPI_SEP_REQ_SLOTSTATUS_PREDICTED_FAULT);
2543 vdevice->vtarget->tflags |=
2544 MPT_TARGET_FLAGS_LED_ON;
2545 }
2546 }
2547 }
2548 } else {
2549 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Hmmm... SenseData len=0! (?)\n",
2550 ioc->name));
2551 }
2552 }
2553
2554 static int
2555 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc)
2556 {
2557 MPT_SCSI_HOST *hd;
2558 int i;
2559
2560 hd = shost_priv(sc->device->host);
2561
2562 for (i = 0; i < hd->ioc->req_depth; i++) {
2563 if (hd->ScsiLookup[i] == sc) {
2564 return i;
2565 }
2566 }
2567
2568 return -1;
2569 }
2570
2571 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2572 int
2573 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2574 {
2575 MPT_SCSI_HOST *hd;
2576 unsigned long flags;
2577 int ii;
2578
2579 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2580 ": IOC %s_reset routed to SCSI host driver!\n",
2581 ioc->name, reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
2582 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
2583
2584 /* If a FW reload request arrives after base installed but
2585 * before all scsi hosts have been attached, then an alt_ioc
2586 * may have a NULL sh pointer.
2587 */
2588 if (ioc->sh == NULL || shost_priv(ioc->sh) == NULL)
2589 return 0;
2590 else
2591 hd = shost_priv(ioc->sh);
2592
2593 if (reset_phase == MPT_IOC_SETUP_RESET) {
2594 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Setup-Diag Reset\n", ioc->name));
2595
2596 /* Clean Up:
2597 * 1. Set Hard Reset Pending Flag
2598 * All new commands go to doneQ
2599 */
2600 hd->resetPending = 1;
2601
2602 } else if (reset_phase == MPT_IOC_PRE_RESET) {
2603 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Pre-Diag Reset\n", ioc->name));
2604
2605 /* 2. Flush running commands
2606 * Clean ScsiLookup (and associated memory)
2607 * AND clean mytaskQ
2608 */
2609
2610 /* 2b. Reply to OS all known outstanding I/O commands.
2611 */
2612 mptscsih_flush_running_cmds(hd);
2613
2614 /* 2c. If there was an internal command that
2615 * has not completed, configuration or io request,
2616 * free these resources.
2617 */
2618 if (hd->cmdPtr) {
2619 del_timer(&hd->timer);
2620 mpt_free_msg_frame(ioc, hd->cmdPtr);
2621 }
2622
2623 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Pre-Reset complete.\n", ioc->name));
2624
2625 } else {
2626 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Post-Diag Reset\n", ioc->name));
2627
2628 /* Once a FW reload begins, all new OS commands are
2629 * redirected to the doneQ w/ a reset status.
2630 * Init all control structures.
2631 */
2632
2633 /* ScsiLookup initialization
2634 */
2635 for (ii=0; ii < ioc->req_depth; ii++)
2636 hd->ScsiLookup[ii] = NULL;
2637
2638 /* 2. Chain Buffer initialization
2639 */
2640
2641 /* 4. Renegotiate to all devices, if SPI
2642 */
2643
2644 /* 5. Enable new commands to be posted
2645 */
2646 spin_lock_irqsave(&ioc->FreeQlock, flags);
2647 hd->tmPending = 0;
2648 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
2649 hd->resetPending = 0;
2650 hd->tmState = TM_STATE_NONE;
2651
2652 /* 6. If there was an internal command,
2653 * wake this process up.
2654 */
2655 if (hd->cmdPtr) {
2656 /*
2657 * Wake up the original calling thread
2658 */
2659 hd->pLocal = &hd->localReply;
2660 hd->pLocal->completion = MPT_SCANDV_DID_RESET;
2661 hd->scandv_wait_done = 1;
2662 wake_up(&hd->scandv_waitq);
2663 hd->cmdPtr = NULL;
2664 }
2665
2666 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Post-Reset complete.\n", ioc->name));
2667
2668 }
2669
2670 return 1; /* currently means nothing really */
2671 }
2672
2673 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2674 int
2675 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2676 {
2677 MPT_SCSI_HOST *hd;
2678 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2679
2680 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
2681 ioc->name, event));
2682
2683 if (ioc->sh == NULL ||
2684 ((hd = shost_priv(ioc->sh)) == NULL))
2685 return 1;
2686
2687 switch (event) {
2688 case MPI_EVENT_UNIT_ATTENTION: /* 03 */
2689 /* FIXME! */
2690 break;
2691 case MPI_EVENT_IOC_BUS_RESET: /* 04 */
2692 case MPI_EVENT_EXT_BUS_RESET: /* 05 */
2693 if (hd && (ioc->bus_type == SPI) && (hd->soft_resets < -1))
2694 hd->soft_resets++;
2695 break;
2696 case MPI_EVENT_LOGOUT: /* 09 */
2697 /* FIXME! */
2698 break;
2699
2700 case MPI_EVENT_RESCAN: /* 06 */
2701 break;
2702
2703 /*
2704 * CHECKME! Don't think we need to do
2705 * anything for these, but...
2706 */
2707 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */
2708 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */
2709 /*
2710 * CHECKME! Falling thru...
2711 */
2712 break;
2713
2714 case MPI_EVENT_INTEGRATED_RAID: /* 0B */
2715 break;
2716
2717 case MPI_EVENT_NONE: /* 00 */
2718 case MPI_EVENT_LOG_DATA: /* 01 */
2719 case MPI_EVENT_STATE_CHANGE: /* 02 */
2720 case MPI_EVENT_EVENT_CHANGE: /* 0A */
2721 default:
2722 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": Ignoring event (=%02Xh)\n",
2723 ioc->name, event));
2724 break;
2725 }
2726
2727 return 1; /* currently means nothing really */
2728 }
2729
2730 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2731 /*
2732 * Bus Scan and Domain Validation functionality ...
2733 */
2734
2735 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2736 /*
2737 * mptscsih_scandv_complete - Scan and DV callback routine registered
2738 * to Fustion MPT (base) driver.
2739 *
2740 * @ioc: Pointer to MPT_ADAPTER structure
2741 * @mf: Pointer to original MPT request frame
2742 * @mr: Pointer to MPT reply frame (NULL if TurboReply)
2743 *
2744 * This routine is called from mpt.c::mpt_interrupt() at the completion
2745 * of any SCSI IO request.
2746 * This routine is registered with the Fusion MPT (base) driver at driver
2747 * load/init time via the mpt_register() API call.
2748 *
2749 * Returns 1 indicating alloc'd request frame ptr should be freed.
2750 *
2751 * Remark: Sets a completion code and (possibly) saves sense data
2752 * in the IOC member localReply structure.
2753 * Used ONLY for DV and other internal commands.
2754 */
2755 int
2756 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
2757 {
2758 MPT_SCSI_HOST *hd;
2759 SCSIIORequest_t *pReq;
2760 int completionCode;
2761 u16 req_idx;
2762
2763 hd = shost_priv(ioc->sh);
2764
2765 if ((mf == NULL) ||
2766 (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) {
2767 printk(MYIOC_s_ERR_FMT
2768 "ScanDvComplete, %s req frame ptr! (=%p)\n",
2769 ioc->name, mf?"BAD":"NULL", (void *) mf);
2770 goto wakeup;
2771 }
2772
2773 del_timer(&hd->timer);
2774 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
2775 hd->ScsiLookup[req_idx] = NULL;
2776 pReq = (SCSIIORequest_t *) mf;
2777
2778 if (mf != hd->cmdPtr) {
2779 printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n",
2780 ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx);
2781 }
2782 hd->cmdPtr = NULL;
2783
2784 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n",
2785 ioc->name, mf, mr, req_idx));
2786
2787 hd->pLocal = &hd->localReply;
2788 hd->pLocal->scsiStatus = 0;
2789
2790 /* If target struct exists, clear sense valid flag.
2791 */
2792 if (mr == NULL) {
2793 completionCode = MPT_SCANDV_GOOD;
2794 } else {
2795 SCSIIOReply_t *pReply;
2796 u16 status;
2797 u8 scsi_status;
2798
2799 pReply = (SCSIIOReply_t *) mr;
2800
2801 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
2802 scsi_status = pReply->SCSIStatus;
2803
2804
2805 switch(status) {
2806
2807 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
2808 completionCode = MPT_SCANDV_SELECTION_TIMEOUT;
2809 break;
2810
2811 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
2812 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
2813 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
2814 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
2815 completionCode = MPT_SCANDV_DID_RESET;
2816 break;
2817
2818 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
2819 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
2820 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */
2821 if (pReply->Function == MPI_FUNCTION_CONFIG) {
2822 ConfigReply_t *pr = (ConfigReply_t *)mr;
2823 completionCode = MPT_SCANDV_GOOD;
2824 hd->pLocal->header.PageVersion = pr->Header.PageVersion;
2825 hd->pLocal->header.PageLength = pr->Header.PageLength;
2826 hd->pLocal->header.PageNumber = pr->Header.PageNumber;
2827 hd->pLocal->header.PageType = pr->Header.PageType;
2828
2829 } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) {
2830 /* If the RAID Volume request is successful,
2831 * return GOOD, else indicate that
2832 * some type of error occurred.
2833 */
2834 MpiRaidActionReply_t *pr = (MpiRaidActionReply_t *)mr;
2835 if (le16_to_cpu(pr->ActionStatus) == MPI_RAID_ACTION_ASTATUS_SUCCESS)
2836 completionCode = MPT_SCANDV_GOOD;
2837 else
2838 completionCode = MPT_SCANDV_SOME_ERROR;
2839 memcpy(hd->pLocal->sense, pr, sizeof(hd->pLocal->sense));
2840
2841 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) {
2842 u8 *sense_data;
2843 int sz;
2844
2845 /* save sense data in global structure
2846 */
2847 completionCode = MPT_SCANDV_SENSE;
2848 hd->pLocal->scsiStatus = scsi_status;
2849 sense_data = ((u8 *)ioc->sense_buf_pool +
2850 (req_idx * MPT_SENSE_BUFFER_ALLOC));
2851
2852 sz = min_t(int, pReq->SenseBufferLength,
2853 SCSI_STD_SENSE_BYTES);
2854 memcpy(hd->pLocal->sense, sense_data, sz);
2855
2856 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT " Check Condition, sense ptr %p\n",
2857 ioc->name, sense_data));
2858 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) {
2859 if (pReq->CDB[0] == INQUIRY)
2860 completionCode = MPT_SCANDV_ISSUE_SENSE;
2861 else
2862 completionCode = MPT_SCANDV_DID_RESET;
2863 }
2864 else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS)
2865 completionCode = MPT_SCANDV_DID_RESET;
2866 else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2867 completionCode = MPT_SCANDV_DID_RESET;
2868 else {
2869 completionCode = MPT_SCANDV_GOOD;
2870 hd->pLocal->scsiStatus = scsi_status;
2871 }
2872 break;
2873
2874 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
2875 if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED)
2876 completionCode = MPT_SCANDV_DID_RESET;
2877 else
2878 completionCode = MPT_SCANDV_SOME_ERROR;
2879 break;
2880
2881 default:
2882 completionCode = MPT_SCANDV_SOME_ERROR;
2883 break;
2884
2885 } /* switch(status) */
2886
2887 } /* end of address reply case */
2888
2889 hd->pLocal->completion = completionCode;
2890
2891 /* MF and RF are freed in mpt_interrupt
2892 */
2893 wakeup:
2894 /* Free Chain buffers (will never chain) in scan or dv */
2895 //mptscsih_freeChainBuffers(ioc, req_idx);
2896
2897 /*
2898 * Wake up the original calling thread
2899 */
2900 hd->scandv_wait_done = 1;
2901 wake_up(&hd->scandv_waitq);
2902
2903 return 1;
2904 }
2905
2906 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2907 /* mptscsih_timer_expired - Call back for timer process.
2908 * Used only for dv functionality.
2909 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
2910 *
2911 */
2912 void
2913 mptscsih_timer_expired(unsigned long data)
2914 {
2915 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
2916 MPT_ADAPTER *ioc = hd->ioc;
2917
2918 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Timer Expired! Cmd %p\n", ioc->name, hd->cmdPtr));
2919
2920 if (hd->cmdPtr) {
2921 MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr;
2922
2923 if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) {
2924 /* Desire to issue a task management request here.
2925 * TM requests MUST be single threaded.
2926 * If old eh code and no TM current, issue request.
2927 * If new eh code, do nothing. Wait for OS cmd timeout
2928 * for bus reset.
2929 */
2930 } else {
2931 /* Perform a FW reload */
2932 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {
2933 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
2934 }
2935 }
2936 } else {
2937 /* This should NEVER happen */
2938 printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", ioc->name);
2939 }
2940
2941 /* No more processing.
2942 * TM call will generate an interrupt for SCSI TM Management.
2943 * The FW will reply to all outstanding commands, callback will finish cleanup.
2944 * Hard reset clean-up will free all resources.
2945 */
2946 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Timer Expired Complete!\n", ioc->name));
2947
2948 return;
2949 }
2950
2951
2952 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2953 /**
2954 * mptscsih_do_cmd - Do internal command.
2955 * @hd: MPT_SCSI_HOST pointer
2956 * @io: INTERNAL_CMD pointer.
2957 *
2958 * Issue the specified internally generated command and do command
2959 * specific cleanup. For bus scan / DV only.
2960 * NOTES: If command is Inquiry and status is good,
2961 * initialize a target structure, save the data
2962 *
2963 * Remark: Single threaded access only.
2964 *
2965 * Return:
2966 * < 0 if an illegal command or no resources
2967 *
2968 * 0 if good
2969 *
2970 * > 0 if command complete but some type of completion error.
2971 */
2972 static int
2973 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io)
2974 {
2975 MPT_FRAME_HDR *mf;
2976 SCSIIORequest_t *pScsiReq;
2977 SCSIIORequest_t ReqCopy;
2978 int my_idx, ii, dir;
2979 int rc, cmdTimeout;
2980 int in_isr;
2981 char cmdLen;
2982 char CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
2983 char cmd = io->cmd;
2984 MPT_ADAPTER *ioc = hd->ioc;
2985
2986 in_isr = in_interrupt();
2987 if (in_isr) {
2988 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Internal SCSI IO request not allowed in ISR context!\n",
2989 ioc->name));
2990 return -EPERM;
2991 }
2992
2993
2994 /* Set command specific information
2995 */
2996 switch (cmd) {
2997 case INQUIRY:
2998 cmdLen = 6;
2999 dir = MPI_SCSIIO_CONTROL_READ;
3000 CDB[0] = cmd;
3001 CDB[4] = io->size;
3002 cmdTimeout = 10;
3003 break;
3004
3005 case TEST_UNIT_READY:
3006 cmdLen = 6;
3007 dir = MPI_SCSIIO_CONTROL_READ;
3008 cmdTimeout = 10;
3009 break;
3010
3011 case START_STOP:
3012 cmdLen = 6;
3013 dir = MPI_SCSIIO_CONTROL_READ;
3014 CDB[0] = cmd;
3015 CDB[4] = 1; /*Spin up the disk */
3016 cmdTimeout = 15;
3017 break;
3018
3019 case REQUEST_SENSE:
3020 cmdLen = 6;
3021 CDB[0] = cmd;
3022 CDB[4] = io->size;
3023 dir = MPI_SCSIIO_CONTROL_READ;
3024 cmdTimeout = 10;
3025 break;
3026
3027 case READ_BUFFER:
3028 cmdLen = 10;
3029 dir = MPI_SCSIIO_CONTROL_READ;
3030 CDB[0] = cmd;
3031 if (io->flags & MPT_ICFLAG_ECHO) {
3032 CDB[1] = 0x0A;
3033 } else {
3034 CDB[1] = 0x02;
3035 }
3036
3037 if (io->flags & MPT_ICFLAG_BUF_CAP) {
3038 CDB[1] |= 0x01;
3039 }
3040 CDB[6] = (io->size >> 16) & 0xFF;
3041 CDB[7] = (io->size >> 8) & 0xFF;
3042 CDB[8] = io->size & 0xFF;
3043 cmdTimeout = 10;
3044 break;
3045
3046 case WRITE_BUFFER:
3047 cmdLen = 10;
3048 dir = MPI_SCSIIO_CONTROL_WRITE;
3049 CDB[0] = cmd;
3050 if (io->flags & MPT_ICFLAG_ECHO) {
3051 CDB[1] = 0x0A;
3052 } else {
3053 CDB[1] = 0x02;
3054 }
3055 CDB[6] = (io->size >> 16) & 0xFF;
3056 CDB[7] = (io->size >> 8) & 0xFF;
3057 CDB[8] = io->size & 0xFF;
3058 cmdTimeout = 10;
3059 break;
3060
3061 case RESERVE:
3062 cmdLen = 6;
3063 dir = MPI_SCSIIO_CONTROL_READ;
3064 CDB[0] = cmd;
3065 cmdTimeout = 10;
3066 break;
3067
3068 case RELEASE:
3069 cmdLen = 6;
3070 dir = MPI_SCSIIO_CONTROL_READ;
3071 CDB[0] = cmd;
3072 cmdTimeout = 10;
3073 break;
3074
3075 case SYNCHRONIZE_CACHE:
3076 cmdLen = 10;
3077 dir = MPI_SCSIIO_CONTROL_READ;
3078 CDB[0] = cmd;
3079 // CDB[1] = 0x02; /* set immediate bit */
3080 cmdTimeout = 10;
3081 break;
3082
3083 default:
3084 /* Error Case */
3085 return -EFAULT;
3086 }
3087
3088 /* Get and Populate a free Frame
3089 */
3090 if ((mf = mpt_get_msg_frame(ioc->InternalCtx, ioc)) == NULL) {
3091 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "No msg frames!\n",
3092 ioc->name));
3093 return -EBUSY;
3094 }
3095
3096 pScsiReq = (SCSIIORequest_t *) mf;
3097
3098 /* Get the request index */
3099 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
3100 ADD_INDEX_LOG(my_idx); /* for debug */
3101
3102 if (io->flags & MPT_ICFLAG_PHYS_DISK) {
3103 pScsiReq->TargetID = io->physDiskNum;
3104 pScsiReq->Bus = 0;
3105 pScsiReq->ChainOffset = 0;
3106 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH;
3107 } else {
3108 pScsiReq->TargetID = io->id;
3109 pScsiReq->Bus = io->channel;
3110 pScsiReq->ChainOffset = 0;
3111 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST;
3112 }
3113
3114 pScsiReq->CDBLength = cmdLen;
3115 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
3116
3117 pScsiReq->Reserved = 0;
3118
3119 pScsiReq->MsgFlags = mpt_msg_flags();
3120 /* MsgContext set in mpt_get_msg_fram call */
3121
3122 int_to_scsilun(io->lun, (struct scsi_lun *)pScsiReq->LUN);
3123
3124 if (io->flags & MPT_ICFLAG_TAGGED_CMD)
3125 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ);
3126 else
3127 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3128
3129 if (cmd == REQUEST_SENSE) {
3130 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED);
3131 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Untagged! 0x%2x\n",
3132 ioc->name, cmd));
3133 }
3134
3135 for (ii=0; ii < 16; ii++)
3136 pScsiReq->CDB[ii] = CDB[ii];
3137
3138 pScsiReq->DataLength = cpu_to_le32(io->size);
3139 pScsiReq->SenseBufferLowAddr = cpu_to_le32(ioc->sense_buf_low_dma
3140 + (my_idx * MPT_SENSE_BUFFER_ALLOC));
3141
3142 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Command 0x%x for (%d:%d:%d)\n",
3143 ioc->name, cmd, io->channel, io->id, io->lun));
3144
3145 if (dir == MPI_SCSIIO_CONTROL_READ) {
3146 mpt_add_sge((char *) &pScsiReq->SGL,
3147 MPT_SGE_FLAGS_SSIMPLE_READ | io->size,
3148 io->data_dma);
3149 } else {
3150 mpt_add_sge((char *) &pScsiReq->SGL,
3151 MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size,
3152 io->data_dma);
3153 }
3154
3155 /* The ISR will free the request frame, but we need
3156 * the information to initialize the target. Duplicate.
3157 */
3158 memcpy(&ReqCopy, pScsiReq, sizeof(SCSIIORequest_t));
3159
3160 /* Issue this command after:
3161 * finish init
3162 * add timer
3163 * Wait until the reply has been received
3164 * ScsiScanDvCtx callback function will
3165 * set hd->pLocal;
3166 * set scandv_wait_done and call wake_up
3167 */
3168 hd->pLocal = NULL;
3169 hd->timer.expires = jiffies + HZ*cmdTimeout;
3170 hd->scandv_wait_done = 0;
3171
3172 /* Save cmd pointer, for resource free if timeout or
3173 * FW reload occurs
3174 */
3175 hd->cmdPtr = mf;
3176
3177 add_timer(&hd->timer);
3178 mpt_put_msg_frame(ioc->InternalCtx, ioc, mf);
3179 wait_event(hd->scandv_waitq, hd->scandv_wait_done);
3180
3181 if (hd->pLocal) {
3182 rc = hd->pLocal->completion;
3183 hd->pLocal->skip = 0;
3184
3185 /* Always set fatal error codes in some cases.
3186 */
3187 if (rc == MPT_SCANDV_SELECTION_TIMEOUT)
3188 rc = -ENXIO;
3189 else if (rc == MPT_SCANDV_SOME_ERROR)
3190 rc = -rc;
3191 } else {
3192 rc = -EFAULT;
3193 /* This should never happen. */
3194 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT "_do_cmd: Null pLocal!!!\n",
3195 ioc->name));
3196 }
3197
3198 return rc;
3199 }
3200
3201 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3202 /**
3203 * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks.
3204 * @hd: Pointer to a SCSI HOST structure
3205 * @vdevice: virtual target device
3206 *
3207 * Uses the ISR, but with special processing.
3208 * MUST be single-threaded.
3209 *
3210 */
3211 static void
3212 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
3213 {
3214 INTERNAL_CMD iocmd;
3215
3216 /* Ignore hidden raid components, this is handled when the command
3217 * is sent to the volume
3218 */
3219 if (vdevice->vtarget->tflags & MPT_TARGET_FLAGS_RAID_COMPONENT)
3220 return;
3221
3222 if (vdevice->vtarget->type != TYPE_DISK || vdevice->vtarget->deleted ||
3223 !vdevice->configured_lun)
3224 return;
3225
3226 /* Following parameters will not change
3227 * in this routine.
3228 */
3229 iocmd.cmd = SYNCHRONIZE_CACHE;
3230 iocmd.flags = 0;
3231 iocmd.physDiskNum = -1;
3232 iocmd.data = NULL;
3233 iocmd.data_dma = -1;
3234 iocmd.size = 0;
3235 iocmd.rsvd = iocmd.rsvd2 = 0;
3236 iocmd.channel = vdevice->vtarget->channel;
3237 iocmd.id = vdevice->vtarget->id;
3238 iocmd.lun = vdevice->lun;
3239
3240 mptscsih_do_cmd(hd, &iocmd);
3241 }
3242
3243 static ssize_t
3244 mptscsih_version_fw_show(struct class_device *cdev, char *buf)
3245 {
3246 struct Scsi_Host *host = class_to_shost(cdev);
3247 MPT_SCSI_HOST *hd = shost_priv(host);
3248 MPT_ADAPTER *ioc = hd->ioc;
3249
3250 return snprintf(buf, PAGE_SIZE, "%02d.%02d.%02d.%02d\n",
3251 (ioc->facts.FWVersion.Word & 0xFF000000) >> 24,
3252 (ioc->facts.FWVersion.Word & 0x00FF0000) >> 16,
3253 (ioc->facts.FWVersion.Word & 0x0000FF00) >> 8,
3254 ioc->facts.FWVersion.Word & 0x000000FF);
3255 }
3256 static CLASS_DEVICE_ATTR(version_fw, S_IRUGO, mptscsih_version_fw_show, NULL);
3257
3258 static ssize_t
3259 mptscsih_version_bios_show(struct class_device *cdev, char *buf)
3260 {
3261 struct Scsi_Host *host = class_to_shost(cdev);
3262 MPT_SCSI_HOST *hd = shost_priv(host);
3263 MPT_ADAPTER *ioc = hd->ioc;
3264
3265 return snprintf(buf, PAGE_SIZE, "%02x.%02x.%02x.%02x\n",
3266 (ioc->biosVersion & 0xFF000000) >> 24,
3267 (ioc->biosVersion & 0x00FF0000) >> 16,
3268 (ioc->biosVersion & 0x0000FF00) >> 8,
3269 ioc->biosVersion & 0x000000FF);
3270 }
3271 static CLASS_DEVICE_ATTR(version_bios, S_IRUGO, mptscsih_version_bios_show, NULL);
3272
3273 static ssize_t
3274 mptscsih_version_mpi_show(struct class_device *cdev, char *buf)
3275 {
3276 struct Scsi_Host *host = class_to_shost(cdev);
3277 MPT_SCSI_HOST *hd = shost_priv(host);
3278 MPT_ADAPTER *ioc = hd->ioc;
3279
3280 return snprintf(buf, PAGE_SIZE, "%03x\n", ioc->facts.MsgVersion);
3281 }
3282 static CLASS_DEVICE_ATTR(version_mpi, S_IRUGO, mptscsih_version_mpi_show, NULL);
3283
3284 static ssize_t
3285 mptscsih_version_product_show(struct class_device *cdev, char *buf)
3286 {
3287 struct Scsi_Host *host = class_to_shost(cdev);
3288 MPT_SCSI_HOST *hd = shost_priv(host);
3289 MPT_ADAPTER *ioc = hd->ioc;
3290
3291 return snprintf(buf, PAGE_SIZE, "%s\n", ioc->prod_name);
3292 }
3293 static CLASS_DEVICE_ATTR(version_product, S_IRUGO,
3294 mptscsih_version_product_show, NULL);
3295
3296 static ssize_t
3297 mptscsih_version_nvdata_persistent_show(struct class_device *cdev, char *buf)
3298 {
3299 struct Scsi_Host *host = class_to_shost(cdev);
3300 MPT_SCSI_HOST *hd = shost_priv(host);
3301 MPT_ADAPTER *ioc = hd->ioc;
3302
3303 return snprintf(buf, PAGE_SIZE, "%02xh\n",
3304 ioc->nvdata_version_persistent);
3305 }
3306 static CLASS_DEVICE_ATTR(version_nvdata_persistent, S_IRUGO,
3307 mptscsih_version_nvdata_persistent_show, NULL);
3308
3309 static ssize_t
3310 mptscsih_version_nvdata_default_show(struct class_device *cdev, char *buf)
3311 {
3312 struct Scsi_Host *host = class_to_shost(cdev);
3313 MPT_SCSI_HOST *hd = shost_priv(host);
3314 MPT_ADAPTER *ioc = hd->ioc;
3315
3316 return snprintf(buf, PAGE_SIZE, "%02xh\n",ioc->nvdata_version_default);
3317 }
3318 static CLASS_DEVICE_ATTR(version_nvdata_default, S_IRUGO,
3319 mptscsih_version_nvdata_default_show, NULL);
3320
3321 static ssize_t
3322 mptscsih_board_name_show(struct class_device *cdev, char *buf)
3323 {
3324 struct Scsi_Host *host = class_to_shost(cdev);
3325 MPT_SCSI_HOST *hd = shost_priv(host);
3326 MPT_ADAPTER *ioc = hd->ioc;
3327
3328 return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_name);
3329 }
3330 static CLASS_DEVICE_ATTR(board_name, S_IRUGO, mptscsih_board_name_show, NULL);
3331
3332 static ssize_t
3333 mptscsih_board_assembly_show(struct class_device *cdev, char *buf)
3334 {
3335 struct Scsi_Host *host = class_to_shost(cdev);
3336 MPT_SCSI_HOST *hd = shost_priv(host);
3337 MPT_ADAPTER *ioc = hd->ioc;
3338
3339 return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_assembly);
3340 }
3341 static CLASS_DEVICE_ATTR(board_assembly, S_IRUGO,
3342 mptscsih_board_assembly_show, NULL);
3343
3344 static ssize_t
3345 mptscsih_board_tracer_show(struct class_device *cdev, char *buf)
3346 {
3347 struct Scsi_Host *host = class_to_shost(cdev);
3348 MPT_SCSI_HOST *hd = shost_priv(host);
3349 MPT_ADAPTER *ioc = hd->ioc;
3350
3351 return snprintf(buf, PAGE_SIZE, "%s\n", ioc->board_tracer);
3352 }
3353 static CLASS_DEVICE_ATTR(board_tracer, S_IRUGO,
3354 mptscsih_board_tracer_show, NULL);
3355
3356 static ssize_t
3357 mptscsih_io_delay_show(struct class_device *cdev, char *buf)
3358 {
3359 struct Scsi_Host *host = class_to_shost(cdev);
3360 MPT_SCSI_HOST *hd = shost_priv(host);
3361 MPT_ADAPTER *ioc = hd->ioc;
3362
3363 return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->io_missing_delay);
3364 }
3365 static CLASS_DEVICE_ATTR(io_delay, S_IRUGO,
3366 mptscsih_io_delay_show, NULL);
3367
3368 static ssize_t
3369 mptscsih_device_delay_show(struct class_device *cdev, char *buf)
3370 {
3371 struct Scsi_Host *host = class_to_shost(cdev);
3372 MPT_SCSI_HOST *hd = shost_priv(host);
3373 MPT_ADAPTER *ioc = hd->ioc;
3374
3375 return snprintf(buf, PAGE_SIZE, "%02d\n", ioc->device_missing_delay);
3376 }
3377 static CLASS_DEVICE_ATTR(device_delay, S_IRUGO,
3378 mptscsih_device_delay_show, NULL);
3379
3380 static ssize_t
3381 mptscsih_debug_level_show(struct class_device *cdev, char *buf)
3382 {
3383 struct Scsi_Host *host = class_to_shost(cdev);
3384 MPT_SCSI_HOST *hd = shost_priv(host);
3385 MPT_ADAPTER *ioc = hd->ioc;
3386
3387 return snprintf(buf, PAGE_SIZE, "%08xh\n", ioc->debug_level);
3388 }
3389 static ssize_t
3390 mptscsih_debug_level_store(struct class_device *cdev, const char *buf,
3391 size_t count)
3392 {
3393 struct Scsi_Host *host = class_to_shost(cdev);
3394 MPT_SCSI_HOST *hd = shost_priv(host);
3395 MPT_ADAPTER *ioc = hd->ioc;
3396 int val = 0;
3397
3398 if (sscanf(buf, "%x", &val) != 1)
3399 return -EINVAL;
3400
3401 ioc->debug_level = val;
3402 printk(MYIOC_s_INFO_FMT "debug_level=%08xh\n",
3403 ioc->name, ioc->debug_level);
3404 return strlen(buf);
3405 }
3406 static CLASS_DEVICE_ATTR(debug_level, S_IRUGO | S_IWUSR,
3407 mptscsih_debug_level_show, mptscsih_debug_level_store);
3408
3409 struct class_device_attribute *mptscsih_host_attrs[] = {
3410 &class_device_attr_version_fw,
3411 &class_device_attr_version_bios,
3412 &class_device_attr_version_mpi,
3413 &class_device_attr_version_product,
3414 &class_device_attr_version_nvdata_persistent,
3415 &class_device_attr_version_nvdata_default,
3416 &class_device_attr_board_name,
3417 &class_device_attr_board_assembly,
3418 &class_device_attr_board_tracer,
3419 &class_device_attr_io_delay,
3420 &class_device_attr_device_delay,
3421 &class_device_attr_debug_level,
3422 NULL,
3423 };
3424 EXPORT_SYMBOL(mptscsih_host_attrs);
3425
3426 EXPORT_SYMBOL(mptscsih_remove);
3427 EXPORT_SYMBOL(mptscsih_shutdown);
3428 #ifdef CONFIG_PM
3429 EXPORT_SYMBOL(mptscsih_suspend);
3430 EXPORT_SYMBOL(mptscsih_resume);
3431 #endif
3432 EXPORT_SYMBOL(mptscsih_proc_info);
3433 EXPORT_SYMBOL(mptscsih_info);
3434 EXPORT_SYMBOL(mptscsih_qcmd);
3435 EXPORT_SYMBOL(mptscsih_slave_destroy);
3436 EXPORT_SYMBOL(mptscsih_slave_configure);
3437 EXPORT_SYMBOL(mptscsih_abort);
3438 EXPORT_SYMBOL(mptscsih_dev_reset);
3439 EXPORT_SYMBOL(mptscsih_bus_reset);
3440 EXPORT_SYMBOL(mptscsih_host_reset);
3441 EXPORT_SYMBOL(mptscsih_bios_param);
3442 EXPORT_SYMBOL(mptscsih_io_done);
3443 EXPORT_SYMBOL(mptscsih_taskmgmt_complete);
3444 EXPORT_SYMBOL(mptscsih_scandv_complete);
3445 EXPORT_SYMBOL(mptscsih_event_process);
3446 EXPORT_SYMBOL(mptscsih_ioc_reset);
3447 EXPORT_SYMBOL(mptscsih_change_queue_depth);
3448 EXPORT_SYMBOL(mptscsih_timer_expired);
3449 EXPORT_SYMBOL(mptscsih_TMHandler);
3450
3451 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/