diff options
Diffstat (limited to 'drivers/ata/libata-scsi.c')
-rw-r--r-- | drivers/ata/libata-scsi.c | 28 |
1 files changed, 27 insertions, 1 deletions
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 94339c2aed1b..59c9d721b347 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
@@ -3666,7 +3666,8 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht) | |||
3666 | */ | 3666 | */ |
3667 | shost->max_host_blocked = 1; | 3667 | shost->max_host_blocked = 1; |
3668 | 3668 | ||
3669 | scsi_init_shared_tag_map(shost, host->n_tags); | 3669 | if (scsi_init_shared_tag_map(shost, host->n_tags)) |
3670 | goto err_add; | ||
3670 | 3671 | ||
3671 | rc = scsi_add_host_with_dma(ap->scsi_host, | 3672 | rc = scsi_add_host_with_dma(ap->scsi_host, |
3672 | &ap->tdev, ap->host->dev); | 3673 | &ap->tdev, ap->host->dev); |
@@ -4230,3 +4231,28 @@ int ata_sas_queuecmd(struct scsi_cmnd *cmd, struct ata_port *ap) | |||
4230 | return rc; | 4231 | return rc; |
4231 | } | 4232 | } |
4232 | EXPORT_SYMBOL_GPL(ata_sas_queuecmd); | 4233 | EXPORT_SYMBOL_GPL(ata_sas_queuecmd); |
4234 | |||
4235 | int ata_sas_allocate_tag(struct ata_port *ap) | ||
4236 | { | ||
4237 | unsigned int max_queue = ap->host->n_tags; | ||
4238 | unsigned int i, tag; | ||
4239 | |||
4240 | for (i = 0, tag = ap->sas_last_tag + 1; i < max_queue; i++, tag++) { | ||
4241 | tag = tag < max_queue ? tag : 0; | ||
4242 | |||
4243 | /* the last tag is reserved for internal command. */ | ||
4244 | if (tag == ATA_TAG_INTERNAL) | ||
4245 | continue; | ||
4246 | |||
4247 | if (!test_and_set_bit(tag, &ap->sas_tag_allocated)) { | ||
4248 | ap->sas_last_tag = tag; | ||
4249 | return tag; | ||
4250 | } | ||
4251 | } | ||
4252 | return -1; | ||
4253 | } | ||
4254 | |||
4255 | void ata_sas_free_tag(unsigned int tag, struct ata_port *ap) | ||
4256 | { | ||
4257 | clear_bit(tag, &ap->sas_tag_allocated); | ||
4258 | } | ||