patch-2.1.8 linux/drivers/block/floppy.c

Next file: linux/drivers/block/genhd.c
Previous file: linux/drivers/block/cmd640.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.7/linux/drivers/block/floppy.c linux/drivers/block/floppy.c
@@ -107,7 +107,6 @@
 
 /* do print messages for unexpected interrupts */
 static int print_unex=1;
-#include <linux/utsname.h>
 #include <linux/module.h>
 
 /* the following is the mask of allowed drives. By default units 2 and
@@ -132,21 +131,6 @@
 #include <linux/fd.h>
 #include <linux/hdreg.h>
 
-#define OLDFDRAWCMD 0x020d /* send a raw command to the FDC */
-
-struct old_floppy_raw_cmd {
-  void *data;
-  long length;
-
-  unsigned char rate;
-  unsigned char flags;
-  unsigned char cmd_count;
-  unsigned char cmd[9];
-  unsigned char reply_count;
-  unsigned char reply[7];
-  int track;
-};
-
 #include <linux/errno.h>
 #include <linux/malloc.h>
 #include <linux/mm.h>
@@ -2419,6 +2403,17 @@
 #endif
 }
 
+static inline int check_dma_crossing(char *start, 
+				     unsigned long length, char *message)
+{
+	if (CROSS_64KB(start, length)) {
+		printk("DMA xfer crosses 64KB boundary in %s %p-%p\n", 
+		       message, start, start+length);
+		return 1;
+	} else
+		return 0;
+}
+
 /*
  * Formulate a read/write request.
  * this routine decides where to load the data (directly to buffer, or to
@@ -2570,6 +2565,9 @@
 					indirect, direct, sector_t);
 				return 0;
 			}
+			check_dma_crossing(raw_cmd->kernel_data, 
+					   raw_cmd->length, 
+					   "end of make_raw_request [1]");
 			return 2;
 		}
 	}
@@ -2615,6 +2613,8 @@
 	raw_cmd->length = ((raw_cmd->length -1)|(ssize-1))+1;
 	raw_cmd->length <<= 9;
 #ifdef FLOPPY_SANITY_CHECK
+	check_dma_crossing(raw_cmd->kernel_data, raw_cmd->length, 
+			   "end of make_raw_request");
 	if ((raw_cmd->length < current_count_sectors << 9) ||
 	    (raw_cmd->kernel_data != CURRENT->buffer &&
 	     CT(COMMAND) == FD_WRITE &&
@@ -2850,13 +2850,11 @@
 	return copy_from_user(address, param, size) ? -EFAULT : 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) (copy_to_user((void *)param, &(x), sizeof(x)) ? -EFAULT : 0)
+#define _COPYIN(x) (copy_from_user(&(x), (void *)param, sizeof(x)) ? -EFAULT : 0)
 
-#define COPYOUT(x) ECALL(fd_copyout((void *)param, &(x), sizeof(x)))
-#define COPYIN(x) ECALL(fd_copyin((void *)param, &(x), sizeof(x)))
+#define COPYOUT(x) ECALL(_COPYOUT(x))
+#define COPYIN(x) ECALL(_COPYIN(x))
 
 static inline const char *drive_name(int type, int drive)
 {
@@ -2927,24 +2925,11 @@
 static inline int raw_cmd_copyout(int cmd, char *param,
 				  struct floppy_raw_cmd *ptr)
 {
-	struct old_floppy_raw_cmd old_raw_cmd;
 	int ret;
 
 	while(ptr) {
-		if (cmd == OLDFDRAWCMD) {
-			old_raw_cmd.flags = ptr->flags;
-			old_raw_cmd.data = ptr->data;
-			old_raw_cmd.length = ptr->length;
-			old_raw_cmd.rate = ptr->rate;
-			old_raw_cmd.reply_count = ptr->reply_count;
-			memcpy(old_raw_cmd.reply, ptr->reply, 7);
-			COPYOUT(old_raw_cmd);
-			param += sizeof(old_raw_cmd);
-		} else {
-			COPYOUT(*ptr);
-			param += sizeof(struct floppy_raw_cmd);
-		}
-
+		COPYOUT(*ptr);
+		param += sizeof(struct floppy_raw_cmd);
 		if ((ptr->flags & FD_RAW_READ) && ptr->buffer_length){
 			if (ptr->length>=0 && ptr->length<=ptr->buffer_length)
 				ECALL(fd_copyout(ptr->data, 
@@ -2981,7 +2966,6 @@
 				 struct floppy_raw_cmd **rcmd)
 {
 	struct floppy_raw_cmd *ptr;
-	struct old_floppy_raw_cmd old_raw_cmd;
 	int ret;
 	int i;
 	
@@ -2992,37 +2976,20 @@
 		if (!ptr)
 			return -ENOMEM;
 		*rcmd = ptr;
-		if (cmd == OLDFDRAWCMD){
-			COPYIN(old_raw_cmd);
-			ptr->flags = old_raw_cmd.flags;
-			ptr->data = old_raw_cmd.data;
-			ptr->length = old_raw_cmd.length;
-			ptr->rate = old_raw_cmd.rate;
-			ptr->cmd_count = old_raw_cmd.cmd_count;
-			ptr->track = old_raw_cmd.track;
-			ptr->phys_length = 0;
-			ptr->next = 0;
-			ptr->buffer_length = 0;
-			memcpy(ptr->cmd, old_raw_cmd.cmd, 9);
-			param += sizeof(struct old_floppy_raw_cmd);
-			if (ptr->cmd_count > 9)
-				return -EINVAL;
-		} else {
-			COPYIN(*ptr);
-			ptr->next = 0;
-			ptr->buffer_length = 0;
-			param += sizeof(struct floppy_raw_cmd);
-			if (ptr->cmd_count > 33)
-				/* the command may now also take up the space
-				 * initially intended for the reply & the
-				 * reply count. Needed for long 82078 commands
-				 * such as RESTORE, which takes ... 17 command
-				 * bytes. Murphy's law #137: When you reserve
-				 * 16 bytes for a structure, you'll one day
-				 * discover that you really need 17...
-				 */
-				return -EINVAL;
-		}
+		COPYIN(*ptr);
+		ptr->next = 0;
+		ptr->buffer_length = 0;
+		param += sizeof(struct floppy_raw_cmd);
+		if (ptr->cmd_count > 33)
+			/* the command may now also take up the space
+			 * initially intended for the reply & the
+			 * reply count. Needed for long 82078 commands
+			 * such as RESTORE, which takes ... 17 command
+			 * bytes. Murphy's law #137: When you reserve
+			 * 16 bytes for a structure, you'll one day
+			 * discover that you really need 17...
+			 */
+			return -EINVAL;
 
 		for (i=0; i< 16; i++)
 			ptr->reply[i] = 0;
@@ -3037,9 +3004,6 @@
 				return -ENOMEM;
 			ptr->buffer_length = ptr->length;
 		}
-		if ( ptr->flags & FD_RAW_READ )
-		    ECALL( verify_area( VERIFY_WRITE, ptr->data, 
-					ptr->length ));
 		if (ptr->flags & FD_RAW_WRITE)
 			ECALL(fd_copyin(ptr->data, ptr->kernel_data, 
 					ptr->length));
@@ -3181,47 +3145,42 @@
 }
 
 /* handle obsolete ioctl's */
-static struct translation_entry {
-    int newcmd;
-    int oldcmd;
-    int oldsize; /* size of 0x00xx-style ioctl. Reflects old structures, thus
-		  * use numeric values. NO SIZEOFS */
-} translation_table[]= {
-    {FDCLRPRM,		 0,  0},
-    {FDSETPRM,		 1, 28},
-    {FDDEFPRM,		 2, 28},
-    {FDGETPRM,		 3, 28},
-    {FDMSGON,		 4,  0},
-    {FDMSGOFF,		 5,  0},
-    {FDFMTBEG,		 6,  0},
-    {FDFMTTRK,		 7, 12},
-    {FDFMTEND,		 8,  0},
-    {FDSETEMSGTRESH,	10,  0},
-    {FDFLUSH,		11,  0},
-    {FDSETMAXERRS,	12, 20},
-    {OLDFDRAWCMD,      	30,  0},
-    {FDGETMAXERRS,	14, 20},
-    {FDGETDRVTYP,	16, 16},
-    {FDSETDRVPRM,	20, 88},
-    {FDGETDRVPRM,	21, 88},
-    {FDGETDRVSTAT,	22, 52},
-    {FDPOLLDRVSTAT,	23, 52},
-    {FDRESET,		24,  0},
-    {FDGETFDCSTAT,	25, 40},
-    {FDWERRORCLR,	27,  0},
-    {FDWERRORGET,	28, 24},
-    {FDRAWCMD,		 0,  0},
-    {FDEJECT,		 0,  0},
-    {FDTWADDLE,		40,  0} };
+int ioctl_table[]= {
+	FDCLRPRM,
+	FDSETPRM,
+	FDDEFPRM,
+	FDGETPRM,
+	FDMSGON,
+	FDMSGOFF,
+	FDFMTBEG,
+	FDFMTTRK,
+	FDFMTEND,
+	FDSETEMSGTRESH,
+	FDFLUSH,
+	FDSETMAXERRS,
+	FDGETMAXERRS,
+	FDGETDRVTYP,
+	FDSETDRVPRM,
+	FDGETDRVPRM,
+	FDGETDRVSTAT,
+	FDPOLLDRVSTAT,
+	FDRESET,
+	FDGETFDCSTAT,
+	FDWERRORCLR,
+	FDWERRORGET,
+	FDRAWCMD,
+	FDEJECT,
+	FDTWADDLE
+};
 
-static inline int normalize_0x02xx_ioctl(int *cmd, int *size)
+static inline int normalize_ioctl(int *cmd, int *size)
 {
 	int i;
 
-	for (i=0; i < ARRAY_SIZE(translation_table); i++) {
-		if ((*cmd & 0xffff) == (translation_table[i].newcmd & 0xffff)){
+	for (i=0; i < ARRAY_SIZE(ioctl_table); i++) {
+		if ((*cmd & 0xffff) == (ioctl_table[i] & 0xffff)){
 			*size = _IOC_SIZE(*cmd);
-			*cmd = translation_table[i].newcmd;
+			*cmd = ioctl_table[i];
 			if (*size > _IOC_SIZE(*cmd)) {
 				printk("ioctl not yet supported\n");
 				return -EFAULT;
@@ -3232,31 +3191,6 @@
 	return -EINVAL;
 }
 
-static inline int xlate_0x00xx_ioctl(int *cmd, int *size)
-{
-	int i;
-	/* old ioctls' for kernels <= 1.3.33 */
-	/* When the next even release will come around, we'll start
-	 * warning against these.
-	 * When the next odd release will come around, we'll fail with
-	 * -EINVAL */
-	if(strcmp(system_utsname.version, "1.4.0") >= 0)
-		printk("obsolete floppy ioctl %x\n", *cmd);
-	if((system_utsname.version[0] == '1' &&
-	    strcmp(system_utsname.version, "1.5.0") >= 0) ||
-	   (system_utsname.version[0] >= '2' &&
-	    strcmp(system_utsname.version, "2.1.0") >= 0))
-		return -EINVAL;
-	for (i=0; i < ARRAY_SIZE(translation_table); i++) {
-		if (*cmd == translation_table[i].oldcmd) {
-			*size = translation_table[i].oldsize;
-			*cmd = translation_table[i].newcmd;
-			return 0;
-		}
-	}
-	return -EINVAL;
-}
-
 static int get_floppy_geometry(int drive, int type, struct floppy_struct **g)
 {
 	if (type)
@@ -3315,25 +3249,24 @@
 		/* 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;
+		{
+			struct hd_geometry loc;
 			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;
+			loc.heads = g->head;
+			loc.sectors = g->sect;
+			loc.cylinders = g->track;
+			loc.start = 0;
+			return _COPYOUT(loc);
+		}
 		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)]);
+			return put_user(read_ahead[MAJOR(inode->i_rdev)],
+					(int *) param);
 		case BLKFLSBUF:
 			if(!suser()) return -EACCES;
 			fsync_dev(inode->i_rdev);
@@ -3342,16 +3275,14 @@
 
 		case BLKGETSIZE:
 			ECALL(get_floppy_geometry(drive, type, &g));
-			return write_user_long(param, g->size);
+			return put_user(g->size, (int *) param);
 		/* 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));
-	} else if ((cmd & 0xff00) == 0x0000) {
-		ECALL(xlate_0x00xx_ioctl(&cmd, &size));
+		ECALL(normalize_ioctl(&cmd, &size));
 	} else
 		return -EINVAL;
 
@@ -3360,10 +3291,6 @@
 	     ((cmd & 0x40) && !IOCTL_ALLOWED))
 		return -EPERM;
 
-	/* verify writability of result, and fail early */
-	if (_IOC_DIR(cmd) & _IOC_READ)
-		ECALL(verify_area(VERIFY_WRITE,(void *) param, size));
-		
 	/* copyin */
 	CLEARSTRUCT(&inparam);
 	if (_IOC_DIR(cmd) & _IOC_WRITE)
@@ -3458,7 +3385,6 @@
 			return 0;
 		OUT(FDWERRORGET,UDRWE);
 
-		case OLDFDRAWCMD:
 		case FDRAWCMD:
 			if (type)
 				return -EINVAL;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov