diff options
author | Shaohua Li <shli@fb.com> | 2015-01-23 19:52:07 -0800 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2015-01-24 17:09:47 -0700 |
commit | 98bd4be1ba95f2fe7f543910792b7163a5de06eb (patch) | |
tree | bae9c292324fe749f78b48d05585d5eca8b28c97 /drivers | |
parent | 12cb5ce101abfaf74421f8cc9f196e708209eb79 (diff) |
libata: move sas ata tag allocation to libata-scsi.c
Basically move the sas ata tag allocation to libata-scsi.c to make it clear
these staffs are just for sas.
Signed-off-by: Shaohua Li <shli@fb.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ata/libata-core.c | 93 | ||||
-rw-r--r-- | drivers/ata/libata-scsi.c | 28 | ||||
-rw-r--r-- | drivers/ata/libata.h | 2 |
3 files changed, 46 insertions, 77 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 695d33df3df5..d626605ac8f7 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -1525,15 +1525,6 @@ static void ata_qc_complete_internal(struct ata_queued_cmd *qc) complete(waiting); } -static bool ata_valid_internal_tag(struct ata_port *ap, struct ata_device *dev, - unsigned int tag) -{ - if (!ap->scsi_host) - return !test_and_set_bit(tag, &ap->sas_tag_allocated); - return !dev->sdev || - !blk_queue_find_tag(dev->sdev->request_queue, tag); -} - /** * ata_exec_internal_sg - execute libata internal command * @dev: Device to which the command is sent @@ -1594,7 +1585,6 @@ unsigned ata_exec_internal_sg(struct ata_device *dev, else tag = 0; - BUG_ON(!ata_valid_internal_tag(ap, dev, tag)); qc = __ata_qc_from_tag(ap, tag); qc->tag = tag; @@ -4734,80 +4724,36 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words) } /** - * ata_qc_new - Request an available ATA command, for queueing - * @ap: target port - * - * Some ATA host controllers may implement a queue depth which is less - * than ATA_MAX_QUEUE. So we shouldn't allocate a tag which is beyond - * the hardware limitation. + * ata_qc_new_init - Request an available ATA command, and initialize it + * @dev: Device from whom we request an available command structure * * LOCKING: * None. */ -static struct ata_queued_cmd *sas_ata_qc_new(struct ata_port *ap) -{ - struct ata_queued_cmd *qc = NULL; - unsigned int max_queue = ap->host->n_tags; - unsigned int i, tag; - - for (i = 0, tag = ap->sas_last_tag + 1; i < max_queue; i++, tag++) { - tag = tag < max_queue ? tag : 0; - - /* the last tag is reserved for internal command. */ - if (tag == ATA_TAG_INTERNAL) - continue; - - if (!test_and_set_bit(tag, &ap->sas_tag_allocated)) { - qc = __ata_qc_from_tag(ap, tag); - qc->tag = tag; - ap->sas_last_tag = tag; - break; - } - } - - return qc; -} - -static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap, int blktag) +struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev, int tag) { + struct ata_port *ap = dev->link->ap; struct ata_queued_cmd *qc; /* no command while frozen */ if (unlikely(ap->pflags & ATA_PFLAG_FROZEN)) return NULL; - /* SATA will directly use block tag. libsas need its own tag management */ - if (ap->scsi_host) { - qc = __ata_qc_from_tag(ap, blktag); - qc->tag = blktag; - return qc; + /* libsas case */ + if (!ap->scsi_host) { + tag = ata_sas_allocate_tag(ap); + if (tag < 0) + return NULL; } - return sas_ata_qc_new(ap); -} - -/** - * ata_qc_new_init - Request an available ATA command, and initialize it - * @dev: Device from whom we request an available command structure - * - * LOCKING: - * None. - */ - -struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev, int blktag) -{ - struct ata_port *ap = dev->link->ap; - struct ata_queued_cmd *qc; - - qc = ata_qc_new(ap, blktag); - if (qc) { - qc->scsicmd = NULL; - qc->ap = ap; - qc->dev = dev; + qc = __ata_qc_from_tag(ap, tag); + qc->tag = tag; + qc->scsicmd = NULL; + qc->ap = ap; + qc->dev = dev; - ata_qc_reinit(qc); - } + ata_qc_reinit(qc); return qc; } @@ -4822,12 +4768,6 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev, int blktag) * LOCKING: * spin_lock_irqsave(host lock) */ -static void sas_ata_qc_free(unsigned int tag, struct ata_port *ap) -{ - if (!ap->scsi_host) - clear_bit(tag, &ap->sas_tag_allocated); -} - void ata_qc_free(struct ata_queued_cmd *qc) { struct ata_port *ap; @@ -4840,7 +4780,8 @@ void ata_qc_free(struct ata_queued_cmd *qc) tag = qc->tag; if (likely(ata_tag_valid(tag))) { qc->tag = ATA_TAG_POISON; - sas_ata_qc_free(tag, ap); + if (!ap->scsi_host) + ata_sas_free_tag(tag, ap); } } 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) */ shost->max_host_blocked = 1; - scsi_init_shared_tag_map(shost, host->n_tags); + if (scsi_init_shared_tag_map(shost, host->n_tags)) + goto err_add; rc = scsi_add_host_with_dma(ap->scsi_host, &ap->tdev, ap->host->dev); @@ -4230,3 +4231,28 @@ int ata_sas_queuecmd(struct scsi_cmnd *cmd, struct ata_port *ap) return rc; } EXPORT_SYMBOL_GPL(ata_sas_queuecmd); + +int ata_sas_allocate_tag(struct ata_port *ap) +{ + unsigned int max_queue = ap->host->n_tags; + unsigned int i, tag; + + for (i = 0, tag = ap->sas_last_tag + 1; i < max_queue; i++, tag++) { + tag = tag < max_queue ? tag : 0; + + /* the last tag is reserved for internal command. */ + if (tag == ATA_TAG_INTERNAL) + continue; + + if (!test_and_set_bit(tag, &ap->sas_tag_allocated)) { + ap->sas_last_tag = tag; + return tag; + } + } + return -1; +} + +void ata_sas_free_tag(unsigned int tag, struct ata_port *ap) +{ + clear_bit(tag, &ap->sas_tag_allocated); +} diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 40405135bbb6..8c491cd8805b 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -145,6 +145,8 @@ extern void ata_scsi_dev_rescan(struct work_struct *work); extern int ata_bus_probe(struct ata_port *ap); extern int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel, unsigned int id, u64 lun); +int ata_sas_allocate_tag(struct ata_port *ap); +void ata_sas_free_tag(unsigned int tag, struct ata_port *ap); /* libata-eh.c */ |