]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/ata/libata-core.c
libata: Avoid overflow in ata_tf_to_lba48() when tf->hba_lbal > 127
[linux-2.6-omap-h63xx.git] / drivers / ata / libata-core.c
index 1ee9499bd343717ca95252a775c01d77ef3f892f..8824c8da3f2f88abea82ab1de951313ef811bf76 100644 (file)
@@ -1268,7 +1268,7 @@ u64 ata_tf_to_lba48(const struct ata_taskfile *tf)
 
        sectors |= ((u64)(tf->hob_lbah & 0xff)) << 40;
        sectors |= ((u64)(tf->hob_lbam & 0xff)) << 32;
-       sectors |= (tf->hob_lbal & 0xff) << 24;
+       sectors |= ((u64)(tf->hob_lbal & 0xff)) << 24;
        sectors |= (tf->lbah & 0xff) << 16;
        sectors |= (tf->lbam & 0xff) << 8;
        sectors |= (tf->lbal & 0xff);
@@ -1602,7 +1602,6 @@ unsigned long ata_id_xfermask(const u16 *id)
 /**
  *     ata_pio_queue_task - Queue port_task
  *     @ap: The ata_port to queue port_task for
- *     @fn: workqueue function to be scheduled
  *     @data: data for @fn to use
  *     @delay: delay time in msecs for workqueue function
  *
@@ -1713,8 +1712,6 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
        else
                tag = 0;
 
-       if (test_and_set_bit(tag, &ap->qc_allocated))
-               BUG();
        qc = __ata_qc_from_tag(ap, tag);
 
        qc->tag = tag;
@@ -4158,29 +4155,33 @@ static int cable_is_40wire(struct ata_port *ap)
        struct ata_link *link;
        struct ata_device *dev;
 
-       /* If the controller thinks we are 40 wire, we are */
+       /* If the controller thinks we are 40 wire, we are. */
        if (ap->cbl == ATA_CBL_PATA40)
                return 1;
-       /* If the controller thinks we are 80 wire, we are */
+
+       /* If the controller thinks we are 80 wire, we are. */
        if (ap->cbl == ATA_CBL_PATA80 || ap->cbl == ATA_CBL_SATA)
                return 0;
-       /* If the system is known to be 40 wire short cable (eg laptop),
-          then we allow 80 wire modes even if the drive isn't sure */
+
+       /* If the system is known to be 40 wire short cable (eg
+        * laptop), then we allow 80 wire modes even if the drive
+        * isn't sure.
+        */
        if (ap->cbl == ATA_CBL_PATA40_SHORT)
                return 0;
-       /* If the controller doesn't know we scan
-
-          - Note: We look for all 40 wire detects at this point.
-            Any 80 wire detect is taken to be 80 wire cable
-            because
-            - In many setups only the one drive (slave if present)
-               will give a valid detect
-             - If you have a non detect capable drive you don't
-               want it to colour the choice
-        */
+
+       /* If the controller doesn't know, we scan.
+        *
+        * Note: We look for all 40 wire detects at this point.  Any
+        *       80 wire detect is taken to be 80 wire cable because
+        * - in many setups only the one drive (slave if present) will
+        *   give a valid detect
+        * - if you have a non detect capable drive you don't want it
+        *   to colour the choice
+        */
        ata_port_for_each_link(link, ap) {
                ata_link_for_each_dev(dev, link) {
-                       if (!ata_is_40wire(dev))
+                       if (ata_dev_enabled(dev) && !ata_is_40wire(dev))
                                return 0;
                }
        }
@@ -4552,55 +4553,29 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
 #endif /* __BIG_ENDIAN */
 }
 
-/**
- *     ata_qc_new - Request an available ATA command, for queueing
- *     @ap: Port associated with device @dev
- *     @dev: Device from whom we request an available command structure
- *
- *     LOCKING:
- *     None.
- */
-
-static struct ata_queued_cmd *ata_qc_new(struct ata_port *ap)
-{
-       struct ata_queued_cmd *qc = NULL;
-       unsigned int i;
-
-       /* no command while frozen */
-       if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
-               return NULL;
-
-       /* the last tag is reserved for internal command. */
-       for (i = 0; i < ATA_MAX_QUEUE - 1; i++)
-               if (!test_and_set_bit(i, &ap->qc_allocated)) {
-                       qc = __ata_qc_from_tag(ap, i);
-                       break;
-               }
-
-       if (qc)
-               qc->tag = i;
-
-       return qc;
-}
-
 /**
  *     ata_qc_new_init - Request an available ATA command, and initialize it
  *     @dev: Device from whom we request an available command structure
+ *     @tag: command tag
  *
  *     LOCKING:
  *     None.
  */
 
-struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev)
+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;
 
-       qc = ata_qc_new(ap);
+       if (unlikely(ap->pflags & ATA_PFLAG_FROZEN))
+               return NULL;
+
+       qc = __ata_qc_from_tag(ap, tag);
        if (qc) {
                qc->scsicmd = NULL;
                qc->ap = ap;
                qc->dev = dev;
+               qc->tag = tag;
 
                ata_qc_reinit(qc);
        }
@@ -4608,31 +4583,6 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev)
        return qc;
 }
 
-/**
- *     ata_qc_free - free unused ata_queued_cmd
- *     @qc: Command to complete
- *
- *     Designed to free unused ata_queued_cmd object
- *     in case something prevents using it.
- *
- *     LOCKING:
- *     spin_lock_irqsave(host lock)
- */
-void ata_qc_free(struct ata_queued_cmd *qc)
-{
-       struct ata_port *ap = qc->ap;
-       unsigned int tag;
-
-       WARN_ON(qc == NULL);    /* ata_qc_from_tag _might_ return NULL */
-
-       qc->flags = 0;
-       tag = qc->tag;
-       if (likely(ata_tag_valid(tag))) {
-               qc->tag = ATA_TAG_POISON;
-               clear_bit(tag, &ap->qc_allocated);
-       }
-}
-
 void __ata_qc_complete(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
@@ -4697,7 +4647,6 @@ static void ata_verify_xfer(struct ata_queued_cmd *qc)
 /**
  *     ata_qc_complete - Complete an active ATA command
  *     @qc: Command to complete
- *     @err_mask: ATA Status register contents
  *
  *     Indicate to the mid and upper layers that an ATA
  *     command has completed, with either an ok or not-ok status.
@@ -5373,6 +5322,8 @@ struct ata_port *ata_port_alloc(struct ata_host *host)
 
 #ifdef CONFIG_ATA_SFF
        INIT_DELAYED_WORK(&ap->port_task, ata_pio_task);
+#else
+       INIT_DELAYED_WORK(&ap->port_task, NULL);
 #endif
        INIT_DELAYED_WORK(&ap->hotplug_task, ata_scsi_hotplug);
        INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan);