X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fblock%2Fswim3.c;fp=drivers%2Fblock%2Fswim3.c;h=01f042f6f1c42874e9090ce60f0e925d7b73726c;hb=64ba3f394c830ec48a1c31b53dcae312c56f1604;hp=cc42e762396f28fccff473f32b9cc1c73ef862fb;hpb=be1e6109ac94a859551f8e1774eb9a8469fe055c;p=linux-2.6.git diff --git a/drivers/block/swim3.c b/drivers/block/swim3.c index cc42e7623..01f042f6f 100644 --- a/drivers/block/swim3.c +++ b/drivers/block/swim3.c @@ -16,6 +16,7 @@ * handle GCR disks */ +#include #include #include #include @@ -24,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -250,6 +252,8 @@ static int floppy_open(struct inode *inode, struct file *filp); static int floppy_release(struct inode *inode, struct file *filp); static int floppy_check_change(struct gendisk *disk); static int floppy_revalidate(struct gendisk *disk); +static int swim3_add_device(struct device_node *swims); +int swim3_init(void); #ifndef CONFIG_PMAC_MEDIABAY #define check_media_bay(which, what) 1 @@ -1009,63 +1013,117 @@ static struct block_device_operations floppy_fops = { .revalidate_disk= floppy_revalidate, }; -static int swim3_add_device(struct macio_dev *mdev, int index) +int swim3_init(void) +{ + struct device_node *swim; + int err = -ENOMEM; + int i; + + devfs_mk_dir("floppy"); + + swim = find_devices("floppy"); + while (swim && (floppy_count < MAX_FLOPPIES)) + { + swim3_add_device(swim); + swim = swim->next; + } + + swim = find_devices("swim3"); + while (swim && (floppy_count < MAX_FLOPPIES)) + { + swim3_add_device(swim); + swim = swim->next; + } + + if (!floppy_count) + return -ENODEV; + + for (i = 0; i < floppy_count; i++) { + disks[i] = alloc_disk(1); + if (!disks[i]) + goto out; + } + + if (register_blkdev(FLOPPY_MAJOR, "fd")) { + err = -EBUSY; + goto out; + } + + swim3_queue = blk_init_queue(do_fd_request, &swim3_lock); + if (!swim3_queue) { + err = -ENOMEM; + goto out_queue; + } + + for (i = 0; i < floppy_count; i++) { + struct gendisk *disk = disks[i]; + disk->major = FLOPPY_MAJOR; + disk->first_minor = i; + disk->fops = &floppy_fops; + disk->private_data = &floppy_states[i]; + disk->queue = swim3_queue; + disk->flags |= GENHD_FL_REMOVABLE; + sprintf(disk->disk_name, "fd%d", i); + sprintf(disk->devfs_name, "floppy/%d", i); + set_capacity(disk, 2880); + add_disk(disk); + } + return 0; + +out_queue: + unregister_blkdev(FLOPPY_MAJOR, "fd"); +out: + while (i--) + put_disk(disks[i]); + /* shouldn't we do something with results of swim_add_device()? */ + return err; +} + +static int swim3_add_device(struct device_node *swim) { - struct device_node *swim = mdev->ofdev.node; struct device_node *mediabay; - struct floppy_state *fs = &floppy_states[index]; - int rc = -EBUSY; + struct floppy_state *fs = &floppy_states[floppy_count]; + struct resource res_reg, res_dma; - /* Check & Request resources */ - if (macio_resource_count(mdev) < 2) { - printk(KERN_WARNING "ifd%d: no address for %s\n", - index, swim->full_name); - return -ENXIO; + if (of_address_to_resource(swim, 0, &res_reg) || + of_address_to_resource(swim, 1, &res_dma)) { + printk(KERN_ERR "swim3: Can't get addresses\n"); + return -EINVAL; } - if (macio_irq_count(mdev) < 2) { - printk(KERN_WARNING "fd%d: no intrs for device %s\n", - index, swim->full_name); + if (request_mem_region(res_reg.start, res_reg.end - res_reg.start + 1, + " (reg)") == NULL) { + printk(KERN_ERR "swim3: Can't request register space\n"); + return -EINVAL; } - if (macio_request_resource(mdev, 0, "swim3 (mmio)")) { - printk(KERN_ERR "fd%d: can't request mmio resource for %s\n", - index, swim->full_name); - return -EBUSY; + if (request_mem_region(res_dma.start, res_dma.end - res_dma.start + 1, + " (dma)") == NULL) { + release_mem_region(res_reg.start, + res_reg.end - res_reg.start + 1); + printk(KERN_ERR "swim3: Can't request DMA space\n"); + return -EINVAL; } - if (macio_request_resource(mdev, 1, "swim3 (dma)")) { - printk(KERN_ERR "fd%d: can't request dma resource for %s\n", - index, swim->full_name); - macio_release_resource(mdev, 0); - return -EBUSY; + + if (swim->n_intrs < 2) { + printk(KERN_INFO "swim3: expecting 2 intrs (n_intrs:%d)\n", + swim->n_intrs); + release_mem_region(res_reg.start, + res_reg.end - res_reg.start + 1); + release_mem_region(res_dma.start, + res_dma.end - res_dma.start + 1); + return -EINVAL; } - dev_set_drvdata(&mdev->ofdev.dev, fs); - mediabay = (strcasecmp(swim->parent->type, "media-bay") == 0) ? - swim->parent : NULL; + mediabay = (strcasecmp(swim->parent->type, "media-bay") == 0) ? swim->parent : NULL; if (mediabay == NULL) pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 1); memset(fs, 0, sizeof(*fs)); spin_lock_init(&fs->lock); fs->state = idle; - fs->swim3 = (struct swim3 __iomem *) - ioremap(macio_resource_start(mdev, 0), 0x200); - if (fs->swim3 == NULL) { - printk("fd%d: couldn't map registers for %s\n", - index, swim->full_name); - rc = -ENOMEM; - goto out_release; - } - fs->dma = (struct dbdma_regs __iomem *) - ioremap(macio_resource_start(mdev, 1), 0x200); - if (fs->dma == NULL) { - printk("fd%d: couldn't map DMA for %s\n", - index, swim->full_name); - iounmap(fs->swim3); - rc = -ENOMEM; - goto out_release; - } - fs->swim3_intr = macio_irq(mdev, 0); - fs->dma_intr = macio_irq(mdev, 1);; + fs->swim3 = (struct swim3 __iomem *)ioremap(res_reg.start, 0x200); + fs->dma = (struct dbdma_regs __iomem *)ioremap(res_dma.start, 0x200); + fs->swim3_intr = swim->intrs[0].line; + fs->dma_intr = swim->intrs[1].line; fs->cur_cyl = -1; fs->cur_sector = -1; fs->secpercyl = 36; @@ -1079,16 +1137,15 @@ static int swim3_add_device(struct macio_dev *mdev, int index) st_le16(&fs->dma_cmd[1].command, DBDMA_STOP); if (request_irq(fs->swim3_intr, swim3_interrupt, 0, "SWIM3", fs)) { - printk(KERN_ERR "fd%d: couldn't request irq %d for %s\n", - index, fs->swim3_intr, swim->full_name); + printk(KERN_ERR "Couldn't get irq %d for SWIM3\n", fs->swim3_intr); pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 0); - goto out_unmap; return -EBUSY; } /* if (request_irq(fs->dma_intr, fd_dma_interrupt, 0, "SWIM3-dma", fs)) { printk(KERN_ERR "Couldn't get irq %d for SWIM3 DMA", fs->dma_intr); + pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 0); return -EBUSY; } */ @@ -1098,90 +1155,8 @@ static int swim3_add_device(struct macio_dev *mdev, int index) printk(KERN_INFO "fd%d: SWIM3 floppy controller %s\n", floppy_count, mediabay ? "in media bay" : ""); - return 0; - - out_unmap: - iounmap(fs->dma); - iounmap(fs->swim3); - - out_release: - macio_release_resource(mdev, 0); - macio_release_resource(mdev, 1); - - return rc; -} - -static int __devinit swim3_attach(struct macio_dev *mdev, const struct of_device_id *match) -{ - int i, rc; - struct gendisk *disk; - - /* Add the drive */ - rc = swim3_add_device(mdev, floppy_count); - if (rc) - return rc; - - /* Now create the queue if not there yet */ - if (swim3_queue == NULL) { - /* If we failed, there isn't much we can do as the driver is still - * too dumb to remove the device, just bail out - */ - if (register_blkdev(FLOPPY_MAJOR, "fd")) - return 0; - swim3_queue = blk_init_queue(do_fd_request, &swim3_lock); - if (swim3_queue == NULL) { - unregister_blkdev(FLOPPY_MAJOR, "fd"); - return 0; - } - } - - /* Now register that disk. Same comment about failure handling */ - i = floppy_count++; - disk = disks[i] = alloc_disk(1); - if (disk == NULL) - return 0; - - disk->major = FLOPPY_MAJOR; - disk->first_minor = i; - disk->fops = &floppy_fops; - disk->private_data = &floppy_states[i]; - disk->queue = swim3_queue; - disk->flags |= GENHD_FL_REMOVABLE; - sprintf(disk->disk_name, "fd%d", i); - set_capacity(disk, 2880); - add_disk(disk); - - return 0; -} - -static struct of_device_id swim3_match[] = -{ - { - .name = "swim3", - }, - { - .compatible = "ohare-swim3" - }, - { - .compatible = "swim3" - }, -}; - -static struct macio_driver swim3_driver = -{ - .name = "swim3", - .match_table = swim3_match, - .probe = swim3_attach, -#if 0 - .suspend = swim3_suspend, - .resume = swim3_resume, -#endif -}; - - -int swim3_init(void) -{ - macio_register_driver(&swim3_driver); + floppy_count++; + return 0; }