summaryrefslogtreecommitdiffstats
path: root/drivers/acorn/block/mfmhd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/acorn/block/mfmhd.c')
-rw-r--r--drivers/acorn/block/mfmhd.c112
1 files changed, 50 insertions, 62 deletions
diff --git a/drivers/acorn/block/mfmhd.c b/drivers/acorn/block/mfmhd.c
index 5931e1d93..d30251fbb 100644
--- a/drivers/acorn/block/mfmhd.c
+++ b/drivers/acorn/block/mfmhd.c
@@ -115,6 +115,7 @@
#define MAJOR_NR MFM_ACORN_MAJOR
#include <linux/blk.h>
+#include <linux/blkpg.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -975,7 +976,7 @@ static void mfm_request(void)
DBG("mfm_request: Dropping out bottom\n");
}
-static void do_mfm_request(void)
+static void do_mfm_request(request_queue_t *q)
{
DBG("do_mfm_request: about to mfm_request\n");
mfm_request();
@@ -1017,8 +1018,7 @@ static void mfm_interrupt_handler(int unused, void *dev_id, struct pt_regs *regs
/*
- * Tell the user about the drive if we decided it exists. Also,
- * set the size of the drive.
+ * Tell the user about the drive if we decided it exists.
*/
static void mfm_geometry (int drive)
{
@@ -1027,8 +1027,6 @@ static void mfm_geometry (int drive)
mfm_info[drive].cylinders * mfm_info[drive].heads * mfm_info[drive].sectors / 4096,
mfm_info[drive].cylinders, mfm_info[drive].heads, mfm_info[drive].sectors,
mfm_info[drive].lowcurrent, mfm_info[drive].precomp);
- mfm[drive << 6].start_sect = 0;
- mfm[drive << 6].nr_sects = mfm_info[drive].cylinders * mfm_info[drive].heads * mfm_info[drive].sectors / 2;
}
#ifdef CONFIG_BLK_DEV_MFM_AUTODETECT
@@ -1210,24 +1208,6 @@ static int mfm_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long a
return -EFAULT;
return 0;
- case BLKFLSBUF:
- if (!capable(CAP_SYS_ADMIN))
- return -EACCES;
- fsync_dev(dev);
- invalidate_buffers(dev);
- return 0;
-
- case BLKRASET:
- if (!capable(CAP_SYS_ADMIN))
- return -EACCES;
- if (arg > 0xff)
- return -EINVAL;
- read_ahead[major] = arg;
- return 0;
-
- case BLKRAGET:
- return put_user(read_ahead[major], (long *)arg);
-
case BLKGETSIZE:
return put_user (mfm[minor].nr_sects, (long *)arg);
@@ -1248,7 +1228,13 @@ static int mfm_ioctl(struct inode *inode, struct file *file, u_int cmd, u_long a
return -EACCES;
return mfm_reread_partitions(dev);
- RO_IOCTLS(dev, arg);
+ case BLKFLSBUF:
+ case BLKROSET:
+ case BLKROGET:
+ case BLKRASET:
+ case BLKRAGET:
+ case BLKPG:
+ return blk_ioctl(dev, cmd, arg);
default:
return -EINVAL;
@@ -1276,7 +1262,6 @@ static int mfm_open(struct inode *inode, struct file *file)
*/
static int mfm_release(struct inode *inode, struct file *file)
{
- fsync_dev(inode->i_rdev);
mfm_info[DEVICE_NR(MINOR(inode->i_rdev))].access_count--;
MOD_DEC_USE_COUNT;
return 0;
@@ -1295,6 +1280,7 @@ void mfm_setup(char *str, int *ints)
* Set the CHS from the ADFS boot block if it is present. This is not ideal
* since if there are any non-ADFS partitions on the disk, this won't work!
* Hence, I want to get rid of this...
+ * Please, do. It does seriously sucking things.
*/
void xd_set_geometry(kdev_t dev, unsigned char secsptrack, unsigned char heads,
unsigned long discsize, unsigned int secsize)
@@ -1320,18 +1306,16 @@ void xd_set_geometry(kdev_t dev, unsigned char secsptrack, unsigned char heads,
if (raw_cmd.dev == drive)
mfm_specify ();
mfm_geometry (drive);
+ mfm[drive << 6].start_sect = 0;
+ mfm[drive << 6].nr_sects = mfm_info[drive].cylinders * mfm_info[drive].heads * mfm_info[drive].sectors / 2;
}
}
-static void mfm_geninit (struct gendisk *gdev);
-
static struct gendisk mfm_gendisk = {
MAJOR_NR, /* Major number */
"mfm", /* Major name */
6, /* Bits to shift to get real from partition */
1 << 6, /* Number of partitions per real */
- MFM_MAXDRIVES, /* maximum number of real */
- mfm_geninit, /* init function */
mfm, /* hd struct */
mfm_sizes, /* block sizes */
0, /* number */
@@ -1339,17 +1323,30 @@ static struct gendisk mfm_gendisk = {
NULL /* next */
};
-static void mfm_geninit (struct gendisk *gdev)
+static struct block_device_operations mfm_fops =
+{
+ open: mfm_open,
+ release: mfm_release,
+ ioctl: mfm_ioctl,
+};
+
+static void mfm_geninit (void)
{
int i;
- mfm_drives = mfm_initdrives();
+ for (i = 0; i < (MFM_MAXDRIVES << 6); i++) {
+ /* Can't increase this - if you do all hell breaks loose */
+ mfm_blocksizes[i] = 1024;
+ mfm_sectsizes[i] = 512;
+ }
+ blksize_size[MAJOR_NR] = mfm_blocksizes;
+ hardsect_size[MAJOR_NR] = mfm_sectsizes;
- printk("mfm: detected %d hard drive%s\n", mfm_drives, mfm_drives == 1 ? "" : "s");
- gdev->nr_real = mfm_drives;
+ mfm_drives = mfm_initdrives();
- for (i = 0; i < mfm_drives; i++)
- mfm_geometry (i);
+ printk("mfm: detected %d hard drive%s\n", mfm_drives,
+ mfm_drives == 1 ? "" : "s");
+ mfm_gendisk.nr_real = mfm_drives;
if (request_irq(mfm_irq, mfm_interrupt_handler, SA_INTERRUPT, "MFM harddisk", NULL))
printk("mfm: unable to get IRQ%d\n", mfm_irq);
@@ -1357,22 +1354,15 @@ static void mfm_geninit (struct gendisk *gdev)
if (mfm_irqenable)
outw(0x80, mfm_irqenable); /* Required to enable IRQs from MFM podule */
- for (i = 0; i < (MFM_MAXDRIVES << 6); i++) {
- mfm_blocksizes[i] = 1024; /* Can't increase this - if you do all hell breaks loose */
- mfm_sectsizes[i] = 512;
+ for (i = 0; i < mfm_drives; i++) {
+ mfm_geometry (i);
+ register_disk(&mfm_gendisk, MKDEV(MAJOR_NR,i<<6), 1<<6,
+ &mfm_fops,
+ mfm_info[i].cylinders * mfm_info[i].heads *
+ mfm_info[i].sectors / 2);
}
- blksize_size[MAJOR_NR] = mfm_blocksizes;
- hardsect_size[MAJOR_NR] = mfm_sectsizes;
}
-static struct block_device_operations mfm_fops =
-{
- open: mfm_open,
- release: mfm_release,
- ioctl: mfm_ioctl,
-};
-
-
static struct expansion_card *ecs;
/*
@@ -1422,11 +1412,6 @@ int mfm_init (void)
{
unsigned char irqmask;
- if (register_blkdev(MAJOR_NR, "mfm", &mfm_fops)) {
- printk("mfm_init: unable to get major number %d\n", MAJOR_NR);
- return -1;
- }
-
if (mfm_probecontroller(ONBOARD_MFM_ADDRESS)) {
mfm_addr = ONBOARD_MFM_ADDRESS;
mfm_IRQPollLoc = IOC_IRQSTATB;
@@ -1449,6 +1434,12 @@ int mfm_init (void)
ecard_claim(ecs);
}
+ if (register_blkdev(MAJOR_NR, "mfm", &mfm_fops)) {
+ printk("mfm_init: unable to get major number %d\n", MAJOR_NR);
+ ecard_release(ecs);
+ return -1;
+ }
+
printk("mfm: found at address %08X, interrupt %d\n", mfm_addr, mfm_irq);
request_region (mfm_addr, 10, "mfm");
@@ -1457,7 +1448,7 @@ int mfm_init (void)
hdc63463_irqpolladdress = ioaddr(mfm_IRQPollLoc);
hdc63463_irqpollmask = irqmask;
- blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;
+ blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB?) read ahread */
#ifndef MODULE
@@ -1468,6 +1459,7 @@ int mfm_init (void)
Busy = 0;
lastspecifieddrive = -1;
+ mfm_geninit();
return 0;
}
@@ -1506,10 +1498,10 @@ static int mfm_reread_partitions(kdev_t dev)
mfm_gendisk.part[minor].nr_sects = 0;
}
- mfm_gendisk.part[start].nr_sects = mfm_info[target].heads *
- mfm_info[target].cylinders * mfm_info[target].sectors / 2;
+ /* Divide by 2, since sectors are 2 times smaller than usual ;-) */
- resetup_one_dev(&mfm_gendisk, target);
+ grok_partitions(&mfm_gendisk, target, 1<<6, mfm_info[target].heads *
+ mfm_info[target].cylinders * mfm_info[target].sectors / 2);
mfm_info[target].busy = 0;
wake_up (&mfm_wait_open);
@@ -1519,11 +1511,7 @@ static int mfm_reread_partitions(kdev_t dev)
#ifdef MODULE
int init_module(void)
{
- int ret;
- ret = mfm_init();
- if (!ret)
- mfm_geninit(&mfm_gendisk);
- return ret;
+ return mfm_init();
}
void cleanup_module(void)