diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ata/libata-core.c | 54 | ||||
-rw-r--r-- | drivers/ata/libata-scsi.c | 4 | ||||
-rw-r--r-- | drivers/ata/libata.h | 2 |
3 files changed, 45 insertions, 15 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 5c84fb5c3372..695d33df3df5 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -1525,6 +1525,15 @@ static void ata_qc_complete_internal(struct ata_queued_cmd *qc) | |||
1525 | complete(waiting); | 1525 | complete(waiting); |
1526 | } | 1526 | } |
1527 | 1527 | ||
1528 | static bool ata_valid_internal_tag(struct ata_port *ap, struct ata_device *dev, | ||
1529 | unsigned int tag) | ||
1530 | { | ||
1531 | if (!ap->scsi_host) | ||
1532 | return !test_and_set_bit(tag, &ap->sas_tag_allocated); | ||
1533 | return !dev->sdev || | ||
1534 | !blk_queue_find_tag(dev->sdev->request_queue, tag); | ||
1535 | } | ||
1536 | |||
1528 | /** | 1537 | /** |
1529 | * ata_exec_internal_sg - execute libata internal command | 1538 | * ata_exec_internal_sg - execute libata internal command |
1530 | * @dev: Device to which the command is sent | 1539 | * @dev: Device to which the command is sent |
@@ -1585,8 +1594,7 @@ unsigned ata_exec_internal_sg(struct ata_device *dev, | |||
1585 | else | 1594 | else |
1586 | tag = 0; | 1595 | tag = 0; |
1587 | 1596 | ||
1588 | if (test_and_set_bit(tag, &ap->qc_allocated)) | 1597 | BUG_ON(!ata_valid_internal_tag(ap, dev, tag)); |
1589 | BUG(); | ||
1590 | qc = __ata_qc_from_tag(ap, tag); | 1598 | qc = __ata_qc_from_tag(ap, tag); |
1591 | 1599 | ||
1592 | qc->tag = tag; | 1600 | qc->tag = tag; |
@@ -4737,27 +4745,23 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words) | |||
4737 | * None. | 4745 | * None. |
4738 | */ | 4746 | */ |
4739 | 4747 | ||
4740 | static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap) | 4748 | static struct ata_queued_cmd *sas_ata_qc_new(struct ata_port *ap) |
4741 | { | 4749 | { |
4742 | struct ata_queued_cmd *qc = NULL; | 4750 | struct ata_queued_cmd *qc = NULL; |
4743 | unsigned int max_queue = ap->host->n_tags; | 4751 | unsigned int max_queue = ap->host->n_tags; |
4744 | unsigned int i, tag; | 4752 | unsigned int i, tag; |
4745 | 4753 | ||
4746 | /* no command while frozen */ | 4754 | for (i = 0, tag = ap->sas_last_tag + 1; i < max_queue; i++, tag++) { |
4747 | if (unlikely(ap->pflags & ATA_PFLAG_FROZEN)) | ||
4748 | return NULL; | ||
4749 | |||
4750 | for (i = 0, tag = ap->last_tag + 1; i < max_queue; i++, tag++) { | ||
4751 | tag = tag < max_queue ? tag : 0; | 4755 | tag = tag < max_queue ? tag : 0; |
4752 | 4756 | ||
4753 | /* the last tag is reserved for internal command. */ | 4757 | /* the last tag is reserved for internal command. */ |
4754 | if (tag == ATA_TAG_INTERNAL) | 4758 | if (tag == ATA_TAG_INTERNAL) |
4755 | continue; | 4759 | continue; |
4756 | 4760 | ||
4757 | if (!test_and_set_bit(tag, &ap->qc_allocated)) { | 4761 | if (!test_and_set_bit(tag, &ap->sas_tag_allocated)) { |
4758 | qc = __ata_qc_from_tag(ap, tag); | 4762 | qc = __ata_qc_from_tag(ap, tag); |
4759 | qc->tag = tag; | 4763 | qc->tag = tag; |
4760 | ap->last_tag = tag; | 4764 | ap->sas_last_tag = tag; |
4761 | break; | 4765 | break; |
4762 | } | 4766 | } |
4763 | } | 4767 | } |
@@ -4765,6 +4769,24 @@ static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap) | |||
4765 | return qc; | 4769 | return qc; |
4766 | } | 4770 | } |
4767 | 4771 | ||
4772 | static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap, int blktag) | ||
4773 | { | ||
4774 | struct ata_queued_cmd *qc; | ||
4775 | |||
4776 | /* no command while frozen */ | ||
4777 | if (unlikely(ap->pflags & ATA_PFLAG_FROZEN)) | ||
4778 | return NULL; | ||
4779 | |||
4780 | /* SATA will directly use block tag. libsas need its own tag management */ | ||
4781 | if (ap->scsi_host) { | ||
4782 | qc = __ata_qc_from_tag(ap, blktag); | ||
4783 | qc->tag = blktag; | ||
4784 | return qc; | ||
4785 | } | ||
4786 | |||
4787 | return sas_ata_qc_new(ap); | ||
4788 | } | ||
4789 | |||
4768 | /** | 4790 | /** |
4769 | * ata_qc_new_init - Request an available ATA command, and initialize it | 4791 | * ata_qc_new_init - Request an available ATA command, and initialize it |
4770 | * @dev: Device from whom we request an available command structure | 4792 | * @dev: Device from whom we request an available command structure |
@@ -4773,12 +4795,12 @@ static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap) | |||
4773 | * None. | 4795 | * None. |
4774 | */ | 4796 | */ |
4775 | 4797 | ||
4776 | struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev) | 4798 | struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev, int blktag) |
4777 | { | 4799 | { |
4778 | struct ata_port *ap = dev->link->ap; | 4800 | struct ata_port *ap = dev->link->ap; |
4779 | struct ata_queued_cmd *qc; | 4801 | struct ata_queued_cmd *qc; |
4780 | 4802 | ||
4781 | qc = ata_qc_new(ap); | 4803 | qc = ata_qc_new(ap, blktag); |
4782 | if (qc) { | 4804 | if (qc) { |
4783 | qc->scsicmd = NULL; | 4805 | qc->scsicmd = NULL; |
4784 | qc->ap = ap; | 4806 | qc->ap = ap; |
@@ -4800,6 +4822,12 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev) | |||
4800 | * LOCKING: | 4822 | * LOCKING: |
4801 | * spin_lock_irqsave(host lock) | 4823 | * spin_lock_irqsave(host lock) |
4802 | */ | 4824 | */ |
4825 | static void sas_ata_qc_free(unsigned int tag, struct ata_port *ap) | ||
4826 | { | ||
4827 | if (!ap->scsi_host) | ||
4828 | clear_bit(tag, &ap->sas_tag_allocated); | ||
4829 | } | ||
4830 | |||
4803 | void ata_qc_free(struct ata_queued_cmd *qc) | 4831 | void ata_qc_free(struct ata_queued_cmd *qc) |
4804 | { | 4832 | { |
4805 | struct ata_port *ap; | 4833 | struct ata_port *ap; |
@@ -4812,7 +4840,7 @@ void ata_qc_free(struct ata_queued_cmd *qc) | |||
4812 | tag = qc->tag; | 4840 | tag = qc->tag; |
4813 | if (likely(ata_tag_valid(tag))) { | 4841 | if (likely(ata_tag_valid(tag))) { |
4814 | qc->tag = ATA_TAG_POISON; | 4842 | qc->tag = ATA_TAG_POISON; |
4815 | clear_bit(tag, &ap->qc_allocated); | 4843 | sas_ata_qc_free(tag, ap); |
4816 | } | 4844 | } |
4817 | } | 4845 | } |
4818 | 4846 | ||
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index e364e86e84d7..94339c2aed1b 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
@@ -756,7 +756,7 @@ static struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev, | |||
756 | { | 756 | { |
757 | struct ata_queued_cmd *qc; | 757 | struct ata_queued_cmd *qc; |
758 | 758 | ||
759 | qc = ata_qc_new_init(dev); | 759 | qc = ata_qc_new_init(dev, cmd->request->tag); |
760 | if (qc) { | 760 | if (qc) { |
761 | qc->scsicmd = cmd; | 761 | qc->scsicmd = cmd; |
762 | qc->scsidone = cmd->scsi_done; | 762 | qc->scsidone = cmd->scsi_done; |
@@ -3666,6 +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); | ||
3670 | |||
3669 | rc = scsi_add_host_with_dma(ap->scsi_host, | 3671 | rc = scsi_add_host_with_dma(ap->scsi_host, |
3670 | &ap->tdev, ap->host->dev); | 3672 | &ap->tdev, ap->host->dev); |
3671 | if (rc) | 3673 | if (rc) |
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 5f4e0cca56ec..40405135bbb6 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h | |||
@@ -63,7 +63,7 @@ extern struct ata_link *ata_dev_phys_link(struct ata_device *dev); | |||
63 | extern void ata_force_cbl(struct ata_port *ap); | 63 | extern void ata_force_cbl(struct ata_port *ap); |
64 | extern u64 ata_tf_to_lba(const struct ata_taskfile *tf); | 64 | extern u64 ata_tf_to_lba(const struct ata_taskfile *tf); |
65 | extern u64 ata_tf_to_lba48(const struct ata_taskfile *tf); | 65 | extern u64 ata_tf_to_lba48(const struct ata_taskfile *tf); |
66 | extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev); | 66 | extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev, int tag); |
67 | extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev, | 67 | extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev, |
68 | u64 block, u32 n_block, unsigned int tf_flags, | 68 | u64 block, u32 n_block, unsigned int tf_flags, |
69 | unsigned int tag); | 69 | unsigned int tag); |