Commit 4d4f47fc authored by Paul Mackerras's avatar Paul Mackerras

Merge samba.org:/stuff/paulus/kernel/linux-2.5

into samba.org:/stuff/paulus/kernel/for-linus-ppc
parents 6c2d7826 8514206e
...@@ -287,17 +287,14 @@ void show_regs(struct pt_regs *r) ...@@ -287,17 +287,14 @@ void show_regs(struct pt_regs *r)
rw->ins[4], rw->ins[5], rw->ins[6], rw->ins[7]); rw->ins[4], rw->ins[5], rw->ins[6], rw->ins[7]);
} }
void show_trace_task(struct task_struct *tsk) void show_stack(struct task_struct *tsk, unsigned long *_ksp)
{ {
unsigned long pc, fp; unsigned long pc, fp;
unsigned long task_base = (unsigned long) tsk; unsigned long task_base = (unsigned long) tsk;
struct reg_window *rw; struct reg_window *rw;
int count = 0; int count = 0;
if (!tsk) fp = (unsigned long) _ksp;
return;
fp = tsk->thread_info->ksp;
do { do {
/* Bogus frame pointer? */ /* Bogus frame pointer? */
if (fp < (task_base + sizeof(struct task_struct)) || if (fp < (task_base + sizeof(struct task_struct)) ||
...@@ -311,6 +308,13 @@ void show_trace_task(struct task_struct *tsk) ...@@ -311,6 +308,13 @@ void show_trace_task(struct task_struct *tsk)
printk("\n"); printk("\n");
} }
void show_trace_task(struct task_struct *tsk)
{
if (tsk)
show_stack(tsk,
(unsigned long *) tsk->thread_info->ksp);
}
/* /*
* Note: sparc64 has a pretty intricated thread_saved_pc, check it out. * Note: sparc64 has a pretty intricated thread_saved_pc, check it out.
*/ */
......
...@@ -64,9 +64,9 @@ sys_call_table: ...@@ -64,9 +64,9 @@ sys_call_table:
/*215*/ .long sys_ipc, sys_sigreturn, sys_clone, sys_nis_syscall, sys_adjtimex /*215*/ .long sys_ipc, sys_sigreturn, sys_clone, sys_nis_syscall, sys_adjtimex
/*220*/ .long sys_sigprocmask, sys_ni_syscall, sys_delete_module, sys_ni_syscall, sys_getpgid /*220*/ .long sys_sigprocmask, sys_ni_syscall, sys_delete_module, sys_ni_syscall, sys_getpgid
/*225*/ .long sys_bdflush, sys_sysfs, sys_nis_syscall, sys_setfsuid16, sys_setfsgid16 /*225*/ .long sys_bdflush, sys_sysfs, sys_nis_syscall, sys_setfsuid16, sys_setfsgid16
/*230*/ .long sys_select, sys_time, sys_nis_syscall, sys_stime, sys_nis_syscall /*230*/ .long sys_select, sys_time, sys_nis_syscall, sys_stime, sys_statfs64
/* "We are the Knights of the Forest of Ni!!" */ /* "We are the Knights of the Forest of Ni!!" */
/*235*/ .long sys_nis_syscall, sys_llseek, sys_mlock, sys_munlock, sys_mlockall /*235*/ .long sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys_mlockall
/*240*/ .long sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler /*240*/ .long sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler
/*245*/ .long sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep /*245*/ .long sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep
/*250*/ .long sparc_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl /*250*/ .long sparc_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl
......
...@@ -65,8 +65,8 @@ sys_call_table32: ...@@ -65,8 +65,8 @@ sys_call_table32:
.word sys32_ipc, sys32_sigreturn, sys_clone, sys_nis_syscall, sys32_adjtimex .word sys32_ipc, sys32_sigreturn, sys_clone, sys_nis_syscall, sys32_adjtimex
/*220*/ .word compat_sys_sigprocmask, sys_ni_syscall, sys32_delete_module, sys_ni_syscall, sys_getpgid /*220*/ .word compat_sys_sigprocmask, sys_ni_syscall, sys32_delete_module, sys_ni_syscall, sys_getpgid
.word sys32_bdflush, sys32_sysfs, sys_nis_syscall, sys32_setfsuid16, sys32_setfsgid16 .word sys32_bdflush, sys32_sysfs, sys_nis_syscall, sys32_setfsuid16, sys32_setfsgid16
/*230*/ .word sys32_select, sys_time, sys_nis_syscall, sys_stime, sys_ni_syscall /*230*/ .word sys32_select, sys_time, sys_nis_syscall, sys_stime, sys_statfs64
.word sys_ni_syscall, sys_llseek, sys_mlock, sys_munlock, sys_mlockall .word sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys_mlockall
/*240*/ .word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler /*240*/ .word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler
.word sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys32_sched_rr_get_interval, compat_sys_nanosleep .word sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys32_sched_rr_get_interval, compat_sys_nanosleep
/*250*/ .word sys32_mremap, sys32_sysctl, sys_getsid, sys_fdatasync, sys32_nfsservctl /*250*/ .word sys32_mremap, sys32_sysctl, sys_getsid, sys_fdatasync, sys32_nfsservctl
...@@ -124,11 +124,8 @@ sys_call_table: ...@@ -124,11 +124,8 @@ sys_call_table:
.word sys_ipc, sys_nis_syscall, sys_clone, sys_nis_syscall, sys_adjtimex .word sys_ipc, sys_nis_syscall, sys_clone, sys_nis_syscall, sys_adjtimex
/*220*/ .word sys_nis_syscall, sys_ni_syscall, sys_delete_module, sys_ni_syscall, sys_getpgid /*220*/ .word sys_nis_syscall, sys_ni_syscall, sys_delete_module, sys_ni_syscall, sys_getpgid
.word sys_bdflush, sys_sysfs, sys_nis_syscall, sys_setfsuid, sys_setfsgid .word sys_bdflush, sys_sysfs, sys_nis_syscall, sys_setfsuid, sys_setfsgid
/*230*/ .word sys_select, sys_nis_syscall, sys_nis_syscall, sys_stime, sys_statfs64
/* 234 and 235 were for the hugetlb syscalls. They can be reused */ .word sys_fstatfs64, sys_llseek, sys_mlock, sys_munlock, sys_mlockall
/*230*/ .word sys_select, sys_nis_syscall, sys_nis_syscall, sys_stime, sys_nis_syscall
.word sys_nis_syscall, sys_llseek, sys_mlock, sys_munlock, sys_mlockall
/*240*/ .word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler /*240*/ .word sys_munlockall, sys_sched_setparam, sys_sched_getparam, sys_sched_setscheduler, sys_sched_getscheduler
.word sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep .word sys_sched_yield, sys_sched_get_priority_max, sys_sched_get_priority_min, sys_sched_rr_get_interval, sys_nanosleep
/*250*/ .word sys64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl /*250*/ .word sys64_mremap, sys_sysctl, sys_getsid, sys_fdatasync, sys_nfsservctl
......
...@@ -1569,12 +1569,15 @@ void user_instruction_dump (unsigned int *pc) ...@@ -1569,12 +1569,15 @@ void user_instruction_dump (unsigned int *pc)
printk("\n"); printk("\n");
} }
void show_trace_raw(struct thread_info *tp, unsigned long ksp) void show_stack(struct task_struct *tsk, unsigned long *_ksp)
{ {
unsigned long pc, fp, thread_base; unsigned long pc, fp, thread_base, ksp;
struct thread_info *tp = tsk->thread_info;
struct reg_window *rw; struct reg_window *rw;
int count = 0; int count = 0;
ksp = (unsigned long) _ksp;
if (tp == current_thread_info()) if (tp == current_thread_info())
flushw_all(); flushw_all();
...@@ -1596,17 +1599,17 @@ void show_trace_raw(struct thread_info *tp, unsigned long ksp) ...@@ -1596,17 +1599,17 @@ void show_trace_raw(struct thread_info *tp, unsigned long ksp)
void show_trace_task(struct task_struct *tsk) void show_trace_task(struct task_struct *tsk)
{ {
if (tsk) if (tsk)
show_trace_raw(tsk->thread_info, show_stack(tsk,
tsk->thread_info->ksp); (unsigned long *) tsk->thread_info->ksp);
} }
void dump_stack(void) void dump_stack(void)
{ {
unsigned long ksp; unsigned long *ksp;
__asm__ __volatile__("mov %%fp, %0" __asm__ __volatile__("mov %%fp, %0"
: "=r" (ksp)); : "=r" (ksp));
show_trace_raw(current_thread_info(), ksp); show_stack(current, ksp);
} }
void die_if_kernel(char *str, struct pt_regs *regs) void die_if_kernel(char *str, struct pt_regs *regs)
......
...@@ -149,16 +149,14 @@ static void unhandled_fault(unsigned long address, struct task_struct *tsk, ...@@ -149,16 +149,14 @@ static void unhandled_fault(unsigned long address, struct task_struct *tsk,
die_if_kernel("Oops", regs); die_if_kernel("Oops", regs);
} }
extern void show_trace_raw(struct thread_info *, unsigned long);
static void bad_kernel_pc(struct pt_regs *regs) static void bad_kernel_pc(struct pt_regs *regs)
{ {
unsigned long ksp; unsigned long *ksp;
printk(KERN_CRIT "OOPS: Bogus kernel PC [%016lx] in fault handler\n", printk(KERN_CRIT "OOPS: Bogus kernel PC [%016lx] in fault handler\n",
regs->tpc); regs->tpc);
__asm__("mov %%sp, %0" : "=r" (ksp)); __asm__("mov %%sp, %0" : "=r" (ksp));
show_trace_raw(current_thread_info(), ksp); show_stack(current, ksp);
unhandled_fault(regs->tpc, current, regs); unhandled_fault(regs->tpc, current, regs);
} }
......
...@@ -390,7 +390,7 @@ struct sol_statvfs64 { ...@@ -390,7 +390,7 @@ struct sol_statvfs64 {
static int report_statvfs(struct vfsmount *mnt, struct inode *inode, u32 buf) static int report_statvfs(struct vfsmount *mnt, struct inode *inode, u32 buf)
{ {
struct statfs s; struct kstatfs s;
int error; int error;
struct sol_statvfs *ss = (struct sol_statvfs *)A(buf); struct sol_statvfs *ss = (struct sol_statvfs *)A(buf);
...@@ -424,7 +424,7 @@ static int report_statvfs(struct vfsmount *mnt, struct inode *inode, u32 buf) ...@@ -424,7 +424,7 @@ static int report_statvfs(struct vfsmount *mnt, struct inode *inode, u32 buf)
static int report_statvfs64(struct vfsmount *mnt, struct inode *inode, u32 buf) static int report_statvfs64(struct vfsmount *mnt, struct inode *inode, u32 buf)
{ {
struct statfs s; struct kstatfs s;
int error; int error;
struct sol_statvfs64 *ss = (struct sol_statvfs64 *)A(buf); struct sol_statvfs64 *ss = (struct sol_statvfs64 *)A(buf);
......
...@@ -60,12 +60,10 @@ ...@@ -60,12 +60,10 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/file.h> #include <linux/file.h>
#include <linux/bio.h>
#include <linux/stat.h> #include <linux/stat.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/major.h> #include <linux/major.h>
#include <linux/wait.h> #include <linux/wait.h>
#include <linux/blk.h>
#include <linux/blkpg.h> #include <linux/blkpg.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/devfs_fs_kernel.h> #include <linux/devfs_fs_kernel.h>
...@@ -144,7 +142,8 @@ struct loop_func_table *xfer_funcs[MAX_LO_CRYPT] = { ...@@ -144,7 +142,8 @@ struct loop_func_table *xfer_funcs[MAX_LO_CRYPT] = {
&xor_funcs &xor_funcs
}; };
static int figure_loop_size(struct loop_device *lo) static int
figure_loop_size(struct loop_device *lo)
{ {
loff_t size = lo->lo_backing_file->f_dentry->d_inode->i_mapping->host->i_size; loff_t size = lo->lo_backing_file->f_dentry->d_inode->i_mapping->host->i_size;
sector_t x; sector_t x;
...@@ -154,14 +153,16 @@ static int figure_loop_size(struct loop_device *lo) ...@@ -154,14 +153,16 @@ static int figure_loop_size(struct loop_device *lo)
*/ */
size = (size - lo->lo_offset) >> 9; size = (size - lo->lo_offset) >> 9;
x = (sector_t)size; x = (sector_t)size;
if ((loff_t)x != size) if ((loff_t)x != size)
return -EFBIG; return -EFBIG;
set_capacity(disks[lo->lo_number], size); set_capacity(disks[lo->lo_number], x);
return 0; return 0;
} }
static inline int lo_do_transfer(struct loop_device *lo, int cmd, char *rbuf, static inline int
lo_do_transfer(struct loop_device *lo, int cmd, char *rbuf,
char *lbuf, int size, sector_t rblock) char *lbuf, int size, sector_t rblock)
{ {
if (!lo->transfer) if (!lo->transfer)
...@@ -614,9 +615,12 @@ static int loop_thread(void *data) ...@@ -614,9 +615,12 @@ static int loop_thread(void *data)
daemonize("loop%d", lo->lo_number); daemonize("loop%d", lo->lo_number);
current->flags |= PF_IOTHREAD; /* loop can be used in an encrypted device /*
hence, it mustn't be stopped at all because it could * loop can be used in an encrypted device,
be indirectly used during suspension */ * hence, it mustn't be stopped at all
* because it could be indirectly used during suspension
*/
current->flags |= PF_IOTHREAD;
set_user_nice(current, -20); set_user_nice(current, -20);
...@@ -771,33 +775,39 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, ...@@ -771,33 +775,39 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
return error; return error;
} }
static int loop_release_xfer(struct loop_device *lo) static int
loop_release_xfer(struct loop_device *lo)
{ {
int err = 0; int err = 0;
if (lo->lo_encrypt_type) { struct loop_func_table *xfer = lo->lo_encryption;
struct loop_func_table *xfer= xfer_funcs[lo->lo_encrypt_type];
if (xfer && xfer->release) if (xfer) {
if (xfer->release)
err = xfer->release(lo); err = xfer->release(lo);
if (xfer && xfer->unlock) lo->transfer = NULL;
xfer->unlock(lo); lo->lo_encryption = NULL;
lo->lo_encrypt_type = 0; module_put(xfer->owner);
} }
return err; return err;
} }
static int static int
loop_init_xfer(struct loop_device *lo, int type, const struct loop_info64 *i) loop_init_xfer(struct loop_device *lo, struct loop_func_table *xfer,
const struct loop_info64 *i)
{ {
int err = 0; int err = 0;
if (type) {
struct loop_func_table *xfer = xfer_funcs[type]; if (xfer) {
struct module *owner = xfer->owner;
if (!try_module_get(owner))
return -EINVAL;
if (xfer->init) if (xfer->init)
err = xfer->init(lo, i); err = xfer->init(lo, i);
if (!err) { if (err)
lo->lo_encrypt_type = type; module_put(owner);
if (xfer->lock) else
xfer->lock(lo); lo->lo_encryption = xfer;
}
} }
return err; return err;
} }
...@@ -809,9 +819,11 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) ...@@ -809,9 +819,11 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
if (lo->lo_state != Lo_bound) if (lo->lo_state != Lo_bound)
return -ENXIO; return -ENXIO;
if (lo->lo_refcnt > 1) /* we needed one fd for the ioctl */ if (lo->lo_refcnt > 1) /* we needed one fd for the ioctl */
return -EBUSY; return -EBUSY;
if (filp==NULL)
if (filp == NULL)
return -EINVAL; return -EINVAL;
spin_lock_irq(&lo->lo_lock); spin_lock_irq(&lo->lo_lock);
...@@ -828,7 +840,7 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev) ...@@ -828,7 +840,7 @@ static int loop_clr_fd(struct loop_device *lo, struct block_device *bdev)
lo->transfer = NULL; lo->transfer = NULL;
lo->ioctl = NULL; lo->ioctl = NULL;
lo->lo_device = NULL; lo->lo_device = NULL;
lo->lo_encrypt_type = 0; lo->lo_encryption = NULL;
lo->lo_offset = 0; lo->lo_offset = 0;
lo->lo_encrypt_key_size = 0; lo->lo_encrypt_key_size = 0;
lo->lo_flags = 0; lo->lo_flags = 0;
...@@ -849,8 +861,7 @@ static int ...@@ -849,8 +861,7 @@ static int
loop_set_status(struct loop_device *lo, const struct loop_info64 *info) loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
{ {
int err; int err;
unsigned int type; struct loop_func_table *xfer;
loff_t offset;
if (lo->lo_encrypt_key_size && lo->lo_key_owner != current->uid && if (lo->lo_encrypt_key_size && lo->lo_key_owner != current->uid &&
!capable(CAP_SYS_ADMIN)) !capable(CAP_SYS_ADMIN))
...@@ -859,32 +870,39 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info) ...@@ -859,32 +870,39 @@ loop_set_status(struct loop_device *lo, const struct loop_info64 *info)
return -ENXIO; return -ENXIO;
if ((unsigned int) info->lo_encrypt_key_size > LO_KEY_SIZE) if ((unsigned int) info->lo_encrypt_key_size > LO_KEY_SIZE)
return -EINVAL; return -EINVAL;
type = info->lo_encrypt_type;
if (type >= MAX_LO_CRYPT || xfer_funcs[type] == NULL)
return -EINVAL;
if (type == LO_CRYPT_XOR && info->lo_encrypt_key_size == 0)
return -EINVAL;
err = loop_release_xfer(lo); err = loop_release_xfer(lo);
if (!err) if (err)
err = loop_init_xfer(lo, type, info); return err;
offset = lo->lo_offset; if (info->lo_encrypt_type) {
if (offset != info->lo_offset) { unsigned int type = info->lo_encrypt_type;
lo->lo_offset = info->lo_offset;
if (figure_loop_size(lo)){ if (type >= MAX_LO_CRYPT)
err = -EFBIG; return -EINVAL;
lo->lo_offset = offset; xfer = xfer_funcs[type];
} if (xfer == NULL)
} return -EINVAL;
} else
xfer = NULL;
err = loop_init_xfer(lo, xfer, info);
if (err) if (err)
return err; return err;
if (lo->lo_offset != info->lo_offset) {
lo->lo_offset = info->lo_offset;
if (figure_loop_size(lo))
return -EFBIG;
}
strlcpy(lo->lo_name, info->lo_name, LO_NAME_SIZE); strlcpy(lo->lo_name, info->lo_name, LO_NAME_SIZE);
lo->transfer = xfer_funcs[type]->transfer; if (!xfer)
lo->ioctl = xfer_funcs[type]->ioctl; xfer = &none_funcs;
lo->transfer = xfer->transfer;
lo->ioctl = xfer->ioctl;
lo->lo_encrypt_key_size = info->lo_encrypt_key_size; lo->lo_encrypt_key_size = info->lo_encrypt_key_size;
lo->lo_init[0] = info->lo_init[0]; lo->lo_init[0] = info->lo_init[0];
lo->lo_init[1] = info->lo_init[1]; lo->lo_init[1] = info->lo_init[1];
...@@ -917,7 +935,8 @@ loop_get_status(struct loop_device *lo, struct loop_info64 *info) ...@@ -917,7 +935,8 @@ loop_get_status(struct loop_device *lo, struct loop_info64 *info)
info->lo_offset = lo->lo_offset; info->lo_offset = lo->lo_offset;
info->lo_flags = lo->lo_flags; info->lo_flags = lo->lo_flags;
strlcpy(info->lo_name, lo->lo_name, LO_NAME_SIZE); strlcpy(info->lo_name, lo->lo_name, LO_NAME_SIZE);
info->lo_encrypt_type = lo->lo_encrypt_type; info->lo_encrypt_type =
lo->lo_encryption ? lo->lo_encryption->number : 0;
if (lo->lo_encrypt_key_size && capable(CAP_SYS_ADMIN)) { if (lo->lo_encrypt_key_size && capable(CAP_SYS_ADMIN)) {
info->lo_encrypt_key_size = lo->lo_encrypt_key_size; info->lo_encrypt_key_size = lo->lo_encrypt_key_size;
memcpy(info->lo_encrypt_key, lo->lo_encrypt_key, memcpy(info->lo_encrypt_key, lo->lo_encrypt_key,
...@@ -1060,30 +1079,22 @@ static int lo_ioctl(struct inode * inode, struct file * file, ...@@ -1060,30 +1079,22 @@ static int lo_ioctl(struct inode * inode, struct file * file,
static int lo_open(struct inode *inode, struct file *file) static int lo_open(struct inode *inode, struct file *file)
{ {
struct loop_device *lo = inode->i_bdev->bd_disk->private_data; struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
int type;
down(&lo->lo_ctl_mutex); down(&lo->lo_ctl_mutex);
type = lo->lo_encrypt_type;
if (type && xfer_funcs[type] && xfer_funcs[type]->lock)
xfer_funcs[type]->lock(lo);
lo->lo_refcnt++; lo->lo_refcnt++;
up(&lo->lo_ctl_mutex); up(&lo->lo_ctl_mutex);
return 0; return 0;
} }
static int lo_release(struct inode *inode, struct file *file) static int lo_release(struct inode *inode, struct file *file)
{ {
struct loop_device *lo = inode->i_bdev->bd_disk->private_data; struct loop_device *lo = inode->i_bdev->bd_disk->private_data;
int type;
down(&lo->lo_ctl_mutex); down(&lo->lo_ctl_mutex);
type = lo->lo_encrypt_type;
--lo->lo_refcnt; --lo->lo_refcnt;
if (xfer_funcs[type] && xfer_funcs[type]->unlock)
xfer_funcs[type]->unlock(lo);
up(&lo->lo_ctl_mutex); up(&lo->lo_ctl_mutex);
return 0; return 0;
} }
...@@ -1103,27 +1114,34 @@ MODULE_LICENSE("GPL"); ...@@ -1103,27 +1114,34 @@ MODULE_LICENSE("GPL");
int loop_register_transfer(struct loop_func_table *funcs) int loop_register_transfer(struct loop_func_table *funcs)
{ {
if ((unsigned)funcs->number > MAX_LO_CRYPT || xfer_funcs[funcs->number]) unsigned int n = funcs->number;
if (n >= MAX_LO_CRYPT || xfer_funcs[n])
return -EINVAL; return -EINVAL;
xfer_funcs[funcs->number] = funcs; xfer_funcs[n] = funcs;
return 0; return 0;
} }
int loop_unregister_transfer(int number) int loop_unregister_transfer(int number)
{ {
unsigned int n = number;
struct loop_device *lo; struct loop_device *lo;
struct loop_func_table *xfer;
if ((unsigned)number >= MAX_LO_CRYPT) if (n == 0 || n >= MAX_LO_CRYPT || (xfer = xfer_funcs[n]) == NULL)
return -EINVAL; return -EINVAL;
xfer_funcs[n] = NULL;
for (lo = &loop_dev[0]; lo < &loop_dev[max_loop]; lo++) { for (lo = &loop_dev[0]; lo < &loop_dev[max_loop]; lo++) {
int type = lo->lo_encrypt_type; down(&lo->lo_ctl_mutex);
if (type == number) {
xfer_funcs[type]->release(lo); if (lo->lo_encryption == xfer)
lo->transfer = NULL; loop_release_xfer(lo);
lo->lo_encrypt_type = 0;
} up(&lo->lo_ctl_mutex);
} }
xfer_funcs[number] = NULL;
return 0; return 0;
} }
...@@ -1193,6 +1211,7 @@ int __init loop_init(void) ...@@ -1193,6 +1211,7 @@ int __init loop_init(void)
void loop_exit(void) void loop_exit(void)
{ {
int i; int i;
for (i = 0; i < max_loop; i++) { for (i = 0; i < max_loop; i++) {
del_gendisk(disks[i]); del_gendisk(disks[i]);
put_disk(disks[i]); put_disk(disks[i]);
......
...@@ -28,6 +28,9 @@ ...@@ -28,6 +28,9 @@
* the transmit lock. <steve@chygwyn.com> * the transmit lock. <steve@chygwyn.com>
* 02-10-11 Allow hung xmit to be aborted via SIGKILL & various fixes. * 02-10-11 Allow hung xmit to be aborted via SIGKILL & various fixes.
* <Paul.Clements@SteelEye.com> <James.Bottomley@SteelEye.com> * <Paul.Clements@SteelEye.com> <James.Bottomley@SteelEye.com>
* 03-06-22 Make nbd work with new linux 2.5 block layer design. This fixes
* memory corruption from module removal and possible memory corruption
* from sending/receiving disk data. <ldl@aros.net>
* *
* possible FIXME: make set_sock / set_blksize / set_size / do_it one syscall * possible FIXME: make set_sock / set_blksize / set_size / do_it one syscall
* why not: would need verify_area and friends, would share yet another * why not: would need verify_area and friends, would share yet another
...@@ -63,6 +66,16 @@ ...@@ -63,6 +66,16 @@
static struct nbd_device nbd_dev[MAX_NBD]; static struct nbd_device nbd_dev[MAX_NBD];
/*
* Use just one lock (or at most 1 per NIC). Two arguments for this:
* 1. Each NIC is essentially a synchronization point for all servers
* accessed through that NIC so there's no need to have more locks
* than NICs anyway.
* 2. More locks lead to more "Dirty cache line bouncing" which will slow
* down each lock to the point where they're actually slower than just
* a single lock.
* Thanks go to Jens Axboe and Al Viro for their LKML emails explaining this!
*/
static spinlock_t nbd_lock = SPIN_LOCK_UNLOCKED; static spinlock_t nbd_lock = SPIN_LOCK_UNLOCKED;
#define DEBUG( s ) #define DEBUG( s )
...@@ -168,6 +181,17 @@ static int nbd_xmit(int send, struct socket *sock, char *buf, int size, int msg_ ...@@ -168,6 +181,17 @@ static int nbd_xmit(int send, struct socket *sock, char *buf, int size, int msg_
return result; return result;
} }
static inline int sock_send_bvec(struct socket *sock, struct bio_vec *bvec,
int flags)
{
int result;
void *kaddr = kmap(bvec->bv_page);
result = nbd_xmit(1, sock, kaddr + bvec->bv_offset, bvec->bv_len,
flags);
kunmap(bvec->bv_page);
return result;
}
#define FAIL( s ) { printk( KERN_ERR "NBD: " s "(result %d)\n", result ); goto error_out; } #define FAIL( s ) { printk( KERN_ERR "NBD: " s "(result %d)\n", result ); goto error_out; }
void nbd_send_req(struct nbd_device *lo, struct request *req) void nbd_send_req(struct nbd_device *lo, struct request *req)
...@@ -209,7 +233,7 @@ void nbd_send_req(struct nbd_device *lo, struct request *req) ...@@ -209,7 +233,7 @@ void nbd_send_req(struct nbd_device *lo, struct request *req)
if ((i < (bio->bi_vcnt - 1)) || bio->bi_next) if ((i < (bio->bi_vcnt - 1)) || bio->bi_next)
flags = MSG_MORE; flags = MSG_MORE;
DEBUG("data, "); DEBUG("data, ");
result = nbd_xmit(1, sock, page_address(bvec->bv_page) + bvec->bv_offset, bvec->bv_len, flags); result = sock_send_bvec(sock, bvec, flags);
if (result <= 0) if (result <= 0)
FAIL("Send data failed."); FAIL("Send data failed.");
} }
...@@ -244,6 +268,16 @@ static struct request *nbd_find_request(struct nbd_device *lo, char *handle) ...@@ -244,6 +268,16 @@ static struct request *nbd_find_request(struct nbd_device *lo, char *handle)
return NULL; return NULL;
} }
static inline int sock_recv_bvec(struct socket *sock, struct bio_vec *bvec)
{
int result;
void *kaddr = kmap(bvec->bv_page);
result = nbd_xmit(0, sock, kaddr + bvec->bv_offset, bvec->bv_len,
MSG_WAITALL);
kunmap(bvec->bv_page);
return result;
}
#define HARDFAIL( s ) { printk( KERN_ERR "NBD: " s "(result %d)\n", result ); lo->harderror = result; return NULL; } #define HARDFAIL( s ) { printk( KERN_ERR "NBD: " s "(result %d)\n", result ); lo->harderror = result; return NULL; }
struct request *nbd_read_stat(struct nbd_device *lo) struct request *nbd_read_stat(struct nbd_device *lo)
/* NULL returned = something went wrong, inform userspace */ /* NULL returned = something went wrong, inform userspace */
...@@ -251,10 +285,11 @@ struct request *nbd_read_stat(struct nbd_device *lo) ...@@ -251,10 +285,11 @@ struct request *nbd_read_stat(struct nbd_device *lo)
int result; int result;
struct nbd_reply reply; struct nbd_reply reply;
struct request *req; struct request *req;
struct socket *sock = lo->sock;
DEBUG("reading control, "); DEBUG("reading control, ");
reply.magic = 0; reply.magic = 0;
result = nbd_xmit(0, lo->sock, (char *) &reply, sizeof(reply), MSG_WAITALL); result = nbd_xmit(0, sock, (char *) &reply, sizeof(reply), MSG_WAITALL);
if (result <= 0) if (result <= 0)
HARDFAIL("Recv control failed."); HARDFAIL("Recv control failed.");
req = nbd_find_request(lo, reply.handle); req = nbd_find_request(lo, reply.handle);
...@@ -268,14 +303,17 @@ struct request *nbd_read_stat(struct nbd_device *lo) ...@@ -268,14 +303,17 @@ struct request *nbd_read_stat(struct nbd_device *lo)
FAIL("Other side returned error."); FAIL("Other side returned error.");
if (nbd_cmd(req) == NBD_CMD_READ) { if (nbd_cmd(req) == NBD_CMD_READ) {
struct bio *bio = req->bio; int i;
struct bio *bio;
DEBUG("data, "); DEBUG("data, ");
do { rq_for_each_bio(bio, req) {
result = nbd_xmit(0, lo->sock, bio_data(bio), bio->bi_size, MSG_WAITALL); struct bio_vec *bvec;
bio_for_each_segment(bvec, bio, i) {
result = sock_recv_bvec(sock, bvec);
if (result <= 0) if (result <= 0)
HARDFAIL("Recv data failed."); HARDFAIL("Recv data failed.");
bio = bio->bi_next; }
} while(bio); }
} }
DEBUG("done.\n"); DEBUG("done.\n");
return req; return req;
...@@ -538,8 +576,6 @@ static struct block_device_operations nbd_fops = ...@@ -538,8 +576,6 @@ static struct block_device_operations nbd_fops =
* (Just smiley confuses emacs :-) * (Just smiley confuses emacs :-)
*/ */
static struct request_queue nbd_queue;
static int __init nbd_init(void) static int __init nbd_init(void)
{ {
int err = -ENOMEM; int err = -ENOMEM;
...@@ -555,6 +591,17 @@ static int __init nbd_init(void) ...@@ -555,6 +591,17 @@ static int __init nbd_init(void)
if (!disk) if (!disk)
goto out; goto out;
nbd_dev[i].disk = disk; nbd_dev[i].disk = disk;
/*
* The new linux 2.5 block layer implementation requires
* every gendisk to have its very own request_queue struct.
* These structs are big so we dynamically allocate them.
*/
disk->queue = kmalloc(sizeof(struct request_queue), GFP_KERNEL);
if (!disk->queue) {
put_disk(disk);
goto out;
}
blk_init_queue(disk->queue, do_nbd_request, &nbd_lock);
} }
if (register_blkdev(NBD_MAJOR, "nbd")) { if (register_blkdev(NBD_MAJOR, "nbd")) {
...@@ -564,7 +611,6 @@ static int __init nbd_init(void) ...@@ -564,7 +611,6 @@ static int __init nbd_init(void)
#ifdef MODULE #ifdef MODULE
printk("nbd: registered device at major %d\n", NBD_MAJOR); printk("nbd: registered device at major %d\n", NBD_MAJOR);
#endif #endif
blk_init_queue(&nbd_queue, do_nbd_request, &nbd_lock);
devfs_mk_dir("nbd"); devfs_mk_dir("nbd");
for (i = 0; i < MAX_NBD; i++) { for (i = 0; i < MAX_NBD; i++) {
struct gendisk *disk = nbd_dev[i].disk; struct gendisk *disk = nbd_dev[i].disk;
...@@ -582,7 +628,6 @@ static int __init nbd_init(void) ...@@ -582,7 +628,6 @@ static int __init nbd_init(void)
disk->first_minor = i; disk->first_minor = i;
disk->fops = &nbd_fops; disk->fops = &nbd_fops;
disk->private_data = &nbd_dev[i]; disk->private_data = &nbd_dev[i];
disk->queue = &nbd_queue;
sprintf(disk->disk_name, "nbd%d", i); sprintf(disk->disk_name, "nbd%d", i);
sprintf(disk->devfs_name, "nbd/%d", i); sprintf(disk->devfs_name, "nbd/%d", i);
set_capacity(disk, 0x3ffffe); set_capacity(disk, 0x3ffffe);
...@@ -591,8 +636,10 @@ static int __init nbd_init(void) ...@@ -591,8 +636,10 @@ static int __init nbd_init(void)
return 0; return 0;
out: out:
while (i--) while (i--) {
kfree(nbd_dev[i].disk->queue);
put_disk(nbd_dev[i].disk); put_disk(nbd_dev[i].disk);
}
return err; return err;
} }
...@@ -600,12 +647,22 @@ static void __exit nbd_cleanup(void) ...@@ -600,12 +647,22 @@ static void __exit nbd_cleanup(void)
{ {
int i; int i;
for (i = 0; i < MAX_NBD; i++) { for (i = 0; i < MAX_NBD; i++) {
del_gendisk(nbd_dev[i].disk); struct gendisk *disk = nbd_dev[i].disk;
put_disk(nbd_dev[i].disk); if (disk) {
if (disk->queue) {
blk_cleanup_queue(disk->queue);
kfree(disk->queue);
disk->queue = NULL;
}
del_gendisk(disk);
put_disk(disk);
}
} }
devfs_remove("nbd"); devfs_remove("nbd");
blk_cleanup_queue(&nbd_queue);
unregister_blkdev(NBD_MAJOR, "nbd"); unregister_blkdev(NBD_MAJOR, "nbd");
#ifdef MODULE
printk("nbd: unregistered device at major %d\n", NBD_MAJOR);
#endif
} }
module_init(nbd_init); module_init(nbd_init);
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
This is access code for flashes using ARM's flash partitioning This is access code for flashes using ARM's flash partitioning
standards. standards.
$Id: afs.c,v 1.11 2003/05/16 17:08:24 dwmw2 Exp $ $Id: afs.c,v 1.12 2003/06/13 15:31:06 rmk Exp $
======================================================================*/ ======================================================================*/
...@@ -76,17 +76,19 @@ afs_read_footer(struct mtd_info *mtd, u_int *img_start, u_int *iis_start, ...@@ -76,17 +76,19 @@ afs_read_footer(struct mtd_info *mtd, u_int *img_start, u_int *iis_start,
return ret; return ret;
} }
ret = 1;
/* /*
* Does it contain the magic number? * Does it contain the magic number?
*/ */
if (fs.signature != 0xa0ffff9f) if (fs.signature != 0xa0ffff9f)
ret = 1; ret = 0;
/* /*
* Don't touch the SIB. * Don't touch the SIB.
*/ */
if (fs.type == 2) if (fs.type == 2)
ret = 1; ret = 0;
*iis_start = fs.image_info_base & mask; *iis_start = fs.image_info_base & mask;
*img_start = fs.image_start & mask; *img_start = fs.image_start & mask;
...@@ -96,14 +98,14 @@ afs_read_footer(struct mtd_info *mtd, u_int *img_start, u_int *iis_start, ...@@ -96,14 +98,14 @@ afs_read_footer(struct mtd_info *mtd, u_int *img_start, u_int *iis_start,
* be located after the footer structure. * be located after the footer structure.
*/ */
if (*iis_start >= ptr) if (*iis_start >= ptr)
ret = 1; ret = 0;
/* /*
* Check the start of this image. The image * Check the start of this image. The image
* data can not be located after this block. * data can not be located after this block.
*/ */
if (*img_start > off) if (*img_start > off)
ret = 1; ret = 0;
return ret; return ret;
} }
...@@ -152,7 +154,7 @@ static int parse_afs_partitions(struct mtd_info *mtd, ...@@ -152,7 +154,7 @@ static int parse_afs_partitions(struct mtd_info *mtd,
ret = afs_read_footer(mtd, &img_ptr, &iis_ptr, off, mask); ret = afs_read_footer(mtd, &img_ptr, &iis_ptr, off, mask);
if (ret < 0) if (ret < 0)
break; break;
if (ret == 1) if (ret == 0)
continue; continue;
ret = afs_read_iis(mtd, &iis, iis_ptr); ret = afs_read_iis(mtd, &iis, iis_ptr);
...@@ -185,7 +187,7 @@ static int parse_afs_partitions(struct mtd_info *mtd, ...@@ -185,7 +187,7 @@ static int parse_afs_partitions(struct mtd_info *mtd,
ret = afs_read_footer(mtd, &img_ptr, &iis_ptr, off, mask); ret = afs_read_footer(mtd, &img_ptr, &iis_ptr, off, mask);
if (ret < 0) if (ret < 0)
break; break;
if (ret == 1) if (ret == 0)
continue; continue;
/* Read the image info block */ /* Read the image info block */
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* Author: Jonas Holmberg <jonas.holmberg@axis.com> * Author: Jonas Holmberg <jonas.holmberg@axis.com>
* *
* $Id: amd_flash.c,v 1.22 2003/05/28 13:47:19 dwmw2 Exp $ * $Id: amd_flash.c,v 1.23 2003/06/12 09:24:13 dwmw2 Exp $
* *
* Copyright (c) 2001 Axis Communications AB * Copyright (c) 2001 Axis Communications AB
* *
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/mtd/map.h> #include <linux/mtd/map.h>
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/flashchip.h> #include <linux/mtd/flashchip.h>
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* *
* (C) 2000 Red Hat. GPL'd * (C) 2000 Red Hat. GPL'd
* *
* $Id: cfi_cmdset_0001.c,v 1.123 2003/05/28 12:51:48 dwmw2 Exp $ * $Id: cfi_cmdset_0001.c,v 1.126 2003/06/23 07:45:48 dwmw2 Exp $
* *
* *
* 10/10/2000 Nicolas Pitre <nico@cam.org> * 10/10/2000 Nicolas Pitre <nico@cam.org>
...@@ -936,7 +936,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip, ...@@ -936,7 +936,7 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
struct cfi_private *cfi = map->fldrv_priv; struct cfi_private *cfi = map->fldrv_priv;
cfi_word status, status_OK; cfi_word status, status_OK;
unsigned long cmd_adr, timeo; unsigned long cmd_adr, timeo;
int wbufsize, z, ret=0; int wbufsize, z, ret=0, bytes, words;
wbufsize = CFIDEV_INTERLEAVE << cfi->cfiq->MaxBufWriteSize; wbufsize = CFIDEV_INTERLEAVE << cfi->cfiq->MaxBufWriteSize;
adr += chip->start; adr += chip->start;
...@@ -995,10 +995,13 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip, ...@@ -995,10 +995,13 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
} }
/* Write length of data to come */ /* Write length of data to come */
cfi_write(map, CMD(len/CFIDEV_BUSWIDTH-1), cmd_adr ); bytes = len & (CFIDEV_BUSWIDTH-1);
words = len / CFIDEV_BUSWIDTH;
cfi_write(map, CMD(words - !bytes), cmd_adr );
/* Write data */ /* Write data */
for (z = 0; z < len; z += CFIDEV_BUSWIDTH) { z = 0;
while(z < words * CFIDEV_BUSWIDTH) {
if (cfi_buswidth_is_1()) { if (cfi_buswidth_is_1()) {
map_write8 (map, *((__u8*)buf)++, adr+z); map_write8 (map, *((__u8*)buf)++, adr+z);
} else if (cfi_buswidth_is_2()) { } else if (cfi_buswidth_is_2()) {
...@@ -1011,6 +1014,26 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip, ...@@ -1011,6 +1014,26 @@ static inline int do_write_buffer(struct map_info *map, struct flchip *chip,
ret = -EINVAL; ret = -EINVAL;
goto out; goto out;
} }
z += CFIDEV_BUSWIDTH;
}
if (bytes) {
int i = 0, n = 0;
u_char tmp_buf[8], *tmp_p = tmp_buf;
while (bytes--)
tmp_buf[i++] = buf[n++];
while (i < CFIDEV_BUSWIDTH)
tmp_buf[i++] = 0xff;
if (cfi_buswidth_is_2()) {
map_write16 (map, *((__u16*)tmp_p)++, adr+z);
} else if (cfi_buswidth_is_4()) {
map_write32 (map, *((__u32*)tmp_p)++, adr+z);
} else if (cfi_buswidth_is_8()) {
map_write64 (map, *((__u64*)tmp_p)++, adr+z);
} else {
ret = -EINVAL;
goto out;
}
} }
/* GO GO GO */ /* GO GO GO */
cfi_write(map, CMD(0xd0), cmd_adr); cfi_write(map, CMD(0xd0), cmd_adr);
...@@ -1119,12 +1142,12 @@ static int cfi_intelext_write_buffers (struct mtd_info *mtd, loff_t to, ...@@ -1119,12 +1142,12 @@ static int cfi_intelext_write_buffers (struct mtd_info *mtd, loff_t to,
} }
/* Write buffer is worth it only if more than one word to write... */ /* Write buffer is worth it only if more than one word to write... */
while(len > CFIDEV_BUSWIDTH) { while(len) {
/* We must not cross write block boundaries */ /* We must not cross write block boundaries */
int size = wbufsize - (ofs & (wbufsize-1)); int size = wbufsize - (ofs & (wbufsize-1));
if (size > len) if (size > len)
size = len & ~(CFIDEV_BUSWIDTH-1); size = len;
ret = do_write_buffer(map, &cfi->chips[chipnum], ret = do_write_buffer(map, &cfi->chips[chipnum],
ofs, buf, size); ofs, buf, size);
if (ret) if (ret)
...@@ -1142,17 +1165,6 @@ static int cfi_intelext_write_buffers (struct mtd_info *mtd, loff_t to, ...@@ -1142,17 +1165,6 @@ static int cfi_intelext_write_buffers (struct mtd_info *mtd, loff_t to,
return 0; return 0;
} }
} }
/* ... and write the remaining bytes */
if (len > 0) {
size_t local_retlen;
ret = cfi_intelext_write_words(mtd, ofs + (chipnum << cfi->chipshift),
len, &local_retlen, buf);
if (ret)
return ret;
(*retlen) += local_retlen;
}
return 0; return 0;
} }
...@@ -1423,6 +1435,7 @@ static void cfi_intelext_sync (struct mtd_info *mtd) ...@@ -1423,6 +1435,7 @@ static void cfi_intelext_sync (struct mtd_info *mtd)
* with the chip now anyway. * with the chip now anyway.
*/ */
} }
spin_unlock(chip->mutex);
} }
/* Unlock the chips again */ /* Unlock the chips again */
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* (c) 1999 Machine Vision Holdings, Inc. * (c) 1999 Machine Vision Holdings, Inc.
* (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org> * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
* *
* $Id: doc2000.c,v 1.52 2003/05/20 21:03:07 dwmw2 Exp $ * $Id: doc2000.c,v 1.53 2003/06/11 09:45:19 dwmw2 Exp $
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -553,6 +553,7 @@ static void DoC2k_init(struct mtd_info *mtd) ...@@ -553,6 +553,7 @@ static void DoC2k_init(struct mtd_info *mtd)
mtd->type = MTD_NANDFLASH; mtd->type = MTD_NANDFLASH;
mtd->flags = MTD_CAP_NANDFLASH; mtd->flags = MTD_CAP_NANDFLASH;
mtd->ecctype = MTD_ECC_RS_DiskOnChip;
mtd->size = 0; mtd->size = 0;
mtd->erasesize = 0; mtd->erasesize = 0;
mtd->oobblock = 512; mtd->oobblock = 512;
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* (c) 1999 Machine Vision Holdings, Inc. * (c) 1999 Machine Vision Holdings, Inc.
* (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org> * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
* *
* $Id: doc2001.c,v 1.40 2003/05/20 21:03:07 dwmw2 Exp $ * $Id: doc2001.c,v 1.41 2003/06/11 09:45:19 dwmw2 Exp $
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -359,9 +359,10 @@ static void DoCMil_init(struct mtd_info *mtd) ...@@ -359,9 +359,10 @@ static void DoCMil_init(struct mtd_info *mtd)
mtd->type = MTD_NANDFLASH; mtd->type = MTD_NANDFLASH;
mtd->flags = MTD_CAP_NANDFLASH; mtd->flags = MTD_CAP_NANDFLASH;
mtd->ecctype = MTD_ECC_RS_DiskOnChip;
mtd->size = 0; mtd->size = 0;
/* FIXME: erase size is not always 8kB */ /* FIXME: erase size is not always 8KiB */
mtd->erasesize = 0x2000; mtd->erasesize = 0x2000;
mtd->oobblock = 512; mtd->oobblock = 512;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* (c) 1999 Machine Vision Holdings, Inc. * (c) 1999 Machine Vision Holdings, Inc.
* (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org> * (c) 1999, 2000 David Woodhouse <dwmw2@infradead.org>
* *
* $Id: doc2001plus.c,v 1.4 2003/05/23 11:28:46 dwmw2 Exp $ * $Id: doc2001plus.c,v 1.5 2003/06/11 09:45:19 dwmw2 Exp $
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -458,6 +458,7 @@ static void DoCMilPlus_init(struct mtd_info *mtd) ...@@ -458,6 +458,7 @@ static void DoCMilPlus_init(struct mtd_info *mtd)
mtd->type = MTD_NANDFLASH; mtd->type = MTD_NANDFLASH;
mtd->flags = MTD_CAP_NANDFLASH; mtd->flags = MTD_CAP_NANDFLASH;
mtd->ecctype = MTD_ECC_RS_DiskOnChip;
mtd->size = 0; mtd->size = 0;
mtd->erasesize = 0; mtd->erasesize = 0;
......
/* This version ported to the Linux-MTD system by dwmw2@infradead.org /* This version ported to the Linux-MTD system by dwmw2@infradead.org
* $Id: ftl.c,v 1.50 2003/05/21 10:49:47 dwmw2 Exp $ * $Id: ftl.c,v 1.51 2003/06/23 12:00:08 dwmw2 Exp $
* *
* Fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br> * Fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
* - fixes some leaks on failure in build_maps and ftl_notify_add, cleanups * - fixes some leaks on failure in build_maps and ftl_notify_add, cleanups
...@@ -984,37 +984,20 @@ static int ftl_write(partition_t *part, caddr_t buffer, ...@@ -984,37 +984,20 @@ static int ftl_write(partition_t *part, caddr_t buffer,
return 0; return 0;
} /* ftl_write */ } /* ftl_write */
/*====================================================================== static int ftl_getgeo(struct mtd_blktrans_dev *dev, struct hd_geometry *geo)
IOCTL calls for getting device parameters.
======================================================================*/
static int ftl_ioctl(struct mtd_blktrans_dev *dev, struct inode *inode,
struct file *file, u_int cmd, u_long arg)
{ {
struct hd_geometry *geo = (struct hd_geometry *)arg;
partition_t *part = (void *)dev; partition_t *part = (void *)dev;
u_long sect; u_long sect;
switch (cmd) { /* Sort of arbitrary: round size down to 4KiB boundary */
case HDIO_GETGEO:
/* Sort of arbitrary: round size down to 4K boundary */
sect = le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE; sect = le32_to_cpu(part->header.FormattedSize)/SECTOR_SIZE;
if (put_user(1, (char *)&geo->heads) ||
put_user(8, (char *)&geo->sectors) ||
put_user((sect>>3), (short *)&geo->cylinders) ||
put_user(0, (u_long *)&geo->start))
return -EFAULT;
case BLKFLSBUF:
return 0;
}
return -ENOTTY;
} /* ftl_ioctl */
geo->heads = 1;
geo->sectors = 8;
geo->cylinders = sect >> 3;
/*======================================================================*/ return 0;
}
static int ftl_readsect(struct mtd_blktrans_dev *dev, static int ftl_readsect(struct mtd_blktrans_dev *dev,
unsigned long block, char *buf) unsigned long block, char *buf)
...@@ -1102,7 +1085,7 @@ struct mtd_blktrans_ops ftl_tr = { ...@@ -1102,7 +1085,7 @@ struct mtd_blktrans_ops ftl_tr = {
.part_bits = PART_BITS, .part_bits = PART_BITS,
.readsect = ftl_readsect, .readsect = ftl_readsect,
.writesect = ftl_writesect, .writesect = ftl_writesect,
.ioctl = ftl_ioctl, .getgeo = ftl_getgeo,
.add_mtd = ftl_add_mtd, .add_mtd = ftl_add_mtd,
.remove_dev = ftl_remove_dev, .remove_dev = ftl_remove_dev,
.owner = THIS_MODULE, .owner = THIS_MODULE,
...@@ -1110,7 +1093,7 @@ struct mtd_blktrans_ops ftl_tr = { ...@@ -1110,7 +1093,7 @@ struct mtd_blktrans_ops ftl_tr = {
int init_ftl(void) int init_ftl(void)
{ {
DEBUG(0, "$Id: ftl.c,v 1.50 2003/05/21 10:49:47 dwmw2 Exp $\n"); DEBUG(0, "$Id: ftl.c,v 1.51 2003/06/23 12:00:08 dwmw2 Exp $\n");
return register_mtd_blktrans(&ftl_tr); return register_mtd_blktrans(&ftl_tr);
} }
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* (c) 1999 Machine Vision Holdings, Inc. * (c) 1999 Machine Vision Holdings, Inc.
* Author: David Woodhouse <dwmw2@infradead.org> * Author: David Woodhouse <dwmw2@infradead.org>
* *
* $Id: inftlcore.c,v 1.9 2003/05/23 11:41:47 dwmw2 Exp $ * $Id: inftlcore.c,v 1.11 2003/06/23 12:00:08 dwmw2 Exp $
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -113,7 +113,7 @@ static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) ...@@ -113,7 +113,7 @@ static void inftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
(long)inftl->sectors ); (long)inftl->sectors );
} }
if (add_mtd_blktrans_dev) { if (add_mtd_blktrans_dev(&inftl->mbd)) {
if (inftl->PUtable) if (inftl->PUtable)
kfree(inftl->PUtable); kfree(inftl->PUtable);
if (inftl->VUtable) if (inftl->VUtable)
...@@ -835,35 +835,22 @@ static int inftl_readblock(struct mtd_blktrans_dev *mbd, unsigned long block, ...@@ -835,35 +835,22 @@ static int inftl_readblock(struct mtd_blktrans_dev *mbd, unsigned long block,
return 0; return 0;
} }
static int inftl_getgeo(struct mtd_blktrans_dev *dev, struct hd_geometry *geo)
static int inftl_ioctl(struct mtd_blktrans_dev *dev,
struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg)
{ {
struct NFTLrecord *nftl = (void *)dev; struct NFTLrecord *nftl = (void *)dev;
switch (cmd) { geo->heads = nftl->heads;
case HDIO_GETGEO: { geo->sectors = nftl->sectors;
struct hd_geometry g; geo->cylinders = nftl->cylinders;
g.heads = nftl->heads;
g.sectors = nftl->sectors;
g.cylinders = nftl->cylinders;
g.start = 0;
return copy_to_user((void *)arg, &g, sizeof g) ? -EFAULT : 0;
}
default: return 0;
return -ENOTTY;
}
} }
struct mtd_blktrans_ops inftl_tr = { struct mtd_blktrans_ops inftl_tr = {
.name = "inftl", .name = "inftl",
.major = INFTL_MAJOR, .major = INFTL_MAJOR,
.part_bits = INFTL_PARTN_BITS, .part_bits = INFTL_PARTN_BITS,
.ioctl = inftl_ioctl, .getgeo = inftl_getgeo,
.readsect = inftl_readblock, .readsect = inftl_readblock,
.writesect = inftl_writeblock, .writesect = inftl_writeblock,
.add_mtd = inftl_add_mtd, .add_mtd = inftl_add_mtd,
...@@ -875,7 +862,7 @@ extern char inftlmountrev[]; ...@@ -875,7 +862,7 @@ extern char inftlmountrev[];
int __init init_inftl(void) int __init init_inftl(void)
{ {
printk(KERN_INFO "INFTL: inftlcore.c $Revision: 1.9 $, " printk(KERN_INFO "INFTL: inftlcore.c $Revision: 1.11 $, "
"inftlmount.c %s\n", inftlmountrev); "inftlmount.c %s\n", inftlmountrev);
return register_mtd_blktrans(&inftl_tr); return register_mtd_blktrans(&inftl_tr);
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Author: Fabrice Bellard (fabrice.bellard@netgem.com) * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
* Copyright (C) 2000 Netgem S.A. * Copyright (C) 2000 Netgem S.A.
* *
* $Id: inftlmount.c,v 1.9 2003/05/23 11:35:07 dwmw2 Exp $ * $Id: inftlmount.c,v 1.11 2003/06/23 07:39:21 dwmw2 Exp $
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#define __NO_VERSION__
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/module.h> #include <linux/module.h>
#include <asm/errno.h> #include <asm/errno.h>
...@@ -42,7 +41,7 @@ ...@@ -42,7 +41,7 @@
#include <linux/mtd/inftl.h> #include <linux/mtd/inftl.h>
#include <linux/mtd/compatmac.h> #include <linux/mtd/compatmac.h>
char inftlmountrev[]="$Revision: 1.9 $"; char inftlmountrev[]="$Revision: 1.11 $";
/* /*
* find_boot_record: Find the INFTL Media Header and its Spare copy which * find_boot_record: Find the INFTL Media Header and its Spare copy which
...@@ -242,7 +241,7 @@ static int find_boot_record(struct INFTLrecord *inftl) ...@@ -242,7 +241,7 @@ static int find_boot_record(struct INFTLrecord *inftl)
} }
if ((ip->lastUnit - ip->firstUnit + 1) < ip->virtualUnits) { if ((ip->lastUnit - ip->firstUnit + 1) < ip->virtualUnits) {
printk(KERN_WARNING "INFTL: Media Header " printk(KERN_WARNING "INFTL: Media Header "
"Parition %d sanity check failed\n" "Partition %d sanity check failed\n"
" firstUnit %d : lastUnit %d > " " firstUnit %d : lastUnit %d > "
"virtualUnits %d\n", i, ip->lastUnit, "virtualUnits %d\n", i, ip->lastUnit,
ip->firstUnit, ip->Reserved0); ip->firstUnit, ip->Reserved0);
...@@ -250,7 +249,7 @@ static int find_boot_record(struct INFTLrecord *inftl) ...@@ -250,7 +249,7 @@ static int find_boot_record(struct INFTLrecord *inftl)
} }
if (ip->Reserved1 != 0) { if (ip->Reserved1 != 0) {
printk(KERN_WARNING "INFTL: Media Header " printk(KERN_WARNING "INFTL: Media Header "
"Parition %d sanity check failed: " "Partition %d sanity check failed: "
"Reserved1 %d != 0\n", "Reserved1 %d != 0\n",
i, ip->Reserved1); i, ip->Reserved1);
return -1; return -1;
...@@ -261,7 +260,7 @@ static int find_boot_record(struct INFTLrecord *inftl) ...@@ -261,7 +260,7 @@ static int find_boot_record(struct INFTLrecord *inftl)
} }
if (i >= 4) { if (i >= 4) {
printk(KERN_WARNING "INFTL: Media Header Parition " printk(KERN_WARNING "INFTL: Media Header Partition "
"sanity check failed:\n No partition " "sanity check failed:\n No partition "
"marked as Disk Partition\n"); "marked as Disk Partition\n");
return -1; return -1;
...@@ -630,7 +629,7 @@ int INFTL_mount(struct INFTLrecord *s) ...@@ -630,7 +629,7 @@ int INFTL_mount(struct INFTLrecord *s)
if (prev_block < s->nb_blocks) if (prev_block < s->nb_blocks)
prev_block += s->firstEUN; prev_block += s->firstEUN;
/* Already explored paritial chain? */ /* Already explored partial chain? */
if (s->PUtable[block] != BLOCK_NOTEXPLORED) { if (s->PUtable[block] != BLOCK_NOTEXPLORED) {
/* Check if chain for this logical */ /* Check if chain for this logical */
if (logical_block == first_logical_block) { if (logical_block == first_logical_block) {
......
# drivers/mtd/maps/Kconfig # drivers/mtd/maps/Kconfig
# $Id: Kconfig,v 1.11 2003/05/28 15:16:56 dwmw2 Exp $ # $Id: Kconfig,v 1.12 2003/06/23 07:38:11 dwmw2 Exp $
menu "Mapping drivers for chip access" menu "Mapping drivers for chip access"
depends on MTD!=n depends on MTD!=n
...@@ -476,7 +476,7 @@ config MTD_PCMCIA ...@@ -476,7 +476,7 @@ config MTD_PCMCIA
config MTD_UCLINUX config MTD_UCLINUX
tristate "Generic uClinux RAM/ROM filesystem support" tristate "Generic uClinux RAM/ROM filesystem support"
depends on MTD_PARTITIONS depends on MTD_PARTITIONS && !MMU
help help
Map driver to support image based filesystems for uClinux. Map driver to support image based filesystems for uClinux.
......
/* /*
* $Id: arctic-mtd.c,v 1.8 2003/05/21 12:45:17 dwmw2 Exp $ * $Id: arctic-mtd.c,v 1.10 2003/06/02 16:37:59 trini Exp $
* *
* drivers/mtd/maps/arctic-mtd.c MTD mappings and partition tables for * drivers/mtd/maps/arctic-mtd.c MTD mappings and partition tables for
* IBM 405LP Arctic boards. * IBM 405LP Arctic boards.
...@@ -45,18 +45,23 @@ ...@@ -45,18 +45,23 @@
#include <asm/ibm4xx.h> #include <asm/ibm4xx.h>
/* /*
* fe000000 -- ff9fffff Arctic FFS (26MB) * 0 : 0xFE00 0000 - 0xFEFF FFFF : Filesystem 1 (16MiB)
* ffa00000 -- fff5ffff kernel (5.504MB) * 1 : 0xFF00 0000 - 0xFF4F FFFF : kernel (5.12MiB)
* fff60000 -- ffffffff firmware (640KB) * 2 : 0xFF50 0000 - 0xFFF5 FFFF : Filesystem 2 (10.624MiB) (if non-XIP)
* 3 : 0xFFF6 0000 - 0xFFFF FFFF : PIBS Firmware (640KiB)
*/ */
#define ARCTIC_FFS_SIZE 0x01a00000 /* 26 M */ #define FFS1_SIZE 0x01000000 /* 16MiB */
#define ARCTIC_FIRMWARE_SIZE 0x000a0000 /* 640K */ #define KERNEL_SIZE 0x00500000 /* 5.12MiB */
#define FFS2_SIZE 0x00a60000 /* 10.624MiB */
#define FIRMWARE_SIZE 0x000a0000 /* 640KiB */
#define NAME "Arctic Linux Flash" #define NAME "Arctic Linux Flash"
#define PADDR SUBZERO_BOOTFLASH_PADDR #define PADDR SUBZERO_BOOTFLASH_PADDR
#define SIZE SUBZERO_BOOTFLASH_SIZE
#define BUSWIDTH 2 #define BUSWIDTH 2
#define SIZE SUBZERO_BOOTFLASH_SIZE
#define PARTITIONS 4
/* Flash memories on these boards are memory resources, accessed big-endian. */ /* Flash memories on these boards are memory resources, accessed big-endian. */
...@@ -73,17 +78,19 @@ static struct map_info arctic_mtd_map = { ...@@ -73,17 +78,19 @@ static struct map_info arctic_mtd_map = {
static struct mtd_info *arctic_mtd; static struct mtd_info *arctic_mtd;
static struct mtd_partition arctic_partitions[3] = { static struct mtd_partition arctic_partitions[PARTITIONS] = {
{ .name = "Arctic FFS", { .name = "Filesystem",
.size = ARCTIC_FFS_SIZE, .size = FFS1_SIZE,
.offset = 0,}, .offset = 0,},
{ .name = "Kernel", { .name = "Kernel",
.size = SUBZERO_BOOTFLASH_SIZE - ARCTIC_FFS_SIZE - .size = KERNEL_SIZE,
ARCTIC_FIRMWARE_SIZE, .offset = FFS1_SIZE,},
.offset = ARCTIC_FFS_SIZE,}, { .name = "Filesystem",
.size = FFS2_SIZE,
.offset = FFS1_SIZE + KERNEL_SIZE,},
{ .name = "Firmware", { .name = "Firmware",
.size = ARCTIC_FIRMWARE_SIZE, .size = FIRMWARE_SIZE,
.offset = SUBZERO_BOOTFLASH_SIZE - ARCTIC_FIRMWARE_SIZE,}, .offset = SUBZERO_BOOTFLASH_SIZE - FIRMWARE_SIZE,},
}; };
static int __init static int __init
...@@ -107,7 +114,7 @@ init_arctic_mtd(void) ...@@ -107,7 +114,7 @@ init_arctic_mtd(void)
arctic_mtd->owner = THIS_MODULE; arctic_mtd->owner = THIS_MODULE;
return add_mtd_partitions(arctic_mtd, arctic_partitions, 3); return add_mtd_partitions(arctic_mtd, arctic_partitions, PARTITIONS);
} }
static void __exit static void __exit
......
/* /*
* $Id: ebony.c,v 1.7 2003/05/21 12:45:18 dwmw2 Exp $ * $Id: ebony.c,v 1.8 2003/06/23 11:48:18 dwmw2 Exp $
* *
* Mapping for Ebony user flash * Mapping for Ebony user flash
* *
...@@ -60,8 +60,6 @@ static struct mtd_partition ebony_large_partitions[] = { ...@@ -60,8 +60,6 @@ static struct mtd_partition ebony_large_partitions[] = {
} }
}; };
#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
int __init init_ebony(void) int __init init_ebony(void)
{ {
u8 fpga0_reg; u8 fpga0_reg;
...@@ -109,7 +107,7 @@ int __init init_ebony(void) ...@@ -109,7 +107,7 @@ int __init init_ebony(void)
if (flash) { if (flash) {
flash->owner = THIS_MODULE; flash->owner = THIS_MODULE;
add_mtd_partitions(flash, ebony_small_partitions, add_mtd_partitions(flash, ebony_small_partitions,
NB_OF(ebony_small_partitions)); ARRAY_SIZE(ebony_small_partitions));
} else { } else {
printk("map probe failed for flash\n"); printk("map probe failed for flash\n");
return -ENXIO; return -ENXIO;
...@@ -131,7 +129,7 @@ int __init init_ebony(void) ...@@ -131,7 +129,7 @@ int __init init_ebony(void)
if (flash) { if (flash) {
flash->owner = THIS_MODULE; flash->owner = THIS_MODULE;
add_mtd_partitions(flash, ebony_large_partitions, add_mtd_partitions(flash, ebony_large_partitions,
NB_OF(ebony_large_partitions)); ARRAY_SIZE(ebony_large_partitions));
} else { } else {
printk("map probe failed for flash\n"); printk("map probe failed for flash\n");
return -ENXIO; return -ENXIO;
......
/* /*
* $Id: edb7312.c,v 1.8 2003/05/21 12:45:18 dwmw2 Exp $ * $Id: edb7312.c,v 1.9 2003/06/23 11:48:18 dwmw2 Exp $
* *
* Handle mapping of the NOR flash on Cogent EDB7312 boards * Handle mapping of the NOR flash on Cogent EDB7312 boards
* *
...@@ -67,7 +67,6 @@ static struct mtd_partition static_partitions[3] = ...@@ -67,7 +67,6 @@ static struct mtd_partition static_partitions[3] =
}, },
}; };
#define NB_OF(x) (sizeof (x) / sizeof (x[0]))
static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
#endif #endif
...@@ -109,7 +108,7 @@ int __init init_edb7312nor(void) ...@@ -109,7 +108,7 @@ int __init init_edb7312nor(void)
if (mtd_parts_nb == 0) if (mtd_parts_nb == 0)
{ {
mtd_parts = static_partitions; mtd_parts = static_partitions;
mtd_parts_nb = NB_OF(static_partitions); mtd_parts_nb = ARRAY_SIZE(static_partitions);
part_type = "static"; part_type = "static";
} }
#endif #endif
......
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
$Id: elan-104nc.c,v 1.17 2003/05/21 15:15:07 dwmw2 Exp $ $Id: elan-104nc.c,v 1.18 2003/06/23 07:37:02 dwmw2 Exp $
The ELAN-104NC has up to 8 Mibyte of Intel StrataFlash (28F320/28F640) in x16 The ELAN-104NC has up to 8 Mibyte of Intel StrataFlash (28F320/28F640) in x16
mode. This drivers uses the CFI probe and Intel Extended Command Set drivers. mode. This drivers uses the CFI probe and Intel Extended Command Set drivers.
...@@ -223,20 +223,13 @@ static void cleanup_elan_104nc(void) ...@@ -223,20 +223,13 @@ static void cleanup_elan_104nc(void)
} }
iounmap((void *)iomapadr); iounmap((void *)iomapadr);
release_region(PAGE_IO,PAGE_IO_SIZE);
} }
int __init init_elan_104nc(void) int __init init_elan_104nc(void)
{ {
/* Urg! We use I/O port 0x22 without request_region()ing it */ /* Urg! We use I/O port 0x22 without request_region()ing it,
/* because it's already allocated to the PIC. */
if (check_region(PAGE_IO,PAGE_IO_SIZE) != 0) {
printk( KERN_ERR"%s: IO ports 0x%x-0x%x in use\n",
elan_104nc_map.name,
PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1 );
return -EAGAIN;
}
*/
iomapadr = (unsigned long)ioremap(WINDOW_START, WINDOW_LENGTH); iomapadr = (unsigned long)ioremap(WINDOW_START, WINDOW_LENGTH);
if (!iomapadr) { if (!iomapadr) {
printk( KERN_ERR"%s: failed to ioremap memory region\n", printk( KERN_ERR"%s: failed to ioremap memory region\n",
...@@ -244,10 +237,6 @@ int __init init_elan_104nc(void) ...@@ -244,10 +237,6 @@ int __init init_elan_104nc(void)
return -EIO; return -EIO;
} }
/*
request_region( PAGE_IO, PAGE_IO_SIZE, "ELAN-104NC flash" );
*/
printk( KERN_INFO"%s: IO:0x%x-0x%x MEM:0x%x-0x%x\n", printk( KERN_INFO"%s: IO:0x%x-0x%x MEM:0x%x-0x%x\n",
elan_104nc_map.name, elan_104nc_map.name,
PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1, PAGE_IO, PAGE_IO+PAGE_IO_SIZE-1,
......
/* /*
* $Id: impa7.c,v 1.8 2003/05/21 12:45:18 dwmw2 Exp $ * $Id: impa7.c,v 1.9 2003/06/23 11:47:43 dwmw2 Exp $
* *
* Handle mapping of the NOR flash on implementa A7 boards * Handle mapping of the NOR flash on implementa A7 boards
* *
...@@ -66,12 +66,11 @@ static struct mtd_partition static_partitions[] = ...@@ -66,12 +66,11 @@ static struct mtd_partition static_partitions[] =
}, },
}; };
#define NB_OF(x) (sizeof (x) / sizeof (x[0])) static int mtd_parts_nb[NUM_FLASHBANKS];
static struct mtd_partition *mtd_parts[NUM_FLASHBANKS];
#endif #endif
static int mtd_parts_nb = 0;
static struct mtd_partition *mtd_parts = 0;
static const char *probes[] = { "cmdlinepart", NULL }; static const char *probes[] = { "cmdlinepart", NULL };
int __init init_impa7(void) int __init init_impa7(void)
...@@ -84,7 +83,6 @@ int __init init_impa7(void) ...@@ -84,7 +83,6 @@ int __init init_impa7(void)
{ WINDOW_ADDR0, WINDOW_SIZE0 }, { WINDOW_ADDR0, WINDOW_SIZE0 },
{ WINDOW_ADDR1, WINDOW_SIZE1 }, { WINDOW_ADDR1, WINDOW_SIZE1 },
}; };
char mtdid[10];
int devicesfound = 0; int devicesfound = 0;
for(i=0; i<NUM_FLASHBANKS; i++) for(i=0; i<NUM_FLASHBANKS; i++)
...@@ -107,38 +105,30 @@ int __init init_impa7(void) ...@@ -107,38 +105,30 @@ int __init init_impa7(void)
impa7_mtd[i] = do_map_probe(*type, &impa7_map[i]); impa7_mtd[i] = do_map_probe(*type, &impa7_map[i]);
} }
if (impa7_mtd[i]) if (impa7_mtd[i]) {
{
impa7_mtd[i]->owner = THIS_MODULE; impa7_mtd[i]->owner = THIS_MODULE;
add_mtd_device(impa7_mtd[i]);
devicesfound++; devicesfound++;
#ifdef CONFIG_MTD_PARTITIONS #ifdef CONFIG_MTD_PARTITIONS
mtd_parts_nb = parse_mtd_partitions(impa7_mtd[i], mtd_parts_nb[i] = parse_mtd_partitions(impa7_mtd[i],
probes, probes,
&mtd_parts, &mtd_parts[i],
0); 0);
if (mtd_parts_nb > 0) if (mtd_parts_nb[i] > 0) {
part_type = "command line"; part_type = "command line";
#endif } else {
if (mtd_parts_nb <= 0) mtd_parts[i] = static_partitions;
{ mtd_parts_nb[i] = ARRAY_SIZE(static_partitions);
mtd_parts = static_partitions;
mtd_parts_nb = NB_OF(static_partitions);
part_type = "static"; part_type = "static";
} }
if (mtd_parts_nb <= 0)
{
printk(KERN_NOTICE MSG_PREFIX
"no partition info available\n");
}
else
{
printk(KERN_NOTICE MSG_PREFIX printk(KERN_NOTICE MSG_PREFIX
"using %s partition definition\n", "using %s partition definition\n",
part_type); part_type);
add_mtd_partitions(impa7_mtd[i], add_mtd_partitions(impa7_mtd[i],
mtd_parts, mtd_parts_nb); mtd_parts[i], mtd_parts_nb[i]);
} #else
add_mtd_device(impa7_mtd[i]);
#endif #endif
} }
else else
...@@ -150,15 +140,14 @@ int __init init_impa7(void) ...@@ -150,15 +140,14 @@ int __init init_impa7(void)
static void __exit cleanup_impa7(void) static void __exit cleanup_impa7(void)
{ {
int i; int i;
for (i=0; i<NUM_FLASHBANKS; i++) for (i=0; i<NUM_FLASHBANKS; i++) {
{ if (impa7_mtd[i]) {
if (impa7_mtd[i]) #ifdef CONFIG_MTD_PARTITIONS
{ del_mtd_partitions(impa7_mtd[i]);
#else
del_mtd_device(impa7_mtd[i]); del_mtd_device(impa7_mtd[i]);
#endif
map_destroy(impa7_mtd[i]); map_destroy(impa7_mtd[i]);
}
if (impa7_map[i].virt)
{
iounmap((void *)impa7_map[i].virt); iounmap((void *)impa7_map[i].virt);
impa7_map[i].virt = 0; impa7_map[i].virt = 0;
} }
......
/* /*
* $Id: iq80310.c,v 1.16 2003/05/21 15:15:07 dwmw2 Exp $ * $Id: iq80310.c,v 1.17 2003/06/23 11:48:18 dwmw2 Exp $
* *
* Mapping for the Intel XScale IQ80310 evaluation board * Mapping for the Intel XScale IQ80310 evaluation board
* *
...@@ -57,8 +57,6 @@ static struct mtd_partition iq80310_partitions[4] = { ...@@ -57,8 +57,6 @@ static struct mtd_partition iq80310_partitions[4] = {
} }
}; };
#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
static struct mtd_info *mymtd; static struct mtd_info *mymtd;
static struct mtd_partition *parsed_parts; static struct mtd_partition *parsed_parts;
static const char *probes[] = { "RedBoot", "cmdlinepart", NULL }; static const char *probes[] = { "RedBoot", "cmdlinepart", NULL };
...@@ -94,7 +92,7 @@ static int __init init_iq80310(void) ...@@ -94,7 +92,7 @@ static int __init init_iq80310(void)
nb_parts = parsed_nr_parts; nb_parts = parsed_nr_parts;
} else { } else {
parts = iq80310_partitions; parts = iq80310_partitions;
nb_parts = NB_OF(iq80310_partitions); nb_parts = ARRAY_SIZE(iq80310_partitions);
} }
add_mtd_partitions(mymtd, parts, nb_parts); add_mtd_partitions(mymtd, parts, nb_parts);
return 0; return 0;
......
/* /*
* $Id: lubbock-flash.c,v 1.8 2003/05/21 12:45:19 dwmw2 Exp $ * $Id: lubbock-flash.c,v 1.9 2003/06/23 11:48:18 dwmw2 Exp $
* *
* Map driver for the Lubbock developer platform. * Map driver for the Lubbock developer platform.
* *
...@@ -52,8 +52,6 @@ static struct mtd_partition lubbock_partitions[] = { ...@@ -52,8 +52,6 @@ static struct mtd_partition lubbock_partitions[] = {
} }
}; };
#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
static struct mtd_info *mymtds[2]; static struct mtd_info *mymtds[2];
static struct mtd_partition *parsed_parts[2]; static struct mtd_partition *parsed_parts[2];
static int nr_parsed_parts[2]; static int nr_parsed_parts[2];
...@@ -116,7 +114,7 @@ static int __init init_lubbock(void) ...@@ -116,7 +114,7 @@ static int __init init_lubbock(void)
add_mtd_partitions(mymtds[i], parsed_parts[i], nr_parsed_parts[i]); add_mtd_partitions(mymtds[i], parsed_parts[i], nr_parsed_parts[i]);
} else if (!i) { } else if (!i) {
printk("Using static partitions on %s\n", lubbock_maps[i].name); printk("Using static partitions on %s\n", lubbock_maps[i].name);
add_mtd_partitions(mymtds[i], lubbock_partitions, NB_OF(lubbock_partitions)); add_mtd_partitions(mymtds[i], lubbock_partitions, ARRAY_SIZE(lubbock_partitions));
} else { } else {
printk("Registering %s as whole device\n", lubbock_maps[i].name); printk("Registering %s as whole device\n", lubbock_maps[i].name);
add_mtd_device(mymtds[i]); add_mtd_device(mymtds[i]);
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
* *
* (C) 2001 Pete Popov <ppopov@mvista.com> * (C) 2001 Pete Popov <ppopov@mvista.com>
* *
* $Id: pb1xxx-flash.c,v 1.8 2003/05/21 12:45:19 dwmw2 Exp $ * $Id: pb1xxx-flash.c,v 1.9 2003/06/23 11:48:18 dwmw2 Exp $
*/ */
#include <linux/config.h> #include <linux/config.h>
...@@ -131,9 +131,6 @@ static struct mtd_partition pb1xxx_partitions[] = { ...@@ -131,9 +131,6 @@ static struct mtd_partition pb1xxx_partitions[] = {
#error Unsupported board #error Unsupported board
#endif #endif
#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
static struct mtd_partition *parsed_parts; static struct mtd_partition *parsed_parts;
static struct mtd_info *mymtd; static struct mtd_info *mymtd;
...@@ -151,7 +148,7 @@ int __init pb1xxx_mtd_init(void) ...@@ -151,7 +148,7 @@ int __init pb1xxx_mtd_init(void)
*/ */
part_type = "static"; part_type = "static";
parts = pb1xxx_partitions; parts = pb1xxx_partitions;
nb_parts = NB_OF(pb1xxx_partitions); nb_parts = ARRAY_SIZE(pb1xxx_partitions);
pb1xxx_map.size = flash_size; pb1xxx_map.size = flash_size;
/* /*
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* Handle mapping of the flash memory access routines * Handle mapping of the flash memory access routines
* on TQM8xxL based devices. * on TQM8xxL based devices.
* *
* $Id: tqm8xxl.c,v 1.8 2003/05/21 12:45:20 dwmw2 Exp $ * $Id: tqm8xxl.c,v 1.9 2003/06/23 11:48:18 dwmw2 Exp $
* *
* based on rpxlite.c * based on rpxlite.c
* *
...@@ -110,8 +110,6 @@ static struct mtd_partition tqm8xxl_fs_partitions[] = { ...@@ -110,8 +110,6 @@ static struct mtd_partition tqm8xxl_fs_partitions[] = {
}; };
#endif #endif
#define NB_OF(x) (sizeof(x)/sizeof(x[0]))
int __init init_tqm_mtd(void) int __init init_tqm_mtd(void)
{ {
int idx = 0, ret = 0; int idx = 0, ret = 0;
...@@ -198,11 +196,11 @@ int __init init_tqm_mtd(void) ...@@ -198,11 +196,11 @@ int __init init_tqm_mtd(void)
*/ */
part_banks[0].mtd_part = tqm8xxl_partitions; part_banks[0].mtd_part = tqm8xxl_partitions;
part_banks[0].type = "Static image"; part_banks[0].type = "Static image";
part_banks[0].nums = NB_OF(tqm8xxl_partitions); part_banks[0].nums = ARRAY_SIZE(tqm8xxl_partitions);
part_banks[1].mtd_part = tqm8xxl_fs_partitions; part_banks[1].mtd_part = tqm8xxl_fs_partitions;
part_banks[1].type = "Static file system"; part_banks[1].type = "Static file system";
part_banks[1].nums = NB_OF(tqm8xxl_fs_partitions); part_banks[1].nums = ARRAY_SIZE(tqm8xxl_fs_partitions);
for(idx = 0; idx < num_banks ; idx++) { for(idx = 0; idx < num_banks ; idx++) {
if (part_banks[idx].nums == 0) { if (part_banks[idx].nums == 0) {
......
/* /*
* $Id: mtd_blkdevs.c,v 1.12 2003/05/21 01:00:59 dwmw2 Exp $ * $Id: mtd_blkdevs.c,v 1.16 2003/06/23 13:34:43 dwmw2 Exp $
* *
* (C) 2003 David Woodhouse <dwmw2@infradead.org> * (C) 2003 David Woodhouse <dwmw2@infradead.org>
* *
...@@ -18,8 +18,10 @@ ...@@ -18,8 +18,10 @@
#include <linux/blk.h> #include <linux/blk.h>
#include <linux/blkpg.h> #include <linux/blkpg.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/hdreg.h>
#include <linux/init.h> #include <linux/init.h>
#include <asm/semaphore.h> #include <asm/semaphore.h>
#include <asm/uaccess.h>
#include <linux/devfs_fs_kernel.h> #include <linux/devfs_fs_kernel.h>
static LIST_HEAD(blktrans_majors); static LIST_HEAD(blktrans_majors);
...@@ -46,7 +48,7 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr, ...@@ -46,7 +48,7 @@ static int do_blktrans_request(struct mtd_blktrans_ops *tr,
nsect = req->current_nr_sectors; nsect = req->current_nr_sectors;
buf = req->buffer; buf = req->buffer;
if (!req->flags & REQ_CMD) if (!(req->flags & REQ_CMD))
return 0; return 0;
if (block + nsect > get_capacity(req->rq_disk)) if (block + nsect > get_capacity(req->rq_disk))
...@@ -93,14 +95,14 @@ static int mtd_blktrans_thread(void *arg) ...@@ -93,14 +95,14 @@ static int mtd_blktrans_thread(void *arg)
recalc_sigpending(); recalc_sigpending();
spin_unlock_irq(&current->sighand->siglock); spin_unlock_irq(&current->sighand->siglock);
spin_lock_irq(rq->queue_lock);
while (!tr->blkcore_priv->exiting) { while (!tr->blkcore_priv->exiting) {
struct request *req; struct request *req;
struct mtd_blktrans_dev *dev; struct mtd_blktrans_dev *dev;
int res = 0; int res = 0;
DECLARE_WAITQUEUE(wait, current); DECLARE_WAITQUEUE(wait, current);
spin_lock_irq(rq->queue_lock);
req = elv_next_request(rq); req = elv_next_request(rq);
if (!req) { if (!req) {
...@@ -112,6 +114,8 @@ static int mtd_blktrans_thread(void *arg) ...@@ -112,6 +114,8 @@ static int mtd_blktrans_thread(void *arg)
schedule(); schedule();
remove_wait_queue(&tr->blkcore_priv->thread_wq, &wait); remove_wait_queue(&tr->blkcore_priv->thread_wq, &wait);
spin_lock_irq(rq->queue_lock);
continue; continue;
} }
...@@ -159,7 +163,7 @@ int blktrans_open(struct inode *i, struct file *f) ...@@ -159,7 +163,7 @@ int blktrans_open(struct inode *i, struct file *f)
dev->mtd->usecount++; dev->mtd->usecount++;
ret = 0; ret = 0;
if (tr->open && (ret = tr->open(dev, i, f))) { if (tr->open && (ret = tr->open(dev))) {
dev->mtd->usecount--; dev->mtd->usecount--;
module_put(dev->mtd->owner); module_put(dev->mtd->owner);
out_tr: out_tr:
...@@ -179,7 +183,7 @@ int blktrans_release(struct inode *i, struct file *f) ...@@ -179,7 +183,7 @@ int blktrans_release(struct inode *i, struct file *f)
tr = dev->tr; tr = dev->tr;
if (tr->release) if (tr->release)
ret = tr->release(dev, i, f); ret = tr->release(dev);
if (!ret) { if (!ret) {
dev->mtd->usecount--; dev->mtd->usecount--;
...@@ -194,21 +198,33 @@ int blktrans_release(struct inode *i, struct file *f) ...@@ -194,21 +198,33 @@ int blktrans_release(struct inode *i, struct file *f)
static int blktrans_ioctl(struct inode *inode, struct file *file, static int blktrans_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg) unsigned int cmd, unsigned long arg)
{ {
struct mtd_blktrans_dev *dev; struct mtd_blktrans_dev *dev = inode->i_bdev->bd_disk->private_data;
struct mtd_blktrans_ops *tr; struct mtd_blktrans_ops *tr = dev->tr;
int ret = -ENOTTY;
dev = inode->i_bdev->bd_disk->private_data; switch (cmd) {
tr = dev->tr; case BLKFLSBUF:
if (tr->flush)
return tr->flush(dev);
/* The core code did the work, we had nothing to do. */
return 0;
if (tr->ioctl) case HDIO_GETGEO:
ret = tr->ioctl(dev, inode, file, cmd, arg); if (tr->getgeo) {
struct hd_geometry g;
if (ret == -ENOTTY && (cmd == BLKROSET || cmd == BLKFLSBUF)) { memset(&g, 0, sizeof(g));
/* The core code did the work, we had nothing to do. */ int ret = tr->getgeo(dev, &g);
ret = 0; if (ret)
}
return ret; return ret;
g.start = get_start_sect(inode->i_bdev);
if (copy_to_user((void *)arg, &g, sizeof(g)))
return -EFAULT;
return 0;
} /* else */
default:
return -ENOTTY;
}
} }
struct block_device_operations mtd_blktrans_ops = { struct block_device_operations mtd_blktrans_ops = {
...@@ -328,8 +344,6 @@ void blktrans_notify_add(struct mtd_info *mtd) ...@@ -328,8 +344,6 @@ void blktrans_notify_add(struct mtd_info *mtd)
if (mtd->type == MTD_ABSENT) if (mtd->type == MTD_ABSENT)
return; return;
printk("%s:%s %d: count %d\n", __FILE__, __func__, __LINE__, atomic_read(&mtd_table_mutex.count));
list_for_each(this, &blktrans_majors) { list_for_each(this, &blktrans_majors) {
struct mtd_blktrans_ops *tr = list_entry(this, struct mtd_blktrans_ops, list); struct mtd_blktrans_ops *tr = list_entry(this, struct mtd_blktrans_ops, list);
...@@ -392,8 +406,6 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr) ...@@ -392,8 +406,6 @@ int register_mtd_blktrans(struct mtd_blktrans_ops *tr)
INIT_LIST_HEAD(&tr->devs); INIT_LIST_HEAD(&tr->devs);
list_add(&tr->list, &blktrans_majors); list_add(&tr->list, &blktrans_majors);
printk("%s:%s %d: count %d\n", __FILE__, __func__, __LINE__, atomic_read(&mtd_table_mutex.count));
for (i=0; i<MAX_MTD_DEVICES; i++) { for (i=0; i<MAX_MTD_DEVICES; i++) {
if (mtd_table[i] && mtd_table[i]->type != MTD_ABSENT) if (mtd_table[i] && mtd_table[i]->type != MTD_ABSENT)
tr->add_mtd(tr, mtd_table[i]); tr->add_mtd(tr, mtd_table[i]);
......
/* /*
* Direct MTD block device access * Direct MTD block device access
* *
* $Id: mtdblock.c,v 1.61 2003/05/21 10:49:38 dwmw2 Exp $ * $Id: mtdblock.c,v 1.63 2003/06/23 12:00:08 dwmw2 Exp $
* *
* (C) 2000-2003 Nicolas Pitre <nico@cam.org> * (C) 2000-2003 Nicolas Pitre <nico@cam.org>
* (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> * (C) 1999-2003 David Woodhouse <dwmw2@infradead.org>
...@@ -248,11 +248,19 @@ static int mtdblock_writesect(struct mtd_blktrans_dev *dev, ...@@ -248,11 +248,19 @@ static int mtdblock_writesect(struct mtd_blktrans_dev *dev,
unsigned long block, char *buf) unsigned long block, char *buf)
{ {
struct mtdblk_dev *mtdblk = mtdblks[dev->devnum]; struct mtdblk_dev *mtdblk = mtdblks[dev->devnum];
if (unlikely(!mtdblk->cache_data)) {
mtdblk->cache_data = vmalloc(mtdblk->mtd->erasesize);
if (!mtdblk->cache_data)
return -EINTR;
/* -EINTR is not really correct, but it is the best match
* documented in man 2 write for all cases. We could also
* return -EAGAIN sometimes, but why bother?
*/
}
return do_cached_write(mtdblk, block<<9, 512, buf); return do_cached_write(mtdblk, block<<9, 512, buf);
} }
static int mtdblock_open(struct mtd_blktrans_dev *mbd, static int mtdblock_open(struct mtd_blktrans_dev *mbd)
struct inode *inode, struct file *file)
{ {
struct mtdblk_dev *mtdblk; struct mtdblk_dev *mtdblk;
struct mtd_info *mtd = mbd->mtd; struct mtd_info *mtd = mbd->mtd;
...@@ -279,11 +287,7 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd, ...@@ -279,11 +287,7 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd,
if ((mtdblk->mtd->flags & MTD_CAP_RAM) != MTD_CAP_RAM && if ((mtdblk->mtd->flags & MTD_CAP_RAM) != MTD_CAP_RAM &&
mtdblk->mtd->erasesize) { mtdblk->mtd->erasesize) {
mtdblk->cache_size = mtdblk->mtd->erasesize; mtdblk->cache_size = mtdblk->mtd->erasesize;
mtdblk->cache_data = vmalloc(mtdblk->mtd->erasesize); mtdblk->cache_data = NULL;
if (!mtdblk->cache_data) {
kfree(mtdblk);
return -ENOMEM;
}
} }
mtdblks[dev] = mtdblk; mtdblks[dev] = mtdblk;
...@@ -293,17 +297,13 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd, ...@@ -293,17 +297,13 @@ static int mtdblock_open(struct mtd_blktrans_dev *mbd,
return 0; return 0;
} }
static int mtdblock_release(struct mtd_blktrans_dev *mbd, static int mtdblock_release(struct mtd_blktrans_dev *mbd)
struct inode *inode, struct file *file)
{ {
int dev; int dev = mbd->devnum;
struct mtdblk_dev *mtdblk; struct mtdblk_dev *mtdblk = mtdblks[dev];
DEBUG(MTD_DEBUG_LEVEL1, "mtdblock_release\n"); DEBUG(MTD_DEBUG_LEVEL1, "mtdblock_release\n");
dev = minor(inode->i_rdev);
mtdblk = mtdblks[dev];
down(&mtdblk->cache_sem); down(&mtdblk->cache_sem);
write_cached_data(mtdblk); write_cached_data(mtdblk);
up(&mtdblk->cache_sem); up(&mtdblk->cache_sem);
...@@ -321,27 +321,17 @@ static int mtdblock_release(struct mtd_blktrans_dev *mbd, ...@@ -321,27 +321,17 @@ static int mtdblock_release(struct mtd_blktrans_dev *mbd,
return 0; return 0;
} }
static int mtdblock_flush(struct mtd_blktrans_dev *dev)
static int mtdblock_ioctl(struct mtd_blktrans_dev *dev,
struct inode * inode, struct file * file,
unsigned int cmd, unsigned long arg)
{ {
struct mtdblk_dev *mtdblk; struct mtdblk_dev *mtdblk = mtdblks[dev->devnum];
mtdblk = mtdblks[minor(inode->i_rdev)];
switch (cmd) {
case BLKFLSBUF:
down(&mtdblk->cache_sem); down(&mtdblk->cache_sem);
write_cached_data(mtdblk); write_cached_data(mtdblk);
up(&mtdblk->cache_sem); up(&mtdblk->cache_sem);
if (mtdblk->mtd->sync) if (mtdblk->mtd->sync)
mtdblk->mtd->sync(mtdblk->mtd); mtdblk->mtd->sync(mtdblk->mtd);
return 0; return 0;
default:
return -ENOTTY;
}
} }
static void mtdblock_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) static void mtdblock_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
...@@ -376,7 +366,7 @@ struct mtd_blktrans_ops mtdblock_tr = { ...@@ -376,7 +366,7 @@ struct mtd_blktrans_ops mtdblock_tr = {
.major = 31, .major = 31,
.part_bits = 0, .part_bits = 0,
.open = mtdblock_open, .open = mtdblock_open,
.ioctl = mtdblock_ioctl, .flush = mtdblock_flush,
.release = mtdblock_release, .release = mtdblock_release,
.readsect = mtdblock_readsect, .readsect = mtdblock_readsect,
.writesect = mtdblock_writesect, .writesect = mtdblock_writesect,
......
/* /*
* $Id: mtdblock_ro.c,v 1.17 2003/05/18 19:27:27 dwmw2 Exp $ * $Id: mtdblock_ro.c,v 1.18 2003/06/23 12:00:08 dwmw2 Exp $
* *
* (C) 2003 David Woodhouse <dwmw2@infradead.org> * (C) 2003 David Woodhouse <dwmw2@infradead.org>
* *
* Simple read-only (writable only for RAM) mtdblock driver * Simple read-only (writable only for RAM) mtdblock driver
*/ */
#include <linux/init.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/blktrans.h> #include <linux/mtd/blktrans.h>
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* *
* This code is GPL * This code is GPL
* *
* $Id: mtdpart.c,v 1.39 2003/05/21 15:15:03 dwmw2 Exp $ * $Id: mtdpart.c,v 1.41 2003/06/18 14:53:02 dwmw2 Exp $
* *
* 02-21-2002 Thomas Gleixner <gleixner@autronix.de> * 02-21-2002 Thomas Gleixner <gleixner@autronix.de>
* added support for read_oob, write_oob * added support for read_oob, write_oob
...@@ -120,7 +120,7 @@ static int part_read_fact_prot_reg (struct mtd_info *mtd, loff_t from, size_t le ...@@ -120,7 +120,7 @@ static int part_read_fact_prot_reg (struct mtd_info *mtd, loff_t from, size_t le
size_t *retlen, u_char *buf) size_t *retlen, u_char *buf)
{ {
struct mtd_part *part = PART(mtd); struct mtd_part *part = PART(mtd);
return part->master->read_user_prot_reg (part->master, from, return part->master->read_fact_prot_reg (part->master, from,
len, retlen, buf); len, retlen, buf);
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* Derived from drivers/mtd/spia.c * Derived from drivers/mtd/spia.c
* Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
* *
* $Id: autcpu12.c,v 1.10 2003/04/20 07:24:40 gleixner Exp $ * $Id: autcpu12.c,v 1.11 2003/06/04 17:04:09 gleixner Exp $
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 as
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
*/ */
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/init.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h> #include <linux/mtd/nand.h>
......
...@@ -126,7 +126,13 @@ ...@@ -126,7 +126,13 @@
* supplied by ioctl (MEMSETOOBSEL) are used. * supplied by ioctl (MEMSETOOBSEL) are used.
* For partitions the partition defaults are used (mtdpart.c) * For partitions the partition defaults are used (mtdpart.c)
* *
* $Id: nand.c,v 1.45 2003/05/20 21:01:30 dwmw2 Exp $ * 06-04-2003 tglx: fix compile errors and fix write verify problem for
* some chips, which need either a delay between the readback
* and the next write command or have the CE removed. The
* CE disable/enable is much faster than a 20us delay and
* it should work on all available chips.
*
* $Id: nand.c,v 1.46 2003/06/04 17:10:36 gleixner Exp $
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License version 2 as
...@@ -141,6 +147,7 @@ ...@@ -141,6 +147,7 @@
#include <linux/mtd/mtd.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h> #include <linux/mtd/nand.h>
#include <linux/mtd/nand_ecc.h> #include <linux/mtd/nand_ecc.h>
#include <linux/mtd/compatmac.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <asm/io.h> #include <asm/io.h>
...@@ -510,6 +517,13 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa ...@@ -510,6 +517,13 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
} }
} }
} }
/*
* Terminate the read command. This is faster than sending a reset command or
* applying a 20us delay before issuing the next programm sequence.
* This is not a problem for all chips, but I have found a bunch of them.
*/
nand_deselect();
nand_select();
#endif #endif
return 0; return 0;
} }
......
/* Linux driver for NAND Flash Translation Layer */ /* Linux driver for NAND Flash Translation Layer */
/* (c) 1999 Machine Vision Holdings, Inc. */ /* (c) 1999 Machine Vision Holdings, Inc. */
/* Author: David Woodhouse <dwmw2@infradead.org> */ /* Author: David Woodhouse <dwmw2@infradead.org> */
/* $Id: nftlcore.c,v 1.92 2003/05/23 11:41:47 dwmw2 Exp $ */ /* $Id: nftlcore.c,v 1.94 2003/06/23 12:00:08 dwmw2 Exp $ */
/* /*
The contents of this file are distributed under the GNU General The contents of this file are distributed under the GNU General
...@@ -101,7 +101,7 @@ static void nftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd) ...@@ -101,7 +101,7 @@ static void nftl_add_mtd(struct mtd_blktrans_ops *tr, struct mtd_info *mtd)
(long)nftl->sectors ); (long)nftl->sectors );
} }
if (add_mtd_blktrans_dev) { if (add_mtd_blktrans_dev(&nftl->mbd)) {
if (nftl->ReplUnitTable) if (nftl->ReplUnitTable)
kfree(nftl->ReplUnitTable); kfree(nftl->ReplUnitTable);
if (nftl->EUNtable) if (nftl->EUNtable)
...@@ -699,29 +699,17 @@ static int nftl_readblock(struct mtd_blktrans_dev *mbd, unsigned long block, ...@@ -699,29 +699,17 @@ static int nftl_readblock(struct mtd_blktrans_dev *mbd, unsigned long block,
return 0; return 0;
} }
static int nftl_ioctl(struct mtd_blktrans_dev *dev, static int nftl_getgeo(struct mtd_blktrans_dev *dev, struct hd_geometry *geo)
struct inode * inode, struct file * file,
unsigned int cmd, unsigned long arg)
{ {
struct NFTLrecord *nftl = (void *)dev; struct NFTLrecord *nftl = (void *)dev;
switch (cmd) { geo->heads = nftl->heads;
case HDIO_GETGEO: { geo->sectors = nftl->sectors;
struct hd_geometry g; geo->cylinders = nftl->cylinders;
g.heads = nftl->heads; return 0;
g.sectors = nftl->sectors;
g.cylinders = nftl->cylinders;
g.start = 0;
return copy_to_user((void *)arg, &g, sizeof g) ? -EFAULT : 0;
}
default:
return -ENOTTY;
}
} }
/**************************************************************************** /****************************************************************************
* *
* Module stuff * Module stuff
...@@ -733,7 +721,7 @@ struct mtd_blktrans_ops nftl_tr = { ...@@ -733,7 +721,7 @@ struct mtd_blktrans_ops nftl_tr = {
.name = "nftl", .name = "nftl",
.major = NFTL_MAJOR, .major = NFTL_MAJOR,
.part_bits = NFTL_PARTN_BITS, .part_bits = NFTL_PARTN_BITS,
.ioctl = nftl_ioctl, .getgeo = nftl_getgeo,
.readsect = nftl_readblock, .readsect = nftl_readblock,
#ifdef CONFIG_NFTL_RW #ifdef CONFIG_NFTL_RW
.writesect = nftl_writeblock, .writesect = nftl_writeblock,
...@@ -747,7 +735,7 @@ extern char nftlmountrev[]; ...@@ -747,7 +735,7 @@ extern char nftlmountrev[];
int __init init_nftl(void) int __init init_nftl(void)
{ {
printk(KERN_INFO "NFTL driver: nftlcore.c $Revision: 1.92 $, nftlmount.c %s\n", nftlmountrev); printk(KERN_INFO "NFTL driver: nftlcore.c $Revision: 1.94 $, nftlmount.c %s\n", nftlmountrev);
return register_mtd_blktrans(&nftl_tr); return register_mtd_blktrans(&nftl_tr);
} }
......
...@@ -974,7 +974,7 @@ static const struct hc_driver ehci_driver = { ...@@ -974,7 +974,7 @@ static const struct hc_driver ehci_driver = {
/* EHCI spec says PCI is required. */ /* EHCI spec says PCI is required. */
/* PCI driver selection metadata; PCI hotplugging uses this */ /* PCI driver selection metadata; PCI hotplugging uses this */
static const struct pci_device_id __devinitdata pci_ids [] = { { static struct pci_device_id __devinitdata pci_ids [] = { {
/* handle any USB 2.0 EHCI controller */ /* handle any USB 2.0 EHCI controller */
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* For licensing information, see the file 'LICENCE' in this directory. * For licensing information, see the file 'LICENCE' in this directory.
* *
* $Id: dir.c,v 1.76 2003/05/26 09:50:38 dwmw2 Exp $ * $Id: dir.c,v 1.77 2003/06/05 14:42:24 dwmw2 Exp $
* *
*/ */
...@@ -356,7 +356,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char ...@@ -356,7 +356,7 @@ static int jffs2_symlink (struct inode *dir_i, struct dentry *dentry, const char
up(&f->sem); up(&f->sem);
/* Work out where to put the dirent node now. */ /* Work out where to put the dirent node now. */
writtenlen = (writtenlen+3)&~3; writtenlen = PAD(writtenlen);
phys_ofs += writtenlen; phys_ofs += writtenlen;
alloclen -= writtenlen; alloclen -= writtenlen;
...@@ -653,7 +653,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, mk ...@@ -653,7 +653,7 @@ static int jffs2_mknod (struct inode *dir_i, struct dentry *dentry, int mode, mk
up(&f->sem); up(&f->sem);
/* Work out where to put the dirent node now. */ /* Work out where to put the dirent node now. */
writtenlen = (writtenlen+3)&~3; writtenlen = PAD(writtenlen);
phys_ofs += writtenlen; phys_ofs += writtenlen;
alloclen -= writtenlen; alloclen -= writtenlen;
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#include <linux/vfs.h> #include <linux/vfs.h>
#include "nodelist.h" #include "nodelist.h"
int jffs2_statfs(struct super_block *sb, struct statfs *buf) int jffs2_statfs(struct super_block *sb, struct kstatfs *buf)
{ {
struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); struct jffs2_sb_info *c = JFFS2_SB_INFO(sb);
unsigned long avail; unsigned long avail;
......
...@@ -123,7 +123,7 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f) ...@@ -123,7 +123,7 @@ static inline void jffs2_init_inode_info(struct jffs2_inode_info *f)
#define jffs2_flash_write_oob(c, ofs, len, retlen, buf) ((c)->mtd->write_oob((c)->mtd, ofs, len, retlen, buf)) #define jffs2_flash_write_oob(c, ofs, len, retlen, buf) ((c)->mtd->write_oob((c)->mtd, ofs, len, retlen, buf))
#define jffs2_flash_read_oob(c, ofs, len, retlen, buf) ((c)->mtd->read_oob((c)->mtd, ofs, len, retlen, buf)) #define jffs2_flash_read_oob(c, ofs, len, retlen, buf) ((c)->mtd->read_oob((c)->mtd, ofs, len, retlen, buf))
struct statfs; struct kstatfs;
/* wbuf.c */ /* wbuf.c */
int jffs2_flash_writev(struct jffs2_sb_info *c, const struct iovec *vecs, unsigned long count, loff_t to, size_t *retlen); int jffs2_flash_writev(struct jffs2_sb_info *c, const struct iovec *vecs, unsigned long count, loff_t to, size_t *retlen);
...@@ -169,7 +169,7 @@ void jffs2_read_inode (struct inode *); ...@@ -169,7 +169,7 @@ void jffs2_read_inode (struct inode *);
void jffs2_clear_inode (struct inode *); void jffs2_clear_inode (struct inode *);
struct inode *jffs2_new_inode (struct inode *dir_i, int mode, struct inode *jffs2_new_inode (struct inode *dir_i, int mode,
struct jffs2_raw_inode *ri); struct jffs2_raw_inode *ri);
int jffs2_statfs (struct super_block *, struct statfs *); int jffs2_statfs (struct super_block *, struct kstatfs *);
void jffs2_write_super (struct super_block *); void jffs2_write_super (struct super_block *);
int jffs2_remount_fs (struct super_block *, int *, char *); int jffs2_remount_fs (struct super_block *, int *, char *);
int jffs2_do_fill_super(struct super_block *sb, void *data, int silent); int jffs2_do_fill_super(struct super_block *sb, void *data, int silent);
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* *
* For licensing information, see the file 'LICENCE' in this directory. * For licensing information, see the file 'LICENCE' in this directory.
* *
* $Id: scan.c,v 1.99 2003/04/28 10:17:17 dwmw2 Exp $ * $Id: scan.c,v 1.100 2003/06/05 14:42:24 dwmw2 Exp $
* *
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
...@@ -354,7 +354,7 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo ...@@ -354,7 +354,7 @@ static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblo
if (ofs & 3) { if (ofs & 3) {
printk(KERN_WARNING "Eep. ofs 0x%08x not word-aligned!\n", ofs); printk(KERN_WARNING "Eep. ofs 0x%08x not word-aligned!\n", ofs);
ofs = (ofs+3)&~3; ofs = PAD(ofs);
continue; continue;
} }
if (ofs == prevofs) { if (ofs == prevofs) {
......
...@@ -250,6 +250,8 @@ ...@@ -250,6 +250,8 @@
#define __NR_time 231 /* Linux Specific */ #define __NR_time 231 /* Linux Specific */
/* #define __NR_oldstat 232 Linux Specific */ /* #define __NR_oldstat 232 Linux Specific */
#define __NR_stime 233 /* Linux Specific */ #define __NR_stime 233 /* Linux Specific */
#define __NR_statfs64 234 /* Linux Specific */
#define __NR_fstatfs64 235 /* Linux Specific */
#define __NR__llseek 236 /* Linux Specific */ #define __NR__llseek 236 /* Linux Specific */
#define __NR_mlock 237 #define __NR_mlock 237
#define __NR_munlock 238 #define __NR_munlock 238
...@@ -270,6 +272,11 @@ ...@@ -270,6 +272,11 @@
#define __NR_fdatasync 253 #define __NR_fdatasync 253
#define __NR_nfsservctl 254 #define __NR_nfsservctl 254
#define __NR_aplib 255 #define __NR_aplib 255
/* WARNING: You MAY NOT add syscall numbers larger than 255, since
* all of the syscall tables in the Sparc kernel are
* sized to have 256 entries (starting at zero). Therefore
* find a free slot in the 0-255 range.
*/
#define _syscall0(type,name) \ #define _syscall0(type,name) \
type name(void) \ type name(void) \
......
...@@ -92,7 +92,8 @@ struct compat_statfs { ...@@ -92,7 +92,8 @@ struct compat_statfs {
int f_ffree; int f_ffree;
compat_fsid_t f_fsid; compat_fsid_t f_fsid;
int f_namelen; /* SunOS ignores this field. */ int f_namelen; /* SunOS ignores this field. */
int f_spare[6]; int f_frsize;
int f_spare[5];
}; };
#define COMPAT_RLIM_INFINITY 0x7fffffff #define COMPAT_RLIM_INFINITY 0x7fffffff
......
...@@ -252,8 +252,8 @@ ...@@ -252,8 +252,8 @@
#endif #endif
/* #define __NR_oldstat 232 Linux Specific */ /* #define __NR_oldstat 232 Linux Specific */
#define __NR_stime 233 /* Linux Specific */ #define __NR_stime 233 /* Linux Specific */
/* #define __NR_UNUSED 234 */ #define __NR_statfs64 234 /* Linux Specific */
/* #define __NR_UNUSED 235 */ #define __NR_fstatfs64 235 /* Linux Specific */
#define __NR__llseek 236 /* Linux Specific */ #define __NR__llseek 236 /* Linux Specific */
#define __NR_mlock 237 #define __NR_mlock 237
#define __NR_munlock 238 #define __NR_munlock 238
...@@ -274,6 +274,11 @@ ...@@ -274,6 +274,11 @@
#define __NR_fdatasync 253 #define __NR_fdatasync 253
#define __NR_nfsservctl 254 #define __NR_nfsservctl 254
#define __NR_aplib 255 #define __NR_aplib 255
/* WARNING: You MAY NOT add syscall numbers larger than 255, since
* all of the syscall tables in the Sparc64 kernel are
* sized to have 256 entries (starting at zero). Therefore
* find a free slot in the 0-255 range.
*/
#define _syscall0(type,name) \ #define _syscall0(type,name) \
type name(void) \ type name(void) \
......
...@@ -14,6 +14,9 @@ ...@@ -14,6 +14,9 @@
#define LO_KEY_SIZE 32 #define LO_KEY_SIZE 32
#ifdef __KERNEL__ #ifdef __KERNEL__
#include <linux/bio.h>
#include <linux/blk.h>
#include <linux/spinlock.h>
/* Possible states of device */ /* Possible states of device */
enum { enum {
...@@ -22,18 +25,20 @@ enum { ...@@ -22,18 +25,20 @@ enum {
Lo_rundown, Lo_rundown,
}; };
struct loop_func_table;
struct loop_device { struct loop_device {
int lo_number; int lo_number;
int lo_refcnt; int lo_refcnt;
int lo_offset; int lo_offset;
int lo_encrypt_type;
int lo_encrypt_key_size;
int lo_flags; int lo_flags;
int (*transfer)(struct loop_device *, int cmd, int (*transfer)(struct loop_device *, int cmd,
char *raw_buf, char *loop_buf, int size, char *raw_buf, char *loop_buf, int size,
sector_t real_block); sector_t real_block);
char lo_name[LO_NAME_SIZE]; char lo_name[LO_NAME_SIZE];
char lo_encrypt_key[LO_KEY_SIZE]; char lo_encrypt_key[LO_KEY_SIZE];
int lo_encrypt_key_size;
struct loop_func_table *lo_encryption;
__u32 lo_init[2]; __u32 lo_init[2];
uid_t lo_key_owner; /* Who set the key */ uid_t lo_key_owner; /* Who set the key */
int (*ioctl)(struct loop_device *, int cmd, int (*ioctl)(struct loop_device *, int cmd,
...@@ -129,9 +134,7 @@ struct loop_func_table { ...@@ -129,9 +134,7 @@ struct loop_func_table {
/* release is called from loop_unregister_transfer or clr_fd */ /* release is called from loop_unregister_transfer or clr_fd */
int (*release)(struct loop_device *); int (*release)(struct loop_device *);
int (*ioctl)(struct loop_device *, int cmd, unsigned long arg); int (*ioctl)(struct loop_device *, int cmd, unsigned long arg);
/* lock and unlock manage the module use counts */ struct module *owner;
void (*lock)(struct loop_device *);
void (*unlock)(struct loop_device *);
}; };
int loop_register_transfer(struct loop_func_table *funcs); int loop_register_transfer(struct loop_func_table *funcs);
......
/* /*
* $Id: blktrans.h,v 1.4 2003/05/21 01:01:32 dwmw2 Exp $ * $Id: blktrans.h,v 1.5 2003/06/23 12:00:08 dwmw2 Exp $
* *
* (C) 2003 David Woodhouse <dwmw2@infradead.org> * (C) 2003 David Woodhouse <dwmw2@infradead.org>
* *
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <asm/semaphore.h> #include <asm/semaphore.h>
struct hd_geometry;
struct mtd_info; struct mtd_info;
struct mtd_blktrans_ops; struct mtd_blktrans_ops;
struct file; struct file;
...@@ -42,17 +43,13 @@ struct mtd_blktrans_ops { ...@@ -42,17 +43,13 @@ struct mtd_blktrans_ops {
int (*writesect)(struct mtd_blktrans_dev *dev, int (*writesect)(struct mtd_blktrans_dev *dev,
unsigned long block, char *buffer); unsigned long block, char *buffer);
/* HDIO_GETGEO and HDIO_GETGEO_BIG are the only non-private /* Block layer ioctls */
ioctls which are expected to be passed through */ int (*getgeo)(struct mtd_blktrans_dev *dev, struct hd_geometry *geo);
int (*ioctl)(struct mtd_blktrans_dev *dev, int (*flush)(struct mtd_blktrans_dev *dev);
struct inode * inode, struct file * file,
unsigned int cmd, unsigned long arg);
/* Called with mtd_table_mutex held; no race with add/remove */ /* Called with mtd_table_mutex held; no race with add/remove */
int (*open)(struct mtd_blktrans_dev *dev, int (*open)(struct mtd_blktrans_dev *dev);
struct inode *i, struct file *f); int (*release)(struct mtd_blktrans_dev *dev);
int (*release)(struct mtd_blktrans_dev *dev,
struct inode *i, struct file *f);
/* Called on {de,}registration and on subsequent addition/removal /* Called on {de,}registration and on subsequent addition/removal
of devices, with mtd_table_mutex held. */ of devices, with mtd_table_mutex held. */
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
/* Linux driver for Disk-On-Chip 2000 */ /* Linux driver for Disk-On-Chip 2000 */
/* (c) 1999 Machine Vision Holdings, Inc. */ /* (c) 1999 Machine Vision Holdings, Inc. */
/* Author: David Woodhouse <dwmw2@mvhi.com> */ /* Author: David Woodhouse <dwmw2@mvhi.com> */
/* $Id: doc2000.h,v 1.16 2003/05/23 11:29:33 dwmw2 Exp $ */ /* $Id: doc2000.h,v 1.17 2003/06/12 01:20:46 gerg Exp $ */
#ifndef __MTD_DOC2000_H__ #ifndef __MTD_DOC2000_H__
#define __MTD_DOC2000_H__ #define __MTD_DOC2000_H__
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
#define DoC_Mplus_AccessStatus 0x1008 #define DoC_Mplus_AccessStatus 0x1008
#define DoC_Mplus_DeviceSelect 0x1008 #define DoC_Mplus_DeviceSelect 0x1008
#define DoC_Mplus_Configuration 0x100a #define DoC_Mplus_Configuration 0x100a
#define DoC_Mplus_OutputControl 0x1002 #define DoC_Mplus_OutputControl 0x100c
#define DoC_Mplus_FlashControl 0x1020 #define DoC_Mplus_FlashControl 0x1020
#define DoC_Mplus_FlashSelect 0x1022 #define DoC_Mplus_FlashSelect 0x1022
#define DoC_Mplus_FlashCmd 0x1024 #define DoC_Mplus_FlashCmd 0x1024
......
...@@ -275,6 +275,7 @@ static int create_workqueue_thread(struct workqueue_struct *wq, ...@@ -275,6 +275,7 @@ static int create_workqueue_thread(struct workqueue_struct *wq,
INIT_LIST_HEAD(&cwq->worklist); INIT_LIST_HEAD(&cwq->worklist);
init_waitqueue_head(&cwq->more_work); init_waitqueue_head(&cwq->more_work);
init_waitqueue_head(&cwq->work_done); init_waitqueue_head(&cwq->work_done);
init_completion(&cwq->exit);
init_completion(&startup.done); init_completion(&startup.done);
startup.cwq = cwq; startup.cwq = cwq;
...@@ -320,10 +321,7 @@ static void cleanup_workqueue_thread(struct workqueue_struct *wq, int cpu) ...@@ -320,10 +321,7 @@ static void cleanup_workqueue_thread(struct workqueue_struct *wq, int cpu)
cwq = wq->cpu_wq + cpu; cwq = wq->cpu_wq + cpu;
if (cwq->thread) { if (cwq->thread) {
printk("Cleaning up workqueue thread for %i\n", cpu); /* Tell thread to exit and wait for it. */
/* Initiate an exit and wait for it: */
init_completion(&cwq->exit);
wmb(); /* Thread must see !cwq->thread after completion init */
cwq->thread = NULL; cwq->thread = NULL;
wake_up(&cwq->more_work); wake_up(&cwq->more_work);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment