diff options
Diffstat (limited to 'drivers/scsi/aic94xx/aic94xx_dev.c')
| -rw-r--r-- | drivers/scsi/aic94xx/aic94xx_dev.c | 60 | 
1 files changed, 35 insertions, 25 deletions
diff --git a/drivers/scsi/aic94xx/aic94xx_dev.c b/drivers/scsi/aic94xx/aic94xx_dev.c index 2e2ddec9c0b..33072388ea1 100644 --- a/drivers/scsi/aic94xx/aic94xx_dev.c +++ b/drivers/scsi/aic94xx/aic94xx_dev.c @@ -84,7 +84,7 @@ static void asd_set_ddb_type(struct domain_device *dev)  	struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha;  	int ddb = (int) (unsigned long) dev->lldd_dev; -	if (dev->dev_type == SATA_PM_PORT) +	if (dev->dev_type == SAS_SATA_PM_PORT)  		asd_ddbsite_write_byte(asd_ha,ddb, DDB_TYPE, DDB_TYPE_PM_PORT);  	else if (dev->tproto)  		asd_ddbsite_write_byte(asd_ha,ddb, DDB_TYPE, DDB_TYPE_TARGET); @@ -109,36 +109,46 @@ static int asd_init_sata_tag_ddb(struct domain_device *dev)  	return 0;  } -static int asd_init_sata(struct domain_device *dev) +void asd_set_dmamode(struct domain_device *dev)  {  	struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha; +	struct ata_device *ata_dev = sas_to_ata_dev(dev);  	int ddb = (int) (unsigned long) dev->lldd_dev;  	u32 qdepth = 0; -	int res = 0; -	asd_ddbsite_write_word(asd_ha, ddb, ATA_CMD_SCBPTR, 0xFFFF); -	if ((dev->dev_type == SATA_DEV || dev->dev_type == SATA_PM_PORT) && -	    dev->sata_dev.identify_device && -	    dev->sata_dev.identify_device[10] != 0) { -		u16 w75 = le16_to_cpu(dev->sata_dev.identify_device[75]); -		u16 w76 = le16_to_cpu(dev->sata_dev.identify_device[76]); - -		if (w76 & 0x100) /* NCQ? */ -			qdepth = (w75 & 0x1F) + 1; +	if (dev->dev_type == SAS_SATA_DEV || dev->dev_type == SAS_SATA_PM_PORT) { +		if (ata_id_has_ncq(ata_dev->id)) +			qdepth = ata_id_queue_depth(ata_dev->id);  		asd_ddbsite_write_dword(asd_ha, ddb, SATA_TAG_ALLOC_MASK,  					(1ULL<<qdepth)-1);  		asd_ddbsite_write_byte(asd_ha, ddb, NUM_SATA_TAGS, qdepth);  	} -	if (dev->dev_type == SATA_DEV || dev->dev_type == SATA_PM || -	    dev->dev_type == SATA_PM_PORT) { + +	if (qdepth > 0) +		if (asd_init_sata_tag_ddb(dev) != 0) { +			unsigned long flags; + +			spin_lock_irqsave(dev->sata_dev.ap->lock, flags); +			ata_dev->flags |= ATA_DFLAG_NCQ_OFF; +			spin_unlock_irqrestore(dev->sata_dev.ap->lock, flags); +		} +} + +static int asd_init_sata(struct domain_device *dev) +{ +	struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha; +	int ddb = (int) (unsigned long) dev->lldd_dev; + +	asd_ddbsite_write_word(asd_ha, ddb, ATA_CMD_SCBPTR, 0xFFFF); +	if (dev->dev_type == SAS_SATA_DEV || dev->dev_type == SAS_SATA_PM || +	    dev->dev_type == SAS_SATA_PM_PORT) {  		struct dev_to_host_fis *fis = (struct dev_to_host_fis *)  			dev->frame_rcvd;  		asd_ddbsite_write_byte(asd_ha, ddb, SATA_STATUS, fis->status);  	}  	asd_ddbsite_write_word(asd_ha, ddb, NCQ_DATA_SCB_PTR, 0xFFFF); -	if (qdepth > 0) -		res = asd_init_sata_tag_ddb(dev); -	return res; + +	return 0;  }  static int asd_init_target_ddb(struct domain_device *dev) @@ -164,7 +174,7 @@ static int asd_init_target_ddb(struct domain_device *dev)  	asd_ddbsite_write_byte(asd_ha, ddb, CONN_MASK, dev->port->phy_mask);  	if (dev->port->oob_mode != SATA_OOB_MODE) {  		flags |= OPEN_REQUIRED; -		if ((dev->dev_type == SATA_DEV) || +		if ((dev->dev_type == SAS_SATA_DEV) ||  		    (dev->tproto & SAS_PROTOCOL_STP)) {  			struct smp_resp *rps_resp = &dev->sata_dev.rps_resp;  			if (rps_resp->frame_type == SMP_RESPONSE && @@ -178,8 +188,8 @@ static int asd_init_target_ddb(struct domain_device *dev)  		} else {  			flags |= CONCURRENT_CONN_SUPP;  			if (!dev->parent && -			    (dev->dev_type == EDGE_DEV || -			     dev->dev_type == FANOUT_DEV)) +			    (dev->dev_type == SAS_EDGE_EXPANDER_DEVICE || +			     dev->dev_type == SAS_FANOUT_EXPANDER_DEVICE))  				asd_ddbsite_write_byte(asd_ha, ddb, MAX_CCONN,  						       4);  			else @@ -188,7 +198,7 @@ static int asd_init_target_ddb(struct domain_device *dev)  			asd_ddbsite_write_byte(asd_ha, ddb, NUM_CTX, 1);  		}  	} -	if (dev->dev_type == SATA_PM) +	if (dev->dev_type == SAS_SATA_PM)  		flags |= SATA_MULTIPORT;  	asd_ddbsite_write_byte(asd_ha, ddb, DDB_TARG_FLAGS, flags); @@ -201,7 +211,7 @@ static int asd_init_target_ddb(struct domain_device *dev)  	asd_ddbsite_write_word(asd_ha, ddb, SEND_QUEUE_TAIL, 0xFFFF);  	asd_ddbsite_write_word(asd_ha, ddb, SISTER_DDB, 0xFFFF); -	if (dev->dev_type == SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) { +	if (dev->dev_type == SAS_SATA_DEV || (dev->tproto & SAS_PROTOCOL_STP)) {  		i = asd_init_sata(dev);  		if (i < 0) {  			asd_free_ddb(asd_ha, ddb); @@ -209,7 +219,7 @@ static int asd_init_target_ddb(struct domain_device *dev)  		}  	} -	if (dev->dev_type == SAS_END_DEV) { +	if (dev->dev_type == SAS_END_DEVICE) {  		struct sas_end_device *rdev = rphy_to_end_device(dev->rphy);  		if (rdev->I_T_nexus_loss_timeout > 0)  			asd_ddbsite_write_word(asd_ha, ddb, ITNL_TIMEOUT, @@ -318,10 +328,10 @@ int asd_dev_found(struct domain_device *dev)  	spin_lock_irqsave(&asd_ha->hw_prof.ddb_lock, flags);  	switch (dev->dev_type) { -	case SATA_PM: +	case SAS_SATA_PM:  		res = asd_init_sata_pm_ddb(dev);  		break; -	case SATA_PM_PORT: +	case SAS_SATA_PM_PORT:  		res = asd_init_sata_pm_port_ddb(dev);  		break;  	default:  | 
