Re: get_fs_byte and put_fs_long in 2.1.4?

Alain Knaff (Alain.Knaff@imag.fr)
Fri, 18 Oct 1996 00:00:49 +0200


>
>After compiling 2.1.4, I recieved the following
>unresolved symbols:
>
>*** Unresolved symbols in module /lib/modules/2.1.4/block/floppy.o
> get_fs_byte
>*** Unresolved symbols in module /lib/modules/2.1.4/block/loop.o
> put_fs_long
>
>Any ideas?
>

The following patch fixes the floppy problem (and a few other pb's as
well)

diff -ur 2.1.4/linux/drivers/block/floppy.c linux/drivers/block/floppy.c
--- 2.1.4/linux/drivers/block/floppy.c Wed Oct 16 23:35:00 1996
+++ linux/drivers/block/floppy.c Thu Oct 17 21:51:37 1996
@@ -130,7 +130,7 @@


#include <linux/fd.h>
-
+#include <linux/hdreg.h>

#define OLDFDRAWCMD 0x020d /* send a raw command to the FDC */

@@ -918,6 +918,13 @@
static struct tq_struct floppy_tq =
{ 0, 0, 0, 0 };

+static void schedule_bh( void (*handler)(void*) )
+{
+ floppy_tq.routine = (void *)(void *) handler;
+ queue_task_irq(&floppy_tq, &tq_immediate);
+ mark_bh(IMMEDIATE_BH);
+}
+
static struct timer_list fd_timer ={ NULL, NULL, 0, 0, 0 };

static void cancel_activity(void)
@@ -1685,12 +1692,9 @@
} while ((ST0 & 0x83) != UNIT(current_drive) && inr == 2);
}
if (handler) {
- if(intr_count >= 2) {
- /* expected interrupt */
- floppy_tq.routine = (void *)(void *) handler;
- queue_task_irq(&floppy_tq, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
- } else
+ if(intr_count >= 2)
+ schedule_bh( (void *)(void *) handler);
+ else
handler();
} else
FDCS->reset = 1;
@@ -1928,9 +1932,7 @@
int ret;
unsigned long flags;

- floppy_tq.routine = (void *)(void *) handler;
- queue_task(&floppy_tq, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
+ schedule_bh((void *)(void *)handler);
INT_OFF;
while(command_status < 2 && NO_SIGNAL){
is_alive("wait_til_done");
@@ -2737,9 +2739,7 @@

if (TESTF(FD_NEED_TWADDLE))
twaddle();
- floppy_tq.routine = (void *)(void *) floppy_start;
- queue_task(&floppy_tq, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
+ schedule_bh( (void *)(void *) floppy_start);
#ifdef DEBUGT
debugt("queue fd request");
#endif
@@ -2754,18 +2754,19 @@
bad_flp_intr,
request_done };

-static struct tq_struct request_tq =
-{ 0, 0, (void *) (void *) redo_fd_request, 0 };
-
static void process_fd_request(void)
{
cont = &rw_cont;
- queue_task(&request_tq, &tq_immediate);
- mark_bh(IMMEDIATE_BH);
+ schedule_bh( (void *)(void *) redo_fd_request);
}

static void do_fd_request(void)
{
+ if(usage_count == 0) {
+ printk("warning: usage count=0, CURRENT=%p exiting\n", CURRENT);
+ printk("sect=%d cmd=%d\n", CURRENT->sector, CURRENT->cmd);
+ return;
+ }
sti();
if (fdc_busy){
/* fdc busy, this new request will be treated when the
@@ -2839,22 +2840,19 @@
* Misc Ioctl's and support
* ========================
*/
-static int fd_copyout(void *param, const void *address, int size)
+static inline int fd_copyout(void *param, const void *address, int size)
{
- int ret;
-
- ECALL(verify_area(VERIFY_WRITE,param,size));
- copy_to_user(param,(void *) address, size);
- return 0;
+ return copy_to_user(param,address, size) ? -EFAULT : 0;
}

-static int fd_copyin(void *param, void *address, int size)
+static inline int fd_copyin(void *param, void *address, int size)
{
- int ret;
+ return copy_from_user(address, param, size) ? -EFAULT : 0;
+}

- ECALL(verify_area(VERIFY_READ,param,size));
- copy_from_user((void *) address, param, size);
- return 0;
+static inline int write_user_long(unsigned long useraddr, unsigned long value)
+{
+ return put_user(value, (unsigned long *)useraddr) ? -EFAULT : 0;
}

#define COPYOUT(x) ECALL(fd_copyout((void *)param, &(x), sizeof(x)))
@@ -3259,6 +3257,21 @@
return -EINVAL;
}

+static int get_floppy_geometry(int drive, int type, struct floppy_struct **g)
+{
+ if (type)
+ *g = &floppy_type[type];
+ else {
+ LOCK_FDC(drive,0);
+ CALL(poll_drive(0,0));
+ process_fd_request();
+ *g = current_type[drive];
+ }
+ if(!*g)
+ return -ENODEV;
+ return 0;
+}
+
static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long param)
{
@@ -3297,6 +3310,43 @@
cmd = FDEJECT;
}

+ /* generic block device ioctls */
+ switch(cmd) {
+ /* the following have been inspired by the corresponding
+ * code for other block devices. */
+ struct floppy_struct *g;
+ struct hd_geometry *loc;
+
+ case HDIO_GETGEO:
+ loc = (struct hd_geometry *) param;
+ ECALL(get_floppy_geometry(drive, type, &g));
+ ECALL(verify_area(VERIFY_WRITE, loc, sizeof(*loc)));
+ put_user(g->head, &loc->heads);
+ put_user(g->sect, &loc->sectors);
+ put_user(g->track, &loc->cylinders);
+ put_user(0,&loc->start);
+ return 0;
+ case BLKRASET:
+ if(!suser()) return -EACCES;
+ if(param > 0xff) return -EINVAL;
+ read_ahead[MAJOR(inode->i_rdev)] = param;
+ return 0;
+ case BLKRAGET:
+ return write_user_long(param,
+ read_ahead[MAJOR(inode->i_rdev)]);
+ case BLKFLSBUF:
+ if(!suser()) return -EACCES;
+ fsync_dev(inode->i_rdev);
+ invalidate_buffers(inode->i_rdev);
+ return 0;
+
+ case BLKGETSIZE:
+ ECALL(get_floppy_geometry(drive, type, &g));
+ return write_user_long(param, g->size);
+ /* BLKRRPART is not defined as floppies don't have
+ * partition tables */
+ }
+
/* convert the old style command into a new style command */
if ((cmd & 0xff00) == 0x0200) {
ECALL(normalize_0x02xx_ioctl(&cmd, &size));
@@ -3345,15 +3395,9 @@
return set_geometry(cmd, & inparam.g,
drive, type, device);
case FDGETPRM:
- LOCK_FDC(drive,1);
- CALL(poll_drive(1,0));
- process_fd_request();
- if (type)
- outparam = (char *) &floppy_type[type];
- else
- outparam = (char *) current_type[drive];
- if(!outparam)
- return -ENODEV;
+ ECALL(get_floppy_geometry(drive, type,
+ (struct floppy_struct**)
+ &outparam));
break;

case FDMSGON:
@@ -4174,7 +4218,7 @@
j=1;

for (i=current->mm->env_start; i< current->mm->env_end; i ++){
- c= get_fs_byte(i);
+ get_user(c,(unsigned char*)i);
if (match){
if (j==99)
c='\0';
diff -ur 2.1.4/linux/fs/buffer.c linux/fs/buffer.c
--- 2.1.4/linux/fs/buffer.c Thu Oct 17 21:47:38 1996
+++ linux/fs/buffer.c Thu Oct 17 21:22:55 1996
@@ -210,7 +210,31 @@
next->b_count--;
retry = 1;
}
-
+
+ repeat2:
+ bh = lru_list[BUF_LOCKED];
+ if (!bh)
+ break;
+ for (i = nr_buffers_type[BUF_LOCKED]*2 ; i-- > 0 ; bh = next) {
+ if (bh->b_list != BUF_LOCKED)
+ goto repeat2;
+ next = bh->b_next_free;
+ if (!lru_list[BUF_LOCKED])
+ break;
+ if (dev && bh->b_dev != dev)
+ continue;
+ if (buffer_locked(bh)) {
+ /* Buffer is locked; skip it unless wait is
+ requested AND pass > 0. */
+ if (!wait || !pass) {
+ retry = 1;
+ continue;
+ }
+ wait_on_buffer (bh);
+ goto repeat2;
+ }
+ }
+
/* If we are waiting for the sync to succeed, and if any dirty
blocks were written, then repeat; on the second pass, only
wait for buffers being written (do not pass to write any