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