aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/libata-core.c32
-rw-r--r--include/linux/libata.h9
2 files changed, 37 insertions, 4 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c
index de2cd61a264d..966abb5f423e 100644
--- a/drivers/scsi/libata-core.c
+++ b/drivers/scsi/libata-core.c
@@ -980,15 +980,39 @@ unsigned ata_exec_internal(struct ata_device *dev,
980 struct ata_port *ap = dev->ap; 980 struct ata_port *ap = dev->ap;
981 u8 command = tf->command; 981 u8 command = tf->command;
982 struct ata_queued_cmd *qc; 982 struct ata_queued_cmd *qc;
983 unsigned int tag, preempted_tag;
983 DECLARE_COMPLETION(wait); 984 DECLARE_COMPLETION(wait);
984 unsigned long flags; 985 unsigned long flags;
985 unsigned int err_mask; 986 unsigned int err_mask;
986 987
987 spin_lock_irqsave(&ap->host_set->lock, flags); 988 spin_lock_irqsave(&ap->host_set->lock, flags);
988 989
989 qc = ata_qc_new_init(dev); 990 /* initialize internal qc */
990 BUG_ON(qc == NULL);
991 991
992 /* XXX: Tag 0 is used for drivers with legacy EH as some
993 * drivers choke if any other tag is given. This breaks
994 * ata_tag_internal() test for those drivers. Don't use new
995 * EH stuff without converting to it.
996 */
997 if (ap->ops->error_handler)
998 tag = ATA_TAG_INTERNAL;
999 else
1000 tag = 0;
1001
1002 if (test_and_set_bit(tag, &ap->qactive))
1003 BUG();
1004 qc = ata_qc_from_tag(ap, tag);
1005
1006 qc->tag = tag;
1007 qc->scsicmd = NULL;
1008 qc->ap = ap;
1009 qc->dev = dev;
1010 ata_qc_reinit(qc);
1011
1012 preempted_tag = ap->active_tag;
1013 ap->active_tag = ATA_TAG_POISON;
1014
1015 /* prepare & issue qc */
992 qc->tf = *tf; 1016 qc->tf = *tf;
993 if (cdb) 1017 if (cdb)
994 memcpy(qc->cdb, cdb, ATAPI_CDB_LEN); 1018 memcpy(qc->cdb, cdb, ATAPI_CDB_LEN);
@@ -1035,6 +1059,7 @@ unsigned ata_exec_internal(struct ata_device *dev,
1035 err_mask = qc->err_mask; 1059 err_mask = qc->err_mask;
1036 1060
1037 ata_qc_free(qc); 1061 ata_qc_free(qc);
1062 ap->active_tag = preempted_tag;
1038 1063
1039 /* XXX - Some LLDDs (sata_mv) disable port on command failure. 1064 /* XXX - Some LLDDs (sata_mv) disable port on command failure.
1040 * Until those drivers are fixed, we detect the condition 1065 * Until those drivers are fixed, we detect the condition
@@ -4014,7 +4039,8 @@ static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
4014 struct ata_queued_cmd *qc = NULL; 4039 struct ata_queued_cmd *qc = NULL;
4015 unsigned int i; 4040 unsigned int i;
4016 4041
4017 for (i = 0; i < ATA_MAX_QUEUE; i++) 4042 /* the last tag is reserved for internal command. */
4043 for (i = 0; i < ATA_MAX_QUEUE - 1; i++)
4018 if (!test_and_set_bit(i, &ap->qactive)) { 4044 if (!test_and_set_bit(i, &ap->qactive)) {
4019 qc = ata_qc_from_tag(ap, i); 4045 qc = ata_qc_from_tag(ap, i);
4020 break; 4046 break;
diff --git a/include/linux/libata.h b/include/linux/libata.h
index e5d6d7f8e6dc..5a403e434ff8 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -108,7 +108,9 @@ enum {
108 LIBATA_MAX_PRD = ATA_MAX_PRD / 2, 108 LIBATA_MAX_PRD = ATA_MAX_PRD / 2,
109 ATA_MAX_PORTS = 8, 109 ATA_MAX_PORTS = 8,
110 ATA_DEF_QUEUE = 1, 110 ATA_DEF_QUEUE = 1,
111 ATA_MAX_QUEUE = 1, 111 /* tag ATA_MAX_QUEUE - 1 is reserved for internal commands */
112 ATA_MAX_QUEUE = 2,
113 ATA_TAG_INTERNAL = ATA_MAX_QUEUE - 1,
112 ATA_MAX_SECTORS = 200, /* FIXME */ 114 ATA_MAX_SECTORS = 200, /* FIXME */
113 ATA_MAX_BUS = 2, 115 ATA_MAX_BUS = 2,
114 ATA_DEF_BUSY_WAIT = 10000, 116 ATA_DEF_BUSY_WAIT = 10000,
@@ -717,6 +719,11 @@ static inline unsigned int ata_tag_valid(unsigned int tag)
717 return (tag < ATA_MAX_QUEUE) ? 1 : 0; 719 return (tag < ATA_MAX_QUEUE) ? 1 : 0;
718} 720}
719 721
722static inline unsigned int ata_tag_internal(unsigned int tag)
723{
724 return tag == ATA_MAX_QUEUE - 1;
725}
726
720static inline unsigned int ata_class_enabled(unsigned int class) 727static inline unsigned int ata_class_enabled(unsigned int class)
721{ 728{
722 return class == ATA_DEV_ATA || class == ATA_DEV_ATAPI; 729 return class == ATA_DEV_ATA || class == ATA_DEV_ATAPI;