1 /* 2 * linux/drivers/message/fusion/mptscsih.c 3 * For use with LSI Logic PCI chip/adapter(s) 4 * running LSI Logic Fusion MPT (Message Passing Technology) firmware. 5 * 6 * Copyright (c) 1999-2005 LSI Logic Corporation 7 * (mailto:mpt_linux_developer@lsil.com) 8 * 9 */ 10 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 11 /* 12 This program is free software; you can redistribute it and/or modify 13 it under the terms of the GNU General Public License as published by 14 the Free Software Foundation; version 2 of the License. 15 16 This program is distributed in the hope that it will be useful, 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 GNU General Public License for more details. 20 21 NO WARRANTY 22 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR 23 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT 24 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, 25 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is 26 solely responsible for determining the appropriateness of using and 27 distributing the Program and assumes all risks associated with its 28 exercise of rights under this Agreement, including but not limited to 29 the risks and costs of program errors, damage to or loss of data, 30 programs or equipment, and unavailability or interruption of operations. 31 32 DISCLAIMER OF LIABILITY 33 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY 34 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 35 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND 36 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 37 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 38 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED 39 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES 40 41 You should have received a copy of the GNU General Public License 42 along with this program; if not, write to the Free Software 43 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 44 */ 45 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 46 47 #include "linux_compat.h" /* linux-2.6 tweaks */ 48 #include <linux/module.h> 49 #include <linux/kernel.h> 50 #include <linux/init.h> 51 #include <linux/errno.h> 52 #include <linux/kdev_t.h> 53 #include <linux/blkdev.h> 54 #include <linux/delay.h> /* for mdelay */ 55 #include <linux/interrupt.h> /* needed for in_interrupt() proto */ 56 #include <linux/reboot.h> /* notifier code */ 57 #include <linux/sched.h> 58 #include <linux/workqueue.h> 59 60 #include <scsi/scsi.h> 61 #include <scsi/scsi_cmnd.h> 62 #include <scsi/scsi_device.h> 63 #include <scsi/scsi_host.h> 64 #include <scsi/scsi_tcq.h> 65 #include <scsi/scsi_dbg.h> 66 67 #include "mptbase.h" 68 #include "mptscsih.h" 69 70 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 71 #define my_NAME "Fusion MPT SCSI Host driver" 72 #define my_VERSION MPT_LINUX_VERSION_COMMON 73 #define MYNAM "mptscsih" 74 75 MODULE_AUTHOR(MODULEAUTHOR); 76 MODULE_DESCRIPTION(my_NAME); 77 MODULE_LICENSE("GPL"); 78 79 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 80 81 typedef struct _BIG_SENSE_BUF { 82 u8 data[MPT_SENSE_BUFFER_ALLOC]; 83 } BIG_SENSE_BUF; 84 85 #define MPT_SCANDV_GOOD (0x00000000) /* must be 0 */ 86 #define MPT_SCANDV_DID_RESET (0x00000001) 87 #define MPT_SCANDV_SENSE (0x00000002) 88 #define MPT_SCANDV_SOME_ERROR (0x00000004) 89 #define MPT_SCANDV_SELECTION_TIMEOUT (0x00000008) 90 #define MPT_SCANDV_ISSUE_SENSE (0x00000010) 91 #define MPT_SCANDV_FALLBACK (0x00000020) 92 93 #define MPT_SCANDV_MAX_RETRIES (10) 94 95 #define MPT_ICFLAG_BUF_CAP 0x01 /* ReadBuffer Read Capacity format */ 96 #define MPT_ICFLAG_ECHO 0x02 /* ReadBuffer Echo buffer format */ 97 #define MPT_ICFLAG_EBOS 0x04 /* ReadBuffer Echo buffer has EBOS */ 98 #define MPT_ICFLAG_PHYS_DISK 0x08 /* Any SCSI IO but do Phys Disk Format */ 99 #define MPT_ICFLAG_TAGGED_CMD 0x10 /* Do tagged IO */ 100 #define MPT_ICFLAG_DID_RESET 0x20 /* Bus Reset occurred with this command */ 101 #define MPT_ICFLAG_RESERVED 0x40 /* Reserved has been issued */ 102 103 typedef struct _internal_cmd { 104 char *data; /* data pointer */ 105 dma_addr_t data_dma; /* data dma address */ 106 int size; /* transfer size */ 107 u8 cmd; /* SCSI Op Code */ 108 u8 bus; /* bus number */ 109 u8 id; /* SCSI ID (virtual) */ 110 u8 lun; 111 u8 flags; /* Bit Field - See above */ 112 u8 physDiskNum; /* Phys disk number, -1 else */ 113 u8 rsvd2; 114 u8 rsvd; 115 } INTERNAL_CMD; 116 117 typedef struct _negoparms { 118 u8 width; 119 u8 offset; 120 u8 factor; 121 u8 flags; 122 } NEGOPARMS; 123 124 typedef struct _dv_parameters { 125 NEGOPARMS max; 126 NEGOPARMS now; 127 u8 cmd; 128 u8 id; 129 u16 pad1; 130 } DVPARAMETERS; 131 132 /* 133 * Other private/forward protos... 134 */ 135 int mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); 136 static void mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq); 137 int mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); 138 139 static int mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt, 140 SCSIIORequest_t *pReq, int req_idx); 141 static void mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx); 142 static void mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply); 143 static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd); 144 static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout ); 145 static u32 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc); 146 147 static int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout); 148 static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout); 149 150 int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); 151 int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); 152 153 static void mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen); 154 static void mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56); 155 static void mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq); 156 static void mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags); 157 static void mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id); 158 static int mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target, int flags); 159 static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus); 160 int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); 161 static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd); 162 static int mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum); 163 164 static struct work_struct mptscsih_persistTask; 165 166 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION 167 static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io); 168 static void mptscsih_domainValidation(void *hd); 169 static int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id); 170 static void mptscsih_qas_check(MPT_SCSI_HOST *hd, int id); 171 static int mptscsih_doDv(MPT_SCSI_HOST *hd, int channel, int target); 172 static void mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage); 173 static void mptscsih_fillbuf(char *buffer, int size, int index, int width); 174 static void mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id); 175 #endif 176 177 void mptscsih_remove(struct pci_dev *); 178 void mptscsih_shutdown(struct pci_dev *); 179 #ifdef CONFIG_PM 180 int mptscsih_suspend(struct pci_dev *pdev, pm_message_t state); 181 int mptscsih_resume(struct pci_dev *pdev); 182 #endif 183 184 #define SNS_LEN(scp) sizeof((scp)->sense_buffer) 185 186 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION 187 /* 188 * Domain Validation task structure 189 */ 190 static DEFINE_SPINLOCK(dvtaskQ_lock); 191 static int dvtaskQ_active = 0; 192 static int dvtaskQ_release = 0; 193 static struct work_struct dvTaskQ_task; 194 #endif 195 196 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 197 /** 198 * mptscsih_add_sge - Place a simple SGE at address pAddr. 199 * @pAddr: virtual address for SGE 200 * @flagslength: SGE flags and data transfer length 201 * @dma_addr: Physical address 202 * 203 * This routine places a MPT request frame back on the MPT adapter's 204 * FreeQ. 205 */ 206 static inline void 207 mptscsih_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr) 208 { 209 if (sizeof(dma_addr_t) == sizeof(u64)) { 210 SGESimple64_t *pSge = (SGESimple64_t *) pAddr; 211 u32 tmp = dma_addr & 0xFFFFFFFF; 212 213 pSge->FlagsLength = cpu_to_le32(flagslength); 214 pSge->Address.Low = cpu_to_le32(tmp); 215 tmp = (u32) ((u64)dma_addr >> 32); 216 pSge->Address.High = cpu_to_le32(tmp); 217 218 } else { 219 SGESimple32_t *pSge = (SGESimple32_t *) pAddr; 220 pSge->FlagsLength = cpu_to_le32(flagslength); 221 pSge->Address = cpu_to_le32(dma_addr); 222 } 223 } /* mptscsih_add_sge() */ 224 225 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 226 /** 227 * mptscsih_add_chain - Place a chain SGE at address pAddr. 228 * @pAddr: virtual address for SGE 229 * @next: nextChainOffset value (u32's) 230 * @length: length of next SGL segment 231 * @dma_addr: Physical address 232 * 233 * This routine places a MPT request frame back on the MPT adapter's 234 * FreeQ. 235 */ 236 static inline void 237 mptscsih_add_chain(char *pAddr, u8 next, u16 length, dma_addr_t dma_addr) 238 { 239 if (sizeof(dma_addr_t) == sizeof(u64)) { 240 SGEChain64_t *pChain = (SGEChain64_t *) pAddr; 241 u32 tmp = dma_addr & 0xFFFFFFFF; 242 243 pChain->Length = cpu_to_le16(length); 244 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size(); 245 246 pChain->NextChainOffset = next; 247 248 pChain->Address.Low = cpu_to_le32(tmp); 249 tmp = (u32) ((u64)dma_addr >> 32); 250 pChain->Address.High = cpu_to_le32(tmp); 251 } else { 252 SGEChain32_t *pChain = (SGEChain32_t *) pAddr; 253 pChain->Length = cpu_to_le16(length); 254 pChain->Flags = MPI_SGE_FLAGS_CHAIN_ELEMENT | mpt_addr_size(); 255 pChain->NextChainOffset = next; 256 pChain->Address = cpu_to_le32(dma_addr); 257 } 258 } /* mptscsih_add_chain() */ 259 260 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 261 /* 262 * mptscsih_getFreeChainBuffer - Function to get a free chain 263 * from the MPT_SCSI_HOST FreeChainQ. 264 * @ioc: Pointer to MPT_ADAPTER structure 265 * @req_idx: Index of the SCSI IO request frame. (output) 266 * 267 * return SUCCESS or FAILED 268 */ 269 static inline int 270 mptscsih_getFreeChainBuffer(MPT_ADAPTER *ioc, int *retIndex) 271 { 272 MPT_FRAME_HDR *chainBuf; 273 unsigned long flags; 274 int rc; 275 int chain_idx; 276 277 dsgprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer called\n", 278 ioc->name)); 279 spin_lock_irqsave(&ioc->FreeQlock, flags); 280 if (!list_empty(&ioc->FreeChainQ)) { 281 int offset; 282 283 chainBuf = list_entry(ioc->FreeChainQ.next, MPT_FRAME_HDR, 284 u.frame.linkage.list); 285 list_del(&chainBuf->u.frame.linkage.list); 286 offset = (u8 *)chainBuf - (u8 *)ioc->ChainBuffer; 287 chain_idx = offset / ioc->req_sz; 288 rc = SUCCESS; 289 dsgprintk((MYIOC_s_ERR_FMT "getFreeChainBuffer chainBuf=%p ChainBuffer=%p offset=%d chain_idx=%d\n", 290 ioc->name, chainBuf, ioc->ChainBuffer, offset, chain_idx)); 291 } else { 292 rc = FAILED; 293 chain_idx = MPT_HOST_NO_CHAIN; 294 dfailprintk((MYIOC_s_INFO_FMT "getFreeChainBuffer failed\n", 295 ioc->name)); 296 } 297 spin_unlock_irqrestore(&ioc->FreeQlock, flags); 298 299 *retIndex = chain_idx; 300 return rc; 301 } /* mptscsih_getFreeChainBuffer() */ 302 303 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 304 /* 305 * mptscsih_AddSGE - Add a SGE (plus chain buffers) to the 306 * SCSIIORequest_t Message Frame. 307 * @ioc: Pointer to MPT_ADAPTER structure 308 * @SCpnt: Pointer to scsi_cmnd structure 309 * @pReq: Pointer to SCSIIORequest_t structure 310 * 311 * Returns ... 312 */ 313 static int 314 mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt, 315 SCSIIORequest_t *pReq, int req_idx) 316 { 317 char *psge; 318 char *chainSge; 319 struct scatterlist *sg; 320 int frm_sz; 321 int sges_left, sg_done; 322 int chain_idx = MPT_HOST_NO_CHAIN; 323 int sgeOffset; 324 int numSgeSlots, numSgeThisFrame; 325 u32 sgflags, sgdir, thisxfer = 0; 326 int chain_dma_off = 0; 327 int newIndex; 328 int ii; 329 dma_addr_t v2; 330 u32 RequestNB; 331 332 sgdir = le32_to_cpu(pReq->Control) & MPI_SCSIIO_CONTROL_DATADIRECTION_MASK; 333 if (sgdir == MPI_SCSIIO_CONTROL_WRITE) { 334 sgdir = MPT_TRANSFER_HOST_TO_IOC; 335 } else { 336 sgdir = MPT_TRANSFER_IOC_TO_HOST; 337 } 338 339 psge = (char *) &pReq->SGL; 340 frm_sz = ioc->req_sz; 341 342 /* Map the data portion, if any. 343 * sges_left = 0 if no data transfer. 344 */ 345 if ( (sges_left = SCpnt->use_sg) ) { 346 sges_left = pci_map_sg(ioc->pcidev, 347 (struct scatterlist *) SCpnt->request_buffer, 348 SCpnt->use_sg, 349 SCpnt->sc_data_direction); 350 if (sges_left == 0) 351 return FAILED; 352 } else if (SCpnt->request_bufflen) { 353 SCpnt->SCp.dma_handle = pci_map_single(ioc->pcidev, 354 SCpnt->request_buffer, 355 SCpnt->request_bufflen, 356 SCpnt->sc_data_direction); 357 dsgprintk((MYIOC_s_INFO_FMT "SG: non-SG for %p, len=%d\n", 358 ioc->name, SCpnt, SCpnt->request_bufflen)); 359 mptscsih_add_sge((char *) &pReq->SGL, 360 0xD1000000|MPT_SGE_FLAGS_ADDRESSING|sgdir|SCpnt->request_bufflen, 361 SCpnt->SCp.dma_handle); 362 363 return SUCCESS; 364 } 365 366 /* Handle the SG case. 367 */ 368 sg = (struct scatterlist *) SCpnt->request_buffer; 369 sg_done = 0; 370 sgeOffset = sizeof(SCSIIORequest_t) - sizeof(SGE_IO_UNION); 371 chainSge = NULL; 372 373 /* Prior to entering this loop - the following must be set 374 * current MF: sgeOffset (bytes) 375 * chainSge (Null if original MF is not a chain buffer) 376 * sg_done (num SGE done for this MF) 377 */ 378 379 nextSGEset: 380 numSgeSlots = ((frm_sz - sgeOffset) / (sizeof(u32) + sizeof(dma_addr_t)) ); 381 numSgeThisFrame = (sges_left < numSgeSlots) ? sges_left : numSgeSlots; 382 383 sgflags = MPT_SGE_FLAGS_SIMPLE_ELEMENT | MPT_SGE_FLAGS_ADDRESSING | sgdir; 384 385 /* Get first (num - 1) SG elements 386 * Skip any SG entries with a length of 0 387 * NOTE: at finish, sg and psge pointed to NEXT data/location positions 388 */ 389 for (ii=0; ii < (numSgeThisFrame-1); ii++) { 390 thisxfer = sg_dma_len(sg); 391 if (thisxfer == 0) { 392 sg ++; /* Get next SG element from the OS */ 393 sg_done++; 394 continue; 395 } 396 397 v2 = sg_dma_address(sg); 398 mptscsih_add_sge(psge, sgflags | thisxfer, v2); 399 400 sg++; /* Get next SG element from the OS */ 401 psge += (sizeof(u32) + sizeof(dma_addr_t)); 402 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t)); 403 sg_done++; 404 } 405 406 if (numSgeThisFrame == sges_left) { 407 /* Add last element, end of buffer and end of list flags. 408 */ 409 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT | 410 MPT_SGE_FLAGS_END_OF_BUFFER | 411 MPT_SGE_FLAGS_END_OF_LIST; 412 413 /* Add last SGE and set termination flags. 414 * Note: Last SGE may have a length of 0 - which should be ok. 415 */ 416 thisxfer = sg_dma_len(sg); 417 418 v2 = sg_dma_address(sg); 419 mptscsih_add_sge(psge, sgflags | thisxfer, v2); 420 /* 421 sg++; 422 psge += (sizeof(u32) + sizeof(dma_addr_t)); 423 */ 424 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t)); 425 sg_done++; 426 427 if (chainSge) { 428 /* The current buffer is a chain buffer, 429 * but there is not another one. 430 * Update the chain element 431 * Offset and Length fields. 432 */ 433 mptscsih_add_chain((char *)chainSge, 0, sgeOffset, ioc->ChainBufferDMA + chain_dma_off); 434 } else { 435 /* The current buffer is the original MF 436 * and there is no Chain buffer. 437 */ 438 pReq->ChainOffset = 0; 439 RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03; 440 dsgprintk((MYIOC_s_INFO_FMT 441 "Single Buffer RequestNB=%x, sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset)); 442 ioc->RequestNB[req_idx] = RequestNB; 443 } 444 } else { 445 /* At least one chain buffer is needed. 446 * Complete the first MF 447 * - last SGE element, set the LastElement bit 448 * - set ChainOffset (words) for orig MF 449 * (OR finish previous MF chain buffer) 450 * - update MFStructPtr ChainIndex 451 * - Populate chain element 452 * Also 453 * Loop until done. 454 */ 455 456 dsgprintk((MYIOC_s_INFO_FMT "SG: Chain Required! sg done %d\n", 457 ioc->name, sg_done)); 458 459 /* Set LAST_ELEMENT flag for last non-chain element 460 * in the buffer. Since psge points at the NEXT 461 * SGE element, go back one SGE element, update the flags 462 * and reset the pointer. (Note: sgflags & thisxfer are already 463 * set properly). 464 */ 465 if (sg_done) { 466 u32 *ptmp = (u32 *) (psge - (sizeof(u32) + sizeof(dma_addr_t))); 467 sgflags = le32_to_cpu(*ptmp); 468 sgflags |= MPT_SGE_FLAGS_LAST_ELEMENT; 469 *ptmp = cpu_to_le32(sgflags); 470 } 471 472 if (chainSge) { 473 /* The current buffer is a chain buffer. 474 * chainSge points to the previous Chain Element. 475 * Update its chain element Offset and Length (must 476 * include chain element size) fields. 477 * Old chain element is now complete. 478 */ 479 u8 nextChain = (u8) (sgeOffset >> 2); 480 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t)); 481 mptscsih_add_chain((char *)chainSge, nextChain, sgeOffset, ioc->ChainBufferDMA + chain_dma_off); 482 } else { 483 /* The original MF buffer requires a chain buffer - 484 * set the offset. 485 * Last element in this MF is a chain element. 486 */ 487 pReq->ChainOffset = (u8) (sgeOffset >> 2); 488 RequestNB = (((sgeOffset - 1) >> ioc->NBShiftFactor) + 1) & 0x03; 489 dsgprintk((MYIOC_s_ERR_FMT "Chain Buffer Needed, RequestNB=%x sgeOffset=%d\n", ioc->name, RequestNB, sgeOffset)); 490 ioc->RequestNB[req_idx] = RequestNB; 491 } 492 493 sges_left -= sg_done; 494 495 496 /* NOTE: psge points to the beginning of the chain element 497 * in current buffer. Get a chain buffer. 498 */ 499 if ((mptscsih_getFreeChainBuffer(ioc, &newIndex)) == FAILED) { 500 dfailprintk((MYIOC_s_INFO_FMT 501 "getFreeChainBuffer FAILED SCSI cmd=%02x (%p)\n", 502 ioc->name, pReq->CDB[0], SCpnt)); 503 return FAILED; 504 } 505 506 /* Update the tracking arrays. 507 * If chainSge == NULL, update ReqToChain, else ChainToChain 508 */ 509 if (chainSge) { 510 ioc->ChainToChain[chain_idx] = newIndex; 511 } else { 512 ioc->ReqToChain[req_idx] = newIndex; 513 } 514 chain_idx = newIndex; 515 chain_dma_off = ioc->req_sz * chain_idx; 516 517 /* Populate the chainSGE for the current buffer. 518 * - Set chain buffer pointer to psge and fill 519 * out the Address and Flags fields. 520 */ 521 chainSge = (char *) psge; 522 dsgprintk((KERN_INFO " Current buff @ %p (index 0x%x)", 523 psge, req_idx)); 524 525 /* Start the SGE for the next buffer 526 */ 527 psge = (char *) (ioc->ChainBuffer + chain_dma_off); 528 sgeOffset = 0; 529 sg_done = 0; 530 531 dsgprintk((KERN_INFO " Chain buff @ %p (index 0x%x)\n", 532 psge, chain_idx)); 533 534 /* Start the SGE for the next buffer 535 */ 536 537 goto nextSGEset; 538 } 539 540 return SUCCESS; 541 } /* mptscsih_AddSGE() */ 542 543 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 544 /* 545 * mptscsih_io_done - Main SCSI IO callback routine registered to 546 * Fusion MPT (base) driver 547 * @ioc: Pointer to MPT_ADAPTER structure 548 * @mf: Pointer to original MPT request frame 549 * @r: Pointer to MPT reply frame (NULL if TurboReply) 550 * 551 * This routine is called from mpt.c::mpt_interrupt() at the completion 552 * of any SCSI IO request. 553 * This routine is registered with the Fusion MPT (base) driver at driver 554 * load/init time via the mpt_register() API call. 555 * 556 * Returns 1 indicating alloc'd request frame ptr should be freed. 557 */ 558 int 559 mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) 560 { 561 struct scsi_cmnd *sc; 562 MPT_SCSI_HOST *hd; 563 SCSIIORequest_t *pScsiReq; 564 SCSIIOReply_t *pScsiReply; 565 u16 req_idx; 566 567 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata; 568 569 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx); 570 sc = hd->ScsiLookup[req_idx]; 571 if (sc == NULL) { 572 MPIHeader_t *hdr = (MPIHeader_t *)mf; 573 574 /* Remark: writeSDP1 will use the ScsiDoneCtx 575 * If a SCSI I/O cmd, device disabled by OS and 576 * completion done. Cannot touch sc struct. Just free mem. 577 */ 578 if (hdr->Function == MPI_FUNCTION_SCSI_IO_REQUEST) 579 printk(MYIOC_s_ERR_FMT "NULL ScsiCmd ptr!\n", 580 ioc->name); 581 582 mptscsih_freeChainBuffers(ioc, req_idx); 583 return 1; 584 } 585 586 sc->result = DID_OK << 16; /* Set default reply as OK */ 587 pScsiReq = (SCSIIORequest_t *) mf; 588 pScsiReply = (SCSIIOReply_t *) mr; 589 590 if((ioc->facts.MsgVersion >= MPI_VERSION_01_05) && pScsiReply){ 591 dmfprintk((MYIOC_s_INFO_FMT 592 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d,task-tag=%d)\n", 593 ioc->name, mf, mr, sc, req_idx, pScsiReply->TaskTag)); 594 }else{ 595 dmfprintk((MYIOC_s_INFO_FMT 596 "ScsiDone (mf=%p,mr=%p,sc=%p,idx=%d)\n", 597 ioc->name, mf, mr, sc, req_idx)); 598 } 599 600 if (pScsiReply == NULL) { 601 /* special context reply handling */ 602 ; 603 } else { 604 u32 xfer_cnt; 605 u16 status; 606 u8 scsi_state, scsi_status; 607 608 status = le16_to_cpu(pScsiReply->IOCStatus) & MPI_IOCSTATUS_MASK; 609 scsi_state = pScsiReply->SCSIState; 610 scsi_status = pScsiReply->SCSIStatus; 611 xfer_cnt = le32_to_cpu(pScsiReply->TransferCount); 612 sc->resid = sc->request_bufflen - xfer_cnt; 613 614 /* 615 * if we get a data underrun indication, yet no data was 616 * transferred and the SCSI status indicates that the 617 * command was never started, change the data underrun 618 * to success 619 */ 620 if (status == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN && xfer_cnt == 0 && 621 (scsi_status == MPI_SCSI_STATUS_BUSY || 622 scsi_status == MPI_SCSI_STATUS_RESERVATION_CONFLICT || 623 scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL)) { 624 status = MPI_IOCSTATUS_SUCCESS; 625 } 626 627 dreplyprintk((KERN_NOTICE "Reply ha=%d id=%d lun=%d:\n" 628 "IOCStatus=%04xh SCSIState=%02xh SCSIStatus=%02xh\n" 629 "resid=%d bufflen=%d xfer_cnt=%d\n", 630 ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1], 631 status, scsi_state, scsi_status, sc->resid, 632 sc->request_bufflen, xfer_cnt)); 633 634 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) 635 mptscsih_copy_sense_data(sc, hd, mf, pScsiReply); 636 637 /* 638 * Look for + dump FCP ResponseInfo[]! 639 */ 640 if (scsi_state & MPI_SCSI_STATE_RESPONSE_INFO_VALID && 641 pScsiReply->ResponseInfo) { 642 printk(KERN_NOTICE "ha=%d id=%d lun=%d: " 643 "FCP_ResponseInfo=%08xh\n", 644 ioc->id, pScsiReq->TargetID, pScsiReq->LUN[1], 645 le32_to_cpu(pScsiReply->ResponseInfo)); 646 } 647 648 switch(status) { 649 case MPI_IOCSTATUS_BUSY: /* 0x0002 */ 650 /* CHECKME! 651 * Maybe: DRIVER_BUSY | SUGGEST_RETRY | DID_SOFT_ERROR (retry) 652 * But not: DID_BUS_BUSY lest one risk 653 * killing interrupt handler:-( 654 */ 655 sc->result = SAM_STAT_BUSY; 656 break; 657 658 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */ 659 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */ 660 sc->result = DID_BAD_TARGET << 16; 661 break; 662 663 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */ 664 /* Spoof to SCSI Selection Timeout! */ 665 sc->result = DID_NO_CONNECT << 16; 666 667 if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF) 668 hd->sel_timeout[pScsiReq->TargetID]++; 669 break; 670 671 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */ 672 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */ 673 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */ 674 /* Linux handles an unsolicited DID_RESET better 675 * than an unsolicited DID_ABORT. 676 */ 677 sc->result = DID_RESET << 16; 678 679 /* GEM Workaround. */ 680 if (ioc->bus_type == SCSI) 681 mptscsih_no_negotiate(hd, sc->device->id); 682 break; 683 684 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */ 685 sc->resid = sc->request_bufflen - xfer_cnt; 686 if((xfer_cnt==0)||(sc->underflow > xfer_cnt)) 687 sc->result=DID_SOFT_ERROR << 16; 688 else /* Sufficient data transfer occurred */ 689 sc->result = (DID_OK << 16) | scsi_status; 690 dreplyprintk((KERN_NOTICE 691 "RESIDUAL_MISMATCH: result=%x on id=%d\n", sc->result, sc->device->id)); 692 break; 693 694 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */ 695 /* 696 * Do upfront check for valid SenseData and give it 697 * precedence! 698 */ 699 sc->result = (DID_OK << 16) | scsi_status; 700 if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) { 701 /* Have already saved the status and sense data 702 */ 703 ; 704 } else { 705 if (xfer_cnt < sc->underflow) { 706 if (scsi_status == SAM_STAT_BUSY) 707 sc->result = SAM_STAT_BUSY; 708 else 709 sc->result = DID_SOFT_ERROR << 16; 710 } 711 if (scsi_state & (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS)) { 712 /* What to do? 713 */ 714 sc->result = DID_SOFT_ERROR << 16; 715 } 716 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) { 717 /* Not real sure here either... */ 718 sc->result = DID_RESET << 16; 719 } 720 } 721 722 dreplyprintk((KERN_NOTICE " sc->underflow={report ERR if < %02xh bytes xfer'd}\n", 723 sc->underflow)); 724 dreplyprintk((KERN_NOTICE " ActBytesXferd=%02xh\n", xfer_cnt)); 725 /* Report Queue Full 726 */ 727 if (scsi_status == MPI_SCSI_STATUS_TASK_SET_FULL) 728 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq); 729 730 break; 731 732 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */ 733 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */ 734 if (scsi_status == MPI_SCSI_STATUS_BUSY) 735 sc->result = (DID_BUS_BUSY << 16) | scsi_status; 736 else 737 sc->result = (DID_OK << 16) | scsi_status; 738 if (scsi_state == 0) { 739 ; 740 } else if (scsi_state & MPI_SCSI_STATE_AUTOSENSE_VALID) { 741 /* 742 * If running against circa 200003dd 909 MPT f/w, 743 * may get this (AUTOSENSE_VALID) for actual TASK_SET_FULL 744 * (QUEUE_FULL) returned from device! --> get 0x0000?128 745 * and with SenseBytes set to 0. 746 */ 747 if (pScsiReply->SCSIStatus == MPI_SCSI_STATUS_TASK_SET_FULL) 748 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq); 749 750 } 751 else if (scsi_state & 752 (MPI_SCSI_STATE_AUTOSENSE_FAILED | MPI_SCSI_STATE_NO_SCSI_STATUS) 753 ) { 754 /* 755 * What to do? 756 */ 757 sc->result = DID_SOFT_ERROR << 16; 758 } 759 else if (scsi_state & MPI_SCSI_STATE_TERMINATED) { 760 /* Not real sure here either... */ 761 sc->result = DID_RESET << 16; 762 } 763 else if (scsi_state & MPI_SCSI_STATE_QUEUE_TAG_REJECTED) { 764 /* Device Inq. data indicates that it supports 765 * QTags, but rejects QTag messages. 766 * This command completed OK. 767 * 768 * Not real sure here either so do nothing... */ 769 } 770 771 if (sc->result == MPI_SCSI_STATUS_TASK_SET_FULL) 772 mptscsih_report_queue_full(sc, pScsiReply, pScsiReq); 773 774 /* Add handling of: 775 * Reservation Conflict, Busy, 776 * Command Terminated, CHECK 777 */ 778 break; 779 780 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */ 781 sc->result = DID_SOFT_ERROR << 16; 782 break; 783 784 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */ 785 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */ 786 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */ 787 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */ 788 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */ 789 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */ 790 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */ 791 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */ 792 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */ 793 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */ 794 default: 795 /* 796 * What to do? 797 */ 798 sc->result = DID_SOFT_ERROR << 16; 799 break; 800 801 } /* switch(status) */ 802 803 dreplyprintk((KERN_NOTICE " sc->result is %08xh\n", sc->result)); 804 } /* end of address reply case */ 805 806 /* Unmap the DMA buffers, if any. */ 807 if (sc->use_sg) { 808 pci_unmap_sg(ioc->pcidev, (struct scatterlist *) sc->request_buffer, 809 sc->use_sg, sc->sc_data_direction); 810 } else if (sc->request_bufflen) { 811 pci_unmap_single(ioc->pcidev, sc->SCp.dma_handle, 812 sc->request_bufflen, sc->sc_data_direction); 813 } 814 815 hd->ScsiLookup[req_idx] = NULL; 816 817 sc->scsi_done(sc); /* Issue the command callback */ 818 819 /* Free Chain buffers */ 820 mptscsih_freeChainBuffers(ioc, req_idx); 821 return 1; 822 } 823 824 /* 825 * mptscsih_flush_running_cmds - For each command found, search 826 * Scsi_Host instance taskQ and reply to OS. 827 * Called only if recovering from a FW reload. 828 * @hd: Pointer to a SCSI HOST structure 829 * 830 * Returns: None. 831 * 832 * Must be called while new I/Os are being queued. 833 */ 834 static void 835 mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd) 836 { 837 MPT_ADAPTER *ioc = hd->ioc; 838 struct scsi_cmnd *SCpnt; 839 MPT_FRAME_HDR *mf; 840 int ii; 841 int max = ioc->req_depth; 842 843 dprintk((KERN_INFO MYNAM ": flush_ScsiLookup called\n")); 844 for (ii= 0; ii < max; ii++) { 845 if ((SCpnt = hd->ScsiLookup[ii]) != NULL) { 846 847 /* Command found. 848 */ 849 850 /* Null ScsiLookup index 851 */ 852 hd->ScsiLookup[ii] = NULL; 853 854 mf = MPT_INDEX_2_MFPTR(ioc, ii); 855 dmfprintk(( "flush: ScsiDone (mf=%p,sc=%p)\n", 856 mf, SCpnt)); 857 858 /* Set status, free OS resources (SG DMA buffers) 859 * Do OS callback 860 * Free driver resources (chain, msg buffers) 861 */ 862 if (SCpnt->use_sg) { 863 pci_unmap_sg(ioc->pcidev, 864 (struct scatterlist *) SCpnt->request_buffer, 865 SCpnt->use_sg, 866 SCpnt->sc_data_direction); 867 } else if (SCpnt->request_bufflen) { 868 pci_unmap_single(ioc->pcidev, 869 SCpnt->SCp.dma_handle, 870 SCpnt->request_bufflen, 871 SCpnt->sc_data_direction); 872 } 873 SCpnt->result = DID_RESET << 16; 874 SCpnt->host_scribble = NULL; 875 876 /* Free Chain buffers */ 877 mptscsih_freeChainBuffers(ioc, ii); 878 879 /* Free Message frames */ 880 mpt_free_msg_frame(ioc, mf); 881 882 SCpnt->scsi_done(SCpnt); /* Issue the command callback */ 883 } 884 } 885 886 return; 887 } 888 889 /* 890 * mptscsih_search_running_cmds - Delete any commands associated 891 * with the specified target and lun. Function called only 892 * when a lun is disable by mid-layer. 893 * Do NOT access the referenced scsi_cmnd structure or 894 * members. Will cause either a paging or NULL ptr error. 895 * @hd: Pointer to a SCSI HOST structure 896 * @target: target id 897 * @lun: lun 898 * 899 * Returns: None. 900 * 901 * Called from slave_destroy. 902 */ 903 static void 904 mptscsih_search_running_cmds(MPT_SCSI_HOST *hd, uint target, uint lun) 905 { 906 SCSIIORequest_t *mf = NULL; 907 int ii; 908 int max = hd->ioc->req_depth; 909 struct scsi_cmnd *sc; 910 911 dsprintk((KERN_INFO MYNAM ": search_running target %d lun %d max %d\n", 912 target, lun, max)); 913 914 for (ii=0; ii < max; ii++) { 915 if ((sc = hd->ScsiLookup[ii]) != NULL) { 916 917 mf = (SCSIIORequest_t *)MPT_INDEX_2_MFPTR(hd->ioc, ii); 918 919 dsprintk(( "search_running: found (sc=%p, mf = %p) target %d, lun %d \n", 920 hd->ScsiLookup[ii], mf, mf->TargetID, mf->LUN[1])); 921 922 if ((mf->TargetID != ((u8)target)) || (mf->LUN[1] != ((u8) lun))) 923 continue; 924 925 /* Cleanup 926 */ 927 hd->ScsiLookup[ii] = NULL; 928 mptscsih_freeChainBuffers(hd->ioc, ii); 929 mpt_free_msg_frame(hd->ioc, (MPT_FRAME_HDR *)mf); 930 if (sc->use_sg) { 931 pci_unmap_sg(hd->ioc->pcidev, 932 (struct scatterlist *) sc->request_buffer, 933 sc->use_sg, 934 sc->sc_data_direction); 935 } else if (sc->request_bufflen) { 936 pci_unmap_single(hd->ioc->pcidev, 937 sc->SCp.dma_handle, 938 sc->request_bufflen, 939 sc->sc_data_direction); 940 } 941 sc->host_scribble = NULL; 942 sc->result = DID_NO_CONNECT << 16; 943 sc->scsi_done(sc); 944 } 945 } 946 return; 947 } 948 949 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 950 951 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 952 /* 953 * mptscsih_report_queue_full - Report QUEUE_FULL status returned 954 * from a SCSI target device. 955 * @sc: Pointer to scsi_cmnd structure 956 * @pScsiReply: Pointer to SCSIIOReply_t 957 * @pScsiReq: Pointer to original SCSI request 958 * 959 * This routine periodically reports QUEUE_FULL status returned from a 960 * SCSI target device. It reports this to the console via kernel 961 * printk() API call, not more than once every 10 seconds. 962 */ 963 static void 964 mptscsih_report_queue_full(struct scsi_cmnd *sc, SCSIIOReply_t *pScsiReply, SCSIIORequest_t *pScsiReq) 965 { 966 long time = jiffies; 967 MPT_SCSI_HOST *hd; 968 969 if (sc->device == NULL) 970 return; 971 if (sc->device->host == NULL) 972 return; 973 if ((hd = (MPT_SCSI_HOST *)sc->device->host->hostdata) == NULL) 974 return; 975 976 if (time - hd->last_queue_full > 10 * HZ) { 977 dprintk((MYIOC_s_WARN_FMT "Device (%d:%d:%d) reported QUEUE_FULL!\n", 978 hd->ioc->name, 0, sc->device->id, sc->device->lun)); 979 hd->last_queue_full = time; 980 } 981 } 982 983 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 984 /* 985 * mptscsih_remove - Removed scsi devices 986 * @pdev: Pointer to pci_dev structure 987 * 988 * 989 */ 990 void 991 mptscsih_remove(struct pci_dev *pdev) 992 { 993 MPT_ADAPTER *ioc = pci_get_drvdata(pdev); 994 struct Scsi_Host *host = ioc->sh; 995 MPT_SCSI_HOST *hd; 996 int count; 997 unsigned long flags; 998 int sz1; 999 1000 if(!host) { 1001 mpt_detach(pdev); 1002 return; 1003 } 1004 1005 scsi_remove_host(host); 1006 1007 if((hd = (MPT_SCSI_HOST *)host->hostdata) == NULL) 1008 return; 1009 1010 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION 1011 /* Check DV thread active */ 1012 count = 10 * HZ; 1013 spin_lock_irqsave(&dvtaskQ_lock, flags); 1014 if (dvtaskQ_active) { 1015 spin_unlock_irqrestore(&dvtaskQ_lock, flags); 1016 while(dvtaskQ_active && --count) 1017 schedule_timeout_interruptible(1); 1018 } else { 1019 spin_unlock_irqrestore(&dvtaskQ_lock, flags); 1020 } 1021 if (!count) 1022 printk(KERN_ERR MYNAM ": ERROR - DV thread still active!\n"); 1023 #if defined(MPT_DEBUG_DV) || defined(MPT_DEBUG_DV_TINY) 1024 else 1025 printk(KERN_ERR MYNAM ": DV thread orig %d, count %d\n", 10 * HZ, count); 1026 #endif 1027 #endif 1028 1029 mptscsih_shutdown(pdev); 1030 1031 sz1=0; 1032 1033 if (hd->ScsiLookup != NULL) { 1034 sz1 = hd->ioc->req_depth * sizeof(void *); 1035 kfree(hd->ScsiLookup); 1036 hd->ScsiLookup = NULL; 1037 } 1038 1039 /* 1040 * Free pointer array. 1041 */ 1042 kfree(hd->Targets); 1043 hd->Targets = NULL; 1044 1045 dprintk((MYIOC_s_INFO_FMT 1046 "Free'd ScsiLookup (%d) memory\n", 1047 hd->ioc->name, sz1)); 1048 1049 kfree(hd->info_kbuf); 1050 1051 /* NULL the Scsi_Host pointer 1052 */ 1053 hd->ioc->sh = NULL; 1054 1055 scsi_host_put(host); 1056 1057 mpt_detach(pdev); 1058 1059 } 1060 1061 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1062 /* 1063 * mptscsih_shutdown - reboot notifier 1064 * 1065 */ 1066 void 1067 mptscsih_shutdown(struct pci_dev *pdev) 1068 { 1069 MPT_ADAPTER *ioc = pci_get_drvdata(pdev); 1070 struct Scsi_Host *host = ioc->sh; 1071 MPT_SCSI_HOST *hd; 1072 1073 if(!host) 1074 return; 1075 1076 hd = (MPT_SCSI_HOST *)host->hostdata; 1077 1078 /* Flush the cache of this adapter 1079 */ 1080 if(hd != NULL) 1081 mptscsih_synchronize_cache(hd, 0); 1082 1083 } 1084 1085 #ifdef CONFIG_PM 1086 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1087 /* 1088 * mptscsih_suspend - Fusion MPT scsi driver suspend routine. 1089 * 1090 * 1091 */ 1092 int 1093 mptscsih_suspend(struct pci_dev *pdev, pm_message_t state) 1094 { 1095 mptscsih_shutdown(pdev); 1096 return mpt_suspend(pdev,state); 1097 } 1098 1099 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1100 /* 1101 * mptscsih_resume - Fusion MPT scsi driver resume routine. 1102 * 1103 * 1104 */ 1105 int 1106 mptscsih_resume(struct pci_dev *pdev) 1107 { 1108 MPT_ADAPTER *ioc = pci_get_drvdata(pdev); 1109 struct Scsi_Host *host = ioc->sh; 1110 MPT_SCSI_HOST *hd; 1111 1112 mpt_resume(pdev); 1113 1114 if(!host) 1115 return 0; 1116 1117 hd = (MPT_SCSI_HOST *)host->hostdata; 1118 if(!hd) 1119 return 0; 1120 1121 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION 1122 { 1123 unsigned long lflags; 1124 spin_lock_irqsave(&dvtaskQ_lock, lflags); 1125 if (!dvtaskQ_active) { 1126 dvtaskQ_active = 1; 1127 spin_unlock_irqrestore(&dvtaskQ_lock, lflags); 1128 INIT_WORK(&dvTaskQ_task, 1129 mptscsih_domainValidation, (void *) hd); 1130 schedule_work(&dvTaskQ_task); 1131 } else { 1132 spin_unlock_irqrestore(&dvtaskQ_lock, lflags); 1133 } 1134 } 1135 #endif 1136 return 0; 1137 } 1138 1139 #endif 1140 1141 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1142 /** 1143 * mptscsih_info - Return information about MPT adapter 1144 * @SChost: Pointer to Scsi_Host structure 1145 * 1146 * (linux scsi_host_template.info routine) 1147 * 1148 * Returns pointer to buffer where information was written. 1149 */ 1150 const char * 1151 mptscsih_info(struct Scsi_Host *SChost) 1152 { 1153 MPT_SCSI_HOST *h; 1154 int size = 0; 1155 1156 h = (MPT_SCSI_HOST *)SChost->hostdata; 1157 1158 if (h) { 1159 if (h->info_kbuf == NULL) 1160 if ((h->info_kbuf = kmalloc(0x1000 /* 4Kb */, GFP_KERNEL)) == NULL) 1161 return h->info_kbuf; 1162 h->info_kbuf[0] = '\0'; 1163 1164 mpt_print_ioc_summary(h->ioc, h->info_kbuf, &size, 0, 0); 1165 h->info_kbuf[size-1] = '\0'; 1166 } 1167 1168 return h->info_kbuf; 1169 } 1170 1171 struct info_str { 1172 char *buffer; 1173 int length; 1174 int offset; 1175 int pos; 1176 }; 1177 1178 static void 1179 mptscsih_copy_mem_info(struct info_str *info, char *data, int len) 1180 { 1181 if (info->pos + len > info->length) 1182 len = info->length - info->pos; 1183 1184 if (info->pos + len < info->offset) { 1185 info->pos += len; 1186 return; 1187 } 1188 1189 if (info->pos < info->offset) { 1190 data += (info->offset - info->pos); 1191 len -= (info->offset - info->pos); 1192 } 1193 1194 if (len > 0) { 1195 memcpy(info->buffer + info->pos, data, len); 1196 info->pos += len; 1197 } 1198 } 1199 1200 static int 1201 mptscsih_copy_info(struct info_str *info, char *fmt, ...) 1202 { 1203 va_list args; 1204 char buf[81]; 1205 int len; 1206 1207 va_start(args, fmt); 1208 len = vsprintf(buf, fmt, args); 1209 va_end(args); 1210 1211 mptscsih_copy_mem_info(info, buf, len); 1212 return len; 1213 } 1214 1215 static int 1216 mptscsih_host_info(MPT_ADAPTER *ioc, char *pbuf, off_t offset, int len) 1217 { 1218 struct info_str info; 1219 1220 info.buffer = pbuf; 1221 info.length = len; 1222 info.offset = offset; 1223 info.pos = 0; 1224 1225 mptscsih_copy_info(&info, "%s: %s, ", ioc->name, ioc->prod_name); 1226 mptscsih_copy_info(&info, "%s%08xh, ", MPT_FW_REV_MAGIC_ID_STRING, ioc->facts.FWVersion.Word); 1227 mptscsih_copy_info(&info, "Ports=%d, ", ioc->facts.NumberOfPorts); 1228 mptscsih_copy_info(&info, "MaxQ=%d\n", ioc->req_depth); 1229 1230 return ((info.pos > info.offset) ? info.pos - info.offset : 0); 1231 } 1232 1233 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1234 /** 1235 * mptscsih_proc_info - Return information about MPT adapter 1236 * 1237 * (linux scsi_host_template.info routine) 1238 * 1239 * buffer: if write, user data; if read, buffer for user 1240 * length: if write, return length; 1241 * offset: if write, 0; if read, the current offset into the buffer from 1242 * the previous read. 1243 * hostno: scsi host number 1244 * func: if write = 1; if read = 0 1245 */ 1246 int 1247 mptscsih_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset, 1248 int length, int func) 1249 { 1250 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; 1251 MPT_ADAPTER *ioc = hd->ioc; 1252 int size = 0; 1253 1254 if (func) { 1255 /* 1256 * write is not supported 1257 */ 1258 } else { 1259 if (start) 1260 *start = buffer; 1261 1262 size = mptscsih_host_info(ioc, buffer, offset, length); 1263 } 1264 1265 return size; 1266 } 1267 1268 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1269 #define ADD_INDEX_LOG(req_ent) do { } while(0) 1270 1271 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1272 /** 1273 * mptscsih_qcmd - Primary Fusion MPT SCSI initiator IO start routine. 1274 * @SCpnt: Pointer to scsi_cmnd structure 1275 * @done: Pointer SCSI mid-layer IO completion function 1276 * 1277 * (linux scsi_host_template.queuecommand routine) 1278 * This is the primary SCSI IO start routine. Create a MPI SCSIIORequest 1279 * from a linux scsi_cmnd request and send it to the IOC. 1280 * 1281 * Returns 0. (rtn value discarded by linux scsi mid-layer) 1282 */ 1283 int 1284 mptscsih_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *)) 1285 { 1286 MPT_SCSI_HOST *hd; 1287 MPT_FRAME_HDR *mf; 1288 SCSIIORequest_t *pScsiReq; 1289 VirtDevice *pTarget = SCpnt->device->hostdata; 1290 int lun; 1291 u32 datalen; 1292 u32 scsictl; 1293 u32 scsidir; 1294 u32 cmd_len; 1295 int my_idx; 1296 int ii; 1297 1298 hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata; 1299 lun = SCpnt->device->lun; 1300 SCpnt->scsi_done = done; 1301 1302 dmfprintk((MYIOC_s_INFO_FMT "qcmd: SCpnt=%p, done()=%p\n", 1303 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt, done)); 1304 1305 if (hd->resetPending) { 1306 dtmprintk((MYIOC_s_WARN_FMT "qcmd: SCpnt=%p timeout + 60HZ\n", 1307 (hd && hd->ioc) ? hd->ioc->name : "ioc?", SCpnt)); 1308 return SCSI_MLQUEUE_HOST_BUSY; 1309 } 1310 1311 /* 1312 * Put together a MPT SCSI request... 1313 */ 1314 if ((mf = mpt_get_msg_frame(hd->ioc->DoneCtx, hd->ioc)) == NULL) { 1315 dprintk((MYIOC_s_WARN_FMT "QueueCmd, no msg frames!!\n", 1316 hd->ioc->name)); 1317 return SCSI_MLQUEUE_HOST_BUSY; 1318 } 1319 1320 pScsiReq = (SCSIIORequest_t *) mf; 1321 1322 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx); 1323 1324 ADD_INDEX_LOG(my_idx); 1325 1326 /* TUR's being issued with scsictl=0x02000000 (DATA_IN)! 1327 * Seems we may receive a buffer (datalen>0) even when there 1328 * will be no data transfer! GRRRRR... 1329 */ 1330 if (SCpnt->sc_data_direction == DMA_FROM_DEVICE) { 1331 datalen = SCpnt->request_bufflen; 1332 scsidir = MPI_SCSIIO_CONTROL_READ; /* DATA IN (host<--ioc<--dev) */ 1333 } else if (SCpnt->sc_data_direction == DMA_TO_DEVICE) { 1334 datalen = SCpnt->request_bufflen; 1335 scsidir = MPI_SCSIIO_CONTROL_WRITE; /* DATA OUT (host-->ioc-->dev) */ 1336 } else { 1337 datalen = 0; 1338 scsidir = MPI_SCSIIO_CONTROL_NODATATRANSFER; 1339 } 1340 1341 /* Default to untagged. Once a target structure has been allocated, 1342 * use the Inquiry data to determine if device supports tagged. 1343 */ 1344 if (pTarget 1345 && (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES) 1346 && (SCpnt->device->tagged_supported)) { 1347 scsictl = scsidir | MPI_SCSIIO_CONTROL_SIMPLEQ; 1348 } else { 1349 scsictl = scsidir | MPI_SCSIIO_CONTROL_UNTAGGED; 1350 } 1351 1352 /* Use the above information to set up the message frame 1353 */ 1354 pScsiReq->TargetID = (u8) pTarget->target_id; 1355 pScsiReq->Bus = pTarget->bus_id; 1356 pScsiReq->ChainOffset = 0; 1357 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST; 1358 pScsiReq->CDBLength = SCpnt->cmd_len; 1359 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE; 1360 pScsiReq->Reserved = 0; 1361 pScsiReq->MsgFlags = mpt_msg_flags(); 1362 pScsiReq->LUN[0] = 0; 1363 pScsiReq->LUN[1] = lun; 1364 pScsiReq->LUN[2] = 0; 1365 pScsiReq->LUN[3] = 0; 1366 pScsiReq->LUN[4] = 0; 1367 pScsiReq->LUN[5] = 0; 1368 pScsiReq->LUN[6] = 0; 1369 pScsiReq->LUN[7] = 0; 1370 pScsiReq->Control = cpu_to_le32(scsictl); 1371 1372 /* 1373 * Write SCSI CDB into the message 1374 */ 1375 cmd_len = SCpnt->cmd_len; 1376 for (ii=0; ii < cmd_len; ii++) 1377 pScsiReq->CDB[ii] = SCpnt->cmnd[ii]; 1378 1379 for (ii=cmd_len; ii < 16; ii++) 1380 pScsiReq->CDB[ii] = 0; 1381 1382 /* DataLength */ 1383 pScsiReq->DataLength = cpu_to_le32(datalen); 1384 1385 /* SenseBuffer low address */ 1386 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma 1387 + (my_idx * MPT_SENSE_BUFFER_ALLOC)); 1388 1389 /* Now add the SG list 1390 * Always have a SGE even if null length. 1391 */ 1392 if (datalen == 0) { 1393 /* Add a NULL SGE */ 1394 mptscsih_add_sge((char *)&pScsiReq->SGL, MPT_SGE_FLAGS_SSIMPLE_READ | 0, 1395 (dma_addr_t) -1); 1396 } else { 1397 /* Add a 32 or 64 bit SGE */ 1398 if (mptscsih_AddSGE(hd->ioc, SCpnt, pScsiReq, my_idx) != SUCCESS) 1399 goto fail; 1400 } 1401 1402 hd->ScsiLookup[my_idx] = SCpnt; 1403 SCpnt->host_scribble = NULL; 1404 1405 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION 1406 if (hd->ioc->bus_type == SCSI) { 1407 int dvStatus = hd->ioc->spi_data.dvStatus[pTarget->target_id]; 1408 int issueCmd = 1; 1409 1410 if (dvStatus || hd->ioc->spi_data.forceDv) { 1411 1412 if ((dvStatus & MPT_SCSICFG_NEED_DV) || 1413 (hd->ioc->spi_data.forceDv & MPT_SCSICFG_NEED_DV)) { 1414 unsigned long lflags; 1415 /* Schedule DV if necessary */ 1416 spin_lock_irqsave(&dvtaskQ_lock, lflags); 1417 if (!dvtaskQ_active) { 1418 dvtaskQ_active = 1; 1419 spin_unlock_irqrestore(&dvtaskQ_lock, lflags); 1420 INIT_WORK(&dvTaskQ_task, mptscsih_domainValidation, (void *) hd); 1421 1422 schedule_work(&dvTaskQ_task); 1423 } else { 1424 spin_unlock_irqrestore(&dvtaskQ_lock, lflags); 1425 } 1426 hd->ioc->spi_data.forceDv &= ~MPT_SCSICFG_NEED_DV; 1427 } 1428 1429 /* Trying to do DV to this target, extend timeout. 1430 * Wait to issue until flag is clear 1431 */ 1432 if (dvStatus & MPT_SCSICFG_DV_PENDING) { 1433 mod_timer(&SCpnt->eh_timeout, jiffies + 40 * HZ); 1434 issueCmd = 0; 1435 } 1436 1437 /* Set the DV flags. 1438 */ 1439 if (dvStatus & MPT_SCSICFG_DV_NOT_DONE) 1440 mptscsih_set_dvflags(hd, pScsiReq); 1441 1442 if (!issueCmd) 1443 goto fail; 1444 } 1445 } 1446 #endif 1447 1448 mpt_put_msg_frame(hd->ioc->DoneCtx, hd->ioc, mf); 1449 dmfprintk((MYIOC_s_INFO_FMT "Issued SCSI cmd (%p) mf=%p idx=%d\n", 1450 hd->ioc->name, SCpnt, mf, my_idx)); 1451 DBG_DUMP_REQUEST_FRAME(mf) 1452 return 0; 1453 1454 fail: 1455 hd->ScsiLookup[my_idx] = NULL; 1456 mptscsih_freeChainBuffers(hd->ioc, my_idx); 1457 mpt_free_msg_frame(hd->ioc, mf); 1458 return SCSI_MLQUEUE_HOST_BUSY; 1459 } 1460 1461 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1462 /* 1463 * mptscsih_freeChainBuffers - Function to free chain buffers associated 1464 * with a SCSI IO request 1465 * @hd: Pointer to the MPT_SCSI_HOST instance 1466 * @req_idx: Index of the SCSI IO request frame. 1467 * 1468 * Called if SG chain buffer allocation fails and mptscsih callbacks. 1469 * No return. 1470 */ 1471 static void 1472 mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx) 1473 { 1474 MPT_FRAME_HDR *chain; 1475 unsigned long flags; 1476 int chain_idx; 1477 int next; 1478 1479 /* Get the first chain index and reset 1480 * tracker state. 1481 */ 1482 chain_idx = ioc->ReqToChain[req_idx]; 1483 ioc->ReqToChain[req_idx] = MPT_HOST_NO_CHAIN; 1484 1485 while (chain_idx != MPT_HOST_NO_CHAIN) { 1486 1487 /* Save the next chain buffer index */ 1488 next = ioc->ChainToChain[chain_idx]; 1489 1490 /* Free this chain buffer and reset 1491 * tracker 1492 */ 1493 ioc->ChainToChain[chain_idx] = MPT_HOST_NO_CHAIN; 1494 1495 chain = (MPT_FRAME_HDR *) (ioc->ChainBuffer 1496 + (chain_idx * ioc->req_sz)); 1497 1498 spin_lock_irqsave(&ioc->FreeQlock, flags); 1499 list_add_tail(&chain->u.frame.linkage.list, &ioc->FreeChainQ); 1500 spin_unlock_irqrestore(&ioc->FreeQlock, flags); 1501 1502 dmfprintk((MYIOC_s_INFO_FMT "FreeChainBuffers (index %d)\n", 1503 ioc->name, chain_idx)); 1504 1505 /* handle next */ 1506 chain_idx = next; 1507 } 1508 return; 1509 } 1510 1511 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1512 /* 1513 * Reset Handling 1514 */ 1515 1516 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1517 /* 1518 * mptscsih_TMHandler - Generic handler for SCSI Task Management. 1519 * Fall through to mpt_HardResetHandler if: not operational, too many 1520 * failed TM requests or handshake failure. 1521 * 1522 * @ioc: Pointer to MPT_ADAPTER structure 1523 * @type: Task Management type 1524 * @target: Logical Target ID for reset (if appropriate) 1525 * @lun: Logical Unit for reset (if appropriate) 1526 * @ctx2abort: Context for the task to be aborted (if appropriate) 1527 * 1528 * Remark: Currently invoked from a non-interrupt thread (_bh). 1529 * 1530 * Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC 1531 * will be active. 1532 * 1533 * Returns 0 for SUCCESS or -1 if FAILED. 1534 */ 1535 static int 1536 mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout) 1537 { 1538 MPT_ADAPTER *ioc; 1539 int rc = -1; 1540 int doTask = 1; 1541 u32 ioc_raw_state; 1542 unsigned long flags; 1543 1544 /* If FW is being reloaded currently, return success to 1545 * the calling function. 1546 */ 1547 if (hd == NULL) 1548 return 0; 1549 1550 ioc = hd->ioc; 1551 if (ioc == NULL) { 1552 printk(KERN_ERR MYNAM " TMHandler" " NULL ioc!\n"); 1553 return FAILED; 1554 } 1555 dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name)); 1556 1557 // SJR - CHECKME - Can we avoid this here? 1558 // (mpt_HardResetHandler has this check...) 1559 spin_lock_irqsave(&ioc->diagLock, flags); 1560 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)) { 1561 spin_unlock_irqrestore(&ioc->diagLock, flags); 1562 return FAILED; 1563 } 1564 spin_unlock_irqrestore(&ioc->diagLock, flags); 1565 1566 /* Wait a fixed amount of time for the TM pending flag to be cleared. 1567 * If we time out and not bus reset, then we return a FAILED status to the caller. 1568 * The call to mptscsih_tm_pending_wait() will set the pending flag if we are 1569 * successful. Otherwise, reload the FW. 1570 */ 1571 if (mptscsih_tm_pending_wait(hd) == FAILED) { 1572 if (type == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) { 1573 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler abort: " 1574 "Timed out waiting for last TM (%d) to complete! \n", 1575 hd->ioc->name, hd->tmPending)); 1576 return FAILED; 1577 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) { 1578 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target reset: " 1579 "Timed out waiting for last TM (%d) to complete! \n", 1580 hd->ioc->name, hd->tmPending)); 1581 return FAILED; 1582 } else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) { 1583 dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: " 1584 "Timed out waiting for last TM (%d) to complete! \n", 1585 hd->ioc->name, hd->tmPending)); 1586 if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)) 1587 return FAILED; 1588 1589 doTask = 0; 1590 } 1591 } else { 1592 spin_lock_irqsave(&hd->ioc->FreeQlock, flags); 1593 hd->tmPending |= (1 << type); 1594 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); 1595 } 1596 1597 /* Is operational? 1598 */ 1599 ioc_raw_state = mpt_GetIocState(hd->ioc, 0); 1600 1601 #ifdef MPT_DEBUG_RESET 1602 if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) { 1603 printk(MYIOC_s_WARN_FMT 1604 "TM Handler: IOC Not operational(0x%x)!\n", 1605 hd->ioc->name, ioc_raw_state); 1606 } 1607 #endif 1608 1609 if (doTask && ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) 1610 && !(ioc_raw_state & MPI_DOORBELL_ACTIVE)) { 1611 1612 /* Isse the Task Mgmt request. 1613 */ 1614 if (hd->hard_resets < -1) 1615 hd->hard_resets++; 1616 rc = mptscsih_IssueTaskMgmt(hd, type, channel, target, lun, ctx2abort, timeout); 1617 if (rc) { 1618 printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name); 1619 } else { 1620 dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name)); 1621 } 1622 } 1623 1624 /* Only fall through to the HRH if this is a bus reset 1625 */ 1626 if ((type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && (rc || 1627 ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) { 1628 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n", 1629 hd->ioc->name)); 1630 rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP); 1631 } 1632 1633 dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc)); 1634 1635 return rc; 1636 } 1637 1638 1639 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1640 /* 1641 * mptscsih_IssueTaskMgmt - Generic send Task Management function. 1642 * @hd: Pointer to MPT_SCSI_HOST structure 1643 * @type: Task Management type 1644 * @target: Logical Target ID for reset (if appropriate) 1645 * @lun: Logical Unit for reset (if appropriate) 1646 * @ctx2abort: Context for the task to be aborted (if appropriate) 1647 * 1648 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer) 1649 * or a non-interrupt thread. In the former, must not call schedule(). 1650 * 1651 * Not all fields are meaningfull for all task types. 1652 * 1653 * Returns 0 for SUCCESS, -999 for "no msg frames", 1654 * else other non-zero value returned. 1655 */ 1656 static int 1657 mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout) 1658 { 1659 MPT_FRAME_HDR *mf; 1660 SCSITaskMgmt_t *pScsiTm; 1661 int ii; 1662 int retval; 1663 1664 /* Return Fail to calling function if no message frames available. 1665 */ 1666 if ((mf = mpt_get_msg_frame(hd->ioc->TaskCtx, hd->ioc)) == NULL) { 1667 dfailprintk((MYIOC_s_ERR_FMT "IssueTaskMgmt, no msg frames!!\n", 1668 hd->ioc->name)); 1669 return FAILED; 1670 } 1671 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt request @ %p\n", 1672 hd->ioc->name, mf)); 1673 1674 /* Format the Request 1675 */ 1676 pScsiTm = (SCSITaskMgmt_t *) mf; 1677 pScsiTm->TargetID = target; 1678 pScsiTm->Bus = channel; 1679 pScsiTm->ChainOffset = 0; 1680 pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT; 1681 1682 pScsiTm->Reserved = 0; 1683 pScsiTm->TaskType = type; 1684 pScsiTm->Reserved1 = 0; 1685 pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) 1686 ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0; 1687 1688 for (ii= 0; ii < 8; ii++) { 1689 pScsiTm->LUN[ii] = 0; 1690 } 1691 pScsiTm->LUN[1] = lun; 1692 1693 for (ii=0; ii < 7; ii++) 1694 pScsiTm->Reserved2[ii] = 0; 1695 1696 pScsiTm->TaskMsgContext = ctx2abort; 1697 1698 dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n", 1699 hd->ioc->name, ctx2abort, type)); 1700 1701 DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm); 1702 1703 if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc, 1704 sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, 1705 CAN_SLEEP)) != 0) { 1706 dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!" 1707 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd, 1708 hd->ioc, mf)); 1709 mpt_free_msg_frame(hd->ioc, mf); 1710 return retval; 1711 } 1712 1713 if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) { 1714 dfailprintk((MYIOC_s_ERR_FMT "_wait_for_completion FAILED!" 1715 " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd, 1716 hd->ioc, mf)); 1717 mpt_free_msg_frame(hd->ioc, mf); 1718 dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n", 1719 hd->ioc->name)); 1720 retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP); 1721 } 1722 1723 return retval; 1724 } 1725 1726 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1727 /** 1728 * mptscsih_abort - Abort linux scsi_cmnd routine, new_eh variant 1729 * @SCpnt: Pointer to scsi_cmnd structure, IO to be aborted 1730 * 1731 * (linux scsi_host_template.eh_abort_handler routine) 1732 * 1733 * Returns SUCCESS or FAILED. 1734 */ 1735 int 1736 mptscsih_abort(struct scsi_cmnd * SCpnt) 1737 { 1738 MPT_SCSI_HOST *hd; 1739 MPT_ADAPTER *ioc; 1740 MPT_FRAME_HDR *mf; 1741 u32 ctx2abort; 1742 int scpnt_idx; 1743 int retval; 1744 1745 /* If we can't locate our host adapter structure, return FAILED status. 1746 */ 1747 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL) { 1748 SCpnt->result = DID_RESET << 16; 1749 SCpnt->scsi_done(SCpnt); 1750 dfailprintk((KERN_INFO MYNAM ": mptscsih_abort: " 1751 "Can't locate host! (sc=%p)\n", 1752 SCpnt)); 1753 return FAILED; 1754 } 1755 1756 ioc = hd->ioc; 1757 if (hd->resetPending) { 1758 return FAILED; 1759 } 1760 1761 if (hd->timeouts < -1) 1762 hd->timeouts++; 1763 1764 /* Find this command 1765 */ 1766 if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) { 1767 /* Cmd not found in ScsiLookup. 1768 * Do OS callback. 1769 */ 1770 SCpnt->result = DID_RESET << 16; 1771 dtmprintk((KERN_INFO MYNAM ": %s: mptscsih_abort: " 1772 "Command not in the active list! (sc=%p)\n", 1773 hd->ioc->name, SCpnt)); 1774 return SUCCESS; 1775 } 1776 1777 printk(KERN_WARNING MYNAM ": %s: attempting task abort! (sc=%p)\n", 1778 hd->ioc->name, SCpnt); 1779 scsi_print_command(SCpnt); 1780 1781 /* Most important! Set TaskMsgContext to SCpnt's MsgContext! 1782 * (the IO to be ABORT'd) 1783 * 1784 * NOTE: Since we do not byteswap MsgContext, we do not 1785 * swap it here either. It is an opaque cookie to 1786 * the controller, so it does not matter. -DaveM 1787 */ 1788 mf = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx); 1789 ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext; 1790 1791 hd->abortSCpnt = SCpnt; 1792 1793 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK, 1794 SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, 1795 ctx2abort, 2 /* 2 second timeout */); 1796 1797 printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n", 1798 hd->ioc->name, 1799 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt); 1800 1801 if (retval == 0) 1802 return SUCCESS; 1803 1804 if(retval != FAILED ) { 1805 hd->tmPending = 0; 1806 hd->tmState = TM_STATE_NONE; 1807 } 1808 return FAILED; 1809 } 1810 1811 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1812 /** 1813 * mptscsih_dev_reset - Perform a SCSI TARGET_RESET! new_eh variant 1814 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to 1815 * 1816 * (linux scsi_host_template.eh_dev_reset_handler routine) 1817 * 1818 * Returns SUCCESS or FAILED. 1819 */ 1820 int 1821 mptscsih_dev_reset(struct scsi_cmnd * SCpnt) 1822 { 1823 MPT_SCSI_HOST *hd; 1824 int retval; 1825 1826 /* If we can't locate our host adapter structure, return FAILED status. 1827 */ 1828 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){ 1829 dtmprintk((KERN_INFO MYNAM ": mptscsih_dev_reset: " 1830 "Can't locate host! (sc=%p)\n", 1831 SCpnt)); 1832 return FAILED; 1833 } 1834 1835 if (hd->resetPending) 1836 return FAILED; 1837 1838 printk(KERN_WARNING MYNAM ": %s: attempting target reset! (sc=%p)\n", 1839 hd->ioc->name, SCpnt); 1840 scsi_print_command(SCpnt); 1841 1842 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, 1843 SCpnt->device->channel, SCpnt->device->id, 1844 0, 0, 5 /* 5 second timeout */); 1845 1846 printk (KERN_WARNING MYNAM ": %s: target reset: %s (sc=%p)\n", 1847 hd->ioc->name, 1848 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt); 1849 1850 if (retval == 0) 1851 return SUCCESS; 1852 1853 if(retval != FAILED ) { 1854 hd->tmPending = 0; 1855 hd->tmState = TM_STATE_NONE; 1856 } 1857 return FAILED; 1858 } 1859 1860 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1861 /** 1862 * mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant 1863 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to 1864 * 1865 * (linux scsi_host_template.eh_bus_reset_handler routine) 1866 * 1867 * Returns SUCCESS or FAILED. 1868 */ 1869 int 1870 mptscsih_bus_reset(struct scsi_cmnd * SCpnt) 1871 { 1872 MPT_SCSI_HOST *hd; 1873 int retval; 1874 1875 /* If we can't locate our host adapter structure, return FAILED status. 1876 */ 1877 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){ 1878 dtmprintk((KERN_INFO MYNAM ": mptscsih_bus_reset: " 1879 "Can't locate host! (sc=%p)\n", 1880 SCpnt ) ); 1881 return FAILED; 1882 } 1883 1884 printk(KERN_WARNING MYNAM ": %s: attempting bus reset! (sc=%p)\n", 1885 hd->ioc->name, SCpnt); 1886 scsi_print_command(SCpnt); 1887 1888 if (hd->timeouts < -1) 1889 hd->timeouts++; 1890 1891 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, 1892 SCpnt->device->channel, 0, 0, 0, 5 /* 5 second timeout */); 1893 1894 printk (KERN_WARNING MYNAM ": %s: bus reset: %s (sc=%p)\n", 1895 hd->ioc->name, 1896 ((retval == 0) ? "SUCCESS" : "FAILED" ), SCpnt); 1897 1898 if (retval == 0) 1899 return SUCCESS; 1900 1901 if(retval != FAILED ) { 1902 hd->tmPending = 0; 1903 hd->tmState = TM_STATE_NONE; 1904 } 1905 return FAILED; 1906 } 1907 1908 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1909 /** 1910 * mptscsih_host_reset - Perform a SCSI host adapter RESET! 1911 * new_eh variant 1912 * @SCpnt: Pointer to scsi_cmnd structure, IO which reset is due to 1913 * 1914 * (linux scsi_host_template.eh_host_reset_handler routine) 1915 * 1916 * Returns SUCCESS or FAILED. 1917 */ 1918 int 1919 mptscsih_host_reset(struct scsi_cmnd *SCpnt) 1920 { 1921 MPT_SCSI_HOST * hd; 1922 int status = SUCCESS; 1923 1924 /* If we can't locate the host to reset, then we failed. */ 1925 if ((hd = (MPT_SCSI_HOST *) SCpnt->device->host->hostdata) == NULL){ 1926 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: " 1927 "Can't locate host! (sc=%p)\n", 1928 SCpnt ) ); 1929 return FAILED; 1930 } 1931 1932 printk(KERN_WARNING MYNAM ": %s: Attempting host reset! (sc=%p)\n", 1933 hd->ioc->name, SCpnt); 1934 1935 /* If our attempts to reset the host failed, then return a failed 1936 * status. The host will be taken off line by the SCSI mid-layer. 1937 */ 1938 if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0){ 1939 status = FAILED; 1940 } else { 1941 /* Make sure TM pending is cleared and TM state is set to 1942 * NONE. 1943 */ 1944 hd->tmPending = 0; 1945 hd->tmState = TM_STATE_NONE; 1946 } 1947 1948 dtmprintk( ( KERN_INFO MYNAM ": mptscsih_host_reset: " 1949 "Status = %s\n", 1950 (status == SUCCESS) ? "SUCCESS" : "FAILED" ) ); 1951 1952 return status; 1953 } 1954 1955 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1956 /** 1957 * mptscsih_tm_pending_wait - wait for pending task management request to 1958 * complete. 1959 * @hd: Pointer to MPT host structure. 1960 * 1961 * Returns {SUCCESS,FAILED}. 1962 */ 1963 static int 1964 mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd) 1965 { 1966 unsigned long flags; 1967 int loop_count = 4 * 10; /* Wait 10 seconds */ 1968 int status = FAILED; 1969 1970 do { 1971 spin_lock_irqsave(&hd->ioc->FreeQlock, flags); 1972 if (hd->tmState == TM_STATE_NONE) { 1973 hd->tmState = TM_STATE_IN_PROGRESS; 1974 hd->tmPending = 1; 1975 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); 1976 status = SUCCESS; 1977 break; 1978 } 1979 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); 1980 msleep(250); 1981 } while (--loop_count); 1982 1983 return status; 1984 } 1985 1986 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1987 /** 1988 * mptscsih_tm_wait_for_completion - wait for completion of TM task 1989 * @hd: Pointer to MPT host structure. 1990 * 1991 * Returns {SUCCESS,FAILED}. 1992 */ 1993 static int 1994 mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout ) 1995 { 1996 unsigned long flags; 1997 int loop_count = 4 * timeout; 1998 int status = FAILED; 1999 2000 do { 2001 spin_lock_irqsave(&hd->ioc->FreeQlock, flags); 2002 if(hd->tmPending == 0) { 2003 status = SUCCESS; 2004 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); 2005 break; 2006 } 2007 spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); 2008 msleep_interruptible(250); 2009 } while (--loop_count); 2010 2011 return status; 2012 } 2013 2014 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2015 /** 2016 * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver 2017 * @ioc: Pointer to MPT_ADAPTER structure 2018 * @mf: Pointer to SCSI task mgmt request frame 2019 * @mr: Pointer to SCSI task mgmt reply frame 2020 * 2021 * This routine is called from mptbase.c::mpt_interrupt() at the completion 2022 * of any SCSI task management request. 2023 * This routine is registered with the MPT (base) driver at driver 2024 * load/init time via the mpt_register() API call. 2025 * 2026 * Returns 1 indicating alloc'd request frame ptr should be freed. 2027 */ 2028 int 2029 mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) 2030 { 2031 SCSITaskMgmtReply_t *pScsiTmReply; 2032 SCSITaskMgmt_t *pScsiTmReq; 2033 MPT_SCSI_HOST *hd; 2034 unsigned long flags; 2035 u16 iocstatus; 2036 u8 tmType; 2037 2038 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n", 2039 ioc->name, mf, mr)); 2040 if (ioc->sh) { 2041 /* Depending on the thread, a timer is activated for 2042 * the TM request. Delete this timer on completion of TM. 2043 * Decrement count of outstanding TM requests. 2044 */ 2045 hd = (MPT_SCSI_HOST *)ioc->sh->hostdata; 2046 } else { 2047 dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n", 2048 ioc->name)); 2049 return 1; 2050 } 2051 2052 if (mr == NULL) { 2053 dtmprintk((MYIOC_s_WARN_FMT "ERROR! TaskMgmt Reply: NULL Request %p\n", 2054 ioc->name, mf)); 2055 return 1; 2056 } else { 2057 pScsiTmReply = (SCSITaskMgmtReply_t*)mr; 2058 pScsiTmReq = (SCSITaskMgmt_t*)mf; 2059 2060 /* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */ 2061 tmType = pScsiTmReq->TaskType; 2062 2063 dtmprintk((MYIOC_s_WARN_FMT " TaskType = %d, TerminationCount=%d\n", 2064 ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount))); 2065 DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply); 2066 2067 iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK; 2068 dtmprintk((MYIOC_s_WARN_FMT " SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n", 2069 ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo))); 2070 /* Error? (anything non-zero?) */ 2071 if (iocstatus) { 2072 2073 /* clear flags and continue. 2074 */ 2075 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK) 2076 hd->abortSCpnt = NULL; 2077 2078 /* If an internal command is present 2079 * or the TM failed - reload the FW. 2080 * FC FW may respond FAILED to an ABORT 2081 */ 2082 if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) { 2083 if ((hd->cmdPtr) || 2084 (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED)) { 2085 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) { 2086 printk((KERN_WARNING 2087 " Firmware Reload FAILED!!\n")); 2088 } 2089 } 2090 } 2091 } else { 2092 dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name)); 2093 2094 hd->abortSCpnt = NULL; 2095 2096 } 2097 } 2098 2099 spin_lock_irqsave(&ioc->FreeQlock, flags); 2100 hd->tmPending = 0; 2101 spin_unlock_irqrestore(&ioc->FreeQlock, flags); 2102 hd->tmState = TM_STATE_NONE; 2103 2104 return 1; 2105 } 2106 2107 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2108 /* 2109 * This is anyones guess quite frankly. 2110 */ 2111 int 2112 mptscsih_bios_param(struct scsi_device * sdev, struct block_device *bdev, 2113 sector_t capacity, int geom[]) 2114 { 2115 int heads; 2116 int sectors; 2117 sector_t cylinders; 2118 ulong dummy; 2119 2120 heads = 64; 2121 sectors = 32; 2122 2123 dummy = heads * sectors; 2124 cylinders = capacity; 2125 sector_div(cylinders,dummy); 2126 2127 /* 2128 * Handle extended translation size for logical drives 2129 * > 1Gb 2130 */ 2131 if ((ulong)capacity >= 0x200000) { 2132 heads = 255; 2133 sectors = 63; 2134 dummy = heads * sectors; 2135 cylinders = capacity; 2136 sector_div(cylinders,dummy); 2137 } 2138 2139 /* return result */ 2140 geom[0] = heads; 2141 geom[1] = sectors; 2142 geom[2] = cylinders; 2143 2144 dprintk((KERN_NOTICE 2145 ": bios_param: Id=%i Lun=%i Channel=%i CHS=%i/%i/%i\n", 2146 sdev->id, sdev->lun,sdev->channel,(int)cylinders,heads,sectors)); 2147 2148 return 0; 2149 } 2150 2151 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2152 /* 2153 * OS entry point to allow host driver to alloc memory 2154 * for each scsi device. Called once per device the bus scan. 2155 * Return non-zero if allocation fails. 2156 * Init memory once per id (not LUN). 2157 */ 2158 int 2159 mptscsih_slave_alloc(struct scsi_device *device) 2160 { 2161 struct Scsi_Host *host = device->host; 2162 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; 2163 VirtDevice *vdev; 2164 uint target = device->id; 2165 2166 if (hd == NULL) 2167 return -ENODEV; 2168 2169 if ((vdev = hd->Targets[target]) != NULL) 2170 goto out; 2171 2172 vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL); 2173 if (!vdev) { 2174 printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n", 2175 hd->ioc->name, sizeof(VirtDevice)); 2176 return -ENOMEM; 2177 } 2178 2179 memset(vdev, 0, sizeof(VirtDevice)); 2180 vdev->tflags = MPT_TARGET_FLAGS_Q_YES; 2181 vdev->ioc_id = hd->ioc->id; 2182 vdev->target_id = device->id; 2183 vdev->bus_id = device->channel; 2184 vdev->raidVolume = 0; 2185 hd->Targets[device->id] = vdev; 2186 if (hd->ioc->bus_type == SCSI) { 2187 if (hd->ioc->raid_data.isRaid & (1 << device->id)) { 2188 vdev->raidVolume = 1; 2189 ddvtprintk((KERN_INFO 2190 "RAID Volume @ id %d\n", device->id)); 2191 } 2192 } else { 2193 vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY; 2194 } 2195 2196 out: 2197 vdev->num_luns++; 2198 device->hostdata = vdev; 2199 return 0; 2200 } 2201 2202 /* 2203 * OS entry point to allow for host driver to free allocated memory 2204 * Called if no device present or device being unloaded 2205 */ 2206 void 2207 mptscsih_slave_destroy(struct scsi_device *device) 2208 { 2209 struct Scsi_Host *host = device->host; 2210 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)host->hostdata; 2211 VirtDevice *vdev; 2212 uint target = device->id; 2213 uint lun = device->lun; 2214 2215 if (hd == NULL) 2216 return; 2217 2218 mptscsih_search_running_cmds(hd, target, lun); 2219 2220 vdev = hd->Targets[target]; 2221 vdev->luns[0] &= ~(1 << lun); 2222 if (--vdev->num_luns) 2223 return; 2224 2225 kfree(hd->Targets[target]); 2226 hd->Targets[target] = NULL; 2227 2228 if (hd->ioc->bus_type == SCSI) { 2229 if (mptscsih_is_phys_disk(hd->ioc, target)) { 2230 hd->ioc->spi_data.forceDv |= MPT_SCSICFG_RELOAD_IOC_PG3; 2231 } else { 2232 hd->ioc->spi_data.dvStatus[target] = 2233 MPT_SCSICFG_NEGOTIATE; 2234 2235 if (!hd->negoNvram) { 2236 hd->ioc->spi_data.dvStatus[target] |= 2237 MPT_SCSICFG_DV_NOT_DONE; 2238 } 2239 } 2240 } 2241 } 2242 2243 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2244 /* 2245 * mptscsih_change_queue_depth - This function will set a devices queue depth 2246 * @sdev: per scsi_device pointer 2247 * @qdepth: requested queue depth 2248 * 2249 * Adding support for new 'change_queue_depth' api. 2250 */ 2251 int 2252 mptscsih_change_queue_depth(struct scsi_device *sdev, int qdepth) 2253 { 2254 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sdev->host->hostdata; 2255 VirtDevice *pTarget; 2256 int max_depth; 2257 int tagged; 2258 2259 if (hd == NULL) 2260 return 0; 2261 if (!(pTarget = hd->Targets[sdev->id])) 2262 return 0; 2263 2264 if (hd->ioc->bus_type == SCSI) { 2265 if (pTarget->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY) { 2266 if (!(pTarget->tflags & MPT_TARGET_FLAGS_Q_YES)) 2267 max_depth = 1; 2268 else if (((pTarget->inq_data[0] & 0x1f) == 0x00) && 2269 (pTarget->minSyncFactor <= MPT_ULTRA160 )) 2270 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH; 2271 else 2272 max_depth = MPT_SCSI_CMD_PER_DEV_LOW; 2273 } else { 2274 /* error case - No Inq. Data */ 2275 max_depth = 1; 2276 } 2277 } else 2278 max_depth = MPT_SCSI_CMD_PER_DEV_HIGH; 2279 2280 if (qdepth > max_depth) 2281 qdepth = max_depth; 2282 if (qdepth == 1) 2283 tagged = 0; 2284 else 2285 tagged = MSG_SIMPLE_TAG; 2286 2287 scsi_adjust_queue_depth(sdev, tagged, qdepth); 2288 return sdev->queue_depth; 2289 } 2290 2291 /* 2292 * OS entry point to adjust the queue_depths on a per-device basis. 2293 * Called once per device the bus scan. Use it to force the queue_depth 2294 * member to 1 if a device does not support Q tags. 2295 * Return non-zero if fails. 2296 */ 2297 int 2298 mptscsih_slave_configure(struct scsi_device *device) 2299 { 2300 struct Scsi_Host *sh = device->host; 2301 VirtDevice *pTarget; 2302 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *)sh->hostdata; 2303 2304 if ((hd == NULL) || (hd->Targets == NULL)) { 2305 return 0; 2306 } 2307 2308 dsprintk((MYIOC_s_INFO_FMT 2309 "device @ %p, id=%d, LUN=%d, channel=%d\n", 2310 hd->ioc->name, device, device->id, device->lun, device->channel)); 2311 dsprintk((MYIOC_s_INFO_FMT 2312 "sdtr %d wdtr %d ppr %d inq length=%d\n", 2313 hd->ioc->name, device->sdtr, device->wdtr, 2314 device->ppr, device->inquiry_len)); 2315 2316 if (device->id > sh->max_id) { 2317 /* error case, should never happen */ 2318 scsi_adjust_queue_depth(device, 0, 1); 2319 goto slave_configure_exit; 2320 } 2321 2322 pTarget = hd->Targets[device->id]; 2323 2324 if (pTarget == NULL) { 2325 /* Driver doesn't know about this device. 2326 * Kernel may generate a "Dummy Lun 0" which 2327 * may become a real Lun if a 2328 * "scsi add-single-device" command is executed 2329 * while the driver is active (hot-plug a 2330 * device). LSI Raid controllers need 2331 * queue_depth set to DEV_HIGH for this reason. 2332 */ 2333 scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG, 2334 MPT_SCSI_CMD_PER_DEV_HIGH); 2335 goto slave_configure_exit; 2336 } 2337 2338 mptscsih_initTarget(hd, device->channel, device->id, device->lun, 2339 device->inquiry, device->inquiry_len ); 2340 mptscsih_change_queue_depth(device, MPT_SCSI_CMD_PER_DEV_HIGH); 2341 2342 dsprintk((MYIOC_s_INFO_FMT 2343 "Queue depth=%d, tflags=%x\n", 2344 hd->ioc->name, device->queue_depth, pTarget->tflags)); 2345 2346 dsprintk((MYIOC_s_INFO_FMT 2347 "negoFlags=%x, maxOffset=%x, SyncFactor=%x\n", 2348 hd->ioc->name, pTarget->negoFlags, pTarget->maxOffset, pTarget->minSyncFactor)); 2349 2350 slave_configure_exit: 2351 2352 dsprintk((MYIOC_s_INFO_FMT 2353 "tagged %d, simple %d, ordered %d\n", 2354 hd->ioc->name,device->tagged_supported, device->simple_tags, 2355 device->ordered_tags)); 2356 2357 return 0; 2358 } 2359 2360 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2361 /* 2362 * Private routines... 2363 */ 2364 2365 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2366 /* Utility function to copy sense data from the scsi_cmnd buffer 2367 * to the FC and SCSI target structures. 2368 * 2369 */ 2370 static void 2371 mptscsih_copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply) 2372 { 2373 VirtDevice *target; 2374 SCSIIORequest_t *pReq; 2375 u32 sense_count = le32_to_cpu(pScsiReply->SenseCount); 2376 int index; 2377 2378 /* Get target structure 2379 */ 2380 pReq = (SCSIIORequest_t *) mf; 2381 index = (int) pReq->TargetID; 2382 target = hd->Targets[index]; 2383 2384 if (sense_count) { 2385 u8 *sense_data; 2386 int req_index; 2387 2388 /* Copy the sense received into the scsi command block. */ 2389 req_index = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx); 2390 sense_data = ((u8 *)hd->ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC)); 2391 memcpy(sc->sense_buffer, sense_data, SNS_LEN(sc)); 2392 2393 /* Log SMART data (asc = 0x5D, non-IM case only) if required. 2394 */ 2395 if ((hd->ioc->events) && (hd->ioc->eventTypes & (1 << MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE))) { 2396 if ((sense_data[12] == 0x5D) && (target->raidVolume == 0)) { 2397 int idx; 2398 MPT_ADAPTER *ioc = hd->ioc; 2399 2400 idx = ioc->eventContext % ioc->eventLogSize; 2401 ioc->events[idx].event = MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE; 2402 ioc->events[idx].eventContext = ioc->eventContext; 2403 2404 ioc->events[idx].data[0] = (pReq->LUN[1] << 24) || 2405 (MPI_EVENT_SCSI_DEV_STAT_RC_SMART_DATA << 16) || 2406 (pReq->Bus << 8) || pReq->TargetID; 2407 2408 ioc->events[idx].data[1] = (sense_data[13] << 8) || sense_data[12]; 2409 2410 ioc->eventContext++; 2411 } 2412 } 2413 } else { 2414 dprintk((MYIOC_s_INFO_FMT "Hmmm... SenseData len=0! (?)\n", 2415 hd->ioc->name)); 2416 } 2417 } 2418 2419 static u32 2420 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc) 2421 { 2422 MPT_SCSI_HOST *hd; 2423 int i; 2424 2425 hd = (MPT_SCSI_HOST *) sc->device->host->hostdata; 2426 2427 for (i = 0; i < hd->ioc->req_depth; i++) { 2428 if (hd->ScsiLookup[i] == sc) { 2429 return i; 2430 } 2431 } 2432 2433 return -1; 2434 } 2435 2436 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2437 int 2438 mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) 2439 { 2440 MPT_SCSI_HOST *hd; 2441 unsigned long flags; 2442 int ii; 2443 2444 dtmprintk((KERN_WARNING MYNAM 2445 ": IOC %s_reset routed to SCSI host driver!\n", 2446 reset_phase==MPT_IOC_SETUP_RESET ? "setup" : ( 2447 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"))); 2448 2449 /* If a FW reload request arrives after base installed but 2450 * before all scsi hosts have been attached, then an alt_ioc 2451 * may have a NULL sh pointer. 2452 */ 2453 if ((ioc->sh == NULL) || (ioc->sh->hostdata == NULL)) 2454 return 0; 2455 else 2456 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata; 2457 2458 if (reset_phase == MPT_IOC_SETUP_RESET) { 2459 dtmprintk((MYIOC_s_WARN_FMT "Setup-Diag Reset\n", ioc->name)); 2460 2461 /* Clean Up: 2462 * 1. Set Hard Reset Pending Flag 2463 * All new commands go to doneQ 2464 */ 2465 hd->resetPending = 1; 2466 2467 } else if (reset_phase == MPT_IOC_PRE_RESET) { 2468 dtmprintk((MYIOC_s_WARN_FMT "Pre-Diag Reset\n", ioc->name)); 2469 2470 /* 2. Flush running commands 2471 * Clean ScsiLookup (and associated memory) 2472 * AND clean mytaskQ 2473 */ 2474 2475 /* 2b. Reply to OS all known outstanding I/O commands. 2476 */ 2477 mptscsih_flush_running_cmds(hd); 2478 2479 /* 2c. If there was an internal command that 2480 * has not completed, configuration or io request, 2481 * free these resources. 2482 */ 2483 if (hd->cmdPtr) { 2484 del_timer(&hd->timer); 2485 mpt_free_msg_frame(ioc, hd->cmdPtr); 2486 } 2487 2488 dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name)); 2489 2490 } else { 2491 dtmprintk((MYIOC_s_WARN_FMT "Post-Diag Reset\n", ioc->name)); 2492 2493 /* Once a FW reload begins, all new OS commands are 2494 * redirected to the doneQ w/ a reset status. 2495 * Init all control structures. 2496 */ 2497 2498 /* ScsiLookup initialization 2499 */ 2500 for (ii=0; ii < hd->ioc->req_depth; ii++) 2501 hd->ScsiLookup[ii] = NULL; 2502 2503 /* 2. Chain Buffer initialization 2504 */ 2505 2506 /* 4. Renegotiate to all devices, if SCSI 2507 */ 2508 if (ioc->bus_type == SCSI) { 2509 dnegoprintk(("writeSDP1: ALL_IDS USE_NVRAM\n")); 2510 mptscsih_writeSDP1(hd, 0, 0, MPT_SCSICFG_ALL_IDS | MPT_SCSICFG_USE_NVRAM); 2511 } 2512 2513 /* 5. Enable new commands to be posted 2514 */ 2515 spin_lock_irqsave(&ioc->FreeQlock, flags); 2516 hd->tmPending = 0; 2517 spin_unlock_irqrestore(&ioc->FreeQlock, flags); 2518 hd->resetPending = 0; 2519 hd->tmState = TM_STATE_NONE; 2520 2521 /* 6. If there was an internal command, 2522 * wake this process up. 2523 */ 2524 if (hd->cmdPtr) { 2525 /* 2526 * Wake up the original calling thread 2527 */ 2528 hd->pLocal = &hd->localReply; 2529 hd->pLocal->completion = MPT_SCANDV_DID_RESET; 2530 hd->scandv_wait_done = 1; 2531 wake_up(&hd->scandv_waitq); 2532 hd->cmdPtr = NULL; 2533 } 2534 2535 /* 7. Set flag to force DV and re-read IOC Page 3 2536 */ 2537 if (ioc->bus_type == SCSI) { 2538 ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3; 2539 ddvtprintk(("Set reload IOC Pg3 Flag\n")); 2540 } 2541 2542 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name)); 2543 2544 } 2545 2546 return 1; /* currently means nothing really */ 2547 } 2548 2549 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2550 /* work queue thread to clear the persitency table */ 2551 static void 2552 mptscsih_sas_persist_clear_table(void * arg) 2553 { 2554 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg; 2555 2556 mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT); 2557 } 2558 2559 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2560 int 2561 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply) 2562 { 2563 MPT_SCSI_HOST *hd; 2564 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF; 2565 2566 devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n", 2567 ioc->name, event)); 2568 2569 if (ioc->sh == NULL || 2570 ((hd = (MPT_SCSI_HOST *)ioc->sh->hostdata) == NULL)) 2571 return 1; 2572 2573 switch (event) { 2574 case MPI_EVENT_UNIT_ATTENTION: /* 03 */ 2575 /* FIXME! */ 2576 break; 2577 case MPI_EVENT_IOC_BUS_RESET: /* 04 */ 2578 case MPI_EVENT_EXT_BUS_RESET: /* 05 */ 2579 if (hd && (ioc->bus_type == SCSI) && (hd->soft_resets < -1)) 2580 hd->soft_resets++; 2581 break; 2582 case MPI_EVENT_LOGOUT: /* 09 */ 2583 /* FIXME! */ 2584 break; 2585 2586 /* 2587 * CHECKME! Don't think we need to do 2588 * anything for these, but... 2589 */ 2590 case MPI_EVENT_RESCAN: /* 06 */ 2591 case MPI_EVENT_LINK_STATUS_CHANGE: /* 07 */ 2592 case MPI_EVENT_LOOP_STATE_CHANGE: /* 08 */ 2593 /* 2594 * CHECKME! Falling thru... 2595 */ 2596 break; 2597 2598 case MPI_EVENT_INTEGRATED_RAID: /* 0B */ 2599 { 2600 pMpiEventDataRaid_t pRaidEventData = 2601 (pMpiEventDataRaid_t) pEvReply->Data; 2602 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION 2603 /* Domain Validation Needed */ 2604 if (ioc->bus_type == SCSI && 2605 pRaidEventData->ReasonCode == 2606 MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) 2607 mptscsih_set_dvflags_raid(hd, pRaidEventData->PhysDiskNum); 2608 #endif 2609 break; 2610 } 2611 2612 /* Persistent table is full. */ 2613 case MPI_EVENT_PERSISTENT_TABLE_FULL: 2614 INIT_WORK(&mptscsih_persistTask, 2615 mptscsih_sas_persist_clear_table,(void *)ioc); 2616 schedule_work(&mptscsih_persistTask); 2617 break; 2618 2619 case MPI_EVENT_NONE: /* 00 */ 2620 case MPI_EVENT_LOG_DATA: /* 01 */ 2621 case MPI_EVENT_STATE_CHANGE: /* 02 */ 2622 case MPI_EVENT_EVENT_CHANGE: /* 0A */ 2623 default: 2624 dprintk((KERN_INFO " Ignoring event (=%02Xh)\n", event)); 2625 break; 2626 } 2627 2628 return 1; /* currently means nothing really */ 2629 } 2630 2631 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2632 /* 2633 * mptscsih_initTarget - Target, LUN alloc/free functionality. 2634 * @hd: Pointer to MPT_SCSI_HOST structure 2635 * @bus_id: Bus number (?) 2636 * @target_id: SCSI target id 2637 * @lun: SCSI LUN id 2638 * @data: Pointer to data 2639 * @dlen: Number of INQUIRY bytes 2640 * 2641 * NOTE: It's only SAFE to call this routine if data points to 2642 * sane & valid STANDARD INQUIRY data! 2643 * 2644 * Allocate and initialize memory for this target. 2645 * Save inquiry data. 2646 * 2647 */ 2648 static void 2649 mptscsih_initTarget(MPT_SCSI_HOST *hd, int bus_id, int target_id, u8 lun, char *data, int dlen) 2650 { 2651 int indexed_lun, lun_index; 2652 VirtDevice *vdev; 2653 SpiCfgData *pSpi; 2654 char data_56; 2655 2656 dinitprintk((MYIOC_s_INFO_FMT "initTarget bus=%d id=%d lun=%d hd=%p\n", 2657 hd->ioc->name, bus_id, target_id, lun, hd)); 2658 2659 /* 2660 * If the peripheral qualifier filter is enabled then if the target reports a 0x1 2661 * (i.e. The targer is capable of supporting the specified peripheral device type 2662 * on this logical unit; however, the physical device is not currently connected 2663 * to this logical unit) it will be converted to a 0x3 (i.e. The target is not 2664 * capable of supporting a physical device on this logical unit). This is to work 2665 * around a bug in th emid-layer in some distributions in which the mid-layer will 2666 * continue to try to communicate to the LUN and evntually create a dummy LUN. 2667 */ 2668 if (hd->mpt_pq_filter && dlen && (data[0] & 0xE0)) 2669 data[0] |= 0x40; 2670 2671 /* Is LUN supported? If so, upper 2 bits will be 0 2672 * in first byte of inquiry data. 2673 */ 2674 if (data[0] & 0xe0) 2675 return; 2676 2677 if ((vdev = hd->Targets[target_id]) == NULL) { 2678 return; 2679 } 2680 2681 lun_index = (lun >> 5); /* 32 luns per lun_index */ 2682 indexed_lun = (lun % 32); 2683 vdev->luns[lun_index] |= (1 << indexed_lun); 2684 2685 if (hd->ioc->bus_type == SCSI) { 2686 if ((data[0] == TYPE_PROCESSOR) && (hd->ioc->spi_data.Saf_Te)) { 2687 /* Treat all Processors as SAF-TE if 2688 * command line option is set */ 2689 vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; 2690 mptscsih_writeIOCPage4(hd, target_id, bus_id); 2691 }else if ((data[0] == TYPE_PROCESSOR) && 2692 !(vdev->tflags & MPT_TARGET_FLAGS_SAF_TE_ISSUED )) { 2693 if ( dlen > 49 ) { 2694 vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY; 2695 if ( data[44] == 'S' && 2696 data[45] == 'A' && 2697 data[46] == 'F' && 2698 data[47] == '-' && 2699 data[48] == 'T' && 2700 data[49] == 'E' ) { 2701 vdev->tflags |= MPT_TARGET_FLAGS_SAF_TE_ISSUED; 2702 mptscsih_writeIOCPage4(hd, target_id, bus_id); 2703 } 2704 } 2705 } 2706 if (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_INQUIRY)) { 2707 if ( dlen > 8 ) { 2708 memcpy (vdev->inq_data, data, 8); 2709 } else { 2710 memcpy (vdev->inq_data, data, dlen); 2711 } 2712 2713 /* If have not done DV, set the DV flag. 2714 */ 2715 pSpi = &hd->ioc->spi_data; 2716 if ((data[0] == TYPE_TAPE) || (data[0] == TYPE_PROCESSOR)) { 2717 if (pSpi->dvStatus[target_id] & MPT_SCSICFG_DV_NOT_DONE) 2718 pSpi->dvStatus[target_id] |= MPT_SCSICFG_NEED_DV; 2719 } 2720 2721 vdev->tflags |= MPT_TARGET_FLAGS_VALID_INQUIRY; 2722 2723 2724 data_56 = 0x0F; /* Default to full capabilities if Inq data length is < 57 */ 2725 if (dlen > 56) { 2726 if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) { 2727 /* Update the target capabilities 2728 */ 2729 data_56 = data[56]; 2730 vdev->tflags |= MPT_TARGET_FLAGS_VALID_56; 2731 } 2732 } 2733 mptscsih_setTargetNegoParms(hd, vdev, data_56); 2734 } else { 2735 /* Initial Inquiry may not request enough data bytes to 2736 * obtain byte 57. DV will; if target doesn't return 2737 * at least 57 bytes, data[56] will be zero. */ 2738 if (dlen > 56) { 2739 if ( (!(vdev->tflags & MPT_TARGET_FLAGS_VALID_56))) { 2740 /* Update the target capabilities 2741 */ 2742 data_56 = data[56]; 2743 vdev->tflags |= MPT_TARGET_FLAGS_VALID_56; 2744 mptscsih_setTargetNegoParms(hd, vdev, data_56); 2745 } 2746 } 2747 } 2748 } 2749 } 2750 2751 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2752 /* 2753 * Update the target negotiation parameters based on the 2754 * the Inquiry data, adapter capabilities, and NVRAM settings. 2755 * 2756 */ 2757 static void 2758 mptscsih_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtDevice *target, char byte56) 2759 { 2760 SpiCfgData *pspi_data = &hd->ioc->spi_data; 2761 int id = (int) target->target_id; 2762 int nvram; 2763 VirtDevice *vdev; 2764 int ii; 2765 u8 width = MPT_NARROW; 2766 u8 factor = MPT_ASYNC; 2767 u8 offset = 0; 2768 u8 version, nfactor; 2769 u8 noQas = 1; 2770 2771 target->negoFlags = pspi_data->noQas; 2772 2773 /* noQas == 0 => device supports QAS. Need byte 56 of Inq to determine 2774 * support. If available, default QAS to off and allow enabling. 2775 * If not available, default QAS to on, turn off for non-disks. 2776 */ 2777 2778 /* Set flags based on Inquiry data 2779 */ 2780 version = target->inq_data[2] & 0x07; 2781 if (version < 2) { 2782 width = 0; 2783 factor = MPT_ULTRA2; 2784 offset = pspi_data->maxSyncOffset; 2785 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES; 2786 } else { 2787 if (target->inq_data[7] & 0x20) { 2788 width = 1; 2789 } 2790 2791 if (target->inq_data[7] & 0x10) { 2792 factor = pspi_data->minSyncFactor; 2793 if (target->tflags & MPT_TARGET_FLAGS_VALID_56) { 2794 /* bits 2 & 3 show Clocking support */ 2795 if ((byte56 & 0x0C) == 0) 2796 factor = MPT_ULTRA2; 2797 else { 2798 if ((byte56 & 0x03) == 0) 2799 factor = MPT_ULTRA160; 2800 else { 2801 factor = MPT_ULTRA320; 2802 if (byte56 & 0x02) 2803 { 2804 ddvtprintk((KERN_INFO "Enabling QAS due to byte56=%02x on id=%d!\n", byte56, id)); 2805 noQas = 0; 2806 } 2807 if (target->inq_data[0] == TYPE_TAPE) { 2808 if (byte56 & 0x01) 2809 target->negoFlags |= MPT_TAPE_NEGO_IDP; 2810 } 2811 } 2812 } 2813 } else { 2814 ddvtprintk((KERN_INFO "Enabling QAS on id=%d due to ~TARGET_FLAGS_VALID_56!\n", id)); 2815 noQas = 0; 2816 } 2817 2818 offset = pspi_data->maxSyncOffset; 2819 2820 /* If RAID, never disable QAS 2821 * else if non RAID, do not disable 2822 * QAS if bit 1 is set 2823 * bit 1 QAS support, non-raid only 2824 * bit 0 IU support 2825 */ 2826 if (target->raidVolume == 1) { 2827 noQas = 0; 2828 } 2829 } else { 2830 factor = MPT_ASYNC; 2831 offset = 0; 2832 } 2833 } 2834 2835 if ( (target->inq_data[7] & 0x02) == 0) { 2836 target->tflags &= ~MPT_TARGET_FLAGS_Q_YES; 2837 } 2838 2839 /* Update tflags based on NVRAM settings. (SCSI only) 2840 */ 2841 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) { 2842 nvram = pspi_data->nvram[id]; 2843 nfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8; 2844 2845 if (width) 2846 width = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1; 2847 2848 if (offset > 0) { 2849 /* Ensure factor is set to the 2850 * maximum of: adapter, nvram, inquiry 2851 */ 2852 if (nfactor) { 2853 if (nfactor < pspi_data->minSyncFactor ) 2854 nfactor = pspi_data->minSyncFactor; 2855 2856 factor = max(factor, nfactor); 2857 if (factor == MPT_ASYNC) 2858 offset = 0; 2859 } else { 2860 offset = 0; 2861 factor = MPT_ASYNC; 2862 } 2863 } else { 2864 factor = MPT_ASYNC; 2865 } 2866 } 2867 2868 /* Make sure data is consistent 2869 */ 2870 if ((!width) && (factor < MPT_ULTRA2)) { 2871 factor = MPT_ULTRA2; 2872 } 2873 2874 /* Save the data to the target structure. 2875 */ 2876 target->minSyncFactor = factor; 2877 target->maxOffset = offset; 2878 target->maxWidth = width; 2879 2880 target->tflags |= MPT_TARGET_FLAGS_VALID_NEGO; 2881 2882 /* Disable unused features. 2883 */ 2884 if (!width) 2885 target->negoFlags |= MPT_TARGET_NO_NEGO_WIDE; 2886 2887 if (!offset) 2888 target->negoFlags |= MPT_TARGET_NO_NEGO_SYNC; 2889 2890 if ( factor > MPT_ULTRA320 ) 2891 noQas = 0; 2892 2893 /* GEM, processor WORKAROUND 2894 */ 2895 if ((target->inq_data[0] == TYPE_PROCESSOR) || (target->inq_data[0] > 0x08)) { 2896 target->negoFlags |= (MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC); 2897 pspi_data->dvStatus[id] |= MPT_SCSICFG_BLK_NEGO; 2898 } else { 2899 if (noQas && (pspi_data->noQas == 0)) { 2900 pspi_data->noQas |= MPT_TARGET_NO_NEGO_QAS; 2901 target->negoFlags |= MPT_TARGET_NO_NEGO_QAS; 2902 2903 /* Disable QAS in a mixed configuration case 2904 */ 2905 2906 ddvtprintk((KERN_INFO "Disabling QAS due to noQas=%02x on id=%d!\n", noQas, id)); 2907 for (ii = 0; ii < id; ii++) { 2908 if ( (vdev = hd->Targets[ii]) ) { 2909 vdev->negoFlags |= MPT_TARGET_NO_NEGO_QAS; 2910 mptscsih_writeSDP1(hd, 0, ii, vdev->negoFlags); 2911 } 2912 } 2913 } 2914 } 2915 2916 /* Write SDP1 on this I/O to this target */ 2917 if (pspi_data->dvStatus[id] & MPT_SCSICFG_NEGOTIATE) { 2918 ddvtprintk((KERN_INFO "MPT_SCSICFG_NEGOTIATE on id=%d!\n", id)); 2919 mptscsih_writeSDP1(hd, 0, id, hd->negoNvram); 2920 pspi_data->dvStatus[id] &= ~MPT_SCSICFG_NEGOTIATE; 2921 } else if (pspi_data->dvStatus[id] & MPT_SCSICFG_BLK_NEGO) { 2922 ddvtprintk((KERN_INFO "MPT_SCSICFG_BLK_NEGO on id=%d!\n", id)); 2923 mptscsih_writeSDP1(hd, 0, id, MPT_SCSICFG_BLK_NEGO); 2924 pspi_data->dvStatus[id] &= ~MPT_SCSICFG_BLK_NEGO; 2925 } 2926 } 2927 2928 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2929 /* If DV disabled (negoNvram set to USE_NVARM) or if not LUN 0, return. 2930 * Else set the NEED_DV flag after Read Capacity Issued (disks) 2931 * or Mode Sense (cdroms). 2932 * 2933 * Tapes, initTarget will set this flag on completion of Inquiry command. 2934 * Called only if DV_NOT_DONE flag is set 2935 */ 2936 static void 2937 mptscsih_set_dvflags(MPT_SCSI_HOST *hd, SCSIIORequest_t *pReq) 2938 { 2939 MPT_ADAPTER *ioc = hd->ioc; 2940 u8 cmd; 2941 SpiCfgData *pSpi; 2942 2943 ddvtprintk((MYIOC_s_NOTE_FMT 2944 " set_dvflags: id=%d lun=%d negoNvram=%x cmd=%x\n", 2945 hd->ioc->name, pReq->TargetID, pReq->LUN[1], hd->negoNvram, pReq->CDB[0])); 2946 2947 if ((pReq->LUN[1] != 0) || (hd->negoNvram != 0)) 2948 return; 2949 2950 cmd = pReq->CDB[0]; 2951 2952 if ((cmd == READ_CAPACITY) || (cmd == MODE_SENSE)) { 2953 pSpi = &ioc->spi_data; 2954 if ((ioc->raid_data.isRaid & (1 << pReq->TargetID)) && ioc->raid_data.pIocPg3) { 2955 /* Set NEED_DV for all hidden disks 2956 */ 2957 Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk; 2958 int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks; 2959 2960 while (numPDisk) { 2961 pSpi->dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV; 2962 ddvtprintk(("NEED_DV set for phys disk id %d\n", pPDisk->PhysDiskID)); 2963 pPDisk++; 2964 numPDisk--; 2965 } 2966 } 2967 pSpi->dvStatus[pReq->TargetID] |= MPT_SCSICFG_NEED_DV; 2968 ddvtprintk(("NEED_DV set for visible disk id %d\n", pReq->TargetID)); 2969 } 2970 } 2971 2972 /* mptscsih_raid_set_dv_flags() 2973 * 2974 * New or replaced disk. Set DV flag and schedule DV. 2975 */ 2976 static void 2977 mptscsih_set_dvflags_raid(MPT_SCSI_HOST *hd, int id) 2978 { 2979 MPT_ADAPTER *ioc = hd->ioc; 2980 SpiCfgData *pSpi = &ioc->spi_data; 2981 Ioc3PhysDisk_t *pPDisk; 2982 int numPDisk; 2983 2984 if (hd->negoNvram != 0) 2985 return; 2986 2987 ddvtprintk(("DV requested for phys disk id %d\n", id)); 2988 if (ioc->raid_data.pIocPg3) { 2989 pPDisk = ioc->raid_data.pIocPg3->PhysDisk; 2990 numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks; 2991 while (numPDisk) { 2992 if (id == pPDisk->PhysDiskNum) { 2993 pSpi->dvStatus[pPDisk->PhysDiskID] = 2994 (MPT_SCSICFG_NEED_DV | MPT_SCSICFG_DV_NOT_DONE); 2995 pSpi->forceDv = MPT_SCSICFG_NEED_DV; 2996 ddvtprintk(("NEED_DV set for phys disk id %d\n", 2997 pPDisk->PhysDiskID)); 2998 break; 2999 } 3000 pPDisk++; 3001 numPDisk--; 3002 } 3003 3004 if (numPDisk == 0) { 3005 /* The physical disk that needs DV was not found 3006 * in the stored IOC Page 3. The driver must reload 3007 * this page. DV routine will set the NEED_DV flag for 3008 * all phys disks that have DV_NOT_DONE set. 3009 */ 3010 pSpi->forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3; 3011 ddvtprintk(("phys disk %d not found. Setting reload IOC Pg3 Flag\n",id)); 3012 } 3013 } 3014 } 3015 3016 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3017 /* 3018 * If no Target, bus reset on 1st I/O. Set the flag to 3019 * prevent any future negotiations to this device. 3020 */ 3021 static void 3022 mptscsih_no_negotiate(MPT_SCSI_HOST *hd, int target_id) 3023 { 3024 3025 if ((hd->Targets) && (hd->Targets[target_id] == NULL)) 3026 hd->ioc->spi_data.dvStatus[target_id] |= MPT_SCSICFG_BLK_NEGO; 3027 3028 return; 3029 } 3030 3031 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3032 /* 3033 * SCSI Config Page functionality ... 3034 */ 3035 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3036 /* mptscsih_setDevicePage1Flags - add Requested and Configuration fields flags 3037 * based on width, factor and offset parameters. 3038 * @width: bus width 3039 * @factor: sync factor 3040 * @offset: sync offset 3041 * @requestedPtr: pointer to requested values (updated) 3042 * @configurationPtr: pointer to configuration values (updated) 3043 * @flags: flags to block WDTR or SDTR negotiation 3044 * 3045 * Return: None. 3046 * 3047 * Remark: Called by writeSDP1 and _dv_params 3048 */ 3049 static void 3050 mptscsih_setDevicePage1Flags (u8 width, u8 factor, u8 offset, int *requestedPtr, int *configurationPtr, u8 flags) 3051 { 3052 u8 nowide = flags & MPT_TARGET_NO_NEGO_WIDE; 3053 u8 nosync = flags & MPT_TARGET_NO_NEGO_SYNC; 3054 3055 *configurationPtr = 0; 3056 *requestedPtr = width ? MPI_SCSIDEVPAGE1_RP_WIDE : 0; 3057 *requestedPtr |= (offset << 16) | (factor << 8); 3058 3059 if (width && offset && !nowide && !nosync) { 3060 if (factor < MPT_ULTRA160) { 3061 *requestedPtr |= (MPI_SCSIDEVPAGE1_RP_IU + MPI_SCSIDEVPAGE1_RP_DT); 3062 if ((flags & MPT_TARGET_NO_NEGO_QAS) == 0) 3063 *requestedPtr |= MPI_SCSIDEVPAGE1_RP_QAS; 3064 if (flags & MPT_TAPE_NEGO_IDP) 3065 *requestedPtr |= 0x08000000; 3066 } else if (factor < MPT_ULTRA2) { 3067 *requestedPtr |= MPI_SCSIDEVPAGE1_RP_DT; 3068 } 3069 } 3070 3071 if (nowide) 3072 *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_WDTR_DISALLOWED; 3073 3074 if (nosync) 3075 *configurationPtr |= MPI_SCSIDEVPAGE1_CONF_SDTR_DISALLOWED; 3076 3077 return; 3078 } 3079 3080 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3081 /* mptscsih_writeSDP1 - write SCSI Device Page 1 3082 * @hd: Pointer to a SCSI Host Strucutre 3083 * @portnum: IOC port number 3084 * @target_id: writeSDP1 for single ID 3085 * @flags: MPT_SCSICFG_ALL_IDS, MPT_SCSICFG_USE_NVRAM, MPT_SCSICFG_BLK_NEGO 3086 * 3087 * Return: -EFAULT if read of config page header fails 3088 * or 0 if success. 3089 * 3090 * Remark: If a target has been found, the settings from the 3091 * target structure are used, else the device is set 3092 * to async/narrow. 3093 * 3094 * Remark: Called during init and after a FW reload. 3095 * Remark: We do not wait for a return, write pages sequentially. 3096 */ 3097 static int 3098 mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target_id, int flags) 3099 { 3100 MPT_ADAPTER *ioc = hd->ioc; 3101 Config_t *pReq; 3102 SCSIDevicePage1_t *pData; 3103 VirtDevice *pTarget=NULL; 3104 MPT_FRAME_HDR *mf; 3105 dma_addr_t dataDma; 3106 u16 req_idx; 3107 u32 frameOffset; 3108 u32 requested, configuration, flagsLength; 3109 int ii, nvram; 3110 int id = 0, maxid = 0; 3111 u8 width; 3112 u8 factor; 3113 u8 offset; 3114 u8 bus = 0; 3115 u8 negoFlags; 3116 u8 maxwidth, maxoffset, maxfactor; 3117 3118 if (ioc->spi_data.sdp1length == 0) 3119 return 0; 3120 3121 if (flags & MPT_SCSICFG_ALL_IDS) { 3122 id = 0; 3123 maxid = ioc->sh->max_id - 1; 3124 } else if (ioc->sh) { 3125 id = target_id; 3126 maxid = min_t(int, id, ioc->sh->max_id - 1); 3127 } 3128 3129 for (; id <= maxid; id++) { 3130 3131 if (id == ioc->pfacts[portnum].PortSCSIID) 3132 continue; 3133 3134 /* Use NVRAM to get adapter and target maximums 3135 * Data over-riden by target structure information, if present 3136 */ 3137 maxwidth = ioc->spi_data.maxBusWidth; 3138 maxoffset = ioc->spi_data.maxSyncOffset; 3139 maxfactor = ioc->spi_data.minSyncFactor; 3140 if (ioc->spi_data.nvram && (ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) { 3141 nvram = ioc->spi_data.nvram[id]; 3142 3143 if (maxwidth) 3144 maxwidth = nvram & MPT_NVRAM_WIDE_DISABLE ? 0 : 1; 3145 3146 if (maxoffset > 0) { 3147 maxfactor = (nvram & MPT_NVRAM_SYNC_MASK) >> 8; 3148 if (maxfactor == 0) { 3149 /* Key for async */ 3150 maxfactor = MPT_ASYNC; 3151 maxoffset = 0; 3152 } else if (maxfactor < ioc->spi_data.minSyncFactor) { 3153 maxfactor = ioc->spi_data.minSyncFactor; 3154 } 3155 } else 3156 maxfactor = MPT_ASYNC; 3157 } 3158 3159 /* Set the negotiation flags. 3160 */ 3161 negoFlags = ioc->spi_data.noQas; 3162 if (!maxwidth) 3163 negoFlags |= MPT_TARGET_NO_NEGO_WIDE; 3164 3165 if (!maxoffset) 3166 negoFlags |= MPT_TARGET_NO_NEGO_SYNC; 3167 3168 if (flags & MPT_SCSICFG_USE_NVRAM) { 3169 width = maxwidth; 3170 factor = maxfactor; 3171 offset = maxoffset; 3172 } else { 3173 width = 0; 3174 factor = MPT_ASYNC; 3175 offset = 0; 3176 //negoFlags = 0; 3177 //negoFlags = MPT_TARGET_NO_NEGO_SYNC; 3178 } 3179 3180 /* If id is not a raid volume, get the updated 3181 * transmission settings from the target structure. 3182 */ 3183 if (hd->Targets && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) { 3184 width = pTarget->maxWidth; 3185 factor = pTarget->minSyncFactor; 3186 offset = pTarget->maxOffset; 3187 negoFlags = pTarget->negoFlags; 3188 } 3189 3190 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION 3191 /* Force to async and narrow if DV has not been executed 3192 * for this ID 3193 */ 3194 if ((hd->ioc->spi_data.dvStatus[id] & MPT_SCSICFG_DV_NOT_DONE) != 0) { 3195 width = 0; 3196 factor = MPT_ASYNC; 3197 offset = 0; 3198 } 3199 #endif 3200 3201 if (flags & MPT_SCSICFG_BLK_NEGO) 3202 negoFlags |= MPT_TARGET_NO_NEGO_WIDE | MPT_TARGET_NO_NEGO_SYNC; 3203 3204 mptscsih_setDevicePage1Flags(width, factor, offset, 3205 &requested, &configuration, negoFlags); 3206 dnegoprintk(("writeSDP1: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n", 3207 target_id, width, factor, offset, negoFlags, requested, configuration)); 3208 3209 /* Get a MF for this command. 3210 */ 3211 if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) { 3212 dfailprintk((MYIOC_s_WARN_FMT "write SDP1: no msg frames!\n", 3213 ioc->name)); 3214 return -EAGAIN; 3215 } 3216 3217 ddvprintk((MYIOC_s_INFO_FMT "WriteSDP1 (mf=%p, id=%d, req=0x%x, cfg=0x%x)\n", 3218 hd->ioc->name, mf, id, requested, configuration)); 3219 3220 3221 /* Set the request and the data pointers. 3222 * Request takes: 36 bytes (32 bit SGE) 3223 * SCSI Device Page 1 requires 16 bytes 3224 * 40 + 16 <= size of SCSI IO Request = 56 bytes 3225 * and MF size >= 64 bytes. 3226 * Place data at end of MF. 3227 */ 3228 pReq = (Config_t *)mf; 3229 3230 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx); 3231 frameOffset = ioc->req_sz - sizeof(SCSIDevicePage1_t); 3232 3233 pData = (SCSIDevicePage1_t *)((u8 *) mf + frameOffset); 3234 dataDma = ioc->req_frames_dma + (req_idx * ioc->req_sz) + frameOffset; 3235 3236 /* Complete the request frame (same for all requests). 3237 */ 3238 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; 3239 pReq->Reserved = 0; 3240 pReq->ChainOffset = 0; 3241 pReq->Function = MPI_FUNCTION_CONFIG; 3242 pReq->ExtPageLength = 0; 3243 pReq->ExtPageType = 0; 3244 pReq->MsgFlags = 0; 3245 for (ii=0; ii < 8; ii++) { 3246 pReq->Reserved2[ii] = 0; 3247 } 3248 pReq->Header.PageVersion = ioc->spi_data.sdp1version; 3249 pReq->Header.PageLength = ioc->spi_data.sdp1length; 3250 pReq->Header.PageNumber = 1; 3251 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE; 3252 pReq->PageAddress = cpu_to_le32(id | (bus << 8 )); 3253 3254 /* Add a SGE to the config request. 3255 */ 3256 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE | ioc->spi_data.sdp1length * 4; 3257 3258 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma); 3259 3260 /* Set up the common data portion 3261 */ 3262 pData->Header.PageVersion = pReq->Header.PageVersion; 3263 pData->Header.PageLength = pReq->Header.PageLength; 3264 pData->Header.PageNumber = pReq->Header.PageNumber; 3265 pData->Header.PageType = pReq->Header.PageType; 3266 pData->RequestedParameters = cpu_to_le32(requested); 3267 pData->Reserved = 0; 3268 pData->Configuration = cpu_to_le32(configuration); 3269 3270 dprintk((MYIOC_s_INFO_FMT 3271 "write SDP1: id %d pgaddr 0x%x req 0x%x config 0x%x\n", 3272 ioc->name, id, (id | (bus<<8)), 3273 requested, configuration)); 3274 3275 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf); 3276 } 3277 3278 return 0; 3279 } 3280 3281 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3282 /* mptscsih_writeIOCPage4 - write IOC Page 4 3283 * @hd: Pointer to a SCSI Host Structure 3284 * @target_id: write IOC Page4 for this ID & Bus 3285 * 3286 * Return: -EAGAIN if unable to obtain a Message Frame 3287 * or 0 if success. 3288 * 3289 * Remark: We do not wait for a return, write pages sequentially. 3290 */ 3291 static int 3292 mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus) 3293 { 3294 MPT_ADAPTER *ioc = hd->ioc; 3295 Config_t *pReq; 3296 IOCPage4_t *IOCPage4Ptr; 3297 MPT_FRAME_HDR *mf; 3298 dma_addr_t dataDma; 3299 u16 req_idx; 3300 u32 frameOffset; 3301 u32 flagsLength; 3302 int ii; 3303 3304 /* Get a MF for this command. 3305 */ 3306 if ((mf = mpt_get_msg_frame(ioc->DoneCtx, ioc)) == NULL) { 3307 dfailprintk((MYIOC_s_WARN_FMT "writeIOCPage4 : no msg frames!\n", 3308 ioc->name)); 3309 return -EAGAIN; 3310 } 3311 3312 /* Set the request and the data pointers. 3313 * Place data at end of MF. 3314 */ 3315 pReq = (Config_t *)mf; 3316 3317 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx); 3318 frameOffset = ioc->req_sz - sizeof(IOCPage4_t); 3319 3320 /* Complete the request frame (same for all requests). 3321 */ 3322 pReq->Action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; 3323 pReq->Reserved = 0; 3324 pReq->ChainOffset = 0; 3325 pReq->Function = MPI_FUNCTION_CONFIG; 3326 pReq->ExtPageLength = 0; 3327 pReq->ExtPageType = 0; 3328 pReq->MsgFlags = 0; 3329 for (ii=0; ii < 8; ii++) { 3330 pReq->Reserved2[ii] = 0; 3331 } 3332 3333 IOCPage4Ptr = ioc->spi_data.pIocPg4; 3334 dataDma = ioc->spi_data.IocPg4_dma; 3335 ii = IOCPage4Ptr->ActiveSEP++; 3336 IOCPage4Ptr->SEP[ii].SEPTargetID = target_id; 3337 IOCPage4Ptr->SEP[ii].SEPBus = bus; 3338 pReq->Header = IOCPage4Ptr->Header; 3339 pReq->PageAddress = cpu_to_le32(target_id | (bus << 8 )); 3340 3341 /* Add a SGE to the config request. 3342 */ 3343 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE | 3344 (IOCPage4Ptr->Header.PageLength + ii) * 4; 3345 3346 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, dataDma); 3347 3348 dinitprintk((MYIOC_s_INFO_FMT 3349 "writeIOCPage4: MaxSEP=%d ActiveSEP=%d id=%d bus=%d\n", 3350 ioc->name, IOCPage4Ptr->MaxSEP, IOCPage4Ptr->ActiveSEP, target_id, bus)); 3351 3352 mpt_put_msg_frame(ioc->DoneCtx, ioc, mf); 3353 3354 return 0; 3355 } 3356 3357 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3358 /* 3359 * Bus Scan and Domain Validation functionality ... 3360 */ 3361 3362 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3363 /* 3364 * mptscsih_scandv_complete - Scan and DV callback routine registered 3365 * to Fustion MPT (base) driver. 3366 * 3367 * @ioc: Pointer to MPT_ADAPTER structure 3368 * @mf: Pointer to original MPT request frame 3369 * @mr: Pointer to MPT reply frame (NULL if TurboReply) 3370 * 3371 * This routine is called from mpt.c::mpt_interrupt() at the completion 3372 * of any SCSI IO request. 3373 * This routine is registered with the Fusion MPT (base) driver at driver 3374 * load/init time via the mpt_register() API call. 3375 * 3376 * Returns 1 indicating alloc'd request frame ptr should be freed. 3377 * 3378 * Remark: Sets a completion code and (possibly) saves sense data 3379 * in the IOC member localReply structure. 3380 * Used ONLY for DV and other internal commands. 3381 */ 3382 int 3383 mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) 3384 { 3385 MPT_SCSI_HOST *hd; 3386 SCSIIORequest_t *pReq; 3387 int completionCode; 3388 u16 req_idx; 3389 3390 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata; 3391 3392 if ((mf == NULL) || 3393 (mf >= MPT_INDEX_2_MFPTR(ioc, ioc->req_depth))) { 3394 printk(MYIOC_s_ERR_FMT 3395 "ScanDvComplete, %s req frame ptr! (=%p)\n", 3396 ioc->name, mf?"BAD":"NULL", (void *) mf); 3397 goto wakeup; 3398 } 3399 3400 del_timer(&hd->timer); 3401 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx); 3402 hd->ScsiLookup[req_idx] = NULL; 3403 pReq = (SCSIIORequest_t *) mf; 3404 3405 if (mf != hd->cmdPtr) { 3406 printk(MYIOC_s_WARN_FMT "ScanDvComplete (mf=%p, cmdPtr=%p, idx=%d)\n", 3407 hd->ioc->name, (void *)mf, (void *) hd->cmdPtr, req_idx); 3408 } 3409 hd->cmdPtr = NULL; 3410 3411 ddvprintk((MYIOC_s_INFO_FMT "ScanDvComplete (mf=%p,mr=%p,idx=%d)\n", 3412 hd->ioc->name, mf, mr, req_idx)); 3413 3414 hd->pLocal = &hd->localReply; 3415 hd->pLocal->scsiStatus = 0; 3416 3417 /* If target struct exists, clear sense valid flag. 3418 */ 3419 if (mr == NULL) { 3420 completionCode = MPT_SCANDV_GOOD; 3421 } else { 3422 SCSIIOReply_t *pReply; 3423 u16 status; 3424 u8 scsi_status; 3425 3426 pReply = (SCSIIOReply_t *) mr; 3427 3428 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK; 3429 scsi_status = pReply->SCSIStatus; 3430 3431 ddvtprintk((KERN_NOTICE " IOCStatus=%04xh, SCSIState=%02xh, SCSIStatus=%02xh, IOCLogInfo=%08xh\n", 3432 status, pReply->SCSIState, scsi_status, 3433 le32_to_cpu(pReply->IOCLogInfo))); 3434 3435 switch(status) { 3436 3437 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */ 3438 completionCode = MPT_SCANDV_SELECTION_TIMEOUT; 3439 break; 3440 3441 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */ 3442 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */ 3443 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */ 3444 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */ 3445 completionCode = MPT_SCANDV_DID_RESET; 3446 break; 3447 3448 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */ 3449 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */ 3450 case MPI_IOCSTATUS_SUCCESS: /* 0x0000 */ 3451 if (pReply->Function == MPI_FUNCTION_CONFIG) { 3452 ConfigReply_t *pr = (ConfigReply_t *)mr; 3453 completionCode = MPT_SCANDV_GOOD; 3454 hd->pLocal->header.PageVersion = pr->Header.PageVersion; 3455 hd->pLocal->header.PageLength = pr->Header.PageLength; 3456 hd->pLocal->header.PageNumber = pr->Header.PageNumber; 3457 hd->pLocal->header.PageType = pr->Header.PageType; 3458 3459 } else if (pReply->Function == MPI_FUNCTION_RAID_ACTION) { 3460 /* If the RAID Volume request is successful, 3461 * return GOOD, else indicate that 3462 * some type of error occurred. 3463 */ 3464 MpiRaidActionReply_t *pr = (MpiRaidActionReply_t *)mr; 3465 if (le16_to_cpu(pr->ActionStatus) == MPI_RAID_ACTION_ASTATUS_SUCCESS) 3466 completionCode = MPT_SCANDV_GOOD; 3467 else 3468 completionCode = MPT_SCANDV_SOME_ERROR; 3469 3470 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID) { 3471 u8 *sense_data; 3472 int sz; 3473 3474 /* save sense data in global structure 3475 */ 3476 completionCode = MPT_SCANDV_SENSE; 3477 hd->pLocal->scsiStatus = scsi_status; 3478 sense_data = ((u8 *)hd->ioc->sense_buf_pool + 3479 (req_idx * MPT_SENSE_BUFFER_ALLOC)); 3480 3481 sz = min_t(int, pReq->SenseBufferLength, 3482 SCSI_STD_SENSE_BYTES); 3483 memcpy(hd->pLocal->sense, sense_data, sz); 3484 3485 ddvprintk((KERN_NOTICE " Check Condition, sense ptr %p\n", 3486 sense_data)); 3487 } else if (pReply->SCSIState & MPI_SCSI_STATE_AUTOSENSE_FAILED) { 3488 if (pReq->CDB[0] == INQUIRY) 3489 completionCode = MPT_SCANDV_ISSUE_SENSE; 3490 else 3491 completionCode = MPT_SCANDV_DID_RESET; 3492 } 3493 else if (pReply->SCSIState & MPI_SCSI_STATE_NO_SCSI_STATUS) 3494 completionCode = MPT_SCANDV_DID_RESET; 3495 else if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED) 3496 completionCode = MPT_SCANDV_DID_RESET; 3497 else { 3498 completionCode = MPT_SCANDV_GOOD; 3499 hd->pLocal->scsiStatus = scsi_status; 3500 } 3501 break; 3502 3503 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */ 3504 if (pReply->SCSIState & MPI_SCSI_STATE_TERMINATED) 3505 completionCode = MPT_SCANDV_DID_RESET; 3506 else 3507 completionCode = MPT_SCANDV_SOME_ERROR; 3508 break; 3509 3510 default: 3511 completionCode = MPT_SCANDV_SOME_ERROR; 3512 break; 3513 3514 } /* switch(status) */ 3515 3516 ddvtprintk((KERN_NOTICE " completionCode set to %08xh\n", 3517 completionCode)); 3518 } /* end of address reply case */ 3519 3520 hd->pLocal->completion = completionCode; 3521 3522 /* MF and RF are freed in mpt_interrupt 3523 */ 3524 wakeup: 3525 /* Free Chain buffers (will never chain) in scan or dv */ 3526 //mptscsih_freeChainBuffers(ioc, req_idx); 3527 3528 /* 3529 * Wake up the original calling thread 3530 */ 3531 hd->scandv_wait_done = 1; 3532 wake_up(&hd->scandv_waitq); 3533 3534 return 1; 3535 } 3536 3537 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3538 /* mptscsih_timer_expired - Call back for timer process. 3539 * Used only for dv functionality. 3540 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long 3541 * 3542 */ 3543 void 3544 mptscsih_timer_expired(unsigned long data) 3545 { 3546 MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data; 3547 3548 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired! Cmd %p\n", hd->ioc->name, hd->cmdPtr)); 3549 3550 if (hd->cmdPtr) { 3551 MPIHeader_t *cmd = (MPIHeader_t *)hd->cmdPtr; 3552 3553 if (cmd->Function == MPI_FUNCTION_SCSI_IO_REQUEST) { 3554 /* Desire to issue a task management request here. 3555 * TM requests MUST be single threaded. 3556 * If old eh code and no TM current, issue request. 3557 * If new eh code, do nothing. Wait for OS cmd timeout 3558 * for bus reset. 3559 */ 3560 ddvtprintk((MYIOC_s_NOTE_FMT "DV Cmd Timeout: NoOp\n", hd->ioc->name)); 3561 } else { 3562 /* Perform a FW reload */ 3563 if (mpt_HardResetHandler(hd->ioc, NO_SLEEP) < 0) { 3564 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", hd->ioc->name); 3565 } 3566 } 3567 } else { 3568 /* This should NEVER happen */ 3569 printk(MYIOC_s_WARN_FMT "Null cmdPtr!!!!\n", hd->ioc->name); 3570 } 3571 3572 /* No more processing. 3573 * TM call will generate an interrupt for SCSI TM Management. 3574 * The FW will reply to all outstanding commands, callback will finish cleanup. 3575 * Hard reset clean-up will free all resources. 3576 */ 3577 ddvprintk((MYIOC_s_WARN_FMT "Timer Expired Complete!\n", hd->ioc->name)); 3578 3579 return; 3580 } 3581 3582 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION 3583 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3584 /* mptscsih_do_raid - Format and Issue a RAID volume request message. 3585 * @hd: Pointer to scsi host structure 3586 * @action: What do be done. 3587 * @id: Logical target id. 3588 * @bus: Target locations bus. 3589 * 3590 * Returns: < 0 on a fatal error 3591 * 0 on success 3592 * 3593 * Remark: Wait to return until reply processed by the ISR. 3594 */ 3595 static int 3596 mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io) 3597 { 3598 MpiRaidActionRequest_t *pReq; 3599 MPT_FRAME_HDR *mf; 3600 int in_isr; 3601 3602 in_isr = in_interrupt(); 3603 if (in_isr) { 3604 dprintk((MYIOC_s_WARN_FMT "Internal raid request not allowed in ISR context!\n", 3605 hd->ioc->name)); 3606 return -EPERM; 3607 } 3608 3609 /* Get and Populate a free Frame 3610 */ 3611 if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) { 3612 ddvprintk((MYIOC_s_WARN_FMT "_do_raid: no msg frames!\n", 3613 hd->ioc->name)); 3614 return -EAGAIN; 3615 } 3616 pReq = (MpiRaidActionRequest_t *)mf; 3617 pReq->Action = action; 3618 pReq->Reserved1 = 0; 3619 pReq->ChainOffset = 0; 3620 pReq->Function = MPI_FUNCTION_RAID_ACTION; 3621 pReq->VolumeID = io->id; 3622 pReq->VolumeBus = io->bus; 3623 pReq->PhysDiskNum = io->physDiskNum; 3624 pReq->MsgFlags = 0; 3625 pReq->Reserved2 = 0; 3626 pReq->ActionDataWord = 0; /* Reserved for this action */ 3627 //pReq->ActionDataSGE = 0; 3628 3629 mpt_add_sge((char *)&pReq->ActionDataSGE, 3630 MPT_SGE_FLAGS_SSIMPLE_READ | 0, (dma_addr_t) -1); 3631 3632 ddvprintk((MYIOC_s_INFO_FMT "RAID Volume action %x id %d\n", 3633 hd->ioc->name, action, io->id)); 3634 3635 hd->pLocal = NULL; 3636 hd->timer.expires = jiffies + HZ*10; /* 10 second timeout */ 3637 hd->scandv_wait_done = 0; 3638 3639 /* Save cmd pointer, for resource free if timeout or 3640 * FW reload occurs 3641 */ 3642 hd->cmdPtr = mf; 3643 3644 add_timer(&hd->timer); 3645 mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf); 3646 wait_event(hd->scandv_waitq, hd->scandv_wait_done); 3647 3648 if ((hd->pLocal == NULL) || (hd->pLocal->completion != MPT_SCANDV_GOOD)) 3649 return -1; 3650 3651 return 0; 3652 } 3653 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */ 3654 3655 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3656 /** 3657 * mptscsih_do_cmd - Do internal command. 3658 * @hd: MPT_SCSI_HOST pointer 3659 * @io: INTERNAL_CMD pointer. 3660 * 3661 * Issue the specified internally generated command and do command 3662 * specific cleanup. For bus scan / DV only. 3663 * NOTES: If command is Inquiry and status is good, 3664 * initialize a target structure, save the data 3665 * 3666 * Remark: Single threaded access only. 3667 * 3668 * Return: 3669 * < 0 if an illegal command or no resources 3670 * 3671 * 0 if good 3672 * 3673 * > 0 if command complete but some type of completion error. 3674 */ 3675 static int 3676 mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *io) 3677 { 3678 MPT_FRAME_HDR *mf; 3679 SCSIIORequest_t *pScsiReq; 3680 SCSIIORequest_t ReqCopy; 3681 int my_idx, ii, dir; 3682 int rc, cmdTimeout; 3683 int in_isr; 3684 char cmdLen; 3685 char CDB[]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; 3686 char cmd = io->cmd; 3687 3688 in_isr = in_interrupt(); 3689 if (in_isr) { 3690 dprintk((MYIOC_s_WARN_FMT "Internal SCSI IO request not allowed in ISR context!\n", 3691 hd->ioc->name)); 3692 return -EPERM; 3693 } 3694 3695 3696 /* Set command specific information 3697 */ 3698 switch (cmd) { 3699 case INQUIRY: 3700 cmdLen = 6; 3701 dir = MPI_SCSIIO_CONTROL_READ; 3702 CDB[0] = cmd; 3703 CDB[4] = io->size; 3704 cmdTimeout = 10; 3705 break; 3706 3707 case TEST_UNIT_READY: 3708 cmdLen = 6; 3709 dir = MPI_SCSIIO_CONTROL_READ; 3710 cmdTimeout = 10; 3711 break; 3712 3713 case START_STOP: 3714 cmdLen = 6; 3715 dir = MPI_SCSIIO_CONTROL_READ; 3716 CDB[0] = cmd; 3717 CDB[4] = 1; /*Spin up the disk */ 3718 cmdTimeout = 15; 3719 break; 3720 3721 case REQUEST_SENSE: 3722 cmdLen = 6; 3723 CDB[0] = cmd; 3724 CDB[4] = io->size; 3725 dir = MPI_SCSIIO_CONTROL_READ; 3726 cmdTimeout = 10; 3727 break; 3728 3729 case READ_BUFFER: 3730 cmdLen = 10; 3731 dir = MPI_SCSIIO_CONTROL_READ; 3732 CDB[0] = cmd; 3733 if (io->flags & MPT_ICFLAG_ECHO) { 3734 CDB[1] = 0x0A; 3735 } else { 3736 CDB[1] = 0x02; 3737 } 3738 3739 if (io->flags & MPT_ICFLAG_BUF_CAP) { 3740 CDB[1] |= 0x01; 3741 } 3742 CDB[6] = (io->size >> 16) & 0xFF; 3743 CDB[7] = (io->size >> 8) & 0xFF; 3744 CDB[8] = io->size & 0xFF; 3745 cmdTimeout = 10; 3746 break; 3747 3748 case WRITE_BUFFER: 3749 cmdLen = 10; 3750 dir = MPI_SCSIIO_CONTROL_WRITE; 3751 CDB[0] = cmd; 3752 if (io->flags & MPT_ICFLAG_ECHO) { 3753 CDB[1] = 0x0A; 3754 } else { 3755 CDB[1] = 0x02; 3756 } 3757 CDB[6] = (io->size >> 16) & 0xFF; 3758 CDB[7] = (io->size >> 8) & 0xFF; 3759 CDB[8] = io->size & 0xFF; 3760 cmdTimeout = 10; 3761 break; 3762 3763 case RESERVE: 3764 cmdLen = 6; 3765 dir = MPI_SCSIIO_CONTROL_READ; 3766 CDB[0] = cmd; 3767 cmdTimeout = 10; 3768 break; 3769 3770 case RELEASE: 3771 cmdLen = 6; 3772 dir = MPI_SCSIIO_CONTROL_READ; 3773 CDB[0] = cmd; 3774 cmdTimeout = 10; 3775 break; 3776 3777 case SYNCHRONIZE_CACHE: 3778 cmdLen = 10; 3779 dir = MPI_SCSIIO_CONTROL_READ; 3780 CDB[0] = cmd; 3781 // CDB[1] = 0x02; /* set immediate bit */ 3782 cmdTimeout = 10; 3783 break; 3784 3785 default: 3786 /* Error Case */ 3787 return -EFAULT; 3788 } 3789 3790 /* Get and Populate a free Frame 3791 */ 3792 if ((mf = mpt_get_msg_frame(hd->ioc->InternalCtx, hd->ioc)) == NULL) { 3793 ddvprintk((MYIOC_s_WARN_FMT "No msg frames!\n", 3794 hd->ioc->name)); 3795 return -EBUSY; 3796 } 3797 3798 pScsiReq = (SCSIIORequest_t *) mf; 3799 3800 /* Get the request index */ 3801 my_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx); 3802 ADD_INDEX_LOG(my_idx); /* for debug */ 3803 3804 if (io->flags & MPT_ICFLAG_PHYS_DISK) { 3805 pScsiReq->TargetID = io->physDiskNum; 3806 pScsiReq->Bus = 0; 3807 pScsiReq->ChainOffset = 0; 3808 pScsiReq->Function = MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH; 3809 } else { 3810 pScsiReq->TargetID = io->id; 3811 pScsiReq->Bus = io->bus; 3812 pScsiReq->ChainOffset = 0; 3813 pScsiReq->Function = MPI_FUNCTION_SCSI_IO_REQUEST; 3814 } 3815 3816 pScsiReq->CDBLength = cmdLen; 3817 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE; 3818 3819 pScsiReq->Reserved = 0; 3820 3821 pScsiReq->MsgFlags = mpt_msg_flags(); 3822 /* MsgContext set in mpt_get_msg_fram call */ 3823 3824 for (ii=0; ii < 8; ii++) 3825 pScsiReq->LUN[ii] = 0; 3826 pScsiReq->LUN[1] = io->lun; 3827 3828 if (io->flags & MPT_ICFLAG_TAGGED_CMD) 3829 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_SIMPLEQ); 3830 else 3831 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED); 3832 3833 if (cmd == REQUEST_SENSE) { 3834 pScsiReq->Control = cpu_to_le32(dir | MPI_SCSIIO_CONTROL_UNTAGGED); 3835 ddvprintk((MYIOC_s_INFO_FMT "Untagged! 0x%2x\n", 3836 hd->ioc->name, cmd)); 3837 } 3838 3839 for (ii=0; ii < 16; ii++) 3840 pScsiReq->CDB[ii] = CDB[ii]; 3841 3842 pScsiReq->DataLength = cpu_to_le32(io->size); 3843 pScsiReq->SenseBufferLowAddr = cpu_to_le32(hd->ioc->sense_buf_low_dma 3844 + (my_idx * MPT_SENSE_BUFFER_ALLOC)); 3845 3846 ddvprintk((MYIOC_s_INFO_FMT "Sending Command 0x%x for (%d:%d:%d)\n", 3847 hd->ioc->name, cmd, io->bus, io->id, io->lun)); 3848 3849 if (dir == MPI_SCSIIO_CONTROL_READ) { 3850 mpt_add_sge((char *) &pScsiReq->SGL, 3851 MPT_SGE_FLAGS_SSIMPLE_READ | io->size, 3852 io->data_dma); 3853 } else { 3854 mpt_add_sge((char *) &pScsiReq->SGL, 3855 MPT_SGE_FLAGS_SSIMPLE_WRITE | io->size, 3856 io->data_dma); 3857 } 3858 3859 /* The ISR will free the request frame, but we need 3860 * the information to initialize the target. Duplicate. 3861 */ 3862 memcpy(&ReqCopy, pScsiReq, sizeof(SCSIIORequest_t)); 3863 3864 /* Issue this command after: 3865 * finish init 3866 * add timer 3867 * Wait until the reply has been received 3868 * ScsiScanDvCtx callback function will 3869 * set hd->pLocal; 3870 * set scandv_wait_done and call wake_up 3871 */ 3872 hd->pLocal = NULL; 3873 hd->timer.expires = jiffies + HZ*cmdTimeout; 3874 hd->scandv_wait_done = 0; 3875 3876 /* Save cmd pointer, for resource free if timeout or 3877 * FW reload occurs 3878 */ 3879 hd->cmdPtr = mf; 3880 3881 add_timer(&hd->timer); 3882 mpt_put_msg_frame(hd->ioc->InternalCtx, hd->ioc, mf); 3883 wait_event(hd->scandv_waitq, hd->scandv_wait_done); 3884 3885 if (hd->pLocal) { 3886 rc = hd->pLocal->completion; 3887 hd->pLocal->skip = 0; 3888 3889 /* Always set fatal error codes in some cases. 3890 */ 3891 if (rc == MPT_SCANDV_SELECTION_TIMEOUT) 3892 rc = -ENXIO; 3893 else if (rc == MPT_SCANDV_SOME_ERROR) 3894 rc = -rc; 3895 } else { 3896 rc = -EFAULT; 3897 /* This should never happen. */ 3898 ddvprintk((MYIOC_s_INFO_FMT "_do_cmd: Null pLocal!!!\n", 3899 hd->ioc->name)); 3900 } 3901 3902 return rc; 3903 } 3904 3905 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3906 /** 3907 * mptscsih_synchronize_cache - Send SYNCHRONIZE_CACHE to all disks. 3908 * @hd: Pointer to MPT_SCSI_HOST structure 3909 * @portnum: IOC port number 3910 * 3911 * Uses the ISR, but with special processing. 3912 * MUST be single-threaded. 3913 * 3914 * Return: 0 on completion 3915 */ 3916 static int 3917 mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum) 3918 { 3919 MPT_ADAPTER *ioc= hd->ioc; 3920 VirtDevice *pTarget; 3921 SCSIDevicePage1_t *pcfg1Data = NULL; 3922 INTERNAL_CMD iocmd; 3923 CONFIGPARMS cfg; 3924 dma_addr_t cfg1_dma_addr = -1; 3925 ConfigPageHeader_t header1; 3926 int bus = 0; 3927 int id = 0; 3928 int lun; 3929 int indexed_lun, lun_index; 3930 int hostId = ioc->pfacts[portnum].PortSCSIID; 3931 int max_id; 3932 int requested, configuration, data; 3933 int doConfig = 0; 3934 u8 flags, factor; 3935 3936 max_id = ioc->sh->max_id - 1; 3937 3938 /* Following parameters will not change 3939 * in this routine. 3940 */ 3941 iocmd.cmd = SYNCHRONIZE_CACHE; 3942 iocmd.flags = 0; 3943 iocmd.physDiskNum = -1; 3944 iocmd.data = NULL; 3945 iocmd.data_dma = -1; 3946 iocmd.size = 0; 3947 iocmd.rsvd = iocmd.rsvd2 = 0; 3948 3949 /* No SCSI hosts 3950 */ 3951 if (hd->Targets == NULL) 3952 return 0; 3953 3954 /* Skip the host 3955 */ 3956 if (id == hostId) 3957 id++; 3958 3959 /* Write SDP1 for all SCSI devices 3960 * Alloc memory and set up config buffer 3961 */ 3962 if (ioc->bus_type == SCSI) { 3963 if (ioc->spi_data.sdp1length > 0) { 3964 pcfg1Data = (SCSIDevicePage1_t *)pci_alloc_consistent(ioc->pcidev, 3965 ioc->spi_data.sdp1length * 4, &cfg1_dma_addr); 3966 3967 if (pcfg1Data != NULL) { 3968 doConfig = 1; 3969 header1.PageVersion = ioc->spi_data.sdp1version; 3970 header1.PageLength = ioc->spi_data.sdp1length; 3971 header1.PageNumber = 1; 3972 header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE; 3973 cfg.cfghdr.hdr = &header1; 3974 cfg.physAddr = cfg1_dma_addr; 3975 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; 3976 cfg.dir = 1; 3977 cfg.timeout = 0; 3978 } 3979 } 3980 } 3981 3982 /* loop through all devices on this port 3983 */ 3984 while (bus < MPT_MAX_BUS) { 3985 iocmd.bus = bus; 3986 iocmd.id = id; 3987 pTarget = hd->Targets[(int)id]; 3988 3989 if (doConfig) { 3990 3991 /* Set the negotiation flags */ 3992 if (pTarget && (pTarget = hd->Targets[id]) && !pTarget->raidVolume) { 3993 flags = pTarget->negoFlags; 3994 } else { 3995 flags = hd->ioc->spi_data.noQas; 3996 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) { 3997 data = hd->ioc->spi_data.nvram[id]; 3998 3999 if (data & MPT_NVRAM_WIDE_DISABLE) 4000 flags |= MPT_TARGET_NO_NEGO_WIDE; 4001 4002 factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT; 4003 if ((factor == 0) || (factor == MPT_ASYNC)) 4004 flags |= MPT_TARGET_NO_NEGO_SYNC; 4005 } 4006 } 4007 4008 /* Force to async, narrow */ 4009 mptscsih_setDevicePage1Flags(0, MPT_ASYNC, 0, &requested, 4010 &configuration, flags); 4011 dnegoprintk(("syncronize cache: id=%d width=0 factor=MPT_ASYNC " 4012 "offset=0 negoFlags=%x request=%x config=%x\n", 4013 id, flags, requested, configuration)); 4014 pcfg1Data->RequestedParameters = cpu_to_le32(requested); 4015 pcfg1Data->Reserved = 0; 4016 pcfg1Data->Configuration = cpu_to_le32(configuration); 4017 cfg.pageAddr = (bus<<8) | id; 4018 mpt_config(hd->ioc, &cfg); 4019 } 4020 4021 /* If target Ptr NULL or if this target is NOT a disk, skip. 4022 */ 4023 if ((pTarget) && (pTarget->inq_data[0] == TYPE_DISK)){ 4024 for (lun=0; lun <= MPT_LAST_LUN; lun++) { 4025 /* If LUN present, issue the command 4026 */ 4027 lun_index = (lun >> 5); /* 32 luns per lun_index */ 4028 indexed_lun = (lun % 32); 4029 if (pTarget->luns[lun_index] & (1<<indexed_lun)) { 4030 iocmd.lun = lun; 4031 (void) mptscsih_do_cmd(hd, &iocmd); 4032 } 4033 } 4034 } 4035 4036 /* get next relevant device */ 4037 id++; 4038 4039 if (id == hostId) 4040 id++; 4041 4042 if (id > max_id) { 4043 id = 0; 4044 bus++; 4045 } 4046 } 4047 4048 if (pcfg1Data) { 4049 pci_free_consistent(ioc->pcidev, header1.PageLength * 4, pcfg1Data, cfg1_dma_addr); 4050 } 4051 4052 return 0; 4053 } 4054 4055 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION 4056 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4057 /** 4058 * mptscsih_domainValidation - Top level handler for domain validation. 4059 * @hd: Pointer to MPT_SCSI_HOST structure. 4060 * 4061 * Uses the ISR, but with special processing. 4062 * Called from schedule, should not be in interrupt mode. 4063 * While thread alive, do dv for all devices needing dv 4064 * 4065 * Return: None. 4066 */ 4067 static void 4068 mptscsih_domainValidation(void *arg) 4069 { 4070 MPT_SCSI_HOST *hd; 4071 MPT_ADAPTER *ioc; 4072 unsigned long flags; 4073 int id, maxid, dvStatus, did; 4074 int ii, isPhysDisk; 4075 4076 spin_lock_irqsave(&dvtaskQ_lock, flags); 4077 dvtaskQ_active = 1; 4078 if (dvtaskQ_release) { 4079 dvtaskQ_active = 0; 4080 spin_unlock_irqrestore(&dvtaskQ_lock, flags); 4081 return; 4082 } 4083 spin_unlock_irqrestore(&dvtaskQ_lock, flags); 4084 4085 /* For this ioc, loop through all devices and do dv to each device. 4086 * When complete with this ioc, search through the ioc list, and 4087 * for each scsi ioc found, do dv for all devices. Exit when no 4088 * device needs dv. 4089 */ 4090 did = 1; 4091 while (did) { 4092 did = 0; 4093 list_for_each_entry(ioc, &ioc_list, list) { 4094 spin_lock_irqsave(&dvtaskQ_lock, flags); 4095 if (dvtaskQ_release) { 4096 dvtaskQ_active = 0; 4097 spin_unlock_irqrestore(&dvtaskQ_lock, flags); 4098 return; 4099 } 4100 spin_unlock_irqrestore(&dvtaskQ_lock, flags); 4101 4102 msleep(250); 4103 4104 /* DV only to SCSI adapters */ 4105 if (ioc->bus_type != SCSI) 4106 continue; 4107 4108 /* Make sure everything looks ok */ 4109 if (ioc->sh == NULL) 4110 continue; 4111 4112 hd = (MPT_SCSI_HOST *) ioc->sh->hostdata; 4113 if (hd == NULL) 4114 continue; 4115 4116 if ((ioc->spi_data.forceDv & MPT_SCSICFG_RELOAD_IOC_PG3) != 0) { 4117 mpt_read_ioc_pg_3(ioc); 4118 if (ioc->raid_data.pIocPg3) { 4119 Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk; 4120 int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks; 4121 4122 while (numPDisk) { 4123 if (ioc->spi_data.dvStatus[pPDisk->PhysDiskID] & MPT_SCSICFG_DV_NOT_DONE) 4124 ioc->spi_data.dvStatus[pPDisk->PhysDiskID] |= MPT_SCSICFG_NEED_DV; 4125 4126 pPDisk++; 4127 numPDisk--; 4128 } 4129 } 4130 ioc->spi_data.forceDv &= ~MPT_SCSICFG_RELOAD_IOC_PG3; 4131 } 4132 4133 maxid = min_t(int, ioc->sh->max_id, MPT_MAX_SCSI_DEVICES); 4134 4135 for (id = 0; id < maxid; id++) { 4136 spin_lock_irqsave(&dvtaskQ_lock, flags); 4137 if (dvtaskQ_release) { 4138 dvtaskQ_active = 0; 4139 spin_unlock_irqrestore(&dvtaskQ_lock, flags); 4140 return; 4141 } 4142 spin_unlock_irqrestore(&dvtaskQ_lock, flags); 4143 dvStatus = hd->ioc->spi_data.dvStatus[id]; 4144 4145 if (dvStatus & MPT_SCSICFG_NEED_DV) { 4146 did++; 4147 hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_DV_PENDING; 4148 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_NEED_DV; 4149 4150 msleep(250); 4151 4152 /* If hidden phys disk, block IO's to all 4153 * raid volumes 4154 * else, process normally 4155 */ 4156 isPhysDisk = mptscsih_is_phys_disk(ioc, id); 4157 if (isPhysDisk) { 4158 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) { 4159 if (hd->ioc->raid_data.isRaid & (1 << ii)) { 4160 hd->ioc->spi_data.dvStatus[ii] |= MPT_SCSICFG_DV_PENDING; 4161 } 4162 } 4163 } 4164 4165 if(mpt_alt_ioc_wait(hd->ioc)!=0) { 4166 ddvprintk((MYIOC_s_WARN_FMT "alt_ioc busy!\n", 4167 hd->ioc->name)); 4168 continue; 4169 } 4170 4171 if (mptscsih_doDv(hd, 0, id) == 1) { 4172 /* Untagged device was busy, try again 4173 */ 4174 hd->ioc->spi_data.dvStatus[id] |= MPT_SCSICFG_NEED_DV; 4175 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_PENDING; 4176 } else { 4177 /* DV is complete. Clear flags. 4178 */ 4179 hd->ioc->spi_data.dvStatus[id] &= ~(MPT_SCSICFG_DV_NOT_DONE | MPT_SCSICFG_DV_PENDING); 4180 } 4181 4182 spin_lock(&hd->ioc->initializing_hba_lock); 4183 hd->ioc->initializing_hba_lock_flag=0; 4184 spin_unlock(&hd->ioc->initializing_hba_lock); 4185 4186 if (isPhysDisk) { 4187 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) { 4188 if (hd->ioc->raid_data.isRaid & (1 << ii)) { 4189 hd->ioc->spi_data.dvStatus[ii] &= ~MPT_SCSICFG_DV_PENDING; 4190 } 4191 } 4192 } 4193 4194 if (hd->ioc->spi_data.noQas) 4195 mptscsih_qas_check(hd, id); 4196 } 4197 } 4198 } 4199 } 4200 4201 spin_lock_irqsave(&dvtaskQ_lock, flags); 4202 dvtaskQ_active = 0; 4203 spin_unlock_irqrestore(&dvtaskQ_lock, flags); 4204 4205 return; 4206 } 4207 4208 /* Search IOC page 3 to determine if this is hidden physical disk 4209 */ 4210 /* Search IOC page 3 to determine if this is hidden physical disk 4211 */ 4212 static int 4213 mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id) 4214 { 4215 int i; 4216 4217 if (!ioc->raid_data.isRaid || !ioc->raid_data.pIocPg3) 4218 return 0; 4219 4220 for (i = 0; i < ioc->raid_data.pIocPg3->NumPhysDisks; i++) { 4221 if (id == ioc->raid_data.pIocPg3->PhysDisk[i].PhysDiskID) 4222 return 1; 4223 } 4224 4225 return 0; 4226 } 4227 4228 /* Write SDP1 if no QAS has been enabled 4229 */ 4230 static void 4231 mptscsih_qas_check(MPT_SCSI_HOST *hd, int id) 4232 { 4233 VirtDevice *pTarget; 4234 int ii; 4235 4236 if (hd->Targets == NULL) 4237 return; 4238 4239 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) { 4240 if (ii == id) 4241 continue; 4242 4243 if ((hd->ioc->spi_data.dvStatus[ii] & MPT_SCSICFG_DV_NOT_DONE) != 0) 4244 continue; 4245 4246 pTarget = hd->Targets[ii]; 4247 4248 if ((pTarget != NULL) && (!pTarget->raidVolume)) { 4249 if ((pTarget->negoFlags & hd->ioc->spi_data.noQas) == 0) { 4250 pTarget->negoFlags |= hd->ioc->spi_data.noQas; 4251 dnegoprintk(("writeSDP1: id=%d flags=0\n", id)); 4252 mptscsih_writeSDP1(hd, 0, ii, 0); 4253 } 4254 } else { 4255 if (mptscsih_is_phys_disk(hd->ioc, ii) == 1) { 4256 dnegoprintk(("writeSDP1: id=%d SCSICFG_USE_NVRAM\n", id)); 4257 mptscsih_writeSDP1(hd, 0, ii, MPT_SCSICFG_USE_NVRAM); 4258 } 4259 } 4260 } 4261 return; 4262 } 4263 4264 4265 4266 #define MPT_GET_NVRAM_VALS 0x01 4267 #define MPT_UPDATE_MAX 0x02 4268 #define MPT_SET_MAX 0x04 4269 #define MPT_SET_MIN 0x08 4270 #define MPT_FALLBACK 0x10 4271 #define MPT_SAVE 0x20 4272 4273 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4274 /** 4275 * mptscsih_doDv - Perform domain validation to a target. 4276 * @hd: Pointer to MPT_SCSI_HOST structure. 4277 * @portnum: IOC port number. 4278 * @target: Physical ID of this target 4279 * 4280 * Uses the ISR, but with special processing. 4281 * MUST be single-threaded. 4282 * Test will exit if target is at async & narrow. 4283 * 4284 * Return: None. 4285 */ 4286 static int 4287 mptscsih_doDv(MPT_SCSI_HOST *hd, int bus_number, int id) 4288 { 4289 MPT_ADAPTER *ioc = hd->ioc; 4290 VirtDevice *pTarget; 4291 SCSIDevicePage1_t *pcfg1Data; 4292 SCSIDevicePage0_t *pcfg0Data; 4293 u8 *pbuf1; 4294 u8 *pbuf2; 4295 u8 *pDvBuf; 4296 dma_addr_t dvbuf_dma = -1; 4297 dma_addr_t buf1_dma = -1; 4298 dma_addr_t buf2_dma = -1; 4299 dma_addr_t cfg1_dma_addr = -1; 4300 dma_addr_t cfg0_dma_addr = -1; 4301 ConfigPageHeader_t header1; 4302 ConfigPageHeader_t header0; 4303 DVPARAMETERS dv; 4304 INTERNAL_CMD iocmd; 4305 CONFIGPARMS cfg; 4306 int dv_alloc = 0; 4307 int rc, sz = 0; 4308 int bufsize = 0; 4309 int dataBufSize = 0; 4310 int echoBufSize = 0; 4311 int notDone; 4312 int patt; 4313 int repeat; 4314 int retcode = 0; 4315 int nfactor = MPT_ULTRA320; 4316 char firstPass = 1; 4317 char doFallback = 0; 4318 char readPage0; 4319 char bus, lun; 4320 char inq0 = 0; 4321 4322 if (ioc->spi_data.sdp1length == 0) 4323 return 0; 4324 4325 if (ioc->spi_data.sdp0length == 0) 4326 return 0; 4327 4328 /* If multiple buses are used, require that the initiator 4329 * id be the same on all buses. 4330 */ 4331 if (id == ioc->pfacts[0].PortSCSIID) 4332 return 0; 4333 4334 lun = 0; 4335 bus = (u8) bus_number; 4336 ddvtprintk((MYIOC_s_NOTE_FMT 4337 "DV started: bus=%d, id=%d dv @ %p\n", 4338 ioc->name, bus, id, &dv)); 4339 4340 /* Prep DV structure 4341 */ 4342 memset (&dv, 0, sizeof(DVPARAMETERS)); 4343 dv.id = id; 4344 4345 /* Populate tmax with the current maximum 4346 * transfer parameters for this target. 4347 * Exit if narrow and async. 4348 */ 4349 dv.cmd = MPT_GET_NVRAM_VALS; 4350 mptscsih_dv_parms(hd, &dv, NULL); 4351 4352 /* Prep SCSI IO structure 4353 */ 4354 iocmd.id = id; 4355 iocmd.bus = bus; 4356 iocmd.lun = lun; 4357 iocmd.flags = 0; 4358 iocmd.physDiskNum = -1; 4359 iocmd.rsvd = iocmd.rsvd2 = 0; 4360 4361 pTarget = hd->Targets[id]; 4362 4363 /* Use tagged commands if possible. 4364 */ 4365 if (pTarget) { 4366 if (pTarget->tflags & MPT_TARGET_FLAGS_Q_YES) 4367 iocmd.flags |= MPT_ICFLAG_TAGGED_CMD; 4368 else { 4369 if (hd->ioc->facts.FWVersion.Word < 0x01000600) 4370 return 0; 4371 4372 if ((hd->ioc->facts.FWVersion.Word >= 0x01010000) && 4373 (hd->ioc->facts.FWVersion.Word < 0x01010B00)) 4374 return 0; 4375 } 4376 } 4377 4378 /* Prep cfg structure 4379 */ 4380 cfg.pageAddr = (bus<<8) | id; 4381 cfg.cfghdr.hdr = NULL; 4382 4383 /* Prep SDP0 header 4384 */ 4385 header0.PageVersion = ioc->spi_data.sdp0version; 4386 header0.PageLength = ioc->spi_data.sdp0length; 4387 header0.PageNumber = 0; 4388 header0.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE; 4389 4390 /* Prep SDP1 header 4391 */ 4392 header1.PageVersion = ioc->spi_data.sdp1version; 4393 header1.PageLength = ioc->spi_data.sdp1length; 4394 header1.PageNumber = 1; 4395 header1.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE; 4396 4397 if (header0.PageLength & 1) 4398 dv_alloc = (header0.PageLength * 4) + 4; 4399 4400 dv_alloc += (2048 + (header1.PageLength * 4)); 4401 4402 pDvBuf = pci_alloc_consistent(ioc->pcidev, dv_alloc, &dvbuf_dma); 4403 if (pDvBuf == NULL) 4404 return 0; 4405 4406 sz = 0; 4407 pbuf1 = (u8 *)pDvBuf; 4408 buf1_dma = dvbuf_dma; 4409 sz +=1024; 4410 4411 pbuf2 = (u8 *) (pDvBuf + sz); 4412 buf2_dma = dvbuf_dma + sz; 4413 sz +=1024; 4414 4415 pcfg0Data = (SCSIDevicePage0_t *) (pDvBuf + sz); 4416 cfg0_dma_addr = dvbuf_dma + sz; 4417 sz += header0.PageLength * 4; 4418 4419 /* 8-byte alignment 4420 */ 4421 if (header0.PageLength & 1) 4422 sz += 4; 4423 4424 pcfg1Data = (SCSIDevicePage1_t *) (pDvBuf + sz); 4425 cfg1_dma_addr = dvbuf_dma + sz; 4426 4427 /* Skip this ID? Set cfg.cfghdr.hdr to force config page write 4428 */ 4429 { 4430 SpiCfgData *pspi_data = &hd->ioc->spi_data; 4431 if (pspi_data->nvram && (pspi_data->nvram[id] != MPT_HOST_NVRAM_INVALID)) { 4432 /* Set the factor from nvram */ 4433 nfactor = (pspi_data->nvram[id] & MPT_NVRAM_SYNC_MASK) >> 8; 4434 if (nfactor < pspi_data->minSyncFactor ) 4435 nfactor = pspi_data->minSyncFactor; 4436 4437 if (!(pspi_data->nvram[id] & MPT_NVRAM_ID_SCAN_ENABLE) || 4438 (pspi_data->PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_OFF_DV) ) { 4439 4440 ddvprintk((MYIOC_s_NOTE_FMT "DV Skipped: bus, id, lun (%d, %d, %d)\n", 4441 ioc->name, bus, id, lun)); 4442 4443 dv.cmd = MPT_SET_MAX; 4444 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data); 4445 cfg.cfghdr.hdr = &header1; 4446 4447 /* Save the final negotiated settings to 4448 * SCSI device page 1. 4449 */ 4450 cfg.physAddr = cfg1_dma_addr; 4451 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; 4452 cfg.dir = 1; 4453 mpt_config(hd->ioc, &cfg); 4454 goto target_done; 4455 } 4456 } 4457 } 4458 4459 /* Finish iocmd inititialization - hidden or visible disk? */ 4460 if (ioc->raid_data.pIocPg3) { 4461 /* Search IOC page 3 for matching id 4462 */ 4463 Ioc3PhysDisk_t *pPDisk = ioc->raid_data.pIocPg3->PhysDisk; 4464 int numPDisk = ioc->raid_data.pIocPg3->NumPhysDisks; 4465 4466 while (numPDisk) { 4467 if (pPDisk->PhysDiskID == id) { 4468 /* match */ 4469 iocmd.flags |= MPT_ICFLAG_PHYS_DISK; 4470 iocmd.physDiskNum = pPDisk->PhysDiskNum; 4471 4472 /* Quiesce the IM 4473 */ 4474 if (mptscsih_do_raid(hd, MPI_RAID_ACTION_QUIESCE_PHYS_IO, &iocmd) < 0) { 4475 ddvprintk((MYIOC_s_ERR_FMT "RAID Queisce FAILED!\n", ioc->name)); 4476 goto target_done; 4477 } 4478 break; 4479 } 4480 pPDisk++; 4481 numPDisk--; 4482 } 4483 } 4484 4485 /* RAID Volume ID's may double for a physical device. If RAID but 4486 * not a physical ID as well, skip DV. 4487 */ 4488 if ((hd->ioc->raid_data.isRaid & (1 << id)) && !(iocmd.flags & MPT_ICFLAG_PHYS_DISK)) 4489 goto target_done; 4490 4491 4492 /* Basic Test. 4493 * Async & Narrow - Inquiry 4494 * Async & Narrow - Inquiry 4495 * Maximum transfer rate - Inquiry 4496 * Compare buffers: 4497 * If compare, test complete. 4498 * If miscompare and first pass, repeat 4499 * If miscompare and not first pass, fall back and repeat 4500 */ 4501 hd->pLocal = NULL; 4502 readPage0 = 0; 4503 sz = SCSI_MAX_INQUIRY_BYTES; 4504 rc = MPT_SCANDV_GOOD; 4505 while (1) { 4506 ddvprintk((MYIOC_s_NOTE_FMT "DV: Start Basic test on id=%d\n", ioc->name, id)); 4507 retcode = 0; 4508 dv.cmd = MPT_SET_MIN; 4509 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data); 4510 4511 cfg.cfghdr.hdr = &header1; 4512 cfg.physAddr = cfg1_dma_addr; 4513 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; 4514 cfg.dir = 1; 4515 if (mpt_config(hd->ioc, &cfg) != 0) 4516 goto target_done; 4517 4518 /* Wide - narrow - wide workaround case 4519 */ 4520 if ((rc == MPT_SCANDV_ISSUE_SENSE) && dv.max.width) { 4521 /* Send an untagged command to reset disk Qs corrupted 4522 * when a parity error occurs on a Request Sense. 4523 */ 4524 if ((hd->ioc->facts.FWVersion.Word >= 0x01000600) || 4525 ((hd->ioc->facts.FWVersion.Word >= 0x01010000) && 4526 (hd->ioc->facts.FWVersion.Word < 0x01010B00)) ) { 4527 4528 iocmd.cmd = REQUEST_SENSE; 4529 iocmd.data_dma = buf1_dma; 4530 iocmd.data = pbuf1; 4531 iocmd.size = 0x12; 4532 if (mptscsih_do_cmd(hd, &iocmd) < 0) 4533 goto target_done; 4534 else { 4535 if (hd->pLocal == NULL) 4536 goto target_done; 4537 rc = hd->pLocal->completion; 4538 if ((rc == MPT_SCANDV_GOOD) || (rc == MPT_SCANDV_SENSE)) { 4539 dv.max.width = 0; 4540 doFallback = 0; 4541 } else 4542 goto target_done; 4543 } 4544 } else 4545 goto target_done; 4546 } 4547 4548 iocmd.cmd = INQUIRY; 4549 iocmd.data_dma = buf1_dma; 4550 iocmd.data = pbuf1; 4551 iocmd.size = sz; 4552 memset(pbuf1, 0x00, sz); 4553 if (mptscsih_do_cmd(hd, &iocmd) < 0) 4554 goto target_done; 4555 else { 4556 if (hd->pLocal == NULL) 4557 goto target_done; 4558 rc = hd->pLocal->completion; 4559 if (rc == MPT_SCANDV_GOOD) { 4560 if (hd->pLocal->scsiStatus == SAM_STAT_BUSY) { 4561 if ((iocmd.flags & MPT_ICFLAG_TAGGED_CMD) == 0) 4562 retcode = 1; 4563 else 4564 retcode = 0; 4565 4566 goto target_done; 4567 } 4568 } else if (rc == MPT_SCANDV_SENSE) { 4569 ; 4570 } else { 4571 /* If first command doesn't complete 4572 * with a good status or with a check condition, 4573 * exit. 4574 */ 4575 goto target_done; 4576 } 4577 } 4578 4579 /* Reset the size for disks 4580 */ 4581 inq0 = (*pbuf1) & 0x1F; 4582 if ((inq0 == 0) && pTarget && !pTarget->raidVolume) { 4583 sz = 0x40; 4584 iocmd.size = sz; 4585 } 4586 4587 /* Another GEM workaround. Check peripheral device type, 4588 * if PROCESSOR, quit DV. 4589 */ 4590 if (inq0 == TYPE_PROCESSOR) { 4591 mptscsih_initTarget(hd, 4592 bus, 4593 id, 4594 lun, 4595 pbuf1, 4596 sz); 4597 goto target_done; 4598 } 4599 4600 if (inq0 > 0x08) 4601 goto target_done; 4602 4603 if (mptscsih_do_cmd(hd, &iocmd) < 0) 4604 goto target_done; 4605 4606 if (sz == 0x40) { 4607 if ((pTarget->maxWidth == 1) && (pTarget->maxOffset) && (nfactor < 0x0A) 4608 && (pTarget->minSyncFactor > 0x09)) { 4609 if ((pbuf1[56] & 0x04) == 0) 4610 ; 4611 else if ((pbuf1[56] & 0x01) == 1) { 4612 pTarget->minSyncFactor = 4613 nfactor > MPT_ULTRA320 ? nfactor : MPT_ULTRA320; 4614 } else { 4615 pTarget->minSyncFactor = 4616 nfactor > MPT_ULTRA160 ? nfactor : MPT_ULTRA160; 4617 } 4618 4619 dv.max.factor = pTarget->minSyncFactor; 4620 4621 if ((pbuf1[56] & 0x02) == 0) { 4622 pTarget->negoFlags |= MPT_TARGET_NO_NEGO_QAS; 4623 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS; 4624 ddvprintk((MYIOC_s_NOTE_FMT 4625 "DV: Start Basic noQas on id=%d due to pbuf1[56]=%x\n", 4626 ioc->name, id, pbuf1[56])); 4627 } 4628 } 4629 } 4630 4631 if (doFallback) 4632 dv.cmd = MPT_FALLBACK; 4633 else 4634 dv.cmd = MPT_SET_MAX; 4635 4636 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data); 4637 if (mpt_config(hd->ioc, &cfg) != 0) 4638 goto target_done; 4639 4640 if ((!dv.now.width) && (!dv.now.offset)) 4641 goto target_done; 4642 4643 iocmd.cmd = INQUIRY; 4644 iocmd.data_dma = buf2_dma; 4645 iocmd.data = pbuf2; 4646 iocmd.size = sz; 4647 memset(pbuf2, 0x00, sz); 4648 if (mptscsih_do_cmd(hd, &iocmd) < 0) 4649 goto target_done; 4650 else if (hd->pLocal == NULL) 4651 goto target_done; 4652 else { 4653 /* Save the return code. 4654 * If this is the first pass, 4655 * read SCSI Device Page 0 4656 * and update the target max parameters. 4657 */ 4658 rc = hd->pLocal->completion; 4659 doFallback = 0; 4660 if (rc == MPT_SCANDV_GOOD) { 4661 if (!readPage0) { 4662 u32 sdp0_info; 4663 u32 sdp0_nego; 4664 4665 cfg.cfghdr.hdr = &header0; 4666 cfg.physAddr = cfg0_dma_addr; 4667 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 4668 cfg.dir = 0; 4669 4670 if (mpt_config(hd->ioc, &cfg) != 0) 4671 goto target_done; 4672 4673 sdp0_info = le32_to_cpu(pcfg0Data->Information) & 0x0E; 4674 sdp0_nego = (le32_to_cpu(pcfg0Data->NegotiatedParameters) & 0xFF00 ) >> 8; 4675 4676 /* Quantum and Fujitsu workarounds. 4677 * Quantum: PPR U320 -> PPR reply with Ultra2 and wide 4678 * Fujitsu: PPR U320 -> Msg Reject and Ultra2 and wide 4679 * Resetart with a request for U160. 4680 */ 4681 if ((dv.now.factor == MPT_ULTRA320) && (sdp0_nego == MPT_ULTRA2)) { 4682 doFallback = 1; 4683 } else { 4684 dv.cmd = MPT_UPDATE_MAX; 4685 mptscsih_dv_parms(hd, &dv, (void *)pcfg0Data); 4686 /* Update the SCSI device page 1 area 4687 */ 4688 pcfg1Data->RequestedParameters = pcfg0Data->NegotiatedParameters; 4689 readPage0 = 1; 4690 } 4691 } 4692 4693 /* Quantum workaround. Restart this test will the fallback 4694 * flag set. 4695 */ 4696 if (doFallback == 0) { 4697 if (memcmp(pbuf1, pbuf2, sz) != 0) { 4698 if (!firstPass) 4699 doFallback = 1; 4700 } else { 4701 ddvprintk((MYIOC_s_NOTE_FMT 4702 "DV:Inquiry compared id=%d, calling initTarget\n", ioc->name, id)); 4703 hd->ioc->spi_data.dvStatus[id] &= ~MPT_SCSICFG_DV_NOT_DONE; 4704 mptscsih_initTarget(hd, 4705 bus, 4706 id, 4707 lun, 4708 pbuf1, 4709 sz); 4710 break; /* test complete */ 4711 } 4712 } 4713 4714 4715 } else if (rc == MPT_SCANDV_ISSUE_SENSE) 4716 doFallback = 1; /* set fallback flag */ 4717 else if ((rc == MPT_SCANDV_DID_RESET) || 4718 (rc == MPT_SCANDV_SENSE) || 4719 (rc == MPT_SCANDV_FALLBACK)) 4720 doFallback = 1; /* set fallback flag */ 4721 else 4722 goto target_done; 4723 4724 firstPass = 0; 4725 } 4726 } 4727 ddvprintk((MYIOC_s_NOTE_FMT "DV: Basic test on id=%d completed OK.\n", ioc->name, id)); 4728 4729 if (ioc->spi_data.mpt_dv == 0) 4730 goto target_done; 4731 4732 inq0 = (*pbuf1) & 0x1F; 4733 4734 /* Continue only for disks 4735 */ 4736 if (inq0 != 0) 4737 goto target_done; 4738 4739 if ( ioc->spi_data.PortFlags == MPI_SCSIPORTPAGE2_PORT_FLAGS_BASIC_DV_ONLY ) 4740 goto target_done; 4741 4742 /* Start the Enhanced Test. 4743 * 0) issue TUR to clear out check conditions 4744 * 1) read capacity of echo (regular) buffer 4745 * 2) reserve device 4746 * 3) do write-read-compare data pattern test 4747 * 4) release 4748 * 5) update nego parms to target struct 4749 */ 4750 cfg.cfghdr.hdr = &header1; 4751 cfg.physAddr = cfg1_dma_addr; 4752 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; 4753 cfg.dir = 1; 4754 4755 iocmd.cmd = TEST_UNIT_READY; 4756 iocmd.data_dma = -1; 4757 iocmd.data = NULL; 4758 iocmd.size = 0; 4759 notDone = 1; 4760 while (notDone) { 4761 if (mptscsih_do_cmd(hd, &iocmd) < 0) 4762 goto target_done; 4763 4764 if (hd->pLocal == NULL) 4765 goto target_done; 4766 4767 rc = hd->pLocal->completion; 4768 if (rc == MPT_SCANDV_GOOD) 4769 notDone = 0; 4770 else if (rc == MPT_SCANDV_SENSE) { 4771 u8 skey = hd->pLocal->sense[2] & 0x0F; 4772 u8 asc = hd->pLocal->sense[12]; 4773 u8 ascq = hd->pLocal->sense[13]; 4774 ddvprintk((MYIOC_s_INFO_FMT 4775 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", 4776 ioc->name, skey, asc, ascq)); 4777 4778 if (skey == UNIT_ATTENTION) 4779 notDone++; /* repeat */ 4780 else if ((skey == NOT_READY) && 4781 (asc == 0x04)&&(ascq == 0x01)) { 4782 /* wait then repeat */ 4783 mdelay (2000); 4784 notDone++; 4785 } else if ((skey == NOT_READY) && (asc == 0x3A)) { 4786 /* no medium, try read test anyway */ 4787 notDone = 0; 4788 } else { 4789 /* All other errors are fatal. 4790 */ 4791 ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.", 4792 ioc->name)); 4793 goto target_done; 4794 } 4795 } else 4796 goto target_done; 4797 } 4798 4799 iocmd.cmd = READ_BUFFER; 4800 iocmd.data_dma = buf1_dma; 4801 iocmd.data = pbuf1; 4802 iocmd.size = 4; 4803 iocmd.flags |= MPT_ICFLAG_BUF_CAP; 4804 4805 dataBufSize = 0; 4806 echoBufSize = 0; 4807 for (patt = 0; patt < 2; patt++) { 4808 if (patt == 0) 4809 iocmd.flags |= MPT_ICFLAG_ECHO; 4810 else 4811 iocmd.flags &= ~MPT_ICFLAG_ECHO; 4812 4813 notDone = 1; 4814 while (notDone) { 4815 bufsize = 0; 4816 4817 /* If not ready after 8 trials, 4818 * give up on this device. 4819 */ 4820 if (notDone > 8) 4821 goto target_done; 4822 4823 if (mptscsih_do_cmd(hd, &iocmd) < 0) 4824 goto target_done; 4825 else if (hd->pLocal == NULL) 4826 goto target_done; 4827 else { 4828 rc = hd->pLocal->completion; 4829 ddvprintk(("ReadBuffer Comp Code %d", rc)); 4830 ddvprintk((" buff: %0x %0x %0x %0x\n", 4831 pbuf1[0], pbuf1[1], pbuf1[2], pbuf1[3])); 4832 4833 if (rc == MPT_SCANDV_GOOD) { 4834 notDone = 0; 4835 if (iocmd.flags & MPT_ICFLAG_ECHO) { 4836 bufsize = ((pbuf1[2] & 0x1F) <<8) | pbuf1[3]; 4837 if (pbuf1[0] & 0x01) 4838 iocmd.flags |= MPT_ICFLAG_EBOS; 4839 } else { 4840 bufsize = pbuf1[1]<<16 | pbuf1[2]<<8 | pbuf1[3]; 4841 } 4842 } else if (rc == MPT_SCANDV_SENSE) { 4843 u8 skey = hd->pLocal->sense[2] & 0x0F; 4844 u8 asc = hd->pLocal->sense[12]; 4845 u8 ascq = hd->pLocal->sense[13]; 4846 ddvprintk((MYIOC_s_INFO_FMT 4847 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", 4848 ioc->name, skey, asc, ascq)); 4849 if (skey == ILLEGAL_REQUEST) { 4850 notDone = 0; 4851 } else if (skey == UNIT_ATTENTION) { 4852 notDone++; /* repeat */ 4853 } else if ((skey == NOT_READY) && 4854 (asc == 0x04)&&(ascq == 0x01)) { 4855 /* wait then repeat */ 4856 mdelay (2000); 4857 notDone++; 4858 } else { 4859 /* All other errors are fatal. 4860 */ 4861 ddvprintk((MYIOC_s_INFO_FMT "DV: fatal error.", 4862 ioc->name)); 4863 goto target_done; 4864 } 4865 } else { 4866 /* All other errors are fatal 4867 */ 4868 goto target_done; 4869 } 4870 } 4871 } 4872 4873 if (iocmd.flags & MPT_ICFLAG_ECHO) 4874 echoBufSize = bufsize; 4875 else 4876 dataBufSize = bufsize; 4877 } 4878 sz = 0; 4879 iocmd.flags &= ~MPT_ICFLAG_BUF_CAP; 4880 4881 /* Use echo buffers if possible, 4882 * Exit if both buffers are 0. 4883 */ 4884 if (echoBufSize > 0) { 4885 iocmd.flags |= MPT_ICFLAG_ECHO; 4886 if (dataBufSize > 0) 4887 bufsize = min(echoBufSize, dataBufSize); 4888 else 4889 bufsize = echoBufSize; 4890 } else if (dataBufSize == 0) 4891 goto target_done; 4892 4893 ddvprintk((MYIOC_s_INFO_FMT "%s Buffer Capacity %d\n", ioc->name, 4894 (iocmd.flags & MPT_ICFLAG_ECHO) ? "Echo" : " ", bufsize)); 4895 4896 /* Data buffers for write-read-compare test max 1K. 4897 */ 4898 sz = min(bufsize, 1024); 4899 4900 /* --- loop ---- 4901 * On first pass, always issue a reserve. 4902 * On additional loops, only if a reset has occurred. 4903 * iocmd.flags indicates if echo or regular buffer 4904 */ 4905 for (patt = 0; patt < 4; patt++) { 4906 ddvprintk(("Pattern %d\n", patt)); 4907 if ((iocmd.flags & MPT_ICFLAG_RESERVED) && (iocmd.flags & MPT_ICFLAG_DID_RESET)) { 4908 iocmd.cmd = TEST_UNIT_READY; 4909 iocmd.data_dma = -1; 4910 iocmd.data = NULL; 4911 iocmd.size = 0; 4912 if (mptscsih_do_cmd(hd, &iocmd) < 0) 4913 goto target_done; 4914 4915 iocmd.cmd = RELEASE; 4916 iocmd.data_dma = -1; 4917 iocmd.data = NULL; 4918 iocmd.size = 0; 4919 if (mptscsih_do_cmd(hd, &iocmd) < 0) 4920 goto target_done; 4921 else if (hd->pLocal == NULL) 4922 goto target_done; 4923 else { 4924 rc = hd->pLocal->completion; 4925 ddvprintk(("Release rc %d\n", rc)); 4926 if (rc == MPT_SCANDV_GOOD) 4927 iocmd.flags &= ~MPT_ICFLAG_RESERVED; 4928 else 4929 goto target_done; 4930 } 4931 iocmd.flags &= ~MPT_ICFLAG_RESERVED; 4932 } 4933 iocmd.flags &= ~MPT_ICFLAG_DID_RESET; 4934 4935 if (iocmd.flags & MPT_ICFLAG_EBOS) 4936 goto skip_Reserve; 4937 4938 repeat = 5; 4939 while (repeat && (!(iocmd.flags & MPT_ICFLAG_RESERVED))) { 4940 iocmd.cmd = RESERVE; 4941 iocmd.data_dma = -1; 4942 iocmd.data = NULL; 4943 iocmd.size = 0; 4944 if (mptscsih_do_cmd(hd, &iocmd) < 0) 4945 goto target_done; 4946 else if (hd->pLocal == NULL) 4947 goto target_done; 4948 else { 4949 rc = hd->pLocal->completion; 4950 if (rc == MPT_SCANDV_GOOD) { 4951 iocmd.flags |= MPT_ICFLAG_RESERVED; 4952 } else if (rc == MPT_SCANDV_SENSE) { 4953 /* Wait if coming ready 4954 */ 4955 u8 skey = hd->pLocal->sense[2] & 0x0F; 4956 u8 asc = hd->pLocal->sense[12]; 4957 u8 ascq = hd->pLocal->sense[13]; 4958 ddvprintk((MYIOC_s_INFO_FMT 4959 "DV: Reserve Failed: ", ioc->name)); 4960 ddvprintk(("SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", 4961 skey, asc, ascq)); 4962 4963 if ((skey == NOT_READY) && (asc == 0x04)&& 4964 (ascq == 0x01)) { 4965 /* wait then repeat */ 4966 mdelay (2000); 4967 notDone++; 4968 } else { 4969 ddvprintk((MYIOC_s_INFO_FMT 4970 "DV: Reserved Failed.", ioc->name)); 4971 goto target_done; 4972 } 4973 } else { 4974 ddvprintk((MYIOC_s_INFO_FMT "DV: Reserved Failed.", 4975 ioc->name)); 4976 goto target_done; 4977 } 4978 } 4979 } 4980 4981 skip_Reserve: 4982 mptscsih_fillbuf(pbuf1, sz, patt, 1); 4983 iocmd.cmd = WRITE_BUFFER; 4984 iocmd.data_dma = buf1_dma; 4985 iocmd.data = pbuf1; 4986 iocmd.size = sz; 4987 if (mptscsih_do_cmd(hd, &iocmd) < 0) 4988 goto target_done; 4989 else if (hd->pLocal == NULL) 4990 goto target_done; 4991 else { 4992 rc = hd->pLocal->completion; 4993 if (rc == MPT_SCANDV_GOOD) 4994 ; /* Issue read buffer */ 4995 else if (rc == MPT_SCANDV_DID_RESET) { 4996 /* If using echo buffers, reset to data buffers. 4997 * Else do Fallback and restart 4998 * this test (re-issue reserve 4999 * because of bus reset). 5000 */ 5001 if ((iocmd.flags & MPT_ICFLAG_ECHO) && (dataBufSize >= bufsize)) { 5002 iocmd.flags &= ~MPT_ICFLAG_ECHO; 5003 } else { 5004 dv.cmd = MPT_FALLBACK; 5005 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data); 5006 5007 if (mpt_config(hd->ioc, &cfg) != 0) 5008 goto target_done; 5009 5010 if ((!dv.now.width) && (!dv.now.offset)) 5011 goto target_done; 5012 } 5013 5014 iocmd.flags |= MPT_ICFLAG_DID_RESET; 5015 patt = -1; 5016 continue; 5017 } else if (rc == MPT_SCANDV_SENSE) { 5018 /* Restart data test if UA, else quit. 5019 */ 5020 u8 skey = hd->pLocal->sense[2] & 0x0F; 5021 ddvprintk((MYIOC_s_INFO_FMT 5022 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey, 5023 hd->pLocal->sense[12], hd->pLocal->sense[13])); 5024 if (skey == UNIT_ATTENTION) { 5025 patt = -1; 5026 continue; 5027 } else if (skey == ILLEGAL_REQUEST) { 5028 if (iocmd.flags & MPT_ICFLAG_ECHO) { 5029 if (dataBufSize >= bufsize) { 5030 iocmd.flags &= ~MPT_ICFLAG_ECHO; 5031 patt = -1; 5032 continue; 5033 } 5034 } 5035 goto target_done; 5036 } 5037 else 5038 goto target_done; 5039 } else { 5040 /* fatal error */ 5041 goto target_done; 5042 } 5043 } 5044 5045 iocmd.cmd = READ_BUFFER; 5046 iocmd.data_dma = buf2_dma; 5047 iocmd.data = pbuf2; 5048 iocmd.size = sz; 5049 if (mptscsih_do_cmd(hd, &iocmd) < 0) 5050 goto target_done; 5051 else if (hd->pLocal == NULL) 5052 goto target_done; 5053 else { 5054 rc = hd->pLocal->completion; 5055 if (rc == MPT_SCANDV_GOOD) { 5056 /* If buffers compare, 5057 * go to next pattern, 5058 * else, do a fallback and restart 5059 * data transfer test. 5060 */ 5061 if (memcmp (pbuf1, pbuf2, sz) == 0) { 5062 ; /* goto next pattern */ 5063 } else { 5064 /* Miscompare with Echo buffer, go to data buffer, 5065 * if that buffer exists. 5066 * Miscompare with Data buffer, check first 4 bytes, 5067 * some devices return capacity. Exit in this case. 5068 */ 5069 if (iocmd.flags & MPT_ICFLAG_ECHO) { 5070 if (dataBufSize >= bufsize) 5071 iocmd.flags &= ~MPT_ICFLAG_ECHO; 5072 else 5073 goto target_done; 5074 } else { 5075 if (dataBufSize == (pbuf2[1]<<16 | pbuf2[2]<<8 | pbuf2[3])) { 5076 /* Argh. Device returning wrong data. 5077 * Quit DV for this device. 5078 */ 5079 goto target_done; 5080 } 5081 5082 /* Had an actual miscompare. Slow down.*/ 5083 dv.cmd = MPT_FALLBACK; 5084 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data); 5085 5086 if (mpt_config(hd->ioc, &cfg) != 0) 5087 goto target_done; 5088 5089 if ((!dv.now.width) && (!dv.now.offset)) 5090 goto target_done; 5091 } 5092 5093 patt = -1; 5094 continue; 5095 } 5096 } else if (rc == MPT_SCANDV_DID_RESET) { 5097 /* Do Fallback and restart 5098 * this test (re-issue reserve 5099 * because of bus reset). 5100 */ 5101 dv.cmd = MPT_FALLBACK; 5102 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data); 5103 5104 if (mpt_config(hd->ioc, &cfg) != 0) 5105 goto target_done; 5106 5107 if ((!dv.now.width) && (!dv.now.offset)) 5108 goto target_done; 5109 5110 iocmd.flags |= MPT_ICFLAG_DID_RESET; 5111 patt = -1; 5112 continue; 5113 } else if (rc == MPT_SCANDV_SENSE) { 5114 /* Restart data test if UA, else quit. 5115 */ 5116 u8 skey = hd->pLocal->sense[2] & 0x0F; 5117 ddvprintk((MYIOC_s_INFO_FMT 5118 "SenseKey:ASC:ASCQ = (%x:%02x:%02x)\n", ioc->name, skey, 5119 hd->pLocal->sense[12], hd->pLocal->sense[13])); 5120 if (skey == UNIT_ATTENTION) { 5121 patt = -1; 5122 continue; 5123 } 5124 else 5125 goto target_done; 5126 } else { 5127 /* fatal error */ 5128 goto target_done; 5129 } 5130 } 5131 5132 } /* --- end of patt loop ---- */ 5133 5134 target_done: 5135 if (iocmd.flags & MPT_ICFLAG_RESERVED) { 5136 iocmd.cmd = RELEASE; 5137 iocmd.data_dma = -1; 5138 iocmd.data = NULL; 5139 iocmd.size = 0; 5140 if (mptscsih_do_cmd(hd, &iocmd) < 0) 5141 printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d", 5142 ioc->name, id); 5143 else if (hd->pLocal) { 5144 if (hd->pLocal->completion == MPT_SCANDV_GOOD) 5145 iocmd.flags &= ~MPT_ICFLAG_RESERVED; 5146 } else { 5147 printk(MYIOC_s_INFO_FMT "DV: Release failed. id %d", 5148 ioc->name, id); 5149 } 5150 } 5151 5152 5153 /* Set if cfg1_dma_addr contents is valid 5154 */ 5155 if ((cfg.cfghdr.hdr != NULL) && (retcode == 0)){ 5156 /* If disk, not U320, disable QAS 5157 */ 5158 if ((inq0 == 0) && (dv.now.factor > MPT_ULTRA320)) { 5159 hd->ioc->spi_data.noQas = MPT_TARGET_NO_NEGO_QAS; 5160 ddvprintk((MYIOC_s_NOTE_FMT 5161 "noQas set due to id=%d has factor=%x\n", ioc->name, id, dv.now.factor)); 5162 } 5163 5164 dv.cmd = MPT_SAVE; 5165 mptscsih_dv_parms(hd, &dv, (void *)pcfg1Data); 5166 5167 /* Double writes to SDP1 can cause problems, 5168 * skip save of the final negotiated settings to 5169 * SCSI device page 1. 5170 * 5171 cfg.cfghdr.hdr = &header1; 5172 cfg.physAddr = cfg1_dma_addr; 5173 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; 5174 cfg.dir = 1; 5175 mpt_config(hd->ioc, &cfg); 5176 */ 5177 } 5178 5179 /* If this is a RAID Passthrough, enable internal IOs 5180 */ 5181 if (iocmd.flags & MPT_ICFLAG_PHYS_DISK) { 5182 if (mptscsih_do_raid(hd, MPI_RAID_ACTION_ENABLE_PHYS_IO, &iocmd) < 0) 5183 ddvprintk((MYIOC_s_ERR_FMT "RAID Enable FAILED!\n", ioc->name)); 5184 } 5185 5186 /* Done with the DV scan of the current target 5187 */ 5188 if (pDvBuf) 5189 pci_free_consistent(ioc->pcidev, dv_alloc, pDvBuf, dvbuf_dma); 5190 5191 ddvtprintk((MYIOC_s_INFO_FMT "DV Done id=%d\n", 5192 ioc->name, id)); 5193 5194 return retcode; 5195 } 5196 5197 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 5198 /* mptscsih_dv_parms - perform a variety of operations on the 5199 * parameters used for negotiation. 5200 * @hd: Pointer to a SCSI host. 5201 * @dv: Pointer to a structure that contains the maximum and current 5202 * negotiated parameters. 5203 */ 5204 static void 5205 mptscsih_dv_parms(MPT_SCSI_HOST *hd, DVPARAMETERS *dv,void *pPage) 5206 { 5207 VirtDevice *pTarget; 5208 SCSIDevicePage0_t *pPage0; 5209 SCSIDevicePage1_t *pPage1; 5210 int val = 0, data, configuration; 5211 u8 width = 0; 5212 u8 offset = 0; 5213 u8 factor = 0; 5214 u8 negoFlags = 0; 5215 u8 cmd = dv->cmd; 5216 u8 id = dv->id; 5217 5218 switch (cmd) { 5219 case MPT_GET_NVRAM_VALS: 5220 ddvprintk((MYIOC_s_NOTE_FMT "Getting NVRAM: ", 5221 hd->ioc->name)); 5222 /* Get the NVRAM values and save in tmax 5223 * If not an LVD bus, the adapter minSyncFactor has been 5224 * already throttled back. 5225 */ 5226 negoFlags = hd->ioc->spi_data.noQas; 5227 if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume) { 5228 width = pTarget->maxWidth; 5229 offset = pTarget->maxOffset; 5230 factor = pTarget->minSyncFactor; 5231 negoFlags |= pTarget->negoFlags; 5232 } else { 5233 if (hd->ioc->spi_data.nvram && (hd->ioc->spi_data.nvram[id] != MPT_HOST_NVRAM_INVALID)) { 5234 data = hd->ioc->spi_data.nvram[id]; 5235 width = data & MPT_NVRAM_WIDE_DISABLE ? 0 : 1; 5236 if ((offset = hd->ioc->spi_data.maxSyncOffset) == 0) 5237 factor = MPT_ASYNC; 5238 else { 5239 factor = (data & MPT_NVRAM_SYNC_MASK) >> MPT_NVRAM_SYNC_SHIFT; 5240 if ((factor == 0) || (factor == MPT_ASYNC)){ 5241 factor = MPT_ASYNC; 5242 offset = 0; 5243 } 5244 } 5245 } else { 5246 width = MPT_NARROW; 5247 offset = 0; 5248 factor = MPT_ASYNC; 5249 } 5250 5251 /* Set the negotiation flags */ 5252 if (!width) 5253 negoFlags |= MPT_TARGET_NO_NEGO_WIDE; 5254 5255 if (!offset) 5256 negoFlags |= MPT_TARGET_NO_NEGO_SYNC; 5257 } 5258 5259 /* limit by adapter capabilities */ 5260 width = min(width, hd->ioc->spi_data.maxBusWidth); 5261 offset = min(offset, hd->ioc->spi_data.maxSyncOffset); 5262 factor = max(factor, hd->ioc->spi_data.minSyncFactor); 5263 5264 /* Check Consistency */ 5265 if (offset && (factor < MPT_ULTRA2) && !width) 5266 factor = MPT_ULTRA2; 5267 5268 dv->max.width = width; 5269 dv->max.offset = offset; 5270 dv->max.factor = factor; 5271 dv->max.flags = negoFlags; 5272 ddvprintk((" id=%d width=%d factor=%x offset=%x flags=%x\n", 5273 id, width, factor, offset, negoFlags)); 5274 break; 5275 5276 case MPT_UPDATE_MAX: 5277 ddvprintk((MYIOC_s_NOTE_FMT 5278 "Updating with SDP0 Data: ", hd->ioc->name)); 5279 /* Update tmax values with those from Device Page 0.*/ 5280 pPage0 = (SCSIDevicePage0_t *) pPage; 5281 if (pPage0) { 5282 val = le32_to_cpu(pPage0->NegotiatedParameters); 5283 dv->max.width = val & MPI_SCSIDEVPAGE0_NP_WIDE ? 1 : 0; 5284 dv->max.offset = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_OFFSET_MASK) >> 16; 5285 dv->max.factor = (val&MPI_SCSIDEVPAGE0_NP_NEG_SYNC_PERIOD_MASK) >> 8; 5286 } 5287 5288 dv->now.width = dv->max.width; 5289 dv->now.offset = dv->max.offset; 5290 dv->now.factor = dv->max.factor; 5291 ddvprintk(("id=%d width=%d factor=%x offset=%x flags=%x\n", 5292 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags)); 5293 break; 5294 5295 case MPT_SET_MAX: 5296 ddvprintk((MYIOC_s_NOTE_FMT "Setting Max: ", 5297 hd->ioc->name)); 5298 /* Set current to the max values. Update the config page.*/ 5299 dv->now.width = dv->max.width; 5300 dv->now.offset = dv->max.offset; 5301 dv->now.factor = dv->max.factor; 5302 dv->now.flags = dv->max.flags; 5303 5304 pPage1 = (SCSIDevicePage1_t *)pPage; 5305 if (pPage1) { 5306 mptscsih_setDevicePage1Flags (dv->now.width, dv->now.factor, 5307 dv->now.offset, &val, &configuration, dv->now.flags); 5308 dnegoprintk(("Setting Max: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n", 5309 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration)); 5310 pPage1->RequestedParameters = cpu_to_le32(val); 5311 pPage1->Reserved = 0; 5312 pPage1->Configuration = cpu_to_le32(configuration); 5313 } 5314 5315 ddvprintk(("id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x configuration=%x\n", 5316 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags, val, configuration)); 5317 break; 5318 5319 case MPT_SET_MIN: 5320 ddvprintk((MYIOC_s_NOTE_FMT "Setting Min: ", 5321 hd->ioc->name)); 5322 /* Set page to asynchronous and narrow 5323 * Do not update now, breaks fallback routine. */ 5324 width = MPT_NARROW; 5325 offset = 0; 5326 factor = MPT_ASYNC; 5327 negoFlags = dv->max.flags; 5328 5329 pPage1 = (SCSIDevicePage1_t *)pPage; 5330 if (pPage1) { 5331 mptscsih_setDevicePage1Flags (width, factor, 5332 offset, &val, &configuration, negoFlags); 5333 dnegoprintk(("Setting Min: id=%d width=%d factor=%x offset=%x negoFlags=%x request=%x config=%x\n", 5334 id, width, factor, offset, negoFlags, val, configuration)); 5335 pPage1->RequestedParameters = cpu_to_le32(val); 5336 pPage1->Reserved = 0; 5337 pPage1->Configuration = cpu_to_le32(configuration); 5338 } 5339 ddvprintk(("id=%d width=%d factor=%x offset=%x request=%x config=%x negoFlags=%x\n", 5340 id, width, factor, offset, val, configuration, negoFlags)); 5341 break; 5342 5343 case MPT_FALLBACK: 5344 ddvprintk((MYIOC_s_NOTE_FMT 5345 "Fallback: Start: offset %d, factor %x, width %d \n", 5346 hd->ioc->name, dv->now.offset, 5347 dv->now.factor, dv->now.width)); 5348 width = dv->now.width; 5349 offset = dv->now.offset; 5350 factor = dv->now.factor; 5351 if ((offset) && (dv->max.width)) { 5352 if (factor < MPT_ULTRA160) 5353 factor = MPT_ULTRA160; 5354 else if (factor < MPT_ULTRA2) { 5355 factor = MPT_ULTRA2; 5356 width = MPT_WIDE; 5357 } else if ((factor == MPT_ULTRA2) && width) { 5358 factor = MPT_ULTRA2; 5359 width = MPT_NARROW; 5360 } else if (factor < MPT_ULTRA) { 5361 factor = MPT_ULTRA; 5362 width = MPT_WIDE; 5363 } else if ((factor == MPT_ULTRA) && width) { 5364 width = MPT_NARROW; 5365 } else if (factor < MPT_FAST) { 5366 factor = MPT_FAST; 5367 width = MPT_WIDE; 5368 } else if ((factor == MPT_FAST) && width) { 5369 factor = MPT_FAST; 5370 width = MPT_NARROW; 5371 } else if (factor < MPT_SCSI) { 5372 factor = MPT_SCSI; 5373 width = MPT_WIDE; 5374 } else if ((factor == MPT_SCSI) && width) { 5375 factor = MPT_SCSI; 5376 width = MPT_NARROW; 5377 } else { 5378 factor = MPT_ASYNC; 5379 offset = 0; 5380 } 5381 5382 } else if (offset) { 5383 width = MPT_NARROW; 5384 if (factor < MPT_ULTRA) 5385 factor = MPT_ULTRA; 5386 else if (factor < MPT_FAST) 5387 factor = MPT_FAST; 5388 else if (factor < MPT_SCSI) 5389 factor = MPT_SCSI; 5390 else { 5391 factor = MPT_ASYNC; 5392 offset = 0; 5393 } 5394 5395 } else { 5396 width = MPT_NARROW; 5397 factor = MPT_ASYNC; 5398 } 5399 dv->max.flags |= MPT_TARGET_NO_NEGO_QAS; 5400 dv->max.flags &= ~MPT_TAPE_NEGO_IDP; 5401 5402 dv->now.width = width; 5403 dv->now.offset = offset; 5404 dv->now.factor = factor; 5405 dv->now.flags = dv->max.flags; 5406 5407 pPage1 = (SCSIDevicePage1_t *)pPage; 5408 if (pPage1) { 5409 mptscsih_setDevicePage1Flags (width, factor, offset, &val, 5410 &configuration, dv->now.flags); 5411 dnegoprintk(("Finish: id=%d width=%d offset=%d factor=%x negoFlags=%x request=%x config=%x\n", 5412 id, width, offset, factor, dv->now.flags, val, configuration)); 5413 5414 pPage1->RequestedParameters = cpu_to_le32(val); 5415 pPage1->Reserved = 0; 5416 pPage1->Configuration = cpu_to_le32(configuration); 5417 } 5418 5419 ddvprintk(("Finish: id=%d offset=%d factor=%x width=%d request=%x config=%x\n", 5420 id, dv->now.offset, dv->now.factor, dv->now.width, val, configuration)); 5421 break; 5422 5423 case MPT_SAVE: 5424 ddvprintk((MYIOC_s_NOTE_FMT 5425 "Saving to Target structure: ", hd->ioc->name)); 5426 ddvprintk(("id=%d width=%x factor=%x offset=%d flags=%x\n", 5427 id, dv->now.width, dv->now.factor, dv->now.offset, dv->now.flags)); 5428 5429 /* Save these values to target structures 5430 * or overwrite nvram (phys disks only). 5431 */ 5432 5433 if ((hd->Targets)&&((pTarget = hd->Targets[(int)id]) != NULL) && !pTarget->raidVolume ) { 5434 pTarget->maxWidth = dv->now.width; 5435 pTarget->maxOffset = dv->now.offset; 5436 pTarget->minSyncFactor = dv->now.factor; 5437 pTarget->negoFlags = dv->now.flags; 5438 } else { 5439 /* Preserv all flags, use 5440 * read-modify-write algorithm 5441 */ 5442 if (hd->ioc->spi_data.nvram) { 5443 data = hd->ioc->spi_data.nvram[id]; 5444 5445 if (dv->now.width) 5446 data &= ~MPT_NVRAM_WIDE_DISABLE; 5447 else 5448 data |= MPT_NVRAM_WIDE_DISABLE; 5449 5450 if (!dv->now.offset) 5451 factor = MPT_ASYNC; 5452 5453 data &= ~MPT_NVRAM_SYNC_MASK; 5454 data |= (dv->now.factor << MPT_NVRAM_SYNC_SHIFT) & MPT_NVRAM_SYNC_MASK; 5455 5456 hd->ioc->spi_data.nvram[id] = data; 5457 } 5458 } 5459 break; 5460 } 5461 } 5462 5463 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 5464 /* mptscsih_fillbuf - fill a buffer with a special data pattern 5465 * cleanup. For bus scan only. 5466 * 5467 * @buffer: Pointer to data buffer to be filled. 5468 * @size: Number of bytes to fill 5469 * @index: Pattern index 5470 * @width: bus width, 0 (8 bits) or 1 (16 bits) 5471 */ 5472 static void 5473 mptscsih_fillbuf(char *buffer, int size, int index, int width) 5474 { 5475 char *ptr = buffer; 5476 int ii; 5477 char byte; 5478 short val; 5479 5480 switch (index) { 5481 case 0: 5482 5483 if (width) { 5484 /* Pattern: 0000 FFFF 0000 FFFF 5485 */ 5486 for (ii=0; ii < size; ii++, ptr++) { 5487 if (ii & 0x02) 5488 *ptr = 0xFF; 5489 else 5490 *ptr = 0x00; 5491 } 5492 } else { 5493 /* Pattern: 00 FF 00 FF 5494 */ 5495 for (ii=0; ii < size; ii++, ptr++) { 5496 if (ii & 0x01) 5497 *ptr = 0xFF; 5498 else 5499 *ptr = 0x00; 5500 } 5501 } 5502 break; 5503 5504 case 1: 5505 if (width) { 5506 /* Pattern: 5555 AAAA 5555 AAAA 5555 5507 */ 5508 for (ii=0; ii < size; ii++, ptr++) { 5509 if (ii & 0x02) 5510 *ptr = 0xAA; 5511 else 5512 *ptr = 0x55; 5513 } 5514 } else { 5515 /* Pattern: 55 AA 55 AA 55 5516 */ 5517 for (ii=0; ii < size; ii++, ptr++) { 5518 if (ii & 0x01) 5519 *ptr = 0xAA; 5520 else 5521 *ptr = 0x55; 5522 } 5523 } 5524 break; 5525 5526 case 2: 5527 /* Pattern: 00 01 02 03 04 05 5528 * ... FE FF 00 01.. 5529 */ 5530 for (ii=0; ii < size; ii++, ptr++) 5531 *ptr = (char) ii; 5532 break; 5533 5534 case 3: 5535 if (width) { 5536 /* Wide Pattern: FFFE 0001 FFFD 0002 5537 * ... 4000 DFFF 8000 EFFF 5538 */ 5539 byte = 0; 5540 for (ii=0; ii < size/2; ii++) { 5541 /* Create the base pattern 5542 */ 5543 val = (1 << byte); 5544 /* every 64 (0x40) bytes flip the pattern 5545 * since we fill 2 bytes / iteration, 5546 * test for ii = 0x20 5547 */ 5548 if (ii & 0x20) 5549 val = ~(val); 5550 5551 if (ii & 0x01) { 5552 *ptr = (char)( (val & 0xFF00) >> 8); 5553 ptr++; 5554 *ptr = (char)(val & 0xFF); 5555 byte++; 5556 byte &= 0x0F; 5557 } else { 5558 val = ~val; 5559 *ptr = (char)( (val & 0xFF00) >> 8); 5560 ptr++; 5561 *ptr = (char)(val & 0xFF); 5562 } 5563 5564 ptr++; 5565 } 5566 } else { 5567 /* Narrow Pattern: FE 01 FD 02 FB 04 5568 * .. 7F 80 01 FE 02 FD ... 80 7F 5569 */ 5570 byte = 0; 5571 for (ii=0; ii < size; ii++, ptr++) { 5572 /* Base pattern - first 32 bytes 5573 */ 5574 if (ii & 0x01) { 5575 *ptr = (1 << byte); 5576 byte++; 5577 byte &= 0x07; 5578 } else { 5579 *ptr = (char) (~(1 << byte)); 5580 } 5581 5582 /* Flip the pattern every 32 bytes 5583 */ 5584 if (ii & 0x20) 5585 *ptr = ~(*ptr); 5586 } 5587 } 5588 break; 5589 } 5590 } 5591 #endif /* ~MPTSCSIH_ENABLE_DOMAIN_VALIDATION */ 5592 5593 EXPORT_SYMBOL(mptscsih_remove); 5594 EXPORT_SYMBOL(mptscsih_shutdown); 5595 #ifdef CONFIG_PM 5596 EXPORT_SYMBOL(mptscsih_suspend); 5597 EXPORT_SYMBOL(mptscsih_resume); 5598 #endif 5599 EXPORT_SYMBOL(mptscsih_proc_info); 5600 EXPORT_SYMBOL(mptscsih_info); 5601 EXPORT_SYMBOL(mptscsih_qcmd); 5602 EXPORT_SYMBOL(mptscsih_slave_alloc); 5603 EXPORT_SYMBOL(mptscsih_slave_destroy); 5604 EXPORT_SYMBOL(mptscsih_slave_configure); 5605 EXPORT_SYMBOL(mptscsih_abort); 5606 EXPORT_SYMBOL(mptscsih_dev_reset); 5607 EXPORT_SYMBOL(mptscsih_bus_reset); 5608 EXPORT_SYMBOL(mptscsih_host_reset); 5609 EXPORT_SYMBOL(mptscsih_bios_param); 5610 EXPORT_SYMBOL(mptscsih_io_done); 5611 EXPORT_SYMBOL(mptscsih_taskmgmt_complete); 5612 EXPORT_SYMBOL(mptscsih_scandv_complete); 5613 EXPORT_SYMBOL(mptscsih_event_process); 5614 EXPORT_SYMBOL(mptscsih_ioc_reset); 5615 EXPORT_SYMBOL(mptscsih_change_queue_depth); 5616 EXPORT_SYMBOL(mptscsih_timer_expired); 5617 5618 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 5619