Commit 7473f096 authored by Alexander Viro's avatar Alexander Viro Committed by James Bottomley

[PATCH] xd.c

	* switched to private queues
	* set ->queue and ->private_data
	* switched to use of ->bd_disk and ->rq_disk
	* cleaned up
parent 9bc1bce3
...@@ -52,7 +52,6 @@ ...@@ -52,7 +52,6 @@
#include <asm/dma.h> #include <asm/dma.h>
#define MAJOR_NR XT_DISK_MAJOR #define MAJOR_NR XT_DISK_MAJOR
#define DEVICE_NR(device) (minor(device) >> 6)
#include <linux/blk.h> #include <linux/blk.h>
#include <linux/blkpg.h> #include <linux/blkpg.h>
...@@ -129,8 +128,8 @@ static spinlock_t xd_lock = SPIN_LOCK_UNLOCKED; ...@@ -129,8 +128,8 @@ static spinlock_t xd_lock = SPIN_LOCK_UNLOCKED;
static struct gendisk *xd_gendisk[2]; static struct gendisk *xd_gendisk[2];
static struct block_device_operations xd_fops = { static struct block_device_operations xd_fops = {
owner: THIS_MODULE, .owner = THIS_MODULE,
ioctl: xd_ioctl, .ioctl = xd_ioctl,
}; };
static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int); static DECLARE_WAIT_QUEUE_HEAD(xd_wait_int);
static u_char xd_drives, xd_irq = 5, xd_dma = 3, xd_maxsectors; static u_char xd_drives, xd_irq = 5, xd_dma = 3, xd_maxsectors;
...@@ -144,6 +143,8 @@ static struct timer_list xd_watchdog_int; ...@@ -144,6 +143,8 @@ static struct timer_list xd_watchdog_int;
static volatile u_char xd_error; static volatile u_char xd_error;
static int nodma = XD_DONT_USE_DMA; static int nodma = XD_DONT_USE_DMA;
static struct request_queue xd_queue;
static devfs_handle_t devfs_handle = NULL; static devfs_handle_t devfs_handle = NULL;
/* xd_init: register the block device number and set up pointer tables */ /* xd_init: register the block device number and set up pointer tables */
...@@ -177,7 +178,7 @@ static int __init xd_init(void) ...@@ -177,7 +178,7 @@ static int __init xd_init(void)
goto out1; goto out1;
} }
devfs_handle = devfs_mk_dir (NULL, "xd", NULL); devfs_handle = devfs_mk_dir (NULL, "xd", NULL);
blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), do_xd_request, &xd_lock); blk_init_queue(&xd_queue, do_xd_request, &xd_lock);
if (xd_detect(&controller,&address)) { if (xd_detect(&controller,&address)) {
printk("Detected a%s controller (type %d) at address %06x\n", printk("Detected a%s controller (type %d) at address %06x\n",
...@@ -193,11 +194,6 @@ static int __init xd_init(void) ...@@ -193,11 +194,6 @@ static int __init xd_init(void)
printk("Detected %d hard drive%s (using IRQ%d & DMA%d)\n", printk("Detected %d hard drive%s (using IRQ%d & DMA%d)\n",
xd_drives,xd_drives == 1 ? "" : "s",xd_irq,xd_dma); 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,
xd_info[i].cylinders,xd_info[i].heads,
xd_info[i].sectors);
} }
err = -ENODEV; err = -ENODEV;
...@@ -205,13 +201,20 @@ static int __init xd_init(void) ...@@ -205,13 +201,20 @@ static int __init xd_init(void)
goto out3; goto out3;
for (i = 0; i < xd_drives; i++) { for (i = 0; i < xd_drives; i++) {
XD_INFO *p = &xd_info[i];
struct gendisk *disk = alloc_disk(64); struct gendisk *disk = alloc_disk(64);
if (!disk) if (!disk)
goto Enomem; goto Enomem;
p->unit = i;
disk->major = MAJOR_NR; disk->major = MAJOR_NR;
disk->first_minor = i<<6; disk->first_minor = i<<6;
sprintf(disk->disk_name, "xd%c", i+'a'); sprintf(disk->disk_name, "xd%c", i+'a');
disk->fops = &xd_fops; disk->fops = &xd_fops;
disk->private_data = p;
disk->queue = &xd_queue;
set_capacity(disk, p->heads * p->cylinders * p->sectors);
printk(" %s: CHS=%d/%d/%d\n", disk->disk_name,
p->cylinders, p->heads, p->sectors);
xd_gendisk[i] = disk; xd_gendisk[i] = disk;
} }
...@@ -227,14 +230,10 @@ static int __init xd_init(void) ...@@ -227,14 +230,10 @@ static int __init xd_init(void)
} }
/* xd_maxsectors depends on controller - so set after detection */ /* xd_maxsectors depends on controller - so set after detection */
blk_queue_max_sectors(BLK_DEFAULT_QUEUE(MAJOR_NR), xd_maxsectors); blk_queue_max_sectors(&xd_queue, xd_maxsectors);
for (i = 0; i < xd_drives; i++) { for (i = 0; i < xd_drives; i++)
struct gendisk *disk = xd_gendisk[i]; add_disk(xd_gendisk[i]);
set_capacity(disk, xd_info[i].heads * xd_info[i].cylinders *
xd_info[i].sectors);
add_disk(disk);
}
return 0; return 0;
...@@ -246,7 +245,7 @@ static int __init xd_init(void) ...@@ -246,7 +245,7 @@ static int __init xd_init(void)
out3: out3:
release_region(xd_iobase,4); release_region(xd_iobase,4);
out2: out2:
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR)); blk_cleanup_queue(&xd_queue);
unregister_blkdev(MAJOR_NR, "xd"); unregister_blkdev(MAJOR_NR, "xd");
out1: out1:
if (xd_dma_buffer) if (xd_dma_buffer)
...@@ -286,55 +285,50 @@ static u_char __init xd_detect (u_char *controller, unsigned int *address) ...@@ -286,55 +285,50 @@ static u_char __init xd_detect (u_char *controller, unsigned int *address)
/* do_xd_request: handle an incoming request */ /* do_xd_request: handle an incoming request */
static void do_xd_request (request_queue_t * q) static void do_xd_request (request_queue_t * q)
{ {
u_int block,count,retry;
int code;
if (xdc_busy) if (xdc_busy)
return; return;
while (1) { while (!blk_queue_empty(q)) {
int unit; struct request *req = elv_next_request(q);
code = 0; unsigned block = req->sector;
/* do some checking on the request structure */ unsigned count = req->nr_sectors;
if (blk_queue_empty(QUEUE)) int rw = rq_data_dir(req);
return; XD_INFO *disk = req->rq_disk->private_data;
int res = 0;
unit = DEVICE_NR(CURRENT->rq_dev); int retry;
if (unit < xd_drives
&& (CURRENT->flags & REQ_CMD) if (!(req->flags & REQ_CMD)) {
&& CURRENT->sector + CURRENT->nr_sectors end_request(req, 0);
<= get_capacity(xd_gendisk[unit])) { continue;
block = CURRENT->sector; }
count = CURRENT->nr_sectors; if (block + count > get_capacity(req->rq_disk)) {
end_request(req, 0);
switch (rq_data_dir(CURRENT)) { continue;
case READ:
case WRITE:
for (retry = 0; (retry < XD_RETRIES) && !code; retry++)
code = xd_readwrite(rq_data_dir(CURRENT),unit,
CURRENT->buffer,block,count);
break;
default:
printk("do_xd_request: unknown request\n");
break;
} }
if (rw != READ && rw != WRITE) {
printk("do_xd_request: unknown request\n");
end_request(req, 0);
continue;
} }
end_request(CURRENT, code); /* wrap up, 0 = fail, 1 = success */ for (retry = 0; (retry < XD_RETRIES) && !res; retry++)
res = xd_readwrite(rw, disk, req->buffer, block, count);
end_request(req, res); /* wrap up, 0 = fail, 1 = success */
} }
} }
/* xd_ioctl: handle device ioctl's */ /* 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,u_int cmd,u_long arg)
{ {
int dev = DEVICE_NR(inode->i_rdev); XD_INFO *p = inode->i_bdev->bd_disk->private_data;
switch (cmd) { switch (cmd) {
case HDIO_GETGEO: case HDIO_GETGEO:
{ {
struct hd_geometry g; struct hd_geometry g;
struct hd_geometry *geometry = (struct hd_geometry *) arg; struct hd_geometry *geometry = (struct hd_geometry *) arg;
g.heads = xd_info[dev].heads; g.heads = p->heads;
g.sectors = xd_info[dev].sectors; g.sectors = p->sectors;
g.cylinders = xd_info[dev].cylinders; g.cylinders = p->cylinders;
g.start = get_start_sect(inode->i_bdev); g.start = get_start_sect(inode->i_bdev);
return copy_to_user(geometry, &g, sizeof g) ? -EFAULT : 0; return copy_to_user(geometry, &g, sizeof g) ? -EFAULT : 0;
} }
...@@ -364,8 +358,9 @@ static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg) ...@@ -364,8 +358,9 @@ static int xd_ioctl (struct inode *inode,struct file *file,u_int cmd,u_long arg)
} }
/* xd_readwrite: handle a read/write request */ /* 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 (u_char operation,XD_INFO *p,char *buffer,u_int block,u_int count)
{ {
int drive = p->unit;
u_char cmdblk[6],sense[4]; u_char cmdblk[6],sense[4];
u_short track,cylinder; u_short track,cylinder;
u_char head,sector,control,mode = PIO_MODE,temp; u_char head,sector,control,mode = PIO_MODE,temp;
...@@ -378,16 +373,16 @@ static int xd_readwrite (u_char operation,u_char drive,char *buffer,u_int block, ...@@ -378,16 +373,16 @@ static int xd_readwrite (u_char operation,u_char drive,char *buffer,u_int block,
spin_unlock_irq(&xd_lock); spin_unlock_irq(&xd_lock);
control = xd_info[drive].control; control = p->control;
if (!xd_dma_buffer) if (!xd_dma_buffer)
xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200); xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
while (count) { while (count) {
temp = count < xd_maxsectors ? count : xd_maxsectors; temp = count < xd_maxsectors ? count : xd_maxsectors;
track = block / xd_info[drive].sectors; track = block / p->sectors;
head = track % xd_info[drive].heads; head = track % p->heads;
cylinder = track / xd_info[drive].heads; cylinder = track / p->heads;
sector = block % xd_info[drive].sectors; sector = block % p->sectors;
#ifdef DEBUG_READWRITE #ifdef DEBUG_READWRITE
printk("xd_readwrite: drive = %d, head = %d, cylinder = %d, sector = %d, count = %d\n",drive,head,cylinder,sector,temp); printk("xd_readwrite: drive = %d, head = %d, cylinder = %d, sector = %d, count = %d\n",drive,head,cylinder,sector,temp);
...@@ -1057,7 +1052,7 @@ void cleanup_module(void) ...@@ -1057,7 +1052,7 @@ void cleanup_module(void)
del_gendisk(xd_gendisk[i]); del_gendisk(xd_gendisk[i]);
put_disk(xd_gendisk[i]); put_disk(xd_gendisk[i]);
} }
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR)); blk_cleanup_queue(&xd_queue);
release_region(xd_iobase,4); release_region(xd_iobase,4);
devfs_unregister (devfs_handle); devfs_unregister (devfs_handle);
if (xd_drives) { if (xd_drives) {
......
...@@ -84,16 +84,9 @@ typedef struct { ...@@ -84,16 +84,9 @@ typedef struct {
u_short cylinders; u_short cylinders;
u_char sectors; u_char sectors;
u_char control; u_char control;
int unit;
} XD_INFO; } XD_INFO;
/* this structure is returned to the HDIO_GETGEO ioctl */
typedef struct {
__u8 heads;
__u8 sectors;
__u8 cylinders;
__u32 start;
} XD_GEOMETRY;
/* this structure defines a ROM BIOS signature */ /* this structure defines a ROM BIOS signature */
typedef struct { typedef struct {
unsigned int offset; unsigned int offset;
...@@ -111,7 +104,7 @@ static u_char xd_initdrives (void (*init_drive)(u_char drive)); ...@@ -111,7 +104,7 @@ static u_char xd_initdrives (void (*init_drive)(u_char drive));
static void do_xd_request (request_queue_t * q); static void do_xd_request (request_queue_t * q);
static int xd_ioctl (struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg); static int xd_ioctl (struct inode *inode,struct file *file,unsigned int cmd,unsigned long arg);
static int xd_readwrite (u_char operation,u_char drive,char *buffer,u_int block,u_int count); static int xd_readwrite (u_char operation,XD_INFO *disk,char *buffer,u_int block,u_int count);
static void xd_recalibrate (u_char drive); static void xd_recalibrate (u_char drive);
static void xd_interrupt_handler (int irq, void *dev_id, struct pt_regs *regs); static void xd_interrupt_handler (int irq, void *dev_id, struct pt_regs *regs);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment