Re: [RFT][PATCH] Poke ACPI about connected floppy drives

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




thanks,
Len Brown, Intel Open Source Technology Center

On Mon, 22 Nov 2010, Kyle McMartin wrote:

> I've gotten a few complaints because I removed the floppy module
> modaliases in Fedora, which means people with ancient junk need
> to manually probe it. (Some modern machines spend a good few seconds
> probing non-existant floppy drives otherwise.)
> 
> Re-organize floppy.ko a bit to allow us to, in the case of CONFIG_ACPI,
> poke the ACPI _FDE object to see how many floppy drives are connected,
> and not bother probing if there are none.
> 
> I'd appreciate it if people could test this patch, and let me know how
> many floppy drives they actually have, versus how many are reported
> from the ACPI object. My 965-era Asus lies through its teeth about the
> table, so I'm not entirely convinced this method is tenable, but it's my
> olive branch to the floppy users.
> 
> If !CONFIG_ACPI, it should have the ordinary pnp ids and bind that way.

(adding linux-acpi list)

I've got two machines handy that have a floppy drive,
an Intel D975XBX2 (Core2 extreme desktop motherboard)
supermicro X7DB8 (Core2 Dual Xeon workstation)

Both of them have PNP PNP0700 devices present in their DSDT.
However, neither implement the _FDE method.

I have 45 DSDTs on-hand that include PNP0700,
but only 18 of those implement _FDE...

I have a Lenovo T61 which has PNP0700 and implements _FDE.
However, it doesn't physically have a floppy, and so
acpi_fde_add() will never get called -- I guess
because _CRS said it wasn't present?  This seems
to make evaluating _FDE from the .add routine
somewhat redundant, no?

Note that you've got a memory leak in acpi_fde_add()
in the "if (!c)" case.  Also, "rmmod floppy" takes an oops.

cheers,
Len Brown, Intel Open Source Technology Center

> Not-yet-signed-off-by: Kyle McMartin <kyle@xxxxxxxxxx>
> 
> ---
> diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c
> index 3951020..9208596 100644
> --- a/drivers/block/floppy.c
> +++ b/drivers/block/floppy.c
> @@ -193,6 +193,9 @@ static int print_unex = 1;
>  #include <linux/io.h>
>  #include <linux/uaccess.h>
>  
> +#include <acpi/acpi_bus.h>
> +#include <acpi/acpi_drivers.h>
> +
>  /*
>   * PS/2 floppies have much slower step rates than regular floppies.
>   * It's been recommended that take about 1/4 of the default speed
> @@ -4548,6 +4551,110 @@ static void __init parse_floppy_cfg_string(char *cfg)
>  	}
>  }
>  
> +static void __exit floppy_module_exit(void);
> +
> +#if defined(CONFIG_ACPI)
> +
> +#define MAX_ACPI_FLOPPIES	4
> +struct fde_ret {
> +	u32 floppies[MAX_ACPI_FLOPPIES];
> +	u32 tape;
> +};
> +
> +static int acpi_fde_add(struct acpi_device *dev)
> +{
> +	struct acpi_buffer out = { ACPI_ALLOCATE_BUFFER, NULL };
> +	union acpi_object *obj;
> +	struct fde_ret *fde;
> +	acpi_status status;
> +	int i, c = 0;
> +
> +	status = acpi_evaluate_object(dev->handle, "_FDE", NULL, &out);
> +	if (ACPI_FAILURE(status)) {	/* fallback */
> +		pr_info("acpi_fde: failed to evaluate _FDE\n");
> +		goto probe_floppies;
> +	}
> +
> +	obj = out.pointer;
> +	if (!obj || obj->type != ACPI_TYPE_BUFFER) {
> +		pr_info("acpi_fde: bad return from _FDE method\n");
> +		goto probe_floppies;
> +	}
> +
> +	fde = (struct fde_ret *)obj->buffer.pointer;
> +
> +	for (i = 0; i < MAX_ACPI_FLOPPIES; i++)
> +		if (fde->floppies[i])
> +			c++;
> +
> +	pr_info("acpi_fde: firmware reports %d floppies attached\n", c);
> +	if (!c)
> +		return 0;
> +
> +	/* fallthrough, we had floppies... */
> +probe_floppies:
> +	kfree(out.pointer);
> +
> +	if (floppy)
> +		parse_floppy_cfg_string(floppy);
> +	return floppy_init();
> +}
> +
> +static const struct acpi_device_id fde_pnpids[] = {
> +	{ "PNP0700", 0 },
> +	{ "PNP0701", 0 },
> +	{ "", 0 }
> +};
> +MODULE_DEVICE_TABLE(acpi, fde_pnpids);
> +
> +static struct acpi_driver acpi_fde_driver = {
> +	.name = "fde",
> +	.class = "floppy",
> +	.ids = fde_pnpids,
> +	.ops = {
> +		.add = acpi_fde_add,
> +	},
> +};
> +
> +static int __init acpi_fde_init(void)
> +{
> +	int err;
> +
> +	if (acpi_disabled) {
> +		if (floppy)
> +			parse_floppy_cfg_string(floppy);
> +		return floppy_init();
> +	}
> +
> +	err = acpi_bus_register_driver(&acpi_fde_driver);
> +	if (err) {
> +		pr_info("error register acpi floppy\n");
> +		return err;
> +	}
> +
> +	pr_info("floppy: loaded\n");
> +
> +	return 0;
> +}
> +module_init(acpi_fde_init);
> +
> +static void __exit acpi_fde_fini(void) {
> +	acpi_bus_unregister_driver(&acpi_fde_driver);
> +	floppy_module_exit();
> +	pr_info("floppy: unloaded\n");
> +}
> +module_exit(acpi_fde_fini);
> +
> +#else /*!CONFIG_ACPI*/
> +
> +/* This doesn't actually get used other than for module information */
> +static const struct pnp_device_id floppy_pnpids[] = {
> +	{"PNP0700", 0},
> +	{}
> +};
> +
> +MODULE_DEVICE_TABLE(pnp, floppy_pnpids);
> +
>  static int __init floppy_module_init(void)
>  {
>  	if (floppy)
> @@ -4556,6 +4663,10 @@ static int __init floppy_module_init(void)
>  }
>  module_init(floppy_module_init);
>  
> +module_exit(floppy_module_exit);
> +
> +#endif /*CONFIG_ACPI*/
> +
>  static void __exit floppy_module_exit(void)
>  {
>  	int drive;
> @@ -4587,8 +4698,6 @@ static void __exit floppy_module_exit(void)
>  	fd_eject(0);
>  }
>  
> -module_exit(floppy_module_exit);
> -
>  module_param(floppy, charp, 0);
>  module_param(FLOPPY_IRQ, int, 0);
>  module_param(FLOPPY_DMA, int, 0);
> @@ -4596,14 +4705,6 @@ MODULE_AUTHOR("Alain L. Knaff");
>  MODULE_SUPPORTED_DEVICE("fd");
>  MODULE_LICENSE("GPL");
>  
> -/* This doesn't actually get used other than for module information */
> -static const struct pnp_device_id floppy_pnpids[] = {
> -	{"PNP0700", 0},
> -	{}
> -};
> -
> -MODULE_DEVICE_TABLE(pnp, floppy_pnpids);
> -
>  #else
>  
>  __setup("floppy=", floppy_setup);
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux IBM ACPI]     [Linux Power Management]     [Linux Kernel]     [Linux Laptop]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Device Mapper]     [Linux Resources]

  Powered by Linux