diff options
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_scsih.c')
| -rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_scsih.c | 83 | 
1 files changed, 46 insertions, 37 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c index 5055f925d2cd..dd461015813f 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c +++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c @@ -173,7 +173,7 @@ struct fw_event_work {  	u8			VP_ID;  	u8			ignore;  	u16			event; -	void			*event_data; +	char			event_data[0] __aligned(4);  };  /* raid transport support */ @@ -1292,7 +1292,8 @@ _scsih_target_alloc(struct scsi_target *starget)  	unsigned long flags;  	struct sas_rphy *rphy; -	sas_target_priv_data = kzalloc(sizeof(struct scsi_target), GFP_KERNEL); +	sas_target_priv_data = kzalloc(sizeof(*sas_target_priv_data), +				       GFP_KERNEL);  	if (!sas_target_priv_data)  		return -ENOMEM; @@ -1406,7 +1407,8 @@ _scsih_slave_alloc(struct scsi_device *sdev)  	struct _sas_device *sas_device;  	unsigned long flags; -	sas_device_priv_data = kzalloc(sizeof(struct scsi_device), GFP_KERNEL); +	sas_device_priv_data = kzalloc(sizeof(*sas_device_priv_data), +				       GFP_KERNEL);  	if (!sas_device_priv_data)  		return -ENOMEM; @@ -2832,7 +2834,6 @@ _scsih_fw_event_free(struct MPT2SAS_ADAPTER *ioc, struct fw_event_work  	spin_lock_irqsave(&ioc->fw_event_lock, flags);  	list_del(&fw_event->list); -	kfree(fw_event->event_data);  	kfree(fw_event);  	spin_unlock_irqrestore(&ioc->fw_event_lock, flags);  } @@ -2899,11 +2900,10 @@ _scsih_fw_event_cleanup_queue(struct MPT2SAS_ADAPTER *ioc)  		return;  	list_for_each_entry_safe(fw_event, next, &ioc->fw_event_list, list) { -		if (cancel_delayed_work(&fw_event->delayed_work)) { +		if (cancel_delayed_work_sync(&fw_event->delayed_work)) {  			_scsih_fw_event_free(ioc, fw_event);  			continue;  		} -		fw_event->cancel_pending_work = 1;  	}  } @@ -3518,7 +3518,8 @@ _scsih_check_topo_delete_events(struct MPT2SAS_ADAPTER *ioc,  		if (fw_event->event != MPI2_EVENT_SAS_TOPOLOGY_CHANGE_LIST ||  		    fw_event->ignore)  			continue; -		local_event_data = fw_event->event_data; +		local_event_data = (Mpi2EventDataSasTopologyChangeList_t *) +			fw_event->event_data;  		if (local_event_data->ExpStatus ==  		    MPI2_EVENT_SAS_TOPO_ES_ADDED ||  		    local_event_data->ExpStatus == @@ -5502,7 +5503,9 @@ _scsih_sas_topology_change_event(struct MPT2SAS_ADAPTER *ioc,  	u64 sas_address;  	unsigned long flags;  	u8 link_rate, prev_link_rate; -	Mpi2EventDataSasTopologyChangeList_t *event_data = fw_event->event_data; +	Mpi2EventDataSasTopologyChangeList_t *event_data = +		(Mpi2EventDataSasTopologyChangeList_t *) +		fw_event->event_data;  #ifdef CONFIG_SCSI_MPT2SAS_LOGGING  	if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) @@ -5697,7 +5700,8 @@ _scsih_sas_device_status_change_event(struct MPT2SAS_ADAPTER *ioc,  	u64 sas_address;  	unsigned long flags;  	Mpi2EventDataSasDeviceStatusChange_t *event_data = -	    fw_event->event_data; +		(Mpi2EventDataSasDeviceStatusChange_t *) +		fw_event->event_data;  #ifdef CONFIG_SCSI_MPT2SAS_LOGGING  	if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) @@ -5792,6 +5796,7 @@ _scsih_sas_enclosure_dev_status_change_event(struct MPT2SAS_ADAPTER *ioc,  #ifdef CONFIG_SCSI_MPT2SAS_LOGGING  	if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK)  		_scsih_sas_enclosure_dev_status_change_event_debug(ioc, +		     (Mpi2EventDataSasEnclDevStatusChange_t *)  		     fw_event->event_data);  #endif  } @@ -5816,7 +5821,9 @@ _scsih_sas_broadcast_primitive_event(struct MPT2SAS_ADAPTER *ioc,  	u32 termination_count;  	u32 query_count;  	Mpi2SCSITaskManagementReply_t *mpi_reply; -	Mpi2EventDataSasBroadcastPrimitive_t *event_data = fw_event->event_data; +	Mpi2EventDataSasBroadcastPrimitive_t *event_data = +		(Mpi2EventDataSasBroadcastPrimitive_t *) +		fw_event->event_data;  	u16 ioc_status;  	unsigned long flags;  	int r; @@ -5967,7 +5974,9 @@ static void  _scsih_sas_discovery_event(struct MPT2SAS_ADAPTER *ioc,      struct fw_event_work *fw_event)  { -	Mpi2EventDataSasDiscovery_t *event_data = fw_event->event_data; +	Mpi2EventDataSasDiscovery_t *event_data = +		(Mpi2EventDataSasDiscovery_t *) +		fw_event->event_data;  #ifdef CONFIG_SCSI_MPT2SAS_LOGGING  	if (ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) { @@ -6355,7 +6364,9 @@ _scsih_sas_ir_config_change_event(struct MPT2SAS_ADAPTER *ioc,  	Mpi2EventIrConfigElement_t *element;  	int i;  	u8 foreign_config; -	Mpi2EventDataIrConfigChangeList_t *event_data = fw_event->event_data; +	Mpi2EventDataIrConfigChangeList_t *event_data = +		(Mpi2EventDataIrConfigChangeList_t *) +		fw_event->event_data;  #ifdef CONFIG_SCSI_MPT2SAS_LOGGING  	if ((ioc->logging_level & MPT_DEBUG_EVENT_WORK_TASK) @@ -6423,7 +6434,9 @@ _scsih_sas_ir_volume_event(struct MPT2SAS_ADAPTER *ioc,  	u16 handle;  	u32 state;  	int rc; -	Mpi2EventDataIrVolume_t *event_data = fw_event->event_data; +	Mpi2EventDataIrVolume_t *event_data = +		(Mpi2EventDataIrVolume_t *) +		fw_event->event_data;  	if (ioc->shost_recovery)  		return; @@ -6507,7 +6520,9 @@ _scsih_sas_ir_physical_disk_event(struct MPT2SAS_ADAPTER *ioc,  	Mpi2ConfigReply_t mpi_reply;  	Mpi2SasDevicePage0_t sas_device_pg0;  	u32 ioc_status; -	Mpi2EventDataIrPhysicalDisk_t *event_data = fw_event->event_data; +	Mpi2EventDataIrPhysicalDisk_t *event_data = +		(Mpi2EventDataIrPhysicalDisk_t *) +		fw_event->event_data;  	u64 sas_address;  	if (ioc->shost_recovery) @@ -6630,7 +6645,9 @@ static void  _scsih_sas_ir_operation_status_event(struct MPT2SAS_ADAPTER *ioc,      struct fw_event_work *fw_event)  { -	Mpi2EventDataIrOperationStatus_t *event_data = fw_event->event_data; +	Mpi2EventDataIrOperationStatus_t *event_data = +		(Mpi2EventDataIrOperationStatus_t *) +		fw_event->event_data;  	static struct _raid_device *raid_device;  	unsigned long flags;  	u16 handle; @@ -7401,7 +7418,7 @@ _firmware_event_work(struct work_struct *work)  	struct MPT2SAS_ADAPTER *ioc = fw_event->ioc;  	/* the queue is being flushed so ignore this event */ -	if (ioc->remove_host || fw_event->cancel_pending_work || +	if (ioc->remove_host ||  	    ioc->pci_error_recovery) {  		_scsih_fw_event_free(ioc, fw_event);  		return; @@ -7590,23 +7607,15 @@ mpt2sas_scsih_event_callback(struct MPT2SAS_ADAPTER *ioc, u8 msix_index,  		return;  	} -	fw_event = kzalloc(sizeof(struct fw_event_work), GFP_ATOMIC); -	if (!fw_event) { -		printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", -		    ioc->name, __FILE__, __LINE__, __func__); -		return; -	}  	sz = le16_to_cpu(mpi_reply->EventDataLength) * 4; -	fw_event->event_data = kzalloc(sz, GFP_ATOMIC); -	if (!fw_event->event_data) { +	fw_event = kzalloc(sizeof(*fw_event) + sz, GFP_ATOMIC); +	if (!fw_event) {  		printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n",  		    ioc->name, __FILE__, __LINE__, __func__); -		kfree(fw_event);  		return;  	} -	memcpy(fw_event->event_data, mpi_reply->EventData, -	    sz); +	memcpy(fw_event->event_data, mpi_reply->EventData, sz);  	fw_event->ioc = ioc;  	fw_event->VF_ID = mpi_reply->VF_ID;  	fw_event->VP_ID = mpi_reply->VP_ID; @@ -7857,9 +7866,9 @@ _scsih_remove(struct pci_dev *pdev)  	}  	sas_remove_host(shost); +	scsi_remove_host(shost);  	mpt2sas_base_detach(ioc);  	list_del(&ioc->list); -	scsi_remove_host(shost);  	scsi_host_put(shost);  } @@ -8200,13 +8209,6 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)  		}  	} -	if ((scsi_add_host(shost, &pdev->dev))) { -		printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", -		    ioc->name, __FILE__, __LINE__, __func__); -		list_del(&ioc->list); -		goto out_add_shost_fail; -	} -  	/* register EEDP capabilities with SCSI layer */  	if (prot_mask)  		scsi_host_set_prot(shost, prot_mask); @@ -8248,16 +8250,23 @@ _scsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)  		}  	} else  		ioc->hide_drives = 0; + +	if ((scsi_add_host(shost, &pdev->dev))) { +		printk(MPT2SAS_ERR_FMT "failure at %s:%d/%s()!\n", +		    ioc->name, __FILE__, __LINE__, __func__); +		goto out_add_shost_fail; +	} +  	scsi_scan_host(shost);  	return 0; + out_add_shost_fail: +	mpt2sas_base_detach(ioc);   out_attach_fail:  	destroy_workqueue(ioc->firmware_event_thread);   out_thread_fail:  	list_del(&ioc->list); -	scsi_remove_host(shost); - out_add_shost_fail:  	scsi_host_put(shost);  	return -ENODEV;  }  |