aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/message/fusion/mptbase.c1
-rw-r--r--drivers/message/fusion/mptbase.h10
-rw-r--r--drivers/message/fusion/mptfc.c125
-rw-r--r--drivers/message/fusion/mptscsih.c48
4 files changed, 107 insertions, 77 deletions
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index ac66a658aa11..5fe6e8df50ab 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -1189,7 +1189,6 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1189 ioc->diagPending = 0; 1189 ioc->diagPending = 0;
1190 spin_lock_init(&ioc->diagLock); 1190 spin_lock_init(&ioc->diagLock);
1191 spin_lock_init(&ioc->fc_rescan_work_lock); 1191 spin_lock_init(&ioc->fc_rescan_work_lock);
1192 spin_lock_init(&ioc->fc_rport_lock);
1193 spin_lock_init(&ioc->initializing_hba_lock); 1192 spin_lock_init(&ioc->initializing_hba_lock);
1194 1193
1195 /* Initialize the event logging. 1194 /* Initialize the event logging.
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index be7e8501b53c..f673cca507e1 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -76,8 +76,8 @@
76#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR 76#define COPYRIGHT "Copyright (c) 1999-2005 " MODULEAUTHOR
77#endif 77#endif
78 78
79#define MPT_LINUX_VERSION_COMMON "3.03.08" 79#define MPT_LINUX_VERSION_COMMON "3.03.09"
80#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.08" 80#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.03.09"
81#define WHAT_MAGIC_STRING "@" "(" "#" ")" 81#define WHAT_MAGIC_STRING "@" "(" "#" ")"
82 82
83#define show_mptmod_ver(s,ver) \ 83#define show_mptmod_ver(s,ver) \
@@ -489,7 +489,6 @@ typedef struct _RaidCfgData {
489 489
490#define MPT_RPORT_INFO_FLAGS_REGISTERED 0x01 /* rport registered */ 490#define MPT_RPORT_INFO_FLAGS_REGISTERED 0x01 /* rport registered */
491#define MPT_RPORT_INFO_FLAGS_MISSING 0x02 /* missing from DevPage0 scan */ 491#define MPT_RPORT_INFO_FLAGS_MISSING 0x02 /* missing from DevPage0 scan */
492#define MPT_RPORT_INFO_FLAGS_MAPPED_VDEV 0x04 /* target mapped in vdev */
493 492
494/* 493/*
495 * data allocated for each fc rport device 494 * data allocated for each fc rport device
@@ -501,7 +500,6 @@ struct mptfc_rport_info
501 struct scsi_target *starget; 500 struct scsi_target *starget;
502 FCDevicePage0_t pg0; 501 FCDevicePage0_t pg0;
503 u8 flags; 502 u8 flags;
504 u8 remap_needed;
505}; 503};
506 504
507/* 505/*
@@ -628,11 +626,11 @@ typedef struct _MPT_ADAPTER
628 struct work_struct mptscsih_persistTask; 626 struct work_struct mptscsih_persistTask;
629 627
630 struct list_head fc_rports; 628 struct list_head fc_rports;
631 spinlock_t fc_rport_lock; /* list and ri flags */
632 spinlock_t fc_rescan_work_lock; 629 spinlock_t fc_rescan_work_lock;
633 int fc_rescan_work_count; 630 int fc_rescan_work_count;
634 struct work_struct fc_rescan_work; 631 struct work_struct fc_rescan_work;
635 632 char fc_rescan_work_q_name[KOBJ_NAME_LEN];
633 struct workqueue_struct *fc_rescan_work_q;
636} MPT_ADAPTER; 634} MPT_ADAPTER;
637 635
638/* 636/*
diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c
index b343f2a68b1c..e1fb5a166366 100644
--- a/drivers/message/fusion/mptfc.c
+++ b/drivers/message/fusion/mptfc.c
@@ -355,15 +355,13 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
355 struct fc_rport *rport; 355 struct fc_rport *rport;
356 struct mptfc_rport_info *ri; 356 struct mptfc_rport_info *ri;
357 int new_ri = 1; 357 int new_ri = 1;
358 u64 pn; 358 u64 pn, nn;
359 unsigned long flags;
360 VirtTarget *vtarget; 359 VirtTarget *vtarget;
361 360
362 if (mptfc_generate_rport_ids(pg0, &rport_ids) < 0) 361 if (mptfc_generate_rport_ids(pg0, &rport_ids) < 0)
363 return; 362 return;
364 363
365 /* scan list looking for a match */ 364 /* scan list looking for a match */
366 spin_lock_irqsave(&ioc->fc_rport_lock, flags);
367 list_for_each_entry(ri, &ioc->fc_rports, list) { 365 list_for_each_entry(ri, &ioc->fc_rports, list) {
368 pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low; 366 pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
369 if (pn == rport_ids.port_name) { /* match */ 367 if (pn == rport_ids.port_name) { /* match */
@@ -373,11 +371,9 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
373 } 371 }
374 } 372 }
375 if (new_ri) { /* allocate one */ 373 if (new_ri) { /* allocate one */
376 spin_unlock_irqrestore(&ioc->fc_rport_lock, flags);
377 ri = kzalloc(sizeof(struct mptfc_rport_info), GFP_KERNEL); 374 ri = kzalloc(sizeof(struct mptfc_rport_info), GFP_KERNEL);
378 if (!ri) 375 if (!ri)
379 return; 376 return;
380 spin_lock_irqsave(&ioc->fc_rport_lock, flags);
381 list_add_tail(&ri->list, &ioc->fc_rports); 377 list_add_tail(&ri->list, &ioc->fc_rports);
382 } 378 }
383 379
@@ -387,14 +383,11 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
387 /* MPT_RPORT_INFO_FLAGS_REGISTERED - rport not previously deleted */ 383 /* MPT_RPORT_INFO_FLAGS_REGISTERED - rport not previously deleted */
388 if (!(ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED)) { 384 if (!(ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED)) {
389 ri->flags |= MPT_RPORT_INFO_FLAGS_REGISTERED; 385 ri->flags |= MPT_RPORT_INFO_FLAGS_REGISTERED;
390 spin_unlock_irqrestore(&ioc->fc_rport_lock, flags);
391 rport = fc_remote_port_add(ioc->sh, channel, &rport_ids); 386 rport = fc_remote_port_add(ioc->sh, channel, &rport_ids);
392 spin_lock_irqsave(&ioc->fc_rport_lock, flags);
393 if (rport) { 387 if (rport) {
394 ri->rport = rport; 388 ri->rport = rport;
395 if (new_ri) /* may have been reset by user */ 389 if (new_ri) /* may have been reset by user */
396 rport->dev_loss_tmo = mptfc_dev_loss_tmo; 390 rport->dev_loss_tmo = mptfc_dev_loss_tmo;
397 *((struct mptfc_rport_info **)rport->dd_data) = ri;
398 /* 391 /*
399 * if already mapped, remap here. If not mapped, 392 * if already mapped, remap here. If not mapped,
400 * target_alloc will allocate vtarget and map, 393 * target_alloc will allocate vtarget and map,
@@ -406,16 +399,20 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
406 vtarget->target_id = pg0->CurrentTargetID; 399 vtarget->target_id = pg0->CurrentTargetID;
407 vtarget->bus_id = pg0->CurrentBus; 400 vtarget->bus_id = pg0->CurrentBus;
408 } 401 }
409 ri->remap_needed = 0;
410 } 402 }
403 /* once dd_data is filled in, commands will issue to hardware */
404 *((struct mptfc_rport_info **)rport->dd_data) = ri;
405
406 pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
407 nn = (u64)ri->pg0.WWNN.High << 32 | (u64)ri->pg0.WWNN.Low;
411 dfcprintk ((MYIOC_s_INFO_FMT 408 dfcprintk ((MYIOC_s_INFO_FMT
412 "mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, " 409 "mptfc_reg_dev.%d: %x, %llx / %llx, tid %d, "
413 "rport tid %d, tmo %d\n", 410 "rport tid %d, tmo %d\n",
414 ioc->name, 411 ioc->name,
415 ioc->sh->host_no, 412 ioc->sh->host_no,
416 pg0->PortIdentifier, 413 pg0->PortIdentifier,
417 pg0->WWNN, 414 (unsigned long long)nn,
418 pg0->WWPN, 415 (unsigned long long)pn,
419 pg0->CurrentTargetID, 416 pg0->CurrentTargetID,
420 ri->rport->scsi_target_id, 417 ri->rport->scsi_target_id,
421 ri->rport->dev_loss_tmo)); 418 ri->rport->dev_loss_tmo));
@@ -425,8 +422,6 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
425 ri = NULL; 422 ri = NULL;
426 } 423 }
427 } 424 }
428 spin_unlock_irqrestore(&ioc->fc_rport_lock,flags);
429
430} 425}
431 426
432/* 427/*
@@ -476,7 +471,6 @@ mptfc_target_alloc(struct scsi_target *starget)
476 vtarget->target_id = ri->pg0.CurrentTargetID; 471 vtarget->target_id = ri->pg0.CurrentTargetID;
477 vtarget->bus_id = ri->pg0.CurrentBus; 472 vtarget->bus_id = ri->pg0.CurrentBus;
478 ri->starget = starget; 473 ri->starget = starget;
479 ri->remap_needed = 0;
480 rc = 0; 474 rc = 0;
481 } 475 }
482 } 476 }
@@ -502,10 +496,10 @@ mptfc_slave_alloc(struct scsi_device *sdev)
502 VirtDevice *vdev; 496 VirtDevice *vdev;
503 struct scsi_target *starget; 497 struct scsi_target *starget;
504 struct fc_rport *rport; 498 struct fc_rport *rport;
505 unsigned long flags;
506 499
507 500
508 rport = starget_to_rport(scsi_target(sdev)); 501 starget = scsi_target(sdev);
502 rport = starget_to_rport(starget);
509 503
510 if (!rport || fc_remote_port_chkready(rport)) 504 if (!rport || fc_remote_port_chkready(rport))
511 return -ENXIO; 505 return -ENXIO;
@@ -519,10 +513,8 @@ mptfc_slave_alloc(struct scsi_device *sdev)
519 return -ENOMEM; 513 return -ENOMEM;
520 } 514 }
521 515
522 spin_lock_irqsave(&hd->ioc->fc_rport_lock,flags);
523 516
524 sdev->hostdata = vdev; 517 sdev->hostdata = vdev;
525 starget = scsi_target(sdev);
526 vtarget = starget->hostdata; 518 vtarget = starget->hostdata;
527 519
528 if (vtarget->num_luns == 0) { 520 if (vtarget->num_luns == 0) {
@@ -535,14 +527,16 @@ mptfc_slave_alloc(struct scsi_device *sdev)
535 vdev->vtarget = vtarget; 527 vdev->vtarget = vtarget;
536 vdev->lun = sdev->lun; 528 vdev->lun = sdev->lun;
537 529
538 spin_unlock_irqrestore(&hd->ioc->fc_rport_lock,flags);
539
540 vtarget->num_luns++; 530 vtarget->num_luns++;
541 531
532
542#ifdef DMPT_DEBUG_FC 533#ifdef DMPT_DEBUG_FC
543 { 534 {
535 u64 nn, pn;
544 struct mptfc_rport_info *ri; 536 struct mptfc_rport_info *ri;
545 ri = *((struct mptfc_rport_info **)rport->dd_data); 537 ri = *((struct mptfc_rport_info **)rport->dd_data);
538 pn = (u64)ri->pg0.WWPN.High << 32 | (u64)ri->pg0.WWPN.Low;
539 nn = (u64)ri->pg0.WWNN.High << 32 | (u64)ri->pg0.WWNN.Low;
546 dfcprintk ((MYIOC_s_INFO_FMT 540 dfcprintk ((MYIOC_s_INFO_FMT
547 "mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, " 541 "mptfc_slv_alloc.%d: num_luns %d, sdev.id %d, "
548 "CurrentTargetID %d, %x %llx %llx\n", 542 "CurrentTargetID %d, %x %llx %llx\n",
@@ -550,7 +544,9 @@ mptfc_slave_alloc(struct scsi_device *sdev)
550 sdev->host->host_no, 544 sdev->host->host_no,
551 vtarget->num_luns, 545 vtarget->num_luns,
552 sdev->id, ri->pg0.CurrentTargetID, 546 sdev->id, ri->pg0.CurrentTargetID,
553 ri->pg0.PortIdentifier, ri->pg0.WWPN, ri->pg0.WWNN)); 547 ri->pg0.PortIdentifier,
548 (unsigned long long)pn,
549 (unsigned long long)nn));
554 } 550 }
555#endif 551#endif
556 552
@@ -570,11 +566,31 @@ mptfc_qcmd(struct scsi_cmnd *SCpnt, void (*done)(struct scsi_cmnd *))
570 done(SCpnt); 566 done(SCpnt);
571 return 0; 567 return 0;
572 } 568 }
569
570 /* dd_data is null until finished adding target */
573 ri = *((struct mptfc_rport_info **)rport->dd_data); 571 ri = *((struct mptfc_rport_info **)rport->dd_data);
574 if (unlikely(ri->remap_needed)) 572 if (unlikely(!ri)) {
575 return SCSI_MLQUEUE_HOST_BUSY; 573 dfcprintk ((MYIOC_s_INFO_FMT
574 "mptfc_qcmd.%d: %d:%d, dd_data is null.\n",
575 ((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->name,
576 ((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->sh->host_no,
577 SCpnt->device->id,SCpnt->device->lun));
578 SCpnt->result = DID_IMM_RETRY << 16;
579 done(SCpnt);
580 return 0;
581 }
576 582
577 return mptscsih_qcmd(SCpnt,done); 583 err = mptscsih_qcmd(SCpnt,done);
584#ifdef DMPT_DEBUG_FC
585 if (unlikely(err)) {
586 dfcprintk ((MYIOC_s_INFO_FMT
587 "mptfc_qcmd.%d: %d:%d, mptscsih_qcmd returns non-zero.\n",
588 ((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->name,
589 ((MPT_SCSI_HOST *) SCpnt->device->host->hostdata)->ioc->sh->host_no,
590 SCpnt->device->id,SCpnt->device->lun));
591 }
592#endif
593 return err;
578} 594}
579 595
580static void 596static void
@@ -615,18 +631,17 @@ mptfc_rescan_devices(void *arg)
615 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg; 631 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
616 int ii; 632 int ii;
617 int work_to_do; 633 int work_to_do;
634 u64 pn;
618 unsigned long flags; 635 unsigned long flags;
619 struct mptfc_rport_info *ri; 636 struct mptfc_rport_info *ri;
620 637
621 do { 638 do {
622 /* start by tagging all ports as missing */ 639 /* start by tagging all ports as missing */
623 spin_lock_irqsave(&ioc->fc_rport_lock,flags);
624 list_for_each_entry(ri, &ioc->fc_rports, list) { 640 list_for_each_entry(ri, &ioc->fc_rports, list) {
625 if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) { 641 if (ri->flags & MPT_RPORT_INFO_FLAGS_REGISTERED) {
626 ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING; 642 ri->flags |= MPT_RPORT_INFO_FLAGS_MISSING;
627 } 643 }
628 } 644 }
629 spin_unlock_irqrestore(&ioc->fc_rport_lock,flags);
630 645
631 /* 646 /*
632 * now rescan devices known to adapter, 647 * now rescan devices known to adapter,
@@ -639,33 +654,24 @@ mptfc_rescan_devices(void *arg)
639 } 654 }
640 655
641 /* delete devices still missing */ 656 /* delete devices still missing */
642 spin_lock_irqsave(&ioc->fc_rport_lock, flags);
643 list_for_each_entry(ri, &ioc->fc_rports, list) { 657 list_for_each_entry(ri, &ioc->fc_rports, list) {
644 /* if newly missing, delete it */ 658 /* if newly missing, delete it */
645 if ((ri->flags & (MPT_RPORT_INFO_FLAGS_REGISTERED | 659 if (ri->flags & MPT_RPORT_INFO_FLAGS_MISSING) {
646 MPT_RPORT_INFO_FLAGS_MISSING))
647 == (MPT_RPORT_INFO_FLAGS_REGISTERED |
648 MPT_RPORT_INFO_FLAGS_MISSING)) {
649 660
650 ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED| 661 ri->flags &= ~(MPT_RPORT_INFO_FLAGS_REGISTERED|
651 MPT_RPORT_INFO_FLAGS_MISSING); 662 MPT_RPORT_INFO_FLAGS_MISSING);
652 ri->remap_needed = 1; 663 fc_remote_port_delete(ri->rport); /* won't sleep */
653 fc_remote_port_delete(ri->rport);
654 /*
655 * remote port not really deleted 'cause
656 * binding is by WWPN and driver only
657 * registers FCP_TARGETs but cannot trust
658 * data structures.
659 */
660 ri->rport = NULL; 664 ri->rport = NULL;
665
666 pn = (u64)ri->pg0.WWPN.High << 32 |
667 (u64)ri->pg0.WWPN.Low;
661 dfcprintk ((MYIOC_s_INFO_FMT 668 dfcprintk ((MYIOC_s_INFO_FMT
662 "mptfc_rescan.%d: %llx deleted\n", 669 "mptfc_rescan.%d: %llx deleted\n",
663 ioc->name, 670 ioc->name,
664 ioc->sh->host_no, 671 ioc->sh->host_no,
665 ri->pg0.WWPN)); 672 (unsigned long long)pn));
666 } 673 }
667 } 674 }
668 spin_unlock_irqrestore(&ioc->fc_rport_lock,flags);
669 675
670 /* 676 /*
671 * allow multiple passes as target state 677 * allow multiple passes as target state
@@ -870,10 +876,23 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
870 goto out_mptfc_probe; 876 goto out_mptfc_probe;
871 } 877 }
872 878
873 for (ii=0; ii < ioc->facts.NumberOfPorts; ii++) { 879 /* initialize workqueue */
874 mptfc_init_host_attr(ioc,ii); 880
875 mptfc_GetFcDevPage0(ioc,ii,mptfc_register_dev); 881 snprintf(ioc->fc_rescan_work_q_name, KOBJ_NAME_LEN, "mptfc_wq_%d",
876 } 882 sh->host_no);
883 ioc->fc_rescan_work_q =
884 create_singlethread_workqueue(ioc->fc_rescan_work_q_name);
885 if (!ioc->fc_rescan_work_q)
886 goto out_mptfc_probe;
887
888 /*
889 * scan for rports -
890 * by doing it via the workqueue, some locking is eliminated
891 */
892
893 ioc->fc_rescan_work_count = 1;
894 queue_work(ioc->fc_rescan_work_q, &ioc->fc_rescan_work);
895 flush_workqueue(ioc->fc_rescan_work_q);
877 896
878 return 0; 897 return 0;
879 898
@@ -949,8 +968,18 @@ mptfc_init(void)
949static void __devexit 968static void __devexit
950mptfc_remove(struct pci_dev *pdev) 969mptfc_remove(struct pci_dev *pdev)
951{ 970{
952 MPT_ADAPTER *ioc = pci_get_drvdata(pdev); 971 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
953 struct mptfc_rport_info *p, *n; 972 struct mptfc_rport_info *p, *n;
973 struct workqueue_struct *work_q;
974 unsigned long flags;
975
976 /* destroy workqueue */
977 if ((work_q=ioc->fc_rescan_work_q)) {
978 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
979 ioc->fc_rescan_work_q = NULL;
980 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
981 destroy_workqueue(work_q);
982 }
954 983
955 fc_remove_host(ioc->sh); 984 fc_remove_host(ioc->sh);
956 985
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index 6a71b066bd21..84fa271eb8f4 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -632,7 +632,11 @@ mptscsih_io_done(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
632 632
633 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */ 633 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
634 /* Spoof to SCSI Selection Timeout! */ 634 /* Spoof to SCSI Selection Timeout! */
635 sc->result = DID_NO_CONNECT << 16; 635 if (ioc->bus_type != FC)
636 sc->result = DID_NO_CONNECT << 16;
637 /* else fibre, just stall until rescan event */
638 else
639 sc->result = DID_REQUEUE << 16;
636 640
637 if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF) 641 if (hd->sel_timeout[pScsiReq->TargetID] < 0xFFFF)
638 hd->sel_timeout[pScsiReq->TargetID]++; 642 hd->sel_timeout[pScsiReq->TargetID]++;
@@ -1645,7 +1649,6 @@ int
1645mptscsih_abort(struct scsi_cmnd * SCpnt) 1649mptscsih_abort(struct scsi_cmnd * SCpnt)
1646{ 1650{
1647 MPT_SCSI_HOST *hd; 1651 MPT_SCSI_HOST *hd;
1648 MPT_ADAPTER *ioc;
1649 MPT_FRAME_HDR *mf; 1652 MPT_FRAME_HDR *mf;
1650 u32 ctx2abort; 1653 u32 ctx2abort;
1651 int scpnt_idx; 1654 int scpnt_idx;
@@ -1663,14 +1666,6 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
1663 return FAILED; 1666 return FAILED;
1664 } 1667 }
1665 1668
1666 ioc = hd->ioc;
1667 if (hd->resetPending) {
1668 return FAILED;
1669 }
1670
1671 if (hd->timeouts < -1)
1672 hd->timeouts++;
1673
1674 /* Find this command 1669 /* Find this command
1675 */ 1670 */
1676 if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) { 1671 if ((scpnt_idx = SCPNT_TO_LOOKUP_IDX(SCpnt)) < 0) {
@@ -1684,6 +1679,13 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
1684 return SUCCESS; 1679 return SUCCESS;
1685 } 1680 }
1686 1681
1682 if (hd->resetPending) {
1683 return FAILED;
1684 }
1685
1686 if (hd->timeouts < -1)
1687 hd->timeouts++;
1688
1687 printk(KERN_WARNING MYNAM ": %s: attempting task abort! (sc=%p)\n", 1689 printk(KERN_WARNING MYNAM ": %s: attempting task abort! (sc=%p)\n",
1688 hd->ioc->name, SCpnt); 1690 hd->ioc->name, SCpnt);
1689 scsi_print_command(SCpnt); 1691 scsi_print_command(SCpnt);
@@ -1703,7 +1705,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
1703 vdev = SCpnt->device->hostdata; 1705 vdev = SCpnt->device->hostdata;
1704 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK, 1706 retval = mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
1705 vdev->vtarget->bus_id, vdev->vtarget->target_id, vdev->lun, 1707 vdev->vtarget->bus_id, vdev->vtarget->target_id, vdev->lun,
1706 ctx2abort, mptscsih_get_tm_timeout(ioc)); 1708 ctx2abort, mptscsih_get_tm_timeout(hd->ioc));
1707 1709
1708 printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n", 1710 printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
1709 hd->ioc->name, 1711 hd->ioc->name,
@@ -2521,15 +2523,15 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
2521 2523
2522 /* 7. FC: Rescan for blocked rports which might have returned. 2524 /* 7. FC: Rescan for blocked rports which might have returned.
2523 */ 2525 */
2524 else if (ioc->bus_type == FC) { 2526 if (ioc->bus_type == FC) {
2525 int work_count;
2526 unsigned long flags;
2527
2528 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags); 2527 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
2529 work_count = ++ioc->fc_rescan_work_count; 2528 if (ioc->fc_rescan_work_q) {
2529 if (ioc->fc_rescan_work_count++ == 0) {
2530 queue_work(ioc->fc_rescan_work_q,
2531 &ioc->fc_rescan_work);
2532 }
2533 }
2530 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags); 2534 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
2531 if (work_count == 1)
2532 schedule_work(&ioc->fc_rescan_work);
2533 } 2535 }
2534 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name)); 2536 dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
2535 2537
@@ -2544,7 +2546,6 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2544{ 2546{
2545 MPT_SCSI_HOST *hd; 2547 MPT_SCSI_HOST *hd;
2546 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF; 2548 u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
2547 int work_count;
2548 unsigned long flags; 2549 unsigned long flags;
2549 2550
2550 devtverboseprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n", 2551 devtverboseprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
@@ -2569,10 +2570,13 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
2569 2570
2570 case MPI_EVENT_RESCAN: /* 06 */ 2571 case MPI_EVENT_RESCAN: /* 06 */
2571 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags); 2572 spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
2572 work_count = ++ioc->fc_rescan_work_count; 2573 if (ioc->fc_rescan_work_q) {
2574 if (ioc->fc_rescan_work_count++ == 0) {
2575 queue_work(ioc->fc_rescan_work_q,
2576 &ioc->fc_rescan_work);
2577 }
2578 }
2573 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags); 2579 spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
2574 if (work_count == 1)
2575 schedule_work(&ioc->fc_rescan_work);
2576 break; 2580 break;
2577 2581
2578 /* 2582 /*