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