From 312f7da2824c82800ee78d6190f12854456957af Mon Sep 17 00:00:00 2001 From: Albert Lee Date: Tue, 27 Sep 2005 17:38:03 +0800 Subject: [PATCH] libata: interrupt driven pio for libata-core - add PIO_ST_FIRST for the state before sending ATAPI CDB or sending "ATA PIO data out" first data block. - add ATA_TFLAG_POLLING and ATA_DFLAG_CDB_INTR flags - remove the ATA_FLAG_NOINTR flag since the interrupt handler is now aware of the states - modify ata_pio_sector() and atapi_pio_bytes() to work in the interrupt context - modify the ata_host_intr() to handle PIO interrupts - modify ata_qc_issue_prot() to initialize states - atapi_packet_task() changed to handle "ATA PIO data out" first data block - support the pre-ATA4 ATAPI device which raise interrupt when ready to receive CDB Signed-off-by: Albert Lee Signed-off-by: Jeff Garzik --- include/linux/ata.h | 3 +++ include/linux/libata.h | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/ata.h b/include/linux/ata.h index a5b74efab067..6fec2f6f2d59 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -181,6 +181,7 @@ enum { ATA_TFLAG_ISADDR = (1 << 1), /* enable r/w to nsect/lba regs */ ATA_TFLAG_DEVICE = (1 << 2), /* enable r/w to device reg */ ATA_TFLAG_WRITE = (1 << 3), /* data dir: host->dev==1 (write) */ + ATA_TFLAG_POLLING = (1 << 4), /* set nIEN to 1 and use polling */ }; enum ata_tf_protocols { @@ -250,6 +251,8 @@ struct ata_taskfile { ((u64) (id)[(n) + 1] << 16) | \ ((u64) (id)[(n) + 0]) ) +#define ata_id_cdb_intr(id) (((id)[0] & 0x60) == 0x20) + static inline int atapi_cdb_len(u16 *dev_id) { u16 tmp = dev_id[0] & 0x3; diff --git a/include/linux/libata.h b/include/linux/libata.h index bb2d916bce44..9ac2b69df3c1 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -97,6 +97,7 @@ enum { ATA_DFLAG_LBA48 = (1 << 0), /* device supports LBA48 */ ATA_DFLAG_PIO = (1 << 1), /* device currently in PIO mode */ ATA_DFLAG_LOCK_SECTORS = (1 << 2), /* don't adjust max_sectors */ + ATA_DFLAG_CDB_INTR = (1 << 3), /* device asserts INTRQ when ready for CDB */ ATA_DEV_UNKNOWN = 0, /* unknown device */ ATA_DEV_ATA = 1, /* ATA device */ @@ -115,8 +116,6 @@ enum { ATA_FLAG_MMIO = (1 << 6), /* use MMIO, not PIO */ ATA_FLAG_SATA_RESET = (1 << 7), /* use COMRESET */ ATA_FLAG_PIO_DMA = (1 << 8), /* PIO cmds via DMA */ - ATA_FLAG_NOINTR = (1 << 9), /* FIXME: Remove this once - * proper HSM is in place. */ ATA_QCFLAG_ACTIVE = (1 << 1), /* cmd not yet ack'd to scsi lyer */ ATA_QCFLAG_SG = (1 << 3), /* have s/g table? */ @@ -165,6 +164,7 @@ enum hsm_task_states { HSM_ST_LAST, HSM_ST_LAST_POLL, HSM_ST_ERR, + HSM_ST_FIRST, }; /* forward declarations */ -- cgit v1.2.3 From e50362eccd8809a224cda5f71714a088ba37b2ab Mon Sep 17 00:00:00 2001 From: Albert Lee Date: Tue, 27 Sep 2005 17:39:50 +0800 Subject: [PATCH] libata: interrupt driven pio for LLD libata.h: libata-core: Add ATA_FLAG_PIO_POLLING flag for LLDs that expect interrupt for command completion only. sata_nv.c: sata_vsc.c: irq handler is wrapper around ata_host_intr(), can handle PIO interrupts. sata_promise.c: sata_sx4.c: sata_qstor.c: sata_mv.c: Private irq handler. Polling mode ATA_FLAG_PIO_POLLING used for compatibility. Signed-off-by: Albert Lee Signed-off-by: Jeff Garzik --- include/linux/libata.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 9ac2b69df3c1..ea8ab29aa92e 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -116,6 +116,8 @@ enum { ATA_FLAG_MMIO = (1 << 6), /* use MMIO, not PIO */ ATA_FLAG_SATA_RESET = (1 << 7), /* use COMRESET */ ATA_FLAG_PIO_DMA = (1 << 8), /* PIO cmds via DMA */ + ATA_FLAG_PIO_POLLING = (1 << 9), /* use polling PIO if LLD + * doesn't handle PIO interrupts */ ATA_QCFLAG_ACTIVE = (1 << 1), /* cmd not yet ack'd to scsi lyer */ ATA_QCFLAG_SG = (1 << 3), /* have s/g table? */ -- cgit v1.2.3 From c56b14d2a3e32695e13cd49b417da889da744d1c Mon Sep 17 00:00:00 2001 From: Albert Lee Date: Fri, 30 Sep 2005 19:07:39 +0800 Subject: [PATCH] libata irq-pio: add comments and cleanup Signed-off-by: Albert Lee Signed-off-by: Jeff Garzik --- include/linux/libata.h | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index ea8ab29aa92e..1fcd0ef9e1c9 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -158,15 +158,16 @@ enum { }; enum hsm_task_states { - HSM_ST_UNKNOWN, - HSM_ST_IDLE, - HSM_ST_POLL, - HSM_ST_TMOUT, - HSM_ST, - HSM_ST_LAST, - HSM_ST_LAST_POLL, - HSM_ST_ERR, - HSM_ST_FIRST, + HSM_ST_UNKNOWN, /* state unknown */ + HSM_ST_IDLE, /* no command on going */ + HSM_ST_POLL, /* same as HSM_ST, waits longer */ + HSM_ST_TMOUT, /* timeout */ + HSM_ST, /* (waiting the device to) transfer data */ + HSM_ST_LAST, /* (waiting the device to) complete command */ + HSM_ST_LAST_POLL, /* same as HSM_ST_LAST, waits longer */ + HSM_ST_ERR, /* error */ + HSM_ST_FIRST, /* (waiting the device to) + write CDB or first data block */ }; /* forward declarations */ -- cgit v1.2.3 From f9997be974be40e884e9e8157ded2f2f9aed454c Mon Sep 17 00:00:00 2001 From: Albert Lee Date: Fri, 30 Sep 2005 19:09:31 +0800 Subject: [PATCH] libata irq-pio: rename atapi_packet_task() and comments Signed-off-by: Albert Lee Signed-off-by: Jeff Garzik --- include/linux/libata.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 1fcd0ef9e1c9..7e6feb97406e 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -129,8 +129,8 @@ enum { ATA_TMOUT_PIO = 30 * HZ, ATA_TMOUT_BOOT = 30 * HZ, /* hueristic */ ATA_TMOUT_BOOT_QUICK = 7 * HZ, /* hueristic */ - ATA_TMOUT_CDB = 30 * HZ, - ATA_TMOUT_CDB_QUICK = 5 * HZ, + ATA_TMOUT_DATAOUT = 30 * HZ, + ATA_TMOUT_DATAOUT_QUICK = 5 * HZ, /* ATA bus states */ BUS_UNKNOWN = 0, @@ -319,7 +319,7 @@ struct ata_port { struct ata_host_stats stats; struct ata_host_set *host_set; - struct work_struct packet_task; + struct work_struct dataout_task; struct work_struct pio_task; unsigned int hsm_task_state; -- cgit v1.2.3 From e27486db89ef04d5df1727c52362fa3d50cff241 Mon Sep 17 00:00:00 2001 From: Albert Lee Date: Tue, 1 Nov 2005 19:24:49 +0800 Subject: [PATCH] libata irq-pio: merge the ata_dataout_task workqueue with ata_pio_task workqueue - remove ap->dataout_task from struct ata_port - let ata_pio_task() handle the HSM_ST_FIRST state. - rename ata_dataout_task() to ata_pio_first_block() - replace the ata_dataout_task workqueue with ata_pio_task workqueue Signed-off-by: Albert Lee ======== Signed-off-by: Jeff Garzik --- include/linux/libata.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index ad0451dfee15..70ae140dbf23 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -346,8 +346,6 @@ struct ata_port { struct ata_host_stats stats; struct ata_host_set *host_set; - struct work_struct dataout_task; - struct work_struct pio_task; unsigned int hsm_task_state; unsigned long pio_task_timeout; -- cgit v1.2.3 From 07f6f7d074e68d56d82e7cc5c65096033ac8dc56 Mon Sep 17 00:00:00 2001 From: Albert Lee Date: Tue, 1 Nov 2005 19:33:20 +0800 Subject: [PATCH] libata irq-pio: add read/write multiple support - add is_multi_taskfile() to ata.h - initialize ata_device->multi_count with device identify data - use ata_pio_sectors() to support r/w multiple commands Signed-off-by: Albert Lee ======== Signed-off-by: Jeff Garzik --- include/linux/ata.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ata.h b/include/linux/ata.h index d54da3306d2c..f512104a1a3f 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -293,6 +293,14 @@ static inline int is_atapi_taskfile(const struct ata_taskfile *tf) (tf->protocol == ATA_PROT_ATAPI_DMA); } +static inline int is_multi_taskfile(struct ata_taskfile *tf) +{ + return (tf->command == ATA_CMD_READ_MULTI) || + (tf->command == ATA_CMD_WRITE_MULTI) || + (tf->command == ATA_CMD_READ_MULTI_EXT) || + (tf->command == ATA_CMD_WRITE_MULTI_EXT); +} + static inline int ata_ok(u8 status) { return ((status & (ATA_BUSY | ATA_DRDY | ATA_DF | ATA_DRQ | ATA_ERR)) -- cgit v1.2.3 From 3b2d99429e3386b6e2ac949fc72486509c8bbe36 Mon Sep 17 00:00:00 2001 From: Venkatesh Pallipadi Date: Wed, 14 Dec 2005 15:05:00 -0500 Subject: P-state software coordination for ACPI core http://bugzilla.kernel.org/show_bug.cgi?id=5737 Signed-off-by: Venkatesh Pallipadi Signed-off-by: Len Brown --- include/linux/cpufreq.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/cpufreq.h b/include/linux/cpufreq.h index 17866d7e2b71..f7d988366941 100644 --- a/include/linux/cpufreq.h +++ b/include/linux/cpufreq.h @@ -73,6 +73,8 @@ struct cpufreq_real_policy { struct cpufreq_policy { cpumask_t cpus; /* affected CPUs */ + unsigned int shared_type; /* ANY or ALL affected CPUs + should set cpufreq */ unsigned int cpu; /* cpu nr of registered CPU */ struct cpufreq_cpuinfo cpuinfo;/* see above */ @@ -99,6 +101,8 @@ struct cpufreq_policy { #define CPUFREQ_INCOMPATIBLE (1) #define CPUFREQ_NOTIFY (2) +#define CPUFREQ_SHARED_TYPE_ALL (0) /* All dependent CPUs should set freq */ +#define CPUFREQ_SHARED_TYPE_ANY (1) /* Freq can be set from any dependent CPU */ /******************** cpufreq transition notifiers *******************/ -- cgit v1.2.3 From c2956a3b0d1c17b38da369811a6ce93eb7a01a04 Mon Sep 17 00:00:00 2001 From: Albert Lee Date: Fri, 3 Mar 2006 10:34:05 +0800 Subject: [PATCH] libata-dev: recognize WRITE_MULTI_FUA_EXT for r/w multiple Recognize ATA_CMD_WRITE_MULTI_FUA_EXT as r/w multiple commands. Signed-off-by: Albert Lee Signed-off-by: Jeff Garzik --- include/linux/ata.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/ata.h b/include/linux/ata.h index 469952366ed4..e7b0c21f6cd4 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -314,7 +314,8 @@ static inline int is_multi_taskfile(struct ata_taskfile *tf) return (tf->command == ATA_CMD_READ_MULTI) || (tf->command == ATA_CMD_WRITE_MULTI) || (tf->command == ATA_CMD_READ_MULTI_EXT) || - (tf->command == ATA_CMD_WRITE_MULTI_EXT); + (tf->command == ATA_CMD_WRITE_MULTI_EXT) || + (tf->command == ATA_CMD_WRITE_MULTI_FUA_EXT); } static inline int ata_ok(u8 status) -- cgit v1.2.3 From 200d5a7684cc49ef4be40e832daf3f217e70dfbb Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 15 Feb 2006 16:24:49 +0900 Subject: [PATCH] libata: increase LBA48 max sectors to 65535 max_hw_sectors/max_sectors separation patch made into the tree, increase max_sectors to its hardware limit. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index d81cecdda4f3..4dff3cf9d389 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -110,6 +110,7 @@ enum { ATA_DEF_QUEUE = 1, ATA_MAX_QUEUE = 1, ATA_MAX_SECTORS = 200, /* FIXME */ + ATA_MAX_SECTORS_LBA48 = 65535, ATA_MAX_BUS = 2, ATA_DEF_BUSY_WAIT = 10000, ATA_SHORT_PAUSE = (HZ >> 6) + 1, -- cgit v1.2.3 From 27cdadef6dfe0d0614653919a110fc75ab1650ce Mon Sep 17 00:00:00 2001 From: Albert Lee Date: Sat, 25 Mar 2006 17:53:57 +0800 Subject: [PATCH] libata-dev: Cleanup unused enums/functions Cleanup the following unused functions: - ata_pio_poll() - ata_pio_complete() - ata_pio_first_block() - ata_pio_block() - ata_pio_error() ap->pio_task_timeout and other enums. Signed-off-by: Albert Lee Signed-off-by: Jeff Garzik --- include/linux/libata.h | 9 --------- 1 file changed, 9 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 70ca99bbc6c7..0eb71c1773a1 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -162,13 +162,8 @@ enum { ATA_QCFLAG_EH_SCHEDULED = (1 << 5), /* EH scheduled */ /* various lengths of time */ - ATA_TMOUT_PIO = 30 * HZ, ATA_TMOUT_BOOT = 30 * HZ, /* heuristic */ ATA_TMOUT_BOOT_QUICK = 7 * HZ, /* heuristic */ - ATA_TMOUT_DATAOUT = 30 * HZ, - ATA_TMOUT_DATAOUT_QUICK = 5 * HZ, - ATA_TMOUT_CDB = 30 * HZ, - ATA_TMOUT_CDB_QUICK = 5 * HZ, ATA_TMOUT_INTERNAL = 30 * HZ, ATA_TMOUT_INTERNAL_QUICK = 5 * HZ, @@ -216,11 +211,8 @@ enum { enum hsm_task_states { HSM_ST_UNKNOWN, /* state unknown */ HSM_ST_IDLE, /* no command on going */ - HSM_ST_POLL, /* same as HSM_ST, waits longer */ - HSM_ST_TMOUT, /* timeout */ HSM_ST, /* (waiting the device to) transfer data */ HSM_ST_LAST, /* (waiting the device to) complete command */ - HSM_ST_LAST_POLL, /* same as HSM_ST_LAST, waits longer */ HSM_ST_ERR, /* error */ HSM_ST_FIRST, /* (waiting the device to) write CDB or first data block */ @@ -409,7 +401,6 @@ struct ata_port { struct work_struct port_task; unsigned int hsm_task_state; - unsigned long pio_task_timeout; u32 msg_enable; struct list_head eh_done_q; -- cgit v1.2.3 From e1211e3fa7fd05ff0d4f597fd37e40de8acc6784 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 1 Apr 2006 01:38:18 +0900 Subject: [PATCH] libata: implement ata_dev_enabled and disabled() This patch renames ata_dev_present() to ata_dev_enabled() and adds ata_dev_disabled(). This is to discern the state where a device is present but disabled from not-present state. This disctinction is necessary when configuring transfer mode because device selection timing must not be violated even if a device fails to configure. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 0d61357604d5..c6883ba8cba9 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -672,14 +672,24 @@ static inline unsigned int ata_tag_valid(unsigned int tag) return (tag < ATA_MAX_QUEUE) ? 1 : 0; } -static inline unsigned int ata_class_present(unsigned int class) +static inline unsigned int ata_class_enabled(unsigned int class) { return class == ATA_DEV_ATA || class == ATA_DEV_ATAPI; } -static inline unsigned int ata_dev_present(const struct ata_device *dev) +static inline unsigned int ata_class_disabled(unsigned int class) { - return ata_class_present(dev->class); + return class == ATA_DEV_ATA_UNSUP || class == ATA_DEV_ATAPI_UNSUP; +} + +static inline unsigned int ata_dev_enabled(const struct ata_device *dev) +{ + return ata_class_enabled(dev->class); +} + +static inline unsigned int ata_dev_disabled(const struct ata_device *dev) +{ + return ata_class_disabled(dev->class); } static inline u8 ata_chk_status(struct ata_port *ap) -- cgit v1.2.3 From 002c8054fa8d0f1afce2b0c728be32d338b9293a Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 2 Apr 2006 17:54:46 +0900 Subject: [PATCH] libata: implement ata_dev_absent() For the time being we cannot use ata_dev_present() as it was renamed to ata_dev_enabled() but we still need presence test. Implement negation of the test. Conveniently, the negated result is needed in more places. This is suggested by Jeff Garzik. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index c6883ba8cba9..0f8e3720edd9 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -682,6 +682,11 @@ static inline unsigned int ata_class_disabled(unsigned int class) return class == ATA_DEV_ATA_UNSUP || class == ATA_DEV_ATAPI_UNSUP; } +static inline unsigned int ata_class_absent(unsigned int class) +{ + return !ata_class_enabled(class) && !ata_class_disabled(class); +} + static inline unsigned int ata_dev_enabled(const struct ata_device *dev) { return ata_class_enabled(dev->class); @@ -692,6 +697,11 @@ static inline unsigned int ata_dev_disabled(const struct ata_device *dev) return ata_class_disabled(dev->class); } +static inline unsigned int ata_dev_absent(const struct ata_device *dev) +{ + return ata_class_absent(dev->class); +} + static inline u8 ata_chk_status(struct ata_port *ap) { return ap->ops->check_status(ap); -- cgit v1.2.3 From 1c3fae4d7eb121933341443c37d3bbee43c0fb68 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 2 Apr 2006 20:53:28 +0900 Subject: [PATCH] libata: implement ap->sata_spd_limit and helpers ap->sata_spd_limit contrains SATA PHY speed of the port. It is initialized to the configured value prior to probing thus preserving BIOS configured value. hardreset is responsible for applying SPD limit and sata_std_hardreset() is updated to do that. SATA SPD limit will be used to enhance failure handling during probing and later by EH. This patch also normalizes some comments around affected code. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 0f8e3720edd9..a5207e66ca52 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -397,6 +397,7 @@ struct ata_port { unsigned int mwdma_mask; unsigned int udma_mask; unsigned int cbl; /* cable type; ATA_CBL_xxx */ + unsigned int sata_spd_limit; /* SATA PHY speed limit */ struct ata_device device[ATA_MAX_DEVICES]; -- cgit v1.2.3 From 14d2bac1877ed4e2cc940d1680db1a4f29225811 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 2 Apr 2006 17:54:46 +0900 Subject: [PATCH] libata: improve ata_bus_probe() Improve ata_bus_probe() such that configuration failures are handled better. Each device is given ATA_PROBE_MAX_TRIES chances, but any non-transient error (revalidation failure with -ENODEV, configuration failure with -EINVAL...) disables the device directly. Any IO error results in SATA PHY speed down and ata_set_mode() failure lowers transfer mode. The last try always puts a device into PIO-0. After each failure, the whole port is reset to make sure that the controller and all the devices are in a known and stable state. The reset also applies SATA SPD configuration if necessary. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index a5207e66ca52..a4a1e6304e78 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -211,6 +211,9 @@ enum { /* Masks for port functions */ ATA_PORT_PRIMARY = (1 << 0), ATA_PORT_SECONDARY = (1 << 1), + + /* how hard are we gonna try to probe/recover devices */ + ATA_PROBE_MAX_TRIES = 3, }; enum hsm_task_states { -- cgit v1.2.3 From c43c555c3a6db7f0b55fd9b66d7ecff16e827d4e Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 2 Apr 2006 18:51:52 +0900 Subject: [PATCH] libata: ATA_FLAG_IN_EH is not used, kill it Kill unused flag ATA_FLAG_IN_EH. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index a4a1e6304e78..e20b0bfbd5f2 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -152,7 +152,6 @@ enum { ATA_FLAG_IRQ_MASK = (1 << 14), /* Mask IRQ in PIO xfers */ ATA_FLAG_FLUSH_PORT_TASK = (1 << 15), /* Flush port task */ - ATA_FLAG_IN_EH = (1 << 16), /* EH in progress */ ATA_QCFLAG_ACTIVE = (1 << 1), /* cmd not yet ack'd to scsi lyer */ ATA_QCFLAG_SG = (1 << 3), /* have s/g table? */ -- cgit v1.2.3 From 949b38af40a0b88b7267908b1554a45b97b5b737 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 2 Apr 2006 18:51:52 +0900 Subject: [PATCH] libata: clean up constants * Reorder ATA_DFLAG_* such that feature flags determined by ata_dev_configure() are on lower bits. Reserve lower eight bits for this purpose and allocate dynamic flags from bit 8. * Reorder ATA_FLAG_* such that feature flags determined during driver initiailization are on bits 0:15, dynamic flags on 16:23 and LLDD specific flags on 24:31. * Kill trailing white space and lower-case an one line comment for consistency. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 61 ++++++++++++++++++++++++++------------------------ 1 file changed, 32 insertions(+), 29 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index e20b0bfbd5f2..b7488a31e320 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -120,9 +120,10 @@ enum { ATA_SHT_USE_CLUSTERING = 1, /* struct ata_device stuff */ - ATA_DFLAG_LBA48 = (1 << 0), /* device supports LBA48 */ - ATA_DFLAG_PIO = (1 << 1), /* device currently in PIO mode */ - ATA_DFLAG_LBA = (1 << 2), /* device supports LBA */ + ATA_DFLAG_LBA = (1 << 0), /* device supports LBA */ + ATA_DFLAG_LBA48 = (1 << 1), /* device supports LBA48 */ + + ATA_DFLAG_PIO = (1 << 8), /* device currently in PIO mode */ ATA_DEV_UNKNOWN = 0, /* unknown device */ ATA_DEV_ATA = 1, /* ATA device */ @@ -132,32 +133,34 @@ enum { ATA_DEV_NONE = 5, /* no device */ /* struct ata_port flags */ - ATA_FLAG_SLAVE_POSS = (1 << 1), /* host supports slave dev */ + ATA_FLAG_SLAVE_POSS = (1 << 0), /* host supports slave dev */ /* (doesn't imply presence) */ - ATA_FLAG_PORT_DISABLED = (1 << 2), /* port is disabled, ignore it */ - ATA_FLAG_SATA = (1 << 3), - ATA_FLAG_NO_LEGACY = (1 << 4), /* no legacy mode check */ - ATA_FLAG_SRST = (1 << 5), /* (obsolete) use ATA SRST, not E.D.D. */ - ATA_FLAG_MMIO = (1 << 6), /* use MMIO, not PIO */ - ATA_FLAG_SATA_RESET = (1 << 7), /* (obsolete) use COMRESET */ - ATA_FLAG_PIO_DMA = (1 << 8), /* PIO cmds via DMA */ - ATA_FLAG_NOINTR = (1 << 9), /* FIXME: Remove this once - * proper HSM is in place. */ - ATA_FLAG_DEBUGMSG = (1 << 10), - ATA_FLAG_NO_ATAPI = (1 << 11), /* No ATAPI support */ - - ATA_FLAG_SUSPENDED = (1 << 12), /* port is suspended */ - - ATA_FLAG_PIO_LBA48 = (1 << 13), /* Host DMA engine is LBA28 only */ - ATA_FLAG_IRQ_MASK = (1 << 14), /* Mask IRQ in PIO xfers */ - - ATA_FLAG_FLUSH_PORT_TASK = (1 << 15), /* Flush port task */ - - ATA_QCFLAG_ACTIVE = (1 << 1), /* cmd not yet ack'd to scsi lyer */ - ATA_QCFLAG_SG = (1 << 3), /* have s/g table? */ - ATA_QCFLAG_SINGLE = (1 << 4), /* no s/g, just a single buffer */ + ATA_FLAG_SATA = (1 << 1), + ATA_FLAG_NO_LEGACY = (1 << 2), /* no legacy mode check */ + ATA_FLAG_MMIO = (1 << 3), /* use MMIO, not PIO */ + ATA_FLAG_SRST = (1 << 4), /* (obsolete) use ATA SRST, not E.D.D. */ + ATA_FLAG_SATA_RESET = (1 << 5), /* (obsolete) use COMRESET */ + ATA_FLAG_NO_ATAPI = (1 << 6), /* No ATAPI support */ + ATA_FLAG_PIO_DMA = (1 << 7), /* PIO cmds via DMA */ + ATA_FLAG_PIO_LBA48 = (1 << 8), /* Host DMA engine is LBA28 only */ + ATA_FLAG_IRQ_MASK = (1 << 9), /* Mask IRQ in PIO xfers */ + + ATA_FLAG_NOINTR = (1 << 16), /* FIXME: Remove this once + * proper HSM is in place. */ + ATA_FLAG_DEBUGMSG = (1 << 17), + ATA_FLAG_FLUSH_PORT_TASK = (1 << 18), /* flush port task */ + + ATA_FLAG_PORT_DISABLED = (1 << 19), /* port is disabled, ignore it */ + ATA_FLAG_SUSPENDED = (1 << 20), /* port is suspended */ + + /* bits 24:31 of ap->flags are reserved for LLDD specific flags */ + + /* struct ata_queued_cmd flags */ + ATA_QCFLAG_ACTIVE = (1 << 0), /* cmd not yet ack'd to scsi lyer */ + ATA_QCFLAG_SG = (1 << 1), /* have s/g table? */ + ATA_QCFLAG_SINGLE = (1 << 2), /* no s/g, just a single buffer */ ATA_QCFLAG_DMAMAP = ATA_QCFLAG_SG | ATA_QCFLAG_SINGLE, - ATA_QCFLAG_EH_SCHEDULED = (1 << 5), /* EH scheduled */ + ATA_QCFLAG_EH_SCHEDULED = (1 << 3), /* EH scheduled */ /* host set flags */ ATA_HOST_SIMPLEX = (1 << 0), /* Host is simplex, one DMA channel per host_set only */ @@ -206,8 +209,8 @@ enum { /* size of buffer to pad xfers ending on unaligned boundaries */ ATA_DMA_PAD_SZ = 4, ATA_DMA_PAD_BUF_SZ = ATA_DMA_PAD_SZ * ATA_MAX_QUEUE, - - /* Masks for port functions */ + + /* masks for port functions */ ATA_PORT_PRIMARY = (1 << 0), ATA_PORT_SECONDARY = (1 << 1), -- cgit v1.2.3 From 198e0fed9e59461fc1890dd8b75ec72d14638873 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 2 Apr 2006 18:51:52 +0900 Subject: [PATCH] libata: rename ATA_FLAG_PORT_DISABLED to ATA_FLAG_DISABLED Rename ATA_FLAG_PORT_DISABLED to ATA_FLAG_DISABLED for consistency. (ATA_FLAG_* are always about ports). Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index b7488a31e320..890262f44d0a 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -150,7 +150,7 @@ enum { ATA_FLAG_DEBUGMSG = (1 << 17), ATA_FLAG_FLUSH_PORT_TASK = (1 << 18), /* flush port task */ - ATA_FLAG_PORT_DISABLED = (1 << 19), /* port is disabled, ignore it */ + ATA_FLAG_DISABLED = (1 << 19), /* port is disabled, ignore it */ ATA_FLAG_SUSPENDED = (1 << 20), /* port is suspended */ /* bits 24:31 of ap->flags are reserved for LLDD specific flags */ -- cgit v1.2.3 From ea1dd4e13010eb9dd5ffb4bfabbb472bc238bebb Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 2 Apr 2006 18:51:53 +0900 Subject: [PATCH] libata: clear only affected flags during ata_dev_configure() ata_dev_configure() should not clear dynamic device flags determined elsewhere. Lower eight bits are reserved for feature flags, define ATA_DFLAG_CFG_MASK and clear only those bits before configuring device. Without this patch, ATA_DFLAG_PIO gets turned off during revalidation making PIO mode unuseable. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 890262f44d0a..cbbc821fe22c 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -122,6 +122,7 @@ enum { /* struct ata_device stuff */ ATA_DFLAG_LBA = (1 << 0), /* device supports LBA */ ATA_DFLAG_LBA48 = (1 << 1), /* device supports LBA48 */ + ATA_DFLAG_CFG_MASK = (1 << 8) - 1, ATA_DFLAG_PIO = (1 << 8), /* device currently in PIO mode */ -- cgit v1.2.3 From 2719736779da2c7fbb17d3de16c817b429bfeb9c Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 2 Apr 2006 18:51:53 +0900 Subject: [PATCH] libata: add ATA_QCFLAG_IO Add a new qc flag ATA_QCFLAG_IO. This flag gets set for normal IO commands originating from SCSI midlayer. This information will be used by EH to determine transfer speed reconfiguration. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index cbbc821fe22c..a6d829cb0567 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -161,7 +161,8 @@ enum { ATA_QCFLAG_SG = (1 << 1), /* have s/g table? */ ATA_QCFLAG_SINGLE = (1 << 2), /* no s/g, just a single buffer */ ATA_QCFLAG_DMAMAP = ATA_QCFLAG_SG | ATA_QCFLAG_SINGLE, - ATA_QCFLAG_EH_SCHEDULED = (1 << 3), /* EH scheduled */ + ATA_QCFLAG_IO = (1 << 3), /* standard IO command */ + ATA_QCFLAG_EH_SCHEDULED = (1 << 4), /* EH scheduled */ /* host set flags */ ATA_HOST_SIMPLEX = (1 << 0), /* Host is simplex, one DMA channel per host_set only */ -- cgit v1.2.3 From ece1d63619df010b8c4f08e43755e2a03f3b6eed Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 2 Apr 2006 18:51:53 +0900 Subject: [PATCH] libata: separate out libata-eh.c A lot of EH codes are about to be added to libata. Separate out libata-eh.c. ata_scsi_timed_out(), ata_scsi_error(), ata_qc_timeout(), ata_eng_timeout(), ata_eh_qc_complete() and ata_eh_qc_retry() are moved. No code is changed by this patch. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index a6d829cb0567..75bdee09c307 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -531,9 +531,6 @@ extern void ata_host_set_remove(struct ata_host_set *host_set); extern int ata_scsi_detect(struct scsi_host_template *sht); extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg); extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)); -extern int ata_scsi_error(struct Scsi_Host *host); -extern void ata_eh_qc_complete(struct ata_queued_cmd *qc); -extern void ata_eh_qc_retry(struct ata_queued_cmd *qc); extern int ata_scsi_release(struct Scsi_Host *host); extern unsigned int ata_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc); extern int ata_scsi_device_resume(struct scsi_device *); @@ -582,7 +579,6 @@ extern void ata_bmdma_stop(struct ata_queued_cmd *qc); extern u8 ata_bmdma_status(struct ata_port *ap); extern void ata_bmdma_irq_clear(struct ata_port *ap); extern void __ata_qc_complete(struct ata_queued_cmd *qc); -extern void ata_eng_timeout(struct ata_port *ap); extern void ata_scsi_simulate(struct ata_port *ap, struct ata_device *dev, struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)); @@ -637,6 +633,14 @@ extern int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bit extern unsigned long ata_pci_default_filter(const struct ata_port *, struct ata_device *, unsigned long); #endif /* CONFIG_PCI */ +/* + * EH + */ +extern int ata_scsi_error(struct Scsi_Host *host); +extern void ata_eng_timeout(struct ata_port *ap); +extern void ata_eh_qc_complete(struct ata_queued_cmd *qc); +extern void ata_eh_qc_retry(struct ata_queued_cmd *qc); + static inline int ata_sg_is_last(struct scatterlist *sg, struct ata_queued_cmd *qc) -- cgit v1.2.3 From 95de719adc94392a95c3c4d0a2d6b8b1ea39d236 Mon Sep 17 00:00:00 2001 From: Albert Lee Date: Tue, 4 Apr 2006 10:57:18 +0800 Subject: [PATCH] libata: convert ATAPI_ENABLE_DMADIR to module parameter Convert the ATAPI_ENABLE_DMADIR compile time option needed by some SATA-PATA bridge to runtime module parameter. Signed-off-by: Albert Lee Signed-off-by: Jeff Garzik --- include/linux/libata.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 75bdee09c307..03231cb6b406 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -44,7 +44,6 @@ #undef ATA_NDEBUG /* define to disable quick runtime checks */ #undef ATA_ENABLE_PATA /* define to enable PATA support in some * low-level drivers */ -#undef ATAPI_ENABLE_DMADIR /* enables ATAPI DMADIR bridge support */ /* note: prints function name for you */ -- cgit v1.2.3 From 381544bba3ae6f2f1004b267da34f840b469033c Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Tue, 11 Apr 2006 13:04:39 -0400 Subject: libata: Fix EH merge difference between this branch and upstream. --- include/linux/libata.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index a7161d42d18f..2564bc514bca 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -637,7 +637,6 @@ extern unsigned long ata_pci_default_filter(const struct ata_port *, struct ata_ /* * EH */ -extern int ata_scsi_error(struct Scsi_Host *host); extern void ata_eng_timeout(struct ata_port *ap); extern void ata_eh_qc_complete(struct ata_queued_cmd *qc); extern void ata_eh_qc_retry(struct ata_queued_cmd *qc); -- cgit v1.2.3 From 35bb94b116e1fd4959ef0d3187458b5820eac8c4 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Tue, 11 Apr 2006 13:12:34 -0400 Subject: libata: Add helper ata_shost_to_port() --- include/linux/libata.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 2564bc514bca..fe0a1dcc76c2 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -33,6 +33,7 @@ #include #include #include +#include /* * compile-time options: to be removed as soon as all the drivers are @@ -977,4 +978,9 @@ static inline void ata_pad_free(struct ata_port *ap, struct device *dev) dma_free_coherent(dev, ATA_DMA_PAD_BUF_SZ, ap->pad, ap->pad_dma); } +static inline struct ata_port *ata_shost_to_port(struct Scsi_Host *host) +{ + return (struct ata_port *) &host->hostdata[0]; +} + #endif /* __LINUX_LIBATA_H__ */ -- cgit v1.2.3 From 2bf2cb26b2512c6a609bb152982c388329bedff6 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 11 Apr 2006 22:16:45 +0900 Subject: [PATCH] libata: kill @verbose from ata_reset_fn_t @verbose was added to ata_reset_fn_t because AHCI complained during probing if no device was attached to the port. However, muting failure message isn't the correct approach. Reset methods are responsible for detecting no device condition and finishing successfully. Now that AHCI softreset is fixed, kill @verbose. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index fe0a1dcc76c2..d5fd5c06e755 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -252,7 +252,7 @@ struct ata_queued_cmd; /* typedefs */ typedef void (*ata_qc_cb_t) (struct ata_queued_cmd *qc); typedef void (*ata_probeinit_fn_t)(struct ata_port *); -typedef int (*ata_reset_fn_t)(struct ata_port *, int, unsigned int *); +typedef int (*ata_reset_fn_t)(struct ata_port *, unsigned int *); typedef void (*ata_postreset_fn_t)(struct ata_port *ap, unsigned int *); struct ata_ioports { @@ -509,10 +509,8 @@ extern int ata_drive_probe_reset(struct ata_port *ap, ata_reset_fn_t softreset, ata_reset_fn_t hardreset, ata_postreset_fn_t postreset, unsigned int *classes); extern void ata_std_probeinit(struct ata_port *ap); -extern int ata_std_softreset(struct ata_port *ap, int verbose, - unsigned int *classes); -extern int sata_std_hardreset(struct ata_port *ap, int verbose, - unsigned int *class); +extern int ata_std_softreset(struct ata_port *ap, unsigned int *classes); +extern int sata_std_hardreset(struct ata_port *ap, unsigned int *class); extern void ata_std_postreset(struct ata_port *ap, unsigned int *classes); extern int ata_dev_revalidate(struct ata_port *ap, struct ata_device *dev, int post_reset); -- cgit v1.2.3 From c22daff41001e9ccead87179ac0547f85447139e Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 11 Apr 2006 22:22:29 +0900 Subject: [PATCH] libata: implement ata_wait_register() As waiting for some register bits to change seems to be a common operation shared by some controllers, implement helper function ata_wait_register(). This function also takes care of register write flushing. Note that the condition is inverted, the wait is over when the masked value does NOT match @val. As we're waiting for bits to change, this test is more powerful and allows the function to be used in more places. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index d5fd5c06e755..dd5bcb5d29b5 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -543,6 +543,9 @@ extern unsigned int ata_busy_sleep(struct ata_port *ap, unsigned long timeout); extern void ata_port_queue_task(struct ata_port *ap, void (*fn)(void *), void *data, unsigned long delay); +extern u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val, + unsigned long interval_msec, + unsigned long timeout_msec); /* * Default driver ops implementations -- cgit v1.2.3 From 499a86af41cf5a4bf811726841bbc49c0e96fd35 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Tue, 11 Apr 2006 22:32:18 +0900 Subject: [PATCH] libata: export ata_set_sata_spd() This will be used by LLDD hardreset implementation. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index dd5bcb5d29b5..d35b1e3bb7e0 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -504,6 +504,7 @@ extern void ata_port_probe(struct ata_port *); extern void __sata_phy_reset(struct ata_port *ap); extern void sata_phy_reset(struct ata_port *ap); extern void ata_bus_reset(struct ata_port *ap); +extern int ata_set_sata_spd(struct ata_port *ap); extern int ata_drive_probe_reset(struct ata_port *ap, ata_probeinit_fn_t probeinit, ata_reset_fn_t softreset, ata_reset_fn_t hardreset, -- cgit v1.2.3 From 32e62c636a728cb39c0b3bd191286f2ca65d4028 Mon Sep 17 00:00:00 2001 From: Bjorn Helgaas Date: Fri, 5 May 2006 17:19:50 -0600 Subject: [IA64] rework memory attribute aliasing This closes a couple holes in our attribute aliasing avoidance scheme: - The current kernel fails mmaps of some /dev/mem MMIO regions because they don't appear in the EFI memory map. This keeps X from working on the Intel Tiger box. - The current kernel allows UC mmap of the 0-1MB region of /sys/.../legacy_mem even when the chipset doesn't support UC access. This causes an MCA when starting X on HP rx7620 and rx8620 boxes in the default configuration. There's more detail in the Documentation/ia64/aliasing.txt file this adds, but the general idea is that if a region might be covered by a granule-sized kernel identity mapping, any access via /dev/mem or mmap must use the same attribute as the identity mapping. Otherwise, we fall back to using an attribute that is supported according to the EFI memory map, or to using UC if the EFI memory map doesn't mention the region. Signed-off-by: Bjorn Helgaas Signed-off-by: Tony Luck --- include/linux/efi.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/efi.h b/include/linux/efi.h index e203613d3aec..66d621dbcb6c 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h @@ -294,6 +294,7 @@ extern void efi_enter_virtual_mode (void); /* switch EFI to virtual mode, if pos extern u64 efi_get_iobase (void); extern u32 efi_mem_type (unsigned long phys_addr); extern u64 efi_mem_attributes (unsigned long phys_addr); +extern u64 efi_mem_attribute (unsigned long phys_addr, unsigned long size); extern int efi_mem_attribute_range (unsigned long phys_addr, unsigned long size, u64 attr); extern int __init efi_uart_console_only (void); -- cgit v1.2.3 From 3c567b7d1137633f3ff67cd1df94abc5fd497a85 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 15 May 2006 20:57:23 +0900 Subject: [PATCH] libata: rename ata_down_sata_spd_limit() and friends Rename ata_down_sata_spd_limit() and friends to sata_down_spd_limit() and likewise for simplicity & consistency. Signed-off-by: Tejun Heo --- include/linux/libata.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index d35b1e3bb7e0..0b67aafd3878 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -504,7 +504,7 @@ extern void ata_port_probe(struct ata_port *); extern void __sata_phy_reset(struct ata_port *ap); extern void sata_phy_reset(struct ata_port *ap); extern void ata_bus_reset(struct ata_port *ap); -extern int ata_set_sata_spd(struct ata_port *ap); +extern int sata_set_spd(struct ata_port *ap); extern int ata_drive_probe_reset(struct ata_port *ap, ata_probeinit_fn_t probeinit, ata_reset_fn_t softreset, ata_reset_fn_t hardreset, -- cgit v1.2.3 From 6cd727b14f1a6cdcb088d1067c1ba0ba124806a7 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 15 May 2006 20:57:28 +0900 Subject: [PATCH] libata: kill duplicate prototypes Kill duplicate prototypes for ata_eh_qc_complete/retry() in libata.h. Signed-off-by: Tejun Heo --- include/linux/libata.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 0b67aafd3878..220b9d7bfc28 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -530,8 +530,6 @@ extern void ata_host_set_remove(struct ata_host_set *host_set); extern int ata_scsi_detect(struct scsi_host_template *sht); extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg); extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)); -extern void ata_eh_qc_complete(struct ata_queued_cmd *qc); -extern void ata_eh_qc_retry(struct ata_queued_cmd *qc); extern int ata_scsi_release(struct Scsi_Host *host); extern unsigned int ata_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc); extern int ata_scsi_device_resume(struct scsi_device *); -- cgit v1.2.3 From fe635c7e91036282e4fd0cc5b4eebc712e43270d Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 15 May 2006 20:57:35 +0900 Subject: [PATCH] libata: use preallocated buffers It's not a very good idea to allocate memory during EH. Use statically allocated buffer for dev->id[] and add 512byte buffer ap->sector_buf. This buffer is owned by EH (or probing) and to be used as temporary buffer for various purposes (IDENTIFY, NCQ log page 10h, PM GSCR block). Signed-off-by: Tejun Heo --- include/linux/libata.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 220b9d7bfc28..0e1a3be39475 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -360,7 +360,7 @@ struct ata_device { unsigned long flags; /* ATA_DFLAG_xxx */ unsigned int class; /* ATA_DEV_xxx */ unsigned int devno; /* 0 or 1 */ - u16 *id; /* IDENTIFY xxx DEVICE data */ + u16 id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */ u8 pio_mode; u8 dma_mode; u8 xfer_mode; @@ -425,6 +425,8 @@ struct ata_port { struct list_head eh_done_q; void *private_data; + + u8 sector_buf[ATA_SECT_SIZE]; /* owned by EH */ }; struct ata_port_operations { -- cgit v1.2.3 From e61e067227bc76b4d9411a50d735c9d87f27b0e2 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 15 May 2006 20:57:40 +0900 Subject: [PATCH] libata: implement qc->result_tf Add qc->result_tf and ATA_QCFLAG_RESULT_TF. This moves the responsibility of loading result TF from post-compltion path to qc execution path. qc->result_tf is loaded if explicitly requested or the qc failsa. This allows more efficient completion implementation and correct handling of result TF for controllers which don't have global TF representation such as sil3124/32. Signed-off-by: Tejun Heo --- include/linux/libata.h | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 0e1a3be39475..a4b8a419caad 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -162,7 +162,9 @@ enum { ATA_QCFLAG_SINGLE = (1 << 2), /* no s/g, just a single buffer */ ATA_QCFLAG_DMAMAP = ATA_QCFLAG_SG | ATA_QCFLAG_SINGLE, ATA_QCFLAG_IO = (1 << 3), /* standard IO command */ - ATA_QCFLAG_EH_SCHEDULED = (1 << 4), /* EH scheduled */ + ATA_QCFLAG_RESULT_TF = (1 << 4), /* result TF requested */ + + ATA_QCFLAG_EH_SCHEDULED = (1 << 16), /* EH scheduled */ /* host set flags */ ATA_HOST_SIMPLEX = (1 << 0), /* Host is simplex, one DMA channel per host_set only */ @@ -343,7 +345,7 @@ struct ata_queued_cmd { struct scatterlist *__sg; unsigned int err_mask; - + struct ata_taskfile result_tf; ata_qc_cb_t complete_fn; void *private_data; @@ -824,6 +826,10 @@ static inline void ata_qc_reinit(struct ata_queued_cmd *qc) qc->err_mask = 0; ata_tf_init(qc->ap, &qc->tf, qc->dev->devno); + + /* init result_tf such that it indicates normal completion */ + qc->result_tf.command = ATA_DRDY; + qc->result_tf.feature = 0; } /** @@ -839,9 +845,15 @@ static inline void ata_qc_reinit(struct ata_queued_cmd *qc) */ static inline void ata_qc_complete(struct ata_queued_cmd *qc) { + struct ata_port *ap = qc->ap; + if (unlikely(qc->flags & ATA_QCFLAG_EH_SCHEDULED)) return; + /* read result TF if failed or requested */ + if (qc->err_mask || qc->flags & ATA_QCFLAG_RESULT_TF) + ap->ops->tf_read(ap, &qc->result_tf); + __ata_qc_complete(qc); } -- cgit v1.2.3 From 34bf21704c848fe00c516d1c8f163db08b70b137 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 15 May 2006 20:57:46 +0900 Subject: [PATCH] libata: implement new SCR handling and port on/offline functions Implement ata_scr_{valid|read|write|write_flush}() and ata_port_{online|offline}(). These functions replace scr_{read|write}() and sata_dev_present(). Major difference between between the new SCR functions and the old ones is that the new ones have a way to signal error to the caller. This makes handling SCR-available and SCR-unavailable cases in the same path easier. Also, it eases later PM implementation where SCR access can fail due to various reasons. ata_port_{online|offline}() functions return 1 only when they are affirmitive of the condition. e.g. if SCR is unaccessible or presence cannot be determined for other reasons, these functions return 0. So, ata_port_online() != !ata_port_offline(). This distinction is useful in many exception handling cases. Signed-off-by: Tejun Heo --- include/linux/libata.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index a4b8a419caad..47b97157995d 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -536,6 +536,12 @@ extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg); extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)); extern int ata_scsi_release(struct Scsi_Host *host); extern unsigned int ata_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc); +extern int sata_scr_valid(struct ata_port *ap); +extern int sata_scr_read(struct ata_port *ap, int reg, u32 *val); +extern int sata_scr_write(struct ata_port *ap, int reg, u32 val); +extern int sata_scr_write_flush(struct ata_port *ap, int reg, u32 val); +extern int ata_port_online(struct ata_port *ap); +extern int ata_port_offline(struct ata_port *ap); extern int ata_scsi_device_resume(struct scsi_device *); extern int ata_scsi_device_suspend(struct scsi_device *, pm_message_t state); extern int ata_device_resume(struct ata_port *, struct ata_device *); -- cgit v1.2.3 From a0ab51cefc95cb7756c4914603fea2b1a0f813c5 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 15 May 2006 20:57:49 +0900 Subject: [PATCH] libata: kill old SCR functions and sata_dev_present() Kill now unused scr_{read|write|write_flush}() and sata_dev_present(). Signed-off-by: Tejun Heo --- include/linux/libata.h | 22 ---------------------- 1 file changed, 22 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 47b97157995d..cd467cd54473 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -939,28 +939,6 @@ static inline u8 ata_irq_ack(struct ata_port *ap, unsigned int chk_drq) return status; } -static inline u32 scr_read(struct ata_port *ap, unsigned int reg) -{ - return ap->ops->scr_read(ap, reg); -} - -static inline void scr_write(struct ata_port *ap, unsigned int reg, u32 val) -{ - ap->ops->scr_write(ap, reg, val); -} - -static inline void scr_write_flush(struct ata_port *ap, unsigned int reg, - u32 val) -{ - ap->ops->scr_write(ap, reg, val); - (void) ap->ops->scr_read(ap, reg); -} - -static inline unsigned int sata_dev_present(struct ata_port *ap) -{ - return ((scr_read(ap, SCR_STATUS) & 0xf) == 0x3) ? 1 : 0; -} - static inline int ata_try_flush_cache(const struct ata_device *dev) { return ata_id_wcache_enabled(dev->id) || -- cgit v1.2.3 From 38d87234d6c47ca487fc6344100323d5adc6f32c Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 15 May 2006 20:57:51 +0900 Subject: [PATCH] libata: add dev->ap Add dev->ap which points back to the port the device belongs to. This makes it unnecessary to pass @ap for silly reasons (e.g. printks). Also, this change is necessary to accomodate later PM support which will introduce ATA link inbetween port and device. Signed-off-by: Tejun Heo --- include/linux/libata.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index cd467cd54473..ac2d2cc78b10 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -358,6 +358,7 @@ struct ata_host_stats { }; struct ata_device { + struct ata_port *ap; u64 n_sectors; /* size of device, if ATA */ unsigned long flags; /* ATA_DFLAG_xxx */ unsigned int class; /* ATA_DEV_xxx */ -- cgit v1.2.3 From 3373efd89dead4ce7818d685729e0431448357c9 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 15 May 2006 20:57:53 +0900 Subject: [PATCH] libata: use dev->ap Use dev->ap where possible and eliminate superflous @ap from functions and structures. Signed-off-by: Tejun Heo --- include/linux/libata.h | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index ac2d2cc78b10..8154b366bbd1 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -518,8 +518,7 @@ extern void ata_std_probeinit(struct ata_port *ap); extern int ata_std_softreset(struct ata_port *ap, unsigned int *classes); extern int sata_std_hardreset(struct ata_port *ap, unsigned int *class); extern void ata_std_postreset(struct ata_port *ap, unsigned int *classes); -extern int ata_dev_revalidate(struct ata_port *ap, struct ata_device *dev, - int post_reset); +extern int ata_dev_revalidate(struct ata_device *dev, int post_reset); extern void ata_port_disable(struct ata_port *); extern void ata_std_ports(struct ata_ioports *ioaddr); #ifdef CONFIG_PCI @@ -545,8 +544,8 @@ extern int ata_port_online(struct ata_port *ap); extern int ata_port_offline(struct ata_port *ap); extern int ata_scsi_device_resume(struct scsi_device *); extern int ata_scsi_device_suspend(struct scsi_device *, pm_message_t state); -extern int ata_device_resume(struct ata_port *, struct ata_device *); -extern int ata_device_suspend(struct ata_port *, struct ata_device *, pm_message_t state); +extern int ata_device_resume(struct ata_device *); +extern int ata_device_suspend(struct ata_device *, pm_message_t state); extern int ata_ratelimit(void); extern unsigned int ata_busy_sleep(struct ata_port *ap, unsigned long timeout_pat, @@ -592,15 +591,13 @@ extern void ata_bmdma_stop(struct ata_queued_cmd *qc); extern u8 ata_bmdma_status(struct ata_port *ap); extern void ata_bmdma_irq_clear(struct ata_port *ap); extern void __ata_qc_complete(struct ata_queued_cmd *qc); -extern void ata_scsi_simulate(struct ata_port *ap, struct ata_device *dev, - struct scsi_cmnd *cmd, +extern void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)); extern int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int geom[]); extern int ata_scsi_slave_config(struct scsi_device *sdev); -extern struct ata_device *ata_dev_pair(struct ata_port *ap, - struct ata_device *adev); +extern struct ata_device *ata_dev_pair(struct ata_device *adev); /* * Timing helpers @@ -812,12 +809,12 @@ static inline struct ata_queued_cmd *ata_qc_from_tag (struct ata_port *ap, return NULL; } -static inline void ata_tf_init(struct ata_port *ap, struct ata_taskfile *tf, unsigned int device) +static inline void ata_tf_init(struct ata_device *dev, struct ata_taskfile *tf) { memset(tf, 0, sizeof(*tf)); - tf->ctl = ap->ctl; - if (device == 0) + tf->ctl = dev->ap->ctl; + if (dev->devno == 0) tf->device = ATA_DEVICE_OBS; else tf->device = ATA_DEVICE_OBS | ATA_DEV1; @@ -832,7 +829,7 @@ static inline void ata_qc_reinit(struct ata_queued_cmd *qc) qc->nbytes = qc->curbytes = 0; qc->err_mask = 0; - ata_tf_init(qc->ap, &qc->tf, qc->dev->devno); + ata_tf_init(qc->dev, &qc->tf); /* init result_tf such that it indicates normal completion */ qc->result_tf.command = ATA_DRDY; -- cgit v1.2.3 From 61440db61fe4945ad9f7b32b4d6a22b17174aa1f Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 15 May 2006 20:57:55 +0900 Subject: [PATCH] libata: implement ATA printk helpers Implement ata_{port|dev}_printk() which prefixes the message with proper identification string. This change is necessary for later PM support because devices and links should be identified differently depending on how they are attached. This also helps unifying device id strings. Currently, there are two forms in use (P is the port number D device number) - 'ataP(D):', and 'ataP: dev D '. These macros also make it harder to forget proper ID string (e.g. printing only port number when a device is in question). Debug message handling can be integrated into these printk macros by passing debug type and level via @lv. Signed-off-by: Tejun Heo --- include/linux/libata.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 8154b366bbd1..91e10e6b7565 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -650,7 +650,18 @@ extern void ata_eng_timeout(struct ata_port *ap); extern void ata_eh_qc_complete(struct ata_queued_cmd *qc); extern void ata_eh_qc_retry(struct ata_queued_cmd *qc); +/* + * printk helpers + */ +#define ata_port_printk(ap, lv, fmt, args...) \ + printk(lv"ata%u: "fmt, (ap)->id , ##args) + +#define ata_dev_printk(dev, lv, fmt, args...) \ + printk(lv"ata%u.%02u: "fmt, (dev)->ap->id, (dev)->devno , ##args) +/* + * qc helpers + */ static inline int ata_sg_is_last(struct scatterlist *sg, struct ata_queued_cmd *qc) { -- cgit v1.2.3 From 9ec957f2002bd2994be659bbc0ec28397fa251ee Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 15 May 2006 20:57:58 +0900 Subject: [PATCH] libata-eh-fw: add flags and operations for new EH Add ATA_FLAG_EH_{PENDING|FROZEN}, ATA_ATA_QCFLAG_{FAILED|SENSE_VALID} and ops->freeze, thaw, error_handler, post_internal_cmd() for new EH. Signed-off-by: Tejun Heo --- include/linux/libata.h | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 91e10e6b7565..e5d6d7f8e6dc 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -146,13 +146,16 @@ enum { ATA_FLAG_PIO_LBA48 = (1 << 8), /* Host DMA engine is LBA28 only */ ATA_FLAG_IRQ_MASK = (1 << 9), /* Mask IRQ in PIO xfers */ - ATA_FLAG_NOINTR = (1 << 16), /* FIXME: Remove this once + ATA_FLAG_NOINTR = (1 << 13), /* FIXME: Remove this once * proper HSM is in place. */ - ATA_FLAG_DEBUGMSG = (1 << 17), - ATA_FLAG_FLUSH_PORT_TASK = (1 << 18), /* flush port task */ + ATA_FLAG_DEBUGMSG = (1 << 14), + ATA_FLAG_FLUSH_PORT_TASK = (1 << 15), /* flush port task */ - ATA_FLAG_DISABLED = (1 << 19), /* port is disabled, ignore it */ - ATA_FLAG_SUSPENDED = (1 << 20), /* port is suspended */ + ATA_FLAG_EH_PENDING = (1 << 16), /* EH pending */ + ATA_FLAG_FROZEN = (1 << 17), /* port is frozen */ + + ATA_FLAG_DISABLED = (1 << 22), /* port is disabled, ignore it */ + ATA_FLAG_SUSPENDED = (1 << 23), /* port is suspended (power) */ /* bits 24:31 of ap->flags are reserved for LLDD specific flags */ @@ -164,7 +167,9 @@ enum { ATA_QCFLAG_IO = (1 << 3), /* standard IO command */ ATA_QCFLAG_RESULT_TF = (1 << 4), /* result TF requested */ - ATA_QCFLAG_EH_SCHEDULED = (1 << 16), /* EH scheduled */ + ATA_QCFLAG_FAILED = (1 << 16), /* cmd failed and is owned by EH */ + ATA_QCFLAG_SENSE_VALID = (1 << 17), /* sense data valid */ + ATA_QCFLAG_EH_SCHEDULED = (1 << 18), /* EH scheduled (obsolete) */ /* host set flags */ ATA_HOST_SIMPLEX = (1 << 0), /* Host is simplex, one DMA channel per host_set only */ @@ -463,7 +468,15 @@ struct ata_port_operations { void (*qc_prep) (struct ata_queued_cmd *qc); unsigned int (*qc_issue) (struct ata_queued_cmd *qc); - void (*eng_timeout) (struct ata_port *ap); + /* Error handlers. ->error_handler overrides ->eng_timeout and + * indicates that new-style EH is in place. + */ + void (*eng_timeout) (struct ata_port *ap); /* obsolete */ + + void (*freeze) (struct ata_port *ap); + void (*thaw) (struct ata_port *ap); + void (*error_handler) (struct ata_port *ap); + void (*post_internal_cmd) (struct ata_queued_cmd *qc); irqreturn_t (*irq_handler)(int, void *, struct pt_regs *); void (*irq_clear) (struct ata_port *); -- cgit v1.2.3 From 2ab7db1ff1d64a2ba389d0692d532f42a15f1f72 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 15 May 2006 20:58:02 +0900 Subject: [PATCH] libata-eh-fw: use special reserved tag and qc for internal commands New EH may issue internal commands to recover from error while failed qc's are still hanging around. To allow such usage, reserve tag ATA_MAX_QUEUE-1 for internal command. This also makes it easy to tell whether a qc is for internal command or not. ata_tag_internal() test implements this test. To avoid breaking existing drivers, ata_exec_internal() uses ATA_TAG_INTERNAL only for drivers which implement ->error_handler. For drivers using old EH, tag 0 is used. Note that this makes ata_tag_internal() test valid only when ->error_handler is implemented. This is okay as drivers on old EH should not and does not have any reason to use ata_tag_internal(). Signed-off-by: Tejun Heo --- include/linux/libata.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index e5d6d7f8e6dc..5a403e434ff8 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -108,7 +108,9 @@ enum { LIBATA_MAX_PRD = ATA_MAX_PRD / 2, ATA_MAX_PORTS = 8, ATA_DEF_QUEUE = 1, - ATA_MAX_QUEUE = 1, + /* tag ATA_MAX_QUEUE - 1 is reserved for internal commands */ + ATA_MAX_QUEUE = 2, + ATA_TAG_INTERNAL = ATA_MAX_QUEUE - 1, ATA_MAX_SECTORS = 200, /* FIXME */ ATA_MAX_BUS = 2, ATA_DEF_BUSY_WAIT = 10000, @@ -717,6 +719,11 @@ static inline unsigned int ata_tag_valid(unsigned int tag) return (tag < ATA_MAX_QUEUE) ? 1 : 0; } +static inline unsigned int ata_tag_internal(unsigned int tag) +{ + return tag == ATA_MAX_QUEUE - 1; +} + static inline unsigned int ata_class_enabled(unsigned int class) { return class == ATA_DEV_ATA || class == ATA_DEV_ATAPI; -- cgit v1.2.3 From f69499f42caf74194df678c9c293f2ee0fe90bc3 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 15 May 2006 20:58:03 +0900 Subject: [PATCH] libata-eh-fw: update ata_qc_from_tag() to enforce normal/EH qc ownership New EH framework has clear distinction about who owns a qc. Every qc starts owned by normal execution path - PIO, interrupt or whatever. When an exception condition occurs which affects the qc, the qc gets scheduled for EH. Note that some events (say, link lost and regained, command timeout) may schedule qc's which are not directly related but could have been affected for EH too. Scheduling for EH is atomic w.r.t. ap->host_set->lock and once schedule for EH, normal execution path is not allowed to access the qc in whatever way. (PIO synchronization acts a bit different and will be dealt with later) This patch make ata_qc_from_tag() check whether a qc is active and owned by normal path before returning it. If conditions don't match, NULL is returned and thus access to the qc is denied. __ata_qc_from_tag() is the original ata_qc_from_tag() and is used by libata core/EH layers to access inactive/failed qc's. This change is applied only if the associated LLDD implements new EH as indicated by non-NULL ->error_handler Signed-off-by: Tejun Heo --- include/linux/libata.h | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 5a403e434ff8..bfcefdca0616 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -832,14 +832,29 @@ static inline void ata_qc_set_polling(struct ata_queued_cmd *qc) qc->tf.ctl |= ATA_NIEN; } -static inline struct ata_queued_cmd *ata_qc_from_tag (struct ata_port *ap, - unsigned int tag) +static inline struct ata_queued_cmd *__ata_qc_from_tag(struct ata_port *ap, + unsigned int tag) { if (likely(ata_tag_valid(tag))) return &ap->qcmd[tag]; return NULL; } +static inline struct ata_queued_cmd *ata_qc_from_tag(struct ata_port *ap, + unsigned int tag) +{ + struct ata_queued_cmd *qc = __ata_qc_from_tag(ap, tag); + + if (unlikely(!qc) || !ap->ops->error_handler) + return qc; + + if ((qc->flags & (ATA_QCFLAG_ACTIVE | + ATA_QCFLAG_FAILED)) == ATA_QCFLAG_ACTIVE) + return qc; + + return NULL; +} + static inline void ata_tf_init(struct ata_device *dev, struct ata_taskfile *tf) { memset(tf, 0, sizeof(*tf)); -- cgit v1.2.3 From f686bcb8078ac7505ec88818886c2c72639f4fc5 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 15 May 2006 20:58:05 +0900 Subject: [PATCH] libata-eh-fw: implement new EH scheduling via error completion There are several ways a qc can get schedule for EH in new EH. This patch implements one of them - completing a qc with ATA_QCFLAG_FAILED set or with non-zero qc->err_mask. ALL such qc's are examined by EH. New EH schedules a qc for EH from completion iff ->error_handler is implemented, qc is marked as failed or qc->err_mask is non-zero and the command is not an internal command (internal cmd is handled via ->post_internal_cmd). The EH scheduling itself is performed by asking SCSI midlayer to schedule EH for the specified scmd. For drivers implementing old-EH, nothing changes. As this change makes ata_qc_complete() rather large, it's not inlined anymore and __ata_qc_complete() is exported to other parts of libata for later use. Signed-off-by: Tejun Heo --- include/linux/libata.h | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index bfcefdca0616..6023f324e68e 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -605,7 +605,7 @@ extern void ata_bmdma_start (struct ata_queued_cmd *qc); extern void ata_bmdma_stop(struct ata_queued_cmd *qc); extern u8 ata_bmdma_status(struct ata_port *ap); extern void ata_bmdma_irq_clear(struct ata_port *ap); -extern void __ata_qc_complete(struct ata_queued_cmd *qc); +extern void ata_qc_complete(struct ata_queued_cmd *qc); extern void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)); extern int ata_std_bios_param(struct scsi_device *sdev, @@ -882,31 +882,6 @@ static inline void ata_qc_reinit(struct ata_queued_cmd *qc) qc->result_tf.feature = 0; } -/** - * ata_qc_complete - Complete an active ATA command - * @qc: Command to complete - * @err_mask: ATA Status register contents - * - * Indicate to the mid and upper layers that an ATA - * command has completed, with either an ok or not-ok status. - * - * LOCKING: - * spin_lock_irqsave(host_set lock) - */ -static inline void ata_qc_complete(struct ata_queued_cmd *qc) -{ - struct ata_port *ap = qc->ap; - - if (unlikely(qc->flags & ATA_QCFLAG_EH_SCHEDULED)) - return; - - /* read result TF if failed or requested */ - if (qc->err_mask || qc->flags & ATA_QCFLAG_RESULT_TF) - ap->ops->tf_read(ap, &qc->result_tf); - - __ata_qc_complete(qc); -} - /** * ata_irq_on - Enable interrupts on a port. * @ap: Port on which interrupts are enabled. -- cgit v1.2.3 From 7b70fc039824bc7303e4007a5f758f832de56611 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 15 May 2006 20:58:07 +0900 Subject: [PATCH] libata-eh-fw: implement ata_port_schedule_eh() and ata_port_abort() ata_port_schedule_eh() directly schedules EH for @ap without associated qc. Once EH scheduled, no further qc is allowed and EH kicks in as soon as all currently active qc's are drained. ata_port_abort() schedules all currently active commands for EH by qc_completing them with ATA_QCFLAG_FAILED set. If ata_port_abort() doesn't find any qc to abort, it directly schedule EH using ata_port_schedule_eh(). These two functions provide ways to invoke EH for conditions which aren't directly related to any specfic qc. Signed-off-by: Tejun Heo --- include/linux/libata.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 6023f324e68e..086e14690954 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -662,6 +662,10 @@ extern unsigned long ata_pci_default_filter(const struct ata_port *, struct ata_ * EH */ extern void ata_eng_timeout(struct ata_port *ap); + +extern void ata_port_schedule_eh(struct ata_port *ap); +extern int ata_port_abort(struct ata_port *ap); + extern void ata_eh_qc_complete(struct ata_queued_cmd *qc); extern void ata_eh_qc_retry(struct ata_queued_cmd *qc); -- cgit v1.2.3 From e318049949b07152d851dbfebbd93e560af45ebe Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 15 May 2006 20:58:09 +0900 Subject: [PATCH] libata-eh-fw: implement freeze/thaw Freezing is performed atomic w.r.t. host_set->lock and once frozen LLDD is not allowed to access the port or any qc on it. Also, libata makes sure that no new qc gets issued to a frozen port. A frozen port is thawed after a reset operation completes successfully, so reset methods must do its job while the port is frozen. During initialization all ports get frozen before requesting IRQ, so reset methods are always invoked on a frozen port. Optional ->freeze and ->thaw operations notify LLDD that the port is being frozen and thawed, respectively. LLDD can disable/enable hardware interrupt in these callbacks if the controller's IRQ mask can be changed dynamically. If the controller doesn't allow such operation, LLDD can check for frozen state in the interrupt handler and ack/clear interrupts unconditionally while frozen. Signed-off-by: Tejun Heo --- include/linux/libata.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 086e14690954..6758b4d374a0 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -665,6 +665,10 @@ extern void ata_eng_timeout(struct ata_port *ap); extern void ata_port_schedule_eh(struct ata_port *ap); extern int ata_port_abort(struct ata_port *ap); +extern int ata_port_freeze(struct ata_port *ap); + +extern void ata_eh_freeze_port(struct ata_port *ap); +extern void ata_eh_thaw_port(struct ata_port *ap); extern void ata_eh_qc_complete(struct ata_queued_cmd *qc); extern void ata_eh_qc_retry(struct ata_queued_cmd *qc); -- cgit v1.2.3 From ad9e27624479bd167dd7eac0cea4bb3ad13bc926 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 15 May 2006 20:58:12 +0900 Subject: [PATCH] libata-eh-fw: update ata_scsi_error() for new EH Update ata_scsi_error() for new EH. ata_scsi_error() is responsible for claiming timed out qcs and invoking ->error_handler in safe and synchronized manner. As the state of the controller is unknown if a qc has timed out, the port is frozen in such cases. Note that ata_scsi_timed_out() isn't used for new EH. This is because a timed out qc cannot be claimed by EH without freezing the port and freezing the port in ata_scsi_timed_out() results in unnecessary abortion of other active qcs. ata_scsi_timed_out() can be removed once all drivers are converted to new EH. While at it, add 'TODO: kill' comments to old EH functions. Signed-off-by: Tejun Heo --- include/linux/libata.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 6758b4d374a0..5ad50163c8ef 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -225,6 +225,9 @@ enum { ATA_PORT_PRIMARY = (1 << 0), ATA_PORT_SECONDARY = (1 << 1), + /* max repeat if error condition is still set after ->error_handler */ + ATA_EH_MAX_REPEAT = 5, + /* how hard are we gonna try to probe/recover devices */ ATA_PROBE_MAX_TRIES = 3, }; -- cgit v1.2.3 From 9be1e979f2e1e57a091a658fa88dac266f9fd6fe Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 15 May 2006 20:58:17 +0900 Subject: [PATCH] libata-eh: add ATA and libata flags for new EH Add ATA and libata flags to be used by new EH. Signed-off-by: Tejun Heo --- include/linux/ata.h | 13 +++++++++++++ include/linux/libata.h | 8 ++++++++ 2 files changed, 21 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ata.h b/include/linux/ata.h index 312a2c0c64e6..a7c41f3df8f4 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -97,6 +97,9 @@ enum { ATA_DRQ = (1 << 3), /* data request i/o */ ATA_ERR = (1 << 0), /* have an error */ ATA_SRST = (1 << 2), /* software reset */ + ATA_ICRC = (1 << 7), /* interface CRC error */ + ATA_UNC = (1 << 6), /* uncorrectable media error */ + ATA_IDNF = (1 << 4), /* ID not found */ ATA_ABORTED = (1 << 2), /* command aborted */ /* ATA command block registers */ @@ -192,6 +195,16 @@ enum { SCR_ACTIVE = 3, SCR_NOTIFICATION = 4, + /* SError bits */ + SERR_DATA_RECOVERED = (1 << 0), /* recovered data error */ + SERR_COMM_RECOVERED = (1 << 1), /* recovered comm failure */ + SERR_DATA = (1 << 8), /* unrecovered data error */ + SERR_PERSISTENT = (1 << 9), /* persistent data/comm error */ + SERR_PROTOCOL = (1 << 10), /* protocol violation */ + SERR_INTERNAL = (1 << 11), /* host internal error */ + SERR_PHYRDY_CHG = (1 << 16), /* PHY RDY changed */ + SERR_DEV_XCHG = (1 << 26), /* device exchanged */ + /* struct ata_taskfile flags */ ATA_TFLAG_LBA48 = (1 << 0), /* enable 48-bit LBA and "HOB" */ ATA_TFLAG_ISADDR = (1 << 1), /* enable r/w to nsect/lba regs */ diff --git a/include/linux/libata.h b/include/linux/libata.h index 5ad50163c8ef..6fe5ed8eabf5 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -155,6 +155,7 @@ enum { ATA_FLAG_EH_PENDING = (1 << 16), /* EH pending */ ATA_FLAG_FROZEN = (1 << 17), /* port is frozen */ + ATA_FLAG_RECOVERED = (1 << 18), /* recovery action performed */ ATA_FLAG_DISABLED = (1 << 22), /* port is disabled, ignore it */ ATA_FLAG_SUSPENDED = (1 << 23), /* port is suspended (power) */ @@ -225,6 +226,13 @@ enum { ATA_PORT_PRIMARY = (1 << 0), ATA_PORT_SECONDARY = (1 << 1), + /* reset / recovery action types */ + ATA_EH_REVALIDATE = (1 << 0), + ATA_EH_SOFTRESET = (1 << 1), + ATA_EH_HARDRESET = (1 << 2), + + ATA_EH_RESET_MASK = ATA_EH_SOFTRESET | ATA_EH_HARDRESET, + /* max repeat if error condition is still set after ->error_handler */ ATA_EH_MAX_REPEAT = 5, -- cgit v1.2.3 From 0c247c559cd70f85ba9f0764ce13ae00e20fcad8 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 15 May 2006 20:58:19 +0900 Subject: [PATCH] libata-eh: implement dev->ering This patch implements ata_ering and uses it to define dev->ering. ata_ering is a ring buffer which records libata errors - whether a command was for normar IO request, err_mask and timestamp. Errors are recorded per-device in dev->ering. This will be used by EH to determine recovery actions. Signed-off-by: Tejun Heo --- include/linux/libata.h | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 6fe5ed8eabf5..f5cea13599c3 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -226,6 +226,9 @@ enum { ATA_PORT_PRIMARY = (1 << 0), ATA_PORT_SECONDARY = (1 << 1), + /* ering size */ + ATA_ERING_SIZE = 32, + /* reset / recovery action types */ ATA_EH_REVALIDATE = (1 << 0), ATA_EH_SOFTRESET = (1 << 1), @@ -375,6 +378,17 @@ struct ata_host_stats { unsigned long rw_reqbuf; }; +struct ata_ering_entry { + int is_io; + unsigned int err_mask; + u64 timestamp; +}; + +struct ata_ering { + int cursor; + struct ata_ering_entry ring[ATA_ERING_SIZE]; +}; + struct ata_device { struct ata_port *ap; u64 n_sectors; /* size of device, if ATA */ @@ -401,6 +415,9 @@ struct ata_device { u16 cylinders; /* Number of cylinders */ u16 heads; /* Number of heads */ u16 sectors; /* Number of sectors per track */ + + /* error history */ + struct ata_ering ering; }; struct ata_port { -- cgit v1.2.3 From f3e81b19aac23c0e8c55d5961324ef7de44c23bb Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 15 May 2006 20:58:21 +0900 Subject: [PATCH] libata-eh: implement ata_eh_info and ata_eh_context struct ata_eh_info serves as the communication channel between execution path and EH. Execution path describes detected error condition in ap->eh_info and EH recovers the port using it. To avoid missing error conditions detected during EH, EH makes its own copy of eh_info and clears it on entry allowing error info to accumulate during EH. Most EH states including EH's copy of eh_info are stored in ap->eh_context (struct ata_eh_context) which is owned by EH and thus doesn't require any synchronization to access and alter. This standardized context makes it easy to integrate various parts of EH and extend EH to handle multiple links (for PM). Signed-off-by: Tejun Heo --- include/linux/libata.h | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index f5cea13599c3..298f9918e375 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -229,6 +229,9 @@ enum { /* ering size */ ATA_ERING_SIZE = 32, + /* desc_len for ata_eh_info and context */ + ATA_EH_DESC_LEN = 80, + /* reset / recovery action types */ ATA_EH_REVALIDATE = (1 << 0), ATA_EH_SOFTRESET = (1 << 1), @@ -236,6 +239,9 @@ enum { ATA_EH_RESET_MASK = ATA_EH_SOFTRESET | ATA_EH_HARDRESET, + /* ata_eh_info->flags */ + ATA_EHI_DID_RESET = (1 << 0), /* already reset this port */ + /* max repeat if error condition is still set after ->error_handler */ ATA_EH_MAX_REPEAT = 5, @@ -420,6 +426,21 @@ struct ata_device { struct ata_ering ering; }; +struct ata_eh_info { + struct ata_device *dev; /* offending device */ + u32 serror; /* SError from LLDD */ + unsigned int err_mask; /* port-wide err_mask */ + unsigned int action; /* ATA_EH_* action mask */ + unsigned int flags; /* ATA_EHI_* flags */ + char desc[ATA_EH_DESC_LEN]; + int desc_len; +}; + +struct ata_eh_context { + struct ata_eh_info i; + int tries[ATA_MAX_DEVICES]; +}; + struct ata_port { struct Scsi_Host *host; /* our co-allocated scsi host */ const struct ata_port_operations *ops; @@ -444,6 +465,11 @@ struct ata_port { unsigned int cbl; /* cable type; ATA_CBL_xxx */ unsigned int sata_spd_limit; /* SATA PHY speed limit */ + /* record runtime error info, protected by host_set lock */ + struct ata_eh_info eh_info; + /* EH context owned by EH */ + struct ata_eh_context eh_context; + struct ata_device device[ATA_MAX_DEVICES]; struct ata_queued_cmd qcmd[ATA_MAX_QUEUE]; @@ -710,6 +736,20 @@ extern void ata_eh_qc_retry(struct ata_queued_cmd *qc); #define ata_dev_printk(dev, lv, fmt, args...) \ printk(lv"ata%u.%02u: "fmt, (dev)->ap->id, (dev)->devno , ##args) +/* + * ata_eh_info helpers + */ +#define ata_ehi_push_desc(ehi, fmt, args...) do { \ + (ehi)->desc_len += scnprintf((ehi)->desc + (ehi)->desc_len, \ + ATA_EH_DESC_LEN - (ehi)->desc_len, \ + fmt , ##args); \ +} while (0) + +#define ata_ehi_clear_desc(ehi) do { \ + (ehi)->desc[0] = '\0'; \ + (ehi)->desc_len = 0; \ +} while (0) + /* * qc helpers */ -- cgit v1.2.3 From 022bdb075b9e1f224088a0b268de56268d7bc5b6 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 15 May 2006 20:58:22 +0900 Subject: [PATCH] libata-eh: implement new EH Implement new EH. The exported interface is ata_do_eh() which is to be called from ->error_handler and performs the following steps to recover the failed port. ata_eh_autopsy() : analyze SError/TF, determine the cause of failure and required recovery actions and record it in ap->eh_context ata_eh_report() : report the failure to user ata_eh_recover() : perform recovery actions described in ap->eh_context ata_eh_finish() : finish failed qcs LLDDs can customize error handling by modifying eh_context before calling ata_do_eh() or, if necessary, doing so inbetween each major steps by calling each step explicitly. Signed-off-by: Tejun Heo --- include/linux/libata.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 298f9918e375..9fe46073cf8c 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -247,6 +247,8 @@ enum { /* how hard are we gonna try to probe/recover devices */ ATA_PROBE_MAX_TRIES = 3, + ATA_EH_RESET_TRIES = 3, + ATA_EH_DEV_TRIES = 3, }; enum hsm_task_states { @@ -727,6 +729,9 @@ extern void ata_eh_thaw_port(struct ata_port *ap); extern void ata_eh_qc_complete(struct ata_queued_cmd *qc); extern void ata_eh_qc_retry(struct ata_queued_cmd *qc); +extern void ata_do_eh(struct ata_port *ap, ata_reset_fn_t softreset, + ata_reset_fn_t hardreset, ata_postreset_fn_t postreset); + /* * printk helpers */ -- cgit v1.2.3 From 6d97dbd72da31a0e334f251fa9df4be9fab6fde2 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 15 May 2006 20:58:24 +0900 Subject: [PATCH] libata-eh: implement BMDMA EH Implement stock BMDMA error handling methods. Signed-off-by: Tejun Heo --- include/linux/libata.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 9fe46073cf8c..6ccacbf889e3 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -661,6 +661,14 @@ extern void ata_bmdma_start (struct ata_queued_cmd *qc); extern void ata_bmdma_stop(struct ata_queued_cmd *qc); extern u8 ata_bmdma_status(struct ata_port *ap); extern void ata_bmdma_irq_clear(struct ata_port *ap); +extern void ata_bmdma_freeze(struct ata_port *ap); +extern void ata_bmdma_thaw(struct ata_port *ap); +extern void ata_bmdma_drive_eh(struct ata_port *ap, + ata_reset_fn_t softreset, + ata_reset_fn_t hardreset, + ata_postreset_fn_t postreset); +extern void ata_bmdma_error_handler(struct ata_port *ap); +extern void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc); extern void ata_qc_complete(struct ata_queued_cmd *qc); extern void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)); -- cgit v1.2.3 From 88e490340ea4c3a2ebc0187a4339912e2fc1a081 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 15 May 2006 21:03:38 +0900 Subject: [PATCH] libata-ncq: add NCQ related ATA/libata constants and macros Add NCQ related ATA/libata constants and macros. Signed-off-by: Tejun Heo --- include/linux/ata.h | 9 +++++++++ include/linux/libata.h | 2 ++ 2 files changed, 11 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ata.h b/include/linux/ata.h index 1cbeb434af9a..c494e1c0531e 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -133,6 +133,8 @@ enum { ATA_CMD_WRITE = 0xCA, ATA_CMD_WRITE_EXT = 0x35, ATA_CMD_WRITE_FUA_EXT = 0x3D, + ATA_CMD_FPDMA_READ = 0x60, + ATA_CMD_FPDMA_WRITE = 0x61, ATA_CMD_PIO_READ = 0x20, ATA_CMD_PIO_READ_EXT = 0x24, ATA_CMD_PIO_WRITE = 0x30, @@ -151,6 +153,10 @@ enum { ATA_CMD_INIT_DEV_PARAMS = 0x91, ATA_CMD_READ_NATIVE_MAX = 0xF8, ATA_CMD_READ_NATIVE_MAX_EXT = 0x27, + ATA_CMD_READ_LOG_EXT = 0x2f, + + /* READ_LOG_EXT pages */ + ATA_LOG_SATA_NCQ = 0x10, /* SETFEATURES stuff */ SETFEATURES_XFER = 0x03, @@ -221,6 +227,7 @@ enum ata_tf_protocols { ATA_PROT_NODATA, /* no data */ ATA_PROT_PIO, /* PIO single sector */ ATA_PROT_DMA, /* DMA */ + ATA_PROT_NCQ, /* NCQ */ ATA_PROT_ATAPI, /* packet command, PIO data xfer*/ ATA_PROT_ATAPI_NODATA, /* packet command, no data */ ATA_PROT_ATAPI_DMA, /* packet command with special DMA sauce */ @@ -276,6 +283,8 @@ struct ata_taskfile { #define ata_id_has_pm(id) ((id)[82] & (1 << 3)) #define ata_id_has_lba(id) ((id)[49] & (1 << 9)) #define ata_id_has_dma(id) ((id)[49] & (1 << 8)) +#define ata_id_has_ncq(id) ((id)[76] & (1 << 8)) +#define ata_id_queue_depth(id) (((id)[75] & 0x1f) + 1) #define ata_id_removeable(id) ((id)[0] & (1 << 7)) #define ata_id_has_dword_io(id) ((id)[50] & (1 << 0)) #define ata_id_u32(id,n) \ diff --git a/include/linux/libata.h b/include/linux/libata.h index db17723e23fb..7c9e280a4829 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -125,6 +125,7 @@ enum { ATA_DFLAG_LBA = (1 << 0), /* device supports LBA */ ATA_DFLAG_LBA48 = (1 << 1), /* device supports LBA48 */ ATA_DFLAG_CDB_INTR = (1 << 2), /* device asserts INTRQ when ready for CDB */ + ATA_DFLAG_NCQ = (1 << 3), /* device supports NCQ */ ATA_DFLAG_CFG_MASK = (1 << 8) - 1, ATA_DFLAG_PIO = (1 << 8), /* device currently in PIO mode */ @@ -150,6 +151,7 @@ enum { ATA_FLAG_IRQ_MASK = (1 << 9), /* Mask IRQ in PIO xfers */ ATA_FLAG_PIO_POLLING = (1 << 10), /* use polling PIO if LLD * doesn't handle PIO interrupts */ + ATA_FLAG_NCQ = (1 << 11), /* host supports NCQ */ ATA_FLAG_DEBUGMSG = (1 << 14), ATA_FLAG_FLUSH_PORT_TASK = (1 << 15), /* flush port task */ -- cgit v1.2.3 From 6cec4a3943bdfe46e2952bc246f17670f747be8d Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 15 May 2006 21:03:41 +0900 Subject: [PATCH] libata-ncq: rename ap->qactive to ap->qc_allocated Rename ap->qactive to ap->qc_allocated. This is to accomodate addition of ap->qc_active, mask of active qcs. Signed-off-by: Tejun Heo --- include/linux/libata.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 7c9e280a4829..b3a4f8bea828 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -474,7 +474,7 @@ struct ata_port { struct ata_device device[ATA_MAX_DEVICES]; struct ata_queued_cmd qcmd[ATA_MAX_QUEUE]; - unsigned long qactive; + unsigned long qc_allocated; unsigned int active_tag; struct ata_host_stats stats; -- cgit v1.2.3 From dedaf2b0365ccec50714fbde0b3215e7e94fa47c Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 15 May 2006 21:03:43 +0900 Subject: [PATCH] libata-ncq: implement ap->qc_active, ap->sactive and complete helper Add ap->qc_active and ap->sactive, mask of all active qcs and libata's view of the SActive register, respectively. Also, implement ata_qc_complete_multiple() which takes new qc_active mask and complete multiple qcs according to the mask. These will be used to track NCQ commands and complete them. The distinction between ap->qc_active and ap->sactive is also useful for later PM implementation. Signed-off-by: Tejun Heo --- include/linux/libata.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index b3a4f8bea828..dd0db2d21bc5 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -475,7 +475,10 @@ struct ata_port { struct ata_queued_cmd qcmd[ATA_MAX_QUEUE]; unsigned long qc_allocated; + unsigned int qc_active; + unsigned int active_tag; + u32 sactive; struct ata_host_stats stats; struct ata_host_set *host_set; @@ -668,6 +671,8 @@ extern void ata_bmdma_drive_eh(struct ata_port *ap, extern void ata_bmdma_error_handler(struct ata_port *ap); extern void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc); extern void ata_qc_complete(struct ata_queued_cmd *qc); +extern int ata_qc_complete_multiple(struct ata_port *ap, u32 qc_active, + void (*finish_qc)(struct ata_queued_cmd *)); extern void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)); extern int ata_std_bios_param(struct scsi_device *sdev, -- cgit v1.2.3 From a6e6ce8e8dc907a2cf2b994b0ea4099423f046bf Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 15 May 2006 21:03:48 +0900 Subject: [PATCH] libata-ncq: implement NCQ device configuration Now that all NCQ related stuff are in place, implement NCQ device configuration and bump ATA_MAX_QUEUE to 32 thus activating NCQ support. Original implementation is from Jens Axboe. Signed-off-by: Tejun Heo --- include/linux/libata.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index dd0db2d21bc5..fcdd798bb086 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -109,7 +109,7 @@ enum { ATA_MAX_PORTS = 8, ATA_DEF_QUEUE = 1, /* tag ATA_MAX_QUEUE - 1 is reserved for internal commands */ - ATA_MAX_QUEUE = 2, + ATA_MAX_QUEUE = 32, ATA_TAG_INTERNAL = ATA_MAX_QUEUE - 1, ATA_MAX_SECTORS = 200, /* FIXME */ ATA_MAX_BUS = 2, @@ -679,6 +679,8 @@ extern int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int geom[]); extern int ata_scsi_slave_config(struct scsi_device *sdev); +extern int ata_scsi_change_queue_depth(struct scsi_device *sdev, + int queue_depth); extern struct ata_device *ata_dev_pair(struct ata_device *adev); /* -- cgit v1.2.3 From 3655d1d323386e001c786af10f0a3f39f438f03b Mon Sep 17 00:00:00 2001 From: Albert Lee Date: Fri, 19 May 2006 11:43:04 +0800 Subject: [PATCH] libata: Fix the HSM error_mask mapping (was: Re: libata-tj and SMART) Fix the HSM error_mask mapping. Changes: - Better mapping in ac_err_mask() - In HSM_ST_FIRST ans HSM_ST state, check ATA_ERR|ATA_DF and map it to AC_ERR_DEV instead of AC_ERR_HSM. - In HSM_ST_FIRST and HSM_ST state, map DRQ=1 ERR=1 to AC_ERR_HSM. - For PIO data in and DRQ=1 ERR=1, add check after the junk data block is read. Signed-off-by: Albert Lee Signed-off-by: Jeff Garzik --- include/linux/libata.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 2803ab8e9243..c51502c047a4 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -1062,7 +1062,7 @@ static inline int ata_try_flush_cache(const struct ata_device *dev) static inline unsigned int ac_err_mask(u8 status) { - if (status & ATA_BUSY) + if (status & (ATA_BUSY | ATA_DRQ)) return AC_ERR_HSM; if (status & (ATA_ERR | ATA_DF)) return AC_ERR_DEV; -- cgit v1.2.3 From 4c5c81613b0eb0dba97a8f312a2f1162f39fd47b Mon Sep 17 00:00:00 2001 From: Andrew Chew Date: Thu, 20 Apr 2006 15:54:26 -0700 Subject: [PATCH] sata_nv: Add MCP61 support Added MCP61 SATA support to sata_nv. Signed-off-by: Jeff Garzik --- include/linux/pci_ids.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index d6fe048376ab..233f60741c82 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1182,6 +1182,10 @@ #define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_1100 0x034E #define PCI_DEVICE_ID_NVIDIA_NVENET_14 0x0372 #define PCI_DEVICE_ID_NVIDIA_NVENET_15 0x0373 +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA 0x03E7 +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE 0x03EC +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2 0x03F6 +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3 0x03F7 #define PCI_VENDOR_ID_IMS 0x10e0 #define PCI_DEVICE_ID_IMS_TT128 0x9128 -- cgit v1.2.3 From a6b2c5d4754dc539a560fdf0d3fb78a14174394a Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Mon, 22 May 2006 16:59:59 +0100 Subject: [PATCH] PATCH: libata. Add ->data_xfer method We need to pass the device in order to do per device checks such as 32bit I/O enables. With the changes to include dev->ap we now don't have to add parameters however just clean them up. Also add data_xfer methods to the existing drivers except ata_piix (which is in the other block of patches). If you reject the piix one just add a data_xfer to it... Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- include/linux/libata.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index c51502c047a4..25a6bf181599 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -525,6 +525,8 @@ struct ata_port_operations { void (*bmdma_setup) (struct ata_queued_cmd *qc); void (*bmdma_start) (struct ata_queued_cmd *qc); + void (*data_xfer) (struct ata_device *, unsigned char *, unsigned int, int); + void (*qc_prep) (struct ata_queued_cmd *qc); unsigned int (*qc_issue) (struct ata_queued_cmd *qc); @@ -646,6 +648,10 @@ extern int ata_port_start (struct ata_port *ap); extern void ata_port_stop (struct ata_port *ap); extern void ata_host_stop (struct ata_host_set *host_set); extern irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs); +extern void ata_mmio_data_xfer(struct ata_device *adev, unsigned char *buf, + unsigned int buflen, int write_data); +extern void ata_pio_data_xfer(struct ata_device *adev, unsigned char *buf, + unsigned int buflen, int write_data); extern void ata_qc_prep(struct ata_queued_cmd *qc); extern void ata_noop_qc_prep(struct ata_queued_cmd *qc); extern unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc); -- cgit v1.2.3 From 957d2df1801865eb1e63864bc63b970aa9c460ba Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Tue, 23 May 2006 13:18:57 +0100 Subject: [PATCH] libata: Remove obsolete flag ATA_FLAG_IRQ_MASK was added when I did the original data transfer with IRQ masked bits for PIO. It has since been replaced by ->pio_data_xfer methods so should be removed so nobody uses it by mistake thinking it still works. Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- include/linux/libata.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 25a6bf181599..9c60b4a4e2fd 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -149,7 +149,6 @@ enum { ATA_FLAG_NO_ATAPI = (1 << 6), /* No ATAPI support */ ATA_FLAG_PIO_DMA = (1 << 7), /* PIO cmds via DMA */ ATA_FLAG_PIO_LBA48 = (1 << 8), /* Host DMA engine is LBA28 only */ - ATA_FLAG_IRQ_MASK = (1 << 9), /* Mask IRQ in PIO xfers */ ATA_FLAG_PIO_POLLING = (1 << 10), /* use polling PIO if LLD * doesn't handle PIO interrupts */ ATA_FLAG_NCQ = (1 << 11), /* host supports NCQ */ -- cgit v1.2.3 From 622b20fcb8b42aa4c3c87c0a036f2ad0927b64bc Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 24 May 2006 14:06:11 +0100 Subject: [PATCH] PCI identifiers for the pata_via update These IDs are also used by the drivers/ide/pci changes submitted by VIA. Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- include/linux/pci_ids.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 233f60741c82..e75727954a12 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1238,6 +1238,7 @@ #define PCI_DEVICE_ID_VIA_PX8X0_0 0x0259 #define PCI_DEVICE_ID_VIA_3269_0 0x0269 #define PCI_DEVICE_ID_VIA_K8T800PRO_0 0x0282 +#define PCI_DEVICE_ID_VIA_3296_0 0x0296 #define PCI_DEVICE_ID_VIA_8363_0 0x0305 #define PCI_DEVICE_ID_VIA_P4M800CE 0x0314 #define PCI_DEVICE_ID_VIA_8371_0 0x0391 @@ -1245,6 +1246,7 @@ #define PCI_DEVICE_ID_VIA_82C561 0x0561 #define PCI_DEVICE_ID_VIA_82C586_1 0x0571 #define PCI_DEVICE_ID_VIA_82C576 0x0576 +#define PCI_DEVICE_ID_VIA_SATA_EIDE 0x0581 #define PCI_DEVICE_ID_VIA_82C586_0 0x0586 #define PCI_DEVICE_ID_VIA_82C596 0x0596 #define PCI_DEVICE_ID_VIA_82C597_0 0x0597 @@ -1285,10 +1287,11 @@ #define PCI_DEVICE_ID_VIA_8783_0 0x3208 #define PCI_DEVICE_ID_VIA_8237 0x3227 #define PCI_DEVICE_ID_VIA_8251 0x3287 -#define PCI_DEVICE_ID_VIA_3296_0 0x0296 +#define PCI_DEVICE_ID_VIA_8237A 0x3337 #define PCI_DEVICE_ID_VIA_8231 0x8231 #define PCI_DEVICE_ID_VIA_8231_4 0x8235 #define PCI_DEVICE_ID_VIA_8365_1 0x8305 +#define PCI_DEVICE_ID_VIA_CX700 0x8324 #define PCI_DEVICE_ID_VIA_8371_1 0x8391 #define PCI_DEVICE_ID_VIA_82C598_1 0x8598 #define PCI_DEVICE_ID_VIA_838X_1 0xB188 -- cgit v1.2.3 From 75e995855f45a83afdae34d50c0b3ee14fb23b7a Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 24 May 2006 14:14:41 +0100 Subject: [PATCH] libata: add pio_data_xfer_noirq Signed-off-by: Alan Cox Signed-off-by: Jeff Garzik --- include/linux/libata.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 9c60b4a4e2fd..b0ee1c1437d6 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -651,6 +651,8 @@ extern void ata_mmio_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data); extern void ata_pio_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data); +extern void ata_pio_data_xfer_noirq(struct ata_device *adev, unsigned char *buf, + unsigned int buflen, int write_data); extern void ata_qc_prep(struct ata_queued_cmd *qc); extern void ata_noop_qc_prep(struct ata_queued_cmd *qc); extern unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc); -- cgit v1.2.3 From 7395acb2c840fd4d0cacc91d6fb71440057141ab Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 31 May 2006 18:27:25 +0900 Subject: [PATCH] libata: shift host flag constants Nudge host flag constants to make a room after ATA_FLAG_EH_PENDING. New EH flag will be added. Signed-off-by: Tejun Heo --- include/linux/libata.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index b0ee1c1437d6..3f9c65f1aafa 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -149,14 +149,14 @@ enum { ATA_FLAG_NO_ATAPI = (1 << 6), /* No ATAPI support */ ATA_FLAG_PIO_DMA = (1 << 7), /* PIO cmds via DMA */ ATA_FLAG_PIO_LBA48 = (1 << 8), /* Host DMA engine is LBA28 only */ - ATA_FLAG_PIO_POLLING = (1 << 10), /* use polling PIO if LLD - * doesn't handle PIO interrupts */ - ATA_FLAG_NCQ = (1 << 11), /* host supports NCQ */ + ATA_FLAG_PIO_POLLING = (1 << 9), /* use polling PIO if LLD + * doesn't handle PIO interrupts */ + ATA_FLAG_NCQ = (1 << 10), /* host supports NCQ */ - ATA_FLAG_DEBUGMSG = (1 << 14), - ATA_FLAG_FLUSH_PORT_TASK = (1 << 15), /* flush port task */ + ATA_FLAG_DEBUGMSG = (1 << 13), + ATA_FLAG_FLUSH_PORT_TASK = (1 << 14), /* flush port task */ - ATA_FLAG_EH_PENDING = (1 << 16), /* EH pending */ + ATA_FLAG_EH_PENDING = (1 << 15), /* EH pending */ ATA_FLAG_FROZEN = (1 << 17), /* port is frozen */ ATA_FLAG_RECOVERED = (1 << 18), /* recovery action performed */ -- cgit v1.2.3 From c6cf9e99d1de5ca6a08fb639bb73031ffe50d802 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 31 May 2006 18:27:27 +0900 Subject: [PATCH] libata: implement ata_eh_wait() Implement ata_eh_wait(). On return from this function, it's guaranteed that the EH which was pending or in progress when the function was called is complete - including the tailing part of SCSI EH. This will be used by hotplug and others to synchronize with EH. Signed-off-by: Tejun Heo --- include/linux/libata.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 3f9c65f1aafa..2eb5828839e4 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -157,6 +157,7 @@ enum { ATA_FLAG_FLUSH_PORT_TASK = (1 << 14), /* flush port task */ ATA_FLAG_EH_PENDING = (1 << 15), /* EH pending */ + ATA_FLAG_EH_IN_PROGRESS = (1 << 16), /* EH in progress */ ATA_FLAG_FROZEN = (1 << 17), /* port is frozen */ ATA_FLAG_RECOVERED = (1 << 18), /* recovery action performed */ @@ -490,6 +491,7 @@ struct ata_port { u32 msg_enable; struct list_head eh_done_q; + wait_queue_head_t eh_wait_q; void *private_data; -- cgit v1.2.3 From abdda7331d469fa965167365f011d05e226008fb Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 31 May 2006 18:27:29 +0900 Subject: [PATCH] libata-hp-prep: add flags and eh_info/context fields for hotplug Add hotplug related flags and eh_info/context fields. Signed-off-by: Tejun Heo --- include/linux/libata.h | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 2eb5828839e4..d4a668cf143b 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -131,6 +131,9 @@ enum { ATA_DFLAG_PIO = (1 << 8), /* device currently in PIO mode */ + ATA_DFLAG_DETACH = (1 << 16), + ATA_DFLAG_DETACHED = (1 << 17), + ATA_DEV_UNKNOWN = 0, /* unknown device */ ATA_DEV_ATA = 1, /* ATA device */ ATA_DEV_ATA_UNSUP = 2, /* ATA device (unsupported) */ @@ -152,6 +155,9 @@ enum { ATA_FLAG_PIO_POLLING = (1 << 9), /* use polling PIO if LLD * doesn't handle PIO interrupts */ ATA_FLAG_NCQ = (1 << 10), /* host supports NCQ */ + ATA_FLAG_HRST_TO_RESUME = (1 << 11), /* hardreset to resume phy */ + ATA_FLAG_SKIP_D2H_BSY = (1 << 12), /* can't wait for the first D2H + * Register FIS clearing BSY */ ATA_FLAG_DEBUGMSG = (1 << 13), ATA_FLAG_FLUSH_PORT_TASK = (1 << 14), /* flush port task */ @@ -160,6 +166,9 @@ enum { ATA_FLAG_EH_IN_PROGRESS = (1 << 16), /* EH in progress */ ATA_FLAG_FROZEN = (1 << 17), /* port is frozen */ ATA_FLAG_RECOVERED = (1 << 18), /* recovery action performed */ + ATA_FLAG_LOADING = (1 << 19), /* boot/loading probe */ + ATA_FLAG_UNLOADING = (1 << 20), /* module is unloading */ + ATA_FLAG_SCSI_HOTPLUG = (1 << 21), /* SCSI hotplug scheduled */ ATA_FLAG_DISABLED = (1 << 22), /* port is disabled, ignore it */ ATA_FLAG_SUSPENDED = (1 << 23), /* port is suspended (power) */ @@ -241,7 +250,9 @@ enum { ATA_EH_RESET_MASK = ATA_EH_SOFTRESET | ATA_EH_HARDRESET, /* ata_eh_info->flags */ - ATA_EHI_DID_RESET = (1 << 0), /* already reset this port */ + ATA_EHI_HOTPLUGGED = (1 << 0), /* could have been hotplugged */ + + ATA_EHI_DID_RESET = (1 << 16), /* already reset this port */ /* max repeat if error condition is still set after ->error_handler */ ATA_EH_MAX_REPEAT = 5, @@ -434,6 +445,10 @@ struct ata_eh_info { unsigned int err_mask; /* port-wide err_mask */ unsigned int action; /* ATA_EH_* action mask */ unsigned int flags; /* ATA_EHI_* flags */ + + unsigned long hotplug_timestamp; + unsigned int probe_mask; + char desc[ATA_EH_DESC_LEN]; int desc_len; }; @@ -441,6 +456,8 @@ struct ata_eh_info { struct ata_eh_context { struct ata_eh_info i; int tries[ATA_MAX_DEVICES]; + unsigned int classes[ATA_MAX_DEVICES]; + unsigned int did_probe_mask; }; struct ata_port { -- cgit v1.2.3 From 72fa4b742b327bd1b07985d79a61c61dbd9fd4e6 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 31 May 2006 18:27:32 +0900 Subject: [PATCH] libata-hp-prep: make some ata_device fields persistent Lifetimes of some fields span over device plugging/unplugging. This patch moves such persistent fields to the top of ata_device and separate them with ATA_DEVICE_CLEAR_OFFSET. Fields above the offset are initialized once during host initializatino while all other fields are cleared before hotplugging. Currently ->ap, devno and part of flags are persistent. Note that flags is partially cleared while holding host_set lock. This is to synchronize with later warm plug implementation which will record hotplug request in dev->flags. Signed-off-by: Tejun Heo --- include/linux/libata.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index d4a668cf143b..aa14eda0656c 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -130,6 +130,7 @@ enum { ATA_DFLAG_CFG_MASK = (1 << 8) - 1, ATA_DFLAG_PIO = (1 << 8), /* device currently in PIO mode */ + ATA_DFLAG_INIT_MASK = (1 << 16) - 1, ATA_DFLAG_DETACH = (1 << 16), ATA_DFLAG_DETACHED = (1 << 17), @@ -410,10 +411,11 @@ struct ata_ering { struct ata_device { struct ata_port *ap; - u64 n_sectors; /* size of device, if ATA */ + unsigned int devno; /* 0 or 1 */ unsigned long flags; /* ATA_DFLAG_xxx */ + /* n_sector is used as CLEAR_OFFSET, read comment above CLEAR_OFFSET */ + u64 n_sectors; /* size of device, if ATA */ unsigned int class; /* ATA_DEV_xxx */ - unsigned int devno; /* 0 or 1 */ u16 id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */ u8 pio_mode; u8 dma_mode; @@ -439,6 +441,11 @@ struct ata_device { struct ata_ering ering; }; +/* Offset into struct ata_device. Fields above it are maintained + * acress device init. Fields below are zeroed. + */ +#define ATA_DEVICE_CLEAR_OFFSET offsetof(struct ata_device, n_sectors) + struct ata_eh_info { struct ata_device *dev; /* offending device */ u32 serror; /* SError from LLDD */ -- cgit v1.2.3 From 5a04bf4befa8bffa012eedc3a0903c158b9131a9 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 31 May 2006 18:27:38 +0900 Subject: [PATCH] libata-hp-prep: implement ap->hw_sata_spd_limit Add ap->hw_sata_spd_limit and initialize it once during the boot initialization (or driver load initialization). ap->sata_spd_limit is reset to ap->hw_sata_spd_limit on hotplug. This prevents spd limits introduced by earlier devices from affecting new devices. Signed-off-by: Tejun Heo --- include/linux/libata.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index aa14eda0656c..10dc235ad8bc 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -489,6 +489,7 @@ struct ata_port { unsigned int mwdma_mask; unsigned int udma_mask; unsigned int cbl; /* cable type; ATA_CBL_xxx */ + unsigned int hw_sata_spd_limit; unsigned int sata_spd_limit; /* SATA PHY speed limit */ /* record runtime error info, protected by host_set lock */ -- cgit v1.2.3 From 3edebac41bab7e146578ad9e723ee7fff71c99c0 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 31 May 2006 18:27:40 +0900 Subject: [PATCH] libata-hp-prep: store attached SCSI device Add device persistent field dev->sdev and store the attached SCSI device. With hotplug, libata needs to know the attached SCSI device to offline and detach it, but scsi_device_lookup() cannot be used because libata will reuse SCSI ID numbers - dead but not gone devices (due to zombie opens, etc...) interfere with the lookup. dev->sdev doesn't hold reference to the SCSI device. It's cleared when the SCSI device goes away. Signed-off-by: Tejun Heo --- include/linux/libata.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 10dc235ad8bc..c0513c752751 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -413,6 +413,7 @@ struct ata_device { struct ata_port *ap; unsigned int devno; /* 0 or 1 */ unsigned long flags; /* ATA_DFLAG_xxx */ + struct scsi_device *sdev; /* attached SCSI device */ /* n_sector is used as CLEAR_OFFSET, read comment above CLEAR_OFFSET */ u64 n_sectors; /* size of device, if ATA */ unsigned int class; /* ATA_DEV_xxx */ -- cgit v1.2.3 From d7bb4cc7575929a60b0a718daa1bce87bea9a9cc Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 31 May 2006 18:27:46 +0900 Subject: [PATCH] libata-hp-prep: implement sata_phy_debounce() With hotplug, PHY always needs to be debounced before a reset as any reset might find new devices. Extract PHY waiting code from sata_phy_resume() and extend it to include SStatus debouncing. Note that sata_phy_debounce() is superset of what used to be done inside sata_phy_resume(). Three default debounce timing parameters are defined to be used by hot/boot plug. As resume failure during probing will be properly handled as errors, timeout doesn't have to be long as before. probeinit() uses the same timeout to retain the original behavior. Signed-off-by: Tejun Heo --- include/linux/libata.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index c0513c752751..1c167f728fb4 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -607,11 +607,17 @@ struct ata_timing { #define FIT(v,vmin,vmax) max_t(short,min_t(short,v,vmax),vmin) +extern const unsigned long sata_deb_timing_boot[]; +extern const unsigned long sata_deb_timing_eh[]; +extern const unsigned long sata_deb_timing_before_fsrst[]; + extern void ata_port_probe(struct ata_port *); extern void __sata_phy_reset(struct ata_port *ap); extern void sata_phy_reset(struct ata_port *ap); extern void ata_bus_reset(struct ata_port *ap); extern int sata_set_spd(struct ata_port *ap); +extern int sata_phy_debounce(struct ata_port *ap, const unsigned long *param); +extern int sata_phy_resume(struct ata_port *ap, const unsigned long *param); extern int ata_drive_probe_reset(struct ata_port *ap, ata_probeinit_fn_t probeinit, ata_reset_fn_t softreset, ata_reset_fn_t hardreset, -- cgit v1.2.3 From f5914a461eb9703773226a0813f6ffcae10c0861 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 31 May 2006 18:27:48 +0900 Subject: [PATCH] libata-hp-prep: add prereset() method and implement ata_std_prereset() With hotplug, every reset might be a probing reset and thus something similar to probe_init() is needed. prereset() method is called before a series of resets to a port and is the counterpart of postreset(). prereset() can tell EH to use different type of reset or skip reset by modifying ehc->i.action. This patch also implements ata_std_prereset(). Most controllers should be able to use this function directly or with some wrapping. After hotplug, different controllers need different actions to resume the PHY and detect the newly attached device. Controllers can be categorized as follows. * Controllers which can wait for the first D2H FIS after hotplug. Note that if the waiting is implemented by polling TF status, there needs to be a way to set BSY on PHY status change. It can be implemented by hardware or with the help of the driver. * Controllers which can wait for the first D2H FIS after sending COMRESET. These controllers need to issue COMRESET to wait for the first FIS. Note that the received D2H FIS could be the first D2H FIS after POR (power-on-reset) or D2H FIS in response to the COMRESET. Some controllers use COMRESET as TF status synchronization point and clear TF automatically (sata_sil). * Controllers which cannot wait for the first D2H FIS reliably. Blindly issuing SRST to spinning-up device often results in command issue failure or timeout, causing extended delay. For these controllers, ata_std_prereset() explicitly waits ATA_SPINUP_WAIT (currently 8s) to give newly attached device time to spin up, then issues reset. Note that failing to getting ready in ATA_SPINUP_WAIT is not critical. libata will retry. So, the timeout needs to be long enough to spin up most devices. LLDDs can tell ata_std_prereset() which of above action is needed with ATA_FLAG_HRST_TO_RESUME and ATA_FLAG_SKIP_D2H_BSY flags. These flags are PHY-specific property and will be moved to ata_link later. While at it, this patch unifies function typedef's such that they all have named arguments. Signed-off-by: Tejun Heo --- include/linux/libata.h | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 1c167f728fb4..fe5f53943c44 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -262,6 +262,15 @@ enum { ATA_PROBE_MAX_TRIES = 3, ATA_EH_RESET_TRIES = 3, ATA_EH_DEV_TRIES = 3, + + /* Drive spinup time (time from power-on to the first D2H FIS) + * in msecs - 8s currently. Failing to get ready in this time + * isn't critical. It will result in reset failure for + * controllers which can't wait for the first D2H FIS. libata + * will retry, so it just has to be long enough to spin up + * most devices. + */ + ATA_SPINUP_WAIT = 8000, }; enum hsm_task_states { @@ -294,9 +303,10 @@ struct ata_queued_cmd; /* typedefs */ typedef void (*ata_qc_cb_t) (struct ata_queued_cmd *qc); -typedef void (*ata_probeinit_fn_t)(struct ata_port *); -typedef int (*ata_reset_fn_t)(struct ata_port *, unsigned int *); -typedef void (*ata_postreset_fn_t)(struct ata_port *ap, unsigned int *); +typedef void (*ata_probeinit_fn_t)(struct ata_port *ap); +typedef int (*ata_prereset_fn_t)(struct ata_port *ap); +typedef int (*ata_reset_fn_t)(struct ata_port *ap, unsigned int *classes); +typedef void (*ata_postreset_fn_t)(struct ata_port *ap, unsigned int *classes); struct ata_ioports { unsigned long cmd_addr; @@ -623,6 +633,7 @@ extern int ata_drive_probe_reset(struct ata_port *ap, ata_reset_fn_t softreset, ata_reset_fn_t hardreset, ata_postreset_fn_t postreset, unsigned int *classes); extern void ata_std_probeinit(struct ata_port *ap); +extern int ata_std_prereset(struct ata_port *ap); extern int ata_std_softreset(struct ata_port *ap, unsigned int *classes); extern int sata_std_hardreset(struct ata_port *ap, unsigned int *class); extern void ata_std_postreset(struct ata_port *ap, unsigned int *classes); @@ -706,7 +717,7 @@ extern u8 ata_bmdma_status(struct ata_port *ap); extern void ata_bmdma_irq_clear(struct ata_port *ap); extern void ata_bmdma_freeze(struct ata_port *ap); extern void ata_bmdma_thaw(struct ata_port *ap); -extern void ata_bmdma_drive_eh(struct ata_port *ap, +extern void ata_bmdma_drive_eh(struct ata_port *ap, ata_prereset_fn_t prereset, ata_reset_fn_t softreset, ata_reset_fn_t hardreset, ata_postreset_fn_t postreset); @@ -784,8 +795,9 @@ extern void ata_eh_thaw_port(struct ata_port *ap); extern void ata_eh_qc_complete(struct ata_queued_cmd *qc); extern void ata_eh_qc_retry(struct ata_queued_cmd *qc); -extern void ata_do_eh(struct ata_port *ap, ata_reset_fn_t softreset, - ata_reset_fn_t hardreset, ata_postreset_fn_t postreset); +extern void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset, + ata_reset_fn_t softreset, ata_reset_fn_t hardreset, + ata_postreset_fn_t postreset); /* * printk helpers -- cgit v1.2.3 From 9a1004d0c11be41c83d06a67dfe74567a41ae582 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 31 May 2006 18:27:52 +0900 Subject: [PATCH] libata: export ata_hsm_move() ata_hsm_move() will be used by LLDDs which depend on standard PIO HSM but implement their own interrupt handlers. Signed-off-by: Tejun Heo --- include/linux/libata.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index fe5f53943c44..a1ceb5b67b97 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -723,6 +723,8 @@ extern void ata_bmdma_drive_eh(struct ata_port *ap, ata_prereset_fn_t prereset, ata_postreset_fn_t postreset); extern void ata_bmdma_error_handler(struct ata_port *ap); extern void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc); +extern int ata_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc, + u8 status, int in_wq); extern void ata_qc_complete(struct ata_queued_cmd *qc); extern int ata_qc_complete_multiple(struct ata_port *ap, u32 qc_active, void (*finish_qc)(struct ata_queued_cmd *)); -- cgit v1.2.3 From 084fe639b81c4d418a2cf714acb0475e3713cb73 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 31 May 2006 18:28:03 +0900 Subject: [PATCH] libata-hp: implement hotplug Implement ATA part of hotplug. To avoid probing broken devices over and over again, disabled devices are not automatically detached. They are detached only if probing is requested for the device or the associated port is offline. Also, to avoid infinite probing loop, Each device is probed only once per EH run. As SATA PHY status is fragile, devices are detached only after it has used up its recovery chances unless explicitly requested by LLDD or user (LLDD may request direct detach if, for example, it supports cold presence detection). Signed-off-by: Tejun Heo --- include/linux/libata.h | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index a1ceb5b67b97..56971943d261 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -824,6 +824,19 @@ extern void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset, (ehi)->desc_len = 0; \ } while (0) +static inline void ata_ehi_hotplugged(struct ata_eh_info *ehi) +{ + if (ehi->flags & ATA_EHI_HOTPLUGGED) + return; + + ehi->flags |= ATA_EHI_HOTPLUGGED; + ehi->hotplug_timestamp = jiffies; + + ehi->err_mask |= AC_ERR_ATA_BUS; + ehi->action |= ATA_EH_SOFTRESET; + ehi->probe_mask |= (1 << ATA_MAX_DEVICES) - 1; +} + /* * qc helpers */ -- cgit v1.2.3 From 580b2102327ab8444af5bde4e70b50d268a1d558 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 31 May 2006 18:28:05 +0900 Subject: [PATCH] libata-hp: implement SCSI part of hotplug Implement SCSI part of hotplug. This must be done in a separate context as SCSI makes use of EH during probing. SCSI scan fails silently if EH is in progress. In such cases, libata pauses briefly and retries until every device is attached. Signed-off-by: Tejun Heo --- include/linux/libata.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 56971943d261..407115624d9f 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -521,7 +521,7 @@ struct ata_port { struct ata_host_set *host_set; struct device *dev; - struct work_struct port_task; + struct work_struct port_task, hotplug_task; unsigned int hsm_task_state; -- cgit v1.2.3 From 83c47bcb3c533180a6dda78152334de50065358a Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 31 May 2006 18:28:07 +0900 Subject: [PATCH] libata-hp: implement warmplug Implement warmplug. User-initiated unplug can be detected by hostt->slave_destroy() and plug by transportt->user_scan(). This patch only implements the two callbacks. The next function will hook them. Signed-off-by: Tejun Heo --- include/linux/libata.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 407115624d9f..74786c33c526 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -734,6 +734,7 @@ extern int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev, sector_t capacity, int geom[]); extern int ata_scsi_slave_config(struct scsi_device *sdev); +extern void ata_scsi_slave_destroy(struct scsi_device *sdev); extern int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth); extern struct ata_device *ata_dev_pair(struct ata_device *adev); -- cgit v1.2.3 From 720ba12620ee09dce269adf4ad50958adac7bb54 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 31 May 2006 18:28:13 +0900 Subject: [PATCH] libata-hp: update unload-unplug Update unload unplug - driver unloading / PCI removal. This is done by ata_port_detach() which short-circuits EH, disables all devices and freezes the port. With this patch, EH and unloading/unplugging are properly synchronized. Signed-off-by: Tejun Heo --- include/linux/libata.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 74786c33c526..f11ba2715bef 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -649,6 +649,7 @@ extern int ata_pci_device_resume(struct pci_dev *pdev); extern int ata_pci_clear_simplex(struct pci_dev *pdev); #endif /* CONFIG_PCI */ extern int ata_device_add(const struct ata_probe_ent *ent); +extern void ata_port_detach(struct ata_port *ap); extern void ata_host_set_remove(struct ata_host_set *host_set); extern int ata_scsi_detect(struct scsi_host_template *sht); extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg); -- cgit v1.2.3 From 52783c5dcc8d317bc8c3e2692d366e8a305abada Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 31 May 2006 18:28:22 +0900 Subject: [PATCH] libata-hp: killl ops->probe_reset Now that all drivers implementing new EH are converted to new probing mechanism, ops->probe_reset doesn't have any user. Kill it. Signed-off-by: Tejun Heo --- include/linux/libata.h | 8 -------- 1 file changed, 8 deletions(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index f11ba2715bef..a2a33a902917 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -303,7 +303,6 @@ struct ata_queued_cmd; /* typedefs */ typedef void (*ata_qc_cb_t) (struct ata_queued_cmd *qc); -typedef void (*ata_probeinit_fn_t)(struct ata_port *ap); typedef int (*ata_prereset_fn_t)(struct ata_port *ap); typedef int (*ata_reset_fn_t)(struct ata_port *ap, unsigned int *classes); typedef void (*ata_postreset_fn_t)(struct ata_port *ap, unsigned int *classes); @@ -553,7 +552,6 @@ struct ata_port_operations { void (*phy_reset) (struct ata_port *ap); /* obsolete */ void (*set_mode) (struct ata_port *ap); - int (*probe_reset) (struct ata_port *ap, unsigned int *classes); void (*post_set_mode) (struct ata_port *ap); @@ -628,11 +626,6 @@ extern void ata_bus_reset(struct ata_port *ap); extern int sata_set_spd(struct ata_port *ap); extern int sata_phy_debounce(struct ata_port *ap, const unsigned long *param); extern int sata_phy_resume(struct ata_port *ap, const unsigned long *param); -extern int ata_drive_probe_reset(struct ata_port *ap, - ata_probeinit_fn_t probeinit, - ata_reset_fn_t softreset, ata_reset_fn_t hardreset, - ata_postreset_fn_t postreset, unsigned int *classes); -extern void ata_std_probeinit(struct ata_port *ap); extern int ata_std_prereset(struct ata_port *ap); extern int ata_std_softreset(struct ata_port *ap, unsigned int *classes); extern int sata_std_hardreset(struct ata_port *ap, unsigned int *class); @@ -688,7 +681,6 @@ extern void ata_std_dev_select (struct ata_port *ap, unsigned int device); extern u8 ata_check_status(struct ata_port *ap); extern u8 ata_altstatus(struct ata_port *ap); extern void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf); -extern int ata_std_probe_reset(struct ata_port *ap, unsigned int *classes); extern int ata_port_start (struct ata_port *ap); extern void ata_port_stop (struct ata_port *ap); extern void ata_host_stop (struct ata_host_set *host_set); -- cgit v1.2.3 From 651d765d0b2c72d33430487c8b6ef64c60cd2134 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Wed, 7 Jun 2006 16:10:19 +1000 Subject: [PATCH] Add a prctl to change the endianness of a process. This new prctl is intended for changing the execution mode of the processor, on processors that support both a little-endian mode and a big-endian mode. It is intended for use by programs such as instruction set emulators (for example an x86 emulator on PowerPC), which may find it convenient to use the processor in an alternate endianness mode when executing translated instructions. Note that this does not imply the existence of a fully-fledged ABI for both endiannesses, or of compatibility code for converting system calls done in the non-native endianness mode. The program is expected to arrange for all of its system call arguments to be presented in the native endianness. Switching between big and little-endian mode will require some care in constructing the instruction sequence for the switch. Generally the instructions up to the instruction that invokes the prctl system call will have to be in the old endianness, and subsequent instructions will have to be in the new endianness. Signed-off-by: Anton Blanchard Signed-off-by: Paul Mackerras --- include/linux/prctl.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include/linux') diff --git a/include/linux/prctl.h b/include/linux/prctl.h index bf022c43a18e..52a9be41250d 100644 --- a/include/linux/prctl.h +++ b/include/linux/prctl.h @@ -52,4 +52,11 @@ #define PR_SET_NAME 15 /* Set process name */ #define PR_GET_NAME 16 /* Get process name */ +/* Get/set process endian */ +#define PR_GET_ENDIAN 19 +#define PR_SET_ENDIAN 20 +# define PR_ENDIAN_BIG 0 +# define PR_ENDIAN_LITTLE 1 /* True little endian mode */ +# define PR_ENDIAN_PPC_LITTLE 2 /* "PowerPC" pseudo little endian */ + #endif /* _LINUX_PRCTL_H */ -- cgit v1.2.3 From 8d7feac3c7504425aaf61dc7d804685a6b89ee43 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 10 Jun 2006 18:37:19 +0200 Subject: [SCSI] remove RQ_SCSI_* flags The RQ_SCSI_* flags are a vestiage of a long past history. The EH code still sets them but we never make use of that information. The other users is pluto.c which never had a chance to work but needs to be kept compiling to keep Davem happy, so copy over the definition there. We could probably get rid of RQ_ACTIVE/RQ_INACTIVE aswell with some work, there's only two more or less bogus looking uses in ubd and scsi. Signed-off-by: Christoph Hellwig Signed-off-by: James Bottomley --- include/linux/blkdev.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 59e1259b1c40..c889c459fd1b 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -439,9 +439,6 @@ struct request_queue #define RQ_INACTIVE (-1) #define RQ_ACTIVE 1 -#define RQ_SCSI_BUSY 0xffff -#define RQ_SCSI_DONE 0xfffe -#define RQ_SCSI_DISCONNECTING 0xffe0 #define QUEUE_FLAG_CLUSTER 0 /* cluster several segments into 1 */ #define QUEUE_FLAG_QUEUED 1 /* uses generic tag queueing */ -- cgit v1.2.3 From 9a9c77dc4c4eed9dfb74080e768c0b3c9d905496 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sun, 11 Jun 2006 11:19:00 +0900 Subject: [PATCH] libata: cosmetic change in struct ata_port Cosmetic change in struct ata_port. Signed-off-by: Tejun Heo --- include/linux/libata.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index a2a33a902917..39e6b77de1a9 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -520,7 +520,8 @@ struct ata_port { struct ata_host_set *host_set; struct device *dev; - struct work_struct port_task, hotplug_task; + struct work_struct port_task; + struct work_struct hotplug_task; unsigned int hsm_task_state; -- cgit v1.2.3 From 3057ac3c1a992ee135cbb7b7d1a12e58d81f0739 Mon Sep 17 00:00:00 2001 From: "zhao, forrest" Date: Mon, 12 Jun 2006 12:01:34 +0800 Subject: [PATCH] Snoop SET FEATURES - WRITE CACHE ENABLE/DISABLE command(v5) This patch makes libata snoop 'SET FEATURES - WRITE CACHE ENABLE/DISABLE' command, executing requisite revalidation processes to update cached data. Signed-off-by: Forrest Zhao Signed-off-by: Jeff Garzik --- include/linux/ata.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ata.h b/include/linux/ata.h index c494e1c0531e..3671af869696 100644 --- a/include/linux/ata.h +++ b/include/linux/ata.h @@ -181,6 +181,9 @@ enum { XFER_PIO_0 = 0x08, XFER_PIO_SLOW = 0x00, + SETFEATURES_WC_ON = 0x02, /* Enable write cache */ + SETFEATURES_WC_OFF = 0x82, /* Disable write cache */ + /* ATAPI stuff */ ATAPI_PKT_DMA = (1 << 0), ATAPI_DMADIR = (1 << 2), /* ATAPI data dir: -- cgit v1.2.3 From 3b01b8af2414b6684051da4a1507dfacdbf24f86 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Mon, 12 Jun 2006 00:22:04 -0400 Subject: libata: fix build, by adding required workqueue member to port struct --- include/linux/libata.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 39e6b77de1a9..61eea5795d5a 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -522,6 +522,7 @@ struct ata_port { struct work_struct port_task; struct work_struct hotplug_task; + struct work_struct scsi_rescan_task; unsigned int hsm_task_state; -- cgit v1.2.3 From f0eb62b81dd16bfc4034916418c3406ba20011e1 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 12 Jun 2006 23:05:38 +0900 Subject: [PATCH] libata: add host_set->next for legacy two host_sets case, take #3 For a legacy ATA controller, libata registers two separate host sets. There was no connection between the two hosts making it impossible to traverse all ports related to the controller. This patch adds host_set->next which points to the second host_set and makes ata_pci_remove_one() remove all associated host_sets. * On device removal, all ports hanging off the device are properly detached. Prior to this patch, ports on the first host_set weren't detached casuing oops on driver unloading. * On device removal, both host_sets are properly freed This will also be used by new power management code to suspend and resume all ports of a controller. host_set/port representation will be improved to handle legacy controllers better and this host_set linking will go away with it. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 61eea5795d5a..f03b8664af11 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -356,7 +356,8 @@ struct ata_host_set { unsigned long flags; int simplex_claimed; /* Keep seperate in case we ever need to do this locked */ - struct ata_port * ports[0]; + struct ata_host_set *next; /* for legacy mode */ + struct ata_port *ports[0]; }; struct ata_queued_cmd { -- cgit v1.2.3 From afefc4158f3c8529e4bb99c1dc119fd792bac220 Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Mon, 19 Jun 2006 19:53:19 +0100 Subject: [ARM] 3592/1: AT91RM9200 Serial driver update Patch from Andrew Victor This patch includes a number of updates to the AT91RM9200 serial driver. Changes include: 1. Conversion to a platform_driver. [Ivan Kokshaysky] 2. Replaced all references to AT91RM9200 with AT91. This driver can now also be used for the AT91SAM9216. 3. Allow TIOCM_LOOP to configure local loopback mode. 4. Cleaned up the 'read_status_mask' usage and interrupt handler code. [Chip Coldwell] 5. Suspend/resume support. [David Brownell] There are a few 'unused variable' warning when compiling this - I removed the new DMA support to keep this first patch simpler. Signed-off-by: Andrew Victor Signed-off-by: Russell King --- include/linux/serial_core.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h index bd14858121ea..56c2a1db4a90 100644 --- a/include/linux/serial_core.h +++ b/include/linux/serial_core.h @@ -67,8 +67,8 @@ /* Parisc type numbers. */ #define PORT_MUX 48 -/* Atmel AT91RM9200 SoC */ -#define PORT_AT91RM9200 49 +/* Atmel AT91xxx SoC */ +#define PORT_AT91 49 /* Macintosh Zilog type numbers */ #define PORT_MAC_ZILOG 50 /* m68k : not yet implemented */ -- cgit v1.2.3 From 48d83325b61043e3bbd24dd37b9fe433744cf330 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 19 Jun 2006 23:57:59 -0700 Subject: [NET]: Prevent multiple qdisc runs Having two or more qdisc_run's contend against each other is bad because it can induce packet reordering if the packets have to be requeued. It appears that this is an unintended consequence of relinquinshing the queue lock while transmitting. That in turn is needed for devices that spend a lot of time in their transmit routine. There are no advantages to be had as devices with queues are inherently single-threaded (the loopback device is not but then it doesn't have a queue). Even if you were to add a queue to a parallel virtual device (e.g., bolt a tbf filter in front of an ipip tunnel device), you would still want to process the queue in sequence to ensure that the packets are ordered correctly. The solution here is to steal a bit from net_device to prevent this. BTW, as qdisc_restart is no longer used by anyone as a module inside the kernel (IIRC it used to with netif_wake_queue), I have not exported the new __qdisc_run function. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- include/linux/netdevice.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index e432b743dda2..39919c882a25 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -233,6 +233,7 @@ enum netdev_state_t __LINK_STATE_RX_SCHED, __LINK_STATE_LINKWATCH_PENDING, __LINK_STATE_DORMANT, + __LINK_STATE_QDISC_RUNNING, }; -- cgit v1.2.3 From 22ae813b85df7c0b0fc7c8d6f336d6a9f566ff97 Mon Sep 17 00:00:00 2001 From: Brice Goglin Date: Tue, 20 Jun 2006 20:03:02 -0700 Subject: [PATCH] add __iowrite64_copy Introduce __iowrite64_copy. It will be used by the Myri-10G Ethernet driver to post requests to the NIC. This driver will be submitted soon. __iowrite64_copy copies to I/O memory in units of 64 bits when possible (on 64 bit architectures). It reverts to __iowrite32_copy on 32 bit architectures. Signed-off-by: Brice Goglin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/io.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/io.h b/include/linux/io.h index 85533ec5aaa1..420e2fdf26f6 100644 --- a/include/linux/io.h +++ b/include/linux/io.h @@ -21,5 +21,6 @@ #include void __iowrite32_copy(void __iomem *to, const void *from, size_t count); +void __iowrite64_copy(void __iomem *to, const void *from, size_t count); #endif /* _LINUX_IO_H */ -- cgit v1.2.3 From 1e92a550e80fef01ebcc0bcd0896109cdb986c72 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 15 Jun 2006 14:11:22 +1000 Subject: [POWERPC] Fix mdelay badness on shared processor partitions On partitioned PPC64 systems where a partition is given 1/10 of a processor, we have seen mdelay() delaying for 10 times longer than it should. The reason is that the generic mdelay(n) does n delays of 1 millisecond each. However, with 1/10 of a processor, we only get a one-millisecond timeslice every 10ms. Thus each 1 millisecond delay loop ends up taking 10ms elapsed time. The solution is just to use the PPC64 udelay function, which uses the timebase to ensure that the delay is based on elapsed time rather than how much processing time the partition has been given. (Yes, the generic mdelay uses the PPC64 udelay, but the problem is that the start time gets reset every millisecond, and each time it gets reset we lose another 9ms.) Signed-off-by: Anton Blanchard Signed-off-by: Paul Mackerras Acked-by: Andrew Morton --- include/linux/delay.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/delay.h b/include/linux/delay.h index acb74865b973..17ddb55430ae 100644 --- a/include/linux/delay.h +++ b/include/linux/delay.h @@ -25,10 +25,7 @@ extern unsigned long loops_per_jiffy; #define MAX_UDELAY_MS 5 #endif -#ifdef notdef -#define mdelay(n) (\ - {unsigned long __ms=(n); while (__ms--) udelay(1000);}) -#else +#ifndef mdelay #define mdelay(n) (\ (__builtin_constant_p(n) && (n)<=MAX_UDELAY_MS) ? udelay((n)*1000) : \ ({unsigned long __ms=(n); while (__ms--) udelay(1000);})) -- cgit v1.2.3 From c34b4c734482dda750deb6089521f7c891b48736 Mon Sep 17 00:00:00 2001 From: Brice Goglin Date: Tue, 9 May 2006 10:52:09 -0700 Subject: [PATCH] PCI: Add PCI_CAP_ID_VNDR Add the vendor-specific extended capability PCI_CAP_ID_VNDR. It will be used by the Myri-10G Ethernet driver (will be submitted soon). Signed-off-by: Brice Goglin Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- include/linux/pci_regs.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h index d27a78b71297..6bce4a240364 100644 --- a/include/linux/pci_regs.h +++ b/include/linux/pci_regs.h @@ -197,6 +197,7 @@ #define PCI_CAP_ID_CHSWP 0x06 /* CompactPCI HotSwap */ #define PCI_CAP_ID_PCIX 0x07 /* PCI-X */ #define PCI_CAP_ID_HT_IRQCONF 0x08 /* HyperTransport IRQ Configuration */ +#define PCI_CAP_ID_VNDR 0x09 /* Vendor specific capability */ #define PCI_CAP_ID_SHPC 0x0C /* PCI Standard Hot-Plug Controller */ #define PCI_CAP_ID_EXP 0x10 /* PCI Express */ #define PCI_CAP_ID_MSIX 0x11 /* MSI-X */ -- cgit v1.2.3 From 75acfecaa031c0e1bc412cee4fe58ba49ff3406c Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Mon, 1 May 2006 10:43:46 -0500 Subject: [PATCH] PCI: Add pci_assign_resource_fixed -- allow fixed address assignments PCI: Add pci_assign_resource_fixed -- allow fixed address assignments On some embedded systems the PCI address for hotplug devices are not only known a priori but are required to be at a given PCI address for other master in the system to be able to access. An example of such a system would be an FPGA which is setup from user space after the system has booted. The FPGA may be access by DSPs in the system and those DSPs expect the FPGA at a fixed PCI address. Added pci_assign_resource_fixed() as a way to allow assignment of the PCI devices's BARs at fixed PCI addresses. Signed-off-by: Kumar Gala Signed-off-by: Greg Kroah-Hartman --- include/linux/pci.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index 6c4bc773f7b7..b9eb9b021d6a 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -496,6 +496,7 @@ int pci_set_dma_mask(struct pci_dev *dev, u64 mask); int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask); void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno); int pci_assign_resource(struct pci_dev *dev, int i); +int pci_assign_resource_fixed(struct pci_dev *dev, int i); void pci_restore_bars(struct pci_dev *dev); /* ROM control related routines */ -- cgit v1.2.3 From bd8481e1646d7649fa101ee57a5139b9da3c2436 Mon Sep 17 00:00:00 2001 From: Doug Thompson Date: Mon, 8 May 2006 17:06:09 -0700 Subject: [PATCH] PCI Bus Parity Status-broken hardware attribute, EDAC foundation Currently, the EDAC (error detection and correction) modules that are in the kernel contain some features that need to be moved. After some good feedback on the PCI Parity detection code and interface (http://www.ussg.iu.edu/hypermail/linux/kernel/0603.1/0897.html) this patch ADDs an new attribute to the pci_dev structure: Namely the 'broken_parity_status' bit. When set this indicates that the respective hardware generates false positives of Parity errors. The EDAC "blacklist" solution was inferior and will be removed in a future patch. Also in this patch is a PCI quirk.c entry for an Infiniband PCI-X card which generates false positive parity errors. I am requesting comments on this AND on the possibility of a exposing this 'broken_parity_status' bit to userland via the PCI device sysfs directory for devices. This access would allow for enabling of this feature on new devices and for old devices that have their drivers updated. (SLES 9 SP3 did this on an ATI motherboard video device). There is a need to update such a PCI attribute between kernel releases. This patch just adds a storage place for the attribute and a quirk entry for a known bad PCI device. PCI Parity reaper/harvestor operations are in EDAC itself and will be refactored to use this PCI attribute instead of its own mechanisms (which are currently disabled) in the future. Signed-off-by: Doug Thompson Signed-off-by: Greg Kroah-Hartman --- include/linux/pci.h | 1 + include/linux/pci_ids.h | 1 + 2 files changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index b9eb9b021d6a..91c37750cd34 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -162,6 +162,7 @@ struct pci_dev { unsigned int is_busmaster:1; /* device is busmaster */ unsigned int no_msi:1; /* device may not use msi */ unsigned int block_ucfg_access:1; /* userspace config space access is blocked */ + unsigned int broken_parity_status:1; /* Device generates false positive parity */ u32 saved_config_space[16]; /* config space saved at suspend time */ struct hlist_head saved_cap_space; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index bcfe9d4f56ae..3d197cdcfa3a 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1946,6 +1946,7 @@ #define PCI_VENDOR_ID_MELLANOX 0x15b3 #define PCI_DEVICE_ID_MELLANOX_TAVOR 0x5a44 +#define PCI_DEVICE_ID_MELLANOX_TAVOR_BRIDGE 0x5a46 #define PCI_DEVICE_ID_MELLANOX_ARBEL_COMPAT 0x6278 #define PCI_DEVICE_ID_MELLANOX_ARBEL 0x6282 #define PCI_DEVICE_ID_MELLANOX_SINAI_OLD 0x5e8c -- cgit v1.2.3 From 74d0a988d3aa359b6b8a8536c8cb92cce02ca5d5 Mon Sep 17 00:00:00 2001 From: Brent Casavant Date: Wed, 10 May 2006 01:49:14 -0700 Subject: [PATCH] PCI: Move various PCI IDs to header file Move various QLogic, Vitesse, and Intel storage controller PCI IDs to the main header file. Signed-off-by: Brent Casavant Acked-by: Jes Sorensen Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman --- include/linux/pci_ids.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 3d197cdcfa3a..e526e7b5ea47 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -848,7 +848,12 @@ #define PCI_VENDOR_ID_QLOGIC 0x1077 +#define PCI_DEVICE_ID_QLOGIC_ISP10160 0x1016 #define PCI_DEVICE_ID_QLOGIC_ISP1020 0x1020 +#define PCI_DEVICE_ID_QLOGIC_ISP1080 0x1080 +#define PCI_DEVICE_ID_QLOGIC_ISP12160 0x1216 +#define PCI_DEVICE_ID_QLOGIC_ISP1240 0x1240 +#define PCI_DEVICE_ID_QLOGIC_ISP1280 0x1280 #define PCI_DEVICE_ID_QLOGIC_ISP2100 0x2100 #define PCI_DEVICE_ID_QLOGIC_ISP2200 0x2200 #define PCI_DEVICE_ID_QLOGIC_ISP2300 0x2300 @@ -1970,6 +1975,9 @@ #define PCI_VENDOR_ID_NETCELL 0x169c #define PCI_DEVICE_ID_REVOLUTION 0x0044 +#define PCI_VENDOR_ID_VITESSE 0x1725 +#define PCI_DEVICE_ID_VITESSE_VSC7174 0x7174 + #define PCI_VENDOR_ID_LINKSYS 0x1737 #define PCI_DEVICE_ID_LINKSYS_EG1064 0x1064 @@ -2149,6 +2157,7 @@ #define PCI_DEVICE_ID_INTEL_ICH8_4 0x2815 #define PCI_DEVICE_ID_INTEL_ICH8_5 0x283e #define PCI_DEVICE_ID_INTEL_ICH8_6 0x2850 +#define PCI_DEVICE_ID_INTEL_GD31244 0x3200 #define PCI_DEVICE_ID_INTEL_82855PM_HB 0x3340 #define PCI_DEVICE_ID_INTEL_82830_HB 0x3575 #define PCI_DEVICE_ID_INTEL_82830_CGC 0x3577 -- cgit v1.2.3 From 99dc804d9bcc2c53f4c20c291bf4e185312a1a0c Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Fri, 26 May 2006 10:58:27 +0800 Subject: [PATCH] PCI: disable msi mode in pci_disable_device Brice said the pci_save_msi_state breaks his driver in his special usage (not in suspend/resume), as pci_save_msi_state will disable msi mode. In his usage, pci_save_state will be called at runtime, and later (after the device operates for some time and has an error) pci_restore_state will be called. In another hand, suspend/resume needs disable msi mode, as device should stop working completely. This patch try to workaround this issue. Drivers are expected call pci_disable_device in suspend time after pci_save_state. Signed-off-by: Shaohua Li Signed-off-by: Greg Kroah-Hartman --- include/linux/pci.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci.h b/include/linux/pci.h index 91c37750cd34..62a8c22f5f60 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -163,6 +163,8 @@ struct pci_dev { unsigned int no_msi:1; /* device may not use msi */ unsigned int block_ucfg_access:1; /* userspace config space access is blocked */ unsigned int broken_parity_status:1; /* Device generates false positive parity */ + unsigned int msi_enabled:1; + unsigned int msix_enabled:1; u32 saved_config_space[16]; /* config space saved at suspend time */ struct hlist_head saved_cap_space; -- cgit v1.2.3 From cf34a8e07f02c76f3f1232eecb681301a3d7b10b Mon Sep 17 00:00:00 2001 From: Brice Goglin Date: Tue, 13 Jun 2006 14:35:42 -0400 Subject: [PATCH] PCI: nVidia quirk to make AER PCI-E extended capability visible The nVidia CK804 PCI-E chipset supports the AER extended capability but sometimes fails to link it (with some BIOS or after a warm reboot). It makes the AER cap invisible to pci_find_ext_capability(). The patch adds a quirk to set the missing bit that controls the linking of the capability. By the way, it removes the corresponding code in the myri10ge driver. Signed-off-by: Brice Goglin Signed-off-by: Loic Prylli Signed-off-by: Greg Kroah-Hartman --- include/linux/pci_ids.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index e526e7b5ea47..fd54a9d4c3d4 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1023,6 +1023,7 @@ #define PCI_DEVICE_ID_NVIDIA_NVENET_8 0x0056 #define PCI_DEVICE_ID_NVIDIA_NVENET_9 0x0057 #define PCI_DEVICE_ID_NVIDIA_CK804_AUDIO 0x0059 +#define PCI_DEVICE_ID_NVIDIA_CK804_PCIE 0x005d #define PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS 0x0064 #define PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE 0x0065 #define PCI_DEVICE_ID_NVIDIA_NVENET_2 0x0066 -- cgit v1.2.3 From 1cdcb6b43fda7424b7435dac8f80b2b5d8a48899 Mon Sep 17 00:00:00 2001 From: Hansjoerg Lipp Date: Sat, 22 Apr 2006 18:36:53 +0200 Subject: [PATCH] TTY: return class device pointer from tty_register_device() Let tty_register_device() return a pointer to the class device it creates. This allows registrants to add their own sysfs files under the class device node. Signed-off-by: Hansjoerg Lipp Signed-off-by: Tilman Schmidt Signed-off-by: Greg Kroah-Hartman --- include/linux/tty.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/tty.h b/include/linux/tty.h index e898eeb94166..cb35ca50a0a6 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -290,7 +290,9 @@ extern int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc); extern int tty_unregister_ldisc(int disc); extern int tty_register_driver(struct tty_driver *driver); extern int tty_unregister_driver(struct tty_driver *driver); -extern void tty_register_device(struct tty_driver *driver, unsigned index, struct device *dev); +extern struct class_device *tty_register_device(struct tty_driver *driver, + unsigned index, + struct device *dev); extern void tty_unregister_device(struct tty_driver *driver, unsigned index); extern int tty_read_raw_data(struct tty_struct *tty, unsigned char *bufp, int buflen); -- cgit v1.2.3 From 1740757e8f94c6899705eb6f5434de9404992778 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 2 May 2006 16:59:59 +0200 Subject: [PATCH] Driver Core: remove unused exports Cc: Arjan van de Ven Signed-off-by: Greg Kroah-Hartman --- include/linux/device.h | 8 -------- 1 file changed, 8 deletions(-) (limited to 'include/linux') diff --git a/include/linux/device.h b/include/linux/device.h index b2e5da2b637b..ade10dd6b779 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -60,11 +60,6 @@ extern void bus_unregister(struct bus_type * bus); extern void bus_rescan_devices(struct bus_type * bus); -extern struct bus_type * get_bus(struct bus_type * bus); -extern void put_bus(struct bus_type * bus); - -extern struct bus_type * find_bus(char * name); - /* iterator helpers for buses */ int bus_for_each_dev(struct bus_type * bus, struct device * start, void * data, @@ -163,9 +158,6 @@ struct class { extern int class_register(struct class *); extern void class_unregister(struct class *); -extern struct class * class_get(struct class *); -extern void class_put(struct class *); - struct class_attribute { struct attribute attr; -- cgit v1.2.3 From 670dd90d81f60ef429cbba54ad235e9207f4d444 Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Mon, 8 May 2006 13:45:57 +0800 Subject: [PATCH] Driver Core: Allow sysdev_class have attributes allow sysdev_class adding attribute. Next patch will use the new API to add an attribute under /sys/device/system/cpu/. Signed-off-by: Shaohua Li Signed-off-by: Greg Kroah-Hartman --- include/linux/sysdev.h | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/sysdev.h b/include/linux/sysdev.h index 2a4b432e1176..166a2e58c287 100644 --- a/include/linux/sysdev.h +++ b/include/linux/sysdev.h @@ -37,11 +37,27 @@ struct sysdev_class { struct kset kset; }; +struct sysdev_class_attribute { + struct attribute attr; + ssize_t (*show)(struct sysdev_class *, char *); + ssize_t (*store)(struct sysdev_class *, const char *, size_t); +}; + +#define SYSDEV_CLASS_ATTR(_name,_mode,_show,_store) \ +struct sysdev_class_attribute attr_##_name = { \ + .attr = {.name = __stringify(_name), .mode = _mode }, \ + .show = _show, \ + .store = _store, \ +}; + extern int sysdev_class_register(struct sysdev_class *); extern void sysdev_class_unregister(struct sysdev_class *); - +extern int sysdev_class_create_file(struct sysdev_class *, + struct sysdev_class_attribute *); +extern void sysdev_class_remove_file(struct sysdev_class *, + struct sysdev_class_attribute *); /** * Auxillary system device drivers. */ -- cgit v1.2.3 From 4039483fd3065920f035eed39ec59085421c0a4f Mon Sep 17 00:00:00 2001 From: Michael Holzheu Date: Tue, 9 May 2006 12:53:49 +0200 Subject: [PATCH] Driver Core: Add /sys/hypervisor when needed To have a home for all hypervisors, this patch creates /sys/hypervisor. A new config option SYS_HYPERVISOR is introduced, which should to be set by architecture dependent hypervisors (e.g. s390 or Xen). Acked-by: Martin Schwidefsky Signed-off-by: Michael Holzheu Signed-off-by: Greg Kroah-Hartman --- include/linux/kobject.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/kobject.h b/include/linux/kobject.h index c187c53cecd0..2d229327959e 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h @@ -190,6 +190,8 @@ struct subsystem _varname##_subsys = { \ /* The global /sys/kernel/ subsystem for people to chain off of */ extern struct subsystem kernel_subsys; +/* The global /sys/hypervisor/ subsystem */ +extern struct subsystem hypervisor_subsys; /** * Helpers for setting the kset of registered objects. -- cgit v1.2.3 From 23681e479129854305da1da32f7f1eaf635ef22c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 14 Jun 2006 12:14:34 -0700 Subject: [PATCH] Driver core: allow struct device to have a dev_t This is the first step in moving class_device to being replaced by struct device. It allows struct device to export a dev_t and makes it easy to dynamically create and destroy struct device as long as they are associated with a specific class. Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- include/linux/device.h | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'include/linux') diff --git a/include/linux/device.h b/include/linux/device.h index ade10dd6b779..b473f4278910 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -142,6 +142,7 @@ struct class { struct subsystem subsys; struct list_head children; + struct list_head devices; struct list_head interfaces; struct semaphore sem; /* locks both the children and interfaces lists */ @@ -305,6 +306,7 @@ struct device { struct kobject kobj; char bus_id[BUS_ID_SIZE]; /* position on parent bus */ struct device_attribute uevent_attr; + struct device_attribute *devt_attr; struct semaphore sem; /* semaphore to synchronize calls to * its driver. @@ -332,6 +334,11 @@ struct device { struct dma_coherent_mem *dma_mem; /* internal for coherent mem override */ + /* class_device migration path */ + struct list_head node; + struct class *class; /* optional*/ + dev_t devt; /* dev_t, creates the sysfs "dev" */ + void (*release)(struct device * dev); }; @@ -373,6 +380,13 @@ extern int device_attach(struct device * dev); extern void driver_attach(struct device_driver * drv); extern void device_reprobe(struct device *dev); +/* + * Easy functions for dynamically creating devices on the fly + */ +extern struct device *device_create(struct class *cls, struct device *parent, + dev_t devt, char *fmt, ...) + __attribute__((format(printf,4,5))); +extern void device_destroy(struct class *cls, dev_t devt); /* * Platform "fixup" functions - allow the platform to have their say -- cgit v1.2.3 From 3e95637a48820ff8bedb33e6439def96ccff1de5 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Fri, 16 Jun 2006 17:10:48 -0400 Subject: [PATCH] Driver Core: Make dev_info and friends print the bus name if there is no driver This patch (as721) makes dev_info and related macros print the device's bus name if the device doesn't have a driver, instead of printing just a blank. If the device isn't on a bus either... well, then it does leave a blank space. But it will be easier for someone else to change if they want. Cc: Matthew Wilcox Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- include/linux/device.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/device.h b/include/linux/device.h index b473f4278910..1e5f30da98bc 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -416,8 +416,9 @@ extern int firmware_register(struct subsystem *); extern void firmware_unregister(struct subsystem *); /* debugging and troubleshooting/diagnostic helpers. */ +extern const char *dev_driver_string(struct device *dev); #define dev_printk(level, dev, format, arg...) \ - printk(level "%s %s: " format , (dev)->driver ? (dev)->driver->name : "" , (dev)->bus_id , ## arg) + printk(level "%s %s: " format , dev_driver_string(dev) , (dev)->bus_id , ## arg) #ifdef DEBUG #define dev_dbg(dev, format, arg...) \ -- cgit v1.2.3 From a5117ba7da37deb09df5eb802dace229b3fb1e9f Mon Sep 17 00:00:00 2001 From: Rene Herman Date: Tue, 6 Jun 2006 23:54:02 +0200 Subject: [PATCH] Driver model: add ISA bus During the recent "isa drivers using platform devices" discussion it was pointed out that (ALSA) ISA drivers ran into the problem of not having the option to fail driver load (device registration rather) upon not finding their hardware due to a probe() error not being passed up through the driver model. In the course of that, I suggested a seperate ISA bus might be best; Russell King agreed and suggested this bus could use the .match() method for the actual device discovery. The attached does this. For this old non (generically) discoverable ISA hardware only the driver itself can do discovery so as a difference with the platform_bus, this isa_bus also distributes match() up to the driver. As another difference: these devices only exist in the driver model due to the driver creating them because it might want to drive them, meaning that all device creation has been made internal as well. The usage model this provides is nice, and has been acked from the ALSA side by Takashi Iwai and Jaroslav Kysela. The ALSA driver module_init's now (for oldisa-only drivers) become: static int __init alsa_card_foo_init(void) { return isa_register_driver(&snd_foo_isa_driver, SNDRV_CARDS); } static void __exit alsa_card_foo_exit(void) { isa_unregister_driver(&snd_foo_isa_driver); } Quite like the other bus models therefore. This removes a lot of duplicated init code from the ALSA ISA drivers. The passed in isa_driver struct is the regular driver struct embedding a struct device_driver, the normal probe/remove/shutdown/suspend/resume callbacks, and as indicated that .match callback. The "SNDRV_CARDS" you see being passed in is a "unsigned int ndev" parameter, indicating how many devices to create and call our methods with. The platform_driver callbacks are called with a platform_device param; the isa_driver callbacks are being called with a "struct device *dev, unsigned int id" pair directly -- with the device creation completely internal to the bus it's much cleaner to not leak isa_dev's by passing them in at all. The id is the only thing we ever want other then the struct device * anyways, and it makes for nicer code in the callbacks as well. With this additional .match() callback ISA drivers have all options. If ALSA would want to keep the old non-load behaviour, it could stick all of the old .probe in .match, which would only keep them registered after everything was found to be present and accounted for. If it wanted the behaviour of always loading as it inadvertently did for a bit after the changeover to platform devices, it could just not provide a .match() and do everything in .probe() as before. If it, as Takashi Iwai already suggested earlier as a way of following the model from saner buses more closely, wants to load when a later bind could conceivably succeed, it could use .match() for the prerequisites (such as checking the user wants the card enabled and that port/irq/dma values have been passed in) and .probe() for everything else. This is the nicest model. To the code... This exports only two functions; isa_{,un}register_driver(). isa_register_driver() register's the struct device_driver, and then loops over the passed in ndev creating devices and registering them. This causes the bus match method to be called for them, which is: int isa_bus_match(struct device *dev, struct device_driver *driver) { struct isa_driver *isa_driver = to_isa_driver(driver); if (dev->platform_data == isa_driver) { if (!isa_driver->match || isa_driver->match(dev, to_isa_dev(dev)->id)) return 1; dev->platform_data = NULL; } return 0; } The first thing this does is check if this device is in fact one of this driver's devices by seeing if the device's platform_data pointer is set to this driver. Platform devices compare strings, but we don't need to do that with everything being internal, so isa_register_driver() abuses dev->platform_data as a isa_driver pointer which we can then check here. I believe platform_data is available for this, but if rather not, moving the isa_driver pointer to the private struct isa_dev is ofcourse fine as well. Then, if the the driver did not provide a .match, it matches. If it did, the driver match() method is called to determine a match. If it did _not_ match, dev->platform_data is reset to indicate this to isa_register_driver which can then unregister the device again. If during all this, there's any error, or no devices matched at all everything is backed out again and the error, or -ENODEV, is returned. isa_unregister_driver() just unregisters the matched devices and the driver itself. More global points/questions... - I'm introducing include/linux/isa.h. It was available but is ofcourse a somewhat generic name. Moving more isa stuff over to it in time is ofcourse fine, so can I have it please? :) - I'm using device_initcall() and added the isa.o (dependent on CONFIG_ISA) after the base driver model things in the Makefile. Will this do, or I really need to stick it in drivers/base/init.c, inside #ifdef CONFIG_ISA? It's working fine. Lastly -- I also looked, a bit, into integrating with PnP. "Old ISA" could be another pnp_protocol, but this does not seem to be a good match, largely due to the same reason platform_devices weren't -- the devices do not have a life of their own outside the driver, meaning the pnp_protocol {get,set}_resources callbacks would need to callback into driver -- which again means you first need to _have_ that driver. Even if there's clean way around that, you only end up inventing fake but valid-form PnP IDs and generally catering to the PnP layer without any practical advantages over this very simple isa_bus. The thing I also suggested earlier about the user echoing values into /sys to set up the hardware from userspace first is... well, cute, but a horrible idea from a user standpoint. Comments ofcourse appreciated. Hope it's okay. As said, the usage model is nice at least. Signed-off-by: Rene Herman --- include/linux/isa.h | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 include/linux/isa.h (limited to 'include/linux') diff --git a/include/linux/isa.h b/include/linux/isa.h new file mode 100644 index 000000000000..1b855335cb11 --- /dev/null +++ b/include/linux/isa.h @@ -0,0 +1,28 @@ +/* + * ISA bus. + */ + +#ifndef __LINUX_ISA_H +#define __LINUX_ISA_H + +#include +#include + +struct isa_driver { + int (*match)(struct device *, unsigned int); + int (*probe)(struct device *, unsigned int); + int (*remove)(struct device *, unsigned int); + void (*shutdown)(struct device *, unsigned int); + int (*suspend)(struct device *, unsigned int, pm_message_t); + int (*resume)(struct device *, unsigned int); + + struct device_driver driver; + struct device *devices; +}; + +#define to_isa_driver(x) container_of((x), struct isa_driver, driver) + +int isa_register_driver(struct isa_driver *, unsigned int); +void isa_unregister_driver(struct isa_driver *); + +#endif /* __LINUX_ISA_H */ -- cgit v1.2.3 From 782a7a632e4b0581ade665e3d89ee97c8db0f441 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 19 May 2006 13:20:20 -0700 Subject: [PATCH] USB: add usb_interrupt_msg() function for api completeness. Really just a wrapper around usb_bulk_msg() but now it's documented much better. Signed-off-by: Greg Kroah-Hartman --- include/linux/usb.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/usb.h b/include/linux/usb.h index 1f492c0c7047..317ec9f28bce 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -1008,6 +1008,8 @@ void usb_buffer_unmap_sg (struct usb_device *dev, unsigned pipe, extern int usb_control_msg(struct usb_device *dev, unsigned int pipe, __u8 request, __u8 requesttype, __u16 value, __u16 index, void *data, __u16 size, int timeout); +extern int usb_interrupt_msg(struct usb_device *usb_dev, unsigned int pipe, + void *data, int len, int *actual_length, int timeout); extern int usb_bulk_msg(struct usb_device *usb_dev, unsigned int pipe, void *data, int len, int *actual_length, int timeout); -- cgit v1.2.3 From 79efa097e75018a2918155f343f0e08e61ee8a8c Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Thu, 1 Jun 2006 13:33:42 -0400 Subject: [PATCH] usbcore: port reset for composite devices This patch (as699) adds usb_reset_composite_device(), a routine for sending a USB port reset to a device with multiple interfaces owned by different drivers. Drivers are notified about impending and completed resets through two new methods in the usb_driver structure. The patch modifieds the usbfs ioctl code to make it use the new routine instead of usb_reset_device(). Follow-up patches will modify the hub, usb-storage, and usbhid drivers so they can utilize this new API. Signed-off-by: Alan Stern Signed-off-by: Greg Kroah-Hartman --- include/linux/usb.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include/linux') diff --git a/include/linux/usb.h b/include/linux/usb.h index 317ec9f28bce..5ad30cefe7b2 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -386,6 +386,8 @@ extern int usb_lock_device_for_reset(struct usb_device *udev, /* USB port reset for device reinitialization */ extern int usb_reset_device(struct usb_device *dev); +extern int usb_reset_composite_device(struct usb_device *dev, + struct usb_interface *iface); extern struct usb_device *usb_find_device(u16 vendor_id, u16 product_id); @@ -554,6 +556,10 @@ struct usb_dynids { * do (or don't) show up otherwise in the filesystem. * @suspend: Called when the device is going to be suspended by the system. * @resume: Called when the device is being resumed by the system. + * @pre_reset: Called by usb_reset_composite_device() when the device + * is about to be reset. + * @post_reset: Called by usb_reset_composite_device() after the device + * has been reset. * @id_table: USB drivers use ID table to support hotplugging. * Export this with MODULE_DEVICE_TABLE(usb,...). This must be set * or your driver's probe function will never get called. @@ -592,6 +598,9 @@ struct usb_driver { int (*suspend) (struct usb_interface *intf, pm_message_t message); int (*resume) (struct usb_interface *intf); + void (*pre_reset) (struct usb_interface *intf); + void (*post_reset) (struct usb_interface *intf); + const struct usb_device_id *id_table; struct usb_dynids dynids; -- cgit v1.2.3 From a8c28f2389942bab376e39351d27525499630248 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Tue, 13 Jun 2006 09:57:47 -0700 Subject: [PATCH] USB: move to This moves to to reduce some of the clutter of usb header files. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- include/linux/usb/cdc.h | 205 ++++++++++++++++++++++++++++++++++++++++++++++++ include/linux/usb_cdc.h | 205 ------------------------------------------------ 2 files changed, 205 insertions(+), 205 deletions(-) create mode 100644 include/linux/usb/cdc.h delete mode 100644 include/linux/usb_cdc.h (limited to 'include/linux') diff --git a/include/linux/usb/cdc.h b/include/linux/usb/cdc.h new file mode 100644 index 000000000000..ba617c372455 --- /dev/null +++ b/include/linux/usb/cdc.h @@ -0,0 +1,205 @@ +/* + * USB Communications Device Class (CDC) definitions + * + * CDC says how to talk to lots of different types of network adapters, + * notably ethernet adapters and various modems. It's used mostly with + * firmware based USB peripherals. + */ + +#define USB_CDC_SUBCLASS_ACM 0x02 +#define USB_CDC_SUBCLASS_ETHERNET 0x06 +#define USB_CDC_SUBCLASS_WHCM 0x08 +#define USB_CDC_SUBCLASS_DMM 0x09 +#define USB_CDC_SUBCLASS_MDLM 0x0a +#define USB_CDC_SUBCLASS_OBEX 0x0b + +#define USB_CDC_PROTO_NONE 0 + +#define USB_CDC_ACM_PROTO_AT_V25TER 1 +#define USB_CDC_ACM_PROTO_AT_PCCA101 2 +#define USB_CDC_ACM_PROTO_AT_PCCA101_WAKE 3 +#define USB_CDC_ACM_PROTO_AT_GSM 4 +#define USB_CDC_ACM_PROTO_AT_3G 5 +#define USB_CDC_ACM_PROTO_AT_CDMA 6 +#define USB_CDC_ACM_PROTO_VENDOR 0xff + +/*-------------------------------------------------------------------------*/ + +/* + * Class-Specific descriptors ... there are a couple dozen of them + */ + +#define USB_CDC_HEADER_TYPE 0x00 /* header_desc */ +#define USB_CDC_CALL_MANAGEMENT_TYPE 0x01 /* call_mgmt_descriptor */ +#define USB_CDC_ACM_TYPE 0x02 /* acm_descriptor */ +#define USB_CDC_UNION_TYPE 0x06 /* union_desc */ +#define USB_CDC_COUNTRY_TYPE 0x07 +#define USB_CDC_NETWORK_TERMINAL_TYPE 0x0a /* network_terminal_desc */ +#define USB_CDC_ETHERNET_TYPE 0x0f /* ether_desc */ +#define USB_CDC_WHCM_TYPE 0x11 +#define USB_CDC_MDLM_TYPE 0x12 /* mdlm_desc */ +#define USB_CDC_MDLM_DETAIL_TYPE 0x13 /* mdlm_detail_desc */ +#define USB_CDC_DMM_TYPE 0x14 +#define USB_CDC_OBEX_TYPE 0x15 + +/* "Header Functional Descriptor" from CDC spec 5.2.3.1 */ +struct usb_cdc_header_desc { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubType; + + __le16 bcdCDC; +} __attribute__ ((packed)); + +/* "Call Management Descriptor" from CDC spec 5.2.3.2 */ +struct usb_cdc_call_mgmt_descriptor { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubType; + + __u8 bmCapabilities; +#define USB_CDC_CALL_MGMT_CAP_CALL_MGMT 0x01 +#define USB_CDC_CALL_MGMT_CAP_DATA_INTF 0x02 + + __u8 bDataInterface; +} __attribute__ ((packed)); + +/* "Abstract Control Management Descriptor" from CDC spec 5.2.3.3 */ +struct usb_cdc_acm_descriptor { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubType; + + __u8 bmCapabilities; +} __attribute__ ((packed)); + +/* "Union Functional Descriptor" from CDC spec 5.2.3.8 */ +struct usb_cdc_union_desc { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubType; + + __u8 bMasterInterface0; + __u8 bSlaveInterface0; + /* ... and there could be other slave interfaces */ +} __attribute__ ((packed)); + +/* "Network Channel Terminal Functional Descriptor" from CDC spec 5.2.3.11 */ +struct usb_cdc_network_terminal_desc { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubType; + + __u8 bEntityId; + __u8 iName; + __u8 bChannelIndex; + __u8 bPhysicalInterface; +} __attribute__ ((packed)); + +/* "Ethernet Networking Functional Descriptor" from CDC spec 5.2.3.16 */ +struct usb_cdc_ether_desc { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubType; + + __u8 iMACAddress; + __le32 bmEthernetStatistics; + __le16 wMaxSegmentSize; + __le16 wNumberMCFilters; + __u8 bNumberPowerFilters; +} __attribute__ ((packed)); + +/* "MDLM Functional Descriptor" from CDC WMC spec 6.7.2.3 */ +struct usb_cdc_mdlm_desc { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubType; + + __le16 bcdVersion; + __u8 bGUID[16]; +} __attribute__ ((packed)); + +/* "MDLM Detail Functional Descriptor" from CDC WMC spec 6.7.2.4 */ +struct usb_cdc_mdlm_detail_desc { + __u8 bLength; + __u8 bDescriptorType; + __u8 bDescriptorSubType; + + /* type is associated with mdlm_desc.bGUID */ + __u8 bGuidDescriptorType; + __u8 bDetailData[0]; +} __attribute__ ((packed)); + +/*-------------------------------------------------------------------------*/ + +/* + * Class-Specific Control Requests (6.2) + * + * section 3.6.2.1 table 4 has the ACM profile, for modems. + * section 3.8.2 table 10 has the ethernet profile. + * + * Microsoft's RNDIS stack for Ethernet is a vendor-specific CDC ACM variant, + * heavily dependent on the encapsulated (proprietary) command mechanism. + */ + +#define USB_CDC_SEND_ENCAPSULATED_COMMAND 0x00 +#define USB_CDC_GET_ENCAPSULATED_RESPONSE 0x01 +#define USB_CDC_REQ_SET_LINE_CODING 0x20 +#define USB_CDC_REQ_GET_LINE_CODING 0x21 +#define USB_CDC_REQ_SET_CONTROL_LINE_STATE 0x22 +#define USB_CDC_REQ_SEND_BREAK 0x23 +#define USB_CDC_SET_ETHERNET_MULTICAST_FILTERS 0x40 +#define USB_CDC_SET_ETHERNET_PM_PATTERN_FILTER 0x41 +#define USB_CDC_GET_ETHERNET_PM_PATTERN_FILTER 0x42 +#define USB_CDC_SET_ETHERNET_PACKET_FILTER 0x43 +#define USB_CDC_GET_ETHERNET_STATISTIC 0x44 + +/* Line Coding Structure from CDC spec 6.2.13 */ +struct usb_cdc_line_coding { + __le32 dwDTERate; + __u8 bCharFormat; +#define USB_CDC_1_STOP_BITS 0 +#define USB_CDC_1_5_STOP_BITS 1 +#define USB_CDC_2_STOP_BITS 2 + + __u8 bParityType; +#define USB_CDC_NO_PARITY 0 +#define USB_CDC_ODD_PARITY 1 +#define USB_CDC_EVEN_PARITY 2 +#define USB_CDC_MARK_PARITY 3 +#define USB_CDC_SPACE_PARITY 4 + + __u8 bDataBits; +} __attribute__ ((packed)); + +/* table 62; bits in multicast filter */ +#define USB_CDC_PACKET_TYPE_PROMISCUOUS (1 << 0) +#define USB_CDC_PACKET_TYPE_ALL_MULTICAST (1 << 1) /* no filter */ +#define USB_CDC_PACKET_TYPE_DIRECTED (1 << 2) +#define USB_CDC_PACKET_TYPE_BROADCAST (1 << 3) +#define USB_CDC_PACKET_TYPE_MULTICAST (1 << 4) /* filtered */ + + +/*-------------------------------------------------------------------------*/ + +/* + * Class-Specific Notifications (6.3) sent by interrupt transfers + * + * section 3.8.2 table 11 of the CDC spec lists Ethernet notifications + * section 3.6.2.1 table 5 specifies ACM notifications, accepted by RNDIS + * RNDIS also defines its own bit-incompatible notifications + */ + +#define USB_CDC_NOTIFY_NETWORK_CONNECTION 0x00 +#define USB_CDC_NOTIFY_RESPONSE_AVAILABLE 0x01 +#define USB_CDC_NOTIFY_SERIAL_STATE 0x20 +#define USB_CDC_NOTIFY_SPEED_CHANGE 0x2a + +struct usb_cdc_notification { + __u8 bmRequestType; + __u8 bNotificationType; + __le16 wValue; + __le16 wIndex; + __le16 wLength; +} __attribute__ ((packed)); + diff --git a/include/linux/usb_cdc.h b/include/linux/usb_cdc.h deleted file mode 100644 index ba617c372455..000000000000 --- a/include/linux/usb_cdc.h +++ /dev/null @@ -1,205 +0,0 @@ -/* - * USB Communications Device Class (CDC) definitions - * - * CDC says how to talk to lots of different types of network adapters, - * notably ethernet adapters and various modems. It's used mostly with - * firmware based USB peripherals. - */ - -#define USB_CDC_SUBCLASS_ACM 0x02 -#define USB_CDC_SUBCLASS_ETHERNET 0x06 -#define USB_CDC_SUBCLASS_WHCM 0x08 -#define USB_CDC_SUBCLASS_DMM 0x09 -#define USB_CDC_SUBCLASS_MDLM 0x0a -#define USB_CDC_SUBCLASS_OBEX 0x0b - -#define USB_CDC_PROTO_NONE 0 - -#define USB_CDC_ACM_PROTO_AT_V25TER 1 -#define USB_CDC_ACM_PROTO_AT_PCCA101 2 -#define USB_CDC_ACM_PROTO_AT_PCCA101_WAKE 3 -#define USB_CDC_ACM_PROTO_AT_GSM 4 -#define USB_CDC_ACM_PROTO_AT_3G 5 -#define USB_CDC_ACM_PROTO_AT_CDMA 6 -#define USB_CDC_ACM_PROTO_VENDOR 0xff - -/*-------------------------------------------------------------------------*/ - -/* - * Class-Specific descriptors ... there are a couple dozen of them - */ - -#define USB_CDC_HEADER_TYPE 0x00 /* header_desc */ -#define USB_CDC_CALL_MANAGEMENT_TYPE 0x01 /* call_mgmt_descriptor */ -#define USB_CDC_ACM_TYPE 0x02 /* acm_descriptor */ -#define USB_CDC_UNION_TYPE 0x06 /* union_desc */ -#define USB_CDC_COUNTRY_TYPE 0x07 -#define USB_CDC_NETWORK_TERMINAL_TYPE 0x0a /* network_terminal_desc */ -#define USB_CDC_ETHERNET_TYPE 0x0f /* ether_desc */ -#define USB_CDC_WHCM_TYPE 0x11 -#define USB_CDC_MDLM_TYPE 0x12 /* mdlm_desc */ -#define USB_CDC_MDLM_DETAIL_TYPE 0x13 /* mdlm_detail_desc */ -#define USB_CDC_DMM_TYPE 0x14 -#define USB_CDC_OBEX_TYPE 0x15 - -/* "Header Functional Descriptor" from CDC spec 5.2.3.1 */ -struct usb_cdc_header_desc { - __u8 bLength; - __u8 bDescriptorType; - __u8 bDescriptorSubType; - - __le16 bcdCDC; -} __attribute__ ((packed)); - -/* "Call Management Descriptor" from CDC spec 5.2.3.2 */ -struct usb_cdc_call_mgmt_descriptor { - __u8 bLength; - __u8 bDescriptorType; - __u8 bDescriptorSubType; - - __u8 bmCapabilities; -#define USB_CDC_CALL_MGMT_CAP_CALL_MGMT 0x01 -#define USB_CDC_CALL_MGMT_CAP_DATA_INTF 0x02 - - __u8 bDataInterface; -} __attribute__ ((packed)); - -/* "Abstract Control Management Descriptor" from CDC spec 5.2.3.3 */ -struct usb_cdc_acm_descriptor { - __u8 bLength; - __u8 bDescriptorType; - __u8 bDescriptorSubType; - - __u8 bmCapabilities; -} __attribute__ ((packed)); - -/* "Union Functional Descriptor" from CDC spec 5.2.3.8 */ -struct usb_cdc_union_desc { - __u8 bLength; - __u8 bDescriptorType; - __u8 bDescriptorSubType; - - __u8 bMasterInterface0; - __u8 bSlaveInterface0; - /* ... and there could be other slave interfaces */ -} __attribute__ ((packed)); - -/* "Network Channel Terminal Functional Descriptor" from CDC spec 5.2.3.11 */ -struct usb_cdc_network_terminal_desc { - __u8 bLength; - __u8 bDescriptorType; - __u8 bDescriptorSubType; - - __u8 bEntityId; - __u8 iName; - __u8 bChannelIndex; - __u8 bPhysicalInterface; -} __attribute__ ((packed)); - -/* "Ethernet Networking Functional Descriptor" from CDC spec 5.2.3.16 */ -struct usb_cdc_ether_desc { - __u8 bLength; - __u8 bDescriptorType; - __u8 bDescriptorSubType; - - __u8 iMACAddress; - __le32 bmEthernetStatistics; - __le16 wMaxSegmentSize; - __le16 wNumberMCFilters; - __u8 bNumberPowerFilters; -} __attribute__ ((packed)); - -/* "MDLM Functional Descriptor" from CDC WMC spec 6.7.2.3 */ -struct usb_cdc_mdlm_desc { - __u8 bLength; - __u8 bDescriptorType; - __u8 bDescriptorSubType; - - __le16 bcdVersion; - __u8 bGUID[16]; -} __attribute__ ((packed)); - -/* "MDLM Detail Functional Descriptor" from CDC WMC spec 6.7.2.4 */ -struct usb_cdc_mdlm_detail_desc { - __u8 bLength; - __u8 bDescriptorType; - __u8 bDescriptorSubType; - - /* type is associated with mdlm_desc.bGUID */ - __u8 bGuidDescriptorType; - __u8 bDetailData[0]; -} __attribute__ ((packed)); - -/*-------------------------------------------------------------------------*/ - -/* - * Class-Specific Control Requests (6.2) - * - * section 3.6.2.1 table 4 has the ACM profile, for modems. - * section 3.8.2 table 10 has the ethernet profile. - * - * Microsoft's RNDIS stack for Ethernet is a vendor-specific CDC ACM variant, - * heavily dependent on the encapsulated (proprietary) command mechanism. - */ - -#define USB_CDC_SEND_ENCAPSULATED_COMMAND 0x00 -#define USB_CDC_GET_ENCAPSULATED_RESPONSE 0x01 -#define USB_CDC_REQ_SET_LINE_CODING 0x20 -#define USB_CDC_REQ_GET_LINE_CODING 0x21 -#define USB_CDC_REQ_SET_CONTROL_LINE_STATE 0x22 -#define USB_CDC_REQ_SEND_BREAK 0x23 -#define USB_CDC_SET_ETHERNET_MULTICAST_FILTERS 0x40 -#define USB_CDC_SET_ETHERNET_PM_PATTERN_FILTER 0x41 -#define USB_CDC_GET_ETHERNET_PM_PATTERN_FILTER 0x42 -#define USB_CDC_SET_ETHERNET_PACKET_FILTER 0x43 -#define USB_CDC_GET_ETHERNET_STATISTIC 0x44 - -/* Line Coding Structure from CDC spec 6.2.13 */ -struct usb_cdc_line_coding { - __le32 dwDTERate; - __u8 bCharFormat; -#define USB_CDC_1_STOP_BITS 0 -#define USB_CDC_1_5_STOP_BITS 1 -#define USB_CDC_2_STOP_BITS 2 - - __u8 bParityType; -#define USB_CDC_NO_PARITY 0 -#define USB_CDC_ODD_PARITY 1 -#define USB_CDC_EVEN_PARITY 2 -#define USB_CDC_MARK_PARITY 3 -#define USB_CDC_SPACE_PARITY 4 - - __u8 bDataBits; -} __attribute__ ((packed)); - -/* table 62; bits in multicast filter */ -#define USB_CDC_PACKET_TYPE_PROMISCUOUS (1 << 0) -#define USB_CDC_PACKET_TYPE_ALL_MULTICAST (1 << 1) /* no filter */ -#define USB_CDC_PACKET_TYPE_DIRECTED (1 << 2) -#define USB_CDC_PACKET_TYPE_BROADCAST (1 << 3) -#define USB_CDC_PACKET_TYPE_MULTICAST (1 << 4) /* filtered */ - - -/*-------------------------------------------------------------------------*/ - -/* - * Class-Specific Notifications (6.3) sent by interrupt transfers - * - * section 3.8.2 table 11 of the CDC spec lists Ethernet notifications - * section 3.6.2.1 table 5 specifies ACM notifications, accepted by RNDIS - * RNDIS also defines its own bit-incompatible notifications - */ - -#define USB_CDC_NOTIFY_NETWORK_CONNECTION 0x00 -#define USB_CDC_NOTIFY_RESPONSE_AVAILABLE 0x01 -#define USB_CDC_NOTIFY_SERIAL_STATE 0x20 -#define USB_CDC_NOTIFY_SPEED_CHANGE 0x2a - -struct usb_cdc_notification { - __u8 bmRequestType; - __u8 bNotificationType; - __le16 wValue; - __le16 wIndex; - __le16 wLength; -} __attribute__ ((packed)); - -- cgit v1.2.3 From 325a4af60dc945bf2da9cbcdbabb276e312b297c Mon Sep 17 00:00:00 2001 From: David Brownell Date: Tue, 13 Jun 2006 09:59:32 -0700 Subject: [PATCH] USB: move hardware-specific to This moves header files for controller-specific platform data from to to start reducing some clutter. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- include/linux/usb/isp116x.h | 29 +++++++++++++++++++++++++++++ include/linux/usb/sl811.h | 26 ++++++++++++++++++++++++++ include/linux/usb_isp116x.h | 29 ----------------------------- include/linux/usb_sl811.h | 26 -------------------------- 4 files changed, 55 insertions(+), 55 deletions(-) create mode 100644 include/linux/usb/isp116x.h create mode 100644 include/linux/usb/sl811.h delete mode 100644 include/linux/usb_isp116x.h delete mode 100644 include/linux/usb_sl811.h (limited to 'include/linux') diff --git a/include/linux/usb/isp116x.h b/include/linux/usb/isp116x.h new file mode 100644 index 000000000000..436dd8a2b64a --- /dev/null +++ b/include/linux/usb/isp116x.h @@ -0,0 +1,29 @@ + +/* + * Board initialization code should put one of these into dev->platform_data + * and place the isp116x onto platform_bus. + */ + +struct isp116x_platform_data { + /* Enable internal resistors on downstream ports */ + unsigned sel15Kres:1; + /* On-chip overcurrent detection */ + unsigned oc_enable:1; + /* INT output polarity */ + unsigned int_act_high:1; + /* INT edge or level triggered */ + unsigned int_edge_triggered:1; + /* Enable wakeup by devices on usb bus (e.g. wakeup + by attachment/detachment or by device activity + such as moving a mouse). When chosen, this option + prevents stopping internal clock, increasing + thereby power consumption in suspended state. */ + unsigned remote_wakeup_enable:1; + /* Inter-io delay (ns). The chip is picky about access timings; it + expects at least: + 150ns delay between consecutive accesses to DATA_REG, + 300ns delay between access to ADDR_REG and DATA_REG + OE, WE MUST NOT be changed during these intervals + */ + void (*delay) (struct device * dev, int delay); +}; diff --git a/include/linux/usb/sl811.h b/include/linux/usb/sl811.h new file mode 100644 index 000000000000..397ee3b3d7f3 --- /dev/null +++ b/include/linux/usb/sl811.h @@ -0,0 +1,26 @@ + +/* + * board initialization should put one of these into dev->platform_data + * and place the sl811hs onto platform_bus named "sl811-hcd". + */ + +struct sl811_platform_data { + unsigned can_wakeup:1; + + /* given port_power, msec/2 after power on till power good */ + u8 potpg; + + /* mA/2 power supplied on this port (max = default = 250) */ + u8 power; + + /* sl811 relies on an external source of VBUS current */ + void (*port_power)(struct device *dev, int is_on); + + /* pulse sl811 nRST (probably with a GPIO) */ + void (*reset)(struct device *dev); + + // some boards need something like these: + // int (*check_overcurrent)(struct device *dev); + // void (*clock_enable)(struct device *dev, int is_on); +}; + diff --git a/include/linux/usb_isp116x.h b/include/linux/usb_isp116x.h deleted file mode 100644 index 436dd8a2b64a..000000000000 --- a/include/linux/usb_isp116x.h +++ /dev/null @@ -1,29 +0,0 @@ - -/* - * Board initialization code should put one of these into dev->platform_data - * and place the isp116x onto platform_bus. - */ - -struct isp116x_platform_data { - /* Enable internal resistors on downstream ports */ - unsigned sel15Kres:1; - /* On-chip overcurrent detection */ - unsigned oc_enable:1; - /* INT output polarity */ - unsigned int_act_high:1; - /* INT edge or level triggered */ - unsigned int_edge_triggered:1; - /* Enable wakeup by devices on usb bus (e.g. wakeup - by attachment/detachment or by device activity - such as moving a mouse). When chosen, this option - prevents stopping internal clock, increasing - thereby power consumption in suspended state. */ - unsigned remote_wakeup_enable:1; - /* Inter-io delay (ns). The chip is picky about access timings; it - expects at least: - 150ns delay between consecutive accesses to DATA_REG, - 300ns delay between access to ADDR_REG and DATA_REG - OE, WE MUST NOT be changed during these intervals - */ - void (*delay) (struct device * dev, int delay); -}; diff --git a/include/linux/usb_sl811.h b/include/linux/usb_sl811.h deleted file mode 100644 index 4f2d012d7309..000000000000 --- a/include/linux/usb_sl811.h +++ /dev/null @@ -1,26 +0,0 @@ - -/* - * board initialization should put one of these into dev->platform_data - * and place the sl811hs onto platform_bus named "sl811-hcd". - */ - -struct sl811_platform_data { - unsigned can_wakeup:1; - - /* given port_power, msec/2 after power on till power good */ - u8 potpg; - - /* mA/2 power supplied on this port (max = default = 250) */ - u8 power; - - /* sl811 relies on an external source of VBUS current */ - void (*port_power)(struct device *dev, int is_on); - - /* pulse sl811 nRST (probably with a GPIO) */ - void (*reset)(struct device *dev); - - // some boards need something like these: - // int (*check_overcurrent)(struct device *dev); - // void (*clock_enable)(struct device *dev, int is_on); -}; - -- cgit v1.2.3 From ae0dadcf0f912cbab2ac84caa437454620bf71b2 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Tue, 13 Jun 2006 10:04:34 -0700 Subject: [PATCH] USB: move to Move to and remove some redundant includes. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- include/linux/usb/input.h | 25 +++++++++++++++++++++++++ include/linux/usb_input.h | 25 ------------------------- 2 files changed, 25 insertions(+), 25 deletions(-) create mode 100644 include/linux/usb/input.h delete mode 100644 include/linux/usb_input.h (limited to 'include/linux') diff --git a/include/linux/usb/input.h b/include/linux/usb/input.h new file mode 100644 index 000000000000..716e0cc16043 --- /dev/null +++ b/include/linux/usb/input.h @@ -0,0 +1,25 @@ +#ifndef __USB_INPUT_H +#define __USB_INPUT_H + +/* + * Copyright (C) 2005 Dmitry Torokhov + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 as published by + * the Free Software Foundation. + */ + +#include +#include +#include + +static inline void +usb_to_input_id(const struct usb_device *dev, struct input_id *id) +{ + id->bustype = BUS_USB; + id->vendor = le16_to_cpu(dev->descriptor.idVendor); + id->product = le16_to_cpu(dev->descriptor.idProduct); + id->version = le16_to_cpu(dev->descriptor.bcdDevice); +} + +#endif diff --git a/include/linux/usb_input.h b/include/linux/usb_input.h deleted file mode 100644 index 716e0cc16043..000000000000 --- a/include/linux/usb_input.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef __USB_INPUT_H -#define __USB_INPUT_H - -/* - * Copyright (C) 2005 Dmitry Torokhov - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - */ - -#include -#include -#include - -static inline void -usb_to_input_id(const struct usb_device *dev, struct input_id *id) -{ - id->bustype = BUS_USB; - id->vendor = le16_to_cpu(dev->descriptor.idVendor); - id->product = le16_to_cpu(dev->descriptor.idProduct); - id->version = le16_to_cpu(dev->descriptor.bcdDevice); -} - -#endif -- cgit v1.2.3 From 9bde7497e0b54178c317fac47a18be7f948dd471 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 14 Jun 2006 12:14:34 -0700 Subject: [PATCH] USB: make endpoints real struct devices This will allow for us to give endpoints a major/minor to create a "usbfs2-like" way to access endpoints directly from userspace in an easier manner than the current usbfs provides us. Signed-off-by: Greg Kroah-Hartman --- include/linux/usb.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/usb.h b/include/linux/usb.h index 5ad30cefe7b2..46956a72de5d 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -40,6 +40,8 @@ struct usb_driver; * Devices may also have class-specific or vendor-specific descriptors. */ +struct ep_device; + /** * struct usb_host_endpoint - host-side endpoint descriptor and queue * @desc: descriptor for this endpoint, wMaxPacketSize in native byteorder @@ -57,7 +59,7 @@ struct usb_host_endpoint { struct usb_endpoint_descriptor desc; struct list_head urb_list; void *hcpriv; - struct kobject *kobj; /* For sysfs info */ + struct ep_device *ep_dev; /* For sysfs info */ unsigned char *extra; /* Extra descriptors */ int extralen; -- cgit v1.2.3 From c182274ffe1277f4e7c564719a696a37cacf74ea Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 19 Jun 2006 23:59:31 -0700 Subject: [PATCH] USB: move usb_device_class class devices to be real devices This moves the usb class devices that control the usbfs nodes to show up in the proper place in the larger device tree. No userspace changes is needed, this is compatible due to the symlinks generated by the driver core. Cc: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- include/linux/usb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/usb.h b/include/linux/usb.h index 46956a72de5d..b69b6cfb0bd7 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -360,7 +360,7 @@ struct usb_device { char *serial; /* iSerialNumber string, if present */ struct list_head filelist; - struct class_device *class_dev; + struct device *usbfs_dev; struct dentry *usbfs_dentry; /* usbfs dentry entry for the device */ /* -- cgit v1.2.3 From bd00949647ddcea47ce4ea8bb2cfcfc98ebf9f2a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 20 Jun 2006 13:09:50 -0700 Subject: [PATCH] USB: convert usb class devices to real devices Signed-off-by: Greg Kroah-Hartman --- include/linux/usb.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/usb.h b/include/linux/usb.h index b69b6cfb0bd7..8dead32e7ebf 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -103,7 +103,8 @@ enum usb_interface_condition { * @condition: binding state of the interface: not bound, binding * (in probe()), bound to a driver, or unbinding (in disconnect()) * @dev: driver model's view of this device - * @class_dev: driver model's class view of this device. + * @usb_dev: if an interface is bound to the USB major, this will point + * to the sysfs representation for that device. * * USB device drivers attach to interfaces on a physical device. Each * interface encapsulates a single high level function, such as feeding @@ -143,7 +144,7 @@ struct usb_interface { * bound to */ enum usb_interface_condition condition; /* state of binding */ struct device dev; /* interface specific device info */ - struct class_device *class_dev; + struct device *usb_dev; /* pointer to the usb class's device, if any */ }; #define to_usb_interface(d) container_of(d, struct usb_interface, dev) #define interface_to_usbdev(intf) \ -- cgit v1.2.3 From 02e0c5d5c2e00374b6808a42f8eea4ea9baaa216 Mon Sep 17 00:00:00 2001 From: Rudolf Marek Date: Thu, 23 Mar 2006 16:48:09 +0100 Subject: [PATCH] i2c-piix4: Add ATI IXP200/300/400 support This patch adds the ATI IXP southbridges support to i2c-piix4, as it turned out those chips are compatible with it. Signed-off-by: Rudolf Marek Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- include/linux/pci_ids.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index bcfe9d4f56ae..489af9d3ce1f 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -352,8 +352,11 @@ #define PCI_DEVICE_ID_ATI_RS480 0x5950 /* ATI IXP Chipset */ #define PCI_DEVICE_ID_ATI_IXP200_IDE 0x4349 +#define PCI_DEVICE_ID_ATI_IXP200_SMBUS 0x4353 +#define PCI_DEVICE_ID_ATI_IXP300_SMBUS 0x4363 #define PCI_DEVICE_ID_ATI_IXP300_IDE 0x4369 #define PCI_DEVICE_ID_ATI_IXP300_SATA 0x436e +#define PCI_DEVICE_ID_ATI_IXP400_SMBUS 0x4372 #define PCI_DEVICE_ID_ATI_IXP400_IDE 0x4376 #define PCI_DEVICE_ID_ATI_IXP400_SATA 0x4379 #define PCI_DEVICE_ID_ATI_IXP400_SATA2 0x437a -- cgit v1.2.3 From 5e9f4f2e5a02bb6908278a819952aa31fffefaa2 Mon Sep 17 00:00:00 2001 From: "Mark A. Greer" Date: Tue, 25 Apr 2006 13:04:54 +0200 Subject: [PATCH] I2C: m41t00: Add support for the ST M41T81 and M41T85 This patch adds support for the ST m41t81 and m41t85 i2c rtc chips to the existing m41t00 driver. Since there is no way to reliably determine what type of rtc chip is in use, the chip type is passed in via platform_data. The i2c address and square wave frequency are passed in via platform_data as well. To accommodate the use of platform_data, a new header file include/linux/m41t00.h has been added. The m41t81 and m41t85 chips halt the updating of their time registers while they are being accessed. They resume when a stop condition exists on the i2c bus or when non-time related regs are accessed. To make the best use of that facility and to make more efficient use of the i2c bus, this patch replaces multiple i2c_smbus_xxx calls with a single i2c_transfer call. Signed-off-by: Mark A. Greer Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- include/linux/m41t00.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 include/linux/m41t00.h (limited to 'include/linux') diff --git a/include/linux/m41t00.h b/include/linux/m41t00.h new file mode 100644 index 000000000000..b423360ca38e --- /dev/null +++ b/include/linux/m41t00.h @@ -0,0 +1,50 @@ +/* + * Definitions for the ST M41T00 family of i2c rtc chips. + * + * Author: Mark A. Greer + * + * 2005, 2006 (c) MontaVista Software, Inc. This file is licensed under + * the terms of the GNU General Public License version 2. This program + * is licensed "as is" without any warranty of any kind, whether express + * or implied. + */ + +#ifndef _M41T00_H +#define _M41T00_H + +#define M41T00_DRV_NAME "m41t00" +#define M41T00_I2C_ADDR 0x68 + +#define M41T00_TYPE_M41T00 0 +#define M41T00_TYPE_M41T81 81 +#define M41T00_TYPE_M41T85 85 + +struct m41t00_platform_data { + u8 type; + u8 i2c_addr; + u8 sqw_freq; +}; + +/* SQW output disabled, this is default value by power on */ +#define M41T00_SQW_DISABLE (0) + +#define M41T00_SQW_32KHZ (1<<4) /* 32.768 KHz */ +#define M41T00_SQW_8KHZ (2<<4) /* 8.192 KHz */ +#define M41T00_SQW_4KHZ (3<<4) /* 4.096 KHz */ +#define M41T00_SQW_2KHZ (4<<4) /* 2.048 KHz */ +#define M41T00_SQW_1KHZ (5<<4) /* 1.024 KHz */ +#define M41T00_SQW_512HZ (6<<4) /* 512 Hz */ +#define M41T00_SQW_256HZ (7<<4) /* 256 Hz */ +#define M41T00_SQW_128HZ (8<<4) /* 128 Hz */ +#define M41T00_SQW_64HZ (9<<4) /* 64 Hz */ +#define M41T00_SQW_32HZ (10<<4) /* 32 Hz */ +#define M41T00_SQW_16HZ (11<<4) /* 16 Hz */ +#define M41T00_SQW_8HZ (12<<4) /* 8 Hz */ +#define M41T00_SQW_4HZ (13<<4) /* 4 Hz */ +#define M41T00_SQW_2HZ (14<<4) /* 2 Hz */ +#define M41T00_SQW_1HZ (15<<4) /* 1 Hz */ + +extern ulong m41t00_get_rtc_time(void); +extern int m41t00_set_rtc_time(ulong nowtime); + +#endif /* _M41T00_H */ -- cgit v1.2.3 From 5c7ae65899a4c5b05b6277f856018d1eeeb98907 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 25 Apr 2006 14:18:16 +0200 Subject: [PATCH] I2C: i2c-nforce2: Add support for the nForce4 MCP51 and MCP55 Add support for the new nForce4 MCP51 (also known as nForce 410 or 430) and nForce4 MCP55 to the i2c-nforce2 driver. Some code changes were required because the base I/O address registers have changed in these versions. Standard BARs are now being used, while the original nForce2 chips used non-standard ones. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- include/linux/pci_ids.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 489af9d3ce1f..d33436097e1d 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -1130,9 +1130,11 @@ #define PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL 0x0258 #define PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL 0x0259 #define PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL 0x025B +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SMBUS 0x0264 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE 0x0265 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA 0x0266 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2 0x0267 +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SMBUS 0x0368 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE 0x036E #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA 0x037E #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2 0x037F -- cgit v1.2.3 From 18f98b1e3147afdb51e545cc6ff2b016c7d088a7 Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Sun, 4 Jun 2006 20:01:08 +0200 Subject: [PATCH] i2c: New bus driver for the OpenCores I2C controller The following patch adds support for the OpenCores I2C controller IP core (See http://www.opencores.org/projects.cgi/web/i2c/overview). Signed-off-by: Peter Korsgaard Signed-off-by: Andrew Morton Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- include/linux/i2c-ocores.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 include/linux/i2c-ocores.h (limited to 'include/linux') diff --git a/include/linux/i2c-ocores.h b/include/linux/i2c-ocores.h new file mode 100644 index 000000000000..8ed591b0887e --- /dev/null +++ b/include/linux/i2c-ocores.h @@ -0,0 +1,19 @@ +/* + * i2c-ocores.h - definitions for the i2c-ocores interface + * + * Peter Korsgaard + * + * This file is licensed under the terms of the GNU General Public License + * version 2. This program is licensed "as is" without any warranty of any + * kind, whether express or implied. + */ + +#ifndef _LINUX_I2C_OCORES_H +#define _LINUX_I2C_OCORES_H + +struct ocores_i2c_platform_data { + u32 regstep; /* distance between registers */ + u32 clock_khz; /* input clock in kHz */ +}; + +#endif /* _LINUX_I2C_OCORES_H */ -- cgit v1.2.3 From 46f5ed753fac512f73069bd07455555b41a8a06e Mon Sep 17 00:00:00 2001 From: Krzysztof Halasa Date: Mon, 12 Jun 2006 21:42:20 +0200 Subject: [PATCH] i2c: Mark block write buffers as const The attached patch marks i2c_smbus_write_block_data() and i2c_smbus_write_i2c_block_data() buffers as const. Signed-off-by: Krzysztof Halasa Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman --- include/linux/i2c.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 0510430e00db..526ddc8eecfb 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h @@ -97,13 +97,13 @@ extern s32 i2c_smbus_write_word_data(struct i2c_client * client, u8 command, u16 value); extern s32 i2c_smbus_write_block_data(struct i2c_client * client, u8 command, u8 length, - u8 *values); + const u8 *values); /* Returns the number of read bytes */ extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client, u8 command, u8 *values); extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client * client, u8 command, u8 length, - u8 *values); + const u8 *values); /* * A driver is capable of handling one or more physical devices present on -- cgit v1.2.3 From b6043fcab4b2b06b9fcde4c783ab253cdc2c1129 Mon Sep 17 00:00:00 2001 From: Evgeniy Polyakov Date: Thu, 23 Mar 2006 19:11:58 +0300 Subject: [PATCH] w1: Move w1-connector definitions into linux/include/connector.h Signed-off-by: Evgeniy Polyakov Signed-off-by: Greg Kroah-Hartman --- include/linux/connector.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/connector.h b/include/linux/connector.h index ad1a22c1c42e..4c02119c6ab9 100644 --- a/include/linux/connector.h +++ b/include/linux/connector.h @@ -34,8 +34,11 @@ #define CN_VAL_PROC 0x1 #define CN_IDX_CIFS 0x2 #define CN_VAL_CIFS 0x1 +#define CN_W1_IDX 0x3 /* w1 communication */ +#define CN_W1_VAL 0x1 -#define CN_NETLINK_USERS 1 + +#define CN_NETLINK_USERS 4 /* * Maximum connector's message size. -- cgit v1.2.3 From bb5427b5466782ba0bbf56a4ed752e08b65a5d08 Mon Sep 17 00:00:00 2001 From: Evgeniy Polyakov Date: Thu, 23 Mar 2006 19:11:58 +0300 Subject: [PATCH] w1: netlink: Mark netlink group 1 as unused. netlink_w1 was moved to connector. Signed-off-by: Evgeniy Polyakov Signed-off-by: Greg Kroah-Hartman --- include/linux/netlink.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/netlink.h b/include/linux/netlink.h index 87b8a5703ebc..855b44668caa 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h @@ -5,7 +5,7 @@ #include #define NETLINK_ROUTE 0 /* Routing/device hook */ -#define NETLINK_W1 1 /* 1-wire subsystem */ +#define NETLINK_UNUSED 1 /* Unused number */ #define NETLINK_USERSOCK 2 /* Reserved for user mode socket protocols */ #define NETLINK_FIREWALL 3 /* Firewalling hook */ #define NETLINK_INET_DIAG 4 /* INET socket monitoring */ -- cgit v1.2.3 From d720024e94de4e8b7f10ee83c532926f3ad5d708 Mon Sep 17 00:00:00 2001 From: Michael LeMay Date: Thu, 22 Jun 2006 14:47:17 -0700 Subject: [PATCH] selinux: add hooks for key subsystem Introduce SELinux hooks to support the access key retention subsystem within the kernel. Incorporate new flask headers from a modified version of the SELinux reference policy, with support for the new security class representing retained keys. Extend the "key_alloc" security hook with a task parameter representing the intended ownership context for the key being allocated. Attach security information to root's default keyrings within the SELinux initialization routine. Has passed David's testsuite. Signed-off-by: Michael LeMay Signed-off-by: David Howells Signed-off-by: James Morris Acked-by: Chris Wright Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/key.h | 18 +++++++++++++----- include/linux/security.h | 10 ++++++---- 2 files changed, 19 insertions(+), 9 deletions(-) (limited to 'include/linux') diff --git a/include/linux/key.h b/include/linux/key.h index cbf464ad9589..8c275d12ef63 100644 --- a/include/linux/key.h +++ b/include/linux/key.h @@ -241,8 +241,9 @@ extern void unregister_key_type(struct key_type *ktype); extern struct key *key_alloc(struct key_type *type, const char *desc, - uid_t uid, gid_t gid, key_perm_t perm, - int not_in_quota); + uid_t uid, gid_t gid, + struct task_struct *ctx, + key_perm_t perm, int not_in_quota); extern int key_payload_reserve(struct key *key, size_t datalen); extern int key_instantiate_and_link(struct key *key, const void *data, @@ -292,7 +293,9 @@ extern int key_unlink(struct key *keyring, struct key *key); extern struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid, - int not_in_quota, struct key *dest); + struct task_struct *ctx, + int not_in_quota, + struct key *dest); extern int keyring_clear(struct key *keyring); @@ -313,7 +316,8 @@ extern void keyring_replace_payload(struct key *key, void *replacement); * the userspace interface */ extern struct key root_user_keyring, root_session_keyring; -extern int alloc_uid_keyring(struct user_struct *user); +extern int alloc_uid_keyring(struct user_struct *user, + struct task_struct *ctx); extern void switch_uid_keyring(struct user_struct *new_user); extern int copy_keys(unsigned long clone_flags, struct task_struct *tsk); extern int copy_thread_group_keys(struct task_struct *tsk); @@ -342,7 +346,7 @@ extern void key_init(void); #define make_key_ref(k) ({ NULL; }) #define key_ref_to_ptr(k) ({ NULL; }) #define is_key_possessed(k) 0 -#define alloc_uid_keyring(u) 0 +#define alloc_uid_keyring(u,c) 0 #define switch_uid_keyring(u) do { } while(0) #define __install_session_keyring(t, k) ({ NULL; }) #define copy_keys(f,t) 0 @@ -355,6 +359,10 @@ extern void key_init(void); #define key_fsgid_changed(t) do { } while(0) #define key_init() do { } while(0) +/* Initial keyrings */ +extern struct key root_user_keyring; +extern struct key root_session_keyring; + #endif /* CONFIG_KEYS */ #endif /* __KERNEL__ */ #endif /* _LINUX_KEY_H */ diff --git a/include/linux/security.h b/include/linux/security.h index 4dfb1b84a9b3..47722d355532 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -1313,7 +1313,7 @@ struct security_operations { /* key management security hooks */ #ifdef CONFIG_KEYS - int (*key_alloc)(struct key *key); + int (*key_alloc)(struct key *key, struct task_struct *tsk); void (*key_free)(struct key *key); int (*key_permission)(key_ref_t key_ref, struct task_struct *context, @@ -3008,9 +3008,10 @@ static inline int security_xfrm_policy_lookup(struct xfrm_policy *xp, u32 sk_sid #ifdef CONFIG_KEYS #ifdef CONFIG_SECURITY -static inline int security_key_alloc(struct key *key) +static inline int security_key_alloc(struct key *key, + struct task_struct *tsk) { - return security_ops->key_alloc(key); + return security_ops->key_alloc(key, tsk); } static inline void security_key_free(struct key *key) @@ -3027,7 +3028,8 @@ static inline int security_key_permission(key_ref_t key_ref, #else -static inline int security_key_alloc(struct key *key) +static inline int security_key_alloc(struct key *key, + struct task_struct *tsk) { return 0; } -- cgit v1.2.3 From 04c567d9313e4927b9835361d8ac0318ce65af6b Mon Sep 17 00:00:00 2001 From: David Howells Date: Thu, 22 Jun 2006 14:47:18 -0700 Subject: [PATCH] Keys: Fix race between two instantiators of a key Add a revocation notification method to the key type and calls it whilst the key's semaphore is still write-locked after setting the revocation flag. The patch then uses this to maintain a reference on the task_struct of the process that calls request_key() for as long as the authorisation key remains unrevoked. This fixes a potential race between two processes both of which have assumed the authority to instantiate a key (one may have forked the other for example). The problem is that there's no locking around the check for revocation of the auth key and the use of the task_struct it points to, nor does the auth key keep a reference on the task_struct. Access to the "context" pointer in the auth key must thenceforth be done with the auth key semaphore held. The revocation method is called with the target key semaphore held write-locked and the search of the context process's keyrings is done with the auth key semaphore read-locked. The check for the revocation state of the auth key just prior to searching it is done after the auth key is read-locked for the search. This ensures that the auth key can't be revoked between the check and the search. The revocation notification method is added so that the context task_struct can be released as soon as instantiation happens rather than waiting for the auth key to be destroyed, thus avoiding the unnecessary pinning of the requesting process. Signed-off-by: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/key.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/key.h b/include/linux/key.h index 8c275d12ef63..e81ebf910d0b 100644 --- a/include/linux/key.h +++ b/include/linux/key.h @@ -205,6 +205,11 @@ struct key_type { /* match a key against a description */ int (*match)(const struct key *key, const void *desc); + /* clear some of the data from a key on revokation (optional) + * - the key's semaphore will be write-locked by the caller + */ + void (*revoke)(struct key *key); + /* clear the data from a key (optional) */ void (*destroy)(struct key *key); -- cgit v1.2.3 From 0e5b3781591cc954037c08ef78edf7f1192d38c5 Mon Sep 17 00:00:00 2001 From: Brice Goglin Date: Thu, 22 Jun 2006 14:47:20 -0700 Subject: [PATCH] PCI: Add PCI_CAP_ID_VNDR Add the vendor-specific extended capability PCI_CAP_ID_VNDR. It is required by the Myri-10G Ethernet driver. Signed-off-by: Brice Goglin Signed-off-by: Greg Kroah-Hartman Cc: Jeff Garzik Cc: "David S. Miller" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/pci_regs.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h index d27a78b71297..6bce4a240364 100644 --- a/include/linux/pci_regs.h +++ b/include/linux/pci_regs.h @@ -197,6 +197,7 @@ #define PCI_CAP_ID_CHSWP 0x06 /* CompactPCI HotSwap */ #define PCI_CAP_ID_PCIX 0x07 /* PCI-X */ #define PCI_CAP_ID_HT_IRQCONF 0x08 /* HyperTransport IRQ Configuration */ +#define PCI_CAP_ID_VNDR 0x09 /* Vendor specific capability */ #define PCI_CAP_ID_SHPC 0x0C /* PCI Standard Hot-Plug Controller */ #define PCI_CAP_ID_EXP 0x10 /* PCI Express */ #define PCI_CAP_ID_MSIX 0x11 /* MSI-X */ -- cgit v1.2.3 From c89681ed7d0e4a61d35bdc12c06c6733b718b2cb Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Thu, 22 Jun 2006 14:47:22 -0700 Subject: [PATCH] remove steal_locks() This patch removes the steal_locks() function. steal_locks() doesn't work correctly with any filesystem that does it's own lock management, including NFS, CIFS, etc. In addition it has weird semantics on local filesystems in case tasks sharing file-descriptor tables are doing POSIX locking operations in parallel to execve(). The steal_locks() function has an effect on applications doing: clone(CLONE_FILES) /* in child */ lock execve lock POSIX locks acquired before execve (by "child", "parent" or any further task sharing files_struct) will after the execve be owned exclusively by "child". According to Chris Wright some LSB/LTP kind of suite triggers without the stealing behavior, but there's no known real-world application that would also fail. Apps using NPTL are not affected, since all other threads are killed before execve. Apps using LinuxThreads are only affected if they - have multiple threads during exec (LinuxThreads doesn't kill other threads, the app may do it with pthread_kill_other_threads_np()) - rely on POSIX locks being inherited across exec Both conditions are documented, but not their interaction. Apps using clone() natively are affected if they - use clone(CLONE_FILES) - rely on POSIX locks being inherited across exec The above scenarios are unlikely, but possible. If the patch is vetoed, there's a plan B, that involves mostly keeping the weird stealing semantics, but changing the way lock ownership is handled so that network and local filesystems work consistently. That would add more complexity though, so this solution seems to be preferred by most people. Signed-off-by: Miklos Szeredi Cc: Trond Myklebust Cc: Matthew Wilcox Cc: Chris Wright Cc: Christoph Hellwig Cc: Steven French Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/fs.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/fs.h b/include/linux/fs.h index ecc8c2c3d8ca..73c7d6f04b31 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -782,7 +782,6 @@ extern int setlease(struct file *, long, struct file_lock **); extern int lease_modify(struct file_lock **, int); extern int lock_may_read(struct inode *, loff_t start, unsigned long count); extern int lock_may_write(struct inode *, loff_t start, unsigned long count); -extern void steal_locks(fl_owner_t from); struct fasync_struct { int magic; -- cgit v1.2.3 From 0feae5c47aabdde59cbbec32d150e17102de37f0 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 22 Jun 2006 14:47:28 -0700 Subject: [PATCH] Fix dcache race during umount The race is that the shrink_dcache_memory shrinker could get called while a filesystem is being unmounted, and could try to prune a dentry belonging to that filesystem. If it does, then it will call in to iput on the inode while the dentry is no longer able to be found by the umounting process. If iput takes a while, generic_shutdown_super could get all the way though shrink_dcache_parent and shrink_dcache_anon and invalidate_inodes without ever waiting on this particular inode. Eventually the superblock gets freed anyway and if the iput tried to touch it (which some filesystems certainly do), it will lose. The promised "Self-destruct in 5 seconds" doesn't lead to a nice day. The race is closed by holding s_umount while calling prune_one_dentry on someone else's dentry. As a down_read_trylock is used, shrink_dcache_memory will no longer try to prune the dentry of a filesystem that is being unmounted, and unmount will not be able to start until any such active prune_one_dentry completes. This requires that prune_dcache *knows* which filesystem (if any) it is doing the prune on behalf of so that it can be careful of other filesystems. shrink_dcache_memory isn't called it on behalf of any filesystem, and so is careful of everything. shrink_dcache_anon is now passed a super_block rather than the s_anon list out of the superblock, so it can get the s_anon list itself, and can pass the superblock down to prune_dcache. If prune_dcache finds a dentry that it cannot free, it leaves it where it is (at the tail of the list) and exits, on the assumption that some other thread will be removing that dentry soon. To try to make sure that some work gets done, a limited number of dnetries which are untouchable are skipped over while choosing the dentry to work on. I believe this race was first found by Kirill Korotaev. Cc: Jan Blunck Acked-by: Kirill Korotaev Cc: Olaf Hering Acked-by: Balbir Singh Signed-off-by: Neil Brown Signed-off-by: Balbir Singh Acked-by: David Howells Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/dcache.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 836325ee0931..46d0e079735d 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -217,7 +217,7 @@ extern struct dentry * d_alloc_anon(struct inode *); extern struct dentry * d_splice_alias(struct inode *, struct dentry *); extern void shrink_dcache_sb(struct super_block *); extern void shrink_dcache_parent(struct dentry *); -extern void shrink_dcache_anon(struct hlist_head *); +extern void shrink_dcache_anon(struct super_block *); extern int d_invalidate(struct dentry *); /* only used at mount-time */ -- cgit v1.2.3 From 4f3865fb57a04db7cca068fed1c15badc064a302 Mon Sep 17 00:00:00 2001 From: Richard Purdie Date: Thu, 22 Jun 2006 14:47:34 -0700 Subject: [PATCH] zlib_inflate: Upgrade library code to a recent version Upgrade the zlib_inflate implementation in the kernel from a patched version 1.1.3/4 to a patched 1.2.3. The code in the kernel is about seven years old and I noticed that the external zlib library's inflate performance was significantly faster (~50%) than the code in the kernel on ARM (and faster again on x86_32). For comparison the newer deflate code is 20% slower on ARM and 50% slower on x86_32 but gives an approx 1% compression ratio improvement. I don't consider this to be an improvement for kernel use so have no plans to change the zlib_deflate code. Various changes have been made to the zlib code in the kernel, the most significant being the extra functions/flush option used by ppp_deflate. This update reimplements the features PPP needs to ensure it continues to work. This code has been tested on ARM under both JFFS2 (with zlib compression enabled) and ppp_deflate and on x86_32. JFFS2 sees an approx. 10% real world file read speed improvement. This patch also removes ZLIB_VERSION as it no longer has a correct value. We don't need version checks anyway as the kernel's module handling will take care of that for us. This removal is also more in keeping with the zlib author's wishes (http://www.zlib.net/zlib_faq.html#faq24) and I've added something to the zlib.h header to note its a modified version. Signed-off-by: Richard Purdie Acked-by: Joern Engel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/zconf.h | 12 +++ include/linux/zlib.h | 209 +++++++++++++++++++++++++++++++------------------- include/linux/zutil.h | 12 --- 3 files changed, 141 insertions(+), 92 deletions(-) (limited to 'include/linux') diff --git a/include/linux/zconf.h b/include/linux/zconf.h index f1cfd66b9554..0beb75e38caa 100644 --- a/include/linux/zconf.h +++ b/include/linux/zconf.h @@ -33,6 +33,18 @@ */ #ifndef MAX_WBITS # define MAX_WBITS 15 /* 32K LZ77 window */ +#endif + +/* default windowBits for decompression. MAX_WBITS is for compression only */ +#ifndef DEF_WBITS +# define DEF_WBITS MAX_WBITS +#endif + +/* default memLevel */ +#if MAX_MEM_LEVEL >= 8 +# define DEF_MEM_LEVEL 8 +#else +# define DEF_MEM_LEVEL MAX_MEM_LEVEL #endif /* Type declarations */ diff --git a/include/linux/zlib.h b/include/linux/zlib.h index 4fa32f0d4df8..9e3192a7dc6f 100644 --- a/include/linux/zlib.h +++ b/include/linux/zlib.h @@ -1,7 +1,6 @@ /* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.1.3, July 9th, 1998 - Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler + Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -24,7 +23,7 @@ The data format used by the zlib library is described by RFCs (Request for - Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt + Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). */ @@ -33,7 +32,22 @@ #include -#define ZLIB_VERSION "1.1.3" +/* zlib deflate based on ZLIB_VERSION "1.1.3" */ +/* zlib inflate based on ZLIB_VERSION "1.2.3" */ + +/* + This is a modified version of zlib for use inside the Linux kernel. + The main changes are to perform all memory allocation in advance. + + Inflation Changes: + * Z_PACKET_FLUSH is added and used by ppp_deflate. Before returning + this checks there is no more input data available and the next data + is a STORED block. It also resets the mode to be read for the next + data, all as per PPP requirements. + * Addition of zlib_inflateIncomp which copies incompressible data into + the history window and adjusts the accoutning without calling + zlib_inflate itself to inflate the data. +*/ /* The 'zlib' compression library provides in-memory compression and @@ -48,9 +62,18 @@ application must provide more input and/or consume the output (providing more output space) before each call. + The compressed data format used by default by the in-memory functions is + the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped + around a deflate stream, which is itself documented in RFC 1951. + The library also supports reading and writing files in gzip (.gz) format with an interface similar to that of stdio. + The zlib format was designed to be compact and fast for use in memory + and on communications channels. The gzip format was designed for single- + file compression on file systems, has a larger header than zlib to maintain + directory information, and uses a different, slower check method than zlib. + The library does not install any signal handler. The decoder checks the consistency of the compressed data, so the library should never crash even in case of corrupted input. @@ -119,7 +142,8 @@ typedef z_stream *z_streamp; #define Z_SYNC_FLUSH 3 #define Z_FULL_FLUSH 4 #define Z_FINISH 5 -/* Allowed flush values; see deflate() below for details */ +#define Z_BLOCK 6 /* Only for inflate at present */ +/* Allowed flush values; see deflate() and inflate() below for details */ #define Z_OK 0 #define Z_STREAM_END 1 @@ -155,13 +179,6 @@ typedef z_stream *z_streamp; /* basic functions */ -extern const char * zlib_zlibVersion (void); -/* The application can compare zlibVersion and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is - not compatible with the zlib.h header file used by the application. - This check is automatically made by deflateInit and inflateInit. - */ - extern int zlib_deflate_workspacesize (void); /* Returns the number of bytes that needs to be allocated for a per- @@ -315,9 +332,9 @@ extern int zlib_inflateInit (z_streamp strm); extern int zlib_inflate (z_streamp strm, int flush); /* inflate decompresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may some - introduce some output latency (reading input without producing any output) - except when forced to flush. + buffer becomes empty or the output buffer becomes full. It may introduce + some output latency (reading input without producing any output) except when + forced to flush. The detailed semantics are as follows. inflate performs one or both of the following actions: @@ -341,11 +358,26 @@ extern int zlib_inflate (z_streamp strm, int flush); must be called again after making room in the output buffer because there might be more output pending. - If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much - output as possible to the output buffer. The flushing behavior of inflate is - not specified for values of the flush parameter other than Z_SYNC_FLUSH - and Z_FINISH, but the current implementation actually flushes as much output - as possible anyway. + The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, + Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much + output as possible to the output buffer. Z_BLOCK requests that inflate() stop + if and when it gets to the next deflate block boundary. When decoding the + zlib or gzip format, this will cause inflate() to return immediately after + the header and before the first block. When doing a raw inflate, inflate() + will go ahead and process the first block, and will return when it gets to + the end of that block, or when it runs out of data. + + The Z_BLOCK option assists in appending to or combining deflate streams. + Also to assist in this, on return inflate() will set strm->data_type to the + number of unused bits in the last byte taken from strm->next_in, plus 64 + if inflate() is currently decoding the last block in the deflate stream, + plus 128 if inflate() returned immediately after decoding an end-of-block + code or decoding the complete header up to just before the first byte of the + deflate stream. The end-of-block will not be indicated until all of the + uncompressed data from that block has been written to strm->next_out. The + number of unused bits may in general be greater than seven, except when + bit 7 of data_type is set, in which case the number of unused bits will be + less than eight. inflate() should normally be called until it returns Z_STREAM_END or an error. However if all decompression is to be performed in a single step @@ -355,29 +387,44 @@ extern int zlib_inflate (z_streamp strm, int flush); uncompressed data. (The size of the uncompressed data may have been saved by the compressor for this purpose.) The next operation on this stream must be inflateEnd to deallocate the decompression state. The use of Z_FINISH - is never required, but can be used to inform inflate that a faster routine + is never required, but can be used to inform inflate that a faster approach may be used for the single inflate() call. - If a preset dictionary is needed at this point (see inflateSetDictionary - below), inflate sets strm-adler to the adler32 checksum of the - dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise - it sets strm->adler to the adler32 checksum of all output produced - so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or - an error code as described below. At the end of the stream, inflate() - checks that its computed adler32 checksum is equal to that saved by the - compressor and returns Z_STREAM_END only if the checksum is correct. + In this implementation, inflate() always flushes as much output as + possible to the output buffer, and always uses the faster approach on the + first call. So the only effect of the flush parameter in this implementation + is on the return value of inflate(), as noted below, or when it returns early + because Z_BLOCK is used. + + If a preset dictionary is needed after this call (see inflateSetDictionary + below), inflate sets strm->adler to the adler32 checksum of the dictionary + chosen by the compressor and returns Z_NEED_DICT; otherwise it sets + strm->adler to the adler32 checksum of all output produced so far (that is, + total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described + below. At the end of the stream, inflate() checks that its computed adler32 + checksum is equal to that saved by the compressor and returns Z_STREAM_END + only if the checksum is correct. + + inflate() will decompress and check either zlib-wrapped or gzip-wrapped + deflate data. The header type is detected automatically. Any information + contained in the gzip header is not retained, so applications that need that + information should instead use raw inflate, see inflateInit2() below, or + inflateBack() and perform their own processing of the gzip header and + trailer. inflate() returns Z_OK if some progress has been made (more input processed or more output produced), Z_STREAM_END if the end of the compressed data has been reached and all uncompressed output has been produced, Z_NEED_DICT if a preset dictionary is needed at this point, Z_DATA_ERROR if the input data was - corrupted (input stream not conforming to the zlib format or incorrect - adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent - (for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if no progress is possible or if there was not - enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR - case, the application may then call inflateSync to look for a good - compression block. + corrupted (input stream not conforming to the zlib format or incorrect check + value), Z_STREAM_ERROR if the stream structure was inconsistent (for example + if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory, + Z_BUF_ERROR if no progress is possible or if there was not enough room in the + output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and + inflate() can be called again with more input and more output space to + continue decompressing. If Z_DATA_ERROR is returned, the application may then + call inflateSync() to look for a good compression block if a partial recovery + of the data is desired. */ @@ -547,16 +594,36 @@ extern int inflateInit2 (z_streamp strm, int windowBits); The windowBits parameter is the base two logarithm of the maximum window size (the size of the history buffer). It should be in the range 8..15 for this version of the library. The default value is 15 if inflateInit is used - instead. If a compressed stream with a larger window size is given as - input, inflate() will return with the error code Z_DATA_ERROR instead of - trying to allocate a larger window. - - inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative - memLevel). msg is set to null if there is no error message. inflateInit2 - does not perform any decompression apart from reading the zlib header if - present: this will be done by inflate(). (So next_in and avail_in may be - modified, but next_out and avail_out are unchanged.) + instead. windowBits must be greater than or equal to the windowBits value + provided to deflateInit2() while compressing, or it must be equal to 15 if + deflateInit2() was not used. If a compressed stream with a larger window + size is given as input, inflate() will return with the error code + Z_DATA_ERROR instead of trying to allocate a larger window. + + windowBits can also be -8..-15 for raw inflate. In this case, -windowBits + determines the window size. inflate() will then process raw deflate data, + not looking for a zlib or gzip header, not generating a check value, and not + looking for any check values for comparison at the end of the stream. This + is for use with other formats that use the deflate compressed data format + such as zip. Those formats provide their own check values. If a custom + format is developed using the raw deflate format for compressed data, it is + recommended that a check value such as an adler32 or a crc32 be applied to + the uncompressed data as is done in the zlib, gzip, and zip formats. For + most applications, the zlib format should be used as is. Note that comments + above on the use in deflateInit2() applies to the magnitude of windowBits. + + windowBits can also be greater than 15 for optional gzip decoding. Add + 32 to windowBits to enable zlib and gzip decoding with automatic header + detection, or add 16 to decode only the gzip format (the zlib format will + return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is + a crc32 instead of an adler32. + + inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough + memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg + is set to null if there is no error message. inflateInit2 does not perform + any decompression apart from reading the zlib header if present: this will + be done by inflate(). (So next_in and avail_in may be modified, but next_out + and avail_out are unchanged.) */ extern int zlib_inflateSetDictionary (z_streamp strm, @@ -564,16 +631,19 @@ extern int zlib_inflateSetDictionary (z_streamp strm, uInt dictLength); /* Initializes the decompression dictionary from the given uncompressed byte - sequence. This function must be called immediately after a call of inflate - if this call returned Z_NEED_DICT. The dictionary chosen by the compressor - can be determined from the Adler32 value returned by this call of - inflate. The compressor and decompressor must use exactly the same - dictionary (see deflateSetDictionary). + sequence. This function must be called immediately after a call of inflate, + if that call returned Z_NEED_DICT. The dictionary chosen by the compressor + can be determined from the adler32 value returned by that call of inflate. + The compressor and decompressor must use exactly the same dictionary (see + deflateSetDictionary). For raw inflate, this function can be called + immediately after inflateInit2() or inflateReset() and before any call of + inflate() to set the dictionary. The application must insure that the + dictionary that was used for compression is provided. inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a parameter is invalid (such as NULL dictionary) or the stream state is inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the - expected one (incorrect Adler32 value). inflateSetDictionary does not + expected one (incorrect adler32 value). inflateSetDictionary does not perform any decompression: this will be done by subsequent calls of inflate(). */ @@ -614,40 +684,19 @@ extern int zlib_inflateIncomp (z_stream *strm); containing the data at next_in (except that the data is not output). */ - /* various hacks, don't look :) */ - -/* deflateInit and inflateInit are macros to allow checking the zlib version - * and the compiler's view of z_stream: - */ -extern int zlib_deflateInit_ (z_streamp strm, int level, - const char *version, int stream_size); -extern int zlib_inflateInit_ (z_streamp strm, - const char *version, int stream_size); -extern int zlib_deflateInit2_ (z_streamp strm, int level, int method, - int windowBits, int memLevel, - int strategy, const char *version, - int stream_size); -extern int zlib_inflateInit2_ (z_streamp strm, int windowBits, - const char *version, int stream_size); #define zlib_deflateInit(strm, level) \ - zlib_deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) + zlib_deflateInit2((strm), (level), Z_DEFLATED, MAX_WBITS, \ + DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY) #define zlib_inflateInit(strm) \ - zlib_inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) -#define zlib_deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - zlib_deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, sizeof(z_stream)) -#define zlib_inflateInit2(strm, windowBits) \ - zlib_inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) + zlib_inflateInit2((strm), DEF_WBITS) +extern int zlib_deflateInit2(z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy); +extern int zlib_inflateInit2(z_streamp strm, int windowBits); #if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL) struct internal_state {int dummy;}; /* hack for buggy compilers */ #endif -extern const char * zlib_zError (int err); -#if 0 -extern int zlib_inflateSyncPoint (z_streamp z); -#endif -extern const uLong * zlib_get_crc_table (void); - #endif /* _ZLIB_H */ diff --git a/include/linux/zutil.h b/include/linux/zutil.h index ee0c59cf2136..6adfa9a6ffe9 100644 --- a/include/linux/zutil.h +++ b/include/linux/zutil.h @@ -23,18 +23,6 @@ typedef unsigned long ulg; /* common constants */ -#ifndef DEF_WBITS -# define DEF_WBITS MAX_WBITS -#endif -/* default windowBits for decompression. MAX_WBITS is for compression only */ - -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif -/* default memLevel */ - #define STORED_BLOCK 0 #define STATIC_TREES 1 #define DYN_TREES 2 -- cgit v1.2.3 From 4a31e348e3ecaf54c50240109ac4574b180f8840 Mon Sep 17 00:00:00 2001 From: Krzysztof Halasa Date: Thu, 22 Jun 2006 22:20:19 +0200 Subject: [PATCH] WAN: register_hdlc_device() doesn't need dev_alloc_name() David Boggs noticed that register_hdlc_device() no longer needs to call dev_alloc_name() as it's called by register_netdev(). register_hdlc_device() is currently equivalent to register_netdev(). hdlc_setup() is now EXPORTed as per David's request. Signed-off-by: Krzysztof Halasa Signed-off-by: Jeff Garzik --- include/linux/hdlc.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/hdlc.h b/include/linux/hdlc.h index df695e9ae327..4513f9e40937 100644 --- a/include/linux/hdlc.h +++ b/include/linux/hdlc.h @@ -188,7 +188,7 @@ int hdlc_x25_ioctl(struct net_device *dev, struct ifreq *ifr); int hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); /* Must be used by hardware driver on module startup/exit */ -int register_hdlc_device(struct net_device *dev); +#define register_hdlc_device(dev) register_netdev(dev) void unregister_hdlc_device(struct net_device *dev); struct net_device *alloc_hdlcdev(void *priv); -- cgit v1.2.3 From 47005f255ed126a4b48a1a2f63164fb1d83bcb0a Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 19 Jun 2006 18:27:23 +0900 Subject: [PATCH] libata: implement per-dev EH action mask eh_info->dev_action[] Currently, the only per-dev EH action is REVALIDATE. EH used to exploit ehi->dev to do selective revalidation on a ATA bus. However, this is a bit hacky and makes it impossible to request selective revalidation from outside of EH or add another per-dev EH action. This patch adds per-dev EH action mask eh_info->dev_action[] and update EH to use this field for REVALIDATE. Note that per-dev actions can still be specified at port-level and it has the same effect of specifying the action for all devices on the port. Signed-off-by: Tejun Heo Signed-off-by: Jeff Garzik --- include/linux/libata.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index f03b8664af11..6b3c3af2c75f 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -249,6 +249,7 @@ enum { ATA_EH_HARDRESET = (1 << 2), ATA_EH_RESET_MASK = ATA_EH_SOFTRESET | ATA_EH_HARDRESET, + ATA_EH_PERDEV_MASK = ATA_EH_REVALIDATE, /* ata_eh_info->flags */ ATA_EHI_HOTPLUGGED = (1 << 0), /* could have been hotplugged */ @@ -462,6 +463,7 @@ struct ata_eh_info { u32 serror; /* SError from LLDD */ unsigned int err_mask; /* port-wide err_mask */ unsigned int action; /* ATA_EH_* action mask */ + unsigned int dev_action[ATA_MAX_DEVICES]; /* dev EH action */ unsigned int flags; /* ATA_EHI_* flags */ unsigned long hotplug_timestamp; -- cgit v1.2.3 From ba6a13083c1b720a47c05bee7bedbb6ef06c4611 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Thu, 22 Jun 2006 23:46:10 -0400 Subject: [libata] Add host lock to struct ata_port Prepare for changes required to support SATA devices attached to SAS HBAs. For these devices we don't want to use host_set at all, since libata will not be the owner of struct scsi_host. Signed-off-by: Brian King (with slight merge modifications made by...) Signed-off-by: Jeff Garzik --- include/linux/libata.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/libata.h b/include/linux/libata.h index 6b3c3af2c75f..20b1cf527c60 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -483,6 +483,7 @@ struct ata_eh_context { struct ata_port { struct Scsi_Host *host; /* our co-allocated scsi host */ const struct ata_port_operations *ops; + spinlock_t *lock; unsigned long flags; /* ATA_FLAG_xxx */ unsigned int id; /* unique id req'd by scsi midlyr */ unsigned int port_no; /* unique port #; from zero */ -- cgit v1.2.3 From 5b057c6b1a25d57edf2b4d1e956e50936480a9ff Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Fri, 23 Jun 2006 02:06:41 -0700 Subject: [NET]: Avoid allocating skb in skb_pad First of all it is unnecessary to allocate a new skb in skb_pad since the existing one is not shared. More importantly, our hard_start_xmit interface does not allow a new skb to be allocated since that breaks requeueing. This patch uses pskb_expand_head to expand the existing skb and linearize it if needed. Actually, someone should sift through every instance of skb_pad on a non-linear skb as they do not fit the reasons why this was originally created. Incidentally, this fixes a minor bug when the skb is cloned (tcpdump, TCP, etc.). As it is skb_pad will simply write over a cloned skb. Because of the position of the write it is unlikely to cause problems but still it's best if we don't do it. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- include/linux/skbuff.h | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 66f8819f9568..f8c7eb79a27f 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -345,7 +345,7 @@ extern struct sk_buff *skb_realloc_headroom(struct sk_buff *skb, extern struct sk_buff *skb_copy_expand(const struct sk_buff *skb, int newheadroom, int newtailroom, gfp_t priority); -extern struct sk_buff * skb_pad(struct sk_buff *skb, int pad); +extern int skb_pad(struct sk_buff *skb, int pad); #define dev_kfree_skb(a) kfree_skb(a) extern void skb_over_panic(struct sk_buff *skb, int len, void *here); @@ -1122,16 +1122,15 @@ static inline int skb_cow(struct sk_buff *skb, unsigned int headroom) * * Pads up a buffer to ensure the trailing bytes exist and are * blanked. If the buffer already contains sufficient data it - * is untouched. Returns the buffer, which may be a replacement - * for the original, or NULL for out of memory - in which case - * the original buffer is still freed. + * is untouched. Otherwise it is extended. Returns zero on + * success. The skb is freed on error. */ -static inline struct sk_buff *skb_padto(struct sk_buff *skb, unsigned int len) +static inline int skb_padto(struct sk_buff *skb, unsigned int len) { unsigned int size = skb->len; if (likely(size >= len)) - return skb; + return 0; return skb_pad(skb, len-size); } -- cgit v1.2.3 From 7967168cefdbc63bf332d6b1548eca7cd65ebbcc Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 22 Jun 2006 02:40:14 -0700 Subject: [NET]: Merge TSO/UFO fields in sk_buff Having separate fields in sk_buff for TSO/UFO (tso_size/ufo_size) is not going to scale if we add any more segmentation methods (e.g., DCCP). So let's merge them. They were used to tell the protocol of a packet. This function has been subsumed by the new gso_type field. This is essentially a set of netdev feature bits (shifted by 16 bits) that are required to process a specific skb. As such it's easy to tell whether a given device can process a GSO skb: you just have to and the gso_type field and the netdev's features field. I've made gso_type a conjunction. The idea is that you have a base type (e.g., SKB_GSO_TCPV4) that can be modified further to support new features. For example, if we add a hardware TSO type that supports ECN, they would declare NETIF_F_TSO | NETIF_F_TSO_ECN. All TSO packets with CWR set would have a gso_type of SKB_GSO_TCPV4 | SKB_GSO_TCPV4_ECN while all other TSO packets would be SKB_GSO_TCPV4. This means that only the CWR packets need to be emulated in software. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- include/linux/netdevice.h | 14 ++++++++++++-- include/linux/skbuff.h | 12 +++++++++--- 2 files changed, 21 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index cead6be467ed..fa5671307b90 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -308,9 +308,12 @@ struct net_device #define NETIF_F_HW_VLAN_RX 256 /* Receive VLAN hw acceleration */ #define NETIF_F_HW_VLAN_FILTER 512 /* Receive filtering on VLAN */ #define NETIF_F_VLAN_CHALLENGED 1024 /* Device cannot handle VLAN packets */ -#define NETIF_F_TSO 2048 /* Can offload TCP/IP segmentation */ #define NETIF_F_LLTX 4096 /* LockLess TX */ -#define NETIF_F_UFO 8192 /* Can offload UDP Large Send*/ + + /* Segmentation offload features */ +#define NETIF_F_GSO_SHIFT 16 +#define NETIF_F_TSO (SKB_GSO_TCPV4 << NETIF_F_GSO_SHIFT) +#define NETIF_F_UFO (SKB_GSO_UDPV4 << NETIF_F_GSO_SHIFT) #define NETIF_F_GEN_CSUM (NETIF_F_NO_CSUM | NETIF_F_HW_CSUM) #define NETIF_F_ALL_CSUM (NETIF_F_IP_CSUM | NETIF_F_GEN_CSUM) @@ -979,6 +982,13 @@ extern void dev_seq_stop(struct seq_file *seq, void *v); extern void linkwatch_run_queue(void); +static inline int netif_needs_gso(struct net_device *dev, struct sk_buff *skb) +{ + int feature = skb_shinfo(skb)->gso_type << NETIF_F_GSO_SHIFT; + return skb_shinfo(skb)->gso_size && + (dev->features & feature) != feature; +} + #endif /* __KERNEL__ */ #endif /* _LINUX_DEV_H */ diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index f8c7eb79a27f..97b0d2d1a6b0 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -134,9 +134,10 @@ struct skb_frag_struct { struct skb_shared_info { atomic_t dataref; unsigned short nr_frags; - unsigned short tso_size; - unsigned short tso_segs; - unsigned short ufo_size; + unsigned short gso_size; + /* Warning: this field is not always filled in (UFO)! */ + unsigned short gso_segs; + unsigned short gso_type; unsigned int ip6_frag_id; struct sk_buff *frag_list; skb_frag_t frags[MAX_SKB_FRAGS]; @@ -168,6 +169,11 @@ enum { SKB_FCLONE_CLONE, }; +enum { + SKB_GSO_TCPV4 = 1 << 0, + SKB_GSO_UDPV4 = 1 << 1, +}; + /** * struct sk_buff - socket buffer * @next: Next buffer in list -- cgit v1.2.3 From f6a78bfcb141f963187464bac838d46a81c3882a Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 22 Jun 2006 02:57:17 -0700 Subject: [NET]: Add generic segmentation offload This patch adds the infrastructure for generic segmentation offload. The idea is to tap into the potential savings of TSO without hardware support by postponing the allocation of segmented skb's until just before the entry point into the NIC driver. The same structure can be used to support software IPv6 TSO, as well as UFO and segmentation offload for other relevant protocols, e.g., DCCP. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- include/linux/netdevice.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index fa5671307b90..b4eae18390cc 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -405,6 +405,9 @@ struct net_device struct list_head qdisc_list; unsigned long tx_queue_len; /* Max frames per queue allowed */ + /* Partially transmitted GSO packet. */ + struct sk_buff *gso_skb; + /* ingress path synchronizer */ spinlock_t ingress_lock; struct Qdisc *qdisc_ingress; @@ -539,6 +542,7 @@ struct packet_type { struct net_device *, struct packet_type *, struct net_device *); + struct sk_buff *(*gso_segment)(struct sk_buff *skb, int sg); void *af_packet_priv; struct list_head list; }; @@ -689,7 +693,8 @@ extern int dev_change_name(struct net_device *, char *); extern int dev_set_mtu(struct net_device *, int); extern int dev_set_mac_address(struct net_device *, struct sockaddr *); -extern void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev); +extern int dev_hard_start_xmit(struct sk_buff *skb, + struct net_device *dev); extern void dev_init(void); @@ -963,6 +968,7 @@ extern int netdev_max_backlog; extern int weight_p; extern int netdev_set_master(struct net_device *dev, struct net_device *master); extern int skb_checksum_help(struct sk_buff *skb, int inward); +extern struct sk_buff *skb_gso_segment(struct sk_buff *skb, int sg); #ifdef CONFIG_BUG extern void netdev_rx_csum_fault(struct net_device *dev); #else -- cgit v1.2.3 From f4c50d990dcf11a296679dc05de3873783236711 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 22 Jun 2006 03:02:40 -0700 Subject: [NET]: Add software TSOv4 This patch adds the GSO implementation for IPv4 TCP. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- include/linux/skbuff.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 97b0d2d1a6b0..a45bba9b8cbd 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -1297,6 +1297,7 @@ extern void skb_split(struct sk_buff *skb, struct sk_buff *skb1, const u32 len); extern void skb_release_data(struct sk_buff *skb); +extern struct sk_buff *skb_segment(struct sk_buff *skb, int sg); static inline void *skb_header_pointer(const struct sk_buff *skb, int offset, int len, void *buffer) -- cgit v1.2.3 From 37c3185a02d4b85fbe134bf5204535405dd2c957 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 22 Jun 2006 03:07:29 -0700 Subject: [NET]: Added GSO toggle This patch adds a generic segmentation offload toggle that can be turned on/off for each net device. For now it only supports in TCPv4. Signed-off-by: Herbert Xu Signed-off-by: David S. Miller --- include/linux/ethtool.h | 2 ++ include/linux/netdevice.h | 1 + 2 files changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index cf2abeca92a0..c6310aef5ab0 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -411,6 +411,8 @@ struct ethtool_ops { #define ETHTOOL_GPERMADDR 0x00000020 /* Get permanent hardware address */ #define ETHTOOL_GUFO 0x00000021 /* Get UFO enable (ethtool_value) */ #define ETHTOOL_SUFO 0x00000022 /* Set UFO enable (ethtool_value) */ +#define ETHTOOL_GGSO 0x00000023 /* Get GSO enable (ethtool_value) */ +#define ETHTOOL_SGSO 0x00000024 /* Set GSO enable (ethtool_value) */ /* compatibility with older code */ #define SPARC_ETH_GSET ETHTOOL_GSET diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index b4eae18390cc..bc747e5d7138 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h @@ -308,6 +308,7 @@ struct net_device #define NETIF_F_HW_VLAN_RX 256 /* Receive VLAN hw acceleration */ #define NETIF_F_HW_VLAN_FILTER 512 /* Receive filtering on VLAN */ #define NETIF_F_VLAN_CHALLENGED 1024 /* Device cannot handle VLAN packets */ +#define NETIF_F_GSO 2048 /* Enable software GSO. */ #define NETIF_F_LLTX 4096 /* LockLess TX */ /* Segmentation offload features */ -- cgit v1.2.3 From c8a553ad7f0bf943047943a758cf07017819cb3c Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 22 Jun 2006 14:28:09 -0700 Subject: [TCP]: Move inclusion of to correct place in The new header shouldn't be included from the !__KERNEL__ portion of tcp.h Signed-off-by: David Woodhouse Signed-off-by: David S. Miller --- include/linux/tcp.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/tcp.h b/include/linux/tcp.h index 420a689c3fb4..8ebf497907f8 100644 --- a/include/linux/tcp.h +++ b/include/linux/tcp.h @@ -18,7 +18,6 @@ #define _LINUX_TCP_H #include -#include #include struct tcphdr { @@ -161,6 +160,7 @@ struct tcp_info #ifdef __KERNEL__ #include +#include #include #include #include -- cgit v1.2.3 From f4b8ea7849544114e9d3d682df4d400180854677 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 22 Jun 2006 16:00:11 -0700 Subject: [NET]: fix net-core kernel-doc Warning(/var/linsrc/linux-2617-g4//include/linux/skbuff.h:304): No description found for parameter 'dma_cookie' Warning(/var/linsrc/linux-2617-g4//include/net/sock.h:1274): No description found for parameter 'copied_early' Warning(/var/linsrc/linux-2617-g4//net/core/dev.c:3309): No description found for parameter 'chan' Warning(/var/linsrc/linux-2617-g4//net/core/dev.c:3309): No description found for parameter 'event' Signed-off-by: Randy Dunlap Signed-off-by: David S. Miller --- include/linux/skbuff.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index a45bba9b8cbd..16eef03ce0eb 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -215,6 +215,8 @@ enum { * @nf_bridge: Saved data about a bridged frame - see br_netfilter.c * @tc_index: Traffic control index * @tc_verd: traffic control verdict + * @dma_cookie: a cookie to one of several possible DMA operations + * done by skb DMA functions * @secmark: security marking */ -- cgit v1.2.3 From 454e2398be9b9fa30433fccc548db34d19aa9958 Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 23 Jun 2006 02:02:57 -0700 Subject: [PATCH] VFS: Permit filesystem to override root dentry on mount Extend the get_sb() filesystem operation to take an extra argument that permits the VFS to pass in the target vfsmount that defines the mountpoint. The filesystem is then required to manually set the superblock and root dentry pointers. For most filesystems, this should be done with simple_set_mnt() which will set the superblock pointer and then set the root dentry to the superblock's s_root (as per the old default behaviour). The get_sb() op now returns an integer as there's now no need to return the superblock pointer. This patch permits a superblock to be implicitly shared amongst several mount points, such as can be done with NFS to avoid potential inode aliasing. In such a case, simple_set_mnt() would not be called, and instead the mnt_root and mnt_sb would be set directly. The patch also makes the following changes: (*) the get_sb_*() convenience functions in the core kernel now take a vfsmount pointer argument and return an integer, so most filesystems have to change very little. (*) If one of the convenience function is not used, then get_sb() should normally call simple_set_mnt() to instantiate the vfsmount. This will always return 0, and so can be tail-called from get_sb(). (*) generic_shutdown_super() now calls shrink_dcache_sb() to clean up the dcache upon superblock destruction rather than shrink_dcache_anon(). This is required because the superblock may now have multiple trees that aren't actually bound to s_root, but that still need to be cleaned up. The currently called functions assume that the whole tree is rooted at s_root, and that anonymous dentries are not the roots of trees which results in dentries being left unculled. However, with the way NFS superblock sharing are currently set to be implemented, these assumptions are violated: the root of the filesystem is simply a dummy dentry and inode (the real inode for '/' may well be inaccessible), and all the vfsmounts are rooted on anonymous[*] dentries with child trees. [*] Anonymous until discovered from another tree. (*) The documentation has been adjusted, including the additional bit of changing ext2_* into foo_* in the documentation. [akpm@osdl.org: convert ipath_fs, do other stuff] Signed-off-by: David Howells Acked-by: Al Viro Cc: Nathan Scott Cc: Roland Dreier Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/dcache.h | 1 - include/linux/fs.h | 25 +++++++++++++++---------- include/linux/ramfs.h | 4 ++-- 3 files changed, 17 insertions(+), 13 deletions(-) (limited to 'include/linux') diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 46d0e079735d..0dd1610a94a9 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h @@ -217,7 +217,6 @@ extern struct dentry * d_alloc_anon(struct inode *); extern struct dentry * d_splice_alias(struct inode *, struct dentry *); extern void shrink_dcache_sb(struct super_block *); extern void shrink_dcache_parent(struct dentry *); -extern void shrink_dcache_anon(struct super_block *); extern int d_invalidate(struct dentry *); /* only used at mount-time */ diff --git a/include/linux/fs.h b/include/linux/fs.h index 73c7d6f04b31..3e50dd24af87 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1269,23 +1269,26 @@ find_exported_dentry(struct super_block *sb, void *obj, void *parent, struct file_system_type { const char *name; int fs_flags; - struct super_block *(*get_sb) (struct file_system_type *, int, - const char *, void *); + int (*get_sb) (struct file_system_type *, int, + const char *, void *, struct vfsmount *); void (*kill_sb) (struct super_block *); struct module *owner; struct file_system_type * next; struct list_head fs_supers; }; -struct super_block *get_sb_bdev(struct file_system_type *fs_type, +extern int get_sb_bdev(struct file_system_type *fs_type, int flags, const char *dev_name, void *data, - int (*fill_super)(struct super_block *, void *, int)); -struct super_block *get_sb_single(struct file_system_type *fs_type, + int (*fill_super)(struct super_block *, void *, int), + struct vfsmount *mnt); +extern int get_sb_single(struct file_system_type *fs_type, int flags, void *data, - int (*fill_super)(struct super_block *, void *, int)); -struct super_block *get_sb_nodev(struct file_system_type *fs_type, + int (*fill_super)(struct super_block *, void *, int), + struct vfsmount *mnt); +extern int get_sb_nodev(struct file_system_type *fs_type, int flags, void *data, - int (*fill_super)(struct super_block *, void *, int)); + int (*fill_super)(struct super_block *, void *, int), + struct vfsmount *mnt); void generic_shutdown_super(struct super_block *sb); void kill_block_super(struct super_block *sb); void kill_anon_super(struct super_block *sb); @@ -1296,8 +1299,10 @@ struct super_block *sget(struct file_system_type *type, int (*test)(struct super_block *,void *), int (*set)(struct super_block *,void *), void *data); -struct super_block *get_sb_pseudo(struct file_system_type *, char *, - struct super_operations *ops, unsigned long); +extern int get_sb_pseudo(struct file_system_type *, char *, + struct super_operations *ops, unsigned long, + struct vfsmount *mnt); +extern int simple_set_mnt(struct vfsmount *mnt, struct super_block *sb); int __put_super(struct super_block *sb); int __put_super_and_need_restart(struct super_block *sb); void unnamed_dev_init(void); diff --git a/include/linux/ramfs.h b/include/linux/ramfs.h index 78ecfa28b1c2..00b340ba6612 100644 --- a/include/linux/ramfs.h +++ b/include/linux/ramfs.h @@ -2,8 +2,8 @@ #define _LINUX_RAMFS_H struct inode *ramfs_get_inode(struct super_block *sb, int mode, dev_t dev); -struct super_block *ramfs_get_sb(struct file_system_type *fs_type, - int flags, const char *dev_name, void *data); +extern int ramfs_get_sb(struct file_system_type *fs_type, + int flags, const char *dev_name, void *data, struct vfsmount *mnt); #ifndef CONFIG_MMU extern unsigned long ramfs_nommu_get_unmapped_area(struct file *file, -- cgit v1.2.3 From 726c334223180e3c0197cc980a432681370d4baf Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 23 Jun 2006 02:02:58 -0700 Subject: [PATCH] VFS: Permit filesystem to perform statfs with a known root dentry Give the statfs superblock operation a dentry pointer rather than a superblock pointer. This complements the get_sb() patch. That reduced the significance of sb->s_root, allowing NFS to place a fake root there. However, NFS does require a dentry to use as a target for the statfs operation. This permits the root in the vfsmount to be used instead. linux/mount.h has been added where necessary to make allyesconfig build successfully. Interest has also been expressed for use with the FUSE and XFS filesystems. Signed-off-by: David Howells Acked-by: Al Viro Cc: Nathan Scott Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/coda_psdev.h | 2 +- include/linux/fs.h | 6 +++--- include/linux/mount.h | 5 +++++ include/linux/security.h | 14 +++++++------- 4 files changed, 16 insertions(+), 11 deletions(-) (limited to 'include/linux') diff --git a/include/linux/coda_psdev.h b/include/linux/coda_psdev.h index d539262a8f89..98f6c52c152b 100644 --- a/include/linux/coda_psdev.h +++ b/include/linux/coda_psdev.h @@ -70,7 +70,7 @@ int venus_pioctl(struct super_block *sb, struct CodaFid *fid, unsigned int cmd, struct PioctlData *data); int coda_downcall(int opcode, union outputArgs *out, struct super_block *sb); int venus_fsync(struct super_block *sb, struct CodaFid *fid); -int venus_statfs(struct super_block *sb, struct kstatfs *sfs); +int venus_statfs(struct dentry *dentry, struct kstatfs *sfs); /* messages between coda filesystem in kernel and Venus */ diff --git a/include/linux/fs.h b/include/linux/fs.h index 3e50dd24af87..c823a3815e24 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1096,7 +1096,7 @@ struct super_operations { int (*sync_fs)(struct super_block *sb, int wait); void (*write_super_lockfs) (struct super_block *); void (*unlockfs) (struct super_block *); - int (*statfs) (struct super_block *, struct kstatfs *); + int (*statfs) (struct dentry *, struct kstatfs *); int (*remount_fs) (struct super_block *, int *, char *); void (*clear_inode) (struct inode *); void (*umount_begin) (struct super_block *); @@ -1325,7 +1325,7 @@ extern struct vfsmount *copy_tree(struct vfsmount *, struct dentry *, int); extern void mnt_set_mountpoint(struct vfsmount *, struct dentry *, struct vfsmount *); -extern int vfs_statfs(struct super_block *, struct kstatfs *); +extern int vfs_statfs(struct dentry *, struct kstatfs *); /* /sys/fs */ extern struct subsystem fs_subsys; @@ -1746,7 +1746,7 @@ extern int dcache_dir_close(struct inode *, struct file *); extern loff_t dcache_dir_lseek(struct file *, loff_t, int); extern int dcache_readdir(struct file *, void *, filldir_t); extern int simple_getattr(struct vfsmount *, struct dentry *, struct kstat *); -extern int simple_statfs(struct super_block *, struct kstatfs *); +extern int simple_statfs(struct dentry *, struct kstatfs *); extern int simple_link(struct dentry *, struct inode *, struct dentry *); extern int simple_unlink(struct inode *, struct dentry *); extern int simple_rmdir(struct inode *, struct dentry *); diff --git a/include/linux/mount.h b/include/linux/mount.h index b7472ae91fa4..60718f12caa9 100644 --- a/include/linux/mount.h +++ b/include/linux/mount.h @@ -17,6 +17,11 @@ #include #include +struct super_block; +struct vfsmount; +struct dentry; +struct namespace; + #define MNT_NOSUID 0x01 #define MNT_NODEV 0x02 #define MNT_NOEXEC 0x04 diff --git a/include/linux/security.h b/include/linux/security.h index 47722d355532..383c320fc834 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -171,9 +171,9 @@ struct swap_info_struct; * Deallocate and clear the sb->s_security field. * @sb contains the super_block structure to be modified. * @sb_statfs: - * Check permission before obtaining filesystem statistics for the @sb - * filesystem. - * @sb contains the super_block structure for the filesystem. + * Check permission before obtaining filesystem statistics for the @mnt + * mountpoint. + * @dentry is a handle on the superblock for the filesystem. * Return 0 if permission is granted. * @sb_mount: * Check permission before an object specified by @dev_name is mounted on @@ -1127,7 +1127,7 @@ struct security_operations { int (*sb_copy_data)(struct file_system_type *type, void *orig, void *copy); int (*sb_kern_mount) (struct super_block *sb, void *data); - int (*sb_statfs) (struct super_block * sb); + int (*sb_statfs) (struct dentry *dentry); int (*sb_mount) (char *dev_name, struct nameidata * nd, char *type, unsigned long flags, void *data); int (*sb_check_sb) (struct vfsmount * mnt, struct nameidata * nd); @@ -1450,9 +1450,9 @@ static inline int security_sb_kern_mount (struct super_block *sb, void *data) return security_ops->sb_kern_mount (sb, data); } -static inline int security_sb_statfs (struct super_block *sb) +static inline int security_sb_statfs (struct dentry *dentry) { - return security_ops->sb_statfs (sb); + return security_ops->sb_statfs (dentry); } static inline int security_sb_mount (char *dev_name, struct nameidata *nd, @@ -2162,7 +2162,7 @@ static inline int security_sb_kern_mount (struct super_block *sb, void *data) return 0; } -static inline int security_sb_statfs (struct super_block *sb) +static inline int security_sb_statfs (struct dentry *dentry) { return 0; } -- cgit v1.2.3 From cb2b95e1c6b56e3d2369d3a5f4bc97f4fa180683 Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Fri, 23 Jun 2006 02:03:01 -0700 Subject: [PATCH] zone handle unaligned zone boundaries The buddy allocator has a requirement that boundaries between contigious zones occur aligned with the the MAX_ORDER ranges. Where they do not we will incorrectly merge pages cross zone boundaries. This can lead to pages from the wrong zone being handed out. Originally the buddy allocator would check that buddies were in the same zone by referencing the zone start and end page frame numbers. This was removed as it became very expensive and the buddy allocator already made the assumption that zones boundaries were aligned. It is clear that not all configurations and architectures are honouring this alignment requirement. Therefore it seems safest to reintroduce support for non-aligned zone boundaries. This patch introduces a new check when considering a page a buddy it compares the zone_table index for the two pages and refuses to merge the pages where they do not match. The zone_table index is unique for each node/zone combination when FLATMEM/DISCONTIGMEM is enabled and for each section/zone combination when SPARSEMEM is enabled (a SPARSEMEM section is at least a MAX_ORDER size). Signed-off-by: Andy Whitcroft Cc: Dave Hansen Cc: Mel Gorman Cc: Yasunori Goto Cc: KAMEZAWA Hiroyuki Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mm.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mm.h b/include/linux/mm.h index e2fa375e478e..697c6bf248c2 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -465,10 +465,13 @@ static inline unsigned long page_zonenum(struct page *page) struct zone; extern struct zone *zone_table[]; +static inline int page_zone_id(struct page *page) +{ + return (page->flags >> ZONETABLE_PGSHIFT) & ZONETABLE_MASK; +} static inline struct zone *page_zone(struct page *page) { - return zone_table[(page->flags >> ZONETABLE_PGSHIFT) & - ZONETABLE_MASK]; + return zone_table[page_zone_id(page)]; } static inline unsigned long page_to_nid(struct page *page) -- cgit v1.2.3 From f886ed443fedb109e2062988bf120a531f0ec80a Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 23 Jun 2006 02:03:06 -0700 Subject: [PATCH] PG_uncached is ia64 only As Nick points out, only ia64 uses PG_uncached. So we can push it up into the higher bits of the lower half of page->flags and make room for another flag on 32-bit machines. Cc: "Luck, Tony" Cc: Jesse Barnes Cc: Jes Sorensen Cc: Nick Piggin Cc: Andy Whitcroft Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/page-flags.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index d276a4e2f825..0c076d58c676 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -7,6 +7,8 @@ #include #include +#include + #include /* @@ -88,7 +90,17 @@ #define PG_nosave_free 18 /* Free, should not be written */ #define PG_buddy 19 /* Page is free, on buddy lists */ -#define PG_uncached 20 /* Page has been mapped as uncached */ + +#if (BITS_PER_LONG > 32) +/* + * 64-bit-only flags build down from bit 31 + * + * 32 bit -------------------------------| FIELDS | FLAGS | + * 64 bit | FIELDS | ?????? FLAGS | + * 63 32 0 + */ +#define PG_uncached 31 /* Page has been mapped as uncached */ +#endif /* * Global page accounting. One instance per CPU. Only unsigned longs are -- cgit v1.2.3 From 02b694dea473ad3db1e2d1b14c1fef8fbd92e5e6 Mon Sep 17 00:00:00 2001 From: Yasunori Goto Date: Fri, 23 Jun 2006 02:03:08 -0700 Subject: [PATCH] wait_table and zonelist initializing for memory hotadd: change name of wait_table_size() This is just to rename from wait_table_size() to wait_table_hash_nr_entries(). Signed-off-by: Yasunori Goto Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mmzone.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 9742e3c16222..652673ea92f1 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -197,7 +197,7 @@ struct zone { /* * wait_table -- the array holding the hash table - * wait_table_size -- the size of the hash table array + * wait_table_hash_nr_entries -- the size of the hash table array * wait_table_bits -- wait_table_size == (1 << wait_table_bits) * * The purpose of all these is to keep track of the people @@ -220,7 +220,7 @@ struct zone { * free_area_init_core() performs the initialization of them. */ wait_queue_head_t * wait_table; - unsigned long wait_table_size; + unsigned long wait_table_hash_nr_entries; unsigned long wait_table_bits; /* -- cgit v1.2.3 From 86356ab147669bd3bcb2149fd9561d1280835c24 Mon Sep 17 00:00:00 2001 From: Yasunori Goto Date: Fri, 23 Jun 2006 02:03:09 -0700 Subject: [PATCH] wait_table and zonelist initializing for memory hotadd: change to meminit for build_zonelist Change definitions of some functions and data from __init to __meminit. These functions and data can be used after bootup by this patch to be used for hot-add codes. Signed-off-by: Yasunori Goto Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/bootmem.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/bootmem.h b/include/linux/bootmem.h index da2d107fe2cf..22866fa2d960 100644 --- a/include/linux/bootmem.h +++ b/include/linux/bootmem.h @@ -91,8 +91,8 @@ static inline void *alloc_remap(int nid, unsigned long size) } #endif -extern unsigned long __initdata nr_kernel_pages; -extern unsigned long __initdata nr_all_pages; +extern unsigned long nr_kernel_pages; +extern unsigned long nr_all_pages; extern void *__init alloc_large_system_hash(const char *tablename, unsigned long bucketsize, -- cgit v1.2.3 From 718127cc3170454f4aa274fdd2f1e01574fecd66 Mon Sep 17 00:00:00 2001 From: Yasunori Goto Date: Fri, 23 Jun 2006 02:03:10 -0700 Subject: [PATCH] wait_table and zonelist initializing for memory hotadd: add return code for init_current_empty_zone When add_zone() is called against empty zone (not populated zone), we have to initialize the zone which didn't initialize at boot time. But, init_currently_empty_zone() may fail due to allocation of wait table. So, this patch is to catch its error code. Changes against wait_table is in the next patch. Signed-off-by: KAMEZAWA Hiroyuki Signed-off-by: Yasunori Goto Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mmzone.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index 652673ea92f1..e82fc1a52cd0 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -333,6 +333,9 @@ void wakeup_kswapd(struct zone *zone, int order); int zone_watermark_ok(struct zone *z, int order, unsigned long mark, int classzone_idx, int alloc_flags); +extern int init_currently_empty_zone(struct zone *zone, unsigned long start_pfn, + unsigned long size); + #ifdef CONFIG_HAVE_MEMORY_PRESENT void memory_present(int nid, unsigned long start, unsigned long end); #else -- cgit v1.2.3 From fadd8fbd153c12963f8fe3c9ef7f8967f286f98b Mon Sep 17 00:00:00 2001 From: KAMEZAWA Hiroyuki Date: Fri, 23 Jun 2006 02:03:13 -0700 Subject: [PATCH] support for panic at OOM This patch adds panic_on_oom sysctl under sys.vm. When sysctl vm.panic_on_oom = 1, the kernel panics intead of killing rogue processes. And if vm.panic_on_oom is 0 the kernel will do oom_kill() in the same way as it does today. Of course, the default value is 0 and only root can modifies it. In general, oom_killer works well and kill rogue processes. So the whole system can survive. But there are environments where panic is preferable rather than kill some processes. Signed-off-by: KAMEZAWA Hiroyuki Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/sysctl.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index cee944dbdcd4..c7132029af0f 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h @@ -186,6 +186,7 @@ enum VM_PERCPU_PAGELIST_FRACTION=30,/* int: fraction of pages in each percpu_pagelist */ VM_ZONE_RECLAIM_MODE=31, /* reclaim local zone memory before going off node */ VM_ZONE_RECLAIM_INTERVAL=32, /* time period to wait after reclaim failure */ + VM_PANIC_ON_OOM=33, /* panic at out-of-memory */ }; -- cgit v1.2.3 From e8f03d02080b25f53cd6bba8dc3a297803f18c01 Mon Sep 17 00:00:00 2001 From: Andreas Dilger Date: Fri, 23 Jun 2006 02:03:14 -0700 Subject: [PATCH] reserve space for swap label Reserve space in the swap disk header for a LABEL and UUID to be specified. This has been possible with util-linux-2.12b (via e2fsprogs 1.36 libblkid), and is used by at least FC3 and later. The kernel doesn't really care about this, but the space shouldn't accidentally be used by something else either. Also make the on-disk structures be fixed-size types, instead of "int", though I don't know of any architecture in use where an "int" isn't the same size as a "__u32" (all current kernel arches have it as "unsigned int"). Signed-off-by: Andreas Dilger Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/swap.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/swap.h b/include/linux/swap.h index aca9bfae208f..cd28ad206dae 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -48,12 +48,14 @@ union swap_header { char magic[10]; /* SWAP-SPACE or SWAPSPACE2 */ } magic; struct { - char bootbits[1024]; /* Space for disklabel etc. */ - unsigned int version; - unsigned int last_page; - unsigned int nr_badpages; - unsigned int padding[125]; - unsigned int badpages[1]; + char bootbits[1024]; /* Space for disklabel etc. */ + __u32 version; + __u32 last_page; + __u32 nr_badpages; + unsigned char sws_uuid[16]; + unsigned char sws_volume[16]; + __u32 padding[117]; + __u32 badpages[1]; } info; }; -- cgit v1.2.3 From a43a8c39bbb493c9e93f6764b350de2e33e18e92 Mon Sep 17 00:00:00 2001 From: "Chen, Kenneth W" Date: Fri, 23 Jun 2006 02:03:15 -0700 Subject: [PATCH] tightening hugetlb strict accounting Current hugetlb strict accounting for shared mapping always assume mapping starts at zero file offset and reserves pages between zero and size of the file. This assumption often reserves (or lock down) a lot more pages then necessary if application maps at none zero file offset. libhugetlbfs is one example that requires proper reservation on shared mapping starts at none zero offset. This patch extends the reservation and hugetlb strict accounting to support any arbitrary pair of (offset, len), resulting a much more robust and accurate scheme. More importantly, it won't lock down any hugetlb pages outside file mapping. Signed-off-by: Ken Chen Acked-by: Adam Litke Cc: David Gibson Cc: William Lee Irwin III Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/hugetlb.h | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 4c5e610fe442..c25a38d8f600 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -23,6 +23,8 @@ int hugetlb_report_node_meminfo(int, char *); unsigned long hugetlb_total_pages(void); int hugetlb_fault(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long address, int write_access); +int hugetlb_reserve_pages(struct inode *inode, long from, long to); +void hugetlb_unreserve_pages(struct inode *inode, long offset, long freed); extern unsigned long max_huge_pages; extern const unsigned long hugetlb_zero, hugetlb_infinity; @@ -139,8 +141,6 @@ struct hugetlbfs_sb_info { struct hugetlbfs_inode_info { struct shared_policy policy; - /* Protected by the (global) hugetlb_lock */ - unsigned long prereserved_hpages; struct inode vfs_inode; }; @@ -157,10 +157,6 @@ static inline struct hugetlbfs_sb_info *HUGETLBFS_SB(struct super_block *sb) extern const struct file_operations hugetlbfs_file_operations; extern struct vm_operations_struct hugetlb_vm_ops; struct file *hugetlb_zero_setup(size_t); -int hugetlb_extend_reservation(struct hugetlbfs_inode_info *info, - unsigned long atleast_hpages); -void hugetlb_truncate_reservation(struct hugetlbfs_inode_info *info, - unsigned long atmost_hpages); int hugetlb_get_quota(struct address_space *mapping); void hugetlb_put_quota(struct address_space *mapping); -- cgit v1.2.3 From 762834e8bf46bf41ce9034d062a7c1f8563175f3 Mon Sep 17 00:00:00 2001 From: Yasunori Goto Date: Fri, 23 Jun 2006 02:03:19 -0700 Subject: [PATCH] Unify pxm_to_node() and node_to_pxm() Consolidate the various arch-specific implementations of pxm_to_node() and node_to_pxm() into a single generic version. Signed-off-by: Yasunori Goto Cc: "Luck, Tony" Cc: Andi Kleen Cc: Dave Hansen Cc: "Brown, Len" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/acpi.h | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'include/linux') diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 1cf0b91d05bd..90d6df1551ed 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -37,6 +37,7 @@ #include #include #include +#include #include @@ -407,10 +408,18 @@ void acpi_table_print_madt_entry (acpi_table_entry_header *madt); void acpi_table_print_srat_entry (acpi_table_entry_header *srat); /* the following four functions are architecture-dependent */ +#ifdef CONFIG_HAVE_ARCH_PARSE_SRAT +#define NR_NODE_MEMBLKS MAX_NUMNODES +#define acpi_numa_slit_init(slit) do {} while (0) +#define acpi_numa_processor_affinity_init(pa) do {} while (0) +#define acpi_numa_memory_affinity_init(ma) do {} while (0) +#define acpi_numa_arch_fixup() do {} while (0) +#else void acpi_numa_slit_init (struct acpi_table_slit *slit); void acpi_numa_processor_affinity_init (struct acpi_table_processor_affinity *pa); void acpi_numa_memory_affinity_init (struct acpi_table_memory_affinity *ma); void acpi_numa_arch_fixup(void); +#endif #ifdef CONFIG_ACPI_HOTPLUG_CPU /* Arch dependent functions for cpu hotplug support */ -- cgit v1.2.3 From 833423143c3a7c6545e409d65febd0d92deb351b Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Fri, 23 Jun 2006 02:03:20 -0700 Subject: [PATCH] mm: introduce remap_vmalloc_range() Add remap_vmalloc_range, vmalloc_user, and vmalloc_32_user so that drivers can have a nice interface for remapping vmalloc memory. Signed-off-by: Nick Piggin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/vmalloc.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include/linux') diff --git a/include/linux/vmalloc.h b/include/linux/vmalloc.h index 1d5577b2b752..f6024ab4eff0 100644 --- a/include/linux/vmalloc.h +++ b/include/linux/vmalloc.h @@ -4,10 +4,13 @@ #include #include /* pgprot_t */ +struct vm_area_struct; + /* bits in vm_struct->flags */ #define VM_IOREMAP 0x00000001 /* ioremap() and friends */ #define VM_ALLOC 0x00000002 /* vmalloc() */ #define VM_MAP 0x00000004 /* vmap()ed pages */ +#define VM_USERMAP 0x00000008 /* suitable for remap_vmalloc_range */ /* bits [20..32] reserved for arch specific ioremap internals */ /* @@ -32,9 +35,11 @@ struct vm_struct { * Highlevel APIs for driver use */ extern void *vmalloc(unsigned long size); +extern void *vmalloc_user(unsigned long size); extern void *vmalloc_node(unsigned long size, int node); extern void *vmalloc_exec(unsigned long size); extern void *vmalloc_32(unsigned long size); +extern void *vmalloc_32_user(unsigned long size); extern void *__vmalloc(unsigned long size, gfp_t gfp_mask, pgprot_t prot); extern void *__vmalloc_area(struct vm_struct *area, gfp_t gfp_mask, pgprot_t prot); @@ -45,6 +50,9 @@ extern void vfree(void *addr); extern void *vmap(struct page **pages, unsigned int count, unsigned long flags, pgprot_t prot); extern void vunmap(void *addr); + +extern int remap_vmalloc_range(struct vm_area_struct *vma, void *addr, + unsigned long pgoff); /* * Lowlevel-APIs (not for driver use!) -- cgit v1.2.3 From 929f97276bcf7f4a95272ed08a85339b98ba210d Mon Sep 17 00:00:00 2001 From: Dean Nelson Date: Fri, 23 Jun 2006 02:03:21 -0700 Subject: [PATCH] change gen_pool allocator to not touch managed memory Modify the gen_pool allocator (lib/genalloc.c) to utilize a bitmap scheme instead of the buddy scheme. The purpose of this change is to eliminate the touching of the actual memory being allocated. Since the change modifies the interface, a change to the uncached allocator (arch/ia64/kernel/uncached.c) is also required. Both Andrey Volkov and Jes Sorenson have expressed a desire that the gen_pool allocator not write to the memory being managed. See the following: http://marc.theaimsgroup.com/?l=linux-kernel&m=113518602713125&w=2 http://marc.theaimsgroup.com/?l=linux-kernel&m=113533568827916&w=2 Signed-off-by: Dean Nelson Cc: Andrey Volkov Acked-by: Jes Sorensen Cc: "Luck, Tony" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/genalloc.h | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) (limited to 'include/linux') diff --git a/include/linux/genalloc.h b/include/linux/genalloc.h index 7fd0576a4454..690c42803d2e 100644 --- a/include/linux/genalloc.h +++ b/include/linux/genalloc.h @@ -4,37 +4,32 @@ * Uses for this includes on-device special memory, uncached memory * etc. * - * This code is based on the buddy allocator found in the sym53c8xx_2 - * driver, adapted for general purpose use. - * * This source code is licensed under the GNU General Public License, * Version 2. See the file COPYING for more details. */ -#include -#define ALLOC_MIN_SHIFT 5 /* 32 bytes minimum */ /* - * Link between free memory chunks of a given size. + * General purpose special memory pool descriptor. */ -struct gen_pool_link { - struct gen_pool_link *next; +struct gen_pool { + rwlock_t lock; + struct list_head chunks; /* list of chunks in this pool */ + int min_alloc_order; /* minimum allocation order */ }; /* - * Memory pool descriptor. + * General purpose special memory pool chunk descriptor. */ -struct gen_pool { +struct gen_pool_chunk { spinlock_t lock; - unsigned long (*get_new_chunk)(struct gen_pool *); - struct gen_pool *next; - struct gen_pool_link *h; - unsigned long private; - int max_chunk_shift; + struct list_head next_chunk; /* next chunk in pool */ + unsigned long start_addr; /* starting address of memory chunk */ + unsigned long end_addr; /* ending address of memory chunk */ + unsigned long bits[0]; /* bitmap for allocating memory chunk */ }; -unsigned long gen_pool_alloc(struct gen_pool *poolp, int size); -void gen_pool_free(struct gen_pool *mp, unsigned long ptr, int size); -struct gen_pool *gen_pool_create(int nr_chunks, int max_chunk_shift, - unsigned long (*fp)(struct gen_pool *), - unsigned long data); +extern struct gen_pool *gen_pool_create(int, int); +extern int gen_pool_add(struct gen_pool *, unsigned long, size_t, int); +extern unsigned long gen_pool_alloc(struct gen_pool *, size_t); +extern void gen_pool_free(struct gen_pool *, unsigned long, size_t); -- cgit v1.2.3 From 612d6c19db2fd0dc97b0fa370613ecd4a305ffc3 Mon Sep 17 00:00:00 2001 From: Nick Piggin Date: Fri, 23 Jun 2006 02:03:22 -0700 Subject: [PATCH] radix-tree: direct data The ability to have height 0 radix trees (a direct pointer to the data item rather than going through a full node->slot) quietly disappeared with old-2.6-bkcvs commit ffee171812d51652f9ba284302d9e5c5cc14bdfd. On 64-bit machines this causes nearly 600 bytes to be used for every <= 4K file in pagecache. Re-introduce this feature, root tags stored in spare ->gfp_mask bits. Simplify radix_tree_delete's complex tag clearing arrangement (which would become even more complex) by just falling back to tag clearing functions (the pagecache radix-tree never uses this path anyway, so the icache savings will mean it's actually a speedup). On my 4GB G5, this saves 8MB RAM per kernel kernel source+object tree in pagecache. Pagecache lookup, insertion, and removal speed for small files will also be improved. This makes RCU radix tree harder, but it's worth it. Signed-off-by: Nick Piggin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/radix-tree.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h index dd83cca28001..9158a68140c9 100644 --- a/include/linux/radix-tree.h +++ b/include/linux/radix-tree.h @@ -23,6 +23,9 @@ #include #include +#define RADIX_TREE_MAX_TAGS 2 + +/* root tags are stored in gfp_mask, shifted by __GFP_BITS_SHIFT */ struct radix_tree_root { unsigned int height; gfp_t gfp_mask; @@ -45,8 +48,6 @@ do { \ (root)->rnode = NULL; \ } while (0) -#define RADIX_TREE_MAX_TAGS 2 - int radix_tree_insert(struct radix_tree_root *, unsigned long, void *); void *radix_tree_lookup(struct radix_tree_root *, unsigned long); void **radix_tree_lookup_slot(struct radix_tree_root *, unsigned long); -- cgit v1.2.3 From 111ebb6e6f7bd7de6d722c5848e95621f43700d9 Mon Sep 17 00:00:00 2001 From: OGAWA Hirofumi Date: Fri, 23 Jun 2006 02:03:26 -0700 Subject: [PATCH] writeback: fix range handling When a writeback_control's `start' and `end' fields are used to indicate a one-byte-range starting at file offset zero, the required values of .start=0,.end=0 mean that the ->writepages() implementation has no way of telling that it is being asked to perform a range request. Because we're currently overloading (start == 0 && end == 0) to mean "this is not a write-a-range request". To make all this sane, the patch changes range of writeback_control. So caller does: If it is calling ->writepages() to write pages, it sets range (range_start/end or range_cyclic) always. And if range_cyclic is true, ->writepages() thinks the range is cyclic, otherwise it just uses range_start and range_end. This patch does, - Add LLONG_MAX, LLONG_MIN, ULLONG_MAX to include/linux/kernel.h -1 is usually ok for range_end (type is long long). But, if someone did, range_end += val; range_end is "val - 1" u64val = range_end >> bits; u64val is "~(0ULL)" or something, they are wrong. So, this adds LLONG_MAX to avoid nasty things, and uses LLONG_MAX for range_end. - All callers of ->writepages() sets range_start/end or range_cyclic. - Fix updates of ->writeback_index. It seems already bit strange. If it starts at 0 and ended by check of nr_to_write, this last index may reduce chance to scan end of file. So, this updates ->writeback_index only if range_cyclic is true or whole-file is scanned. Signed-off-by: OGAWA Hirofumi Cc: Nathan Scott Cc: Anton Altaparmakov Cc: Steven French Cc: "Vladimir V. Saveliev" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/kernel.h | 3 +++ include/linux/writeback.h | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/kernel.h b/include/linux/kernel.h index f4fc576ed4c4..25fccd859fbf 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -24,6 +24,9 @@ extern const char linux_banner[]; #define LONG_MAX ((long)(~0UL>>1)) #define LONG_MIN (-LONG_MAX - 1) #define ULONG_MAX (~0UL) +#define LLONG_MAX ((long long)(~0ULL>>1)) +#define LLONG_MIN (-LLONG_MAX - 1) +#define ULLONG_MAX (~0ULL) #define STACK_MAGIC 0xdeadbeef diff --git a/include/linux/writeback.h b/include/linux/writeback.h index 56f92fcbe94a..9e38b566d0e7 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h @@ -50,14 +50,15 @@ struct writeback_control { * a hint that the filesystem need only write out the pages inside that * byterange. The byte at `end' is included in the writeout request. */ - loff_t start; - loff_t end; + loff_t range_start; + loff_t range_end; unsigned nonblocking:1; /* Don't get stuck on request queues */ unsigned encountered_congestion:1; /* An output: a queue is full */ unsigned for_kupdate:1; /* A kupdate writeback */ unsigned for_reclaim:1; /* Invoked from the page allocator */ unsigned for_writepages:1; /* This is a writepages() call */ + unsigned range_cyclic:1; /* range_start is cyclic */ }; /* -- cgit v1.2.3 From e7340f73307abed9283d0a07570d06e228c205dd Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Fri, 23 Jun 2006 02:03:29 -0700 Subject: [PATCH] page migration cleanup: remove useless definitions Remove the export for migrate_page_remove_references() and migrate_page_copy() that are unlikely to be used directly by filesystems implementing migration. The export was useful when buffer_migrate_page() lived in fs/buffer.c but it has now been moved to migrate.c in the migration reorg. Signed-off-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/migrate.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/migrate.h b/include/linux/migrate.h index 6789c4940c9c..e8d3b08cc354 100644 --- a/include/linux/migrate.h +++ b/include/linux/migrate.h @@ -7,8 +7,6 @@ extern int isolate_lru_page(struct page *p, struct list_head *pagelist); extern int putback_lru_pages(struct list_head *l); extern int migrate_page(struct page *, struct page *); -extern void migrate_page_copy(struct page *, struct page *); -extern int migrate_page_remove_references(struct page *, struct page *, int); extern int migrate_pages(struct list_head *l, struct list_head *t, struct list_head *moved, struct list_head *failed); extern int migrate_pages_to(struct list_head *pagelist, -- cgit v1.2.3 From 2d1db3b1170db4e8bf0531dd636742269c2cf579 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Fri, 23 Jun 2006 02:03:33 -0700 Subject: [PATCH] page migration cleanup: pass "mapping" to migration functions Change handling of address spaces. Pass a pointer to the address space in which the page is migrated to all migration function. This avoids repeatedly having to retrieve the address space pointer from the page and checking it for validity. The old page mapping will change once migration has gone to a certain step, so it is less confusing to have the pointer always available. Move the setting of the mapping and index for the new page into migrate_pages(). Signed-off-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/fs.h | 6 ++++-- include/linux/migrate.h | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/fs.h b/include/linux/fs.h index c823a3815e24..e917403f4d58 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -376,7 +376,8 @@ struct address_space_operations { struct page* (*get_xip_page)(struct address_space *, sector_t, int); /* migrate the contents of a page to the specified target */ - int (*migratepage) (struct page *, struct page *); + int (*migratepage) (struct address_space *, + struct page *, struct page *); }; struct backing_dev_info; @@ -1772,7 +1773,8 @@ extern void simple_release_fs(struct vfsmount **mount, int *count); extern ssize_t simple_read_from_buffer(void __user *, size_t, loff_t *, const void *, size_t); #ifdef CONFIG_MIGRATION -extern int buffer_migrate_page(struct page *, struct page *); +extern int buffer_migrate_page(struct address_space *, + struct page *, struct page *); #else #define buffer_migrate_page NULL #endif diff --git a/include/linux/migrate.h b/include/linux/migrate.h index e8d3b08cc354..287c47b5e5df 100644 --- a/include/linux/migrate.h +++ b/include/linux/migrate.h @@ -6,12 +6,14 @@ #ifdef CONFIG_MIGRATION extern int isolate_lru_page(struct page *p, struct list_head *pagelist); extern int putback_lru_pages(struct list_head *l); -extern int migrate_page(struct page *, struct page *); +extern int migrate_page(struct address_space *, + struct page *, struct page *); extern int migrate_pages(struct list_head *l, struct list_head *t, struct list_head *moved, struct list_head *failed); extern int migrate_pages_to(struct list_head *pagelist, struct vm_area_struct *vma, int dest); -extern int fail_migrate_page(struct page *, struct page *); +extern int fail_migrate_page(struct address_space *, + struct page *, struct page *); extern int migrate_prep(void); -- cgit v1.2.3 From 0697212a411c1dae03c27845f2de2f3adb32c331 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Fri, 23 Jun 2006 02:03:35 -0700 Subject: [PATCH] Swapless page migration: add R/W migration entries Implement read/write migration ptes We take the upper two swapfiles for the two types of migration ptes and define a series of macros in swapops.h. The VM is modified to handle the migration entries. migration entries can only be encountered when the page they are pointing to is locked. This limits the number of places one has to fix. We also check in copy_pte_range and in mprotect_pte_range() for migration ptes. We check for migration ptes in do_swap_cache and call a function that will then wait on the page lock. This allows us to effectively stop all accesses to apge. Migration entries are created by try_to_unmap if called for migration and removed by local functions in migrate.c From: Hugh Dickins Several times while testing swapless page migration (I've no NUMA, just hacking it up to migrate recklessly while running load), I've hit the BUG_ON(!PageLocked(p)) in migration_entry_to_page. This comes from an orphaned migration entry, unrelated to the current correctly locked migration, but hit by remove_anon_migration_ptes as it checks an address in each vma of the anon_vma list. Such an orphan may be left behind if an earlier migration raced with fork: copy_one_pte can duplicate a migration entry from parent to child, after remove_anon_migration_ptes has checked the child vma, but before it has removed it from the parent vma. (If the process were later to fault on this orphaned entry, it would hit the same BUG from migration_entry_wait.) This could be fixed by locking anon_vma in copy_one_pte, but we'd rather not. There's no such problem with file pages, because vma_prio_tree_add adds child vma after parent vma, and the page table locking at each end is enough to serialize. Follow that example with anon_vma: add new vmas to the tail instead of the head. (There's no corresponding problem when inserting migration entries, because a missed pte will leave the page count and mapcount high, which is allowed for. And there's no corresponding problem when migrating via swap, because a leftover swap entry will be correctly faulted. But the swapless method has no refcounting of its entries.) From: Ingo Molnar pte_unmap_unlock() takes the pte pointer as an argument. From: Hugh Dickins Several times while testing swapless page migration, gcc has tried to exec a pointer instead of a string: smells like COW mappings are not being properly write-protected on fork. The protection in copy_one_pte looks very convincing, until at last you realize that the second arg to make_migration_entry is a boolean "write", and SWP_MIGRATION_READ is 30. Anyway, it's better done like in change_pte_range, using is_write_migration_entry and make_migration_entry_read. From: Hugh Dickins Remove unnecessary obfuscation from sys_swapon's range check on swap type, which blew up causing memory corruption once swapless migration made MAX_SWAPFILES no longer 2 ^ MAX_SWAPFILES_SHIFT. Signed-off-by: Hugh Dickins Acked-by: Martin Schwidefsky Signed-off-by: Hugh Dickins Signed-off-by: Christoph Lameter Signed-off-by: Ingo Molnar From: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/swap.h | 7 +++++++ include/linux/swapops.h | 53 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) (limited to 'include/linux') diff --git a/include/linux/swap.h b/include/linux/swap.h index cd28ad206dae..7cee73ef4f15 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -28,7 +28,14 @@ static inline int current_is_kswapd(void) * the type/offset into the pte as 5/27 as well. */ #define MAX_SWAPFILES_SHIFT 5 +#ifndef CONFIG_MIGRATION #define MAX_SWAPFILES (1 << MAX_SWAPFILES_SHIFT) +#else +/* Use last two entries for page migration swap entries */ +#define MAX_SWAPFILES ((1 << MAX_SWAPFILES_SHIFT)-2) +#define SWP_MIGRATION_READ MAX_SWAPFILES +#define SWP_MIGRATION_WRITE (MAX_SWAPFILES + 1) +#endif /* * Magic header for a swap area. The first part of the union is diff --git a/include/linux/swapops.h b/include/linux/swapops.h index 87b9d14c710d..ec639aa3a1d3 100644 --- a/include/linux/swapops.h +++ b/include/linux/swapops.h @@ -67,3 +67,56 @@ static inline pte_t swp_entry_to_pte(swp_entry_t entry) BUG_ON(pte_file(__swp_entry_to_pte(arch_entry))); return __swp_entry_to_pte(arch_entry); } + +#ifdef CONFIG_MIGRATION +static inline swp_entry_t make_migration_entry(struct page *page, int write) +{ + BUG_ON(!PageLocked(page)); + return swp_entry(write ? SWP_MIGRATION_WRITE : SWP_MIGRATION_READ, + page_to_pfn(page)); +} + +static inline int is_migration_entry(swp_entry_t entry) +{ + return unlikely(swp_type(entry) == SWP_MIGRATION_READ || + swp_type(entry) == SWP_MIGRATION_WRITE); +} + +static inline int is_write_migration_entry(swp_entry_t entry) +{ + return unlikely(swp_type(entry) == SWP_MIGRATION_WRITE); +} + +static inline struct page *migration_entry_to_page(swp_entry_t entry) +{ + struct page *p = pfn_to_page(swp_offset(entry)); + /* + * Any use of migration entries may only occur while the + * corresponding page is locked + */ + BUG_ON(!PageLocked(p)); + return p; +} + +static inline void make_migration_entry_read(swp_entry_t *entry) +{ + *entry = swp_entry(SWP_MIGRATION_READ, swp_offset(*entry)); +} + +extern void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd, + unsigned long address); +#else + +#define make_migration_entry(page, write) swp_entry(0, 0) +#define is_migration_entry(swp) 0 +#define migration_entry_to_page(swp) NULL +static inline void make_migration_entry_read(swp_entry_t *entryp) { } +static inline void migration_entry_wait(struct mm_struct *mm, pmd_t *pmd, + unsigned long address) { } +static inline int is_write_migration_entry(swp_entry_t entry) +{ + return 0; +} + +#endif + -- cgit v1.2.3 From d75a0fcda2cfc71b50e16dc89e0c32c57d427e85 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Fri, 23 Jun 2006 02:03:36 -0700 Subject: [PATCH] Swapless page migration: rip out swap based logic Rip the page migration logic out. Remove all code that has to do with swapping during page migration. This also guts the ability to migrate pages to swap. No one used that so lets let it go for good. Page migration should be a bit broken after this patch. Signed-off-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/rmap.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/rmap.h b/include/linux/rmap.h index 2d4c81a220db..bf97b0900014 100644 --- a/include/linux/rmap.h +++ b/include/linux/rmap.h @@ -91,7 +91,6 @@ static inline void page_dup_rmap(struct page *page) */ int page_referenced(struct page *, int is_locked); int try_to_unmap(struct page *, int ignore_refs); -void remove_from_swap(struct page *page); /* * Called from mm/filemap_xip.c to unmap empty zero page -- cgit v1.2.3 From 04e62a29bf157ce1edd168f2b71b533c80d13628 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Fri, 23 Jun 2006 02:03:38 -0700 Subject: [PATCH] More page migration: use migration entries for file pages This implements the use of migration entries to preserve ptes of file backed pages during migration. Processes can therefore be migrated back and forth without loosing their connection to pagecache pages. Note that we implement the migration entries only for linear mappings. Nonlinear mappings still require the unmapping of the ptes for migration. And another writepage() ugliness shows up. writepage() can drop the page lock. Therefore we have to remove migration ptes before calling writepages() in order to avoid having migration entries point to unlocked pages. Signed-off-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/swap.h | 15 --------------- 1 file changed, 15 deletions(-) (limited to 'include/linux') diff --git a/include/linux/swap.h b/include/linux/swap.h index 7cee73ef4f15..1cf234e8df55 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -186,20 +186,6 @@ extern unsigned long shrink_all_memory(unsigned long nr_pages); extern int vm_swappiness; extern int remove_mapping(struct address_space *mapping, struct page *page); -/* possible outcome of pageout() */ -typedef enum { - /* failed to write page out, page is locked */ - PAGE_KEEP, - /* move page to the active list, page is locked */ - PAGE_ACTIVATE, - /* page has been sent to the disk successfully, page is unlocked */ - PAGE_SUCCESS, - /* page is clean and locked */ - PAGE_CLEAN, -} pageout_t; - -extern pageout_t pageout(struct page *page, struct address_space *mapping); - #ifdef CONFIG_NUMA extern int zone_reclaim_mode; extern int zone_reclaim_interval; @@ -259,7 +245,6 @@ extern int remove_exclusive_swap_page(struct page *); struct backing_dev_info; extern spinlock_t swap_lock; -extern int remove_vma_swap(struct vm_area_struct *vma, struct page *page); /* linux/mm/thrash.c */ extern struct mm_struct * swap_token_mm; -- cgit v1.2.3 From 30c253e6da655d73eb8bfe2adca9b8f4d82fb81e Mon Sep 17 00:00:00 2001 From: Andy Whitcroft Date: Fri, 23 Jun 2006 02:03:41 -0700 Subject: [PATCH] sparsemem: record nid during memory present Record the node id as we mark sections for instantiation. Use this nid during instantiation to direct allocations. Signed-off-by: Andy Whitcroft Cc: Mike Kravetz Cc: Dave Hansen Cc: Mel Gorman Cc: Bob Picco Cc: Jack Steiner Cc: Yasunori Goto Cc: Martin Bligh Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mmzone.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h index e82fc1a52cd0..d6120fa69116 100644 --- a/include/linux/mmzone.h +++ b/include/linux/mmzone.h @@ -509,6 +509,10 @@ struct mem_section { * pages. However, it is stored with some other magic. * (see sparse.c::sparse_init_one_section()) * + * Additionally during early boot we encode node id of + * the location of the section here to guide allocation. + * (see sparse.c::memory_present()) + * * Making it a UL at least makes someone do a cast * before using it wrong. */ @@ -548,6 +552,7 @@ extern int __section_nr(struct mem_section* ms); #define SECTION_HAS_MEM_MAP (1UL<<1) #define SECTION_MAP_LAST_BIT (1UL<<2) #define SECTION_MAP_MASK (~(SECTION_MAP_LAST_BIT-1)) +#define SECTION_NID_SHIFT 2 static inline struct page *__section_mem_map_addr(struct mem_section *section) { -- cgit v1.2.3 From bd96b9eb7cfd6ab24ba244360a09980a720874d2 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Fri, 23 Jun 2006 02:03:42 -0700 Subject: [PATCH] mm: fix swap unused warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If CONFIG_SWAP is not defined we get: mm/vmscan.c: In function ‘remove_mapping’: mm/vmscan.c:387: warning: unused variable ‘swap’ Convert defines in swap.h into blank inline functions to fix this warning and be consistent. Signed-off-by: Con Kolivas Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/swap.h | 64 +++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 53 insertions(+), 11 deletions(-) (limited to 'include/linux') diff --git a/include/linux/swap.h b/include/linux/swap.h index 1cf234e8df55..f1a827a972e0 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -282,18 +282,60 @@ static inline void disable_swap_token(void) #define free_pages_and_swap_cache(pages, nr) \ release_pages((pages), (nr), 0); -#define show_swap_cache_info() /*NOTHING*/ -#define free_swap_and_cache(swp) /*NOTHING*/ -#define swap_duplicate(swp) /*NOTHING*/ -#define swap_free(swp) /*NOTHING*/ -#define read_swap_cache_async(swp,vma,addr) NULL -#define lookup_swap_cache(swp) NULL -#define valid_swaphandles(swp, off) 0 +static inline void show_swap_cache_info(void) +{ +} + +static inline void free_swap_and_cache(swp_entry_t swp) +{ +} + +static inline int swap_duplicate(swp_entry_t swp) +{ + return 0; +} + +static inline void swap_free(swp_entry_t swp) +{ +} + +static inline struct page *read_swap_cache_async(swp_entry_t swp, + struct vm_area_struct *vma, unsigned long addr) +{ + return NULL; +} + +static inline struct page *lookup_swap_cache(swp_entry_t swp) +{ + return NULL; +} + +static inline int valid_swaphandles(swp_entry_t entry, unsigned long *offset) +{ + return 0; +} + #define can_share_swap_page(p) (page_mapcount(p) == 1) -#define move_to_swap_cache(p, swp) 1 -#define move_from_swap_cache(p, i, m) 1 -#define __delete_from_swap_cache(p) /*NOTHING*/ -#define delete_from_swap_cache(p) /*NOTHING*/ + +static inline int move_to_swap_cache(struct page *page, swp_entry_t entry) +{ + return 1; +} + +static inline int move_from_swap_cache(struct page *page, unsigned long index, + struct address_space *mapping) +{ + return 1; +} + +static inline void __delete_from_swap_cache(struct page *page) +{ +} + +static inline void delete_from_swap_cache(struct page *page) +{ +} + #define swap_token_default_timeout 0 static inline int remove_exclusive_swap_page(struct page *p) -- cgit v1.2.3 From 9637a5efd4fbe36164c5ce7f6a0ee68b2bf22b7f Mon Sep 17 00:00:00 2001 From: David Howells Date: Fri, 23 Jun 2006 02:03:43 -0700 Subject: [PATCH] add page_mkwrite() vm_operations method Add a new VMA operation to notify a filesystem or other driver about the MMU generating a fault because userspace attempted to write to a page mapped through a read-only PTE. This facility permits the filesystem or driver to: (*) Implement storage allocation/reservation on attempted write, and so to deal with problems such as ENOSPC more gracefully (perhaps by generating SIGBUS). (*) Delay making the page writable until the contents have been written to a backing cache. This is useful for NFS/AFS when using FS-Cache/CacheFS. It permits the filesystem to have some guarantee about the state of the cache. (*) Account and limit number of dirty pages. This is one piece of the puzzle needed to make shared writable mapping work safely in FUSE. Needed by cachefs (Or is it cachefiles? Or fscache? ). At least four other groups have stated an interest in it or a desire to use the functionality it provides: FUSE, OCFS2, NTFS and JFFS2. Also, things like EXT3 really ought to use it to deal with the case of shared-writable mmap encountering ENOSPC before we permit the page to be dirtied. From: Peter Zijlstra get_user_pages(.write=1, .force=1) can generate COW hits on read-only shared mappings, this patch traps those as mkpage_write candidates and fails to handle them the old way. Signed-off-by: David Howells Cc: Miklos Szeredi Cc: Joel Becker Cc: Mark Fasheh Cc: Anton Altaparmakov Cc: David Woodhouse Cc: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/mm.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/mm.h b/include/linux/mm.h index 697c6bf248c2..3b09444121d9 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -199,6 +199,10 @@ struct vm_operations_struct { void (*close)(struct vm_area_struct * area); struct page * (*nopage)(struct vm_area_struct * area, unsigned long address, int *type); int (*populate)(struct vm_area_struct * area, unsigned long address, unsigned long len, pgprot_t prot, unsigned long pgoff, int nonblock); + + /* notification that a previously read-only page is about to become + * writable, if an error is returned it will cause a SIGBUS */ + int (*page_mkwrite)(struct vm_area_struct *vma, struct page *page); #ifdef CONFIG_NUMA int (*set_policy)(struct vm_area_struct *vma, struct mempolicy *new); struct mempolicy *(*get_policy)(struct vm_area_struct *vma, -- cgit v1.2.3 From bd1e22b8e0a90f9a91e4c27db14ca15773659bf7 Mon Sep 17 00:00:00 2001 From: Andrew Morton Date: Fri, 23 Jun 2006 02:03:47 -0700 Subject: [PATCH] initialise total_memory() earlier Initialise total_memory earlier in boot. Because if for some reason we run page reclaim early in boot, we don't want total_memory to be zero when we use it as a divisor. And rename total_memory to vm_total_pages to avoid naming clashes with architectures. Cc: Yasunori Goto Cc: KAMEZAWA Hiroyuki Cc: Martin Bligh Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/swap.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/swap.h b/include/linux/swap.h index f1a827a972e0..dc3f3aa0c83e 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -185,6 +185,7 @@ extern unsigned long try_to_free_pages(struct zone **, gfp_t); extern unsigned long shrink_all_memory(unsigned long nr_pages); extern int vm_swappiness; extern int remove_mapping(struct address_space *mapping, struct page *page); +extern long vm_total_pages; #ifdef CONFIG_NUMA extern int zone_reclaim_mode; -- cgit v1.2.3 From 800590f523bf3bde9fa6c8e4d6763e4bf6a2c8ec Mon Sep 17 00:00:00 2001 From: Paul Drynoff Date: Fri, 23 Jun 2006 02:03:48 -0700 Subject: [PATCH] slab: kmalloc, kzalloc comments cleanup and fix - Move comments for kmalloc to right place, currently it near __do_kmalloc - Comments for kzalloc - More detailed comments for kmalloc - Appearance of "kmalloc" and "kzalloc" man pages after "make mandocs" [rdunlap@xenotime.net: simplification] Signed-off-by: Paul Drynoff Acked-by: Randy Dunlap Cc: Pekka Enberg Cc: Manfred Spraul Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/slab.h | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'include/linux') diff --git a/include/linux/slab.h b/include/linux/slab.h index 9dc93163e065..45ad55b70d1c 100644 --- a/include/linux/slab.h +++ b/include/linux/slab.h @@ -86,6 +86,51 @@ extern void *__kmalloc_track_caller(size_t, gfp_t, void*); __kmalloc_track_caller(size, flags, __builtin_return_address(0)) #endif +/** + * kmalloc - allocate memory + * @size: how many bytes of memory are required. + * @flags: the type of memory to allocate. + * + * kmalloc is the normal method of allocating memory + * in the kernel. + * + * The @flags argument may be one of: + * + * %GFP_USER - Allocate memory on behalf of user. May sleep. + * + * %GFP_KERNEL - Allocate normal kernel ram. May sleep. + * + * %GFP_ATOMIC - Allocation will not sleep. + * For example, use this inside interrupt handlers. + * + * %GFP_HIGHUSER - Allocate pages from high memory. + * + * %GFP_NOIO - Do not do any I/O at all while trying to get memory. + * + * %GFP_NOFS - Do not make any fs calls while trying to get memory. + * + * Also it is possible to set different flags by OR'ing + * in one or more of the following additional @flags: + * + * %__GFP_COLD - Request cache-cold pages instead of + * trying to return cache-warm pages. + * + * %__GFP_DMA - Request memory from the DMA-capable zone. + * + * %__GFP_HIGH - This allocation has high priority and may use emergency pools. + * + * %__GFP_HIGHMEM - Allocated memory may be from highmem. + * + * %__GFP_NOFAIL - Indicate that this allocation is in no way allowed to fail + * (think twice before using). + * + * %__GFP_NORETRY - If memory is not immediately available, + * then give up at once. + * + * %__GFP_NOWARN - If allocation fails, don't issue any warnings. + * + * %__GFP_REPEAT - If allocation fails initially, try once more before failing. + */ static inline void *kmalloc(size_t size, gfp_t flags) { if (__builtin_constant_p(size)) { @@ -111,6 +156,11 @@ found: extern void *__kzalloc(size_t, gfp_t); +/** + * kzalloc - allocate memory. The memory is set to zero. + * @size: how many bytes of memory are required. + * @flags: the type of memory to allocate (see kmalloc). + */ static inline void *kzalloc(size_t size, gfp_t flags) { if (__builtin_constant_p(size)) { -- cgit v1.2.3 From aaa994b300a172afafab47938804836b923e5ef7 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Fri, 23 Jun 2006 02:03:52 -0700 Subject: [PATCH] page migration: handle freeing of pages in migrate_pages() Do not leave pages on the lists passed to migrate_pages(). Seems that we will not need any postprocessing of pages. This will simplify the handling of pages by the callers of migrate_pages(). Signed-off-by: Christoph Lameter Cc: Hugh Dickins Cc: Jes Sorensen Cc: KAMEZAWA Hiroyuki Cc: Lee Schermerhorn Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/migrate.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'include/linux') diff --git a/include/linux/migrate.h b/include/linux/migrate.h index 287c47b5e5df..83af25949fa9 100644 --- a/include/linux/migrate.h +++ b/include/linux/migrate.h @@ -8,8 +8,7 @@ extern int isolate_lru_page(struct page *p, struct list_head *pagelist); extern int putback_lru_pages(struct list_head *l); extern int migrate_page(struct address_space *, struct page *, struct page *); -extern int migrate_pages(struct list_head *l, struct list_head *t, - struct list_head *moved, struct list_head *failed); +extern int migrate_pages(struct list_head *l, struct list_head *t); extern int migrate_pages_to(struct list_head *pagelist, struct vm_area_struct *vma, int dest); extern int fail_migrate_page(struct address_space *, @@ -22,8 +21,8 @@ extern int migrate_prep(void); static inline int isolate_lru_page(struct page *p, struct list_head *list) { return -ENOSYS; } static inline int putback_lru_pages(struct list_head *l) { return 0; } -static inline int migrate_pages(struct list_head *l, struct list_head *t, - struct list_head *moved, struct list_head *failed) { return -ENOSYS; } +static inline int migrate_pages(struct list_head *l, struct list_head *t) + { return -ENOSYS; } static inline int migrate_pages_to(struct list_head *pagelist, struct vm_area_struct *vma, int dest) { return 0; } -- cgit v1.2.3 From 95a402c3847cc16f4ba03013cd01404fa0f14c2e Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Fri, 23 Jun 2006 02:03:53 -0700 Subject: [PATCH] page migration: use allocator function for migrate_pages() Instead of passing a list of new pages, pass a function to allocate a new page. This allows the correct placement of MPOL_INTERLEAVE pages during page migration. It also further simplifies the callers of migrate pages. migrate_pages() becomes similar to migrate_pages_to() so drop migrate_pages_to(). The batching of new page allocations becomes unnecessary. Signed-off-by: Christoph Lameter Cc: Hugh Dickins Cc: Jes Sorensen Cc: KAMEZAWA Hiroyuki Cc: Lee Schermerhorn Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/migrate.h | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/migrate.h b/include/linux/migrate.h index 83af25949fa9..5b95d6568dc4 100644 --- a/include/linux/migrate.h +++ b/include/linux/migrate.h @@ -3,14 +3,15 @@ #include +typedef struct page *new_page_t(struct page *, unsigned long private); + #ifdef CONFIG_MIGRATION extern int isolate_lru_page(struct page *p, struct list_head *pagelist); extern int putback_lru_pages(struct list_head *l); extern int migrate_page(struct address_space *, struct page *, struct page *); -extern int migrate_pages(struct list_head *l, struct list_head *t); -extern int migrate_pages_to(struct list_head *pagelist, - struct vm_area_struct *vma, int dest); +extern int migrate_pages(struct list_head *l, new_page_t x, unsigned long); + extern int fail_migrate_page(struct address_space *, struct page *, struct page *); @@ -21,8 +22,8 @@ extern int migrate_prep(void); static inline int isolate_lru_page(struct page *p, struct list_head *list) { return -ENOSYS; } static inline int putback_lru_pages(struct list_head *l) { return 0; } -static inline int migrate_pages(struct list_head *l, struct list_head *t) - { return -ENOSYS; } +static inline int migrate_pages(struct list_head *l, new_page_t x, + unsigned long private) { return -ENOSYS; } static inline int migrate_pages_to(struct list_head *pagelist, struct vm_area_struct *vma, int dest) { return 0; } -- cgit v1.2.3 From 742755a1d8ce2b548428f7aacf1758b4bba50080 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Fri, 23 Jun 2006 02:03:55 -0700 Subject: [PATCH] page migration: sys_move_pages(): support moving of individual pages move_pages() is used to move individual pages of a process. The function can be used to determine the location of pages and to move them onto the desired node. move_pages() returns status information for each page. long move_pages(pid, number_of_pages_to_move, addresses_of_pages[], nodes[] or NULL, status[], flags); The addresses of pages is an array of void * pointing to the pages to be moved. The nodes array contains the node numbers that the pages should be moved to. If a NULL is passed instead of an array then no pages are moved but the status array is updated. The status request may be used to determine the page state before issuing another move_pages() to move pages. The status array will contain the state of all individual page migration attempts when the function terminates. The status array is only valid if move_pages() completed successfullly. Possible page states in status[]: 0..MAX_NUMNODES The page is now on the indicated node. -ENOENT Page is not present -EACCES Page is mapped by multiple processes and can only be moved if MPOL_MF_MOVE_ALL is specified. -EPERM The page has been mlocked by a process/driver and cannot be moved. -EBUSY Page is busy and cannot be moved. Try again later. -EFAULT Invalid address (no VMA or zero page). -ENOMEM Unable to allocate memory on target node. -EIO Unable to write back page. The page must be written back in order to move it since the page is dirty and the filesystem does not provide a migration function that would allow the moving of dirty pages. -EINVAL A dirty page cannot be moved. The filesystem does not provide a migration function and has no ability to write back pages. The flags parameter indicates what types of pages to move: MPOL_MF_MOVE Move pages that are only mapped by the process. MPOL_MF_MOVE_ALL Also move pages that are mapped by multiple processes. Requires sufficient capabilities. Possible return codes from move_pages() -ENOENT No pages found that would require moving. All pages are either already on the target node, not present, had an invalid address or could not be moved because they were mapped by multiple processes. -EINVAL Flags other than MPOL_MF_MOVE(_ALL) specified or an attempt to migrate pages in a kernel thread. -EPERM MPOL_MF_MOVE_ALL specified without sufficient priviledges. or an attempt to move a process belonging to another user. -EACCES One of the target nodes is not allowed by the current cpuset. -ENODEV One of the target nodes is not online. -ESRCH Process does not exist. -E2BIG Too many pages to move. -ENOMEM Not enough memory to allocate control array. -EFAULT Parameters could not be accessed. A test program for move_pages() may be found with the patches on ftp.kernel.org:/pub/linux/kernel/people/christoph/pmig/patches-2.6.17-rc4-mm3 From: Christoph Lameter Detailed results for sys_move_pages() Pass a pointer to an integer to get_new_page() that may be used to indicate where the completion status of a migration operation should be placed. This allows sys_move_pags() to report back exactly what happened to each page. Wish there would be a better way to do this. Looks a bit hacky. Signed-off-by: Christoph Lameter Cc: Hugh Dickins Cc: Jes Sorensen Cc: KAMEZAWA Hiroyuki Cc: Lee Schermerhorn Cc: Andi Kleen Cc: Michael Kerrisk Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/migrate.h | 2 +- include/linux/syscalls.h | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/migrate.h b/include/linux/migrate.h index 5b95d6568dc4..5dba23a1c0d0 100644 --- a/include/linux/migrate.h +++ b/include/linux/migrate.h @@ -3,7 +3,7 @@ #include -typedef struct page *new_page_t(struct page *, unsigned long private); +typedef struct page *new_page_t(struct page *, unsigned long private, int **); #ifdef CONFIG_MIGRATION extern int isolate_lru_page(struct page *p, struct list_head *pagelist); diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index bd67a4413df7..7e3f23490918 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -516,6 +516,11 @@ asmlinkage long sys_set_mempolicy(int mode, unsigned long __user *nmask, asmlinkage long sys_migrate_pages(pid_t pid, unsigned long maxnode, const unsigned long __user *from, const unsigned long __user *to); +asmlinkage long sys_move_pages(pid_t pid, unsigned long nr_pages, + const void __user * __user *pages, + const int __user *nodes, + int __user *status, + int flags); asmlinkage long sys_mbind(unsigned long start, unsigned long len, unsigned long mode, unsigned long __user *nmask, -- cgit v1.2.3 From 1b2db9fb7adc4d67d9ce7d16ce79c41ee84730fe Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Fri, 23 Jun 2006 02:03:56 -0700 Subject: [PATCH] sys_move_pages: 32bit support (i386, x86_64) sys_move_pages() support for 32bit (i386 plus x86_64 compat layer) Add support for move_pages() on i386 and also add the compat functions necessary to run 32 bit binaries on x86_64. Add compat_sys_move_pages to the x86_64 32bit binary layer. Note that it is not up to date so I added the missing pieces. Not sure if this is done the right way. [akpm@osdl.org: compile fix] Signed-off-by: Christoph Lameter Cc: Andi Kleen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/syscalls.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index 7e3f23490918..e42738c69166 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -521,6 +521,11 @@ asmlinkage long sys_move_pages(pid_t pid, unsigned long nr_pages, const int __user *nodes, int __user *status, int flags); +asmlinkage long compat_sys_move_pages(pid_t pid, unsigned long nr_page, + void __user *pages, + const int __user *nodes, + int __user *status, + int flags); asmlinkage long sys_mbind(unsigned long start, unsigned long len, unsigned long mode, unsigned long __user *nmask, -- cgit v1.2.3 From 9216dfad4fc97ab639ef0885efc713f3d7a20d5b Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Fri, 23 Jun 2006 02:03:57 -0700 Subject: [PATCH] move_pages: fix 32 -> 64 bit compat function The definition of the third parameter is a pointer to an array of virtual addresses which give us some trouble. The existing code calculated the wrong address in the array since I used void to avoid having to specify a type. I now use the correct type "compat_uptr_t __user *" in the definition of the function in kernel/compat.c. However, I used __u32 in syscalls.h. Would have to include compat.h there in order to provide the same definition which would generate an ugly include situation. On both ia64 and x86_64 compat_uptr_t is u32. So this works although parameter declarations differ. Signed-off-by: Christoph Lameter Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/syscalls.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index e42738c69166..33785b79d548 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h @@ -522,7 +522,7 @@ asmlinkage long sys_move_pages(pid_t pid, unsigned long nr_pages, int __user *status, int flags); asmlinkage long compat_sys_move_pages(pid_t pid, unsigned long nr_page, - void __user *pages, + __u32 __user *pages, const int __user *nodes, int __user *status, int flags); -- cgit v1.2.3 From 03e68060636e05989ea94bcb671ab633948f328c Mon Sep 17 00:00:00 2001 From: James Morris Date: Fri, 23 Jun 2006 02:03:58 -0700 Subject: [PATCH] lsm: add task_setioprio hook Implement an LSM hook for setting a task's IO priority, similar to the hook for setting a tasks's nice value. A previous version of this LSM hook was included in an older version of multiadm by Jan Engelhardt, although I don't recall it being submitted upstream. Also included is the corresponding SELinux hook, which re-uses the setsched permission in the proccess class. Signed-off-by: James Morris Acked-by: Stephen Smalley Cc: Jan Engelhardt Cc: Chris Wright Cc: Jens Axboe Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/security.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'include/linux') diff --git a/include/linux/security.h b/include/linux/security.h index 383c320fc834..65b32a0c6207 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -577,6 +577,11 @@ struct swap_info_struct; * @p contains the task_struct of process. * @nice contains the new nice value. * Return 0 if permission is granted. + * @task_setioprio + * Check permission before setting the ioprio value of @p to @ioprio. + * @p contains the task_struct of process. + * @ioprio contains the new ioprio value + * Return 0 if permission is granted. * @task_setrlimit: * Check permission before setting the resource limits of the current * process for @resource to @new_rlim. The old resource limit values can @@ -1210,6 +1215,7 @@ struct security_operations { int (*task_getsid) (struct task_struct * p); int (*task_setgroups) (struct group_info *group_info); int (*task_setnice) (struct task_struct * p, int nice); + int (*task_setioprio) (struct task_struct * p, int ioprio); int (*task_setrlimit) (unsigned int resource, struct rlimit * new_rlim); int (*task_setscheduler) (struct task_struct * p, int policy, struct sched_param * lp); @@ -1836,6 +1842,11 @@ static inline int security_task_setnice (struct task_struct *p, int nice) return security_ops->task_setnice (p, nice); } +static inline int security_task_setioprio (struct task_struct *p, int ioprio) +{ + return security_ops->task_setioprio (p, ioprio); +} + static inline int security_task_setrlimit (unsigned int resource, struct rlimit *new_rlim) { @@ -2478,6 +2489,11 @@ static inline int security_task_setnice (struct task_struct *p, int nice) return 0; } +static inline int security_task_setioprio (struct task_struct *p, int ioprio) +{ + return 0; +} + static inline int security_task_setrlimit (unsigned int resource, struct rlimit *new_rlim) { -- cgit v1.2.3 From 35601547baf92d984b6e59cf3583649da04baea5 Mon Sep 17 00:00:00 2001 From: David Quigley Date: Fri, 23 Jun 2006 02:04:01 -0700 Subject: [PATCH] SELinux: add task_movememory hook This patch adds new security hook, task_movememory, to be called when memory owened by a task is to be moved (e.g. when migrating pages to a this hook is identical to the setscheduler implementation, but a separate hook introduced to allow this check to be specialized in the future if necessary. Since the last posting, the hook has been renamed following feedback from Christoph Lameter. Signed-off-by: David Quigley Acked-by: Stephen Smalley Signed-off-by: James Morris Cc: Christoph Lameter Cc: Andi Kleen Acked-by: Chris Wright Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/security.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'include/linux') diff --git a/include/linux/security.h b/include/linux/security.h index 65b32a0c6207..d2c17bd91a29 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -601,6 +601,10 @@ struct swap_info_struct; * @p. * @p contains the task_struct for process. * Return 0 if permission is granted. + * @task_movememory + * Check permission before moving memory owned by process @p. + * @p contains the task_struct for process. + * Return 0 if permission is granted. * @task_kill: * Check permission before sending signal @sig to @p. @info can be NULL, * the constant 1, or a pointer to a siginfo structure. If @info is 1 or @@ -1220,6 +1224,7 @@ struct security_operations { int (*task_setscheduler) (struct task_struct * p, int policy, struct sched_param * lp); int (*task_getscheduler) (struct task_struct * p); + int (*task_movememory) (struct task_struct * p); int (*task_kill) (struct task_struct * p, struct siginfo * info, int sig); int (*task_wait) (struct task_struct * p); @@ -1865,6 +1870,11 @@ static inline int security_task_getscheduler (struct task_struct *p) return security_ops->task_getscheduler (p); } +static inline int security_task_movememory (struct task_struct *p) +{ + return security_ops->task_movememory (p); +} + static inline int security_task_kill (struct task_struct *p, struct siginfo *info, int sig) { @@ -2512,6 +2522,11 @@ static inline int security_task_getscheduler (struct task_struct *p) return 0; } +static inline int security_task_movememory (struct task_struct *p) +{ + return 0; +} + static inline int security_task_kill (struct task_struct *p, struct siginfo *info, int sig) { -- cgit v1.2.3 From c22ce143d15eb288543fe9873e1c5ac1c01b69a1 Mon Sep 17 00:00:00 2001 From: Hiro Yoshioka Date: Fri, 23 Jun 2006 02:04:16 -0700 Subject: [PATCH] x86: cache pollution aware __copy_from_user_ll() Use the x86 cache-bypassing copy instructions for copy_from_user(). Some performance data are Total of GLOBAL_POWER_EVENTS (CPU cycle samples) 2.6.12.4.orig 1921587 2.6.12.4.nt 1599424 1599424/1921587=83.23% (16.77% reduction) BSQ_CACHE_REFERENCE (L3 cache miss) 2.6.12.4.orig 57427 2.6.12.4.nt 20858 20858/57427=36.32% (63.7% reduction) L3 cache miss reduction of __copy_from_user_ll samples % 37408 65.1412 vmlinux __copy_from_user_ll 23 0.1103 vmlinux __copy_user_zeroing_intel_nocache 23/37408=0.061% (99.94% reduction) Top 5 of 2.6.12.4.nt Counted GLOBAL_POWER_EVENTS events (time during which processor is not stopped) with a unit mask of 0x01 (mandatory) count 100000 samples % app name symbol name 128392 8.0274 vmlinux __copy_user_zeroing_intel_nocache 64206 4.0143 vmlinux journal_add_journal_head 59746 3.7355 vmlinux do_get_write_access 47674 2.9807 vmlinux journal_put_journal_head 46021 2.8774 vmlinux journal_dirty_metadata pattern9-0-cpu4-0-09011728/summary.out Counted BSQ_CACHE_REFERENCE events (cache references seen by the bus unit) with a unit mask of 0x3f (multiple flags) count 3000 samples % app name symbol name 69755 4.2861 vmlinux __copy_user_zeroing_intel_nocache 55685 3.4215 vmlinux journal_add_journal_head 52371 3.2179 vmlinux __find_get_block 45504 2.7960 vmlinux journal_put_journal_head 36005 2.2123 vmlinux journal_stop pattern9-0-cpu4-0-09011744/summary.out Counted BSQ_CACHE_REFERENCE events (cache references seen by the bus unit) with a unit mask of 0x200 (read 3rd level cache miss) count 3000 samples % app name symbol name 1147 5.4994 vmlinux journal_add_journal_head 881 4.2240 vmlinux journal_dirty_data 872 4.1809 vmlinux blk_rq_map_sg 734 3.5192 vmlinux journal_commit_transaction 617 2.9582 vmlinux radix_tree_delete pattern9-0-cpu4-0-09011731/summary.out iozone results are original 2.6.12.4 CPU time = 207.768 sec cache aware CPU time = 184.783 sec (three times run) 184.783/207.768=88.94% (11.06% reduction) original: pattern9-0-cpu4-0-08191720/iozone.out: CPU Utilization: Wall time 45.997 CPU time 64.527 CPU utilization 140.28 % pattern9-0-cpu4-0-08191741/iozone.out: CPU Utilization: Wall time 46.878 CPU time 71.933 CPU utilization 153.45 % pattern9-0-cpu4-0-08191743/iozone.out: CPU Utilization: Wall time 45.152 CPU time 71.308 CPU utilization 157.93 % cache awre: pattern9-0-cpu4-0-09011728/iozone.out: CPU Utilization: Wall time 44.842 CPU time 62.465 CPU utilization 139.30 % pattern9-0-cpu4-0-09011731/iozone.out: CPU Utilization: Wall time 44.718 CPU time 59.273 CPU utilization 132.55 % pattern9-0-cpu4-0-09011744/iozone.out: CPU Utilization: Wall time 44.367 CPU time 63.045 CPU utilization 142.10 % Signed-off-by: Hiro Yoshioka Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/uaccess.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 include/linux/uaccess.h (limited to 'include/linux') diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h new file mode 100644 index 000000000000..391e7ed1eb3f --- /dev/null +++ b/include/linux/uaccess.h @@ -0,0 +1,22 @@ +#ifndef __LINUX_UACCESS_H__ +#define __LINUX_UACCESS_H__ + +#include + +#ifndef ARCH_HAS_NOCACHE_UACCESS + +static inline unsigned long __copy_from_user_inatomic_nocache(void *to, + const void __user *from, unsigned long n) +{ + return __copy_from_user_inatomic(to, from, n); +} + +static inline unsigned long __copy_from_user_nocache(void *to, + const void __user *from, unsigned long n) +{ + return __copy_from_user(to, from, n); +} + +#endif /* ARCH_HAS_NOCACHE_UACCESS */ + +#endif /* __LINUX_UACCESS_H__ */ -- cgit v1.2.3 From 1b61b910e99059abdd54c93aa70e84e076e33d16 Mon Sep 17 00:00:00 2001 From: Zhang Yanmin Date: Fri, 23 Jun 2006 02:04:22 -0700 Subject: [PATCH] x86: kernel irq balance doesn't work On i386, kernel irq balance doesn't work. 1) In function do_irq_balance, after kernel finds the min_loaded cpu but before calling set_pending_irq to really pin the selected_irq to the target cpu, kernel does a cpus_and with irq_affinity[selected_irq]. Later on, when the irq is acked, kernel would calls move_native_irq=>desc->handler->set_affinity to change the irq affinity. However, every function pointed by hw_interrupt_type->set_affinity(unsigned int irq, cpumask_t cpumask) always changes irq_affinity[irq] to cpumask. Next time when recalling do_irq_balance, it has to do cpu_ands again with irq_affinity[selected_irq], but irq_affinity[selected_irq] already becomes one cpu selected by the first irq balance. 2) Function balance_irq in file arch/i386/kernel/io_apic.c has the same issue. [akpm@osdl.org: cleanups] Signed-off-by: Zhang Yanmin Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/irq.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'include/linux') diff --git a/include/linux/irq.h b/include/linux/irq.h index 42c9cd562860..e8a07e75e4fb 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -164,6 +164,14 @@ static inline void set_irq_info(int irq, cpumask_t mask) #endif // CONFIG_SMP +#ifdef CONFIG_IRQBALANCE +extern void set_balance_irq_affinity(unsigned int irq, cpumask_t mask); +#else +static inline void set_balance_irq_affinity(unsigned int irq, cpumask_t mask) +{ +} +#endif + extern int no_irq_affinity; extern int noirqdebug_setup(char *str); -- cgit v1.2.3 From ce4ab0012b32c1a4a1d6e934aeb73bf3151c48d9 Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Fri, 23 Jun 2006 02:04:44 -0700 Subject: [PATCH] swsusp: add architecture special saveable pages support 1. Add architecture specific pages save/restore support. Next two patches will use this to save/restore 'ACPI NVS' pages. 2. Allow reserved pages 'nosave'. This could avoid save/restore BIOS reserved pages. Signed-off-by: Shaohua Li Cc: Pavel Machek Cc: "Rafael J. Wysocki" Cc: Nigel Cunningham Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/suspend.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 96e31aa64cc7..e82cb10fb3ea 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -71,6 +71,7 @@ struct saved_context; void __save_processor_state(struct saved_context *ctxt); void __restore_processor_state(struct saved_context *ctxt); unsigned long get_safe_page(gfp_t gfp_mask); +int swsusp_add_arch_pages(unsigned long start, unsigned long end); /* * XXX: We try to keep some more pages free so that I/O operations succeed -- cgit v1.2.3 From 98317f1271e7fd472983b013c76df6cc15fbef22 Mon Sep 17 00:00:00 2001 From: Roman Zippel Date: Fri, 23 Jun 2006 02:04:54 -0700 Subject: [PATCH] m68k: Remove some unused definitions in zorro.h These definitions have long been superseded by asm-offsets.h Signed-off-by: Roman Zippel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/zorro.h | 42 ------------------------------------------ 1 file changed, 42 deletions(-) (limited to 'include/linux') diff --git a/include/linux/zorro.h b/include/linux/zorro.h index 2f135cf6eef1..913bfc226dda 100644 --- a/include/linux/zorro.h +++ b/include/linux/zorro.h @@ -11,8 +11,6 @@ #ifndef _LINUX_ZORRO_H #define _LINUX_ZORRO_H -#ifndef __ASSEMBLY__ - #include @@ -112,45 +110,6 @@ struct ConfigDev { __u32 cd_Unused[4]; /* for whatever the driver wants */ } __attribute__ ((packed)); -#else /* __ASSEMBLY__ */ - -LN_Succ = 0 -LN_Pred = LN_Succ+4 -LN_Type = LN_Pred+4 -LN_Pri = LN_Type+1 -LN_Name = LN_Pri+1 -LN_sizeof = LN_Name+4 - -ER_Type = 0 -ER_Product = ER_Type+1 -ER_Flags = ER_Product+1 -ER_Reserved03 = ER_Flags+1 -ER_Manufacturer = ER_Reserved03+1 -ER_SerialNumber = ER_Manufacturer+2 -ER_InitDiagVec = ER_SerialNumber+4 -ER_Reserved0c = ER_InitDiagVec+2 -ER_Reserved0d = ER_Reserved0c+1 -ER_Reserved0e = ER_Reserved0d+1 -ER_Reserved0f = ER_Reserved0e+1 -ER_sizeof = ER_Reserved0f+1 - -CD_Node = 0 -CD_Flags = CD_Node+LN_sizeof -CD_Pad = CD_Flags+1 -CD_Rom = CD_Pad+1 -CD_BoardAddr = CD_Rom+ER_sizeof -CD_BoardSize = CD_BoardAddr+4 -CD_SlotAddr = CD_BoardSize+4 -CD_SlotSize = CD_SlotAddr+2 -CD_Driver = CD_SlotSize+2 -CD_NextCD = CD_Driver+4 -CD_Unused = CD_NextCD+4 -CD_sizeof = CD_Unused+(4*4) - -#endif /* __ASSEMBLY__ */ - -#ifndef __ASSEMBLY__ - #define ZORRO_NUM_AUTO 16 #ifdef __KERNEL__ @@ -290,7 +249,6 @@ extern DECLARE_BITMAP(zorro_unused_z2ram, 128); #define Z2RAM_CHUNKSHIFT (16) -#endif /* !__ASSEMBLY__ */ #endif /* __KERNEL__ */ #endif /* _LINUX_ZORRO_H */ -- cgit v1.2.3 From c330dda908b5a46469a997eea90b66f2f9f02b34 Mon Sep 17 00:00:00 2001 From: Jeff Moyer Date: Fri, 23 Jun 2006 02:05:07 -0700 Subject: [PATCH] Add a sysfs file to determine if a kexec kernel is loaded Create two files in /sys/kernel, kexec_loaded and kexec_crash_loaded. Each file contains a simple boolean value indicating whether the relevant kernel has been loaded into memory. The motivation for this is geared around support. Signed-off-by: Jeff Moyer Cc: "Eric W. Biederman" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/kexec.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/kexec.h b/include/linux/kexec.h index cfb3410e32b1..6427949ddf99 100644 --- a/include/linux/kexec.h +++ b/include/linux/kexec.h @@ -106,6 +106,7 @@ extern struct page *kimage_alloc_control_pages(struct kimage *image, extern void crash_kexec(struct pt_regs *); int kexec_should_crash(struct task_struct *); extern struct kimage *kexec_image; +extern struct kimage *kexec_crash_image; #define KEXEC_ON_CRASH 0x00000001 #define KEXEC_ARCH_MASK 0xffff0000 -- cgit v1.2.3 From 090d2b185d8680fc26a2eaf4245d4171dcf4baf1 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Fri, 23 Jun 2006 02:05:08 -0700 Subject: [PATCH] read_mapping_page for address space Add read_mapping_page() which is used for callers that pass mapping->a_ops->readpage as the filler for read_cache_page. This removes some duplication from filesystem code. Signed-off-by: Pekka Enberg Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/pagemap.h | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'include/linux') diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h index 7a1af574dedf..1245df7141aa 100644 --- a/include/linux/pagemap.h +++ b/include/linux/pagemap.h @@ -99,6 +99,13 @@ extern struct page * read_cache_page(struct address_space *mapping, extern int read_cache_pages(struct address_space *mapping, struct list_head *pages, filler_t *filler, void *data); +static inline struct page *read_mapping_page(struct address_space *mapping, + unsigned long index, void *data) +{ + filler_t *filler = (filler_t *)mapping->a_ops->readpage; + return read_cache_page(mapping, index, filler, data); +} + int add_to_page_cache(struct page *page, struct address_space *mapping, unsigned long index, gfp_t gfp_mask); int add_to_page_cache_lru(struct page *page, struct address_space *mapping, -- cgit v1.2.3 From 75e1fcc0b18df0a65ab113198e9dc0e98999a08c Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Fri, 23 Jun 2006 02:05:12 -0700 Subject: [PATCH] vfs: add lock owner argument to flush operation Pass the POSIX lock owner ID to the flush operation. This is useful for filesystems which don't want to store any locking state in inode->i_flock but want to handle locking/unlocking POSIX locks internally. FUSE is one such filesystem but I think it possible that some network filesystems would need this also. Also add a flag to indicate that a POSIX locking request was generated by close(), so filesystems using the above feature won't send an extra locking request in this case. Signed-off-by: Miklos Szeredi Cc: Trond Myklebust Cc: Al Viro Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/coda_linux.h | 2 +- include/linux/fs.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/coda_linux.h b/include/linux/coda_linux.h index b3ecf8f71d97..7b5c5df5cb69 100644 --- a/include/linux/coda_linux.h +++ b/include/linux/coda_linux.h @@ -36,7 +36,7 @@ extern const struct file_operations coda_ioctl_operations; /* operations shared over more than one file */ int coda_open(struct inode *i, struct file *f); -int coda_flush(struct file *f); +int coda_flush(struct file *f, fl_owner_t id); int coda_release(struct inode *i, struct file *f); int coda_permission(struct inode *inode, int mask, struct nameidata *nd); int coda_revalidate_inode(struct dentry *); diff --git a/include/linux/fs.h b/include/linux/fs.h index e917403f4d58..56d8bf0d0a77 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -683,6 +683,7 @@ extern spinlock_t files_lock; #define FL_FLOCK 2 #define FL_ACCESS 8 /* not trying to lock, just looking */ #define FL_LEASE 32 /* lease held on this file */ +#define FL_CLOSE 64 /* unlock on close */ #define FL_SLEEP 128 /* A blocking lock */ /* @@ -1025,7 +1026,7 @@ struct file_operations { long (*compat_ioctl) (struct file *, unsigned int, unsigned long); int (*mmap) (struct file *, struct vm_area_struct *); int (*open) (struct inode *, struct file *); - int (*flush) (struct file *); + int (*flush) (struct file *, fl_owner_t id); int (*release) (struct inode *, struct file *); int (*fsync) (struct file *, struct dentry *, int datasync); int (*aio_fsync) (struct kiocb *, int datasync); -- cgit v1.2.3 From b0904e147f7cbe4be3b4dae49ddccd627bb66f16 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 23 Jun 2006 02:05:13 -0700 Subject: [PATCH] fs/locks.c: make posix_locks_deadlock() static We can now make posix_locks_deadlock() static. Signed-off-by: Adrian Bunk Cc: Trond Myklebust Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/fs.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/fs.h b/include/linux/fs.h index 56d8bf0d0a77..dba4cbd157ee 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -776,7 +776,6 @@ extern int posix_lock_file_conf(struct file *, struct file_lock *, struct file_l extern int posix_lock_file(struct file *, struct file_lock *); extern int posix_lock_file_wait(struct file *, struct file_lock *); extern int posix_unblock_lock(struct file *, struct file_lock *); -extern int posix_locks_deadlock(struct file_lock *, struct file_lock *); extern int flock_lock_file_wait(struct file *filp, struct file_lock *fl); extern int __break_lease(struct inode *inode, unsigned int flags); extern void lease_get_mtime(struct inode *, struct timespec *time); -- cgit v1.2.3 From 8d27e9084b372441dc8c9cf361a965ee58032767 Mon Sep 17 00:00:00 2001 From: Xose Vazquez Perez Date: Fri, 23 Jun 2006 02:05:13 -0700 Subject: [PATCH] module.h: updated comments with a new license "Dual MIT/GPL" is also accepted (kernel/module.c), so updated comments. Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/module.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/linux') diff --git a/include/linux/module.h b/include/linux/module.h index c2d89e037af0..2d366098eab5 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -105,6 +105,8 @@ extern struct module __this_module; * "GPL and additional rights" [GNU Public License v2 rights and more] * "Dual BSD/GPL" [GNU Public License v2 * or BSD license choice] + * "Dual MIT/GPL" [GNU Public License v2 + * or MIT license choice] * "Dual MPL/GPL" [GNU Public License v2 * or Mozilla license choice] * -- cgit v1.2.3 From 260ea1013283d8acbb451459ed1ca560c1445c20 Mon Sep 17 00:00:00 2001 From: "Eric W. Biederman" Date: Fri, 23 Jun 2006 02:05:18 -0700 Subject: [PATCH] ptrace: document the locking rules After a lot of reading the code and thinking about how it behaves I have managed to figure out what the current ptrace locking rules are. The current code is in much better that it appears at first glance. The troublesome code paths are actually the code paths that violate the current rules. ptrace uses simple exclusive access as it's locking. You can only touch task->ptrace if the task is stopped and you are the ptracer, or if the task is running and are the task itself. Very simple, very easy to maintain. It just needs to be documented so people know not to touch ptrace from elsewhere. Currently we do have a few pieces of code that are in violation of this rule. Particularly the core dump code, and ptrace_attach. But so far the code looks fixable. Signed-off-by: Eric W. Biederman Cc: Oleg Nesterov Cc: Roland McGrath Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/ptrace.h | 4 ++++ include/linux/sched.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h index 0d36750fc0f1..ee918bc6e18c 100644 --- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h @@ -51,6 +51,10 @@ #ifdef __KERNEL__ /* * Ptrace flags + * + * The owner ship rules for task->ptrace which holds the ptrace + * flags is simple. When a task is running it owns it's task->ptrace + * flags. When the a task is stopped the ptracer owns task->ptrace. */ #define PT_PTRACED 0x00000001 diff --git a/include/linux/sched.h b/include/linux/sched.h index 267f15257040..a9d23c7d1b25 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -1225,7 +1225,7 @@ static inline int thread_group_empty(task_t *p) (thread_group_leader(p) && !thread_group_empty(p)) /* - * Protects ->fs, ->files, ->mm, ->ptrace, ->group_info, ->comm, keyring + * Protects ->fs, ->files, ->mm, ->group_info, ->comm, keyring * subscriptions and synchronises with wait4(). Also used in procfs. Also * pins the final release of task.io_context. Also protects ->cpuset. * -- cgit v1.2.3 From 0216bfcffe424a5473daa4da47440881b36c1f41 Mon Sep 17 00:00:00 2001 From: Mingming Cao Date: Fri, 23 Jun 2006 02:05:41 -0700 Subject: [PATCH] percpu counter data type changes to suppport more than 2**31 ext3 free blocks counter The percpu counter data type are changed in this set of patches to support more users like ext3 who need more than 32 bit to store the free blocks total in the filesystem. - Generic perpcu counters data type changes. The size of the global counter and local counter were explictly specified using s64 and s32. The global counter is changed from long to s64, while the local counter is changed from long to s32, so we could avoid doing 64 bit update in most cases. - Users of the percpu counters are updated to make use of the new percpu_counter_init() routine now taking an additional parameter to allow users to pass the initial value of the global counter. Signed-off-by: Mingming Cao Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/percpu_counter.h | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) (limited to 'include/linux') diff --git a/include/linux/percpu_counter.h b/include/linux/percpu_counter.h index 66b5de404f22..f5aa593ccf32 100644 --- a/include/linux/percpu_counter.h +++ b/include/linux/percpu_counter.h @@ -10,13 +10,14 @@ #include #include #include +#include #ifdef CONFIG_SMP struct percpu_counter { spinlock_t lock; - long count; - long *counters; + s64 count; + s32 *counters; }; #if NR_CPUS >= 16 @@ -25,11 +26,11 @@ struct percpu_counter { #define FBC_BATCH (NR_CPUS*4) #endif -static inline void percpu_counter_init(struct percpu_counter *fbc) +static inline void percpu_counter_init(struct percpu_counter *fbc, s64 amount) { spin_lock_init(&fbc->lock); - fbc->count = 0; - fbc->counters = alloc_percpu(long); + fbc->count = amount; + fbc->counters = alloc_percpu(s32); } static inline void percpu_counter_destroy(struct percpu_counter *fbc) @@ -37,10 +38,10 @@ static inline void percpu_counter_destroy(struct percpu_counter *fbc) free_percpu(fbc->counters); } -void percpu_counter_mod(struct percpu_counter *fbc, long amount); -long percpu_counter_sum(struct percpu_counter *fbc); +void percpu_counter_mod(struct percpu_counter *fbc, s32 amount); +s64 percpu_counter_sum(struct percpu_counter *fbc); -static inline long percpu_counter_read(struct percpu_counter *fbc) +static inline s64 percpu_counter_read(struct percpu_counter *fbc) { return fbc->count; } @@ -48,13 +49,14 @@ static inline long percpu_counter_read(struct percpu_counter *fbc) /* * It is possible for the percpu_counter_read() to return a small negative * number for some counter which should never be negative. + * */ -static inline long percpu_counter_read_positive(struct percpu_counter *fbc) +static inline s64 percpu_counter_read_positive(struct percpu_counter *fbc) { - long ret = fbc->count; + s64 ret = fbc->count; barrier(); /* Prevent reloads of fbc->count */ - if (ret > 0) + if (ret >= 0) return ret; return 1; } @@ -62,12 +64,12 @@ static inline long percpu_counter_read_positive(struct percpu_counter *fbc) #else struct percpu_counter { - long count; + s64 count; }; -static inline void percpu_counter_init(struct percpu_counter *fbc) +static inline void percpu_counter_init(struct percpu_counter *fbc, s64 amount) { - fbc->count = 0; + fbc->count = amount; } static inline void percpu_counter_destroy(struct percpu_counter *fbc) @@ -75,24 +77,24 @@ static inline void percpu_counter_destroy(struct percpu_counter *fbc) } static inline void -percpu_counter_mod(struct percpu_counter *fbc, long amount) +percpu_counter_mod(struct percpu_counter *fbc, s32 amount) { preempt_disable(); fbc->count += amount; preempt_enable(); } -static inline long percpu_counter_read(struct percpu_counter *fbc) +static inline s64 percpu_counter_read(struct percpu_counter *fbc) { return fbc->count; } -static inline long percpu_counter_read_positive(struct percpu_counter *fbc) +static inline s64 percpu_counter_read_positive(struct percpu_counter *fbc) { return fbc->count; } -static inline long percpu_counter_sum(struct percpu_counter *fbc) +static inline s64 percpu_counter_sum(struct percpu_counter *fbc) { return percpu_counter_read_positive(fbc); } -- cgit v1.2.3 From 368a5fa1f28589e6b54588a139ea872d5b4b1914 Mon Sep 17 00:00:00 2001 From: Hua Zhong Date: Fri, 23 Jun 2006 02:05:42 -0700 Subject: [PATCH] remove unlikely() in might_sleep_if() The likely() profiling tools show that __alloc_page() causes a lot of misses: ! 132 119193 __alloc_pages():mm/page_alloc.c@937 Because most __alloc_page() calls are not atomic. Signed-off-by: Hua Zhong Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/kernel.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 25fccd859fbf..8c21aaa248b4 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -78,7 +78,7 @@ extern int cond_resched(void); # define might_sleep() do { might_resched(); } while (0) #endif -#define might_sleep_if(cond) do { if (unlikely(cond)) might_sleep(); } while (0) +#define might_sleep_if(cond) do { if (cond) might_sleep(); } while (0) #define abs(x) ({ \ int __x = (x); \ -- cgit v1.2.3 From 1d31a4ea8cf7a2afc7299d1d3d8732ca54a5934e Mon Sep 17 00:00:00 2001 From: Matt Helsley Date: Fri, 23 Jun 2006 02:05:42 -0700 Subject: [PATCH] Process Events - Header Cleanup Move connector header include to precisely where it's needed. Remove unused time.h header file as well. This was leftover from previous iterations of the process events patches. Signed-off-by: Matt Helsley Cc: Guillaume Thouvenin Cc: Nguyen Anh Quynh Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/cn_proc.h | 2 -- 1 file changed, 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/cn_proc.h b/include/linux/cn_proc.h index 1417de935057..1e3459a14e20 100644 --- a/include/linux/cn_proc.h +++ b/include/linux/cn_proc.h @@ -26,8 +26,6 @@ #define CN_PROC_H #include -#include -#include /* * Userspace sends this enum to register with the kernel that it is listening -- cgit v1.2.3 From 3fa2164d03fb7af17fcfe4f8800dd754fbd99ff7 Mon Sep 17 00:00:00 2001 From: Matt Helsley Date: Fri, 23 Jun 2006 02:05:44 -0700 Subject: [PATCH] Process Events: License Change Change the license on the process event structure passed between kernel and userspace. Signed-off-by: Matt Helsley Acked-by: Guillaume Thouvenin Acked-by: Nguyen Anh Quynh Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/cn_proc.h | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) (limited to 'include/linux') diff --git a/include/linux/cn_proc.h b/include/linux/cn_proc.h index 1e3459a14e20..dbb7769009be 100644 --- a/include/linux/cn_proc.h +++ b/include/linux/cn_proc.h @@ -3,23 +3,16 @@ * * Copyright (C) Matt Helsley, IBM Corp. 2005 * Based on cn_fork.h by Nguyen Anh Quynh and Guillaume Thouvenin - * Original copyright notice follows: * Copyright (C) 2005 Nguyen Anh Quynh * Copyright (C) 2005 Guillaume Thouvenin * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2.1 of the GNU Lesser General Public License + * as published by the Free Software Foundation. * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */ #ifndef CN_PROC_H -- cgit v1.2.3 From 481fad483487ea967fe20bbc9e565d787f7bf20f Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Fri, 23 Jun 2006 02:05:44 -0700 Subject: [PATCH] strstrip() API Add a new strstrip() function to lib/string.c for removing leading and trailing whitespace from a string. Cc: Michael Holzheu Acked-by: Ingo Oeser Acked-by: Joern Engel Cc: Corey Minyard Signed-off-by: Pekka Enberg Acked-by: Michael Holzheu Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/string.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/linux') diff --git a/include/linux/string.h b/include/linux/string.h index c61306da8c52..e4c755860316 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -56,6 +56,7 @@ extern char * strnchr(const char *, size_t, int); #ifndef __HAVE_ARCH_STRRCHR extern char * strrchr(const char *,int); #endif +extern char * strstrip(char *); #ifndef __HAVE_ARCH_STRSTR extern char * strstr(const char *,const char *); #endif -- cgit v1.2.3 From d83015b8f62ee3fcd338f6f009051ed57f77a531 Mon Sep 17 00:00:00 2001 From: "Paul E. McKenney" Date: Fri, 23 Jun 2006 02:05:51 -0700 Subject: [PATCH] Make RCU API inaccessible to non-GPL Linux kernel modules Remove synchronize_kernel() (deprecated 2-APR-2005 in http://lkml.org/lkml/2005/4/3/11) and makes the RCU API inaccessible to non-GPL Linux kernel modules (as was announced more than one year ago in http://lkml.org/lkml/2005/4/3/8). Tested on x86 and ppc64. Signed-off-by: "Paul E. McKenney" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/rcupdate.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'include/linux') diff --git a/include/linux/rcupdate.h b/include/linux/rcupdate.h index 970284f571a6..6312758393b6 100644 --- a/include/linux/rcupdate.h +++ b/include/linux/rcupdate.h @@ -246,7 +246,7 @@ extern int rcu_needs_cpu(int cpu); * softirq handlers will have completed, since in some kernels, these * handlers can run in process context, and can block. * - * This primitive provides the guarantees made by the (deprecated) + * This primitive provides the guarantees made by the (now removed) * synchronize_kernel() API. In contrast, synchronize_rcu() only * guarantees that rcu_read_lock() sections will have completed. * In "classic RCU", these two guarantees happen to be one and @@ -264,7 +264,6 @@ extern void FASTCALL(call_rcu(struct rcu_head *head, void (*func)(struct rcu_head *head))); extern void FASTCALL(call_rcu_bh(struct rcu_head *head, void (*func)(struct rcu_head *head))); -extern __deprecated_for_modules void synchronize_kernel(void); extern void synchronize_rcu(void); void synchronize_idle(void); extern void rcu_barrier(void); -- cgit v1.2.3 From f5befceb5cfecba49fdf61f8e0eb4d453200eac9 Mon Sep 17 00:00:00 2001 From: Brent Casavant Date: Fri, 23 Jun 2006 02:05:52 -0700 Subject: [PATCH] SGI IOC4: Detect IO card variant There are three different IO cards which an SGI IOC4 controller may find itself on. One of these variants does not bring out the IDE and serial signals, so we need to disable attaching the corresponding IOC4 subdrivers to such cards. Cleans up message clutter emitted during device probing. Signed-off-by: Brent Casavant Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/ioc4.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/linux') diff --git a/include/linux/ioc4.h b/include/linux/ioc4.h index 3dd18b785ebd..de73a3289cc2 100644 --- a/include/linux/ioc4.h +++ b/include/linux/ioc4.h @@ -147,6 +147,10 @@ struct ioc4_misc_regs { #define IOC4_GPCR_EDGE_6 0x40 #define IOC4_GPCR_EDGE_7 0x80 +#define IOC4_VARIANT_IO9 0x0900 +#define IOC4_VARIANT_PCI_RT 0x0901 +#define IOC4_VARIANT_IO10 0x1000 + /* One of these per IOC4 */ struct ioc4_driver_data { struct list_head idd_list; @@ -156,6 +160,7 @@ struct ioc4_driver_data { struct __iomem ioc4_misc_regs *idd_misc_regs; unsigned long count_period; void *idd_serial_data; + unsigned int idd_variant; }; /* One per submodule */ -- cgit v1.2.3 From 54e73770357142e297c916c7865f5fca7499f69c Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Fri, 23 Jun 2006 02:05:54 -0700 Subject: [PATCH] list: introduce list_replace() helper list_replace() is similar to list_replace_rcu(), but unlike list_replace_rcu() it could be used when list_empty(old) == 1 doesn't use barriers Signed-off-by: Oleg Nesterov Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/list.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'include/linux') diff --git a/include/linux/list.h b/include/linux/list.h index 76f05718342c..a02642e4710a 100644 --- a/include/linux/list.h +++ b/include/linux/list.h @@ -197,12 +197,35 @@ static inline void list_del_rcu(struct list_head *entry) entry->prev = LIST_POISON2; } +/** + * list_replace - replace old entry by new one + * @old : the element to be replaced + * @new : the new element to insert + * Note: if 'old' was empty, it will be overwritten. + */ +static inline void list_replace(struct list_head *old, + struct list_head *new) +{ + new->next = old->next; + new->next->prev = new; + new->prev = old->prev; + new->prev->next = new; +} + +static inline void list_replace_init(struct list_head *old, + struct list_head *new) +{ + list_replace(old, new); + INIT_LIST_HEAD(old); +} + /* * list_replace_rcu - replace old entry by new one * @old : the element to be replaced * @new : the new element to insert * * The old entry will be replaced with the new entry atomically. + * Note: 'old' should not be empty. */ static inline void list_replace_rcu(struct list_head *old, struct list_head *new) -- cgit v1.2.3 From 908dcecda1d18803b5823f30e6c47d2882dc0cf1 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Fri, 23 Jun 2006 02:06:00 -0700 Subject: [PATCH] adjust handle_IRR_event() return type Correct the return type of handle_IRQ_event() (inconsistency noticed during Xen development), and remove redundant declarations. The return type adjustment required breaking out the definition of irqreturn_t into a separate header, in order to satisfy current include order dependencies. Signed-off-by: Jan Beulich Cc: Richard Henderson Cc: Ivan Kokshaysky Cc: Russell King Cc: Ian Molton Cc: Mikael Starvik Cc: Yoshinori Sato Cc: Hirokazu Takata Cc: Heiko Carstens Cc: Martin Schwidefsky Cc: William Lee Irwin III Cc: "David S. Miller" Cc: Miles Bader Cc: Geert Uytterhoeven Cc: Roman Zippel Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/interrupt.h | 21 +-------------------- include/linux/irq.h | 3 ++- include/linux/irqreturn.h | 25 +++++++++++++++++++++++++ 3 files changed, 28 insertions(+), 21 deletions(-) create mode 100644 include/linux/irqreturn.h (limited to 'include/linux') diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h index 9e0fefd7884a..70741e170114 100644 --- a/include/linux/interrupt.h +++ b/include/linux/interrupt.h @@ -7,32 +7,13 @@ #include #include #include +#include #include #include #include #include #include -/* - * For 2.4.x compatibility, 2.4.x can use - * - * typedef void irqreturn_t; - * #define IRQ_NONE - * #define IRQ_HANDLED - * #define IRQ_RETVAL(x) - * - * To mix old-style and new-style irq handler returns. - * - * IRQ_NONE means we didn't handle it. - * IRQ_HANDLED means that we did have a valid interrupt and handled it. - * IRQ_RETVAL(x) selects on the two depending on x being non-zero (for handled) - */ -typedef int irqreturn_t; - -#define IRQ_NONE (0) -#define IRQ_HANDLED (1) -#define IRQ_RETVAL(x) ((x) != 0) - struct irqaction { irqreturn_t (*handler)(int, void *, struct pt_regs *); unsigned long flags; diff --git a/include/linux/irq.h b/include/linux/irq.h index e8a07e75e4fb..676e00dfb21a 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -175,7 +176,7 @@ static inline void set_balance_irq_affinity(unsigned int irq, cpumask_t mask) extern int no_irq_affinity; extern int noirqdebug_setup(char *str); -extern fastcall int handle_IRQ_event(unsigned int irq, struct pt_regs *regs, +extern fastcall irqreturn_t handle_IRQ_event(unsigned int irq, struct pt_regs *regs, struct irqaction *action); extern fastcall unsigned int __do_IRQ(unsigned int irq, struct pt_regs *regs); extern void note_interrupt(unsigned int irq, irq_desc_t *desc, diff --git a/include/linux/irqreturn.h b/include/linux/irqreturn.h new file mode 100644 index 000000000000..881883c2009d --- /dev/null +++ b/include/linux/irqreturn.h @@ -0,0 +1,25 @@ +/* irqreturn.h */ +#ifndef _LINUX_IRQRETURN_H +#define _LINUX_IRQRETURN_H + +/* + * For 2.4.x compatibility, 2.4.x can use + * + * typedef void irqreturn_t; + * #define IRQ_NONE + * #define IRQ_HANDLED + * #define IRQ_RETVAL(x) + * + * To mix old-style and new-style irq handler returns. + * + * IRQ_NONE means we didn't handle it. + * IRQ_HANDLED means that we did have a valid interrupt and handled it. + * IRQ_RETVAL(x) selects on the two depending on x being non-zero (for handled) + */ +typedef int irqreturn_t; + +#define IRQ_NONE (0) +#define IRQ_HANDLED (1) +#define IRQ_RETVAL(x) ((x) != 0) + +#endif -- cgit v1.2.3 From 78ce89c92bc6eaf5933b5664bff64253a7103bd7 Mon Sep 17 00:00:00 2001 From: Jan Kara Date: Fri, 23 Jun 2006 02:06:05 -0700 Subject: [PATCH] JBD: split checkpoint lists Split the checkpoint list of the transaction into two lists. In the first list we keep the buffers that need to be submitted for IO. In the second list are kept buffers that were already submitted and we just have to wait for the IO to complete. This should simplify a handling of checkpoint lists a bit and can eventually be also a performance gain. Signed-off-by: Jan Kara Cc: Mark Fasheh Cc: "Stephen C. Tweedie" Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/linux/jbd.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'include/linux') diff --git a/include/linux/jbd.h b/include/linux/jbd.h index 6a425e370cb3..20eb34403d0c 100644 --- a/include/linux/jbd.h +++ b/include/linux/jbd.h @@ -500,6 +500,12 @@ struct transaction_s */ struct journal_head *t_checkpoint_list; + /* + * Doubly-linked circular list of all buffers submitted for IO while + * checkpointing. [j_list_lock] + */ + struct journal_head *t_checkpoint_io_list; + /* * Doubly-linked circular list of temporary buffers currently undergoing * IO in the log [j_list_lock] @@ -849,7 +855,7 @@ extern void journal_commit_transaction(journal_t *); /* Checkpoint list management */ int __journal_clean_checkpoint_list(journal_t *journal); -void __journal_remove_checkpoint(struct journal_head *); +int __journal_remove_checkpoint(struct journal_head *); void __journal_insert_checkpoint(struct journal_head *, transaction_t *); /* Buffer IO */ -- cgit v1.2.3 From fda151d9feafc0e8418f23c716587c44394fcdbf Mon Sep 17 00:00:00 2001 From: Alexey Dobriyan Date: Mon, 5 Jun 2006 12:09:50 +0200 Subject: [PATCH] blktrace_api.h: endian annotations Signed-off-by: Alexey Dobriyan Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe --- include/linux/blktrace_api.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include/linux') diff --git a/include/linux/blktrace_api.h b/include/linux/blktrace_api.h index eb1a867ed245..a7e8cef73d15 100644 --- a/include/linux/blktrace_api.h +++ b/include/linux/blktrace_api.h @@ -90,9 +90,9 @@ struct blk_io_trace { * The remap event */ struct blk_io_trace_remap { - u32 device; + __be32 device; u32 __pad; - u64 sector; + __be64 sector; }; enum { @@ -224,7 +224,7 @@ static inline void blk_add_trace_pdu_int(struct request_queue *q, u32 what, struct bio *bio, unsigned int pdu) { struct blk_trace *bt = q->blk_trace; - u64 rpdu = cpu_to_be64(pdu); + __be64 rpdu = cpu_to_be64(pdu); if (likely(!bt)) return; -- cgit v1.2.3 From b31dc66a54ad986b6b73bdc49c8efc17cbad1833 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 13 Jun 2006 08:26:10 +0200 Subject: [PATCH] Kill PF_SYNCWRITE flag A process flag to indicate whether we are doing sync io is incredibly ugly. It also causes performance problems when one does a lot of async io and then proceeds to sync it. Part of the io will go out as async, and the other part as sync. This causes a disconnect between the previously submitted io and the synced io. For io schedulers such as CFQ, this will cause us lost merges and suboptimal behaviour in scheduling. Remove PF_SYNCWRITE completely from the fsync/msync paths, and let the O_DIRECT path just directly indicate that the writes are sync by using WRITE_SYNC instead. Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 2 ++ include/linux/sched.h | 11 +++++------ 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 3457e7b97363..482a21d67627 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -241,6 +241,7 @@ enum rq_flag_bits { __REQ_PM_RESUME, /* resume request */ __REQ_PM_SHUTDOWN, /* shutdown request */ __REQ_ORDERED_COLOR, /* is before or after barrier */ + __REQ_RW_SYNC, /* request is sync (O_DIRECT) */ __REQ_NR_BITS, /* stops here */ }; @@ -270,6 +271,7 @@ enum rq_flag_bits { #define REQ_PM_RESUME (1 << __REQ_PM_RESUME) #define REQ_PM_SHUTDOWN (1 << __REQ_PM_SHUTDOWN) #define REQ_ORDERED_COLOR (1 << __REQ_ORDERED_COLOR) +#define REQ_RW_SYNC (1 << __REQ_RW_SYNC) /* * State information carried for REQ_PM_SUSPEND and REQ_PM_RESUME diff --git a/include/linux/sched.h b/include/linux/sched.h index a9d23c7d1b25..38b4791e6a5d 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -941,12 +941,11 @@ static inline void put_task_struct(struct task_struct *t) #define PF_KSWAPD 0x00040000 /* I am kswapd */ #define PF_SWAPOFF 0x00080000 /* I am in swapoff */ #define PF_LESS_THROTTLE 0x00100000 /* Throttle me less: I clean memory */ -#define PF_SYNCWRITE 0x00200000 /* I am doing a sync write */ -#define PF_BORROWED_MM 0x00400000 /* I am a kthread doing use_mm */ -#define PF_RANDOMIZE 0x00800000 /* randomize virtual address space */ -#define PF_SWAPWRITE 0x01000000 /* Allowed to write to swap */ -#define PF_SPREAD_PAGE 0x04000000 /* Spread page cache over cpuset */ -#define PF_SPREAD_SLAB 0x08000000 /* Spread some slab caches over cpuset */ +#define PF_BORROWED_MM 0x00200000 /* I am a kthread doing use_mm */ +#define PF_RANDOMIZE 0x00400000 /* randomize virtual address space */ +#define PF_SWAPWRITE 0x00800000 /* Allowed to write to swap */ +#define PF_SPREAD_PAGE 0x01000000 /* Spread page cache over cpuset */ +#define PF_SPREAD_SLAB 0x02000000 /* Spread some slab caches over cpuset */ #define PF_MEMPOLICY 0x10000000 /* Non-default NUMA mempolicy */ /* -- cgit v1.2.3 From ad3caddaa1708e506f20b8e25a4a8ae586fc7d5b Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 13 Jun 2006 08:46:57 +0200 Subject: [PATCH] Get rid of struct request request_pm_state member The IDE power management can just use the ->end_io_data member to store it's data. Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'include/linux') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 482a21d67627..371c0ce5f630 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -195,11 +195,6 @@ struct request { unsigned int timeout; int retries; - /* - * For Power Management requests - */ - struct request_pm_state *pm; - /* * completion callback. end_io_data should be folded in with waiting */ -- cgit v1.2.3 From 8f34ee75decb80007ba77bba5a7384eadff4866d Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Tue, 13 Jun 2006 09:02:34 +0200 Subject: [PATCH] Rearrange a few struct request members This saves 8 bytes of data in 64-bit archs. Signed-off-by: Jens Axboe --- include/linux/blkdev.h | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'include/linux') diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 371c0ce5f630..aafe82788b4e 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -151,11 +151,9 @@ struct request { void *elevator_private; void *completion_data; - unsigned short ioprio; - int rq_status; /* should split this into a few status bits */ - struct gendisk *rq_disk; int errors; + struct gendisk *rq_disk; unsigned long start_time; /* Number of scatter-gather DMA addr+len pairs after @@ -170,8 +168,9 @@ struct request { */ unsigned short nr_hw_segments; + unsigned short ioprio; + int tag; - char *buffer; int ref_count; request_queue_t *q; @@ -179,6 +178,7 @@ struct request { struct completion *waiting; void *special; + char *buffer; /* * when request is used as a packet command carrier @@ -187,9 +187,8 @@ struct request { unsigned char cmd[BLK_MAX_CDB]; unsigned int data_len; - void *data; - unsigned int sense_len; + void *data; void *sense; unsigned int timeout; -- cgit v1.2.3 From dd67d051529387f6e44d22d1d5540ef281965fdd Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Wed, 21 Jun 2006 09:36:18 +0200 Subject: [PATCH] rbtree: support functions used by the io schedulers They all duplicate macros to check for empty root and/or node, and clearing a node. So put those in rbtree.h. Signed-off-by: Jens Axboe --- include/linux/rbtree.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'include/linux') diff --git a/include/linux/rbtree.h b/include/linux/rbtree.h index f37006f21664..8d5382e62c08 100644 --- a/include/linux/rbtree.h +++ b/include/linux/rbtree.h @@ -132,6 +132,10 @@ static inline void rb_set_color(struct rb_node *rb, int color) #define RB_ROOT (struct rb_root) { NULL, } #define rb_entry(ptr, type, member) container_of(ptr, type, member) +#define RB_EMPTY_ROOT(root) ((root)->rb_node == NULL) +#define RB_EMPTY_NODE(node) (rb_parent(node) != node) +#define RB_CLEAR_NODE(node) (rb_set_parent(node, node)) + extern void rb_insert_color(struct rb_node *, struct rb_root *); extern void rb_erase(struct rb_node *, struct rb_root *); -- cgit v1.2.3