Commit 411d439b authored by Alexander Viro's avatar Alexander Viro Committed by Linus Torvalds

[PATCH] cdu31a.c

	* switched to private queue
	* set ->queue
	* slightly cleaned up
parent 61320eeb
...@@ -177,7 +177,6 @@ ...@@ -177,7 +177,6 @@
#include "cdu31a.h" #include "cdu31a.h"
#define MAJOR_NR CDU31A_CDROM_MAJOR #define MAJOR_NR CDU31A_CDROM_MAJOR
#define DEVICE_NR(device) (minor(device))
#include <linux/blk.h> #include <linux/blk.h>
#define CDU31A_READAHEAD 4 /* 128 sector, 64kB, 32 reads read-ahead */ #define CDU31A_READAHEAD 4 /* 128 sector, 64kB, 32 reads read-ahead */
...@@ -238,6 +237,7 @@ static volatile unsigned short sony_cd_result_reg; ...@@ -238,6 +237,7 @@ static volatile unsigned short sony_cd_result_reg;
static volatile unsigned short sony_cd_read_reg; static volatile unsigned short sony_cd_read_reg;
static volatile unsigned short sony_cd_fifost_reg; static volatile unsigned short sony_cd_fifost_reg;
static struct request_queue cdu31a_queue;
static spinlock_t cdu31a_lock = SPIN_LOCK_UNLOCKED; /* queue lock */ static spinlock_t cdu31a_lock = SPIN_LOCK_UNLOCKED; /* queue lock */
static int sony_spun_up = 0; /* Has the drive been spun up? */ static int sony_spun_up = 0; /* Has the drive been spun up? */
...@@ -1531,6 +1531,7 @@ read_data_block(char *buffer, ...@@ -1531,6 +1531,7 @@ read_data_block(char *buffer,
*/ */
static void do_cdu31a_request(request_queue_t * q) static void do_cdu31a_request(request_queue_t * q)
{ {
struct request *req;
int block; int block;
int nblock; int nblock;
unsigned char res_reg[12]; unsigned char res_reg[12];
...@@ -1578,46 +1579,48 @@ static void do_cdu31a_request(request_queue_t * q) ...@@ -1578,46 +1579,48 @@ static void do_cdu31a_request(request_queue_t * q)
del_timer(&cdu31a_abort_timer); del_timer(&cdu31a_abort_timer);
while (1) { while (1) {
cdu31a_request_startover:
/* /*
* The beginning here is stolen from the hard disk driver. I hope * The beginning here is stolen from the hard disk driver. I hope
* it's right. * it's right.
*/ */
if (blk_queue_empty(QUEUE)) if (blk_queue_empty(q))
goto end_do_cdu31a_request; goto end_do_cdu31a_request;
if (!sony_spun_up) { if (!sony_spun_up)
scd_spinup(); scd_spinup();
}
block = CURRENT->sector; req = elv_next_request(q);
nblock = CURRENT->nr_sectors; block = req->sector;
nblock = req->nr_sectors;
if (!sony_toc_read) { if (!sony_toc_read) {
printk("CDU31A: TOC not read\n"); printk("CDU31A: TOC not read\n");
end_request(CURRENT, 0); end_request(req, 0);
goto cdu31a_request_startover; continue;
} }
if(CURRENT->flags & REQ_CMD) { /* WTF??? */
switch (rq_data_dir(CURRENT)) { if (!(req->flags & REQ_CMD))
case READ: continue;
if (rq_data_dir(req) == WRITE) {
end_request(req, 0);
continue;
}
if (rq_data_dir(req) != READ)
panic("CDU31A: Unknown cmd");
/* /*
* If the block address is invalid or the request goes beyond the end of * If the block address is invalid or the request goes beyond the end of
* the media, return an error. * the media, return an error.
*/ */
if ((block / 4) >= sony_toc.lead_out_start_lba) { if ((block / 4) >= sony_toc.lead_out_start_lba) {
printk printk("CDU31A: Request past end of media\n");
("CDU31A: Request past end of media\n"); end_request(req, 0);
end_request(CURRENT, 0); continue;
goto cdu31a_request_startover;
} }
if (((block + nblock) / 4) >= if (((block + nblock) / 4) >= sony_toc.lead_out_start_lba) {
sony_toc.lead_out_start_lba) { printk("CDU31A: Request past end of media\n");
printk end_request(req, 0);
("CDU31A: Request past end of media\n"); continue;
end_request(CURRENT, 0);
goto cdu31a_request_startover;
} }
num_retries = 0; num_retries = 0;
...@@ -1627,17 +1630,16 @@ static void do_cdu31a_request(request_queue_t * q) ...@@ -1627,17 +1630,16 @@ static void do_cdu31a_request(request_queue_t * q)
if (!sony_toc_read) { if (!sony_toc_read) {
printk("CDU31A: TOC not read\n"); printk("CDU31A: TOC not read\n");
end_request(CURRENT, 0); end_request(req, 0);
goto cdu31a_request_startover; continue;
} }
/* If no data is left to be read from the drive, start the /* If no data is left to be read from the drive, start the
next request. */ next request. */
if (sony_blocks_left == 0) { if (sony_blocks_left == 0) {
if (start_request if (start_request(block / 4, CDU31A_READAHEAD / 4, 0)) {
(block / 4, CDU31A_READAHEAD / 4, 0)) { end_request(req, 0);
end_request(CURRENT, 0); continue;
goto cdu31a_request_startover;
} }
} }
/* If the requested block is not the next one waiting in /* If the requested block is not the next one waiting in
...@@ -1645,58 +1647,43 @@ static void do_cdu31a_request(request_queue_t * q) ...@@ -1645,58 +1647,43 @@ static void do_cdu31a_request(request_queue_t * q)
new one. */ new one. */
else if (block != sony_next_block) { else if (block != sony_next_block) {
#if DEBUG #if DEBUG
printk printk("CDU31A Warning: Read for block %d, expected %d\n",
("CDU31A Warning: Read for block %d, expected %d\n",
block, sony_next_block); block, sony_next_block);
#endif #endif
abort_read(); abort_read();
if (!sony_toc_read) { if (!sony_toc_read) {
printk("CDU31A: TOC not read\n"); printk("CDU31A: TOC not read\n");
end_request(CURRENT, 0); end_request(req, 0);
goto cdu31a_request_startover; continue;
} }
if (start_request if (start_request(block / 4, CDU31A_READAHEAD / 4, 0)) {
(block / 4, CDU31A_READAHEAD / 4, 0)) { printk("CDU31a: start request failed\n");
printk end_request(req, 0);
("CDU31a: start request failed\n"); continue;
end_request(CURRENT, 0);
goto cdu31a_request_startover;
} }
} }
read_data_block(CURRENT->buffer, block, nblock, read_data_block(req->buffer, block, nblock, res_reg, &res_size);
res_reg, &res_size);
if (res_reg[0] == 0x20) { if (res_reg[0] != 0x20) {
end_request(req, 1);
continue;
}
if (num_retries > MAX_CDU31A_RETRIES) { if (num_retries > MAX_CDU31A_RETRIES) {
end_request(CURRENT, 0); end_request(req, 0);
goto cdu31a_request_startover; continue;
} }
num_retries++; num_retries++;
if (res_reg[1] == SONY_NOT_SPIN_ERR) { if (res_reg[1] == SONY_NOT_SPIN_ERR) {
do_sony_cd_cmd(SONY_SPIN_UP_CMD, do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg,
NULL, 0, res_reg,
&res_size); &res_size);
} else { } else {
printk printk("CDU31A: %s error for block %d, nblock %d\n",
("CDU31A: %s error for block %d, nblock %d\n", translate_error(res_reg[1]), block, nblock);
translate_error(res_reg[1]),
block, nblock);
} }
goto try_read_again; goto try_read_again;
} else {
end_request(CURRENT, 1);
}
break;
case WRITE:
end_request(CURRENT, 0);
break;
default:
panic("CDU31A: Unknown cmd");
}
}
} }
end_do_cdu31a_request: end_do_cdu31a_request:
spin_lock_irq(q->queue_lock); spin_lock_irq(q->queue_lock);
...@@ -3451,9 +3438,7 @@ int __init cdu31a_init(void) ...@@ -3451,9 +3438,7 @@ int __init cdu31a_init(void)
is_a_cdu31a = is_a_cdu31a =
strcmp("CD-ROM CDU31A", drive_config.product_id) == 0; strcmp("CD-ROM CDU31A", drive_config.product_id) == 0;
blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), blk_init_queue(&cdu31a_queue, do_cdu31a_request, &cdu31a_lock);
do_cdu31a_request,
&cdu31a_lock);
init_timer(&cdu31a_abort_timer); init_timer(&cdu31a_abort_timer);
cdu31a_abort_timer.function = handle_abort_timeout; cdu31a_abort_timer.function = handle_abort_timeout;
...@@ -3462,6 +3447,7 @@ int __init cdu31a_init(void) ...@@ -3462,6 +3447,7 @@ int __init cdu31a_init(void)
scd_gendisk = disk; scd_gendisk = disk;
if (register_cdrom(&scd_info)) if (register_cdrom(&scd_info))
goto errout0; goto errout0;
disk->queue = &cdu31a_queue;
add_disk(disk); add_disk(disk);
disk_changed = 1; disk_changed = 1;
...@@ -3469,7 +3455,7 @@ int __init cdu31a_init(void) ...@@ -3469,7 +3455,7 @@ int __init cdu31a_init(void)
errout0: errout0:
printk("Unable to register CDU-31a with Uniform cdrom driver\n"); printk("Unable to register CDU-31a with Uniform cdrom driver\n");
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR)); blk_cleanup_queue(&cdu31a_queue);
put_disk(disk); put_disk(disk);
errout1: errout1:
if (unregister_blkdev(MAJOR_NR, "cdu31a")) { if (unregister_blkdev(MAJOR_NR, "cdu31a")) {
...@@ -3496,7 +3482,7 @@ void __exit cdu31a_exit(void) ...@@ -3496,7 +3482,7 @@ void __exit cdu31a_exit(void)
return; return;
} }
blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR)); blk_cleanup_queue(&cdu31a_queue);
if (cdu31a_irq > 0) if (cdu31a_irq > 0)
free_irq(cdu31a_irq, NULL); free_irq(cdu31a_irq, NULL);
......
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