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