drivers/block/ataflop.c

Source file repositories/reference/linux-study-clean/drivers/block/ataflop.c

File Facts

System
Linux kernel
Corpus path
drivers/block/ataflop.c
Extension
.c
Size
57860 bytes
Lines
2205
Domain
Driver Families
Bucket
drivers/block
Inferred role
Driver Families: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

static const struct blk_mq_ops ataflop_mq_ops = {
	.queue_rq = ataflop_queue_rq,
};

static int ataflop_alloc_disk(unsigned int drive, unsigned int type)
{
	struct queue_limits lim = {
		.features		= BLK_FEAT_ROTATIONAL,
	};
	struct gendisk *disk;

	disk = blk_mq_alloc_disk(&unit[drive].tag_set, &lim, NULL);
	if (IS_ERR(disk))
		return PTR_ERR(disk);

	disk->major = FLOPPY_MAJOR;
	disk->first_minor = drive + (type << 2);
	disk->minors = 1;
	sprintf(disk->disk_name, "fd%d", drive);
	disk->fops = &floppy_fops;
	disk->flags |= GENHD_FL_NO_PART;
	disk->events = DISK_EVENT_MEDIA_CHANGE;
	disk->private_data = &unit[drive];
	set_capacity(disk, MAX_DISK_SIZE * 2);

	unit[drive].disk[type] = disk;
	return 0;
}

static void ataflop_probe(dev_t dev)
{
	int drive = MINOR(dev) & 3;
	int type  = MINOR(dev) >> 2;

	if (type)
		type--;

	if (drive >= FD_MAX_UNITS || type >= NUM_DISK_MINORS)
		return;
	if (unit[drive].disk[type])
		return;
	if (ataflop_alloc_disk(drive, type))
		return;
	if (add_disk(unit[drive].disk[type]))
		goto cleanup_disk;
	unit[drive].registered[type] = true;
	return;

cleanup_disk:
	put_disk(unit[drive].disk[type]);
	unit[drive].disk[type] = NULL;
}

static void atari_floppy_cleanup(void)
{
	int i;
	int type;

	for (i = 0; i < FD_MAX_UNITS; i++) {
		for (type = 0; type < NUM_DISK_MINORS; type++) {
			if (!unit[i].disk[type])
				continue;
			del_gendisk(unit[i].disk[type]);
			put_disk(unit[i].disk[type]);
		}
		blk_mq_free_tag_set(&unit[i].tag_set);
	}

	timer_delete_sync(&fd_timer);
	atari_stram_free(DMABuffer);
}

static void atari_cleanup_floppy_disk(struct atari_floppy_struct *fs)
{
	int type;

	for (type = 0; type < NUM_DISK_MINORS; type++) {
		if (!fs->disk[type])
			continue;
		if (fs->registered[type])
			del_gendisk(fs->disk[type]);
		put_disk(fs->disk[type]);
	}
	blk_mq_free_tag_set(&fs->tag_set);
}

static int __init atari_floppy_init (void)
{
	int i;
	int ret;

Annotation

Implementation Notes