aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt2sas/mpt2sas_scsih.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_scsih.c')
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c82
1 files changed, 44 insertions, 38 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index 51004768d0f5..7f0af4fcc001 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -2,7 +2,7 @@
2 * Scsi Host Layer for MPT (Message Passing Technology) based controllers 2 * Scsi Host Layer for MPT (Message Passing Technology) based controllers
3 * 3 *
4 * This code is based on drivers/scsi/mpt2sas/mpt2_scsih.c 4 * This code is based on drivers/scsi/mpt2sas/mpt2_scsih.c
5 * Copyright (C) 2007-2012 LSI Corporation 5 * Copyright (C) 2007-2013 LSI Corporation
6 * (mailto:DL-MPTFusionLinux@lsi.com) 6 * (mailto:DL-MPTFusionLinux@lsi.com)
7 * 7 *
8 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or
@@ -628,11 +628,12 @@ _scsih_sas_device_add(struct MPT2SAS_ADAPTER *ioc,
628 * devices while scanning is turned on due to an oops in 628 * devices while scanning is turned on due to an oops in
629 * scsi_sysfs_add_sdev()->add_device()->sysfs_addrm_start() 629 * scsi_sysfs_add_sdev()->add_device()->sysfs_addrm_start()
630 */ 630 */
631 if (!ioc->is_driver_loading) 631 if (!ioc->is_driver_loading) {
632 mpt2sas_transport_port_remove(ioc, 632 mpt2sas_transport_port_remove(ioc,
633 sas_device->sas_address, 633 sas_device->sas_address,
634 sas_device->sas_address_parent); 634 sas_device->sas_address_parent);
635 _scsih_sas_device_remove(ioc, sas_device); 635 _scsih_sas_device_remove(ioc, sas_device);
636 }
636 } 637 }
637} 638}
638 639
@@ -1402,6 +1403,7 @@ _scsih_slave_alloc(struct scsi_device *sdev)
1402 struct MPT2SAS_DEVICE *sas_device_priv_data; 1403 struct MPT2SAS_DEVICE *sas_device_priv_data;
1403 struct scsi_target *starget; 1404 struct scsi_target *starget;
1404 struct _raid_device *raid_device; 1405 struct _raid_device *raid_device;
1406 struct _sas_device *sas_device;
1405 unsigned long flags; 1407 unsigned long flags;
1406 1408
1407 sas_device_priv_data = kzalloc(sizeof(struct scsi_device), GFP_KERNEL); 1409 sas_device_priv_data = kzalloc(sizeof(struct scsi_device), GFP_KERNEL);
@@ -1430,6 +1432,19 @@ _scsih_slave_alloc(struct scsi_device *sdev)
1430 spin_unlock_irqrestore(&ioc->raid_device_lock, flags); 1432 spin_unlock_irqrestore(&ioc->raid_device_lock, flags);
1431 } 1433 }
1432 1434
1435 if (!(sas_target_priv_data->flags & MPT_TARGET_FLAGS_VOLUME)) {
1436 spin_lock_irqsave(&ioc->sas_device_lock, flags);
1437 sas_device = mpt2sas_scsih_sas_device_find_by_sas_address(ioc,
1438 sas_target_priv_data->sas_address);
1439 if (sas_device && (sas_device->starget == NULL)) {
1440 sdev_printk(KERN_INFO, sdev,
1441 "%s : sas_device->starget set to starget @ %d\n",
1442 __func__, __LINE__);
1443 sas_device->starget = starget;
1444 }
1445 spin_unlock_irqrestore(&ioc->sas_device_lock, flags);
1446 }
1447
1433 return 0; 1448 return 0;
1434} 1449}
1435 1450
@@ -6753,7 +6768,7 @@ _scsih_search_responding_sas_devices(struct MPT2SAS_ADAPTER *ioc)
6753 handle))) { 6768 handle))) {
6754 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 6769 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
6755 MPI2_IOCSTATUS_MASK; 6770 MPI2_IOCSTATUS_MASK;
6756 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) 6771 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
6757 break; 6772 break;
6758 handle = le16_to_cpu(sas_device_pg0.DevHandle); 6773 handle = le16_to_cpu(sas_device_pg0.DevHandle);
6759 device_info = le32_to_cpu(sas_device_pg0.DeviceInfo); 6774 device_info = le32_to_cpu(sas_device_pg0.DeviceInfo);
@@ -6862,7 +6877,7 @@ _scsih_search_responding_raid_devices(struct MPT2SAS_ADAPTER *ioc)
6862 &volume_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) { 6877 &volume_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
6863 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 6878 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
6864 MPI2_IOCSTATUS_MASK; 6879 MPI2_IOCSTATUS_MASK;
6865 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) 6880 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
6866 break; 6881 break;
6867 handle = le16_to_cpu(volume_pg1.DevHandle); 6882 handle = le16_to_cpu(volume_pg1.DevHandle);
6868 6883
@@ -6887,7 +6902,7 @@ _scsih_search_responding_raid_devices(struct MPT2SAS_ADAPTER *ioc)
6887 phys_disk_num))) { 6902 phys_disk_num))) {
6888 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 6903 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
6889 MPI2_IOCSTATUS_MASK; 6904 MPI2_IOCSTATUS_MASK;
6890 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) 6905 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
6891 break; 6906 break;
6892 phys_disk_num = pd_pg0.PhysDiskNum; 6907 phys_disk_num = pd_pg0.PhysDiskNum;
6893 handle = le16_to_cpu(pd_pg0.DevHandle); 6908 handle = le16_to_cpu(pd_pg0.DevHandle);
@@ -6967,7 +6982,7 @@ _scsih_search_responding_expanders(struct MPT2SAS_ADAPTER *ioc)
6967 6982
6968 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 6983 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
6969 MPI2_IOCSTATUS_MASK; 6984 MPI2_IOCSTATUS_MASK;
6970 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE) 6985 if (ioc_status != MPI2_IOCSTATUS_SUCCESS)
6971 break; 6986 break;
6972 6987
6973 handle = le16_to_cpu(expander_pg0.DevHandle); 6988 handle = le16_to_cpu(expander_pg0.DevHandle);
@@ -7109,8 +7124,6 @@ _scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc)
7109 MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL, handle))) { 7124 MPI2_SAS_EXPAND_PGAD_FORM_GET_NEXT_HNDL, handle))) {
7110 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 7125 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
7111 MPI2_IOCSTATUS_MASK; 7126 MPI2_IOCSTATUS_MASK;
7112 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
7113 break;
7114 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 7127 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
7115 printk(MPT2SAS_INFO_FMT "\tbreak from expander scan: " 7128 printk(MPT2SAS_INFO_FMT "\tbreak from expander scan: "
7116 "ioc_status(0x%04x), loginfo(0x%08x)\n", 7129 "ioc_status(0x%04x), loginfo(0x%08x)\n",
@@ -7153,8 +7166,6 @@ _scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc)
7153 phys_disk_num))) { 7166 phys_disk_num))) {
7154 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 7167 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
7155 MPI2_IOCSTATUS_MASK; 7168 MPI2_IOCSTATUS_MASK;
7156 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
7157 break;
7158 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 7169 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
7159 printk(MPT2SAS_INFO_FMT "\tbreak from phys disk scan:" 7170 printk(MPT2SAS_INFO_FMT "\tbreak from phys disk scan:"
7160 "ioc_status(0x%04x), loginfo(0x%08x)\n", 7171 "ioc_status(0x%04x), loginfo(0x%08x)\n",
@@ -7219,8 +7230,6 @@ _scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc)
7219 &volume_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) { 7230 &volume_pg1, MPI2_RAID_VOLUME_PGAD_FORM_GET_NEXT_HANDLE, handle))) {
7220 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 7231 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
7221 MPI2_IOCSTATUS_MASK; 7232 MPI2_IOCSTATUS_MASK;
7222 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
7223 break;
7224 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 7233 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
7225 printk(MPT2SAS_INFO_FMT "\tbreak from volume scan: " 7234 printk(MPT2SAS_INFO_FMT "\tbreak from volume scan: "
7226 "ioc_status(0x%04x), loginfo(0x%08x)\n", 7235 "ioc_status(0x%04x), loginfo(0x%08x)\n",
@@ -7278,8 +7287,6 @@ _scsih_scan_for_devices_after_reset(struct MPT2SAS_ADAPTER *ioc)
7278 handle))) { 7287 handle))) {
7279 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & 7288 ioc_status = le16_to_cpu(mpi_reply.IOCStatus) &
7280 MPI2_IOCSTATUS_MASK; 7289 MPI2_IOCSTATUS_MASK;
7281 if (ioc_status == MPI2_IOCSTATUS_CONFIG_INVALID_PAGE)
7282 break;
7283 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { 7290 if (ioc_status != MPI2_IOCSTATUS_SUCCESS) {
7284 printk(MPT2SAS_INFO_FMT "\tbreak from end device scan:" 7291 printk(MPT2SAS_INFO_FMT "\tbreak from end device scan:"
7285 " ioc_status(0x%04x), loginfo(0x%08x)\n", 7292 " ioc_status(0x%04x), loginfo(0x%08x)\n",
@@ -7471,10 +7478,9 @@ _firmware_event_work(struct work_struct *work)
7471 * This function merely adds a new work task into ioc->firmware_event_thread. 7478 * This function merely adds a new work task into ioc->firmware_event_thread.
7472 * The tasks are worked from _firmware_event_work in user context. 7479 * The tasks are worked from _firmware_event_work in user context.
7473 * 7480 *
7474 * Return 1 meaning mf should be freed from _base_interrupt 7481 * Returns void.
7475 * 0 means the mf is freed from this function.
7476 */ 7482 */
7477u8 7483void
7478mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index, 7484mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
7479 u32 reply) 7485 u32 reply)
7480{ 7486{
@@ -7485,14 +7491,14 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
7485 7491
7486 /* events turned off due to host reset or driver unloading */ 7492 /* events turned off due to host reset or driver unloading */
7487 if (ioc->remove_host || ioc->pci_error_recovery) 7493 if (ioc->remove_host || ioc->pci_error_recovery)
7488 return 1; 7494 return;
7489 7495
7490 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply); 7496 mpi_reply = mpt2sas_base_get_reply_virt_addr(ioc, reply);
7491 7497
7492 if (unlikely(!mpi_reply)) { 7498 if (unlikely(!mpi_reply)) {
7493 printk(MPT2SAS_ERR_FMT "mpi_reply not valid at %s:%d/%s()!\n", 7499 printk(MPT2SAS_ERR_FMT "mpi_reply not valid at %s:%d/%s()!\n",
7494 ioc->name, __FILE__, __LINE__, __func__); 7500 ioc->name, __FILE__, __LINE__, __func__);
7495 return 1; 7501 return;
7496 } 7502 }
7497 7503
7498 event = le16_to_cpu(mpi_reply->Event); 7504 event = le16_to_cpu(mpi_reply->Event);
@@ -7507,11 +7513,11 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
7507 7513
7508 if (baen_data->Primitive != 7514 if (baen_data->Primitive !=
7509 MPI2_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT) 7515 MPI2_EVENT_PRIMITIVE_ASYNCHRONOUS_EVENT)
7510 return 1; 7516 return;
7511 7517
7512 if (ioc->broadcast_aen_busy) { 7518 if (ioc->broadcast_aen_busy) {
7513 ioc->broadcast_aen_pending++; 7519 ioc->broadcast_aen_pending++;
7514 return 1; 7520 return;
7515 } else 7521 } else
7516 ioc->broadcast_aen_busy = 1; 7522 ioc->broadcast_aen_busy = 1;
7517 break; 7523 break;
@@ -7587,14 +7593,14 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
7587 break; 7593 break;
7588 7594
7589 default: /* ignore the rest */ 7595 default: /* ignore the rest */
7590 return 1; 7596 return;
7591 } 7597 }
7592 7598
7593 fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC); 7599 fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC);
7594 if (!fw_event) { 7600 if (!fw_event) {
7595 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 7601 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
7596 ioc->name, __FILE__, __LINE__, __func__); 7602 ioc->name, __FILE__, __LINE__, __func__);
7597 return 1; 7603 return;
7598 } 7604 }
7599 sz = le16_to_cpu(mpi_reply->EventDataLength) * 4; 7605 sz = le16_to_cpu(mpi_reply->EventDataLength) * 4;
7600 fw_event->event_data = kzalloc(sz, GFP_ATOMIC); 7606 fw_event->event_data = kzalloc(sz, GFP_ATOMIC);
@@ -7602,7 +7608,7 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
7602 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", 7608 printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",
7603 ioc->name, __FILE__, __LINE__, __func__); 7609 ioc->name, __FILE__, __LINE__, __func__);
7604 kfree(fw_event); 7610 kfree(fw_event);
7605 return 1; 7611 return;
7606 } 7612 }
7607 7613
7608 memcpy(fw_event->event_data, mpi_reply->EventData, 7614 memcpy(fw_event->event_data, mpi_reply->EventData,
@@ -7612,7 +7618,7 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,
7612 fw_event->VP_ID = mpi_reply->VP_ID; 7618 fw_event->VP_ID = mpi_reply->VP_ID;
7613 fw_event->event = event; 7619 fw_event->event = event;
7614 _scsih_fw_event_add(ioc, fw_event); 7620 _scsih_fw_event_add(ioc, fw_event);
7615 return 1; 7621 return;
7616} 7622}
7617 7623
7618/* shost template */ 7624/* shost template */
@@ -7711,10 +7717,6 @@ _scsih_ir_shutdown(struct MPT2SAS_ADAPTER *ioc)
7711 if (!ioc->ir_firmware) 7717 if (!ioc->ir_firmware)
7712 return; 7718 return;
7713 7719
7714 /* are there any volumes ? */
7715 if (list_empty(&ioc->raid_device_list))
7716 return;
7717
7718 mutex_lock(&ioc->scsih_cmds.mutex); 7720 mutex_lock(&ioc->scsih_cmds.mutex);
7719 7721
7720 if (ioc->scsih_cmds.status != MPT2_CMD_NOT_USED) { 7722 if (ioc->scsih_cmds.status != MPT2_CMD_NOT_USED) {
@@ -7929,10 +7931,12 @@ _scsih_probe_boot_devices(struct MPT2SAS_ADAPTER *ioc)
7929 sas_device->sas_address_parent)) { 7931 sas_device->sas_address_parent)) {
7930 _scsih_sas_device_remove(ioc, sas_device); 7932 _scsih_sas_device_remove(ioc, sas_device);
7931 } else if (!sas_device->starget) { 7933 } else if (!sas_device->starget) {
7932 if (!ioc->is_driver_loading) 7934 if (!ioc->is_driver_loading) {
7933 mpt2sas_transport_port_remove(ioc, sas_address, 7935 mpt2sas_transport_port_remove(ioc,
7936 sas_address,
7934 sas_address_parent); 7937 sas_address_parent);
7935 _scsih_sas_device_remove(ioc, sas_device); 7938 _scsih_sas_device_remove(ioc, sas_device);
7939 }
7936 } 7940 }
7937 } 7941 }
7938} 7942}
@@ -7985,14 +7989,14 @@ _scsih_probe_sas(struct MPT2SAS_ADAPTER *ioc)
7985 kfree(sas_device); 7989 kfree(sas_device);
7986 continue; 7990 continue;
7987 } else if (!sas_device->starget) { 7991 } else if (!sas_device->starget) {
7988 if (!ioc->is_driver_loading) 7992 if (!ioc->is_driver_loading) {
7989 mpt2sas_transport_port_remove(ioc, 7993 mpt2sas_transport_port_remove(ioc,
7990 sas_device->sas_address, 7994 sas_device->sas_address,
7991 sas_device->sas_address_parent); 7995 sas_device->sas_address_parent);
7992 list_del(&sas_device->list); 7996 list_del(&sas_device->list);
7993 kfree(sas_device); 7997 kfree(sas_device);
7994 continue; 7998 continue;
7995 7999 }
7996 } 8000 }
7997 spin_lock_irqsave(&ioc->sas_device_lock, flags); 8001 spin_lock_irqsave(&ioc->sas_device_lock, flags);
7998 list_move_tail(&sas_device->list, &ioc->sas_device_list); 8002 list_move_tail(&sas_device->list, &ioc->sas_device_list);
@@ -8175,6 +8179,7 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
8175 INIT_LIST_HEAD(&ioc->sas_hba.sas_port_list); 8179 INIT_LIST_HEAD(&ioc->sas_hba.sas_port_list);
8176 INIT_LIST_HEAD(&ioc->delayed_tr_list); 8180 INIT_LIST_HEAD(&ioc->delayed_tr_list);
8177 INIT_LIST_HEAD(&ioc->delayed_tr_volume_list); 8181 INIT_LIST_HEAD(&ioc->delayed_tr_volume_list);
8182 INIT_LIST_HEAD(&ioc->reply_queue_list);
8178 8183
8179 /* init shost parameters */ 8184 /* init shost parameters */
8180 shost->max_cmd_len = 32; 8185 shost->max_cmd_len = 32;
@@ -8280,6 +8285,7 @@ _scsih_suspend(struct pci_dev *pdev, pm_message_t state)
8280 8285
8281 mpt2sas_base_stop_watchdog(ioc); 8286 mpt2sas_base_stop_watchdog(ioc);
8282 scsi_block_requests(shost); 8287 scsi_block_requests(shost);
8288 _scsih_ir_shutdown(ioc);
8283 device_state = pci_choose_state(pdev, state); 8289 device_state = pci_choose_state(pdev, state);
8284 printk(MPT2SAS_INFO_FMT "pdev=0x%p, slot=%s, entering " 8290 printk(MPT2SAS_INFO_FMT "pdev=0x%p, slot=%s, entering "
8285 "operating state [D%d]\n", ioc->name, pdev, 8291 "operating state [D%d]\n", ioc->name, pdev,