Commit dbaa54b6 authored by Omar Sandoval's avatar Omar Sandoval Committed by Jens Axboe

swim3: add real error handling in setup

The driver doesn't have support for removing a device that has already
been configured, but with more careful ordering we can avoid the need
for that and make sure that we don't leak generic resources.
Signed-off-by: default avatarOmar Sandoval <osandov@fb.com>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent e3896d77
...@@ -1202,47 +1202,59 @@ static int swim3_add_device(struct macio_dev *mdev, int index) ...@@ -1202,47 +1202,59 @@ static int swim3_add_device(struct macio_dev *mdev, int index)
static int swim3_attach(struct macio_dev *mdev, static int swim3_attach(struct macio_dev *mdev,
const struct of_device_id *match) const struct of_device_id *match)
{ {
struct floppy_state *fs;
struct gendisk *disk; struct gendisk *disk;
int index, rc; int rc;
index = floppy_count++; if (floppy_count >= MAX_FLOPPIES)
if (index >= MAX_FLOPPIES)
return -ENXIO; return -ENXIO;
/* Add the drive */ if (floppy_count == 0) {
rc = swim3_add_device(mdev, index); rc = register_blkdev(FLOPPY_MAJOR, "fd");
if (rc) if (rc)
return rc; return rc;
/* Now register that disk. Same comment about failure handling */ }
disk = disks[index] = alloc_disk(1);
if (disk == NULL) fs = &floppy_states[floppy_count];
return -ENOMEM;
disk = alloc_disk(1);
if (disk == NULL) {
rc = -ENOMEM;
goto out_unregister;
}
disk->queue = blk_init_queue(do_fd_request, &swim3_lock); disk->queue = blk_init_queue(do_fd_request, &swim3_lock);
if (disk->queue == NULL) { if (disk->queue == NULL) {
put_disk(disk); rc = -ENOMEM;
return -ENOMEM; goto out_put_disk;
} }
blk_queue_bounce_limit(disk->queue, BLK_BOUNCE_HIGH); blk_queue_bounce_limit(disk->queue, BLK_BOUNCE_HIGH);
disk->queue->queuedata = &floppy_states[index]; disk->queue->queuedata = fs;
if (index == 0) { rc = swim3_add_device(mdev, floppy_count);
/* If we failed, there isn't much we can do as the driver is still if (rc)
* too dumb to remove the device, just bail out goto out_cleanup_queue;
*/
if (register_blkdev(FLOPPY_MAJOR, "fd"))
return 0;
}
disk->major = FLOPPY_MAJOR; disk->major = FLOPPY_MAJOR;
disk->first_minor = index; disk->first_minor = floppy_count;
disk->fops = &floppy_fops; disk->fops = &floppy_fops;
disk->private_data = &floppy_states[index]; disk->private_data = fs;
disk->flags |= GENHD_FL_REMOVABLE; disk->flags |= GENHD_FL_REMOVABLE;
sprintf(disk->disk_name, "fd%d", index); sprintf(disk->disk_name, "fd%d", floppy_count);
set_capacity(disk, 2880); set_capacity(disk, 2880);
add_disk(disk); add_disk(disk);
disks[floppy_count++] = disk;
return 0; return 0;
out_cleanup_queue:
blk_cleanup_queue(disk->queue);
disk->queue = NULL;
out_put_disk:
put_disk(disk);
out_unregister:
if (floppy_count == 0)
unregister_blkdev(FLOPPY_MAJOR, "fd");
return rc;
} }
static const struct of_device_id swim3_match[] = static const struct of_device_id swim3_match[] =
......
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