struct device *dev;
struct request_queue *breq;
+ struct request *req;
spinlock_t lock;
struct gendisk *gd;
static void mg_request(struct request_queue *);
+static bool mg_end_request(struct mg_host *host, int err, unsigned int nr_bytes)
+{
+ if (__blk_end_request(host->req, err, nr_bytes))
+ return true;
+
+ host->req = NULL;
+ return false;
+}
+
+static bool mg_end_request_cur(struct mg_host *host, int err)
+{
+ return mg_end_request(host, err, blk_rq_cur_bytes(host->req));
+}
+
static void mg_dump_status(const char *msg, unsigned int stat,
struct mg_host *host)
{
char *name = MG_DISK_NAME;
- struct request *req;
- if (host->breq) {
- req = elv_next_request(host->breq);
- if (req)
- name = req->rq_disk->disk_name;
- }
+ if (host->req)
+ name = host->req->rq_disk->disk_name;
printk(KERN_ERR "%s: %s: status=0x%02x { ", name, msg, stat & 0xff);
if (stat & ATA_BUSY)
printk("AddrMarkNotFound ");
printk("}");
if (host->error & (ATA_BBK | ATA_UNC | ATA_IDNF | ATA_AMNF)) {
- if (host->breq) {
- req = elv_next_request(host->breq);
- if (req)
- printk(", sector=%u",
- (unsigned int)blk_rq_pos(req));
- }
-
+ if (host->req)
+ printk(", sector=%u",
+ (unsigned int)blk_rq_pos(host->req));
}
printk("\n");
}
static void mg_bad_rw_intr(struct mg_host *host)
{
- struct request *req = elv_next_request(host->breq);
- if (req != NULL)
- if (++req->errors >= MG_MAX_ERRORS ||
- host->error == MG_ERR_TIMEOUT)
- __blk_end_request_cur(req, -EIO);
+ if (host->req)
+ if (++host->req->errors >= MG_MAX_ERRORS ||
+ host->error == MG_ERR_TIMEOUT)
+ mg_end_request_cur(host, -EIO);
}
static unsigned int mg_out(struct mg_host *host,
outb(MG_CMD_RD_CONF, (unsigned long)host->dev_base +
MG_REG_COMMAND);
- } while (__blk_end_request(req, 0, MG_SECTOR_SIZE));
+ } while (mg_end_request(host, 0, MG_SECTOR_SIZE));
}
static void mg_write(struct request *req)
outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base +
MG_REG_COMMAND);
- } while (__blk_end_request(req, 0, MG_SECTOR_SIZE));
+ } while (mg_end_request(host, 0, MG_SECTOR_SIZE));
}
static void mg_read_intr(struct mg_host *host)
{
+ struct request *req = host->req;
u32 i;
u16 *buff;
- struct request *req;
/* check status */
do {
ok_to_read:
/* get current segment of request */
- req = elv_next_request(host->breq);
buff = (u16 *)req->buffer;
/* read 1 sector */
/* send read confirm */
outb(MG_CMD_RD_CONF, (unsigned long)host->dev_base + MG_REG_COMMAND);
- if (__blk_end_request(req, 0, MG_SECTOR_SIZE)) {
+ if (mg_end_request(host, 0, MG_SECTOR_SIZE)) {
/* set handler if read remains */
host->mg_do_intr = mg_read_intr;
mod_timer(&host->timer, jiffies + 3 * HZ);
static void mg_write_intr(struct mg_host *host)
{
+ struct request *req = host->req;
u32 i, j;
u16 *buff;
- struct request *req;
bool rem;
- /* get current segment of request */
- req = elv_next_request(host->breq);
-
/* check status */
do {
i = inb((unsigned long)host->dev_base + MG_REG_STATUS);
return;
ok_to_write:
- if ((rem = __blk_end_request(req, 0, MG_SECTOR_SIZE))) {
+ if ((rem = mg_end_request(host, 0, MG_SECTOR_SIZE))) {
/* write 1 sector and set handler if remains */
buff = (u16 *)req->buffer;
for (j = 0; j < MG_STORAGE_BUFFER_SIZE >> 1; j++) {
{
struct mg_host *host = (struct mg_host *)data;
char *name;
- struct request *req;
spin_lock_irq(&host->lock);
- req = elv_next_request(host->breq);
- if (!req)
+ if (!host->req)
goto out_unlock;
host->mg_do_intr = NULL;
- name = req->rq_disk->disk_name;
+ name = host->req->rq_disk->disk_name;
printk(KERN_DEBUG "%s: timeout\n", name);
host->error = MG_ERR_TIMEOUT;
mg_bad_rw_intr(host);
- mg_request(host->breq);
out_unlock:
+ mg_request(host->breq);
spin_unlock_irq(&host->lock);
}
static void mg_request_poll(struct request_queue *q)
{
- struct request *req;
- struct mg_host *host;
+ struct mg_host *host = q->queuedata;
- while ((req = elv_next_request(q)) != NULL) {
- host = req->rq_disk->private_data;
+ while (1) {
+ if (!host->req) {
+ host->req = elv_next_request(q);
+ if (host->req)
+ blkdev_dequeue_request(host->req);
+ else
+ break;
+ }
- if (unlikely(!blk_fs_request(req))) {
- __blk_end_request_cur(req, -EIO);
+ if (unlikely(!blk_fs_request(host->req))) {
+ mg_end_request_cur(host, -EIO);
continue;
}
- if (rq_data_dir(req) == READ)
- mg_read(req);
+ if (rq_data_dir(host->req) == READ)
+ mg_read(host->req);
else
- mg_write(req);
+ mg_write(host->req);
}
}
/* This function also called from IRQ context */
static void mg_request(struct request_queue *q)
{
+ struct mg_host *host = q->queuedata;
struct request *req;
- struct mg_host *host;
u32 sect_num, sect_cnt;
while (1) {
- req = elv_next_request(q);
- if (!req)
- return;
-
- host = req->rq_disk->private_data;
+ if (!host->req) {
+ host->req = elv_next_request(q);
+ if (host->req)
+ blkdev_dequeue_request(host->req);
+ else
+ break;
+ }
+ req = host->req;
/* check unwanted request call */
if (host->mg_do_intr)
"%s: bad access: sector=%d, count=%d\n",
req->rq_disk->disk_name,
sect_num, sect_cnt);
- __blk_end_request_cur(req, -EIO);
+ mg_end_request_cur(host, -EIO);
continue;
}
if (unlikely(!blk_fs_request(req))) {
- __blk_end_request_cur(req, -EIO);
+ mg_end_request_cur(host, -EIO);
continue;
}
__func__, __LINE__);
goto probe_err_5;
}
+ host->breq->queuedata = host;
/* mflash is random device, thanx for the noop */
elevator_exit(host->breq->elevator);