libata: support the ata host which implements a queue depth less than 32
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / ata / libata-core.c
index bf00fbcde8ad0abb5ac774c79f38958c86b7d82e..d7fb8269cb736603a4fc57c6aa5ef63fc26c1cca 100644 (file)
@@ -4758,6 +4758,10 @@ 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.
+ *
  *     LOCKING:
  *     None.
  */
@@ -4765,14 +4769,16 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
 static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
 {
        struct ata_queued_cmd *qc = NULL;
-       unsigned int i, tag;
+       unsigned int i, tag, max_queue;
+
+       max_queue = ap->scsi_host->can_queue;
 
        /* no command while frozen */
        if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
                return NULL;
 
-       for (i = 0; i < ATA_MAX_QUEUE; i++) {
-               tag = (i + ap->last_tag + 1) % ATA_MAX_QUEUE;
+       for (i = 0, tag = ap->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)
@@ -6154,6 +6160,16 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
 {
        int i, rc;
 
+       /*
+        * The max queue supported by hardware must not be greater than
+        * ATA_MAX_QUEUE.
+        */
+       if (sht->can_queue > ATA_MAX_QUEUE) {
+               dev_err(host->dev, "BUG: the hardware max queue is too large\n");
+               WARN_ON(1);
+               return -EINVAL;
+       }
+
        /* host must have been started */
        if (!(host->flags & ATA_HOST_STARTED)) {
                dev_err(host->dev, "BUG: trying to register unstarted host\n");