diff options
Diffstat (limited to 'drivers/message/fusion/mptsas.c')
-rw-r--r-- | drivers/message/fusion/mptsas.c | 332 |
1 files changed, 272 insertions, 60 deletions
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index da22141152d7..72158237f5e8 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c | |||
@@ -121,6 +121,7 @@ static void mptsas_expander_delete(MPT_ADAPTER *ioc, | |||
121 | static void mptsas_send_expander_event(struct fw_event_work *fw_event); | 121 | static void mptsas_send_expander_event(struct fw_event_work *fw_event); |
122 | static void mptsas_not_responding_devices(MPT_ADAPTER *ioc); | 122 | static void mptsas_not_responding_devices(MPT_ADAPTER *ioc); |
123 | static void mptsas_scan_sas_topology(MPT_ADAPTER *ioc); | 123 | static void mptsas_scan_sas_topology(MPT_ADAPTER *ioc); |
124 | static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id); | ||
124 | 125 | ||
125 | static void mptsas_print_phy_data(MPT_ADAPTER *ioc, | 126 | static void mptsas_print_phy_data(MPT_ADAPTER *ioc, |
126 | MPI_SAS_IO_UNIT0_PHY_DATA *phy_data) | 127 | MPI_SAS_IO_UNIT0_PHY_DATA *phy_data) |
@@ -542,9 +543,10 @@ mptsas_add_device_component(MPT_ADAPTER *ioc, u8 channel, u8 id, | |||
542 | mutex_lock(&ioc->sas_device_info_mutex); | 543 | mutex_lock(&ioc->sas_device_info_mutex); |
543 | list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list, | 544 | list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list, |
544 | list) { | 545 | list) { |
545 | if ((sas_info->sas_address == sas_address || | 546 | if (!sas_info->is_logical_volume && |
546 | (sas_info->fw.channel == channel && | 547 | (sas_info->sas_address == sas_address || |
547 | sas_info->fw.id == id))) { | 548 | (sas_info->fw.channel == channel && |
549 | sas_info->fw.id == id))) { | ||
548 | list_del(&sas_info->list); | 550 | list_del(&sas_info->list); |
549 | kfree(sas_info); | 551 | kfree(sas_info); |
550 | } | 552 | } |
@@ -617,6 +619,100 @@ mptsas_add_device_component_by_fw(MPT_ADAPTER *ioc, u8 channel, u8 id) | |||
617 | } | 619 | } |
618 | 620 | ||
619 | /** | 621 | /** |
622 | * mptsas_add_device_component_starget_ir - Handle Integrated RAID, adding | ||
623 | * each individual device to list | ||
624 | * @ioc: Pointer to MPT_ADAPTER structure | ||
625 | * @channel: fw mapped id's | ||
626 | * @id: | ||
627 | * | ||
628 | **/ | ||
629 | static void | ||
630 | mptsas_add_device_component_starget_ir(MPT_ADAPTER *ioc, | ||
631 | struct scsi_target *starget) | ||
632 | { | ||
633 | CONFIGPARMS cfg; | ||
634 | ConfigPageHeader_t hdr; | ||
635 | dma_addr_t dma_handle; | ||
636 | pRaidVolumePage0_t buffer = NULL; | ||
637 | int i; | ||
638 | RaidPhysDiskPage0_t phys_disk; | ||
639 | struct mptsas_device_info *sas_info, *next; | ||
640 | |||
641 | memset(&cfg, 0 , sizeof(CONFIGPARMS)); | ||
642 | memset(&hdr, 0 , sizeof(ConfigPageHeader_t)); | ||
643 | hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME; | ||
644 | /* assumption that all volumes on channel = 0 */ | ||
645 | cfg.pageAddr = starget->id; | ||
646 | cfg.cfghdr.hdr = &hdr; | ||
647 | cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; | ||
648 | cfg.timeout = 10; | ||
649 | |||
650 | if (mpt_config(ioc, &cfg) != 0) | ||
651 | goto out; | ||
652 | |||
653 | if (!hdr.PageLength) | ||
654 | goto out; | ||
655 | |||
656 | buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, | ||
657 | &dma_handle); | ||
658 | |||
659 | if (!buffer) | ||
660 | goto out; | ||
661 | |||
662 | cfg.physAddr = dma_handle; | ||
663 | cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; | ||
664 | |||
665 | if (mpt_config(ioc, &cfg) != 0) | ||
666 | goto out; | ||
667 | |||
668 | if (!buffer->NumPhysDisks) | ||
669 | goto out; | ||
670 | |||
671 | /* | ||
672 | * Adding entry for hidden components | ||
673 | */ | ||
674 | for (i = 0; i < buffer->NumPhysDisks; i++) { | ||
675 | |||
676 | if (mpt_raid_phys_disk_pg0(ioc, | ||
677 | buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0) | ||
678 | continue; | ||
679 | |||
680 | mptsas_add_device_component_by_fw(ioc, phys_disk.PhysDiskBus, | ||
681 | phys_disk.PhysDiskID); | ||
682 | |||
683 | } | ||
684 | |||
685 | /* | ||
686 | * Delete all matching devices out of the list | ||
687 | */ | ||
688 | mutex_lock(&ioc->sas_device_info_mutex); | ||
689 | list_for_each_entry_safe(sas_info, next, &ioc->sas_device_info_list, | ||
690 | list) { | ||
691 | if (sas_info->is_logical_volume && sas_info->fw.id == | ||
692 | starget->id) { | ||
693 | list_del(&sas_info->list); | ||
694 | kfree(sas_info); | ||
695 | } | ||
696 | } | ||
697 | |||
698 | sas_info = kzalloc(sizeof(struct mptsas_device_info), GFP_KERNEL); | ||
699 | if (sas_info) { | ||
700 | sas_info->fw.id = starget->id; | ||
701 | sas_info->os.id = starget->id; | ||
702 | sas_info->os.channel = starget->channel; | ||
703 | sas_info->is_logical_volume = 1; | ||
704 | INIT_LIST_HEAD(&sas_info->list); | ||
705 | list_add_tail(&sas_info->list, &ioc->sas_device_info_list); | ||
706 | } | ||
707 | mutex_unlock(&ioc->sas_device_info_mutex); | ||
708 | |||
709 | out: | ||
710 | if (buffer) | ||
711 | pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer, | ||
712 | dma_handle); | ||
713 | } | ||
714 | |||
715 | /** | ||
620 | * mptsas_add_device_component_starget - | 716 | * mptsas_add_device_component_starget - |
621 | * @ioc: Pointer to MPT_ADAPTER structure | 717 | * @ioc: Pointer to MPT_ADAPTER structure |
622 | * @starget: | 718 | * @starget: |
@@ -817,6 +913,10 @@ mptsas_find_vtarget(MPT_ADAPTER *ioc, u8 channel, u8 id) | |||
817 | if ((vdevice == NULL) || | 913 | if ((vdevice == NULL) || |
818 | (vdevice->vtarget == NULL)) | 914 | (vdevice->vtarget == NULL)) |
819 | continue; | 915 | continue; |
916 | if ((vdevice->vtarget->tflags & | ||
917 | MPT_TARGET_FLAGS_RAID_COMPONENT || | ||
918 | vdevice->vtarget->raidVolume)) | ||
919 | continue; | ||
820 | if (vdevice->vtarget->id == id && | 920 | if (vdevice->vtarget->id == id && |
821 | vdevice->vtarget->channel == channel) | 921 | vdevice->vtarget->channel == channel) |
822 | vtarget = vdevice->vtarget; | 922 | vtarget = vdevice->vtarget; |
@@ -1487,9 +1587,21 @@ mptsas_slave_configure(struct scsi_device *sdev) | |||
1487 | struct Scsi_Host *host = sdev->host; | 1587 | struct Scsi_Host *host = sdev->host; |
1488 | MPT_SCSI_HOST *hd = shost_priv(host); | 1588 | MPT_SCSI_HOST *hd = shost_priv(host); |
1489 | MPT_ADAPTER *ioc = hd->ioc; | 1589 | MPT_ADAPTER *ioc = hd->ioc; |
1590 | VirtDevice *vdevice = sdev->hostdata; | ||
1490 | 1591 | ||
1491 | if (sdev->channel == MPTSAS_RAID_CHANNEL) | 1592 | if (vdevice->vtarget->deleted) { |
1593 | sdev_printk(KERN_INFO, sdev, "clearing deleted flag\n"); | ||
1594 | vdevice->vtarget->deleted = 0; | ||
1595 | } | ||
1596 | |||
1597 | /* | ||
1598 | * RAID volumes placed beyond the last expected port. | ||
1599 | * Ignore sending sas mode pages in that case.. | ||
1600 | */ | ||
1601 | if (sdev->channel == MPTSAS_RAID_CHANNEL) { | ||
1602 | mptsas_add_device_component_starget_ir(ioc, scsi_target(sdev)); | ||
1492 | goto out; | 1603 | goto out; |
1604 | } | ||
1493 | 1605 | ||
1494 | sas_read_port_mode_page(sdev); | 1606 | sas_read_port_mode_page(sdev); |
1495 | 1607 | ||
@@ -1525,9 +1637,18 @@ mptsas_target_alloc(struct scsi_target *starget) | |||
1525 | * RAID volumes placed beyond the last expected port. | 1637 | * RAID volumes placed beyond the last expected port. |
1526 | */ | 1638 | */ |
1527 | if (starget->channel == MPTSAS_RAID_CHANNEL) { | 1639 | if (starget->channel == MPTSAS_RAID_CHANNEL) { |
1528 | for (i=0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) | 1640 | if (!ioc->raid_data.pIocPg2) { |
1529 | if (id == ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID) | 1641 | kfree(vtarget); |
1530 | channel = ioc->raid_data.pIocPg2->RaidVolume[i].VolumeBus; | 1642 | return -ENXIO; |
1643 | } | ||
1644 | for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) { | ||
1645 | if (id == ioc->raid_data.pIocPg2-> | ||
1646 | RaidVolume[i].VolumeID) { | ||
1647 | channel = ioc->raid_data.pIocPg2-> | ||
1648 | RaidVolume[i].VolumeBus; | ||
1649 | } | ||
1650 | } | ||
1651 | vtarget->raidVolume = 1; | ||
1531 | goto out; | 1652 | goto out; |
1532 | } | 1653 | } |
1533 | 1654 | ||
@@ -3277,59 +3398,66 @@ mptsas_not_responding_devices(MPT_ADAPTER *ioc) | |||
3277 | mutex_lock(&ioc->sas_device_info_mutex); | 3398 | mutex_lock(&ioc->sas_device_info_mutex); |
3278 | redo_device_scan: | 3399 | redo_device_scan: |
3279 | list_for_each_entry(sas_info, &ioc->sas_device_info_list, list) { | 3400 | list_for_each_entry(sas_info, &ioc->sas_device_info_list, list) { |
3280 | sas_device.handle = 0; | 3401 | if (!sas_info->is_logical_volume) { |
3281 | retry_count = 0; | 3402 | sas_device.handle = 0; |
3403 | retry_count = 0; | ||
3282 | retry_page: | 3404 | retry_page: |
3283 | retval = mptsas_sas_device_pg0(ioc, &sas_device, | 3405 | retval = mptsas_sas_device_pg0(ioc, &sas_device, |
3284 | (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID | 3406 | (MPI_SAS_DEVICE_PGAD_FORM_BUS_TARGET_ID |
3285 | << MPI_SAS_DEVICE_PGAD_FORM_SHIFT), | 3407 | << MPI_SAS_DEVICE_PGAD_FORM_SHIFT), |
3286 | (sas_info->fw.channel << 8) + | 3408 | (sas_info->fw.channel << 8) + |
3287 | sas_info->fw.id); | 3409 | sas_info->fw.id); |
3288 | 3410 | ||
3289 | if (sas_device.handle) | 3411 | if (sas_device.handle) |
3290 | continue; | 3412 | continue; |
3291 | if (retval == -EBUSY) { | 3413 | if (retval == -EBUSY) { |
3292 | spin_lock_irqsave(&ioc->taskmgmt_lock, flags); | 3414 | spin_lock_irqsave(&ioc->taskmgmt_lock, flags); |
3293 | if (ioc->ioc_reset_in_progress) { | 3415 | if (ioc->ioc_reset_in_progress) { |
3294 | dfailprintk(ioc, | 3416 | dfailprintk(ioc, |
3295 | printk(MYIOC_s_DEBUG_FMT | 3417 | printk(MYIOC_s_DEBUG_FMT |
3296 | "%s: exiting due to reset\n", | 3418 | "%s: exiting due to reset\n", |
3297 | ioc->name, __func__)); | 3419 | ioc->name, __func__)); |
3298 | spin_unlock_irqrestore | 3420 | spin_unlock_irqrestore |
3299 | (&ioc->taskmgmt_lock, flags); | 3421 | (&ioc->taskmgmt_lock, flags); |
3300 | mutex_unlock(&ioc->sas_device_info_mutex); | 3422 | mutex_unlock(&ioc-> |
3301 | return; | 3423 | sas_device_info_mutex); |
3424 | return; | ||
3425 | } | ||
3426 | spin_unlock_irqrestore(&ioc->taskmgmt_lock, | ||
3427 | flags); | ||
3302 | } | 3428 | } |
3303 | spin_unlock_irqrestore(&ioc->taskmgmt_lock, | ||
3304 | flags); | ||
3305 | } | ||
3306 | 3429 | ||
3307 | if (retval && (retval != -ENODEV)) { | 3430 | if (retval && (retval != -ENODEV)) { |
3308 | if (retry_count < 10) { | 3431 | if (retry_count < 10) { |
3309 | retry_count++; | 3432 | retry_count++; |
3310 | goto retry_page; | 3433 | goto retry_page; |
3311 | } else { | 3434 | } else { |
3312 | devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT | 3435 | devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT |
3313 | "%s: Config page retry exceeded retry " | 3436 | "%s: Config page retry exceeded retry " |
3314 | "count deleting device 0x%llx\n", | 3437 | "count deleting device 0x%llx\n", |
3315 | ioc->name, __func__, | 3438 | ioc->name, __func__, |
3316 | sas_info->sas_address)); | 3439 | sas_info->sas_address)); |
3440 | } | ||
3317 | } | 3441 | } |
3318 | } | ||
3319 | 3442 | ||
3320 | /* delete device */ | 3443 | /* delete device */ |
3321 | vtarget = mptsas_find_vtarget(ioc, | 3444 | vtarget = mptsas_find_vtarget(ioc, |
3322 | sas_info->fw.channel, sas_info->fw.id); | 3445 | sas_info->fw.channel, sas_info->fw.id); |
3323 | if (vtarget) | 3446 | |
3324 | vtarget->deleted = 1; | 3447 | if (vtarget) |
3325 | phy_info = mptsas_find_phyinfo_by_sas_address(ioc, | 3448 | vtarget->deleted = 1; |
3326 | sas_info->sas_address); | 3449 | |
3327 | if (phy_info) { | 3450 | phy_info = mptsas_find_phyinfo_by_sas_address(ioc, |
3328 | mptsas_del_end_device(ioc, phy_info); | 3451 | sas_info->sas_address); |
3329 | goto redo_device_scan; | 3452 | |
3330 | } | 3453 | if (phy_info) { |
3454 | mptsas_del_end_device(ioc, phy_info); | ||
3455 | goto redo_device_scan; | ||
3456 | } | ||
3457 | } else | ||
3458 | mptsas_volume_delete(ioc, sas_info->fw.id); | ||
3331 | } | 3459 | } |
3332 | mutex_unlock(&ioc->sas_device_info_mutex); | 3460 | mutex_lock(&ioc->sas_device_info_mutex); |
3333 | 3461 | ||
3334 | /* expanders */ | 3462 | /* expanders */ |
3335 | mutex_lock(&ioc->sas_topology_mutex); | 3463 | mutex_lock(&ioc->sas_topology_mutex); |
@@ -3508,28 +3636,74 @@ mptsas_find_phyinfo_by_sas_address(MPT_ADAPTER *ioc, u64 sas_address) | |||
3508 | return phy_info; | 3636 | return phy_info; |
3509 | } | 3637 | } |
3510 | 3638 | ||
3511 | 3639 | /** | |
3640 | * mptsas_find_phyinfo_by_phys_disk_num - | ||
3641 | * @ioc: Pointer to MPT_ADAPTER structure | ||
3642 | * @phys_disk_num: | ||
3643 | * @channel: | ||
3644 | * @id: | ||
3645 | * | ||
3646 | **/ | ||
3512 | static struct mptsas_phyinfo * | 3647 | static struct mptsas_phyinfo * |
3513 | mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 channel, u8 id) | 3648 | mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 phys_disk_num, |
3649 | u8 channel, u8 id) | ||
3514 | { | 3650 | { |
3515 | struct mptsas_portinfo *port_info; | ||
3516 | struct mptsas_phyinfo *phy_info = NULL; | 3651 | struct mptsas_phyinfo *phy_info = NULL; |
3652 | struct mptsas_portinfo *port_info; | ||
3653 | RaidPhysDiskPage1_t *phys_disk = NULL; | ||
3654 | int num_paths; | ||
3655 | u64 sas_address = 0; | ||
3517 | int i; | 3656 | int i; |
3518 | 3657 | ||
3658 | phy_info = NULL; | ||
3659 | if (!ioc->raid_data.pIocPg3) | ||
3660 | return NULL; | ||
3661 | /* dual port support */ | ||
3662 | num_paths = mpt_raid_phys_disk_get_num_paths(ioc, phys_disk_num); | ||
3663 | if (!num_paths) | ||
3664 | goto out; | ||
3665 | phys_disk = kzalloc(offsetof(RaidPhysDiskPage1_t, Path) + | ||
3666 | (num_paths * sizeof(RAID_PHYS_DISK1_PATH)), GFP_KERNEL); | ||
3667 | if (!phys_disk) | ||
3668 | goto out; | ||
3669 | mpt_raid_phys_disk_pg1(ioc, phys_disk_num, phys_disk); | ||
3670 | for (i = 0; i < num_paths; i++) { | ||
3671 | if ((phys_disk->Path[i].Flags & 1) != 0) | ||
3672 | /* entry no longer valid */ | ||
3673 | continue; | ||
3674 | if ((id == phys_disk->Path[i].PhysDiskID) && | ||
3675 | (channel == phys_disk->Path[i].PhysDiskBus)) { | ||
3676 | memcpy(&sas_address, &phys_disk->Path[i].WWID, | ||
3677 | sizeof(u64)); | ||
3678 | phy_info = mptsas_find_phyinfo_by_sas_address(ioc, | ||
3679 | sas_address); | ||
3680 | goto out; | ||
3681 | } | ||
3682 | } | ||
3683 | |||
3684 | out: | ||
3685 | kfree(phys_disk); | ||
3686 | if (phy_info) | ||
3687 | return phy_info; | ||
3688 | |||
3689 | /* | ||
3690 | * Extra code to handle RAID0 case, where the sas_address is not updated | ||
3691 | * in phys_disk_page_1 when hotswapped | ||
3692 | */ | ||
3519 | mutex_lock(&ioc->sas_topology_mutex); | 3693 | mutex_lock(&ioc->sas_topology_mutex); |
3520 | list_for_each_entry(port_info, &ioc->sas_topology, list) { | 3694 | list_for_each_entry(port_info, &ioc->sas_topology, list) { |
3521 | for (i = 0; i < port_info->num_phys; i++) { | 3695 | for (i = 0; i < port_info->num_phys && !phy_info; i++) { |
3522 | if (!mptsas_is_end_device( | 3696 | if (!mptsas_is_end_device( |
3523 | &port_info->phy_info[i].attached)) | 3697 | &port_info->phy_info[i].attached)) |
3524 | continue; | 3698 | continue; |
3525 | if (port_info->phy_info[i].attached.phys_disk_num == ~0) | 3699 | if (port_info->phy_info[i].attached.phys_disk_num == ~0) |
3526 | continue; | 3700 | continue; |
3527 | if (port_info->phy_info[i].attached.phys_disk_num != id) | 3701 | if ((port_info->phy_info[i].attached.phys_disk_num == |
3528 | continue; | 3702 | phys_disk_num) && |
3529 | if (port_info->phy_info[i].attached.channel != channel) | 3703 | (port_info->phy_info[i].attached.id == id) && |
3530 | continue; | 3704 | (port_info->phy_info[i].attached.channel == |
3531 | phy_info = &port_info->phy_info[i]; | 3705 | channel)) |
3532 | break; | 3706 | phy_info = &port_info->phy_info[i]; |
3533 | } | 3707 | } |
3534 | } | 3708 | } |
3535 | mutex_unlock(&ioc->sas_topology_mutex); | 3709 | mutex_unlock(&ioc->sas_topology_mutex); |
@@ -3683,8 +3857,9 @@ mptsas_hotplug_work(MPT_ADAPTER *ioc, struct fw_event_work *fw_event, | |||
3683 | mpt_findImVolumes(ioc); | 3857 | mpt_findImVolumes(ioc); |
3684 | 3858 | ||
3685 | phy_info = mptsas_find_phyinfo_by_phys_disk_num( | 3859 | phy_info = mptsas_find_phyinfo_by_phys_disk_num( |
3686 | ioc, hot_plug_info->channel, | 3860 | ioc, hot_plug_info->phys_disk_num, |
3687 | hot_plug_info->phys_disk_num); | 3861 | hot_plug_info->channel, |
3862 | hot_plug_info->id); | ||
3688 | mptsas_del_end_device(ioc, phy_info); | 3863 | mptsas_del_end_device(ioc, phy_info); |
3689 | break; | 3864 | break; |
3690 | 3865 | ||
@@ -4032,6 +4207,7 @@ mptsas_send_ir2_event(struct fw_event_work *fw_event) | |||
4032 | struct mptsas_hotplug_event hot_plug_info; | 4207 | struct mptsas_hotplug_event hot_plug_info; |
4033 | MPI_EVENT_DATA_IR2 *ir2_data; | 4208 | MPI_EVENT_DATA_IR2 *ir2_data; |
4034 | u8 reasonCode; | 4209 | u8 reasonCode; |
4210 | RaidPhysDiskPage0_t phys_disk; | ||
4035 | 4211 | ||
4036 | ioc = fw_event->ioc; | 4212 | ioc = fw_event->ioc; |
4037 | ir2_data = (MPI_EVENT_DATA_IR2 *)fw_event->event_data; | 4213 | ir2_data = (MPI_EVENT_DATA_IR2 *)fw_event->event_data; |
@@ -4047,6 +4223,17 @@ mptsas_send_ir2_event(struct fw_event_work *fw_event) | |||
4047 | case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED: | 4223 | case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED: |
4048 | hot_plug_info.event_type = MPTSAS_ADD_INACTIVE_VOLUME; | 4224 | hot_plug_info.event_type = MPTSAS_ADD_INACTIVE_VOLUME; |
4049 | break; | 4225 | break; |
4226 | case MPI_EVENT_IR2_RC_DUAL_PORT_REMOVED: | ||
4227 | hot_plug_info.phys_disk_num = ir2_data->PhysDiskNum; | ||
4228 | hot_plug_info.event_type = MPTSAS_DEL_PHYSDISK; | ||
4229 | break; | ||
4230 | case MPI_EVENT_IR2_RC_DUAL_PORT_ADDED: | ||
4231 | hot_plug_info.phys_disk_num = ir2_data->PhysDiskNum; | ||
4232 | mpt_raid_phys_disk_pg0(ioc, | ||
4233 | ir2_data->PhysDiskNum, &phys_disk); | ||
4234 | hot_plug_info.id = phys_disk.PhysDiskID; | ||
4235 | hot_plug_info.event_type = MPTSAS_ADD_PHYSDISK; | ||
4236 | break; | ||
4050 | default: | 4237 | default: |
4051 | mptsas_free_fw_event(ioc, fw_event); | 4238 | mptsas_free_fw_event(ioc, fw_event); |
4052 | return; | 4239 | return; |
@@ -4132,6 +4319,31 @@ mptsas_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *reply) | |||
4132 | return 0; | 4319 | return 0; |
4133 | } | 4320 | } |
4134 | 4321 | ||
4322 | /* Delete a volume when no longer listed in ioc pg2 | ||
4323 | */ | ||
4324 | static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id) | ||
4325 | { | ||
4326 | struct scsi_device *sdev; | ||
4327 | int i; | ||
4328 | |||
4329 | sdev = scsi_device_lookup(ioc->sh, MPTSAS_RAID_CHANNEL, id, 0); | ||
4330 | if (!sdev) | ||
4331 | return; | ||
4332 | if (!ioc->raid_data.pIocPg2) | ||
4333 | goto out; | ||
4334 | if (!ioc->raid_data.pIocPg2->NumActiveVolumes) | ||
4335 | goto out; | ||
4336 | for (i = 0; i < ioc->raid_data.pIocPg2->NumActiveVolumes; i++) | ||
4337 | if (ioc->raid_data.pIocPg2->RaidVolume[i].VolumeID == id) | ||
4338 | goto release_sdev; | ||
4339 | out: | ||
4340 | printk(MYIOC_s_INFO_FMT "removing raid volume, channel %d, " | ||
4341 | "id %d\n", ioc->name, MPTSAS_RAID_CHANNEL, id); | ||
4342 | scsi_remove_device(sdev); | ||
4343 | release_sdev: | ||
4344 | scsi_device_put(sdev); | ||
4345 | } | ||
4346 | |||
4135 | static int | 4347 | static int |
4136 | mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) | 4348 | mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) |
4137 | { | 4349 | { |