From 468e6d17ff42e6f291a88c87681b2b5e34e9ab33 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Tue, 5 Feb 2002 00:13:46 -0800 Subject: v2.5.2.1 -> v2.5.2.1.1 - David Howells: abtract out "current->need_resched" as "need_resched()" - Frank Davis: ide-tape update for bio - various: header file fixups - Jens Axboe: fix up bio/ide/highmem issues - Kai Germaschewski: ISDN update - Tim Waugh: parport update - Patrik Mochel: initcall update - Greg KH: USB and Compaq PCI hotplug updates --- include/asm-arm/arch-arc/system.h | 2 +- include/asm-arm/arch-cl7500/system.h | 2 +- include/asm-arm/arch-ebsa110/system.h | 6 +- include/asm-arm/arch-ebsa285/system.h | 4 +- include/asm-arm/arch-nexuspci/system.h | 2 +- include/asm-arm/arch-rpc/system.h | 4 +- include/asm-arm/arch-sa1100/system.h | 2 +- include/asm-arm/arch-tbox/system.h | 4 +- include/asm-i386/mmu_context.h | 9 ++- include/asm-i386/smplock.h | 4 +- include/linux/blk.h | 4 +- include/linux/file.h | 5 +- include/linux/fs.h | 45 ++++++++------ include/linux/ide.h | 21 +++++++ include/linux/init.h | 32 +++++++++- include/linux/init_task.h | 2 - include/linux/isdn.h | 2 - include/linux/mtd/cfi.h | 2 +- include/linux/pci.h | 1 - include/linux/reiserfs_fs_sb.h | 2 +- include/linux/sched.h | 64 ++++++++++++++----- include/scsi/sg.h | 108 ++++++++++++++++----------------- 22 files changed, 200 insertions(+), 127 deletions(-) (limited to 'include') diff --git a/include/asm-arm/arch-arc/system.h b/include/asm-arm/arch-arc/system.h index fce24985d3a1..5886cbeb8718 100644 --- a/include/asm-arm/arch-arc/system.h +++ b/include/asm-arm/arch-arc/system.h @@ -10,7 +10,7 @@ static void arch_idle(void) { - while (!current->need_resched && !hlt_counter); + while (!need_resched() && !hlt_counter); } static inline void arch_reset(char mode) diff --git a/include/asm-arm/arch-cl7500/system.h b/include/asm-arm/arch-cl7500/system.h index 2bdd19913af2..6cb002194834 100644 --- a/include/asm-arm/arch-cl7500/system.h +++ b/include/asm-arm/arch-cl7500/system.h @@ -10,7 +10,7 @@ static void arch_idle(void) { - while (!current->need_resched && !hlt_counter) + while (!need_resched() && !hlt_counter) iomd_writeb(0, IOMD_SUSMODE); } diff --git a/include/asm-arm/arch-ebsa110/system.h b/include/asm-arm/arch-ebsa110/system.h index c4af29befbd9..e33951995e68 100644 --- a/include/asm-arm/arch-ebsa110/system.h +++ b/include/asm-arm/arch-ebsa110/system.h @@ -17,7 +17,7 @@ * will stop our MCLK signal (which provides the clock for the glue * logic, and therefore the timer interrupt). * - * Instead, we spin, waiting for either hlt_counter or need_resched + * Instead, we spin, waiting for either hlt_counter or need_resched() * to be set. If we have been spinning for 2cs, then we drop the * core clock down to the memory clock. */ @@ -28,13 +28,13 @@ static void arch_idle(void) start_idle = jiffies; do { - if (current->need_resched || hlt_counter) + if (need_resched() || hlt_counter) goto slow_out; } while (time_before(jiffies, start_idle + HZ/50)); cpu_do_idle(IDLE_CLOCK_SLOW); - while (!current->need_resched && !hlt_counter) { + while (!need_resched() && !hlt_counter) { /* do nothing slowly */ } diff --git a/include/asm-arm/arch-ebsa285/system.h b/include/asm-arm/arch-ebsa285/system.h index e9b4da1e93a7..9559db044860 100644 --- a/include/asm-arm/arch-ebsa285/system.h +++ b/include/asm-arm/arch-ebsa285/system.h @@ -20,14 +20,14 @@ static void arch_idle(void) start_idle = jiffies; do { - if (current->need_resched || hlt_counter) + if (need_resched() || hlt_counter) goto slow_out; cpu_do_idle(IDLE_WAIT_FAST); } while (time_before(jiffies, start_idle + HZ/50)); cpu_do_idle(IDLE_CLOCK_SLOW); - while (!current->need_resched && !hlt_counter) { + while (!need_resched() && !hlt_counter) { cpu_do_idle(IDLE_WAIT_SLOW); } diff --git a/include/asm-arm/arch-nexuspci/system.h b/include/asm-arm/arch-nexuspci/system.h index 028788bdc743..c5257807042b 100644 --- a/include/asm-arm/arch-nexuspci/system.h +++ b/include/asm-arm/arch-nexuspci/system.h @@ -16,7 +16,7 @@ static void arch_idle(void) { - while (!current->need_resched && !hlt_counter) + while (!need_resched() && !hlt_counter) cpu_do_idle(IDLE_WAIT_SLOW); } diff --git a/include/asm-arm/arch-rpc/system.h b/include/asm-arm/arch-rpc/system.h index 6e070b9071a9..7c781a6d1848 100644 --- a/include/asm-arm/arch-rpc/system.h +++ b/include/asm-arm/arch-rpc/system.h @@ -18,14 +18,14 @@ static void arch_idle(void) start_idle = jiffies; do { - if (current->need_resched || hlt_counter) + if (need_resched() || hlt_counter) goto slow_out; cpu_do_idle(IDLE_WAIT_FAST); } while (time_before(jiffies, start_idle + HZ/50)); cpu_do_idle(IDLE_CLOCK_SLOW); - while (!current->need_resched && !hlt_counter) { + while (!need_resched() && !hlt_counter) { cpu_do_idle(IDLE_WAIT_SLOW); } diff --git a/include/asm-arm/arch-sa1100/system.h b/include/asm-arm/arch-sa1100/system.h index d020a49268a2..6dbf2a45b061 100644 --- a/include/asm-arm/arch-sa1100/system.h +++ b/include/asm-arm/arch-sa1100/system.h @@ -10,7 +10,7 @@ static inline void arch_idle(void) if (!hlt_counter) { int flags; local_irq_save(flags); - if (!current->need_resched) + if (!need_resched()) cpu_do_idle(0); local_irq_restore(flags); } diff --git a/include/asm-arm/arch-tbox/system.h b/include/asm-arm/arch-tbox/system.h index e52bb50fdf62..cf90aafef297 100644 --- a/include/asm-arm/arch-tbox/system.h +++ b/include/asm-arm/arch-tbox/system.h @@ -13,14 +13,14 @@ static void arch_idle(void) start_idle = jiffies; do { - if (current->need_resched || hlt_counter) + if (need_resched() || hlt_counter) goto slow_out; cpu_do_idle(IDLE_WAIT_FAST); } while (time_before(jiffies, start_idle + HZ/50)); cpu_do_idle(IDLE_CLOCK_SLOW); - while (!current->need_resched && !hlt_counter) { + while (!need_resched() && !hlt_counter) { cpu_do_idle(IDLE_WAIT_SLOW); } diff --git a/include/asm-i386/mmu_context.h b/include/asm-i386/mmu_context.h index 2f76058591fb..6525a4b66495 100644 --- a/include/asm-i386/mmu_context.h +++ b/include/asm-i386/mmu_context.h @@ -1,5 +1,5 @@ -#ifndef __I386_MMU_CONTEXT_H -#define __I386_MMU_CONTEXT_H +#ifndef __I386_SCHED_H +#define __I386_SCHED_H #include #include @@ -16,14 +16,13 @@ # error update this function. #endif -static inline int sched_find_first_zero_bit(char *bitmap) +static inline int sched_find_first_zero_bit(unsigned long *b) { - unsigned int *b = (unsigned int *)bitmap; unsigned int rt; rt = b[0] & b[1] & b[2] & b[3]; if (unlikely(rt != 0xffffffff)) - return find_first_zero_bit(bitmap, MAX_RT_PRIO); + return find_first_zero_bit(b, MAX_RT_PRIO); if (b[4] != ~0) return ffz(b[4]) + MAX_RT_PRIO; diff --git a/include/asm-i386/smplock.h b/include/asm-i386/smplock.h index 10cfc1fd0c43..c270defe9be4 100644 --- a/include/asm-i386/smplock.h +++ b/include/asm-i386/smplock.h @@ -19,8 +19,8 @@ extern spinlock_t kernel_flag; do { \ if (unlikely(task->lock_depth >= 0)) { \ spin_unlock(&kernel_flag); \ - release_irqlock(cpu); \ - __sti(); \ + if (global_irq_holder == (cpu)) \ + BUG(); \ } \ } while (0) diff --git a/include/linux/blk.h b/include/linux/blk.h index efede40e2408..b6507e62eb4b 100644 --- a/include/linux/blk.h +++ b/include/linux/blk.h @@ -90,9 +90,9 @@ extern inline struct request *elv_next_request(request_queue_t *q) #define _elv_add_request(q, rq, back, p) do { \ if ((back)) \ - _elv_add_request_core((q), (rq), (q)->queue_head.prev, (p)); \ + _elv_add_request_core((q), (rq), (q)->queue_head.prev, (p)); \ else \ - _elv_add_request_core((q), (rq), &(q)->queue_head, 0); \ + _elv_add_request_core((q), (rq), &(q)->queue_head, (p)); \ } while (0) #define elv_add_request(q, rq, back) _elv_add_request((q), (rq), (back), 1) diff --git a/include/linux/file.h b/include/linux/file.h index bac31250708c..5e006ad08df0 100644 --- a/include/linux/file.h +++ b/include/linux/file.h @@ -5,12 +5,9 @@ #ifndef __LINUX_FILE_H #define __LINUX_FILE_H -#ifndef _LINUX_POSIX_TYPES_H /* __FD_CLR */ +#include #include -#endif -#ifndef __LINUX_COMPILER_H /* unlikely */ #include -#endif /* * The default fd array needs to be at least BITS_PER_LONG, diff --git a/include/linux/fs.h b/include/linux/fs.h index a01f0c3b4d34..4e5de1286d87 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -262,7 +262,7 @@ struct buffer_head { wait_queue_head_t b_wait; - struct inode * b_inode; + int b_inode; /* will go away */ struct list_head b_inode_buffers; /* doubly linked list of inode dirty buffers */ }; @@ -859,6 +859,9 @@ struct seq_file; * without the big kernel lock held in all filesystems. */ struct super_operations { + struct inode *(*alloc_inode)(struct super_block *sb); + void (*destroy_inode)(struct inode *); + void (*read_inode) (struct inode *); /* reiserfs kludge. reiserfs needs 64 bits of information to @@ -1151,7 +1154,16 @@ static inline void mark_buffer_clean(struct buffer_head * bh) extern void FASTCALL(__mark_dirty(struct buffer_head *bh)); extern void FASTCALL(__mark_buffer_dirty(struct buffer_head *bh)); extern void FASTCALL(mark_buffer_dirty(struct buffer_head *bh)); -extern void FASTCALL(buffer_insert_inode_data_queue(struct buffer_head *, struct inode *)); +extern void FASTCALL(buffer_insert_list(struct buffer_head *, struct list_head *)); + +static inline void buffer_insert_inode_queue(struct buffer_head *bh, struct inode *inode) +{ + buffer_insert_list(bh, &inode->i_dirty_buffers); +} +static inline void buffer_insert_inode_data_queue(struct buffer_head *bh, struct inode *inode) +{ + buffer_insert_list(bh, &inode->i_dirty_data_buffers); +} #define atomic_set_buffer_dirty(bh) test_and_set_bit(BH_Dirty, &(bh)->b_state) @@ -1219,10 +1231,16 @@ extern int fsync_dev(kdev_t); extern int fsync_super(struct super_block *); extern int fsync_no_super(struct block_device *); extern void sync_inodes_sb(struct super_block *); -extern int osync_inode_buffers(struct inode *); -extern int osync_inode_data_buffers(struct inode *); -extern int fsync_inode_buffers(struct inode *); -extern int fsync_inode_data_buffers(struct inode *); +extern int osync_buffers_list(struct list_head *); +extern int fsync_buffers_list(struct list_head *); +static inline int fsync_inode_buffers(struct inode *inode) +{ + return fsync_buffers_list(&inode->i_dirty_buffers); +} +static inline int fsync_inode_data_buffers(struct inode *inode) +{ + return fsync_buffers_list(&inode->i_dirty_data_buffers); +} extern int inode_has_buffers(struct inode *); extern void filemap_fdatasync(struct address_space *); extern void filemap_fdatawait(struct address_space *); @@ -1327,6 +1345,7 @@ extern struct dentry * lookup_hash(struct qstr *, struct dentry *); #define user_path_walk(name,nd) __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd) #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd) +extern void inode_init_once(struct inode *); extern void iput(struct inode *); extern void force_delete(struct inode *); extern struct inode * igrab(struct inode *); @@ -1340,20 +1359,8 @@ static inline struct inode *iget(struct super_block *sb, unsigned long ino) } extern void clear_inode(struct inode *); -extern struct inode * get_empty_inode(void); - -static inline struct inode * new_inode(struct super_block *sb) -{ - struct inode *inode = get_empty_inode(); - if (inode) { - inode->i_sb = sb; - inode->i_dev = sb->s_dev; - inode->i_blkbits = sb->s_blocksize_bits; - } - return inode; -} +extern struct inode *new_inode(struct super_block *); extern void remove_suid(struct inode *inode); - extern void insert_inode_hash(struct inode *); extern void remove_inode_hash(struct inode *); extern struct file * get_empty_filp(void); diff --git a/include/linux/ide.h b/include/linux/ide.h index b5e752a49e7d..8b81bcc98cb3 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h @@ -884,6 +884,9 @@ typedef enum { */ #define ide_rq_offset(rq) (((rq)->hard_cur_sectors - (rq)->current_nr_sectors) << 9) +#define task_rq_offset(rq) \ + (((rq)->nr_sectors - (rq)->current_nr_sectors) * SECTOR_SIZE) + extern inline void *ide_map_buffer(struct request *rq, unsigned long *flags) { return bio_kmap_irq(rq->bio, flags) + ide_rq_offset(rq); @@ -894,6 +897,24 @@ extern inline void ide_unmap_buffer(char *buffer, unsigned long *flags) bio_kunmap_irq(buffer, flags); } +/* + * for now, taskfile requests are special :/ + */ +extern inline char *ide_map_rq(struct request *rq, unsigned long *flags) +{ + if (rq->bio) + return ide_map_buffer(rq, flags); + else + return rq->buffer + task_rq_offset(rq); +} + +extern inline void ide_unmap_rq(struct request *rq, char *buf, + unsigned long *flags) +{ + if (rq->bio) + ide_unmap_buffer(buf, flags); +} + /* * This function issues a special IDE device request * onto the request queue. diff --git a/include/linux/init.h b/include/linux/init.h index f0644ca302e8..0a9c2eba880e 100644 --- a/include/linux/init.h +++ b/include/linux/init.h @@ -50,8 +50,26 @@ typedef void (*exitcall_t)(void); extern initcall_t __initcall_start, __initcall_end; -#define __initcall(fn) \ - static initcall_t __initcall_##fn __init_call = fn +/* initcalls are now grouped by functionality into separate + * subsections. Ordering inside the subsections is determined + * by link order. + * For backwards compatability, initcall() puts the call in + * the device init subsection. + */ + +#define __define_initcall(level,fn) \ + static initcall_t __initcall_##fn __attribute__ ((unused,__section__ (".initcall" level ".init"))) = fn + +#define early_arch_initcall(fn) __define_initcall("1",fn) +#define mem_initcall(fn) __define_initcall("2",fn) +#define subsys_initcall(fn) __define_initcall("3",fn) +#define arch_initcall(fn) __define_initcall("4",fn) +#define fs_initcall(fn) __define_initcall("5",fn) +#define device_initcall(fn) __define_initcall("6",fn) +#define late_initcall(fn) __define_initcall("7",fn) + +#define __initcall(fn) device_initcall(fn) + #define __exitcall(fn) \ static exitcall_t __exitcall_##fn __exit_call = fn @@ -80,7 +98,7 @@ extern struct kernel_param __setup_start, __setup_end; #define __initdata __attribute__ ((__section__ (".data.init"))) #define __exitdata __attribute__ ((unused, __section__ (".data.exit"))) #define __initsetup __attribute__ ((unused,__section__ (".setup.init"))) -#define __init_call __attribute__ ((unused,__section__ (".initcall.init"))) +#define __init_call(level) __attribute__ ((unused,__section__ (".initcall" level ".init"))) #define __exit_call __attribute__ ((unused,__section__ (".exitcall.exit"))) /* For assembly routines */ @@ -141,6 +159,14 @@ typedef void (*__cleanup_module_func_t)(void); #define __setup(str,func) /* nothing */ +#define early_arch_initcall(fn) module_init(fn) +#define mem_initcall(fn) module_init(fn) +#define subsys_initcall(fn) module_init(fn) +#define arch_initcall(fn) module_init(fn) +#define fs_initcall(fn) module_init(fn) +#define device_initcall(fn) module_init(fn) +#define late_initcall(fn) module_init(fn) + #endif #ifdef CONFIG_HOTPLUG diff --git a/include/linux/init_task.h b/include/linux/init_task.h index 3c4e71fc0a60..b496169b6023 100644 --- a/include/linux/init_task.h +++ b/include/linux/init_task.h @@ -1,9 +1,7 @@ #ifndef _LINUX__INIT_TASK_H #define _LINUX__INIT_TASK_H -#ifndef __LINUX_FILE_H #include -#endif #define INIT_FILES \ { \ diff --git a/include/linux/isdn.h b/include/linux/isdn.h index 6f6ae516028f..b59350f01f32 100644 --- a/include/linux/isdn.h +++ b/include/linux/isdn.h @@ -178,8 +178,6 @@ typedef struct { * the correspondent code in isdn.c */ -#define ISDN_MINOR_B 0 -#define ISDN_MINOR_BMAX (ISDN_MAX_CHANNELS-1) #define ISDN_MINOR_CTRL 64 #define ISDN_MINOR_CTRLMAX (64 + (ISDN_MAX_CHANNELS-1)) #define ISDN_MINOR_PPP 128 diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h index 7d6b31638321..0ad3d186597d 100644 --- a/include/linux/mtd/cfi.h +++ b/include/linux/mtd/cfi.h @@ -368,7 +368,7 @@ static inline __u8 cfi_read_query(struct map_info *map, __u32 addr) static inline void cfi_udelay(int us) { #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) - if (current->need_resched) { + if (need_resched()) { unsigned long t = us * HZ / 1000000; if (t < 1) t = 1; diff --git a/include/linux/pci.h b/include/linux/pci.h index 4971fa3c3586..7660a0bf8e9b 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -525,7 +525,6 @@ int pcibios_find_device (unsigned short vendor, unsigned short dev_id, /* Generic PCI functions used internally */ -void pci_init(void); int pci_bus_exists(const struct list_head *list, int nr); struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata); struct pci_bus *pci_alloc_primary_bus(int bus); diff --git a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h index a78f78986723..73d6d823fbbb 100644 --- a/include/linux/reiserfs_fs_sb.h +++ b/include/linux/reiserfs_fs_sb.h @@ -300,7 +300,7 @@ struct reiserfs_journal { int j_free_bitmap_nodes ; int j_used_bitmap_nodes ; struct list_head j_bitmap_nodes ; - struct inode j_dummy_inode ; + struct list_head j_dirty_buffers ; struct reiserfs_list_bitmap j_list_bitmap[JOURNAL_NUM_BITMAPS] ; /* array of bitmaps to record the deleted blocks */ struct reiserfs_journal_list j_journal_list[JOURNAL_LIST_COUNT] ; /* array of all the journal lists */ struct reiserfs_journal_cnode *j_hash_table[JOURNAL_HASH_SIZE] ; /* hash table for real buffer heads in current trans */ diff --git a/include/linux/sched.h b/include/linux/sched.h index b8d564fd0c08..3797423a4fbe 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -25,6 +25,7 @@ extern unsigned long event; #include #include #include +#include struct exec_domain; @@ -136,6 +137,8 @@ struct completion; extern rwlock_t tasklist_lock; extern spinlock_t mmlist_lock; +typedef struct task_struct task_t; + extern void sched_init(void); extern void init_idle(void); extern void show_state(void); @@ -144,8 +147,7 @@ extern void trap_init(void); extern void update_process_times(int user); extern void update_one_process(struct task_struct *p, unsigned long user, unsigned long system, int cpu); -extern void expire_task(struct task_struct *p); -extern void idle_tick(void); +extern void scheduler_tick(struct task_struct *p); #define MAX_SCHEDULE_TIMEOUT LONG_MAX extern signed long FASTCALL(schedule_timeout(signed long timeout)); @@ -221,7 +223,6 @@ struct user_struct { extern struct user_struct root_user; #define INIT_USER (&root_user) -typedef struct task_struct task_t; typedef struct prio_array prio_array_t; struct task_struct { @@ -251,7 +252,10 @@ struct task_struct { prio_array_t *array; unsigned int time_slice; - unsigned long sleep_jtime; + + #define MAX_SLEEP_AVG (2*HZ) + unsigned long sleep_avg; + unsigned long sleep_timestamp; unsigned long policy; unsigned long cpus_allowed; @@ -390,30 +394,47 @@ struct task_struct { * them out at 128 to make it easier to search the * scheduler bitmap. */ -#define MAX_RT_PRIO 128 +#define MAX_RT_PRIO 128 /* * The lower the priority of a process, the more likely it is * to run. Priority of a process goes from 0 to 167. The 0-99 * priority range is allocated to RT tasks, the 128-167 range * is for SCHED_OTHER tasks. */ -#define MAX_PRIO (MAX_RT_PRIO+40) -#define DEF_USER_NICE 0 +#define MAX_PRIO (MAX_RT_PRIO + 40) /* - * Default timeslice is 80 msecs, maximum is 160 msecs. + * Scales user-nice values [ -20 ... 0 ... 19 ] + * to static priority [ 128 ... 167 (MAX_PRIO-1) ] + * + * User-nice value of -20 == static priority 128, and + * user-nice value 19 == static priority 167. The lower + * the priority value, the higher the task's priority. + */ +#define NICE_TO_PRIO(n) (MAX_RT_PRIO + (n) + 20) +#define DEF_USER_NICE 0 + +/* + * Default timeslice is 90 msecs, maximum is 180 msecs. * Minimum timeslice is 10 msecs. */ -#define MIN_TIMESLICE (10 * HZ / 1000) -#define MAX_TIMESLICE (160 * HZ / 1000) +#define MIN_TIMESLICE ( 10 * HZ / 1000) +#define MAX_TIMESLICE (180 * HZ / 1000) -#define USER_PRIO(p) ((p)-MAX_RT_PRIO) -#define MAX_USER_PRIO (USER_PRIO(MAX_PRIO)) -#define DEF_PRIO (MAX_RT_PRIO + MAX_USER_PRIO / 3) -#define NICE_TO_PRIO(n) (MAX_PRIO-1 + (n) - 19) +#define USER_PRIO(p) ((p)-MAX_RT_PRIO) +#define MAX_USER_PRIO (USER_PRIO(MAX_PRIO)) -#define NICE_TO_TIMESLICE(n) (MIN_TIMESLICE + \ - ((MAX_TIMESLICE - MIN_TIMESLICE) * (19 - (n))) / 39) +/* + * NICE_TO_TIMESLICE scales nice values [ -20 ... 19 ] + * to time slice values. + * + * The higher a process's priority, the bigger timeslices + * it gets during one round of execution. But even the lowest + * priority process gets MIN_TIMESLICE worth of execution time. + */ + +#define NICE_TO_TIMESLICE(n) (MIN_TIMESLICE + \ + ((MAX_TIMESLICE - MIN_TIMESLICE) * (19-(n))) / 39) extern void set_cpus_allowed(task_t *p, unsigned long new_mask); extern void set_user_nice(task_t *p, long nice); @@ -542,6 +563,17 @@ static inline int signal_pending(struct task_struct *p) { return (p->sigpending != 0); } + +static inline int need_resched(void) +{ + return unlikely(current->need_resched != 0); +} + +static inline void cond_resched(void) +{ + if (need_resched()) + schedule(); +} /* * Re-calculate pending state from the set of locally pending diff --git a/include/scsi/sg.h b/include/scsi/sg.h index 26ee7fea25d2..20624abce6c7 100644 --- a/include/scsi/sg.h +++ b/include/scsi/sg.h @@ -11,78 +11,71 @@ Original driver (sg.h): Version 2 and 3 extensions to driver: * Copyright (C) 1998 - 2001 Douglas Gilbert - Version: 3.1.20 (20010814) - This version is for 2.4 series kernels. - - Changes since 3.1.19 (20010623) - - add SG_GET_ACCESS_COUNT ioctl - - make open() increment and close() decrement access_count - - only register first 256 devices, reject subsequent devices - Changes since 3.1.18 (20010505) - - fix bug that caused long wait when large buffer requested - - fix leak in error case of sg_new_read() [report: Eric Barton] - - add 'online' column to /proc/scsi/sg/devices - Changes since 3.1.17 (20000921) - - add CAP_SYS_RAWIO capability for sensitive stuff - - compile in dio stuff, procfs 'allow_dio' defaulted off (0) - - make premature close and detach more robust - - lun masked into commands <= SCSI_2 - - poll() and async notification now yield POLL_HUP on detach - - various 3rd party tweaks tracking lk 2.4 internal changes + Version: 3.5.23 (20011231) + This version is for 2.5 series kernels. + + Changes since 3.1.22 (20011208) + - branch sg driver for lk 2.5 series + - remove lock_kernel() from sg_close() + - remove code based on scsi mid level dma pool + - change scatterlist 'address' to use page + offset + - add SG_INTERFACE_ID_ORIG Map of SG verions to the Linux kernels in which they appear: ---------- ---------------------------------- original all kernels < 2.2.6 - 2.1.38 2.2.16 - 2.1.39 2.2.17 - 2.2.19 + 2.1.40 2.2.20 3.0.x optional version 3 sg driver for 2.2 series - 3.1.17 2.4.0 ++ + 3.1.17++ 2.4.0++ + 3.5.23++ 2.5.0++ Major new features in SG 3.x driver (cf SG 2.x drivers) - SG_IO ioctl() combines function if write() and read() - new interface (sg_io_hdr_t) but still supports old interface - - scatter/gather in user space and direct IO supported - - The term "indirect IO" refers a method by which data is DMAed into kernel - buffers from the hardware and afterwards is transferred into the user - space (or vice versa if you are writing). Transfer speeds of up to 20 to - 30MBytes/sec have been measured using indirect IO. For faster throughputs - "direct IO" which cuts out the double handling of data is required. - Direct IO is supported by the SG 3.x drivers on 2.4 series Linux kernels - and requires the use of the new interface. - - Requests for direct IO with the new interface will automatically fall back - to indirect IO mode if they cannot be fulfilled. An example of such a case - is an ISA SCSI adapter which is only capable of DMAing to the lower 16MB of - memory due to the architecture of ISA. The 'info' field in the new - interface indicates whether a direct or indirect data transfer took place. - - Obtaining memory for the kernel buffers used in indirect IO is done by - first checking if the "reserved buffer" for the current file descriptor - is available and large enough. If these conditions are _not_ met then - kernel memory is obtained on a per SCSI command basis. This corresponds - to a write(), read() sequence or a SG_IO ioctl() call. Further, the - kernel memory that is suitable for DMA may be constrained by the - architecture of the SCSI adapter (e.g. ISA adapters). + - scatter/gather in user space, direct IO, and mmap supported + + The normal action of this driver is to use the adapter (HBA) driver to DMA + data into kernel buffers and then use the CPU to copy the data into the + user space (vice versa for writes). That is called "indirect" IO due to + the double handling of data. There are two methods offered to remove the + redundant copy: 1) direct IO which uses the kernel kiobuf mechanism and + 2) using the mmap() system call to map the reserve buffer (this driver has + one reserve buffer per fd) into the user space. Both have their advantages. + In terms of absolute speed mmap() is faster. If speed is not a concern, + indirect IO should be fine. Read the documentation for more information. ** N.B. To use direct IO 'echo 1 > /proc/scsi/sg/allow_dio' may be needed. That pseudo file's content is defaulted to 0. ** + + Historical note: this SCSI pass-through driver has been known as "sg" for + a decade. In broader kernel discussions "sg" is used to refer to scatter + gather techniques. The context should clarify which "sg" is referred to. Documentation ============= - A web site for SG device drivers can be found at: + A web site for the SG device driver can be found at: http://www.torque.net/sg [alternatively check the MAINTAINERS file] - The main documents are still based on 2.x versions: + The documentation for the sg version 3 driver can be found at: + http://www.torque.net/sg/p/sg_v3_ho.html + This is a rendering from DocBook source [change the extension to "sgml" + or "xml"]. There are renderings in "ps", "pdf", "rtf" and "txt" (soon). + + The older, version 2 documents discuss the original sg interface in detail: http://www.torque.net/sg/p/scsi-generic.txt http://www.torque.net/sg/p/scsi-generic_long.txt - Documentation on the changes and additions in 3.x version of the sg driver - can be found at: http://www.torque.net/sg/p/scsi-generic_v3.txt A version of this document (potentially out of date) may also be found in the kernel source tree, probably at: /usr/src/linux/Documentation/scsi-generic.txt . - Utility and test programs are available at the sg web site. + + Utility and test programs are available at the sg web site. They are + bundled as sg_utils (for the lk 2.2 series) and sg3_utils (for the + lk 2.4 series). + + There is a HOWTO on the Linux SCSI subsystem in the lk 2.4 series at: + http://www.linuxdoc.org/HOWTO/SCSI-2.4-HOWTO */ + /* New interface introduced in the 3.x SG drivers follows */ typedef struct sg_iovec /* same structure as used by readv() Linux system */ @@ -119,20 +112,23 @@ typedef struct sg_io_hdr unsigned int info; /* [o] auxiliary information */ } sg_io_hdr_t; /* 64 bytes long (on i386) */ +#define SG_INTERFACE_ID_ORIG 'S' + /* Use negative values to flag difference from original sg_header structure */ -#define SG_DXFER_NONE -1 /* e.g. a SCSI Test Unit Ready command */ -#define SG_DXFER_TO_DEV -2 /* e.g. a SCSI WRITE command */ -#define SG_DXFER_FROM_DEV -3 /* e.g. a SCSI READ command */ -#define SG_DXFER_TO_FROM_DEV -4 /* treated like SG_DXFER_FROM_DEV with the +#define SG_DXFER_NONE (-1) /* e.g. a SCSI Test Unit Ready command */ +#define SG_DXFER_TO_DEV (-2) /* e.g. a SCSI WRITE command */ +#define SG_DXFER_FROM_DEV (-3) /* e.g. a SCSI READ command */ +#define SG_DXFER_TO_FROM_DEV (-4) /* treated like SG_DXFER_FROM_DEV with the additional property than during indirect IO the user buffer is copied into the kernel buffers before the transfer */ -#define SG_DXFER_UNKNOWN -5 /* Unknown data direction */ +#define SG_DXFER_UNKNOWN (-5) /* Unknown data direction */ /* following flag values can be "or"-ed together */ #define SG_FLAG_DIRECT_IO 1 /* default is indirect IO */ -#define SG_FLAG_LUN_INHIBIT 2 /* default is to put device's lun into */ - /* the 2nd byte of SCSI command */ +#define SG_FLAG_LUN_INHIBIT 2 /* default is overwrite lun in SCSI */ + /* command block (when <= SCSI_2) */ +#define SG_FLAG_MMAP_IO 4 /* request memory mapped IO */ #define SG_FLAG_NO_DXFER 0x10000 /* no transfer of kernel buffers to/from */ /* user space (debug indirect IO) */ -- cgit v1.2.3