patch-2.4.20 linux-2.4.20/drivers/block/xd.c

Next file: linux-2.4.20/drivers/block/xd.h
Previous file: linux-2.4.20/drivers/block/umem.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.19/drivers/block/xd.c linux-2.4.20/drivers/block/xd.c
@@ -144,32 +144,40 @@
 	release:	xd_release,
 	ioctl:		xd_ioctl,
 };
+
 static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int);
 static DECLARE_WAIT_QUEUE_HEAD(xd_wait_open);
-static u_char xd_valid[XD_MAXDRIVES] = { 0,0 };
-static u_char xd_drives, xd_irq = 5, xd_dma = 3, xd_maxsectors;
-static u_char xd_override __initdata = 0, xd_type __initdata = 0;
-static u_short xd_iobase = 0x320;
+static u8 xd_valid[XD_MAXDRIVES] = { 0,0 };
+static u8 xd_drives, xd_irq = 5, xd_dma = 3, xd_maxsectors;
+static u8 xd_override __initdata = 0, xd_type __initdata = 0;
+static u16 xd_iobase = 0x320;
 static int xd_geo[XD_MAXDRIVES*3] __initdata = { 0, };
 
 static volatile int xdc_busy;
-static DECLARE_WAIT_QUEUE_HEAD(xdc_wait);
 
-static struct timer_list xd_timer, xd_watchdog_int;
+static struct timer_list xd_watchdog_int;
 
-static volatile u_char xd_error;
+static volatile u8 xd_error;
 static int nodma = XD_DONT_USE_DMA;
 
 static devfs_handle_t devfs_handle = NULL;
 
 /* xd_init: register the block device number and set up pointer tables */
-int __init xd_init (void)
+int __init xd_init(void)
 {
-	init_timer (&xd_timer); xd_timer.function = xd_wakeup;
-	init_timer (&xd_watchdog_int); xd_watchdog_int.function = xd_watchdog;
+	init_timer (&xd_watchdog_int); 
+	xd_watchdog_int.function = xd_watchdog;
+
+	if (!xd_dma_buffer)
+		xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
+	if (!xd_dma_buffer)
+	{
+		printk(KERN_ERR "xd: Out of memory.\n");
+		return -ENOMEM;
+	}
 
 	if (devfs_register_blkdev(MAJOR_NR,"xd",&xd_fops)) {
-		printk("xd: Unable to get major number %d\n",MAJOR_NR);
+		printk(KERN_ERR "xd: Unable to get major number %d\n",MAJOR_NR);
 		return -1;
 	}
 	devfs_handle = devfs_mk_dir (NULL, xd_gendisk.major_name, NULL);
@@ -182,9 +190,10 @@
 }
 
 /* xd_detect: scan the possible BIOS ROM locations for the signature strings */
-static u_char __init xd_detect (u_char *controller, unsigned int *address)
+
+static u8 __init xd_detect (u8 *controller, unsigned int *address)
 {
-	u_char i,j,found = 0;
+	u8 i,j,found = 0;
 
 	if (xd_override)
 	{
@@ -206,32 +215,32 @@
 
 /* xd_geninit: grab the IRQ and DMA channel, initialise the drives */
 /* and set up the "raw" device entries in the table */
+
 static void __init xd_geninit (void)
 {
-	u_char i,controller;
+	u8 i,controller;
 	unsigned int address;
 
-	for(i=0;i<(XD_MAXDRIVES << 6);i++) xd_blocksizes[i] = 1024;
+	for(i=0;i<(XD_MAXDRIVES << 6);i++)
+		xd_blocksizes[i] = 1024;
+		
 	blksize_size[MAJOR_NR] = xd_blocksizes;
 
 	if (xd_detect(&controller,&address)) {
-
-		printk("Detected a%s controller (type %d) at address %06x\n",
+		printk(KERN_INFO "Detected a%s controller (type %d) at address %06x\n",
 			xd_sigs[controller].name,controller,address);
-		if (check_region(xd_iobase,4)) {
-			printk("xd: Ports at 0x%x are not available\n",
-				xd_iobase);
+		if (!request_region(xd_iobase,4, "xd")) {
+			printk(KERN_ERR "xd: Ports at 0x%x are not available\n", xd_iobase);
 			return;
 		}
-		request_region(xd_iobase,4,"xd");
 		if (controller)
 			xd_sigs[controller].init_controller(address);
 		xd_drives = xd_initdrives(xd_sigs[controller].init_drive);
 		
-		printk("Detected %d hard drive%s (using IRQ%d & DMA%d)\n",
+		printk(KERN_INFO "Detected %d hard drive%s (using IRQ%d & DMA%d)\n",
 			xd_drives,xd_drives == 1 ? "" : "s",xd_irq,xd_dma);
 		for (i = 0; i < xd_drives; i++)
-			printk(" xd%c: CHS=%d/%d/%d\n",'a'+i,
+			printk(KERN_INFO " xd%c: CHS=%d/%d/%d\n",'a'+i,
 				xd_info[i].cylinders,xd_info[i].heads,
 				xd_info[i].sectors);
 
@@ -239,12 +248,12 @@
 	if (xd_drives) {
 		if (!request_irq(xd_irq,xd_interrupt_handler, 0, "XT hard disk", NULL)) {
 			if (request_dma(xd_dma,"xd")) {
-				printk("xd: unable to get DMA%d\n",xd_dma);
+				printk(KERN_ERR "xd: unable to get DMA%d\n",xd_dma);
 				free_irq(xd_irq, NULL);
 			}
 		}
 		else
-			printk("xd: unable to get IRQ%d\n",xd_irq);
+			printk(KERN_ERR "xd: unable to get IRQ%d\n",xd_irq);
 	}
 
 	/* xd_maxsectors depends on controller - so set after detection */
@@ -270,9 +279,7 @@
 	if (dev < xd_drives) {
 		while (!xd_valid[dev])
 			sleep_on(&xd_wait_open);
-
 		xd_access[dev]++;
-
 		return (0);
 	}
 
@@ -282,18 +289,16 @@
 /* do_xd_request: handle an incoming request */
 static void do_xd_request (request_queue_t * q)
 {
-	u_int block,count,retry;
+	unsigned int block,count,retry;
 	int code;
 
-	sti();
 	if (xdc_busy)
 		return;
+		
 	while (code = 0, !QUEUE_EMPTY) {
 		INIT_REQUEST;	/* do some checking on the request structure */
 
-		if (CURRENT_DEV < xd_drives
-		    && CURRENT->sector + CURRENT->nr_sectors
-		         <= xd_struct[MINOR(CURRENT->rq_dev)].nr_sects) {
+		if (CURRENT_DEV < xd_drives && CURRENT->sector + CURRENT->nr_sectors <= xd_struct[MINOR(CURRENT->rq_dev)].nr_sects) {
 			block = CURRENT->sector + xd_struct[MINOR(CURRENT->rq_dev)].start_sect;
 			count = CURRENT->nr_sectors;
 
@@ -304,8 +309,7 @@
 						code = xd_readwrite(CURRENT->cmd,CURRENT_DEV,CURRENT->buffer,block,count);
 					break;
 				default:
-					printk("do_xd_request: unknown request\n");
-					break;
+					BUG();
 			}
 		}
 		end_request(code);	/* wrap up, 0 = fail, 1 = success */
@@ -313,7 +317,8 @@
 }
 
 /* xd_ioctl: handle device ioctl's */
-static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg)
+
+static int xd_ioctl (struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg)
 {
 	int dev;
 
@@ -327,7 +332,6 @@
 		{
 			struct hd_geometry g;
 			struct hd_geometry *geometry = (struct hd_geometry *) arg;
-			if (!geometry) return -EINVAL;
 			g.heads = xd_info[dev].heads;
 			g.sectors = xd_info[dev].sectors;
 			g.cylinders = xd_info[dev].cylinders;
@@ -335,12 +339,23 @@
 			return copy_to_user(geometry, &g, sizeof g) ? -EFAULT : 0;
 		}
 		case HDIO_SET_DMA:
-			if (!capable(CAP_SYS_ADMIN)) return -EACCES;
-			if (xdc_busy) return -EBUSY;
+			if (!capable(CAP_SYS_ADMIN))
+				return -EACCES;
+			if (xdc_busy)
+				return -EBUSY;
+				
 			nodma = !arg;
+			
 			if (nodma && xd_dma_buffer) {
 				xd_dma_mem_free((unsigned long)xd_dma_buffer, xd_maxsectors * 0x200);
 				xd_dma_buffer = 0;
+			} else if (!nodma && !xd_dma_buffer) {
+				xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
+				if (!xd_dma_buffer)
+				{
+					nodma = XD_DONT_USE_DMA;
+					return -ENOMEM;
+				}
 			}
 			return 0;
 		case HDIO_GET_DMA:
@@ -351,7 +366,6 @@
 			if (!capable(CAP_SYS_ADMIN)) 
 				return -EACCES;
 			return xd_reread_partitions(inode->i_rdev);
-
 		case BLKGETSIZE:
 		case BLKGETSIZE64:
 		case BLKFLSBUF:
@@ -361,7 +375,6 @@
 		case BLKRAGET:
 		case BLKPG:
 			return blk_ioctl(inode->i_rdev, cmd, arg);
-
 		default:
 			return -EINVAL;
 	}
@@ -409,21 +422,20 @@
 }
 
 /* xd_readwrite: handle a read/write request */
-static int xd_readwrite (u_char operation,u_char drive,char *buffer,u_int block,u_int count)
+static int xd_readwrite (u8 operation,u8 drive,char *buffer,unsigned int block,unsigned int count)
 {
-	u_char cmdblk[6],sense[4];
-	u_short track,cylinder;
-	u_char head,sector,control,mode = PIO_MODE,temp;
+	u8 cmdblk[6],sense[4];
+	u16 track,cylinder;
+	u8 head,sector,control,mode = PIO_MODE,temp;
 	char **real_buffer;
-	register int i;
 	
 #ifdef DEBUG_READWRITE
-	printk("xd_readwrite: operation = %s, drive = %d, buffer = 0x%X, block = %d, count = %d\n",operation == READ ? "read" : "write",drive,buffer,block,count);
+	printk(KERN_DEBUG "xd_readwrite: operation = %s, drive = %d, buffer = 0x%X, block = %d, count = %d\n",operation == READ ? "read" : "write",drive,buffer,block,count);
 #endif /* DEBUG_READWRITE */
 
+	spin_unlock_irq(&io_request_lock);
+
 	control = xd_info[drive].control;
-	if (!xd_dma_buffer)
-		xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
 	while (count) {
 		temp = count < xd_maxsectors ? count : xd_maxsectors;
 
@@ -433,28 +445,28 @@
 		sector = block % xd_info[drive].sectors;
 
 #ifdef DEBUG_READWRITE
-		printk("xd_readwrite: drive = %d, head = %d, cylinder = %d, sector = %d, count = %d\n",drive,head,cylinder,sector,temp);
+		printk(KERN_DEBUG "xd_readwrite: drive = %d, head = %d, cylinder = %d, sector = %d, count = %d\n",drive,head,cylinder,sector,temp);
 #endif /* DEBUG_READWRITE */
 
 		if (xd_dma_buffer) {
-			mode = xd_setup_dma(operation == READ ? DMA_MODE_READ : DMA_MODE_WRITE,(u_char *)(xd_dma_buffer),temp * 0x200);
+			mode = xd_setup_dma(operation == READ ? DMA_MODE_READ : DMA_MODE_WRITE,(u8 *)(xd_dma_buffer),temp * 0x200);
 			real_buffer = &xd_dma_buffer;
-			for (i=0; i < (temp * 0x200); i++)
-				xd_dma_buffer[i] = buffer[i];
+			memcpy(xd_dma_buffer, buffer, temp * 0x200);
 		}
 		else
 			real_buffer = &buffer;
 
 		xd_build(cmdblk,operation == READ ? CMD_READ : CMD_WRITE,drive,head,cylinder,sector,temp & 0xFF,control);
 
-		switch (xd_command(cmdblk,mode,(u_char *)(*real_buffer),(u_char *)(*real_buffer),sense,XD_TIMEOUT)) {
+		switch (xd_command(cmdblk,mode,(u8 *)(*real_buffer),(u8 *)(*real_buffer),sense,XD_TIMEOUT)) 
+		{
 			case 1:
-				printk("xd%c: %s timeout, recalibrating drive\n",'a'+drive,(operation == READ ? "read" : "write"));
+				printk(KERN_WARNING "xd%c: %s timeout, recalibrating drive\n",'a'+drive,(operation == READ ? "read" : "write"));
 				xd_recalibrate(drive);
-				return (0);
+				goto fail;
 			case 2:
 				if (sense[0] & 0x30) {
-					printk("xd%c: %s - ",'a'+drive,(operation == READ ? "reading" : "writing"));
+					printk(KERN_ERR "xd%c: %s - ",'a'+drive,(operation == READ ? "reading" : "writing"));
 					switch ((sense[0] & 0x30) >> 4) {
 					case 0: printk("drive error, code = 0x%X",sense[0] & 0x0F);
 						break;
@@ -471,25 +483,30 @@
 				/*	reported drive number = (sense[1] & 0xE0) >> 5 */
 				else
 					printk(" - no valid disk address\n");
-				return (0);
+				goto fail;
 		}
 		if (xd_dma_buffer)
-			for (i=0; i < (temp * 0x200); i++)
-				buffer[i] = xd_dma_buffer[i];
+			memcpy(buffer, xd_dma_buffer, (temp * 0x200));
 
 		count -= temp, buffer += temp * 0x200, block += temp;
 	}
-	return (1);
+	spin_lock_irq(&io_request_lock);
+	return 1;
+
+fail:
+	spin_lock_irq(&io_request_lock);
+	return 0;
+
 }
 
 /* xd_recalibrate: recalibrate a given drive and reset controller if necessary */
-static void xd_recalibrate (u_char drive)
+static void xd_recalibrate (u8 drive)
 {
-	u_char cmdblk[6];
+	u8 cmdblk[6];
 	
 	xd_build(cmdblk,CMD_RECALIBRATE,drive,0,0,0,0,0);
 	if (xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 8))
-		printk("xd%c: warning! error recalibrating, controller may be unstable\n", 'a'+drive);
+		printk(KERN_WARNING "xd%c: warning! error recalibrating, controller may be unstable\n", 'a'+drive);
 }
 
 /* xd_interrupt_handler: interrupt service routine */
@@ -497,17 +514,17 @@
 {
 	if (inb(XD_STATUS) & STAT_INTERRUPT) {							/* check if it was our device */
 #ifdef DEBUG_OTHER
-		printk("xd_interrupt_handler: interrupt detected\n");
+		printk(KERN_DEBUG "xd_interrupt_handler: interrupt detected\n");
 #endif /* DEBUG_OTHER */
 		outb(0,XD_CONTROL);								/* acknowledge interrupt */
 		wake_up(&xd_wait_int);								/* and wake up sleeping processes */
 	}
 	else
-		printk("xd: unexpected interrupt\n");
+		printk(KERN_DEBUG "xd: unexpected interrupt\n");
 }
 
 /* xd_setup_dma: set up the DMA controller for a data transfer */
-static u_char xd_setup_dma (u_char mode,u_char *buffer,u_int count)
+static u8 xd_setup_dma (u8 mode,u8 *buffer,unsigned int count)
 {
 	unsigned long f;
 	
@@ -515,9 +532,9 @@
 		return (PIO_MODE);
 	if (((unsigned long) buffer & 0xFFFF0000) != (((unsigned long) buffer + count) & 0xFFFF0000)) {
 #ifdef DEBUG_OTHER
-		printk("xd_setup_dma: using PIO, transfer overlaps 64k boundary\n");
+		printk(KERN_DEBUG "xd_setup_dma: using PIO, transfer overlaps 64k boundary\n");
 #endif /* DEBUG_OTHER */
-		return (PIO_MODE);
+		return PIO_MODE;
 	}
 	
 	f=claim_dma_lock();
@@ -529,11 +546,11 @@
 	
 	release_dma_lock(f);
 
-	return (DMA_MODE);			/* use DMA and INT */
+	return DMA_MODE;			/* use DMA and INT */
 }
 
 /* xd_build: put stuff into an array in a format suitable for the controller */
-static u_char *xd_build (u_char *cmdblk,u_char command,u_char drive,u_char head,u_short cylinder,u_char sector,u_char count,u_char control)
+static u8 *xd_build (u8 *cmdblk,u8 command,u8 drive,u8 head,u16 cylinder,u8 sector,u8 count,u8 control)
 {
 	cmdblk[0] = command;
 	cmdblk[1] = ((drive & 0x07) << 5) | (head & 0x1F);
@@ -542,13 +559,7 @@
 	cmdblk[4] = count;
 	cmdblk[5] = control;
 	
-	return (cmdblk);
-}
-
-/* xd_wakeup is called from timer interrupt */
-static void xd_wakeup (unsigned long unused)
-{
-	wake_up(&xdc_wait);
+	return cmdblk;
 }
 
 /* xd_wakeup is called from timer interrupt */
@@ -559,25 +570,21 @@
 }
 
 /* xd_waitport: waits until port & mask == flags or a timeout occurs. return 1 for a timeout */
-static inline u_char xd_waitport (u_short port,u_char flags,u_char mask,u_long timeout)
+static inline u8 xd_waitport (u16 port,u8 flags,u8 mask,unsigned long timeout)
 {
-	u_long expiry = jiffies + timeout;
+	unsigned long expiry = jiffies + timeout;
 	int success;
 
 	xdc_busy = 1;
 	while ((success = ((inb(port) & mask) != flags)) && time_before(jiffies, expiry)) {
-		xd_timer.expires = jiffies;
-		cli();
-		add_timer(&xd_timer);
-		sleep_on(&xdc_wait);
-		del_timer(&xd_timer);
-		sti();
+		set_current_state(TASK_UNINTERRUPTIBLE);
+		schedule_timeout(1);
 	}
 	xdc_busy = 0;
 	return (success);
 }
 
-static inline u_int xd_wait_for_IRQ (void)
+static inline unsigned int xd_wait_for_IRQ (void)
 {
 	unsigned long flags;
 	xd_watchdog_int.expires = jiffies + 8 * HZ;
@@ -588,7 +595,7 @@
 	release_dma_lock(flags);
 	
 	sleep_on(&xd_wait_int);
-	del_timer(&xd_watchdog_int);
+	del_timer_sync(&xd_watchdog_int);
 	xdc_busy = 0;
 	
 	flags=claim_dma_lock();
@@ -596,7 +603,7 @@
 	release_dma_lock(flags);
 	
 	if (xd_error) {
-		printk("xd: missed IRQ - command aborted\n");
+		printk(KERN_DEBUG "xd: missed IRQ - command aborted\n");
 		xd_error = 0;
 		return (1);
 	}
@@ -604,12 +611,13 @@
 }
 
 /* xd_command: handle all data transfers necessary for a single command */
-static u_int xd_command (u_char *command,u_char mode,u_char *indata,u_char *outdata,u_char *sense,u_long timeout)
+static unsigned int xd_command (u8 *command,u8 mode,u8 *indata,u8 *outdata,u8 *sense,unsigned long timeout)
 {
-	u_char cmdblk[6],csb,complete = 0;
+	u8 cmdblk[6];
+	u8 csb,complete = 0;
 
 #ifdef DEBUG_COMMAND
-	printk("xd_command: command = 0x%X, mode = 0x%X, indata = 0x%X, outdata = 0x%X, sense = 0x%X\n",command,mode,indata,outdata,sense);
+	printk(KERN_DEBUG "xd_command: command = 0x%X, mode = 0x%X, indata = 0x%X, outdata = 0x%X, sense = 0x%X\n",command,mode,indata,outdata,sense);
 #endif /* DEBUG_COMMAND */
 
 	outb(0,XD_SELECT);
@@ -656,55 +664,57 @@
 	if (csb & CSB_ERROR) {									/* read sense data if error */
 		xd_build(cmdblk,CMD_SENSE,(csb & CSB_LUN) >> 5,0,0,0,0,0);
 		if (xd_command(cmdblk,0,sense,0,0,XD_TIMEOUT))
-			printk("xd: warning! sense command failed!\n");
+			printk(KERN_DEBUG "xd: warning! sense command failed!\n");
 	}
 
 #ifdef DEBUG_COMMAND
-	printk("xd_command: completed with csb = 0x%X\n",csb);
+	printk(KERN_DEBUG "xd_command: completed with csb = 0x%X\n",csb);
 #endif /* DEBUG_COMMAND */
 
 	return (csb & CSB_ERROR);
 }
 
-static u_char __init xd_initdrives (void (*init_drive)(u_char drive))
+static u8 __init xd_initdrives (void (*init_drive)(u8 drive))
 {
-	u_char cmdblk[6],i,count = 0;
+	u8 cmdblk[6],i,count = 0;
 
 	for (i = 0; i < XD_MAXDRIVES; i++) {
 		xd_build(cmdblk,CMD_TESTREADY,i,0,0,0,0,0);
 		if (!xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 8)) {
-	 		xd_timer.expires = jiffies + XD_INIT_DISK_DELAY;
-			add_timer(&xd_timer);
-			sleep_on(&xdc_wait);
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(XD_INIT_DISK_DELAY);
 
 			init_drive(count);
 			count++;
 
-	 		xd_timer.expires = jiffies + XD_INIT_DISK_DELAY;
-			add_timer(&xd_timer);
-			sleep_on(&xdc_wait);
+			set_current_state(TASK_INTERRUPTIBLE);
+			schedule_timeout(XD_INIT_DISK_DELAY);
 		}
 	}
 	return (count);
 }
 
-static void __init xd_manual_geo_set (u_char drive)
+static void __init xd_manual_geo_set (u8 drive)
 {
-	xd_info[drive].heads = (u_char)(xd_geo[3 * drive + 1]);
-	xd_info[drive].cylinders = (u_short)(xd_geo[3 * drive]);
-	xd_info[drive].sectors = (u_char)(xd_geo[3 * drive + 2]);
+	xd_info[drive].heads 	= xd_geo[3 * drive + 1];
+	xd_info[drive].cylinders= xd_geo[3 * drive];
+	xd_info[drive].sectors =  xd_geo[3 * drive + 2];
 }
 
 static void __init xd_dtc_init_controller (unsigned int address)
 {
 	switch (address) {
 		case 0x00000:
-		case 0xC8000:	break;			/*initial: 0x320 */
-		case 0xCA000:	xd_iobase = 0x324; 
-		case 0xD0000:				/*5150CX*/
-		case 0xD8000:	break;			/*5150CX & 5150XL*/
-		default:        printk("xd_dtc_init_controller: unsupported BIOS address %06x\n",address);
-				break;
+		case 0xC8000:
+			break;			/*initial: 0x320 */
+		case 0xCA000:
+			xd_iobase = 0x324; 
+		case 0xD0000:			/*5150CX*/
+		case 0xD8000:
+			break;			/*5150CX & 5150XL*/
+		default:        
+			printk(KERN_ERR "xd_dtc_init_controller: unsupported BIOS address %06x\n",address);
+			break;
 	}
 	xd_maxsectors = 0x01;		/* my card seems to have trouble doing multi-block transfers? */
 
@@ -712,10 +722,10 @@
 }
 
 
-static void __init xd_dtc5150cx_init_drive (u_char drive)
+static void __init xd_dtc5150cx_init_drive (u8 drive)
 {
 	/* values from controller's BIOS - BIOS chip may be removed */
-	static u_short geometry_table[][4] = {
+	static u16 geometry_table[][4] = {
 		{0x200,8,0x200,0x100},
 		{0x267,2,0x267,0x267},
 		{0x264,4,0x264,0x80},
@@ -732,7 +742,7 @@
 		{0x2B9,5,0x2B9,0x2B9},
 		{0x280,6,0x280,0x100},
 		{0x132,4,0x132,0x0}};
-	u_char n;
+	u8 n;
 
 	n = inb(XD_JUMPER);
 	n = (drive ? n : (n >> 2)) & 0x33;
@@ -741,7 +751,7 @@
 		xd_manual_geo_set(drive);
 	else
 		if (n != 7) {	
-			xd_info[drive].heads = (u_char)(geometry_table[n][1]);			/* heads */
+			xd_info[drive].heads = (u8)(geometry_table[n][1]);			/* heads */
 			xd_info[drive].cylinders = geometry_table[n][0];	/* cylinders */
 			xd_info[drive].sectors = 17;				/* sectors */
 #if 0
@@ -751,7 +761,7 @@
 #endif /* 0 */
 		}
 		else {
-			printk("xd%c: undetermined drive geometry\n",'a'+drive);
+			printk(KERN_WARNING "xd%c: undetermined drive geometry\n",'a'+drive);
 			return;
 		}
 	xd_info[drive].control = 5;				/* control byte */
@@ -759,31 +769,31 @@
 	xd_recalibrate(drive);
 }
 
-static void __init xd_dtc_init_drive (u_char drive)
+static void __init xd_dtc_init_drive (u8 drive)
 {
-	u_char cmdblk[6],buf[64];
+	u8 cmdblk[6],buf[64];
 
 	xd_build(cmdblk,CMD_DTCGETGEOM,drive,0,0,0,0,0);
 	if (!xd_command(cmdblk,PIO_MODE,buf,0,0,XD_TIMEOUT * 2)) {
 		xd_info[drive].heads = buf[0x0A];			/* heads */
-		xd_info[drive].cylinders = ((u_short *) (buf))[0x04];	/* cylinders */
+		xd_info[drive].cylinders = ((u16 *) (buf))[0x04];	/* cylinders */
 		xd_info[drive].sectors = 17;				/* sectors */
 		if (xd_geo[3*drive])
 			xd_manual_geo_set(drive);
 #if 0
-		xd_info[drive].rwrite = ((u_short *) (buf + 1))[0x05];	/* reduced write */
-		xd_info[drive].precomp = ((u_short *) (buf + 1))[0x06];	/* write precomp */
+		xd_info[drive].rwrite = ((u16 *) (buf + 1))[0x05];	/* reduced write */
+		xd_info[drive].precomp = ((u16 *) (buf + 1))[0x06];	/* write precomp */
 		xd_info[drive].ecc = buf[0x0F];				/* ecc length */
 #endif /* 0 */
 		xd_info[drive].control = 0;				/* control byte */
 
-		xd_setparam(CMD_DTCSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,((u_short *) (buf + 1))[0x05],((u_short *) (buf + 1))[0x06],buf[0x0F]);
+		xd_setparam(CMD_DTCSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,((u16 *) (buf + 1))[0x05],((u16 *) (buf + 1))[0x06],buf[0x0F]);
 		xd_build(cmdblk,CMD_DTCSETSTEP,drive,0,0,0,0,7);
 		if (xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 2))
-			printk("xd_dtc_init_drive: error setting step rate for xd%c\n", 'a'+drive);
+			printk(KERN_WARNING "xd_dtc_init_drive: error setting step rate for xd%c\n", 'a'+drive);
 	}
 	else
-		printk("xd_dtc_init_drive: error reading geometry for xd%c\n", 'a'+drive);
+		printk(KERN_WARNING "xd_dtc_init_drive: error reading geometry for xd%c\n", 'a'+drive);
 }
 
 static void __init xd_wd_init_controller (unsigned int address)
@@ -796,22 +806,21 @@
 		case 0xCE000:   xd_iobase = 0x32C; break;
 		case 0xD0000:	xd_iobase = 0x328; break; /* ? */
 		case 0xD8000:	xd_iobase = 0x32C; break; /* ? */
-		default:        printk("xd_wd_init_controller: unsupported BIOS address %06x\n",address);
+		default:        printk(KERN_ERR "xd_wd_init_controller: unsupported BIOS address %06x\n",address);
 				break;
 	}
 	xd_maxsectors = 0x01;		/* this one doesn't wrap properly either... */
 
 	outb(0,XD_RESET);		/* reset the controller */
 
-	xd_timer.expires = jiffies + XD_INIT_DISK_DELAY;
-	add_timer(&xd_timer);
-	sleep_on(&xdc_wait);
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	schedule_timeout(XD_INIT_DISK_DELAY);
 }
 
-static void __init xd_wd_init_drive (u_char drive)
+static void __init xd_wd_init_drive (u8 drive)
 {
 	/* values from controller's BIOS - BIOS may be disabled */
-	static u_short geometry_table[][4] = {
+	static u16 geometry_table[][4] = {
 		{0x264,4,0x1C2,0x1C2},   /* common part */
 		{0x132,4,0x099,0x0},
 		{0x267,2,0x1C2,0x1C2},
@@ -827,9 +836,9 @@
 		{0x264,4,0x265,0x265},
 		{0x267,4,0x268,0x268}};
 
-	u_char cmdblk[6],buf[0x200];
-	u_char n = 0,rll,jumper_state,use_jumper_geo;
-	u_char wd_1002 = (xd_sigs[xd_type].string[7] == '6');
+	u8 cmdblk[6],buf[0x200];
+	u8 n = 0,rll,jumper_state,use_jumper_geo;
+	u8 wd_1002 = (xd_sigs[xd_type].string[7] == '6');
 	
 	jumper_state = ~(inb(0x322));
 	if (jumper_state & 0x40)
@@ -838,13 +847,13 @@
 	xd_build(cmdblk,CMD_READ,drive,0,0,0,1,0);
 	if (!xd_command(cmdblk,PIO_MODE,buf,0,0,XD_TIMEOUT * 2)) {
 		xd_info[drive].heads = buf[0x1AF];				/* heads */
-		xd_info[drive].cylinders = ((u_short *) (buf + 1))[0xD6];	/* cylinders */
+		xd_info[drive].cylinders = ((u16 *) (buf + 1))[0xD6];	/* cylinders */
 		xd_info[drive].sectors = 17;					/* sectors */
 		if (xd_geo[3*drive])
 			xd_manual_geo_set(drive);
 #if 0
-		xd_info[drive].rwrite = ((u_short *) (buf))[0xD8];		/* reduced write */
-		xd_info[drive].wprecomp = ((u_short *) (buf))[0xDA];		/* write precomp */
+		xd_info[drive].rwrite = ((u16 *) (buf))[0xD8];		/* reduced write */
+		xd_info[drive].wprecomp = ((u16 *) (buf))[0xDA];		/* write precomp */
 		xd_info[drive].ecc = buf[0x1B4];				/* ecc length */
 #endif /* 0 */
 		xd_info[drive].control = buf[0x1B5];				/* control byte */
@@ -856,7 +865,7 @@
 		else if (use_jumper_geo) {
 			n = (((jumper_state & 0x0F) >> (drive << 1)) & 0x03) | rll;
 			xd_info[drive].cylinders = geometry_table[n][0];
-			xd_info[drive].heads = (u_char)(geometry_table[n][1]);
+			xd_info[drive].heads = (u8)(geometry_table[n][1]);
 			xd_info[drive].control = rll ? 7 : 5;
 #if 0
 			xd_info[drive].rwrite = geometry_table[n][2];
@@ -870,7 +879,7 @@
 					geometry_table[n][2],geometry_table[n][3],0x0B);
 			else
 				xd_setparam(CMD_WDSETPARAM,drive,xd_info[drive].heads,xd_info[drive].cylinders,
-					((u_short *) (buf))[0xD8],((u_short *) (buf))[0xDA],buf[0x1B4]);
+					((u16 *) (buf))[0xD8],((u16 *) (buf))[0xDA],buf[0x1B4]);
 		}
 	/* 1002 based RLL controller requests converted addressing, but reports physical 
 	   (physical 26 sec., logical 17 sec.) 
@@ -888,7 +897,7 @@
 		}
 	}
 	else
-		printk("xd_wd_init_drive: error reading geometry for xd%c\n",'a'+drive);	
+		printk(KERN_WARNING "xd_wd_init_drive: error reading geometry for xd%c\n",'a'+drive);	
 
 }
 
@@ -900,7 +909,7 @@
 		case 0xD0000:	xd_iobase = 0x324; break;
 		case 0xD8000:	xd_iobase = 0x328; break;
 		case 0xE0000:	xd_iobase = 0x32C; break;
-		default:	printk("xd_seagate_init_controller: unsupported BIOS address %06x\n",address);
+		default:	printk(KERN_ERR "xd_seagate_init_controller: unsupported BIOS address %06x\n",address);
 				break;
 	}
 	xd_maxsectors = 0x40;
@@ -908,9 +917,9 @@
 	outb(0,XD_RESET);		/* reset the controller */
 }
 
-static void __init xd_seagate_init_drive (u_char drive)
+static void __init xd_seagate_init_drive (u8 drive)
 {
-	u_char cmdblk[6],buf[0x200];
+	u8 cmdblk[6],buf[0x200];
 
 	xd_build(cmdblk,CMD_ST11GETGEOM,drive,0,0,0,1,0);
 	if (!xd_command(cmdblk,PIO_MODE,buf,0,0,XD_TIMEOUT * 2)) {
@@ -920,7 +929,7 @@
 		xd_info[drive].control = 0;					/* control byte */
 	}
 	else
-		printk("xd_seagate_init_drive: error reading geometry from xd%c\n", 'a'+drive);
+		printk(KERN_WARNING "xd_seagate_init_drive: error reading geometry from xd%c\n", 'a'+drive);
 }
 
 /* Omti support courtesy Dirk Melchers */
@@ -932,7 +941,7 @@
 		case 0xD0000:	xd_iobase = 0x324; break;
 		case 0xD8000:	xd_iobase = 0x328; break;
 		case 0xE0000:	xd_iobase = 0x32C; break;
-		default:	printk("xd_omti_init_controller: unsupported BIOS address %06x\n",address);
+		default:	printk(KERN_ERR "xd_omti_init_controller: unsupported BIOS address %06x\n",address);
 				break;
 	}
 	
@@ -941,7 +950,7 @@
 	outb(0,XD_RESET);		/* reset the controller */
 }
 
-static void __init xd_omti_init_drive (u_char drive)
+static void __init xd_omti_init_drive (u8 drive)
 {
 	/* gets infos from drive */
 	xd_override_init_drive(drive);
@@ -972,22 +981,21 @@
 		case 0xDC000:
 		case 0xDE000:
 		case 0xE0000:	break;
-		default:	printk("xd_xebec_init_controller: unsupported BIOS address %06x\n",address);
+		default:	printk(KERN_ERR "xd_xebec_init_controller: unsupported BIOS address %06x\n",address);
 				break;
 		}
 
 	xd_maxsectors = 0x01;
 	outb(0,XD_RESET);		/* reset the controller */
 
-	xd_timer.expires = jiffies + XD_INIT_DISK_DELAY;
-	add_timer(&xd_timer);
-	sleep_on(&xdc_wait);
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	schedule_timeout(XD_INIT_DISK_DELAY);
 }
 
-static void __init xd_xebec_init_drive (u_char drive)
+static void __init xd_xebec_init_drive (u8 drive)
 {
 	/* values from controller's BIOS - BIOS chip may be removed */
-	static u_short geometry_table[][5] = {
+	static u16 geometry_table[][5] = {
 		{0x132,4,0x080,0x080,0x7},
 		{0x132,4,0x080,0x080,0x17},
 		{0x264,2,0x100,0x100,0x7},
@@ -1004,14 +1012,14 @@
 		{0x400,6,0x400,0x400,0x7},
 		{0x264,8,0x264,0x200,0x17},
 		{0x33E,7,0x33E,0x200,0x7}};
-	u_char n;
+	u8 n;
 
 	n = inb(XD_JUMPER) & 0x0F; /* BIOS's drive number: same geometry 
 					is assumed for BOTH drives */
 	if (xd_geo[3*drive])
 		xd_manual_geo_set(drive);
 	else {
-		xd_info[drive].heads = (u_char)(geometry_table[n][1]);			/* heads */
+		xd_info[drive].heads = (u8)(geometry_table[n][1]);			/* heads */
 		xd_info[drive].cylinders = geometry_table[n][0];	/* cylinders */
 		xd_info[drive].sectors = 17;				/* sectors */
 #if 0
@@ -1027,10 +1035,10 @@
 
 /* xd_override_init_drive: this finds disk geometry in a "binary search" style, narrowing in on the "correct" number of heads
    etc. by trying values until it gets the highest successful value. Idea courtesy Salvador Abreu (spa@fct.unl.pt). */
-static void __init xd_override_init_drive (u_char drive)
+static void __init xd_override_init_drive (u8 drive)
 {
-	u_short min[] = { 0,0,0 },max[] = { 16,1024,64 },test[] = { 0,0,0 };
-	u_char cmdblk[6],i;
+	u16 min[] = { 0,0,0 },max[] = { 16,1024,64 },test[] = { 0,0,0 };
+	u8 cmdblk[6],i;
 
 	if (xd_geo[3*drive])
 		xd_manual_geo_set(drive);
@@ -1038,7 +1046,7 @@
 		for (i = 0; i < 3; i++) {
 			while (min[i] != max[i] - 1) {
 				test[i] = (min[i] + max[i]) / 2;
-				xd_build(cmdblk,CMD_SEEK,drive,(u_char) test[0],(u_short) test[1],(u_char) test[2],0,0);
+				xd_build(cmdblk,CMD_SEEK,drive,(u8) test[0],(u16) test[1],(u8) test[2],0,0);
 				if (!xd_command(cmdblk,PIO_MODE,0,0,0,XD_TIMEOUT * 2))
 					min[i] = test[i];
 				else
@@ -1046,9 +1054,9 @@
 			}
 			test[i] = min[i];
 		}
-		xd_info[drive].heads = (u_char) min[0] + 1;
-		xd_info[drive].cylinders = (u_short) min[1] + 1;
-		xd_info[drive].sectors = (u_char) min[2] + 1;
+		xd_info[drive].heads = (u8) min[0] + 1;
+		xd_info[drive].cylinders = (u16) min[1] + 1;
+		xd_info[drive].sectors = (u8) min[2] + 1;
 	}
 	xd_info[drive].control = 0;
 }
@@ -1069,30 +1077,30 @@
 			if ((integers[1] >= 0) && (integers[1] < (sizeof(xd_sigs) / sizeof(xd_sigs[0]))))
 				xd_type = integers[1];
 		case 0: break;
-		default:printk("xd: too many parameters for xd\n");
+		default:printk(KERN_ERR "xd: too many parameters for xd\n");
 	}
 	xd_maxsectors = 0x01;
 }
 
 /* xd_setparam: set the drive characteristics */
-static void __init xd_setparam (u_char command,u_char drive,u_char heads,u_short cylinders,u_short rwrite,u_short wprecomp,u_char ecc)
+static void __init xd_setparam (u8 command,u8 drive,u8 heads,u16 cylinders,u16 rwrite,u16 wprecomp,u8 ecc)
 {
-	u_char cmdblk[14];
+	u8 cmdblk[14];
 
 	xd_build(cmdblk,command,drive,0,0,0,0,0);
-	cmdblk[6] = (u_char) (cylinders >> 8) & 0x03;
-	cmdblk[7] = (u_char) (cylinders & 0xFF);
+	cmdblk[6] = (u8) (cylinders >> 8) & 0x03;
+	cmdblk[7] = (u8) (cylinders & 0xFF);
 	cmdblk[8] = heads & 0x1F;
-	cmdblk[9] = (u_char) (rwrite >> 8) & 0x03;
-	cmdblk[10] = (u_char) (rwrite & 0xFF);
-	cmdblk[11] = (u_char) (wprecomp >> 8) & 0x03;
-	cmdblk[12] = (u_char) (wprecomp & 0xFF);
+	cmdblk[9] = (u8) (rwrite >> 8) & 0x03;
+	cmdblk[10] = (u8) (rwrite & 0xFF);
+	cmdblk[11] = (u8) (wprecomp >> 8) & 0x03;
+	cmdblk[12] = (u8) (wprecomp & 0xFF);
 	cmdblk[13] = ecc;
 
 	/* Some controllers require geometry info as data, not command */
 
 	if (xd_command(cmdblk,PIO_MODE,0,&cmdblk[6],0,XD_TIMEOUT * 2))
-		printk("xd: error setting characteristics for xd%c\n", 'a'+drive);
+		printk(KERN_WARNING "xd: error setting characteristics for xd%c\n", 'a'+drive);
 }
 
 
@@ -1145,7 +1153,7 @@
 {
 	devfs_unregister_blkdev(MAJOR_NR, "xd");
 	xd_done();
-	devfs_unregister (devfs_handle);
+	devfs_unregister(devfs_handle);
 	if (xd_drives) {
 		free_irq(xd_irq, NULL);
 		free_dma(xd_dma);
@@ -1171,7 +1179,7 @@
 
 	get_options (str, ARRAY_SIZE (integers), integers);
 	if (integers[0]%3 != 0) {
-		printk("xd: incorrect number of parameters for xd_geo\n");
+		printk(KERN_ERR "xd: incorrect number of parameters for xd_geo\n");
 		return 1;
 	}
 	for (i = 0; (i < integers[0]) && (i < 3*XD_MAXDRIVES); i++)

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)