patch-2.1.115 linux/include/asm-sparc64/floppy.h

Next file: linux/include/asm-sparc64/fpumacro.h
Previous file: linux/include/asm-sparc64/firehose.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.114/linux/include/asm-sparc64/floppy.h linux/include/asm-sparc64/floppy.h
@@ -1,4 +1,4 @@
-/* $Id: floppy.h,v 1.7 1997/09/07 03:34:08 davem Exp $
+/* $Id: floppy.h,v 1.11 1998/05/22 14:33:39 jj Exp $
  * asm-sparc64/floppy.h: Sparc specific parts of the Floppy driver.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -11,6 +11,7 @@
 #define __ASM_SPARC64_FLOPPY_H
 
 #include <linux/config.h>
+#include <linux/init.h>
 
 #include <asm/page.h>
 #include <asm/pgtable.h>
@@ -39,7 +40,7 @@
 #define dcr_82077              dir_82077      /* Config Control reg. */
 };
 
-/* You'll only ever find one controller on a SparcStation anyways. */
+/* You'll only ever find one controller on an Ultra anyways. */
 static struct sun_flpy_controller *sun_fdc = NULL;
 volatile unsigned char *fdc_status;
 static struct linux_sbus_device *floppy_sdev = NULL;
@@ -216,21 +217,10 @@
 	int error;
 
 	if(!once) {
-		struct devid_cookie dcookie;
-
 		once = 1;
 
-		dcookie.real_dev_id = NULL;
-		dcookie.imap = dcookie.iclr = 0;
-		dcookie.pil = -1;
-		dcookie.bus_cookie = floppy_sdev->my_bus;
-
-		error = request_fast_irq(FLOPPY_IRQ, floppy_hardint,
-					 (SA_INTERRUPT | SA_SBUS | SA_DCOOKIE),
-					 "floppy", &dcookie);
-
-		if(error == 0)
-			FLOPPY_IRQ = dcookie.ret_ino;
+		error = request_fast_irq(FLOPPY_IRQ, floppy_hardint, 
+					SA_INTERRUPT, "floppy", NULL);
 
 		return ((error == 0) ? 0 : -1);
 	}
@@ -281,29 +271,45 @@
 	outb(val, port);
 }
 
-static void sun_pci_fd_enable_dma(void)
+static void sun_pci_fd_reset_dma(void)
 {
 	unsigned int dcsr;
 
-	dcsr = readl((unsigned long)&sun_fd_ebus_dma->dcsr);
-	dcsr |= (EBUS_DCSR_EN_DMA | EBUS_DCSR_EN_CNT);
+	writel(EBUS_DCSR_RESET, &sun_fd_ebus_dma->dcsr);
+
+	dcsr = EBUS_DCSR_BURST_SZ_16 | EBUS_DCSR_TCI_DIS |
+	       EBUS_DCSR_EN_CNT | EBUS_DCSR_INT_EN;
 	writel(dcsr, (unsigned long)&sun_fd_ebus_dma->dcsr);
 }
 
+static void sun_pci_fd_enable_dma(void)
+{
+	unsigned int dcsr;
+
+	dcsr = readl(&sun_fd_ebus_dma->dcsr);
+	dcsr |= EBUS_DCSR_EN_DMA;
+	writel(dcsr, &sun_fd_ebus_dma->dcsr);
+}
+
 static void sun_pci_fd_disable_dma(void)
 {
 	unsigned int dcsr;
 
-	dcsr = readl((unsigned long)&sun_fd_ebus_dma->dcsr);
-	dcsr &= ~(EBUS_DCSR_EN_DMA | EBUS_DCSR_EN_CNT);
-	writel(dcsr, (unsigned long)&sun_fd_ebus_dma->dcsr);
+	dcsr = readl(&sun_fd_ebus_dma->dcsr);
+	while (dcsr & EBUS_DCSR_DRAIN)
+		dcsr = readl(&sun_fd_ebus_dma->dcsr);
+	dcsr &= ~(EBUS_DCSR_EN_DMA);
+	if (dcsr & EBUS_DCSR_ERR_PEND)
+		sun_pci_fd_reset_dma();
+	writel(dcsr, &sun_fd_ebus_dma->dcsr);
 }
 
 static void sun_pci_fd_set_dma_mode(int mode)
 {
 	unsigned int dcsr;
 
-	dcsr = readl((unsigned long)&sun_fd_ebus_dma->dcsr);
+	dcsr = readl(&sun_fd_ebus_dma->dcsr);
+	dcsr |= EBUS_DCSR_EN_CNT | EBUS_DCSR_TC;
 	/*
 	 * For EBus WRITE means to system memory, which is
 	 * READ for us.
@@ -312,61 +318,61 @@
 		dcsr &= ~(EBUS_DCSR_WRITE);
 	else
 		dcsr |= EBUS_DCSR_WRITE;
-	writel(dcsr, (unsigned long)&sun_fd_ebus_dma->dcsr);
+	writel(dcsr, &sun_fd_ebus_dma->dcsr);
 }
 
 static void sun_pci_fd_set_dma_count(int length)
 {
-	writel(length, (unsigned long)&sun_fd_ebus_dma->dbcr);
+	writel(length, &sun_fd_ebus_dma->dbcr);
 }
 
 static void sun_pci_fd_set_dma_addr(char *buffer)
 {
-	unsigned int addr;
+	unsigned int addr = virt_to_bus(buffer);
+	writel(addr, &sun_fd_ebus_dma->dacr);
+}
 
-	addr = virt_to_bus(buffer);
-	writel(addr, (unsigned long)&sun_fd_ebus_dma->dacr);
+static unsigned int sun_pci_get_dma_residue(void)
+{
+	return readl(&sun_fd_ebus_dma->dbcr);
 }
 
 static void sun_pci_fd_enable_irq(void)
 {
 	unsigned int dcsr;
 
-	dcsr = readl((unsigned long)&sun_fd_ebus_dma->dcsr);
+	dcsr = readl(&sun_fd_ebus_dma->dcsr);
 	dcsr |= EBUS_DCSR_INT_EN;
-	writel(dcsr, (unsigned long)&sun_fd_ebus_dma->dcsr);
+	writel(dcsr, &sun_fd_ebus_dma->dcsr);
 }
 
 static void sun_pci_fd_disable_irq(void)
 {
 	unsigned int dcsr;
 
-	dcsr = readl((unsigned long)&sun_fd_ebus_dma->dcsr);
+	dcsr = readl(&sun_fd_ebus_dma->dcsr);
 	dcsr &= ~(EBUS_DCSR_INT_EN);
-	writel(dcsr, (unsigned long)&sun_fd_ebus_dma->dcsr);
+	writel(dcsr, &sun_fd_ebus_dma->dcsr);
 }
 
 static int sun_pci_fd_request_irq(void)
 {
-	int error;
+	int err;
 
-	error = request_irq(FLOPPY_IRQ, floppy_interrupt, SA_SHIRQ, "floppy", sun_fdc);
-	return ((error == 0) ? 0 : -1);
+	err = request_irq(FLOPPY_IRQ, floppy_interrupt, SA_SHIRQ,
+			  "floppy", sun_fdc);
+	if (err)
+		return -1;
+	sun_pci_fd_enable_irq();
+	return 0;
 }
 
 static void sun_pci_fd_free_irq(void)
 {
+	sun_pci_fd_disable_irq();
 	free_irq(FLOPPY_IRQ, sun_fdc);
 }
 
-static unsigned int sun_pci_get_dma_residue(void)
-{
-	unsigned int res;
-
-	res = readl((unsigned long)&sun_fd_ebus_dma->dbcr);
-	return res;
-}
-
 static int sun_pci_fd_eject(int drive)
 {
 	return -EINVAL;
@@ -375,7 +381,7 @@
 
 static struct linux_prom_registers fd_regs[2];
 
-static unsigned long sun_floppy_init(void)
+__initfunc(static unsigned long sun_floppy_init(void))
 {
 	char state[128];
 	int fd_node, num_regs;
@@ -388,19 +394,26 @@
 	}
 	if(sdev) {
 		floppy_sdev = sdev;
-		FLOPPY_IRQ = sdev->irqs[0].pri;
+		FLOPPY_IRQ = sdev->irqs[0];
 	} else {
 #ifdef CONFIG_PCI
 		struct linux_ebus *ebus;
-		struct linux_ebus_device *edev;
+		struct linux_ebus_device *edev = 0;
 
-		for_all_ebusdev(edev, ebus) {
-			if (!strcmp(edev->prom_name, "fdthree"))
-				break;
+		for_each_ebus(ebus) {
+			for_each_ebusdev(edev, ebus) {
+				if (!strcmp(edev->prom_name, "fdthree"))
+					goto ebus_done;
+			}
 		}
+	ebus_done:
 		if (!edev)
 			return -1;
 
+		prom_getproperty(edev->prom_node, "status", state, sizeof(state));
+		if(!strncmp(state, "disabled", 8))
+			return -1;
+			
 		if (check_region(edev->base_address[1], sizeof(struct linux_ebus_dma))) {
 			printk("sun_floppy_init: can't get region %016lx (%d)\n",
 			       edev->base_address[1], (int)sizeof(struct linux_ebus_dma));
@@ -412,7 +425,7 @@
 		FLOPPY_IRQ = edev->irqs[0];
 
 		sun_fd_ebus_dma = (struct linux_ebus_dma *)edev->base_address[1];
-		writel(EBUS_DCSR_BURST_SZ_16, (unsigned long)&sun_fd_ebus_dma->dcsr);
+		sun_pci_fd_reset_dma();
 
 		sun_fdops.fd_inb = sun_pci_fd_inb;
 		sun_fdops.fd_outb = sun_pci_fd_outb;
@@ -447,12 +460,11 @@
 	num_regs = prom_getproperty(fd_node, "reg", (char *) fd_regs, sizeof(fd_regs));
 	num_regs = (num_regs / sizeof(fd_regs[0]));
 	prom_apply_sbus_ranges(sdev->my_bus, fd_regs, num_regs, sdev);
-	sun_fdc = (struct sun_flpy_controller *) sparc_alloc_io(fd_regs[0].phys_addr,
-								0x0,
-								fd_regs[0].reg_size,
-								"floppy",
-								fd_regs[0].which_io,
-								0x0);
+	/* We cannot do sparc_alloc_io here: it does request_region, which is the generic
+	   floppy driver trying to do once again */
+	sun_fdc = (struct sun_flpy_controller *) (PAGE_OFFSET + fd_regs[0].phys_addr + 
+							(((unsigned long)fd_regs[0].which_io) << 32));
+
 	/* Last minute sanity check... */
 	if(sun_fdc->status1_82077 == 0xff) {
 		sun_fdc = NULL;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov