public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* ACPI + Floppy detection problem in 2.6.8.1-mm4
@ 2004-08-25  1:40 acyr
  2004-08-25  2:09 ` Aric Cyr
  0 siblings, 1 reply; 6+ messages in thread
From: acyr @ 2004-08-25  1:40 UTC (permalink / raw)
  To: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1122 bytes --]

Since patching from 2.6.8.1 to -mm4 I noticed that I can no longer
modprobe the floppy driver.  It is failing to detect the floppy drive
and controller it seems.  Looking at the output from dmesg I have
this:

[-snip-]
inserting floppy driver for 2.6.8.1-mm4
acpi_floppy_resource: 6 ioports at 0x3f0
acpi_floppy_resource: 1 ioports at 0x3f7
floppy: controller ACPI FDC0 at I/O 0x3f0-0x3f5, 0x3f7-0x3f7 irq 6 dma channel 2
Floppy drive(s): fd0 is 1.44M
floppy0: no floppy controllers found
[-snip-]

I saw in the -mm4 changelog that ACPI-based floppy detection was
added, which seems to be working, but the floppy driver doesn't seem
to think the controller/drive exists once the ACPI enumeration is
done.  I just noticed the no_acpi floppy module param in the source,
so I will give that a try.  Since the ACPI code seems to be picking up
the controller and drive just fine, I doubt this is limited to just my
system (i.e. my ACPI tables are screwy etc.).

-- 
Aric Cyr <acyr at alumni dot uwaterloo dot ca>    (http://acyr.net)
gpg fingerprint: 943A 1549 47AC D766 B7F8  D551 6703 7142 C282 D542

[-- Attachment #2: Type: application/pgp-signature, Size: 189 bytes --]

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: ACPI + Floppy detection problem in 2.6.8.1-mm4
  2004-08-25  1:40 ACPI + Floppy detection problem in 2.6.8.1-mm4 acyr
@ 2004-08-25  2:09 ` Aric Cyr
  0 siblings, 0 replies; 6+ messages in thread
From: Aric Cyr @ 2004-08-25  2:09 UTC (permalink / raw)
  To: linux-kernel

On Wed, Aug 25, 2004 at 10:40:28AM +0900, acyr@alumni.uwaterloo.ca wrote:
> done.  I just noticed the no_acpi floppy module param in the source,
> so I will give that a try.  Since the ACPI code seems to be picking up

I just tried the no_acpi module param and the floppy driver loads and
works just fine, so this is indeed an ACPI related.

-- 
Aric Cyr <acyr at alumni dot uwaterloo dot ca>    (http://acyr.net)
gpg fingerprint: 943A 1549 47AC D766 B7F8  D551 6703 7142 C282 D542

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: ACPI + Floppy detection problem in 2.6.8.1-mm4
       [not found] <20040825002220.4867cd17.akpm@osdl.org>
@ 2004-08-25 16:28 ` Bjorn Helgaas
  2004-08-25 20:24   ` Bjorn Helgaas
  0 siblings, 1 reply; 6+ messages in thread
From: Bjorn Helgaas @ 2004-08-25 16:28 UTC (permalink / raw)
  To: acyr; +Cc: linux-kernel, Petr Vandrovec

> inserting floppy driver for 2.6.8.1-mm4
> acpi_floppy_resource: 6 ioports at 0x3f0
> acpi_floppy_resource: 1 ioports at 0x3f7
> floppy: controller ACPI FDC0 at I/O 0x3f0-0x3f5, 0x3f7-0x3f7 irq 6 dma channel 2
> Floppy drive(s): fd0 is 1.44M
> floppy0: no floppy controllers found

Yup, the current -mm4 code assumes that if you have 6 ports in
the first region, they are 0x3f2-0x3f7.  But your BIOS reports
6 ports at 0x3f0-0x3f5.

So I guess we'll have to do something like Petr's approach of
ignoring the low three bits.  Thanks for the report.  I'll send
you a patch to try shortly.

Bjorn

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: ACPI + Floppy detection problem in 2.6.8.1-mm4
  2004-08-25 16:28 ` Bjorn Helgaas
@ 2004-08-25 20:24   ` Bjorn Helgaas
  2004-08-26  7:04     ` Aric Cyr
  0 siblings, 1 reply; 6+ messages in thread
From: Bjorn Helgaas @ 2004-08-25 20:24 UTC (permalink / raw)
  To: acyr; +Cc: linux-kernel, Petr Vandrovec, Len Brown

> > inserting floppy driver for 2.6.8.1-mm4
> > acpi_floppy_resource: 6 ioports at 0x3f0
> > acpi_floppy_resource: 1 ioports at 0x3f7
> > floppy: controller ACPI FDC0 at I/O 0x3f0-0x3f5, 0x3f7-0x3f7 irq 6 dma channel 2
> > Floppy drive(s): fd0 is 1.44M
> > floppy0: no floppy controllers found

Aric and Petr, can you give this patch a try?  It's a replacement for the
one currently in 2.6.8.1-mm4.  I adopted Petr's strategy of just clearing
the low three bits of the first I/O port region, and also his module
unload fixes.

I also added a couple validity checks (for firmware that doesn't
report 0x3f7 or reports 0x3f0 or 0x3f6), and made them ignore the
device altogether if "acpi=strict".  Any comments on that, Len?


Add ACPI-based floppy controller enumeration.

This can be disabled with "floppy=no_acpi", which should only be
required if your BIOS supplies incorrect ACPI _CRS information about
I/O ports, IRQs, or DMA channels.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>

===== Documentation/floppy.txt 1.1 vs edited =====
--- 1.1/Documentation/floppy.txt	2002-02-05 10:40:38 -07:00
+++ edited/Documentation/floppy.txt	2004-08-18 15:41:37 -06:00
@@ -187,6 +187,11 @@
 	   It's been recommended that take about 1/4 of the default speed
 	   in some more extreme cases."
 
+ floppy=no_acpi
+	Don't enumerate floppy controllers using ACPI namespace.
+	You may need this if your ACPI is buggy and reports incorrect
+	I/O port, IRQ, or DMA information.
+
 
 
 Supporting utilities and additional documentation:
===== drivers/block/floppy.c 1.103 vs edited =====
--- 1.103/drivers/block/floppy.c	2004-08-02 02:00:45 -06:00
+++ edited/drivers/block/floppy.c	2004-08-25 13:43:33 -06:00
@@ -181,6 +181,13 @@
 #include <linux/device.h>
 #include <linux/buffer_head.h>	/* for invalidate_buffers() */
 
+#ifdef CONFIG_ACPI_BUS
+#include <linux/acpi.h>
+#include <acpi/acpi_bus.h>
+
+static int no_acpi_floppy;
+#endif
+
 /*
  * PS/2 floppies have much slower step rates than regular floppies.
  * It's been recommended that take about 1/4 of the default speed
@@ -4150,6 +4157,9 @@
 	{"slow", NULL, &slow_floppy, 1, 0},
 	{"unexpected_interrupts", NULL, &print_unex, 1, 0},
 	{"no_unexpected_interrupts", NULL, &print_unex, 0, 0},
+#ifdef CONFIG_ACPI_BUS
+	{"no_acpi", NULL, &no_acpi_floppy, 1, 0},
+#endif
 	{"L40SX", NULL, &print_unex, 0, 0}
 
 	EXTRA_FLOPPY_PARAMS
@@ -4222,11 +4232,192 @@
 	return get_disk(disks[drive]);
 }
 
+#ifdef CONFIG_ACPI_BUS
+static int acpi_floppy_registered;
+static int acpi_floppies;
+
+struct region {
+	unsigned int base;
+	unsigned int size;
+};
+
+struct floppy_resources {
+	unsigned int nr_io_regions;
+	struct region io_region[2];
+	unsigned int irq;
+	unsigned int dma_channel;
+};
+
+static acpi_status acpi_floppy_resource(struct acpi_resource *res, void *data)
+{
+	struct floppy_resources *fd = (struct floppy_resources *) data;
+	struct acpi_resource_io *io;
+	struct acpi_resource_irq *irq;
+	struct acpi_resource_ext_irq *ext_irq;
+	struct acpi_resource_dma *dma;
+	int n;
+
+	if (res->id == ACPI_RSTYPE_IO) {
+		io = &res->data.io;
+		if (io->range_length) {
+			n = fd->nr_io_regions;
+			if (n < 2) {
+				fd->io_region[n].base = io->min_base_address;
+				fd->io_region[n].size = io->range_length;
+				fd->nr_io_regions++;
+			} else {
+				printk(KERN_WARNING "%s: ignoring I/O port region 0x%x-0x%x\n",
+					DEVICE_NAME, io->min_base_address,
+					io->min_base_address + io->range_length - 1);
+			}
+		}
+	} else if (res->id == ACPI_RSTYPE_IRQ) {
+		irq = &res->data.irq;
+		if (irq->number_of_interrupts > 0)
+			fd->irq = acpi_register_gsi(irq->interrupts[0],
+				irq->edge_level, irq->active_high_low);
+	} else if (res->id == ACPI_RSTYPE_EXT_IRQ) {
+		ext_irq = &res->data.extended_irq;
+		if (ext_irq->number_of_interrupts > 0)
+			fd->irq = acpi_register_gsi(ext_irq->interrupts[0],
+				ext_irq->edge_level, ext_irq->active_high_low);
+	} else if (res->id == ACPI_RSTYPE_DMA) {
+		dma = &res->data.dma;
+		if (dma->number_of_channels > 0)
+			fd->dma_channel = dma->channels[0];
+	}
+	return AE_OK;
+}
+
+static int acpi_floppy_add(struct acpi_device *device)
+{
+	struct floppy_resources fd;
+	acpi_status status;
+	unsigned int base, dcr, ide;
+
+	memset(&fd, 0, sizeof(fd));
+	status = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
+		acpi_floppy_resource, &fd);
+	if (ACPI_FAILURE(status))
+		return -ENODEV;
+
+	printk("%s: controller ACPI %s at I/O 0x%x-0x%x",
+		DEVICE_NAME, device->pnp.bus_id, fd.io_region[0].base,
+		fd.io_region[0].base + fd.io_region[0].size - 1);
+	if (fd.nr_io_regions > 1) {
+		if (fd.io_region[1].size == 1)
+			printk(", 0x%x", fd.io_region[1].base);
+		else
+			printk(", 0x%x-0x%x", fd.io_region[1].base,
+				fd.io_region[1].base + fd.io_region[1].size - 1);
+	}
+	printk(" irq %d dma channel %d\n", fd.irq, fd.dma_channel);
+
+	/*
+	 * The most correct resource description is probably of the form
+	 *    0x3f2-0x3f5, 0x3f7
+	 * Those are the only ports this driver actually uses.
+	 *
+	 * 0x3f0 and 0x3f1 were apparently used on PS/2 systems (though
+	 * this driver doesn't touch them), and 0x3f6 is used by IDE.
+	 * Some BIOS's erroneously include those ports, or omit 0x3f7,
+	 * so we should also be able to handle the following:
+	 *    0x3f0-0x3f5
+	 *    0x3f0-0x3f5, 0x3f7
+	 *    0x3f0-0x3f7
+	 *    0x3f2-0x3f7
+	 */
+	base = fd.io_region[0].base & ~0x7;
+	ide = base + 6;
+	dcr = base + 7;
+
+#define contains(region, port)	((region).base <= (port) && \
+				 (port) < (region).base + (region).size)
+
+	if (!(contains(fd.io_region[0], dcr) || contains(fd.io_region[1], dcr))) {
+		printk(KERN_WARNING "%s: %s _CRS doesn't include FD_DCR; assuming 0x%x\n",
+			DEVICE_NAME, device->pnp.bus_id, dcr);
+		if (acpi_strict)
+			return -ENODEV;
+	}
+
+	if (contains(fd.io_region[0], base)) {
+		printk(KERN_WARNING "%s: %s _CRS erroneously includes 0x%x\n",
+			DEVICE_NAME, device->pnp.bus_id, base);
+		if (acpi_strict)
+			return -ENODEV;
+	}
+
+	if (contains(fd.io_region[0], ide)) {
+		printk(KERN_WARNING "%s: %s _CRS erroneously includes 0x%x\n",
+			DEVICE_NAME, device->pnp.bus_id, ide);
+		if (acpi_strict)
+			return -ENODEV;
+	}
+
+#undef contains
+
+	if (acpi_floppies == 0) {
+		FDC1 = base;
+		FLOPPY_IRQ = fd.irq;
+		FLOPPY_DMA = fd.dma_channel;
+	} else if (acpi_floppies == 1) {
+		FDC2 = base;
+		if (fd.irq != FLOPPY_IRQ || fd.dma_channel != FLOPPY_DMA)
+			printk(KERN_WARNING "%s: different IRQ/DMA info for %s; may not work\n",
+				DEVICE_NAME, device->pnp.bus_id);
+	} else {
+		printk(KERN_ERR "%s: only 2 controllers supported; %s ignored\n",
+			DEVICE_NAME, device->pnp.bus_id);
+		return -ENODEV;
+	}
+
+	acpi_floppies++;
+	return 0;
+}
+
+static struct acpi_driver acpi_floppy_driver = {
+	.name	= "floppy",
+	.ids	= "PNP0700",
+	.ops	= {
+		.add	= acpi_floppy_add,
+	},
+};
+
+static int acpi_floppy_init(void)
+{
+	int err;
+
+	if (no_acpi_floppy)
+		return -ENODEV;
+	err = acpi_bus_register_driver(&acpi_floppy_driver);
+	if (err >= 0)
+		acpi_floppy_registered = 1;
+	return err;
+}
+
+static void acpi_floppy_exit(void)
+{
+	if (acpi_floppy_registered) {
+		acpi_bus_unregister_driver(&acpi_floppy_driver);
+		acpi_floppy_registered = 0;
+	}
+}
+#else
+static int  acpi_floppy_init(void) { return -ENODEV; }
+static void acpi_floppy_stop(void) { }
+#endif
+
 int __init floppy_init(void)
 {
 	int i, unit, drive;
 	int err, dr;
 
+	if (acpi_floppy_init() == 0) {
+		err = -ENODEV;
+		goto out_put_acpi;
+	}
+
 	raw_cmd = NULL;
 
 	for (dr = 0; dr < N_DRIVE; dr++) {
@@ -4404,6 +4595,8 @@
 		del_timer(&motor_off_timer[dr]);
 		put_disk(disks[dr]);
 	}
+out_put_acpi:
+	acpi_floppy_exit();
 	return err;
 }
 
@@ -4619,6 +4812,8 @@
 
 	/* eject disk, if any */
 	fd_eject(0);
+
+	acpi_floppy_exit();
 
 	wait_for_completion(&device_release);
 }

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: ACPI + Floppy detection problem in 2.6.8.1-mm4
  2004-08-25 20:24   ` Bjorn Helgaas
@ 2004-08-26  7:04     ` Aric Cyr
  2004-08-26 16:17       ` Bjorn Helgaas
  0 siblings, 1 reply; 6+ messages in thread
From: Aric Cyr @ 2004-08-26  7:04 UTC (permalink / raw)
  To: Bjorn Helgaas; +Cc: linux-kernel, Petr Vandrovec, Len Brown

On Wed, Aug 25, 2004 at 02:24:43PM -0600, Bjorn Helgaas wrote:
> > > inserting floppy driver for 2.6.8.1-mm4
> > > acpi_floppy_resource: 6 ioports at 0x3f0
> > > acpi_floppy_resource: 1 ioports at 0x3f7
> > > floppy: controller ACPI FDC0 at I/O 0x3f0-0x3f5, 0x3f7-0x3f7 irq 6 dma channel 2
> > > Floppy drive(s): fd0 is 1.44M
> > > floppy0: no floppy controllers found
> 
> Aric and Petr, can you give this patch a try?  It's a replacement for the
> one currently in 2.6.8.1-mm4.  I adopted Petr's strategy of just clearing
> the low three bits of the first I/O port region, and also his module
> unload fixes.

Great! Seems to work now:

[-snip-]
inserting floppy driver for 2.6.8.1-mm4
floppy: controller ACPI FDC0 at I/O 0x3f0-0x3f5, 0x3f7 irq 6 dma
channel 2
floppy: FDC0 _CRS erroneously includes 0x3f0
Floppy drive(s): fd0 is 1.44M
FDC 0 is a post-1991 82077
[-snip-]

I'm not sure if that warning is really necessary or not, but for debug
purposes it is not a problem.  As such, might want to consider change
that message to a KERNEL_DEBUG.  Not really a big issue though I
guess.  I just don't like the word "erroneously" in my kernel logs
each time I boot :)

> I also added a couple validity checks (for firmware that doesn't
> report 0x3f7 or reports 0x3f0 or 0x3f6), and made them ignore the
> device altogether if "acpi=strict".  Any comments on that, Len?

I have to remove the acpi_strict code that you added in order to get
the driver to load.  I am using it as a module, and the acpi_strict
symbol does not seem to be exported by the kernel.  Since I am not
using the acpi=strict flag anyways, I just killed the related 6 lines
from your patch before applying it.  I'm sure it would have been fine
had I compiled the driver into the kernel, but as it stands now the
acpi_strict variable would need to be exported I guess.

-- 
Aric Cyr <acyr at alumni dot uwaterloo dot ca>    (http://acyr.net)
gpg fingerprint: 943A 1549 47AC D766 B7F8  D551 6703 7142 C282 D542

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: ACPI + Floppy detection problem in 2.6.8.1-mm4
  2004-08-26  7:04     ` Aric Cyr
@ 2004-08-26 16:17       ` Bjorn Helgaas
  0 siblings, 0 replies; 6+ messages in thread
From: Bjorn Helgaas @ 2004-08-26 16:17 UTC (permalink / raw)
  To: Aric Cyr, Andrew Morton
  Cc: linux-kernel, Petr Vandrovec, Len Brown, Bjorn Helgaas

OK, here's something that I think should be suitable for the next -mm
patchset.

We report exactly what ACPI tells us about I/O port regions.  We mask
off the low three bits of the first region, so we can handle all the
reasonable ACPI weirdnesses.  We warn only about the case where we claim
a port ACPI didn't tell us about.  All the acpi_strict stuff is gone,
at least for now.  The module unload stuff should be fixed.


Add ACPI-based floppy controller enumeration.

This can be disabled with "floppy=no_acpi", which should only be
required if your BIOS supplies incorrect ACPI _CRS information about
I/O ports, IRQs, or DMA channels.

Signed-off-by: Bjorn Helgaas <bjorn.helgaas@hp.com>

===== Documentation/floppy.txt 1.1 vs edited =====
--- 1.1/Documentation/floppy.txt	2002-02-05 10:40:38 -07:00
+++ edited/Documentation/floppy.txt	2004-08-26 10:01:51 -06:00
@@ -187,6 +187,12 @@
 	   It's been recommended that take about 1/4 of the default speed
 	   in some more extreme cases."
 
+ floppy=no_acpi
+	Don't enumerate floppy controllers using ACPI namespace.
+	You may need this if your ACPI is buggy and doesn't report
+	a floppy controller when it actually exists, or if it
+	reports incorrect I/O port, IRQ, or DMA information.
+
 
 
 Supporting utilities and additional documentation:
===== drivers/block/floppy.c 1.103 vs edited =====
--- 1.103/drivers/block/floppy.c	2004-08-02 02:00:45 -06:00
+++ edited/drivers/block/floppy.c	2004-08-26 10:08:58 -06:00
@@ -181,6 +181,13 @@
 #include <linux/device.h>
 #include <linux/buffer_head.h>	/* for invalidate_buffers() */
 
+#ifdef CONFIG_ACPI_BUS
+#include <linux/acpi.h>
+#include <acpi/acpi_bus.h>
+
+static int no_acpi_floppy;
+#endif
+
 /*
  * PS/2 floppies have much slower step rates than regular floppies.
  * It's been recommended that take about 1/4 of the default speed
@@ -4150,6 +4157,9 @@
 	{"slow", NULL, &slow_floppy, 1, 0},
 	{"unexpected_interrupts", NULL, &print_unex, 1, 0},
 	{"no_unexpected_interrupts", NULL, &print_unex, 0, 0},
+#ifdef CONFIG_ACPI_BUS
+	{"no_acpi", NULL, &no_acpi_floppy, 1, 0},
+#endif
 	{"L40SX", NULL, &print_unex, 0, 0}
 
 	EXTRA_FLOPPY_PARAMS
@@ -4222,11 +4232,175 @@
 	return get_disk(disks[drive]);
 }
 
+#ifdef CONFIG_ACPI_BUS
+static int acpi_floppy_registered;
+static int acpi_floppies;
+
+struct region {
+	unsigned int base;
+	unsigned int size;
+};
+
+struct floppy_resources {
+	unsigned int nr_io_regions;
+	struct region io_region[2];
+	unsigned int irq;
+	unsigned int dma_channel;
+};
+
+static acpi_status acpi_floppy_resource(struct acpi_resource *res, void *data)
+{
+	struct floppy_resources *fd = (struct floppy_resources *) data;
+	struct acpi_resource_io *io;
+	struct acpi_resource_irq *irq;
+	struct acpi_resource_ext_irq *ext_irq;
+	struct acpi_resource_dma *dma;
+	int n;
+
+	if (res->id == ACPI_RSTYPE_IO) {
+		io = &res->data.io;
+		if (io->range_length) {
+			n = fd->nr_io_regions;
+			if (n < 2) {
+				fd->io_region[n].base = io->min_base_address;
+				fd->io_region[n].size = io->range_length;
+				fd->nr_io_regions++;
+			} else {
+				printk(KERN_WARNING "%s: ignoring I/O port region 0x%x-0x%x\n",
+					DEVICE_NAME, io->min_base_address,
+					io->min_base_address + io->range_length - 1);
+			}
+		}
+	} else if (res->id == ACPI_RSTYPE_IRQ) {
+		irq = &res->data.irq;
+		if (irq->number_of_interrupts > 0)
+			fd->irq = acpi_register_gsi(irq->interrupts[0],
+				irq->edge_level, irq->active_high_low);
+	} else if (res->id == ACPI_RSTYPE_EXT_IRQ) {
+		ext_irq = &res->data.extended_irq;
+		if (ext_irq->number_of_interrupts > 0)
+			fd->irq = acpi_register_gsi(ext_irq->interrupts[0],
+				ext_irq->edge_level, ext_irq->active_high_low);
+	} else if (res->id == ACPI_RSTYPE_DMA) {
+		dma = &res->data.dma;
+		if (dma->number_of_channels > 0)
+			fd->dma_channel = dma->channels[0];
+	}
+	return AE_OK;
+}
+
+static int acpi_floppy_add(struct acpi_device *device)
+{
+	struct floppy_resources fd;
+	acpi_status status;
+	unsigned int base, dcr;
+
+	memset(&fd, 0, sizeof(fd));
+	status = acpi_walk_resources(device->handle, METHOD_NAME__CRS,
+		acpi_floppy_resource, &fd);
+	if (ACPI_FAILURE(status))
+		return -ENODEV;
+
+	printk("%s: controller ACPI %s at I/O 0x%x-0x%x",
+		DEVICE_NAME, device->pnp.bus_id, fd.io_region[0].base,
+		fd.io_region[0].base + fd.io_region[0].size - 1);
+	if (fd.nr_io_regions > 1) {
+		if (fd.io_region[1].size == 1)
+			printk(", 0x%x", fd.io_region[1].base);
+		else
+			printk(", 0x%x-0x%x", fd.io_region[1].base,
+				fd.io_region[1].base + fd.io_region[1].size - 1);
+	}
+	printk(" irq %d dma channel %d\n", fd.irq, fd.dma_channel);
+
+	/*
+	 * The most correct resource description is probably of the form
+	 *    0x3f2-0x3f5, 0x3f7
+	 * Those are the only ports this driver actually uses.
+	 *
+	 * 0x3f0 and 0x3f1 were apparently used on PS/2 systems (though
+	 * this driver doesn't touch them), and 0x3f6 is used by IDE.
+	 * Some BIOS's erroneously include those ports, or omit 0x3f7,
+	 * so we should also be able to handle the following:
+	 *    0x3f0-0x3f5
+	 *    0x3f0-0x3f5, 0x3f7
+	 *    0x3f0-0x3f7
+	 *    0x3f2-0x3f7
+	 */
+	base = fd.io_region[0].base & ~0x7;
+	dcr = base + 7;
+
+#define contains(region, port)	((region).base <= (port) && \
+				 (port) < (region).base + (region).size)
+
+	if (!(contains(fd.io_region[0], dcr) || contains(fd.io_region[1], dcr))) {
+		printk(KERN_WARNING "%s: %s _CRS doesn't include FD_DCR; also claiming 0x%x\n",
+			DEVICE_NAME, device->pnp.bus_id, dcr);
+	}
+
+#undef contains
+
+	if (acpi_floppies == 0) {
+		FDC1 = base;
+		FLOPPY_IRQ = fd.irq;
+		FLOPPY_DMA = fd.dma_channel;
+	} else if (acpi_floppies == 1) {
+		FDC2 = base;
+		if (fd.irq != FLOPPY_IRQ || fd.dma_channel != FLOPPY_DMA)
+			printk(KERN_WARNING "%s: different IRQ/DMA info for %s; may not work\n",
+				DEVICE_NAME, device->pnp.bus_id);
+	} else {
+		printk(KERN_ERR "%s: only 2 controllers supported; %s ignored\n",
+			DEVICE_NAME, device->pnp.bus_id);
+		return -ENODEV;
+	}
+
+	acpi_floppies++;
+	return 0;
+}
+
+static struct acpi_driver acpi_floppy_driver = {
+	.name	= "floppy",
+	.ids	= "PNP0700",
+	.ops	= {
+		.add	= acpi_floppy_add,
+	},
+};
+
+static int acpi_floppy_init(void)
+{
+	int err;
+
+	if (no_acpi_floppy)
+		return -ENODEV;
+	err = acpi_bus_register_driver(&acpi_floppy_driver);
+	if (err >= 0)
+		acpi_floppy_registered = 1;
+	return err;
+}
+
+static void acpi_floppy_exit(void)
+{
+	if (acpi_floppy_registered) {
+		acpi_bus_unregister_driver(&acpi_floppy_driver);
+		acpi_floppy_registered = 0;
+	}
+}
+#else
+static int  acpi_floppy_init(void) { return -ENODEV; }
+static void acpi_floppy_stop(void) { }
+#endif
+
 int __init floppy_init(void)
 {
 	int i, unit, drive;
 	int err, dr;
 
+	if (acpi_floppy_init() == 0) {
+		err = -ENODEV;
+		goto out_put_acpi;
+	}
+
 	raw_cmd = NULL;
 
 	for (dr = 0; dr < N_DRIVE; dr++) {
@@ -4404,6 +4578,8 @@
 		del_timer(&motor_off_timer[dr]);
 		put_disk(disks[dr]);
 	}
+out_put_acpi:
+	acpi_floppy_exit();
 	return err;
 }
 
@@ -4619,6 +4795,8 @@
 
 	/* eject disk, if any */
 	fd_eject(0);
+
+	acpi_floppy_exit();
 
 	wait_for_completion(&device_release);
 }

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2004-08-26 16:28 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-08-25  1:40 ACPI + Floppy detection problem in 2.6.8.1-mm4 acyr
2004-08-25  2:09 ` Aric Cyr
     [not found] <20040825002220.4867cd17.akpm@osdl.org>
2004-08-25 16:28 ` Bjorn Helgaas
2004-08-25 20:24   ` Bjorn Helgaas
2004-08-26  7:04     ` Aric Cyr
2004-08-26 16:17       ` Bjorn Helgaas

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox