diff options
-rw-r--r-- | drivers/message/fusion/mptbase.c | 1 | ||||
-rw-r--r-- | drivers/message/fusion/mptbase.h | 10 | ||||
-rw-r--r-- | drivers/message/fusion/mptfc.c | 125 | ||||
-rw-r--r-- | drivers/message/fusion/mptscsih.c | 48 |
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 | ||
580 | static void | 596 | static 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) | |||
949 | static void __devexit | 968 | static void __devexit |
950 | mptfc_remove(struct pci_dev *pdev) | 969 | mptfc_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 | |||
1645 | mptscsih_abort(struct scsi_cmnd * SCpnt) | 1649 | mptscsih_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 | /* |