diff options
Diffstat (limited to 'drivers/scsi/libsas/sas_ata.c')
| -rw-r--r-- | drivers/scsi/libsas/sas_ata.c | 47 | 
1 files changed, 27 insertions, 20 deletions
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index ff1d612f6fb9..64a958a99f6a 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c @@ -176,7 +176,6 @@ qc_already_gone:  static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc)  { -	unsigned long flags;  	struct sas_task *task;  	struct scatterlist *sg;  	int ret = AC_ERR_SYSTEM; @@ -187,10 +186,7 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc)  	struct Scsi_Host *host = sas_ha->core.shost;  	struct sas_internal *i = to_sas_internal(host->transportt); -	/* TODO: audit callers to ensure they are ready for qc_issue to -	 * unconditionally re-enable interrupts -	 */ -	local_irq_save(flags); +	/* TODO: we should try to remove that unlock */  	spin_unlock(ap->lock);  	/* If the device fell off, no sense in issuing commands */ @@ -252,7 +248,6 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc)   out:  	spin_lock(ap->lock); -	local_irq_restore(flags);  	return ret;  } @@ -557,34 +552,46 @@ int sas_ata_init(struct domain_device *found_dev)  {  	struct sas_ha_struct *ha = found_dev->port->ha;  	struct Scsi_Host *shost = ha->core.shost; +	struct ata_host *ata_host;  	struct ata_port *ap;  	int rc; -	ata_host_init(&found_dev->sata_dev.ata_host, ha->dev, &sas_sata_ops); -	ap = ata_sas_port_alloc(&found_dev->sata_dev.ata_host, -				&sata_port_info, -				shost); +	ata_host = kzalloc(sizeof(*ata_host), GFP_KERNEL); +	if (!ata_host)	{ +		SAS_DPRINTK("ata host alloc failed.\n"); +		return -ENOMEM; +	} + +	ata_host_init(ata_host, ha->dev, &sas_sata_ops); + +	ap = ata_sas_port_alloc(ata_host, &sata_port_info, shost);  	if (!ap) {  		SAS_DPRINTK("ata_sas_port_alloc failed.\n"); -		return -ENODEV; +		rc = -ENODEV; +		goto free_host;  	}  	ap->private_data = found_dev;  	ap->cbl = ATA_CBL_SATA;  	ap->scsi_host = shost;  	rc = ata_sas_port_init(ap); -	if (rc) { -		ata_sas_port_destroy(ap); -		return rc; -	} -	rc = ata_sas_tport_add(found_dev->sata_dev.ata_host.dev, ap); -	if (rc) { -		ata_sas_port_destroy(ap); -		return rc; -	} +	if (rc) +		goto destroy_port; + +	rc = ata_sas_tport_add(ata_host->dev, ap); +	if (rc) +		goto destroy_port; + +	found_dev->sata_dev.ata_host = ata_host;  	found_dev->sata_dev.ap = ap;  	return 0; + +destroy_port: +	ata_sas_port_destroy(ap); +free_host: +	ata_host_put(ata_host); +	return rc;  }  void sas_ata_task_abort(struct sas_task *task)  |