#include <linux/wait.h>
#include <linux/blkdev.h>
#include <linux/blkpg.h>
+#include <linux/delay.h>
+#include <linux/io.h>
#include <asm/system.h>
-#include <asm/io.h>
#include <asm/uaccess.h>
#include <asm/dma.h>
#define XD_DONT_USE_DMA 0 /* Initial value. may be overriden using
"nodma" module option */
-#define XD_INIT_DISK_DELAY (30*HZ/1000) /* 30 ms delay during disk initialization */
+#define XD_INIT_DISK_DELAY (30) /* 30 ms delay during disk initialization */
/* Above may need to be increased if a problem with the 2nd drive detection
(ST11M controller) or resetting a controller (WD) appears */
-XD_INFO xd_info[XD_MAXDRIVES];
+static XD_INFO xd_info[XD_MAXDRIVES];
/* If you try this driver and find that your card is not detected by the driver at bootup, you need to add your BIOS
signature and details to the following list of signatures. A BIOS signature is a string embedded into the first
0xE0000
};
-static spinlock_t xd_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(xd_lock);
static struct gendisk *xd_gendisk[2];
+static int xd_getgeo(struct block_device *bdev, struct hd_geometry *geo);
+
static struct block_device_operations xd_fops = {
.owner = THIS_MODULE,
.ioctl = xd_ioctl,
+ .getgeo = xd_getgeo,
};
static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int);
static u_char xd_drives, xd_irq = 5, xd_dma = 3, xd_maxsectors;
disk->major = XT_DISK_MAJOR;
disk->first_minor = i<<6;
sprintf(disk->disk_name, "xd%c", i+'a');
- sprintf(disk->devfs_name, "xd/target%d", i);
disk->fops = &xd_fops;
disk->private_data = p;
disk->queue = xd_queue;
/* xd_detect: scan the possible BIOS ROM locations for the signature strings */
static u_char __init xd_detect (u_char *controller, unsigned int *address)
{
- u_char i,j,found = 0;
+ int i, j;
if (xd_override)
{
return(1);
}
- for (i = 0; i < (sizeof(xd_bases) / sizeof(xd_bases[0])) && !found; i++)
- for (j = 1; j < (sizeof(xd_sigs) / sizeof(xd_sigs[0])) && !found; j++)
- if (isa_check_signature(xd_bases[i] + xd_sigs[j].offset,xd_sigs[j].string,strlen(xd_sigs[j].string))) {
+ for (i = 0; i < ARRAY_SIZE(xd_bases); i++) {
+ void __iomem *p = ioremap(xd_bases[i], 0x2000);
+ if (!p)
+ continue;
+ for (j = 1; j < ARRAY_SIZE(xd_sigs); j++) {
+ const char *s = xd_sigs[j].string;
+ if (check_signature(p + xd_sigs[j].offset, s, strlen(s))) {
*controller = j;
xd_type = j;
*address = xd_bases[i];
- found++;
+ iounmap(p);
+ return 1;
}
- return (found);
+ }
+ iounmap(p);
+ }
+ return 0;
}
/* do_xd_request: handle an incoming request */
int res = 0;
int retry;
- if (!(req->flags & REQ_CMD)) {
+ if (!blk_fs_request(req)) {
end_request(req, 0);
continue;
}
}
}
+static int xd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
+{
+ XD_INFO *p = bdev->bd_disk->private_data;
+
+ geo->heads = p->heads;
+ geo->sectors = p->sectors;
+ geo->cylinders = p->cylinders;
+ return 0;
+}
+
/* xd_ioctl: handle device ioctl's */
static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg)
{
- XD_INFO *p = inode->i_bdev->bd_disk->private_data;
-
switch (cmd) {
- case HDIO_GETGEO:
- {
- struct hd_geometry g;
- struct hd_geometry __user *geom= (void __user *)arg;
- g.heads = p->heads;
- g.sectors = p->sectors;
- g.cylinders = p->cylinders;
- g.start = get_start_sect(inode->i_bdev);
- return copy_to_user(geom, &g, sizeof(g)) ? -EFAULT : 0;
- }
case HDIO_SET_DMA:
if (!capable(CAP_SYS_ADMIN)) return -EACCES;
if (xdc_busy) return -EBUSY;
}
/* xd_interrupt_handler: interrupt service routine */
-static irqreturn_t xd_interrupt_handler(int irq, void *dev_id,
- struct pt_regs *regs)
+static irqreturn_t xd_interrupt_handler(int irq, void *dev_id)
{
if (inb(XD_STATUS) & STAT_INTERRUPT) { /* check if it was our device */
#ifdef DEBUG_OTHER
int success;
xdc_busy = 1;
- while ((success = ((inb(port) & mask) != flags)) && time_before(jiffies, expiry)) {
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(1);
- }
+ while ((success = ((inb(port) & mask) != flags)) && time_before(jiffies, expiry))
+ schedule_timeout_uninterruptible(1);
xdc_busy = 0;
return (success);
}
for (i = 0; i < XD_MAXDRIVES; i++) {
xd_build(cmdblk,CMD_TESTREADY,i,0,0,0,0,0);
if (!xd_command(cmdblk,PIO_MODE,NULL,NULL,NULL,XD_TIMEOUT*8)) {
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(XD_INIT_DISK_DELAY);
+ msleep_interruptible(XD_INIT_DISK_DELAY);
init_drive(count);
count++;
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(XD_INIT_DISK_DELAY);
+ msleep_interruptible(XD_INIT_DISK_DELAY);
}
}
return (count);
outb(0,XD_RESET); /* reset the controller */
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(XD_INIT_DISK_DELAY);
+ msleep(XD_INIT_DISK_DELAY);
}
static void __init xd_wd_init_drive (u_char drive)
xd_maxsectors = 0x01;
outb(0,XD_RESET); /* reset the controller */
- set_current_state(TASK_UNINTERRUPTIBLE);
- schedule_timeout(XD_INIT_DISK_DELAY);
+ msleep(XD_INIT_DISK_DELAY);
}
static void __init xd_xebec_init_drive (u_char drive)
case 2: if ((integers[2] > 0) && (integers[2] < 16))
xd_irq = integers[2];
case 1: xd_override = 1;
- if ((integers[1] >= 0) && (integers[1] < (sizeof(xd_sigs) / sizeof(xd_sigs[0]))))
+ if ((integers[1] >= 0) && (integers[1] < ARRAY_SIZE(xd_sigs)))
xd_type = integers[1];
case 0: break;
default:printk("xd: too many parameters for xd\n");
#ifdef MODULE
-MODULE_PARM(xd, "1-4i");
-MODULE_PARM(xd_geo, "3-6i");
-MODULE_PARM(nodma, "i");
+module_param_array(xd, int, NULL, 0);
+module_param_array(xd_geo, int, NULL, 0);
+module_param(nodma, bool, 0);
MODULE_LICENSE("GPL");