- patches.apparmor/remove_suid_new_case_in_2.6.22.diff: Merge fix.
[linux-flexiantxendom0-3.2.10.git] / drivers / ide / ide-lib.c
index a577b38..074bb32 100644 (file)
@@ -69,123 +69,41 @@ char *ide_xfer_verbose (u8 xfer_rate)
 EXPORT_SYMBOL(ide_xfer_verbose);
 
 /**
- *     ide_dma_speed   -       compute DMA speed
- *     @drive: drive
- *     @mode:  modes available
- *
- *     Checks the drive capabilities and returns the speed to use
- *     for the DMA transfer.  Returns 0 if the drive is incapable
- *     of DMA transfers.
- */
-u8 ide_dma_speed(ide_drive_t *drive, u8 mode)
-{
-       struct hd_driveid *id   = drive->id;
-       ide_hwif_t *hwif        = HWIF(drive);
-       u8 ultra_mask, mwdma_mask, swdma_mask;
-       u8 speed = 0;
-
-       if (drive->media != ide_disk && hwif->atapi_dma == 0)
-               return 0;
-
-       /* Capable of UltraDMA modes? */
-       ultra_mask = id->dma_ultra & hwif->ultra_mask;
-
-       if (!(id->field_valid & 4))
-               mode = 0;       /* fallback to MW/SW DMA if no UltraDMA */
-
-       switch (mode) {
-       case 4:
-               if (ultra_mask & 0x40) {
-                       speed = XFER_UDMA_6;
-                       break;
-               }
-       case 3:
-               if (ultra_mask & 0x20) {
-                       speed = XFER_UDMA_5;
-                       break;
-               }
-       case 2:
-               if (ultra_mask & 0x10) {
-                       speed = XFER_UDMA_4;
-                       break;
-               }
-               if (ultra_mask & 0x08) {
-                       speed = XFER_UDMA_3;
-                       break;
-               }
-       case 1:
-               if (ultra_mask & 0x04) {
-                       speed = XFER_UDMA_2;
-                       break;
-               }
-               if (ultra_mask & 0x02) {
-                       speed = XFER_UDMA_1;
-                       break;
-               }
-               if (ultra_mask & 0x01) {
-                       speed = XFER_UDMA_0;
-                       break;
-               }
-       case 0:
-               mwdma_mask = id->dma_mword & hwif->mwdma_mask;
-
-               if (mwdma_mask & 0x04) {
-                       speed = XFER_MW_DMA_2;
-                       break;
-               }
-               if (mwdma_mask & 0x02) {
-                       speed = XFER_MW_DMA_1;
-                       break;
-               }
-               if (mwdma_mask & 0x01) {
-                       speed = XFER_MW_DMA_0;
-                       break;
-               }
-
-               swdma_mask = id->dma_1word & hwif->swdma_mask;
-
-               if (swdma_mask & 0x04) {
-                       speed = XFER_SW_DMA_2;
-                       break;
-               }
-               if (swdma_mask & 0x02) {
-                       speed = XFER_SW_DMA_1;
-                       break;
-               }
-               if (swdma_mask & 0x01) {
-                       speed = XFER_SW_DMA_0;
-                       break;
-               }
-       }
-
-       return speed;
-}
-EXPORT_SYMBOL(ide_dma_speed);
-
-
-/**
- *     ide_rate_filter         -       return best speed for mode
- *     @mode: modes available
+ *     ide_rate_filter         -       filter transfer mode
+ *     @drive: IDE device
  *     @speed: desired speed
  *
- *     Given the available DMA/UDMA mode this function returns
+ *     Given the available transfer modes this function returns
  *     the best available speed at or below the speed requested.
+ *
+ *     FIXME: filter also PIO/SWDMA/MWDMA modes
  */
 
-u8 ide_rate_filter (u8 mode, u8 speed) 
+u8 ide_rate_filter(ide_drive_t *drive, u8 speed)
 {
 #ifdef CONFIG_BLK_DEV_IDEDMA
-       static u8 speed_max[] = {
-               XFER_MW_DMA_2, XFER_UDMA_2, XFER_UDMA_4,
-               XFER_UDMA_5, XFER_UDMA_6
-       };
+       ide_hwif_t *hwif = drive->hwif;
+       u8 mask = hwif->ultra_mask, mode = XFER_MW_DMA_2;
+
+       if (hwif->udma_filter)
+               mask = hwif->udma_filter(drive);
+
+       /*
+        * TODO: speed > XFER_UDMA_2 extra check is needed to avoid false
+        * cable warning from eighty_ninty_three(), moving ide_rate_filter()
+        * calls from ->speedproc to core code will make this hack go away
+        */
+       if (speed > XFER_UDMA_2) {
+               if ((mask & 0x78) && (eighty_ninty_three(drive) == 0))
+                       mask &= 0x07;
+       }
+
+       if (mask)
+               mode = fls(mask) - 1 + XFER_UDMA_0;
 
 //     printk("%s: mode 0x%02x, speed 0x%02x\n", __FUNCTION__, mode, speed);
 
-       /* So that we remember to update this if new modes appear */
-       BUG_ON(mode > 4);
-       return min(speed, speed_max[mode]);
+       return min(speed, mode);
 #else /* !CONFIG_BLK_DEV_IDEDMA */
        return min(speed, (u8)XFER_PIO_4);
 #endif /* CONFIG_BLK_DEV_IDEDMA */
@@ -193,18 +111,6 @@ u8 ide_rate_filter (u8 mode, u8 speed)
 
 EXPORT_SYMBOL(ide_rate_filter);
 
-int ide_dma_enable (ide_drive_t *drive)
-{
-       ide_hwif_t *hwif        = HWIF(drive);
-       struct hd_driveid *id   = drive->id;
-
-       return ((int)   ((((id->dma_ultra >> 8) & hwif->ultra_mask) ||
-                         ((id->dma_mword >> 8) & hwif->mwdma_mask) ||
-                         ((id->dma_1word >> 8) & hwif->swdma_mask)) ? 1 : 0));
-}
-
-EXPORT_SYMBOL(ide_dma_enable);
-
 int ide_use_fast_pio(ide_drive_t *drive)
 {
        struct hd_driveid *id = drive->id;
@@ -435,21 +341,12 @@ void ide_toggle_bounce(ide_drive_t *drive, int on)
 {
        u64 addr = BLK_BOUNCE_HIGH;     /* dma64_addr_t */
 
-#ifndef CONFIG_XEN
        if (!PCI_DMA_BUS_IS_PHYS) {
                addr = BLK_BOUNCE_ANY;
        } else if (on && drive->media == ide_disk) {
                if (HWIF(drive)->pci_dev)
                        addr = HWIF(drive)->pci_dev->dma_mask;
        }
-#else
-       if (on && drive->media == ide_disk) {
-               if (!PCI_DMA_BUS_IS_PHYS)
-                       addr = BLK_BOUNCE_ANY;
-               else if (HWIF(drive)->pci_dev)
-                       addr = HWIF(drive)->pci_dev->dma_mask;
-       }
-#endif
 
        if (drive->queue)
                blk_queue_bounce_limit(drive->queue, addr);