--- lt_hotswap-0.3.6/lt_hotswap.c	2008-02-20 02:12:21.000000000 +0900
+++ lt_hotswap-0.3.6c/lt_hotswap.c	2008-02-20 22:02:48.000000000 +0900
@@ -42,7 +42,8 @@ static struct file_operations lths_proc_
   .write = lths_proc_write,
 };
 
-static unsigned long ide_get_or_set_dma_base (ide_hwif_t *hwif);
+static unsigned long ide_get_or_set_dma_base (const struct ide_port_info *d, ide_hwif_t *hwif);
+static void ide_hwif_setup_dma(struct pci_dev *dev, const struct ide_port_info *d, ide_hwif_t *hwif);
 
 
 
@@ -429,58 +430,86 @@ lths_battery_notify(acpi_handle handle, 
 static void
 lths_scan_ide(int num)
 {
-  ide_pci_device_t *d = ide_hwifs[num].cds;
+  const struct ide_port_info *d = ide_hwifs[num].cds;
   struct pci_dev *dev = ide_hwifs[num].pci_dev;
-    
+  u8 idx[4] = { 0xff, 0xff, 0xff, 0xff };
+
   ide_unregister(num);
-    
+
   // FIXME this is just horrible.  :)
   // But perhaps it's not a horrible assumption to make on modern hw
+
   if (num == 0)
     ide_hwifs[num].mate = &ide_hwifs[1];
   else 
     ide_hwifs[num].mate = &ide_hwifs[0];
   ide_hwifs[num].channel = num;
 
-  if (d->init_iops) {
-    d->init_iops(&ide_hwifs[num]);
-  }
-  if (d->autodma == NODMA)
-    goto bypass_legacy_dma;
+  /* setup proper ancestral information */
+  ide_hwifs[num].gendev.parent = &dev->dev;
 
-  if(d->init_setup_dma)
-    d->init_setup_dma(dev, d, &ide_hwifs[num]);
-  else {
-    unsigned long dma_base = ide_get_or_set_dma_base(&ide_hwifs[num]);
+  if ((!ide_hwifs[num].irq && (d->host_flags & IDE_HFLAG_LEGACY_IRQS)) ||
+      (d->host_flags & IDE_HFLAG_FORCE_LEGACY_IRQS))
+    ide_hwifs[num].irq = num ? 15 : 14;
+
+//  if (d->init_iops) {
+//    d->init_iops(&ide_hwifs[num]);
+//  }
+
+  if ((d->host_flags & IDE_HFLAG_NO_AUTODMA) == 0 ||
+ 	    ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE)) {
+    unsigned long dma_base = ide_get_or_set_dma_base(d,&ide_hwifs[num]);
 
     if (dma_base) {
-      if (d->init_dma) {
-        d->init_dma(&ide_hwifs[num], dma_base);
-      } else {
-        ide_setup_dma(&ide_hwifs[num], dma_base, 8);
-      }
+      if ((d->host_flags & IDE_HFLAG_NO_DMA) == 0)
+        ide_hwif_setup_dma(dev, d, &ide_hwifs[num]);
+      ide_hwifs[num].swdma_mask = d->swdma_mask;
+      ide_hwifs[num].mwdma_mask = d->mwdma_mask;
+      ide_hwifs[num].ultra_mask = d->udma_mask;
     }
   }
 
-bypass_legacy_dma:
-  if (d->init_hwif)
+  ide_hwifs[num].fixup = d->fixup;
+
+  ide_hwifs[num].host_flags = d->host_flags;
+  ide_hwifs[num].pio_mask = d->pio_mask;
+
+  if ((d->host_flags & IDE_HFLAG_SERIALIZE) && ide_hwifs[num].mate)
+    ide_hwifs[num].mate->serialized = ide_hwifs[num].serialized = 1;
+
+  if (d->host_flags & IDE_HFLAG_IO_32BIT) {
+    ide_hwifs[num].drives[0].io_32bit = 1;
+    ide_hwifs[num].drives[1].io_32bit = 1;
+  }
+
+  if (d->host_flags & IDE_HFLAG_UNMASK_IRQS) {
+    ide_hwifs[num].drives[0].unmask = 1;
+    ide_hwifs[num].drives[1].unmask = 1;
+  }
+
+  ide_hwifs[num].drives[0].autotune = 1;
+  ide_hwifs[num].drives[1].autotune = 1;
+
+
+//  if (d->init_hwif)
       /* Call chipset-specific routine
        * for each enabled hwif
        */
-    d->init_hwif(&ide_hwifs[num]);
+//    d->init_hwif(&ide_hwifs[num]);
 
+  if (ide_hwifs[num].io_ports[IDE_DATA_OFFSET] && !ide_hwifs[num].present)
+    idx[num] = num;
 
-  probe_hwif_init(&ide_hwifs[num]);
-  
-  
-  
-  create_proc_ide_interfaces();
+  ide_setup_pci_noise(dev, d);
+//  ide_pci_setup_ports(dev, d, ide_hwifs[num].irq, &idx[num]);
+
+  ide_device_add(idx);
 }
 
 static void
 lths_remove_ide(int num)
 {
-  ide_unregister(num);
+    ide_unregister(num);
 }
 
 static void
@@ -528,7 +557,7 @@ lths_ide_notify(acpi_handle handle, u32 
   switch(event) {
   case ACPI_NOTIFY_EJECT_REQUEST:
     lths_printk(DEBUG_NORMAL, "Requesting IDE eject!\n");
-    acpi_bus_generate_event(device, event, 0);
+    acpi_bus_generate_proc_event(device, event, 0);
     if (auto_eject) { // FIXME perhaps a busy check?
       lths_h->eject(lths_h);
     }
@@ -538,7 +567,7 @@ lths_ide_notify(acpi_handle handle, u32 
       lths_scan_ide(lths_h->num);
     }
     lths_h->present = device->status.present;
-    acpi_bus_generate_event(device, event, device->status.present);
+    acpi_bus_generate_proc_event(device, event, device->status.present);
     break;
   default:
     lths_printk(DEBUG_NORMAL, "Unknown IDE event %08x\n", event);
@@ -582,10 +611,10 @@ lths_floppy_notify(acpi_handle handle, u
   switch(event) {
   case ACPI_NOTIFY_EJECT_REQUEST:
     lths_printk(DEBUG_NORMAL, "Requesting floppy eject!\n");
-    acpi_bus_generate_event(device, event, 0);
+    acpi_bus_generate_proc_event(device, event, 0);
     break;
   case ACPI_NOTIFY_DEVICE_CHECK:
-    acpi_bus_generate_event(device, event, device->status.present);
+    acpi_bus_generate_proc_event(device, event, device->status.present);
     break;
   default:
     lths_printk(DEBUG_NORMAL, "Unknown floppy event %08x\n", event);
@@ -685,15 +714,15 @@ lths_dock_notify(acpi_handle handle, u32
   switch(event) {
   case ACPI_NOTIFY_EJECT_REQUEST:
     lths_printk(DEBUG_NORMAL, "Requesting dock eject!\n");
-    acpi_bus_generate_event(device, event, 0);
+    acpi_bus_generate_proc_event(device, event, 0);
     break;
   case ACPI_NOTIFY_DEVICE_CHECK:
     lths_printk(DEBUG_NORMAL, "Dock device check\n");
-    acpi_bus_generate_event(device, event, device->status.present);
+    acpi_bus_generate_proc_event(device, event, device->status.present);
     break;
   case ACPI_NOTIFY_BUS_CHECK:
     lths_printk(DEBUG_NORMAL, "Dock bus check\n");
-    acpi_bus_generate_event(device, event, device->status.present);
+    acpi_bus_generate_proc_event(device, event, device->status.present);
     break;
   default:
     lths_printk(DEBUG_NORMAL, "Unknown dock event %08x\n", event);
@@ -807,51 +836,26 @@ module_init(lths_module_init);
 module_exit(lths_module_exit);
 
 
-static unsigned long ide_get_or_set_dma_base (ide_hwif_t *hwif)
+static unsigned long ide_get_or_set_dma_base(const struct ide_port_info *d, ide_hwif_t *hwif)
 {
 	unsigned long	dma_base = 0;
 	struct pci_dev	*dev = hwif->pci_dev;
 
-#ifdef CONFIG_BLK_DEV_IDEDMA_FORCED
-	int second_chance = 0;
-
-second_chance_to_dma:
-#endif /* CONFIG_BLK_DEV_IDEDMA_FORCED */
-
 	if (hwif->mmio)
 		return hwif->dma_base;
 
 	if (hwif->mate && hwif->mate->dma_base) {
 		dma_base = hwif->mate->dma_base - (hwif->channel ? 0 : 8);
 	} else {
-		dma_base = pci_resource_start(dev, 4);
-		if (!dma_base) {
-			printk(KERN_ERR "%s: dma_base is invalid\n",
-					hwif->cds->name);
-		}
-	}
+		u8 baridx = (d->host_flags & IDE_HFLAG_CS5520) ? 2 : 4;
 
-#ifdef CONFIG_BLK_DEV_IDEDMA_FORCED
-	/* FIXME - should use pci_assign_resource surely */
-	if ((!dma_base) && (!second_chance)) {
-		unsigned long set_bmiba = 0;
-		second_chance++;
-		switch(dev->vendor) {
-			case PCI_VENDOR_ID_AL:
-				set_bmiba = DEFAULT_BMALIBA; break;
-			case PCI_VENDOR_ID_VIA:
-				set_bmiba = DEFAULT_BMCRBA; break;
-			case PCI_VENDOR_ID_INTEL:
-				set_bmiba = DEFAULT_BMIBA; break;
-			default:
-				return dma_base;
-		}
-		pci_write_config_dword(dev, 0x20, set_bmiba|1);
-		goto second_chance_to_dma;
+		dma_base = pci_resource_start(dev, baridx);
+
+		if (dma_base == 0)
+			printk(KERN_ERR "%s: DMA base is invalid\n", d->name);
 	}
-#endif /* CONFIG_BLK_DEV_IDEDMA_FORCED */
 
-	if (dma_base) {
+	if ((d->host_flags & IDE_HFLAG_CS5520) == 0 && dma_base) {
 		u8 simplex_stat = 0;
 		dma_base += hwif->channel ? 8 : 0;
 
@@ -862,13 +866,13 @@ second_chance_to_dma:
 			case PCI_DEVICE_ID_CMD_643:
 			case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE:
 			case PCI_DEVICE_ID_REVOLUTION:
-				simplex_stat = hwif->INB(dma_base + 2);
-				hwif->OUTB((simplex_stat&0x60),(dma_base + 2));
-				simplex_stat = hwif->INB(dma_base + 2);
+				simplex_stat = inb(dma_base + 2);
+				outb(simplex_stat & 0x60, dma_base + 2);
+				simplex_stat = inb(dma_base + 2);
 				if (simplex_stat & 0x80) {
 					printk(KERN_INFO "%s: simplex device: "
-						"DMA forced\n",
-						hwif->cds->name);
+							 "DMA forced\n",
+							 d->name);
 				}
 				break;
 			default:
@@ -891,8 +895,8 @@ second_chance_to_dma:
  */
 					if (hwif->mate && hwif->mate->dma_base) {
 						printk(KERN_INFO "%s: simplex device: "
-							"DMA disabled\n",
-							hwif->cds->name);
+								 "DMA disabled\n",
+								 d->name);
 						dma_base = 0;
 					}
 				}
@@ -900,3 +904,41 @@ second_chance_to_dma:
 	}
 	return dma_base;
 }
+
+
+static void ide_hwif_setup_dma(struct pci_dev *dev, const struct ide_port_info *d, ide_hwif_t *hwif)
+{
+#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
+	u16 pcicmd;
+
+	pci_read_config_word(dev, PCI_COMMAND, &pcicmd);
+
+	if ((d->host_flags & IDE_HFLAG_NO_AUTODMA) == 0 ||
+	    ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE &&
+	     (dev->class & 0x80))) {
+		unsigned long dma_base = ide_get_or_set_dma_base(d, hwif);
+		if (dma_base && !(pcicmd & PCI_COMMAND_MASTER)) {
+			/*
+ 			 * Set up BM-DMA capability
+			 * (PnP BIOS should have done this)
+ 			 */
+			pci_set_master(dev);
+			if (pci_read_config_word(dev, PCI_COMMAND, &pcicmd) || !(pcicmd & PCI_COMMAND_MASTER)) {
+				printk(KERN_ERR "%s: %s error updating PCICMD\n",
+					hwif->name, d->name);
+				dma_base = 0;
+			}
+		}
+		if (dma_base) {
+			if (d->init_dma) {
+				d->init_dma(hwif, dma_base);
+			} else {
+				ide_setup_dma(hwif, dma_base, 8);
+			}
+		} else {
+			printk(KERN_INFO "%s: %s Bus-Master DMA disabled "
+				"(BIOS)\n", hwif->name, d->name);
+		}
+	}
+#endif /* CONFIG_BLK_DEV_IDEDMA_PCI*/
+}
