X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=drivers%2Fblock%2Fxd.c;h=18a80ff57ce89f821fd3f5910a09207b7f5db605;hb=4eb3033c72099fab3536ed8ac54a5dc99f0832d7;hp=14be4c1ed1aaf53b57c7f62f4010e9b888f116a7;hpb=5b5c5d12b91cb6b2a2967f06aef35d59008dc2e7;p=safe%2Fjmp%2Flinux-2.6 diff --git a/drivers/block/xd.c b/drivers/block/xd.c index 14be4c1..18a80ff 100644 --- a/drivers/block/xd.c +++ b/drivers/block/xd.c @@ -49,6 +49,7 @@ #include #include #include +#include #include #include @@ -130,7 +131,7 @@ 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 = { +static const struct block_device_operations xd_fops = { .owner = THIS_MODULE, .locked_ioctl = xd_ioctl, .getgeo = xd_getgeo, @@ -169,13 +170,6 @@ static int __init xd_init(void) init_timer (&xd_watchdog_int); xd_watchdog_int.function = xd_watchdog; - if (!xd_dma_buffer) - xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200); - if (!xd_dma_buffer) { - printk(KERN_ERR "xd: Out of memory.\n"); - return -ENOMEM; - } - err = -EBUSY; if (register_blkdev(XT_DISK_MAJOR, "xd")) goto out1; @@ -202,6 +196,19 @@ static int __init xd_init(void) xd_drives,xd_drives == 1 ? "" : "s",xd_irq,xd_dma); } + /* + * With the drive detected, xd_maxsectors should now be known. + * If xd_maxsectors is 0, nothing was detected and we fall through + * to return -ENODEV + */ + if (!xd_dma_buffer && xd_maxsectors) { + xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200); + if (!xd_dma_buffer) { + printk(KERN_ERR "xd: Out of memory.\n"); + goto out3; + } + } + err = -ENODEV; if (!xd_drives) goto out3; @@ -236,7 +243,7 @@ static int __init xd_init(void) } /* xd_maxsectors depends on controller - so set after detection */ - blk_queue_max_sectors(xd_queue, xd_maxsectors); + blk_queue_max_hw_sectors(xd_queue, xd_maxsectors); for (i = 0; i < xd_drives; i++) add_disk(xd_gendisk[i]); @@ -249,15 +256,17 @@ out4: for (i = 0; i < xd_drives; i++) put_disk(xd_gendisk[i]); out3: - release_region(xd_iobase,4); + if (xd_maxsectors) + release_region(xd_iobase,4); + + if (xd_dma_buffer) + xd_dma_mem_free((unsigned long)xd_dma_buffer, + xd_maxsectors * 0x200); out2: blk_cleanup_queue(xd_queue); out1a: unregister_blkdev(XT_DISK_MAJOR, "xd"); out1: - if (xd_dma_buffer) - xd_dma_mem_free((unsigned long)xd_dma_buffer, - xd_maxsectors * 0x200); return err; Enomem: err = -ENOMEM; @@ -305,26 +314,25 @@ static void do_xd_request (struct request_queue * q) if (xdc_busy) return; - while ((req = elv_next_request(q)) != NULL) { - unsigned block = req->sector; - unsigned count = req->nr_sectors; + req = blk_fetch_request(q); + while (req) { + unsigned block = blk_rq_pos(req); + unsigned count = blk_rq_cur_sectors(req); XD_INFO *disk = req->rq_disk->private_data; - int res = 0; + int res = -EIO; int retry; - if (!blk_fs_request(req)) { - __blk_end_request_cur(req, -EIO); - continue; - } - if (block + count > get_capacity(req->rq_disk)) { - __blk_end_request_cur(req, -EIO); - continue; - } + if (!blk_fs_request(req)) + goto done; + if (block + count > get_capacity(req->rq_disk)) + goto done; for (retry = 0; (retry < XD_RETRIES) && !res; retry++) res = xd_readwrite(rq_data_dir(req), disk, req->buffer, block, count); + done: /* wrap up, 0 = success, -errno = fail */ - __blk_end_request_cur(req, res); + if (!__blk_end_request_cur(req, res)) + req = blk_fetch_request(q); } }