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