aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/message/fusion/mptsas.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/message/fusion/mptsas.c')
-rw-r--r--drivers/message/fusion/mptsas.c332
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,
121static void mptsas_send_expander_event(struct fw_event_work *fw_event); 121static void mptsas_send_expander_event(struct fw_event_work *fw_event);
122static void mptsas_not_responding_devices(MPT_ADAPTER *ioc); 122static void mptsas_not_responding_devices(MPT_ADAPTER *ioc);
123static void mptsas_scan_sas_topology(MPT_ADAPTER *ioc); 123static void mptsas_scan_sas_topology(MPT_ADAPTER *ioc);
124static void mptsas_volume_delete(MPT_ADAPTER *ioc, u8 id);
124 125
125static void mptsas_print_phy_data(MPT_ADAPTER *ioc, 126static 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 **/
629static void
630mptsas_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;
3282retry_page: 3404retry_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 **/
3512static struct mptsas_phyinfo * 3647static struct mptsas_phyinfo *
3513mptsas_find_phyinfo_by_phys_disk_num(MPT_ADAPTER *ioc, u8 channel, u8 id) 3648mptsas_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 */
4324static 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
4135static int 4347static int
4136mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id) 4348mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
4137{ 4349{